<?php

/*
 *******************
 * AUTHORIZE WORDPRESS TO DOWNLOAD THE PLUGIN FILE
 *******************
 *
 *	We don't allow directly access to the "wphave update" folder [https://wphave.com/wphave-update/], so we use basic authorization.
 *	! Notice: It's important to send the authorization header, to make the download link available for the WordPress plugin update process.
 *
 *  @type	filter
 *  @date	06/18/19
 *  @since	2.0
 *
 *  @param	N/A
 *  @return	N/A
 *
*/

if ( ! function_exists( 'wphave_admin_auto_update_file_authorization' ) ) :

	function wphave_admin_auto_update_file_authorization( $args, $url ) {

		if( class_exists('wphave') ) {
			// We use the same method in the "wphave" plugin. So if this plugin exists, we don't need this filter here.
			return $args;
		}
		
		// Check if the request url contains the "wphave update" folder
		if( strpos( $url, 'https://wphave.com/wphave-update/' ) !== false ) {

			// This simple authorization data we use to get access to the "wphave update" folder
			$username = 'wphave';		
			$password = 'wp_update';

			// Send the authorization header
			$args['headers'] = array( 
				'Authorization' => 'Basic ' . base64_encode( $username . ':' . $password ) 
			);

		}

		return $args;

	}

endif;

add_filter( 'http_request_args', 'wphave_admin_auto_update_file_authorization', 10, 2 );


/*
 *******************
 * AUTO-UPDATE REMOTE ACCESS TO UPDATE SERVER
 *******************
 *
 *	Function to get the update information from the update server via remote access.
 *
 *  @type	function
 *  @date	06/18/19
 *  @since	2.0
 *
 *  @param	N/A
 *  @return	N/A
 *
*/


if ( ! function_exists( 'wphave_admin_update_remote' ) ) :

	function wphave_admin_update_remote( $slug ) {
		
		// Trying to get from cache first
		if( false == $remote = get_transient( 'wphave_update_flag' ) ) {
			
			/* !!!!!
			* Notice: The "https://wphave.com/wphave-update/" directory is proteced by .htpasswd / basic authorization
			* We have to send the correct login credentials to access this directory
			!!!!! */
			
			// This simple authorization data we use to get access to the "wphave update" folder
			$username = 'wphave';		
			$password = 'wp_update';

			// Path to the downloadable plugin file [Includes CURL with basic authorization]
			$file_is_available = wphave_admin_external_file_exists( "https://wphave.com/wphave-update/plugins/{$slug}.zip", array(
				'auth' => true,
				'username' => $username,
				'password' => $password,
			) );

			if( ! $file_is_available ) {
				// Stop here, if no file found
				return false;
			}
			
			// {$slug}.json is the file with the actual plugin information on your server
			$remote = wp_remote_request( "https://wphave.com/wphave-update/update.json", array(
				'timeout' => 10,
				'headers' => array(
					'Authorization' => 'Basic ' . base64_encode( $username . ':' . $password ), // <-- We don't allow directly access to the "wphave update" folder, so we use basic authorization
					'Accept' => 'application/json',
				) )
			);
						
			if( ! is_wp_error( $remote ) && isset( $remote['response']['code'] ) && $remote['response']['code'] == 200 && ! empty( $remote['body'] ) ) {
				set_transient( 'wphave_update_flag', $remote, 24 * HOUR_IN_SECONDS );
			}			

		}
		
		return $remote;

	}

endif;


/*
 *******************
 * UPDATE PLUGIN INFO
 *******************
 *
 *	Function to list important parts for the plugin update process.
 *
 *  @type	function
 *  @date	06/18/19
 *  @since	2.0
 *
 *  @param	N/A
 *  @return	N/A
 *
*/

if ( ! function_exists( 'wphave_admin_update_info' ) ) :

	function wphave_admin_update_info() {

		$plugin = array();
		
		$plugin['name'] = WPHAVE_ADMIN_PLUGIN_NAME;
		$plugin['slug'] = WPHAVE_ADMIN_NAMESPACE;
		$plugin['path'] = WPHAVE_ADMIN_NAMESPACE . '/' . WPHAVE_ADMIN_NAMESPACE . '.php';
		$plugin['package'] = 'https://wphave.com/wphave-update/plugins/wphave-admin.zip';
		
		$plugin['version'] = WPHAVE_ADMIN_VERSION; // --> Current plugin version
		$plugin['tested'] = WPHAVE_ADMIN_WP_VERSION; // --> Tested up to WordPress version
		$plugin['requires'] = WPHAVE_ADMIN_WP_VERSION; // --> Required WordPress version
		$plugin['requires_php'] = WPHAVE_ADMIN_PHP_VERSION; // --> Required PHP version
		
		$plugin['description'] = __('Designed for all the people, who loves to create websites with WordPress. A clean, beautiful and modern admin theme. This theme plugin is very easy to customize and packed with useful features such as wp memory usage, custom login page, custom theme colors and many more.', 'wphave-admin');
		$plugin['installation'] = __('Visit our website to learn more about the installation and update process: <ul><li>Installation: https://wphave.com/documentation/installation/</li><li>Update: https://wphave.com/documentation/update/</li></ul>', 'wphave-admin');
		$plugin['changelog'] = __('Visit our website to see the version changelog on https://wphave.com/changelog/', 'wphave-admin');
		
		$plugin['banners'] = array(
			'low' => wphave_admin_path( 'assets/img/banner-772x250.jpg' ),
			'high' => wphave_admin_path( 'assets/img/banner-1544x500.jpg' ),
		);
		
		$plugin['icons'] = array(
			'2x' => wphave_admin_path( 'assets/img/favicon.png' ),
			'1x' => wphave_admin_path( 'assets/img/favicon.png' ),
			'svg' => wphave_admin_path( 'assets/img/favicon.png' ),
		);
				
		$plugin['url'] = WPHAVE_ADMIN_AUTHOR_URL;
		
		return $plugin;		

	}

endif;


/*
 *******************
 * GET PLUGIN DETAILS
 *******************
 *
 *	Show more details about the plugin. Available on WordPress plugin screen "View Details" by the plugin.
 *
 *  @type	filter
 *  @date	06/18/19
 *  @since	2.0
 *
 *  @param	N/A
 *  @return	N/A
 *
*/

if ( ! function_exists( 'wphave_admin_auto_update_plugin_info' ) ) :

	function wphave_admin_auto_update_plugin_info( $res, $action, $args ) {

		// Do nothing if this is not about getting plugin information
		if( 'plugin_information' !== $action ) {
			return $res;
		}
		
		// Get plugin informations
		$plugin = wphave_admin_update_info();
		
		$slug = $plugin['slug'];
		$name = $plugin['name'];		
		$requires_php = $plugin['requires_php'];		
		
		$banners = $plugin['banners'];
		$icons = $plugin['icons'];
		$url = $plugin['url'];
		
		$description = $plugin['description'];
		$installation = $plugin['installation'];
		$changelog = $plugin['changelog'];
		
		// Do nothing if it is not our plugin
		if( $slug !== $args->slug ) {
			return $res;
		}

		$res = new stdClass();
		
		/****************
		* FIX - PLUGIN INFO PARTS
		****************/

		$res->name = $name;
		$res->slug = $slug;		
		$res->requires_php = $requires_php;

		$res->author = '<a href="' . $url . '">' . WPHAVE_ADMIN_AUTHOR_NAME . '</a>';
		$res->author_profile = $url;			

		$res->banners = $banners;			
		$res->icons = $icons;

		$res->sections = array(
			//'description' => $description,
			'installation' => $installation,
			'changelog' => $changelog,
			// You can add your custom sections (tabs) here
		);

		// In case you want the screenshots tab, use the following HTML format for its content:
		// <ol><li><a href="IMG_URL" target="_blank"><img src="IMG_URL" alt="CAPTION" /></a><p>CAPTION</p></li></ol>
		if( ! empty( $remote['sections']['screenshots'] ) ) {
			$res->sections['screenshots'] = $remote['sections']['screenshots'];
		}
		
		/****************
		* REMOTE - PLUGIN INFO PARTS
		****************/
		
		// Access the update server
		$remote = wphave_admin_update_remote( $slug );

		// Check we have access to the update JSON file from the wphave update server
		if( $remote ) {

			$remote = json_decode( $remote['body'], true );
			$remote = $remote[$slug];			
			
			$res->version = $remote['version']; // --> Latest plugin version
			$res->tested = $remote['tested']; // --> Tested up to WordPress version
			$res->requires = $remote['requires']; // --> Required WordPress version
			$res->download_link = $remote['download_url']; // --> Download link to plugin package
			$res->last_updated = $remote['last_updated']; // --> Date of the latest plugin update

		}

		return $res;

	}

endif;

add_filter('plugins_api', 'wphave_admin_auto_update_plugin_info', 20, 3);


/*
 *******************
 * UPDATE IS AVAILABLE CHECK
 *******************
 *
 *	Function to check if there is a new plugin version available for download.
 *
 *  @type	function
 *  @date	06/18/19
 *  @since	2.0
 *
 *  @param	N/A
 *  @return	N/A
 *
*/

if ( ! function_exists( 'wphave_admin_new_version_is_available' ) ) :

	function wphave_admin_new_version_is_available( $transient ) {

		// Get plugin informations
		$plugin = wphave_admin_update_info();
		
		$slug = $plugin['slug'];
		$path = $plugin['path'];
		$url = $plugin['url'];
		$icons = $plugin['icons'];
		$banners = $plugin['banners'];
		
		// Get the current installed version number of the plugin
		$current_version = $plugin['version'];

		// Get the current installed version number from plugin check or from plugin information
		$current_version = isset( $transient->checked[$path] ) ? $transient->checked[$path] : $current_version;
		
		/****************
		* UPDATE AVAILABLE
		****************/
		
		// Access the update server
		$remote = wphave_admin_update_remote( $slug );
		
		// Check we have access to the update JSON file from the wphave update server
		if( $remote ) {

			$remote = json_decode( $remote['body'], true );
			$remote = $remote[$slug];

			// Compare the current / latest plugin version + the current / required WordPress version
			if( $remote && version_compare( $current_version, $remote['version'], '<' ) && version_compare( get_bloginfo('version'), $remote['requires'], '>=' ) ) {							
				
				$response = (object) array(
					'id' => $path,
					'slug' => $slug,
					'plugin' => $path,
					'new_version' => $remote['version'],
					'url' => $url,
					'package' => $remote['download_url'],
					'icons' => $icons,
					'banners' => $banners,
					'banners_rtl' => array(),
					'requires' => $remote['requires'],
					'tested' => $remote['tested'],
				);				
				
				// NEW UPDATE (new version) available				
				return $response;				
				
			}

		}
		
		/****************
		* NO !!! UPDATE AVAILABLE
		****************/
		
		// NO !!! UPDATE (new version) available
		return false;	

	}

endif;


/*
 *******************
 * ENABLE WORDPRESS UPDATES API
 *******************
 *
 *	Filter to support the WordPress core updates API. This means the user can "Enable" or "Disable" auto updates by himself.
 *	@ https://make.wordpress.org/core/2020/07/30/recommended-usage-of-the-updates-api-to-support-the-auto-updates-ui-for-plugins-and-themes-in-wordpress-5-5/
 *
 *  @type	filter
 *  @date	06/18/19
 *  @since	2.0
 *
 *  @param	N/A
 *  @return	N/A
 *
*/

if ( ! function_exists( 'wphave_admin_support_auto_update_api' ) ) :

	function wphave_admin_support_auto_update_api( $transient ) {
		
		if( ! is_object( $transient ) ) {
			return $transient;
		}		
		
		if( ! isset( $transient->response ) || ! is_array( $transient->response ) ) {
			$transient->response = array();
		}
		
		// Get plugin informations
		$plugin = wphave_admin_update_info();

		$slug = $plugin['slug'];
		$path = $plugin['path'];
		$current_version = $plugin['version'];
		$url = $plugin['url'];
		$package = $plugin['package'];
		$icons = $plugin['icons'];
		$banners = $plugin['banners'];
		$requires = $plugin['requires'];

		/****************
		* UPDATE AVAILABLE
		****************/

		// Check if a new version of the plugin in available for update
		$update = wphave_admin_new_version_is_available( $transient );
		
		if( $update ) {

			// $update should be an array containing all of the fields in $response below.
			$transient->response[$path] = $update;
			
			/*
			error_log( print_r( $transient, true ) );
			*/
			
			// NEW UPDATE (new version) is available
			return $transient;
			
		}
		
		/****************
		* NO !!! UPDATE AVAILABLE
		****************/

		$response = (object) array(
			'id'            => $path,
			'slug'          => $slug,
			'plugin'        => $path,
			'new_version'   => $current_version,
			'url'           => $url,
			'package'       => $package,
			'icons'         => $icons,
			'banners'       => $banners,
			'banners_rtl'   => array(),
			'requires'  	=> $requires,
		);

		// Adding the "mock" response to the `no_update` property is required for the enable/disable auto-updates links to correctly appear in UI.
		$transient->no_update[$path] = $response;
		
		/*
		error_log( print_r( $transient, true ) );
		*/
		
		// NO !!! UPDATE (new version) is available
		return $transient;

	}

endif;
 
add_filter( 'pre_set_site_transient_update_plugins', 'wphave_admin_support_auto_update_api' );


/*
 *******************
 * SHOW NOTICE IF WORDPRESS UPDATES API IS NOT SUPPORTED
 *******************
 *
 *	If we can't support the WordPress update API, we can instead send a notification to let the user know.
 * 	@ https://make.wordpress.org/core/2020/07/15/controlling-plugin-and-theme-auto-updates-ui-in-wordpress-5-5/
 *
 *  @type	filter
 *  @date	06/18/19
 *  @since	2.0
 *
 *  @param	N/A
 *  @return	N/A
 *
*/

/*
if ( ! function_exists( 'wphave_admin_auto_update_not_available_info' ) ) :

	function wphave_admin_auto_update_not_available_info( $html, $plugin_file, $plugin_data ) {

		// Get plugin informations
		$plugin = wphave_admin_update_info();

		$path = $plugin['path'];

		if( $path === $plugin_file ) {
			$html = __( 'Auto-updates are not available for this plugin.', 'wphave-admin' );
		}

		return $html;

	}

endif;

add_filter( 'plugin_auto_update_setting_html', 'wphave_admin_auto_update_not_available_info', 10, 3 );
*/


/*
 *******************
 * ADD PLUGIN UPDATE FUNCTIONALITY
 *******************
 *
 *	Add the possibility to allow users to update the plugin via the WordPress plugins screen.
 *	@ https://gist.github.com/danielbachhuber/7684646
 *
 *  @type	filter
 *  @date	06/18/19
 *  @since	2.0
 *
 *  @param	N/A
 *  @return	N/A
 *
*/

if ( ! function_exists( 'wphave_admin_push_auto_update_process' ) ) :

	function wphave_admin_push_auto_update_process( $transient ) {
		
		if( ! is_object( $transient ) ) {
			return $transient;
		}		
		
		if( ! isset( $transient->response ) || ! is_array( $transient->response ) ) {
			$transient->response = array();
		}
		
		// Get plugin informations
		$plugin = wphave_admin_update_info();

		// Get the plugin path
		$path = $plugin['path'];		
		
		// Check if a new version of the plugin in available for update
		$update = wphave_admin_new_version_is_available( $transient );		
		
		/****************
		* UPDATE AVAILABLE
		****************/
		
		if( $update ) {
			
			$transient->response[$path] = $update;
			
			/*
			error_log( print_r( $transient, true ) );
			*/
			
			// NEW UPDATE (new version) is available
			return $transient;
			
		}
		
		/****************
		* NO !!! UPDATE AVAILABLE
		****************/
		
		/*
		error_log( print_r( $transient, true ) );
		*/
		
		// NO !!! UPDATE (new version) is available
		return $transient;
		
	}

endif;

add_filter('site_transient_update_plugins', 'wphave_admin_push_auto_update_process', 99 ); // <-- ! Notice: Priority should be higher than the priority of the wphave_admin_disable_plugin_update_notice() update process.
add_filter('transient_update_plugins', 'wphave_admin_push_auto_update_process' );


/*
 *******************
 * DISABLE WORDPRESS PLUGIN UPDATE NOTICES
 *******************
 *
 *  In case the official WordPress repo lists a plugin with the same name as the assigned plugin. 
 *	This filter prevents false update notices about another plugin from being displayed and thus falsely overwriting the plugin.
 *
 *  @type	filter
 *  @date	06/18/19
 *  @since	2.0
 *
 *  @param	N/A
 *  @return	N/A
 *
*/

if ( ! function_exists( 'wphave_admin_disable_plugin_update_notice' ) ) :

	function wphave_admin_disable_plugin_update_notice( $value ) { 

		// Disable the update notice for the following theme assigned plugins
		$pluginsToDisable = array(
			'wphave-admin/wphave-admin.php',
		);
		
		if( isset( $value ) && is_object( $value ) ) {
			foreach( $pluginsToDisable as $plugin ) {
				if( isset( $value->response[$plugin] ) ) {
					unset( $value->response[$plugin] );
				}
			}
		}
		
		return $value;

	}

endif;

add_filter( 'site_transient_update_plugins', 'wphave_admin_disable_plugin_update_notice', 12 ); // <-- ! Notice: Priority should be less than the priority of the wphave_admin_push_auto_update_process() update process.


/*
 *******************
 * CLEAR CACHE AFTER AUTO-UPDATE PROCESS
 *******************
 *
 *	Function to clear the WordPress transient cache after the new plugin version is successfully installed.
 *
 *  @type	filter
 *  @date	06/18/19
 *  @since	2.0
 *
 *  @param	N/A
 *  @return	N/A
 *
*/

if ( ! function_exists( 'wphave_admin_after_auto_update_process' ) ) :

	function wphave_admin_after_auto_update_process( $upgrader_object, $options ) {
		
		if( $options['action'] === 'update' && $options['type'] === 'plugin' ) {
			
			// Clean the cache if a new plugin version is installed
			delete_transient( "wphave_update_flag" );
			
		}
		
	}

endif;

add_action( 'upgrader_process_complete', 'wphave_admin_after_auto_update_process', 10, 2 );