<?php
if ( ! defined( 'ABSPATH' ) ) exit;
/*
	If you want to display the 'update now' link just below the plugin when required,
	Then these both lines of code are useful to do the job.
	Just put them in any correct place to run properly.
	Refresh the suitable page to run them once to clear the plugins update history and cache.
	Then make them comment again to allow to run the update check again. And DONE.
	//delete_site_transient( 'update_plugins' );
	//wp_cache_delete( 'plugins', 'plugins' );
*/

class WP_AutoUpdate 
{
	/**
	 * The plugin current version
	 * @var string
	 */
	private $current_version;

	/**
	 * The plugin remote update path
	 * @var string
	 */
	private $update_path;

	/**
	 * Plugin Base Name (plugin_directory/plugin_file.php)
	 * @var string
	 */
	private $plugin_basename;

	private $cache_key;
    private $cache_allowed;
	/**
	 * Plugin name (plugin_file)
	 * @var string
	 */
	private $slug;

	/**
	 * License User
	 * @var string
	 */
	private $license_user;

	/**
	 * License Key 
	 * @var string
	 */
	private $license_key;

	/**
	 * Initialize a new instance of the WordPress Auto-Update class
	 * @param string $current_version
	 * @param string $update_path
	 * @param string $plugin_basename
	 */
	public function __construct( $current_version, $update_path, $plugin_basename, $license_user = '', $license_key = '' )
	{
		// Set the class public variables
		$this->current_version = $current_version;
		$this->update_path = $update_path;

		// Set the License
		$this->license_user = $license_user;
		$this->license_key = $license_key;

		// Set the Plugin Slug	
		$this->plugin_basename = $plugin_basename;
		list ($t1, $t2) = explode( '/', $plugin_basename );
		$this->slug = str_replace( '.php', '', $t2 );		

		// Set the cache details
		$this->cache_key = $this->slug . '_updater_key';
        $this->cache_allowed = true;

		// Define the alternative API for updating checking
		add_filter( 'pre_set_site_transient_update_plugins', array( &$this, 'check_update' ) );

		// Define the alternative response for information checking
		add_filter( 'plugins_api', array( &$this, 'check_info' ), 10, 3 );
		
		// Define the alternative API for clear the update cache files
		add_action( 'upgrader_process_complete', array(  $this, 'purge' ), 10, 2 );
		
		// Define the alternative API to display the custom update notification
		add_action( 'in_plugin_update_message-' . $this->plugin_basename, array(  $this, 'wpdocs_plugin_update_message' ), 10, 2 );
	}

	/**
	 * Add our self-hosted autoupdate plugin to the filter transient
	 *
	 * @param $transient
	 * @return object $ transient
	 */
	public function check_update( $transient )
	{
		if ( empty( $transient->checked ) ) {
			return $transient;
		}

		// Get the remote version
		$remote_version = $this->getRemote('version');
		
		if ( empty($remote_version->new_version) || empty($remote_version->slug) ){
			return $transient;
		} elseif($remote_version->slug !== $this->slug) {
			return $transient;
		}

		// If a newer version is available, add the update
		if ( version_compare( $this->current_version, $remote_version->new_version, '<' ) ) {
			$obj = new stdClass();
			$obj->slug = $this->slug;
			$obj->new_version = $remote_version->new_version;
			//$obj->url = $remote_version->url;
			$obj->plugin = $this->plugin_basename;
			$obj->package = $remote_version->package;
			$obj->tested = $remote_version->tested;
			$obj->update_notification = $remote_version->update_notification;
			$transient->response[$this->plugin_basename] = $obj;
		}
		return $transient;
	}

	/**
	 * Add our self-hosted description to the filter
	 *
	 * @param boolean $false
	 * @param array $action
	 * @param object $arg
	 * @return bool|object
	 */
	public function check_info($obj, $action, $arg)
	{
		if (($action=='query_plugins' || $action=='plugin_information') && isset($arg->slug) && $arg->slug === $this->slug) {
			$remote_info = $this->getRemote('info');
			$remote_info->sections = array('Description' => $remote_info->sections->description,'changelog' => $remote_info->sections->changelog,'Upgrade_Notice' => $remote_info->sections->upgradenotice);
			$remote_info->banners = array('low' => $remote_info->banners->low, 'high' => $remote_info->banners->high);
			return $remote_info;
		}
		
		return $obj;
	}


	public function wpdocs_plugin_update_message( $plugin_data, $new_data ) {
		//echo '<br><strong>Version 2.3.4 is a recommended update 3 </strong><br>' . $new_data->update_notification;
		if ( isset( $plugin_data['update'] ) && $plugin_data['update'] && isset( $new_data->update_notification ) ) {
			$iserror = substr($new_data->update_notification,0,6);
			if(strcasecmp($iserror, "Error:")==0){
				$errmsg = false;
				$iserror = substr($new_data->update_notification,6);
				if(is_numeric($iserror)){
					if($iserror==9) $errmsg = true;
				}
				echo '<br><b><big style="color:#990000;">';
				if($errmsg){
					echo esc_html__("Error: 09; Please enter the SERIAL KEY and ACTIVATE the plugin.","email-otp-authenticator");
				}else{
					echo $new_data->update_notification . '; '.esc_html__("Please report this error number to the developer immediately.","email-otp-authenticator");
				}
				echo '</big><b>';
				ob_get_flush();
			} else {
				$nodes_parts = explode("~",$new_data->update_notification);
				$all_nodes = array();
				$raw_nodes = array();
				for($parts = 0; $parts < count($nodes_parts) ; $parts++){
					$raw_nodes = explode("`",$nodes_parts[$parts]);
					if(count($raw_nodes)>1) $all_nodes[$raw_nodes[0]] = $raw_nodes[1];
				}
				if ( strtolower($all_nodes['show_highlighted_notice']) == 'yes' ) {
					ob_start(); ?>

					<style type="text/css">
						.um_plugin_upgrade_notice {
							font-weight: 400;
							color: <?php echo $all_nodes['fontcolor']; ?>;
							background: <?php echo $all_nodes['background']; ?>;
							padding: 1em;
							margin: 9px 0;
							display: block;
							box-sizing: border-box;
							-webkit-box-sizing: border-box;
							-moz-box-sizing: border-box;
						}

						.um_plugin_upgrade_notice:before {
							content: "<?php echo $all_nodes['iconbefore']; ?>";
							display: inline-block;
							font: 400 18px/1 dashicons;
							speak: none;
							margin: 0 8px 0 -2px;
							-webkit-font-smoothing: antialiased;
							-moz-osx-font-smoothing: grayscale;
							vertical-align: top;
						}
					</style>

					<span class="um_plugin_upgrade_notice">
						<?php echo $all_nodes['notice_message']; ?>
					</span>

					<?php ob_get_flush();
				} else {
					echo '<br>' . $all_nodes['notice_message'];
				}
			}
		}
	}


    public function purge( $upgrader, $options ) {
        if ( $this->cache_allowed && 'update' === $options['action'] && 'plugin' === $options[ 'type' ] ) {
            // just clean the cache when new plugin version is installed
            delete_transient( $this->cache_key );
        }
    }

	/**
	 * Return the remote version
	 * 
	 * @return string $remote_version
	 */
	public function getRemote($action = '')
	{
		$request = get_transient( $this->cache_key );
		if( !(false === $request) ){
			$checkcache = json_decode($request['body']);
			if (! isset($checkcache))
				$request = false;
			elseif ($checkcache == null)
				$request = false;
			elseif (empty($checkcache))
				$request = false;
			elseif (! isset($checkcache->sections->changelog))
				$request = false;
			elseif ($checkcache->sections->changelog == null)
				$request = false;
			elseif (empty($checkcache->sections->changelog))
				$request = false;
		}
		if( false === $request || ! $this->cache_allowed ) {
			$params = array(
				'body' => array(
					'action'       => $action,
					'license_user' => $this->license_user,
					'license_key'  => $this->license_key,
					'client_versn' => $this->current_version,
				),
			);
			
			// Make the POST request
			$request = wp_remote_post($this->update_path, $params );
			
			// Check if response is valid
			if ( (!is_wp_error( $request )) && wp_remote_retrieve_response_code( $request ) === 200 ) {
				if ( $this->cache_allowed ) set_transient( $this->cache_key, $request, DAY_IN_SECONDS );
				//return @unserialize( $request['body'] );
				return @json_decode($request['body']); 
			}
		} else {
			//return @unserialize( $request['body'] );
			return @json_decode($request['body']); 
		}
		return false;
	}
	
/*
// These important lines of code are used in main plugin file.

 * Update URI: http://localhost/objects/pro-test-server/

		public function __construct()  {
			add_action('admin_init', array(&$this, 'emailotpauthn_admin_init'));
		}
		/**
		 * hook into WP's admin_init action hook
		 * /
		public function emailotpauthn_admin_init()
		{
			// Set up the settings for this plugin, and the line below is not related to this self hosted update coding.
			$this->emailotpauthn_init_settings();
			// Possibly do additional admin_init tasks
			global $wp_filter;
			if (isset($wp_filter['admin_notices'])) {
				unset($wp_filter['admin_notices']);
			}
			$plugin_data = get_plugin_data( __FILE__ );
			define('EMAILOTPAUTHN_PLUGIN_NAME', $plugin_data['Name']);
			define('EMAILOTPAUTHN_PLUGIN_VERSION', $plugin_data['Version']);
			define('EMAILOTPAUTHN_PLUGIN_SLUG', $plugin_data['TextDomain']);
			define('EMAILOTPAUTHN_PLUGIN_UPDATEURI', $plugin_data['UpdateURI']);
			define('EMAILOTPAUTHN_PLUGIN_BASENAME', plugin_basename( __FILE__ ));
			require(sprintf("%s/lib/copytype.php", dirname(__FILE__)));
			if($isProCopy) {
				require_once(sprintf("%s/lib/wp_autoupdate.php", dirname(__FILE__)));
				$license_user = get_bloginfo("admin_email");
				$license_key = 'NotRequired';
				$plugin_remote_path = EMAILOTPAUTHN_PLUGIN_UPDATEURI;
				if(substr($plugin_remote_path,-1) !== '/') $plugin_remote_path.= '/';
				$plugin_remote_path = $plugin_remote_path . 'update.php';
				new WP_AutoUpdate ( EMAILOTPAUTHN_PLUGIN_VERSION, $plugin_remote_path, EMAILOTPAUTHN_PLUGIN_BASENAME, $license_user, $license_key );
			}
		} // END public static function activate

*/
}
