<?php
/*
 * This file belongs to the YIT Framework.
 *
 * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.gnu.org/licenses/gpl-3.0.txt
 */
if ( ! defined( 'ABSPATH' ) ) {
	exit;
} // Exit if accessed directly

if ( ! class_exists( 'YITH_Plugin_Upgrade' ) ) {
	/**
	 * YIT Upgrade
	 *
	 * Notify and Update plugin
	 *
	 * @class       YITH_Plugin_Upgrade
	 * @package     YITH
	 * @since       1.0
	 * @author      YITH
	 * @see         WP_Updater Class
	 */
	class YITH_Plugin_Upgrade {

		/**
		 * @var string XML notifier update
		 */
		protected $_remote_url = 'https://update.yithemes.com/plugin-xml.php';

		/**
		 * @var string api server url
		 */
		protected $_package_url = 'https://yithemes.com';

		/**
		 * @var array The registered plugins
		 */
		protected $_plugins = array();

		/**
		 * @var YIT_Upgrade The main instance
		 */
		protected static $_instance;

		/**
		 * Construct
		 *
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function __construct() {
			add_filter( 'upgrader_pre_download', array( $this, 'upgrader_pre_download' ), 10, 3 );
			add_action( 'update-custom_upgrade-plugin-multisite', array( $this, 'upgrade_plugin_multisite' ) );

			add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );

			$is_debug_enabled = defined( 'YIT_LICENCE_DEBUG' ) && YIT_LICENCE_DEBUG;
			if ( $is_debug_enabled ) {
				$this->_package_url = defined( 'YIT_LICENCE_DEBUG_LOCALHOST' ) ? YIT_LICENCE_DEBUG_LOCALHOST : 'http://dev.yithemes.com';
				add_filter( 'block_local_requests', '__return_false' );
			}

			add_action( 'install_plugins_pre_plugin-information', array(
				$this,
				'show_changelog_for_premium_plugins'
			) );
			add_action( 'wp_ajax_yith_plugin_fw_get_premium_changelog', array(
				$this,
				'show_changelog_for_premium_plugins'
			) );
		}
 
		/**
		 * Main plugin Instance
		 *
		 * @param $plugin_slug | string The plugin slug
		 * @param $plugin_init | string The plugin init file
		 *
		 * @return void
		 *
		 * @since  1.0
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public function register( $plugin_slug, $plugin_init ) {

			if ( ! function_exists( 'get_plugins' ) ) {
				include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
			}

			$plugins     = get_plugins();
			$plugin_info = $plugins[ $plugin_init ];

			$plugin = $this->_plugins[ $plugin_init ] = array(
				'info' => $plugin_info,
				'slug' => $plugin_slug,
			);

			$transient = 'yith_register_' . md5( $plugin_slug );
			if ( apply_filters( 'yith_register_delete_transient', false ) ) {
				delete_transient( $transient );
			}
			$info = get_transient( $transient );
			if ( false === $info || apply_filters( 'yith_register_delete_transient', false ) ) {
				$xml         = $this->get_remote_url( $plugin );
				$remote_xml  = wp_remote_get( $xml );

				$error = false;
				if ( ! is_wp_error( $remote_xml ) && isset( $remote_xml['response']['code'] ) && '200' == $remote_xml['response']['code'] ) {
					$plugin_remote_info = function_exists( 'simplexml_load_string' ) ? @simplexml_load_string( $remote_xml['body'] ) : false;
					if ( $plugin_remote_info ) {
						$info['Latest']    = (string) $plugin_remote_info->latest;
						$info['changelog'] = (string) $plugin_remote_info->changelog;
						if ( is_multisite() && current_user_can( 'update_plugins' ) ) {
							YITH_Plugin_Licence()->check( $plugin_slug, false );
						}
						set_transient( $transient, $info, DAY_IN_SECONDS );
					} else {
						$error = true;
						error_log( sprintf( 'SimpleXML error in %s:%s [plugin slug: %s]',
							__FILE__, __FUNCTION__, $plugin_slug ) );
					}
				} else {
					$error = true;
				}

				if ( $error ) {
					// If error, set empty value in the transient to prevent multiple requests
					$info = array( 'Latest' => '', 'changelog' => '' );
					set_transient( $transient, $info, HOUR_IN_SECONDS );
				}
			}

			$this->_plugins[ $plugin_init ]['info']['Latest']    = $info['Latest'];
			$this->_plugins[ $plugin_init ]['info']['changelog'] = $info['changelog'];

			/* === HOOKS === */
			if ( ! is_multisite() || is_plugin_active_for_network( $plugin_init ) ) {
				add_action( 'load-plugins.php', array( $this, 'remove_wp_plugin_update_row' ), 25 );
				add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
			} else if ( is_multisite() && current_user_can( 'update_plugins' ) ) {
				add_action( 'admin_enqueue_scripts', array( $this, 'multisite_updater_script' ) );
			}
		}

		/**
		 * Add the multisite updater scripts
		 *
		 * @return void
		 *
		 * @since    1.0
		 * @author   Andrea Grillo <andrea.grillo@yithemes.com>
		 * @return   bool
		 */
		public function multisite_updater_script() {
			/* === If class YITH_Plugin_Licence doesn't exists, no YITH plugins enabled === */
			if( ! function_exists( 'YITH_Plugin_Licence' ) ){
				return false;
			}

			$update_url = $changelogs = $details_url = array();
			$strings = array(
				'new_version'   => __( 'There is a new version of %plugin_name% available.', 'yith-plugin-upgrade-fw' ),
				'latest'        => __( 'View version %latest% details.', 'yith-plugin-upgrade-fw' ),
				'unavailable'   => __( 'Automatic update is unavailable for this plugin,', 'yith-plugin-upgrade-fw' ),
				'activate'      => __( 'please <a href="%activate_link%">activate</a> your copy of %plugin_name%.', 'yith-plugin-upgrade-fw' ),
				'update_now'    => __( 'Update now.', 'yith-plugin-upgrade-fw' ),
				'version_issue' => __( '<br/><b>Please note:</b> You are using a higher version than the latest available one. </em>Please, make sure you\'ve downloaded the latest version of <em>%plugin_name%</em> from the only <a href="https://yithemes.com" target="_blank">YITH official website</a>, specifically, from your <a href="https://yithemes.com/my-account/recent-downloads/" target="_blank">Downloads page</a>. This is the only way to be sure the version you are using is 100% malware-free.', 'yith-plugin-upgrade-fw' ),
			);

			foreach ( $this->_plugins as $init => $info ) {
				$update_url[ $init ]  = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin-multisite&plugin=' ) . $init, 'upgrade-plugin-multisite_' . $init );
				$details_url[ $init ] = admin_url( 'admin-ajax.php?action=yith_plugin_fw_get_premium_changelog&tab=plugin-information&plugin=' . $init . '&section=changelog&TB_iframe=true&width=640&height=662' );
			}

			$localize_script_args = array(
				'registered'             => $this->_plugins,
				'activated'              => YITH_Plugin_Licence()->get_activated_products(),
				'licence_activation_url' => YITH_Plugin_Licence()->get_licence_activation_page_url(),
				'update_url'             => $update_url,
				'details_url'            => $details_url,
				'strings'                => $strings,
			);
			$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';

			if( defined( 'YIT_CORE_PLUGIN_URL' ) ){
				yit_enqueue_script( 'yit-multisite-updater', YIT_CORE_PLUGIN_URL . '/assets/js/multisite-updater' . $suffix . '.js', array( 'jquery' ), false, true );
			}

			wp_localize_script( 'yit-multisite-updater', 'plugins', $localize_script_args );
		}

		public function admin_enqueue_scripts() {
			global $pagenow;
			if ( 'plugins.php' === $pagenow && defined( 'YIT_CORE_PLUGIN_URL' ) ) {
				$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
				wp_enqueue_style( 'yit-upgrader', YIT_CORE_PLUGIN_URL . '/assets/css/yit-upgrader.css' );
				wp_enqueue_script( 'yith-update-plugins', YIT_CORE_PLUGIN_URL . '/assets/js/yith-update-plugins' . $suffix . '.js', array( 'jquery' ), false, true );

				$update_plugins_localized = array(
					'ajax_nonce' => wp_create_nonce( 'updates' ),
					'ajaxurl'   => admin_url( 'admin-ajax.php', 'relative' ),
					'l10n'       => array(
						/* translators: %s: Plugin name and version */
						'updating' => _x( 'Updating %s...', 'plugin-fw', 'yith-plugin-upgrade-fw' ), // No ellipsis.
						/* translators: %s: Plugin name and version */
						'updated'  => _x( '%s updated!', 'plugin-fw', 'yith-plugin-upgrade-fw' ),
						/* translators: %s: Plugin name and version */
						'failed'   => _x( '%s update failed', 'plugin-fw', 'yith-plugin-upgrade-fw' ),
					),
				);

				wp_localize_script( 'yith-update-plugins', 'yith_plugin_fw', $update_plugins_localized );
			}
		}


		/**
		 * Main plugin Instance
		 *
		 * @static
		 * @return object Main instance
		 *
		 * @since  1.0
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public static function instance() {
			if ( is_null( self::$_instance ) ) {
				self::$_instance = new self();
			}

			return self::$_instance;
		}

		/**
		 * Delete the update plugins transient
		 *
		 * @return void
		 *
		 * @since  1.0
		 * @see    update_plugins transient and pre_set_site_transient_update_plugins hooks
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @deprecated From version 3.1.12
		 */
		public function force_regenerate_update_transient() {
			delete_site_transient( 'update_plugins' );
		}

		/**
		 * Check for plugins update
		 *
		 * If a new plugin version is available set it in the pre_set_site_transient_update_plugins hooks
		 *
		 * @param mixed $transient | update_plugins transient value
		 * @param bool $save | Default: false. Set true to regenerate the update_transient plugins
		 *
		 * @return mixed $transient | The new update_plugins transient value
		 *
		 * @since  1.0
		 * @see    update_plugins transient and pre_set_site_transient_update_plugins hooks
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public function check_update( $transient, $save = false ) {

			foreach ( $this->_plugins as $init => $plugin ) {
				$plugin_slug = $this->_plugins[ $init ]['slug'];
				$xml         = $this->get_remote_url( $plugin );
				$remote_xml  = wp_remote_get( $xml );

				if ( ! is_wp_error( $remote_xml ) && isset( $remote_xml['response']['code'] ) && '200' == $remote_xml['response']['code'] ) {

					$plugin_remote_info = function_exists( 'simplexml_load_string' ) ? @simplexml_load_string( $remote_xml['body'] ) : false;

					if ( $plugin_remote_info ) {
						$wrong_current_version_check = version_compare( $plugin['info']['Version'], $plugin_remote_info->latest, '>' );
						$update_available            = version_compare( $plugin_remote_info->latest, $plugin['info']['Version'], '>' );

						if ( ( $update_available || $wrong_current_version_check ) && ! isset( $transient->response[ $init ] ) ) {

							$package = YITH_Plugin_Licence()->check( $init ) ? $this->_package_url : null;

							$tested_up_to   = (string) str_replace( '.x', '', $plugin_remote_info->{"up-to"} );
							$tested_up_to   = preg_replace( '/-.*$/', '', $tested_up_to );
							$wp_version     = preg_replace( '/-.*$/', '', get_bloginfo( 'version' ) );

							if( strpos( $wp_version, $tested_up_to ) !== false ){
								$tested_up_to = $wp_version;
							}
							$obj                          = new stdClass();
							$obj->slug                    = (string) $init;
							$obj->new_version             = (string) $plugin_remote_info->latest;
							$obj->changelog               = (string) $plugin_remote_info->changelog;
							$obj->package                 = $package;
							$obj->plugin                  = $init;
							$obj->tested                  = $tested_up_to;

							if( ! empty( $plugin_remote_info->icons ) ){
								$obj->icons = (array) $plugin_remote_info->icons;
							}

							$transient->response[ $init ] = $obj;
						}

					} else {
						error_log( sprintf( 'SimpleXML error in %s:%s [plugin slug: %s]',
							__FILE__, __FUNCTION__, $plugin_slug ) );

						return $transient;
					}
				}
			}

			if ( $save ) {
				set_site_transient( 'update_plugins', $transient );
			}

			return $transient;
		}


		/**
		 * Retreive the remote url with query string args
		 *
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @return string the remote url
		 */
		public function get_remote_url( $plugin_info ) {

			$license = $is_membership_license = false;
			$slug    = isset( $plugin_info['slug'] ) ? $plugin_info['slug'] : false;

			if( function_exists( 'YITH_Plugin_Licence' ) && false !== $slug ){
				//Get license for YITH Plugins
				$enabled_license = YITH_Plugin_Licence()->get_licence();

				if( isset( $enabled_license[ $slug ]['activated'] ) && false !== $enabled_license[ $slug ]['activated'] ){
					if( isset( $enabled_license[ $slug ]['licence_key'] ) ){
						$license = $enabled_license[ $slug ]['licence_key'];
					}

					if( isset( $enabled_license[ $slug ]['is_membership'] ) ){
						$is_membership_license = $enabled_license[ $slug ]['is_membership'];
					}
				}
			}

			$args = array(
				'plugin'                => $slug,
				'instance'              => md5( $_SERVER['SERVER_NAME'] ),
				'license'               => $license,
				'is_membership_license' => $is_membership_license,
				'server_ip'             => isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : $_SERVER['REMOTE_ADDR'],
				'version'               => isset( $plugin_info['info']['Version'] ) ? $plugin_info['info']['Version'] : '1.0.0'
			);

			$args = apply_filters( 'yith_get_remove_url_args', $args );

			$url = add_query_arg( $args, $this->_remote_url );

			return $url;
		}
	}
}

if ( ! function_exists( 'YITH_Plugin_Upgrade' ) ) {
	/**
	 * Main instance of plugin
	 *
	 * @return YIT_Upgrade
	 * @since  1.0
	 * @author Andrea Grillo <andrea.grillo@yithemes.com>
	 */
	function YITH_Plugin_Upgrade() {
		return YITH_Plugin_Upgrade::instance();
	}
}

/**
 * Instance a YITH_Plugin_Upgrade object
 */
YITH_Plugin_Upgrade();
