<?php
if ( ! defined( 'ABSPATH' ) || class_exists( 'MH_Updater', false ) )
	return;

/**
 * Plugin Updater Class
 *
 */
class MH_Updater{

	var $config;

	public function __construct( $config = array() ) {

		$defaults = array(
			'base' => '',
			'repo_slug' => '',
		);

		$this->config = wp_parse_args( $config, $defaults );
        
		
        if ( !empty ( $this->config['repo_slug'] ) ){
            if ( !empty( $this->config['base'] ) ){     
              add_filter( 'http_request_args', array( &$this, 'disable_wporg_request' ), 5, 2 );
              add_filter( 'pre_set_site_transient_update_plugins', array( &$this, 'plugins_transient_update' ) );
              add_filter( 'plugins_api', array( &$this, 'plugins_api_result' ), 10, 3 );
              add_filter( 'upgrader_post_install', array( &$this, 'upgrader_post_install' ), 10, 3 );
            }else{
              add_action( 'after_setup_theme', array( $this, 'theme_updater_setup' ), 15 );
            }
        }
	}
    
    /**
	 * Get stored data 
	 */
    public function mh_get_captured_data() {
        $cached = '';
        $cache = mh_request_updates_data();

		if( empty( $cache )) {
			$cached = '';
		} elseif( is_array($cache) ) {
        
            if ( !empty( $this->config['base'] ) ){
                $updater_data = $this->updater_data();
            }else{
                $updater_data = $this->theme_updater_data();
            }

            if ( version_compare( $updater_data['version'], $cache[$updater_data['repo_slug']]['version'], '<' ) ) {

                $cached = $cache[$updater_data['repo_slug']];

                // We need to turn the icons into an array for plugins
                if ( !empty( $cache[$updater_data['repo_slug']]['icons'] ) ) {
                    $cache[$updater_data['repo_slug']]['icons'] = (array) $cache[$updater_data['repo_slug']]['icons'];
                }
            }
        }
		return $cached;
    }

	/**
	 * Disable request to wp.org plugin repository
	 */
	public function disable_wporg_request( $r, $url ){

		$wp_url_string = 'api.wordpress.org/plugins/update-check';

		if ( false === strpos( $url, $wp_url_string ) ){
			return $r;
		}

		$plugin_slug = dirname( $this->config['base'] );

		$r_body = wp_remote_retrieve_body( $r );

		$r_plugins = '';
		$r_plugins_json = false;
		if( isset( $r_body['plugins'] ) ){

			if ( is_serialized( $r_body['plugins'] ) ){
				$r_plugins = @unserialize( $r_body['plugins'] );
				$r_plugins = (array) $r_plugins;
			}else{
				$r_plugins = json_decode( $r_body['plugins'], true );
				$r_plugins_json = true;
			}
		}

		$to_disable = '';

		if  ( !empty( $r_plugins ) ){
			$all_plugins = $r_plugins['plugins'];
			foreach ( $all_plugins as $plugin_base => $plugin_data ){


				if ( dirname( $plugin_base ) == $plugin_slug ){
					$to_disable = $plugin_base;
				}
			}

			if ( !empty( $to_disable ) ){
				unset(  $all_plugins[ $to_disable ] );
			}
            
			if ( true === $r_plugins_json ){
				$r_plugins['plugins'] = $all_plugins;
				$r['body']['plugins'] = json_encode( $r_plugins );
            }else{ 
				$r_plugins['plugins'] = $all_plugins;
				$r_plugins_object = (object) $r_plugins;
				$r['body']['plugins'] = serialize( $r_plugins_object );
			}
		}

		return $r;
	}

	/**
	 * This plugin data
	 */
	public function updater_data(){

		$updater_data = array();

		// basename folder/file.php
		$updater_data['basename'] = $this->config['base'];
		$slug = dirname( $this->config['base'] );
		$updater_data['slug'] = $slug;
		$updater_data['file'] = $slug . '.php';
		$file_path = trailingslashit( WP_PLUGIN_DIR ) . $updater_data['basename'];

		$get_plugin_data = get_plugin_data( $file_path );
        
		$updater_data['name'] = strip_tags( $get_plugin_data['Name'] );
		$updater_data['version'] = strip_tags( $get_plugin_data['Version'] );

		$uri = '';
		if ( $get_plugin_data['PluginURI'] ) $uri = esc_url( $get_plugin_data['PluginURI'] );
		$updater_data['uri'] = $uri;

		$author = strip_tags( $get_plugin_data['Author'] );
		$author_uri = $get_plugin_data['AuthorURI'];
		if ( $author && $author_uri ) $author = '<a href="' . esc_url_raw( $author_uri ) . '">' . $author . '</a>';
		$updater_data['author'] = $author;

		$repo_slug = '';
		if ( !empty( $this->config['repo_slug'] ) )
			$repo_slug = sanitize_title( $this->config['repo_slug'] );
		$updater_data['repo_slug'] = $repo_slug;

		return $updater_data;
	}


	/**
	 * Check for plugin updates
	 */
	public function plugins_transient_update( $checked_data ) {

		if ( empty( $checked_data->checked ) )
			return $checked_data;
        
        if ( ! is_object( $checked_data ) )
			$checked_data = new stdClass;
        
        $data = $this->mh_get_captured_data();
        
        $updater_data = $this->updater_data();
        
        if (!empty( $data)){
            $updates = new stdClass;
            $updates->new_version = $data['version'];
            $updates->package = esc_url_raw( $data['package'] );
            $updates->slug = $updater_data['slug'];
            $updates->url = $data['url'];
            $updates->requires = $data['requires'];
            $updates->tested = $data['tested'];

            if ( isset( $data['icons'] ) ) {
                $updates->icons = maybe_unserialize( $data['icons'] );
            }

           $checked_data->response[$updater_data['basename']] = $updates;
        }
        
		return $checked_data;
	}


	/**
	 * Filter Plugin API
	 */
	public function plugins_api_result( $res, $action, $args ) {

		$updater_data = $this->updater_data();

		if ( is_array($args) )
			$args = (object)$args;

		$plugin_slug = '';

		if ( !isset( $args->slug ) ){

			if ( isset( $_REQUEST['plugin'] ) ){
				$plugin_slug = wp_unslash( $_REQUEST['plugin'] );
                
			}else{
                
                if ( isset( $args->body['request'] ) ){
                    $get_args_body = maybe_unserialize( $args->body['request'] );
                    if ( isset( $get_args_body->slug ) ){
                        $plugin_slug = $get_args_body->slug;
                    }
                }
			}
            
		}else{
			$plugin_slug = $args->slug;
		}
        
        $data = $this->mh_get_captured_data();
        
		if ( $plugin_slug == $updater_data['slug'] && $action == 'plugin_information' && !empty( $data ) ){
   
            $info = new stdClass;
            $info->name = $updater_data['name'];
            $info->version = $data['version'];
            $info->download_link = esc_url_raw( $data['package'] );
            $info->requires = $data['requires'];
            $info->tested = $data['tested'];

            $info->slug = $updater_data['slug'];
            $info->author = $updater_data['author'];
            $info->uri = $updater_data['uri'];
            
            $info->external = true;

            
            if ( isset( $data['sections'] ) ) {
                $info->sections = maybe_unserialize( $data['sections'] );
            }

            if ( isset( $data['banners'] ) ) {
                $info->banners = maybe_unserialize( $data['banners'] );
            }

            if ( isset( $data['icons'] ) ) {
                $info->icons = maybe_unserialize( $data['icons'] );
            }

            if( ! empty( $data['sections'] ) ) {
                foreach( $data['sections'] as $key => $section ) {
                    $info->$key = (array) $section;
                }
            }

            $res = $info;
        }
		return $res;
	}


	/**
	 * Make sure plugin is installed in correct folder
	 */
	public function upgrader_post_install( $true, $hook_extra, $result ) {

		if ( isset( $hook_extra ) ){
            
			$plugin_base = $this->config['base'];
			$plugin_slug = dirname( $plugin_base );

			if ( isset( $hook_extra['plugin'] ) && $hook_extra['plugin'] == $plugin_base ){

				global $wp_filesystem;

				$proper_destination = trailingslashit( WP_PLUGIN_DIR ) . $plugin_slug;
				$wp_filesystem->move( $result['destination'], $proper_destination );
				$result['destination'] = $proper_destination;
				$activate = activate_plugin( trailingslashit( WP_PLUGIN_DIR ) . $plugin_base );

				$fail = esc_html__( 'The plugin has been updated, but could not be reactivated. Please reactivate it manually.', 'mharty' );
				$success = esc_html__( 'Plugin reactivated successfully.', 'mharty' );
				echo is_wp_error( $activate ) ? $fail : $success;
			}
		}
		return $result;
	}
     /**
     * Theme functions
     */
    public function theme_updater_setup(){
        // Get needed data
        $updater_data = $this->theme_updater_data();

        // disable request to wp.org repo
        add_filter( 'http_request_args', array( $this, 'theme_disable_wporg_request' ), 5, 2 );

        // filter theme update transient
        add_filter( 'pre_set_site_transient_update_themes', array( $this, 'theme_transient_update' ) );
        add_filter( 'delete_site_transient_update_themes', array( $this, 'delete_theme_update_transient' ) );
        add_action( 'load-update-core.php',                array( $this, 'delete_theme_update_transient' ) );
        add_action( 'load-themes.php',                     array( $this, 'delete_theme_update_transient' ) );
        add_action( 'admin_notices', array( $this, 'theme_update_nag' ) );
    }
    
    /**
	 * Disable request to wp.org theme repository
	 */
    public function theme_disable_wporg_request( $r, $url ){
        // If it's not a theme update request, bail.
        if ( 0 !== strpos( $url, 'https://api.wordpress.org/themes/update-check/1.1/' ) ) {
            return $r;
        }

        // Decode the JSON response
        $themes = json_decode( $r['body']['themes'] );

        // Remove the active parent and child themes from the check
        $parent = get_option( 'template' );
        $child = get_option( 'stylesheet' );
        unset( $themes->themes->$parent );
        unset( $themes->themes->$child );

        // Encode the updated JSON response
        $r['body']['themes'] = json_encode( $themes );

        return $r;
    }
    
    /**
	 * This theme data
	 */
	public function theme_updater_data(){
        
		$updater_data = array();
        
        // Theme data
        $theme_data = wp_get_theme( get_template() );
        
        //theme name
        $updater_data['name'] = esc_attr( $theme_data->get( 'Name' ) );

        //theme version
        $updater_data['version'] = esc_attr( $theme_data->get( 'Version' ) );
        $updater_data['slug'] = get_template();

				$updater_data['repo_slug'] = 'mharty';

		return $updater_data;
	}
    
    /**
	 * Check for ptheme updates
	 */
	public function theme_transient_update( $checked_data ) {
        
        
        $data = $this->mh_get_captured_data();
        
        $updater_data = $this->theme_updater_data();
        
        if (!empty( $data)){
            
            $updates = array();
            //$updates['theme'] = $updater_data['name'];
            $updates['new_version'] = $data['version'];
            $updates['package'] = esc_url_raw( $data['package'] );
            $updates['url'] = $data['url'] . '/changelog';
            
            if ( !isset( $checked_data->response ) )
                $checked_data = new stdClass();
                $checked_data->response = array();
            
           $checked_data->response[$updater_data['slug']] = $updates;

        }
        
		return $checked_data;
	}
    
    /**
	 * Theme update notification
	 */
    public function theme_update_nag() {
				global $pagenow;
        $updater_data = $this->theme_updater_data();
        $theme = wp_get_theme( $updater_data['repo_slug'] );
        $data = $this->mh_get_captured_data();

        if ( empty($data) ) {
            return;
        }
       if ('valid' !== get_option( 'mharty_activation_key_status', '' )){
         return;
        }

        $update_url = wp_nonce_url( 'update.php?action=upgrade-theme&amp;theme=' . urlencode( $updater_data['repo_slug'] ), 'upgrade-theme_' . $updater_data['repo_slug'] );
             
        if ( version_compare( $updater_data['version'], $data['version'], '<' ) && current_user_can( 'switch_themes' ) ) {
				 if ($pagenow == 'themes.php' || $pagenow == 'update-core.php' || $pagenow == 'update.php' ) {
						return;
				 }
            echo '<div class="update-nag mh-update-nag mh-theme-update-nag"><p>';

						echo '<strong>' . __('Mharty Theme', 'mharty')  . ' (' . $data['version'] . ')</strong> ' . __('is available.', 'mharty') . ' <a href="' . esc_url($data['url'] . '/changelog') . '" title="' .  __('Mharty Theme', 'mharty') . '" target="_blank">' . __('Check out what\'s new', 'mharty') . '</a> ' .  __('or', 'mharty') . ' <a href="' . $update_url . '">' .  __('update now.', 'mharty') . '</a>';
            echo '</p></div>';
        }
    }
    /**
	 * Remove the updater captured data
	 */
	public function delete_theme_update_transient() {
		delete_site_transient( 'mh_captured_updates_data' );
	}
}
