<?php
/**
 * This file belongs to the YIT Plugin 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
 *
 * @author  YITH
 * @package YITH License & Upgrade Framework
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
} // Exit if accessed directly

if ( ! class_exists( 'YITH_Licence' ) ) {
	/**
	 * YIT Licence Panel
	 * Setting Page to Manage Products
	 *
	 * @class      YITH_Licence
	 * @since      1.0
	 * @author     Andrea Grillo      <andrea.grillo@yithemes.com>
	 * @package    YITH
	 */
	abstract class YITH_Licence {

		/**
		 * The registered products info
		 *
		 * @since 1.0
		 * @var mixed array
		 */
		protected $products = array();

		/**
		 * The settings require to add the submenu page "Activation"
		 *
		 * @since 1.0
		 * @var array
		 */
		protected $settings = array();

		/**
		 * Option name
		 *
		 * @since 1.0
		 * @var string
		 */
		protected $licence_option = 'yit_products_licence_activation';

		/**
		 * The yithemes licence api uri
		 *
		 * @since 1.0
		 * @var string
		 */
		protected $api_uri = 'https://licence.yithemes.com/api/';

		/**
		 * The yithemes api uri query args
		 *
		 * @since 1.0
		 * @var string
		 */
		protected $api_uri_query_args = '%request%';

		/**
		 * The yithemes api uri query args
		 *
		 * @since 1.0
		 * @var string
		 */
		public $version = '1.0.0';

		/**
		 * The product type
		 *
		 * @since 1.0
		 * @var string
		 */
		protected $product_type = 'product';

		/**
		 * Constructor
		 *
		 * @since    1.0
		 * @author   Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public function __construct() {
			$plugin_version   = get_file_data( plugin_dir_path( __DIR__ ) . '/init.php', array( 'version' ) );
			$this->version    = ! empty( $plugin_version ) ? $plugin_version[0] : '1.0.0';
			$is_debug_enabled = defined( 'YIT_LICENCE_DEBUG' ) && YIT_LICENCE_DEBUG;
			if ( $is_debug_enabled ) {
				$this->api_uri = defined( 'YIT_LICENCE_DEBUG_LOCALHOST' ) ? YIT_LICENCE_DEBUG_LOCALHOST : 'https://staging-licenceyithemes.kinsta.cloud/api/';
				add_filter( 'block_local_requests', '__return_false' );
			}

			/* Style adn Script */
			add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );

			// load from theme folder...
			load_textdomain( 'yith-plugin-upgrade-fw', get_template_directory() . '/core/plugin-upgrade/languages/yith-plugin-upgrade-fw-' . apply_filters( 'plugin_locale', get_locale(), 'yith-plugin-upgrade-fw' ) . '.mo' )

			// ...or from plugin folder
			|| load_textdomain( 'yith-plugin-upgrade-fw', dirname( __DIR__ ) . '/languages/yith-plugin-upgrade-fw-' . apply_filters( 'plugin_locale', get_locale(), 'yith-plugin-upgrade-fw' ) . '.mo' );

			if ( function_exists( 'yith_plugin_fw_add_requirements' ) ) {
				yith_plugin_fw_add_requirements( __( 'YITH License Activation', 'yith-plugin-fw' ), array( 'min_tls_version' => '1.2' ) );
			}
		}

		/**
		 * Premium products registration
		 *
		 * @param string $init       The products identifier.
		 * @param string $secret_key The secret key.
		 * @param string $product_id The product id.
		 *
		 * @return void
		 * @since    1.0
		 * @author   Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		abstract public function register( $init, $secret_key, $product_id );

		/**
		 * Get protected array products
		 *
		 * @return array
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function get_products() {
			return $this->products;
		}

		/**
		 * Get The home url without protocol
		 *
		 * @return string The home url.
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function get_home_url() {
			$home_url = home_url();
			$schemes  = array( 'https://', 'http://', 'www.' );

			foreach ( $schemes as $scheme ) {
				$home_url = str_replace( $scheme, '', $home_url );
			}

			if ( false !== strpos( $home_url, '?' ) ) {
				list( $base, $query ) = explode( '?', $home_url, 2 );

				$home_url = $base;
			}

			return untrailingslashit( $home_url );
		}

		/**
		 * Check if the request is ajax
		 *
		 * @return bool true if the request is ajax, false otherwise.
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function is_ajax() {
			return defined( 'DOING_AJAX' ) && DOING_AJAX ? true : false;
		}

		/**
		 * Admin Enqueue Scripts
		 *
		 * @return void
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function admin_enqueue_scripts() {
			$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';

			// Support to YIT Framework < 2.0.
			$style_path                  = plugin_dir_url( __DIR__ );
			$script_path                 = $style_path;
			$current_plugin_upgrade_path = plugin_dir_path( __DIR__ );

			if ( false !== strpos( $current_plugin_upgrade_path, 'wp-content/themes' ) ) {
				// If no files in current plugin url try to search it in theme.
				$style_path  = get_template_directory_uri() . '/theme/plugins/yit-framework/plugin-upgrade/';
				$script_path = $style_path;
			}

			/* Register select2 stylesheet */
			if ( ! wp_style_is( 'select2', 'registered' ) ) {
				$is_wc_enabled   = function_exists( 'WC' );
				$base_path       = $is_wc_enabled ? WC()->plugin_url() . '/' : $style_path;
				$select2_version = $is_wc_enabled ? WC()->version : $this->version;
				wp_register_style( 'select2', $base_path . 'assets/css/select2.css', array(), $select2_version );
			}
			/* Register select2 scripts */
			if ( ! wp_script_is( 'wc-enhanced-select', 'registered' ) ) {
				if ( ! wp_script_is( 'selectWoo', 'registered' ) ) {
					wp_register_script( 'selectWoo', $script_path . 'assets/js/selectWoo/selectWoo.full' . $suffix . '.js', array( 'jquery' ), $this->version, true );
				}

				$deps = array( 'jquery', 'selectWoo' );
				wp_register_script( 'wc-enhanced-select', $script_path . 'assets/js/wc-enhanced-select/wc-enhanced-select' . $suffix . '.js', $deps, $this->version, true );
			}

			wp_register_script( 'yit-license-utils', $script_path . 'assets/js/yit-license-utils' . $suffix . '.js', array( 'jquery' ), $this->version, true );
			wp_register_script( 'yit-licence', $script_path . 'assets/js/yit-licence' . $suffix . '.js', array( 'jquery', 'wc-enhanced-select', 'yit-license-utils' ), $this->version, true );
			wp_register_style( 'yit-theme-licence', $style_path . 'assets/css/yit-licence.css', array( 'yit-plugin-style' ), $this->version );

			wp_register_style( 'yith-plugin-upgrade-license-banner', $style_path . 'assets/css/license-banner.css', array(), $this->version );
			wp_register_script( 'yith-plugin-upgrade-license-modal', $script_path . 'assets/js/license-modal' . $suffix . '.js', array( 'jquery', 'yith-ui' ), $this->version, true );

			/* Localize Scripts */
			wp_localize_script(
				'yit-licence',
				'licence_message',
				array(
					// translators: %s stand for the field name.
					'error'                      => sprintf( esc_html_x( 'Please, insert a valid %s', '%s = field name', 'yith-plugin-upgrade-fw' ), '%field%' ),
					// translators: %1$s and %2$s stand for the field names.
					'errors'                     => sprintf( esc_html__( 'Please, insert a valid %1$s and a valid %2$s', 'yith-plugin-upgrade-fw' ), '%field_1%', '%field_2%' ),
					'be_sure'                    => esc_html_x( 'Be sure you entered the e-mail used for your order in YITH', 'error message for activation panel', 'yith-plugin-upgrade-fw' ),
					'server'                     => esc_html__( 'Unable to contact remote server: this occurs when there are issues with connecting to our own servers. Trying again after a few minutes should solve the issue. If the problem persists please submit a support ticket and we will be happy to help you.', 'yith-plugin-upgrade-fw' ),
					'email'                      => esc_html__( 'email address', 'yith-plugin-upgrade-fw' ),
					'license_key'                => esc_html__( 'license key', 'yith-plugin-upgrade-fw' ),
					'are_you_sure'               => esc_html__( 'Are you sure you want to deactivate the license for current site?', 'yith-plugin-upgrade-fw' ),
					'choose_the_plugin_singular' => esc_html( _nx( 'Plugin', 'Choose the plugin', 1, 'Form Label', 'yith-plugin-upgrade-fw' ) ),
					'choose_the_plugin_plural'   => esc_html( _nx( 'Plugin', 'Choose the plugin', 2, 'Form Label', 'yith-plugin-upgrade-fw' ) ),
				)
			);

			$ajax_url = admin_url( 'admin-ajax.php', 'relative' );

			// translators: You can find the License e-mail and the License key in your License & Download page.
			$modal_description_text = esc_html__( 'You can find the License e-mail and the License key in your', 'yith-plugin-upgrade-fw' );
			// translators: My account section name. Use the same translation of the yithemes.com webiste.
			$license_and_download     = esc_html_x( 'Licenses and Downloads page >', 'yithemes.com webiste section', 'yith-plugin-upgrade-fw' );
			$license_and_download_url = 'https://yithemes.com/my-account/recent-downloads/';
			$modal_description        = sprintf( '<div class="yith-license-modal-description">%s <a href="%s" target="_blank" rel="nofollow noopener">%s</a></div>', $modal_description_text, $license_and_download_url, $license_and_download );
			$modal_image_src          = $script_path . 'assets/images/license-and-downloads.png';
			// translators: Button label, use a short text please.
			$cta_text      = esc_html_x( 'Go to your Licenses page', 'Button text', 'yith-plugin-upgrade-fw' );
			$cta           = sprintf( '<a href="%s" target="_blank" rel="nofollow noopener" class="yith-license-modal-cta-link yith-plugin-fw__button--primary yith-plugin-fw__button--xxl">%s</a>', $license_and_download_url, $cta_text );
			$modal_image   = sprintf( '<div class="yith-license-modal-image"><img src="%s" /></div>', $modal_image_src );
			$modal_content = $modal_description . $modal_image;

			$yith_license_utils_i18n = array(
				'ajax_url' => $ajax_url,
				'modal'    => array(
					// translators: Modal title. Shown on activation license page to help the customer to find the license information.
					'title'   => esc_html__( 'Where to find the e-mail and license ?', 'yith-plugin-upgrade-fw' ),
					'content' => $modal_content,
					'footer'  => $cta,
				),
			);

			wp_localize_script( 'yit-licence', 'script_info', array( 'is_debug' => defined( 'YIT_LICENCE_DEBUG' ) && YIT_LICENCE_DEBUG ) );
			wp_localize_script( 'yit-licence', 'yith_ajax', array( 'url' => $ajax_url ) );
			wp_localize_script( 'yit-license-utils', 'yith_license_utils', $yith_license_utils_i18n );

			/* Enqueue Scripts only in Licence Activation page of plugins and themes */
			$current_screen = get_current_screen();
			if ( $current_screen && ( strpos( $current_screen->id, 'yith_plugins_activation' ) !== false || strpos( $current_screen->id, 'yit_panel_license' ) !== false ) ) {
				wp_enqueue_script( 'yit-licence' );
				wp_enqueue_style( 'yit-theme-licence' );
				wp_enqueue_style( 'yith-plugin-fw-fields' );
				wp_enqueue_style( 'select2' );
			}
		}

		/**
		 * Activate Plugins
		 * Send a request to API server to activate plugins
		 *
		 * @return void
		 * @use    wp_send_json
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function activate() {
			// phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
			$product_init = isset( $_REQUEST['product_init'] ) ? sanitize_text_field( $_REQUEST['product_init'] ) : '';
			$product      = $product_init ? $this->get_product( $product_init ) : false;
			$body         = false;
			$activated    = false;

			if ( $product ) {
				$args = array(
					'email'       => isset( $_REQUEST['email'] ) ? sanitize_email( $_REQUEST['email'] ) : '',
					'licence_key' => isset( $_REQUEST['licence_key'] ) ? sanitize_text_field( $_REQUEST['licence_key'] ) : '',
					'product_id'  => isset( $product['product_id'] ) ? sanitize_text_field( $product['product_id'] ) : '',
					'secret_key'  => isset( $product['secret_key'] ) ? sanitize_text_field( $product['secret_key'] ) : '',
					'instance'    => $this->get_home_url(),
					'request'     => 'activation',
				);

				$response = $this->do_request( $this->get_api_uri( 'activation' ), $args );

				if ( ! is_wp_error( $response ) ) {
					$body = json_decode( $response['body'] );
					$body = is_object( $body ) ? get_object_vars( $body ) : false;
				}

				if ( $body && is_array( $body ) ) {

					if ( isset( $body['activated'] ) && $body['activated'] ) {
						$license = array(
							'email'                => urldecode( $args['email'] ),
							'licence_key'          => $args['licence_key'],
							'licence_expires'      => $body['licence_expires'],
							'message'              => $body['message'],
							'activated'            => true,
							'activation_limit'     => $body['activation_limit'],
							'activation_remaining' => $body['activation_remaining'],
							'is_membership'        => isset( $body['is_membership'] ) ? $body['is_membership'] : false,
							'marketplace'          => isset( $body['marketplace'] ) ? $body['marketplace'] : 'yith',
						);

						$option[ $product['product_id'] ] = $license;
						$activated                        = true;

						/* === Check for other plugins activation === */
						$options                           = $this->get_licence();
						$options[ $product['product_id'] ] = $option[ $product['product_id'] ];

						update_option( $this->licence_option, $options );

						/* === Update Plugin Licence Information === */
						yith_plugin_fw_force_regenerate_plugin_update_transient();

						$licenses        = $this->get_licence();
						$info            = $licenses[ $product['product_id'] ];
						$info['init']    = $product_init;
						$info['licence'] = $license;
						$info            = array_merge( $info, $product );

						/* === Licence Activation Template === */
						$body['template']           = $this->show_activation_row( $info, true );
						$body['code']               = 200;
						$body['activation_message'] = $this->get_response_code_message( 200 );
					} else {
						$body['error'] = $this->get_error_message( ! empty( $body['code'] ) ? $body['code'] : 100 );
					}
				}

				if ( ! empty( $_REQUEST['debug'] ) ) {
					$body          = is_array( $body ) ? $body : array();
					$body['debug'] = array( 'response' => $response );
					if ( 'print_r' === $_REQUEST['debug'] ) {
						$body['debug'] = print_r( $body['debug'], true ); // phpcs:ignore
					}
				}

				do_action( "yith_{$this->product_type}_licence_check", $product_init, $activated, $this->product_type );
			}

			wp_send_json( $body );
			// phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		}

		/**
		 * Deactivate Plugins
		 * Send a request to API server to activate plugins
		 *
		 * @return void
		 * @use    wp_send_json
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function deactivate() {
			// phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
			$force_delete = ! empty( $_REQUEST['force_delete'] );
			$product_init = isset( $_REQUEST['product_init'] ) ? sanitize_text_field( $_REQUEST['product_init'] ) : '';
			$product      = $this->get_product( $product_init );
			$license      = $this->get_licence();
			$product_id   = isset( $_POST['product_id'] ) ? sanitize_text_field( $_POST['product_id'] ) : '';
			$body         = false;
			$changed      = false;

			if ( $product && $product_id ) {

				$args     = array(
					'email'       => sanitize_email( $license[ $product_id ]['email'] ),
					'licence_key' => sanitize_text_field( $license[ $product_id ]['licence_key'] ),
					'marketplace' => sanitize_text_field( $license[ $product_id ]['marketplace'] ),
					'product_id'  => sanitize_text_field( $product['product_id'] ),
					'secret_key'  => sanitize_text_field( $product['secret_key'] ),
					'instance'    => $this->get_home_url(),
					'request'     => 'deactivation',
				);
				$response = $this->do_request( $this->get_api_uri( 'deactivation' ), $args );

				if ( ! is_wp_error( $response ) ) {
					$body = json_decode( $response['body'] );
					$body = is_object( $body ) ? get_object_vars( $body ) : false;
				}

				if ( $body && is_array( $body ) ) {
					/* === Get License === */
					$options = $this->get_licence();
					if ( isset( $body['activated'] ) && ! $body['activated'] && ! isset( $body['error'] ) ) {
						$option[ $product['product_id'] ] = array(
							'activated'            => false,
							'email'                => urldecode( $args['email'] ),
							'licence_key'          => $args['licence_key'],
							'licence_expires'      => $body['licence_expires'],
							'message'              => $body['message'],
							'activation_limit'     => $body['activation_limit'],
							'activation_remaining' => $body['activation_remaining'],
							'is_membership'        => isset( $body['is_membership'] ) ? $body['is_membership'] : false,
							'marketplace'          => isset( $body['marketplace'] ) ? $body['marketplace'] : 'yith',
						);

						/* === Check for other plugins activation === */
						$options[ $product['product_id'] ] = $option[ $product['product_id'] ];

						/* === Update Plugin Licence Information === */
						yith_plugin_fw_force_regenerate_plugin_update_transient();

						$changed = update_option( $this->licence_option, $options );

						/* === Licence Activation Template === */
						$body['template'] = $this->show_activation_panel( $this->get_response_code_message( 'deactivated', array( 'instance' => $body['instance'] ) ) );
					} else {
						$body['error'] = $this->get_error_message( $body['code'] );

						if ( $force_delete && in_array( intval( $body['code'] ), array( 106, 107 ), true ) ) {
							$body['code'] = '999';
						}

						switch ( $body['code'] ) {
							/**
							 * Error Code List:
							 * 100 -> Invalid Request
							 * 101 -> Invalid licence key
							 * 102 -> Software has been deactivate
							 * 103 -> Exceeded maximum number of activations
							 * 104 -> Invalid instance ID
							 * 105 -> Invalid security key
							 * 106 -> Licence key has expired
							 * 107 -> Licence key has be banned
							 * 999 -> Remove entry from DB
							 * Only code 101, 106 and 107 have effect on DB during activation
							 * All error code have effect on DB during deactivation
							 */
							case '101':
							case '102':
							case '104':
							case '999':
								unset( $options[ $product['product_id'] ] );
								break;

							case '106':
								$options[ $product['product_id'] ]['activated']       = false;
								$options[ $product['product_id'] ]['message']         = $body['error'];
								$options[ $product['product_id'] ]['status_code']     = $body['code'];
								$options[ $product['product_id'] ]['licence_expires'] = $body['licence_expires'];
								break;

							case '107':
								$options[ $product['product_id'] ]['activated']   = false;
								$options[ $product['product_id'] ]['message']     = $body['error'];
								$options[ $product['product_id'] ]['status_code'] = $body['code'];
								break;
						}

						$changed = update_option( $this->licence_option, $options );

						/* === Licence Activation Template === */
						$deactivate_message = $this->get_response_code_message( 'deactivated' );
						$error_code_message = $this->get_error_message( $body['code'] );
						$message            = sprintf( '<strong>%s</strong>: %s', $deactivate_message, $error_code_message );
						$body['template']   = $this->show_activation_panel( $message );
						$body['activated']  = false;
					}
				}
			}

			if ( true === $changed ) {
				do_action( "yith_{$this->product_type}_licence_check", $product_init, false, $this->product_type );
			}

			wp_send_json( $body );
			// phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		}

		/**
		 * Check Plugins Licence. Send a request to API server to check if plugins is activated
		 *
		 * @param string  $product_init         The plugin init slug.
		 * @param boolean $regenerate_transient True to regenerate transient, false otherwise.
		 * @param boolean $force_check          True to force check, false otherwise.
		 *
		 * @return bool True if activated, false otherwise.
		 * @since  1.0
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public function check( $product_init, $regenerate_transient = true, $force_check = false ) {
			$changed    = false;
			$status     = false;
			$body       = false;
			$product    = $this->get_product( $product_init );
			$licence    = $this->get_licence();
			$product_id = isset( $product['product_id'] ) ? $product['product_id'] : false;

			if ( ! $product_id || ! isset( $licence[ $product_id ] ) ) {
				return false;
			}

			if ( ! $force_check && ! $this->is_check_needed( $licence[ $product_id ] ) ) {
				return ! empty( $licence[ $product_id ]['activated'] );
			}

			$args = array(
				'email'       => $licence[ $product_id ]['email'],
				'licence_key' => $licence[ $product_id ]['licence_key'],
				'product_id'  => $product_id,
				'secret_key'  => $product['secret_key'],
				'instance'    => $this->get_home_url(),
				'request'     => 'check',
			);

			$response = $this->do_request( $this->get_api_uri( 'check' ), $args, 'GET' );

			if ( ! is_wp_error( $response ) ) {
				$body = json_decode( $response['body'] );
				$body = is_object( $body ) ? get_object_vars( $body ) : false;
			}

			if ( $body && is_array( $body ) ) {
				if ( isset( $body['success'] ) && true === $body['success'] ) {

					/**
					 * Code 200 -> Licence key is valid
					 */
					$licence[ $product_id ]['status_code']          = '200';
					$licence[ $product_id ]['activated']            = $body['activated'];
					$licence[ $product_id ]['licence_expires']      = $body['licence_expires'];
					$licence[ $product_id ]['licence_next_check']   = time() + ( 12 * HOUR_IN_SECONDS );
					$licence[ $product_id ]['activation_remaining'] = $body['activation_remaining'];
					$licence[ $product_id ]['activation_limit']     = $body['activation_limit'];
					$licence[ $product_id ]['is_membership']        = isset( $body['is_membership'] ) ? $body['is_membership'] : false;

					$status = (bool) $body['activated'];

				} elseif ( isset( $body['code'] ) ) {

					switch ( $body['code'] ) {

						/**
						 * Error Code List:
						 * 100 -> Invalid Request
						 * 101 -> Invalid licence key
						 * 102 -> Software has been deactivate
						 * 103 -> Exceeded maximum number of activations
						 * 104 -> Invalid instance ID
						 * 105 -> Invalid security key
						 * 106 -> Licence key has expired
						 * 107 -> Licence key has be banned
						 * Only code 101, 106 and 107 have effect on DB during activation
						 * All error code have effect on DB during deactivation
						 */

						case '101':
						case '102':
						case '104':
							unset( $licence[ $product_id ] );
							break;

						case '106':
							$licence[ $product_id ]['activated']       = false;
							$licence[ $product_id ]['message']         = $body['error'];
							$licence[ $product_id ]['status_code']     = $body['code'];
							$licence[ $product_id ]['licence_expires'] = $body['licence_expires'];
							break;

						case '107':
							$licence[ $product_id ]['activated']   = false;
							$licence[ $product_id ]['message']     = $body['error'];
							$licence[ $product_id ]['status_code'] = $body['code'];
							break;
					}
				}

				/* === Update Plugin Licence Information === */
				$changed = update_option( $this->licence_option, $licence );

				if ( true === $changed ) {
					do_action( "yith_{$this->product_type}_licence_check", $product_init, $status, $this->product_type );
				}

				/* === Update Plugin Licence Information === */
				if ( $regenerate_transient ) {
					yith_plugin_fw_force_regenerate_plugin_update_transient();
				}
			}

			return $status;
		}

		/**
		 * Check if given licence needs to be checked
		 *
		 * @param array $licence The licence to check.
		 *
		 * @return boolean
		 * @since  3.1.18
		 * @author Francesco Licandro
		 */
		public function is_check_needed( $licence ) {
			if ( empty( $licence['licence_expires'] ) || $licence['licence_expires'] < time() || empty( $licence['licence_next_check'] ) || $licence['licence_next_check'] < time() ) {
				return true;
			}

			return false;
		}

		/**
		 * Check for licence update
		 *
		 * @param boolean $regenerate_transient True to regenerate transient, false otherwise.
		 * @param boolean $force_check          True to force check, false otherwise.
		 *
		 * @return void
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  2.5
		 * @use    YIT_Theme_Licence->check()
		 */
		public function check_all( $regenerate_transient = true, $force_check = false ) {
			foreach ( $this->products as $init => $info ) {
				$this->check( $init, $regenerate_transient, $force_check );
			}
		}

		/**
		 * Update Plugins Information
		 * Send a request to API server to check activate plugins and update the informations
		 *
		 * @return void
		 * @use    YIT_Theme_Licence->check()
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function update_licence_information() {
			/* Check licence information for alla products */
			$this->check_all( false, true );

			/* === Regenerate Update Plugins Transient === */
			yith_plugin_fw_force_regenerate_plugin_update_transient();

			do_action( 'yit_licence_after_check' );

			if ( $this->is_ajax() ) {
				$response['template'] = $this->show_activation_panel();
				wp_send_json( $response );
			}
		}

		/**
		 * Include activation page template
		 *
		 * @param string $notice The notice to show.
		 *
		 * @return mixed The contents of the output buffer and end output buffering.
		 * @since  1.0
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public function show_activation_panel( $notice = '' ) {

			$path = dirname( __DIR__ );

			if ( $this->is_ajax() ) {
				ob_start();
				require_once $path . '/templates/panel/activation/activation-panel.php';

				return ob_get_clean();
			} else {
				require_once $path . '/templates/panel/activation/activation-panel.php';
			}
		}

		/**
		 * Include activation page template
		 *
		 * @param array   $info          An array of info to show.
		 * @param boolean $use_buffering True to use buffering, false otherwise.
		 *
		 * @return mixed The contents of the output buffer and end output buffering.
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function show_activation_row( $info = array(), $use_buffering = false ) {

			$path = dirname( __DIR__ );
			if ( true === $use_buffering ) {
				ob_start();
				require $path . '/templates/panel/activation/activation-row.php';

				return ob_get_clean();
			} else {
				require $path . '/templates/panel/activation/activation-row.php';
			}
		}

		/**
		 * Get activated products
		 *
		 * @return array
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function get_activated_products() {
			$activated_products = array();
			$licence            = $this->get_licence();

			if ( is_array( $licence ) ) {
				foreach ( $this->products as $init => $info ) {
					if ( in_array( $info['product_id'], array_keys( $licence ), true ) && isset( $licence[ $info['product_id'] ]['activated'] ) && $licence[ $info['product_id'] ]['activated'] ) {
						$product[ $init ]            = $this->products[ $init ];
						$product[ $init ]['licence'] = $licence[ $info['product_id'] ];
						$activated_products[ $init ] = $product[ $init ];
					}
				}
			}

			return $activated_products;
		}

		/**
		 * Get to active products
		 *
		 * @return array
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function get_to_active_products() {
			return array_diff_key( $this->get_products(), $this->get_activated_products() );
		}

		/**
		 * Get no active products
		 *
		 * @return array
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function get_no_active_licence_key() {
			$unactive_products = $this->get_to_active_products();
			$licence           = $this->get_licence();
			$licence_key       = array();

			/**
			 * Remove banned licence key
			 */
			foreach ( $unactive_products as $init => $info ) {
				$product_id = $unactive_products[ $init ]['product_id'];
				if ( isset( $licence[ $product_id ]['activated'] ) && ! $licence[ $product_id ]['activated'] && isset( $licence[ $product_id ]['status_code'] ) ) {
					$status_code = $licence[ $product_id ]['status_code'];

					switch ( $status_code ) {
						case '106':
							$licence_key[ $status_code ][ $init ]            = $unactive_products[ $init ];
							$licence_key[ $status_code ][ $init ]['licence'] = $licence[ $product_id ];
							break;

						case '107':
							$licence_key[ $status_code ][ $init ]            = $unactive_products[ $init ];
							$licence_key[ $status_code ][ $init ]['licence'] = $licence[ $product_id ];
							break;
					}
				}
			}

			return $licence_key;
		}

		/**
		 * Get a specific product information
		 *
		 * @param string $init Product init file.
		 *
		 * @return mixed array
		 * @since  1.0
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public function get_product( $init ) {
			return isset( $this->products[ $init ] ) ? $this->products[ $init ] : false;
		}

		/**
		 * Get product product id information
		 *
		 * @param string $init Product init file.
		 *
		 * @return mixed array
		 * @since  1.0
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public function get_product_id( $init ) {
			return isset( $this->products[ $init ]['product_id'] ) ? $this->products[ $init ]['product_id'] : false;
		}

		/**
		 * Get Renewing uri
		 *
		 * @param string $licence_key The licence key to renew.
		 *
		 * @return mixed The renewing uri if licence_key exists, false otherwise.
		 * @since    1.0
		 * @author   Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public function get_renewing_uri( $licence_key ) {
			return ! empty( $licence_key ) ? str_replace( 'www.', '', $this->api_uri ) . '?renewing_key=' . $licence_key : false;
		}

		/**
		 * Get protected yithemes api uri
		 *
		 * @param string $request The request to set on uri.
		 *
		 * @return mixed array
		 * @since  1.0
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public function get_api_uri( $request ) {
			return str_replace( '%request%', $request, $this->api_uri . $this->api_uri_query_args );
		}

		/**
		 * Get the activation page url
		 *
		 * @return String The activation page url.
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function get_licence_activation_page_url() {
			return esc_url( add_query_arg( array( 'page' => $this->settings['page'] ), admin_url( 'admin.php' ) ) );
		}

		/**
		 * Get the licence information
		 *
		 * @return array The licence array.
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function get_licence() {
			return get_option( $this->licence_option );
		}

		/**
		 * Get the licence information
		 *
		 * @param string $code The error code.
		 * @param array  $args An array of response code arguments.
		 *
		 * @return string The error code message.
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  1.0
		 */
		public function get_response_code_message( $code, $args = array() ) {
			extract( $args ); // phpcs:ignore

			$messages = array(
				'100'         => __( 'Invalid Request', 'yith-plugin-upgrade-fw' ),
				'101'         => __( 'Matching license key not found. Be sure to use the email used for the order in YITH and the correct license serial number.', 'yith-plugin-upgrade-fw' ),
				'102'         => __( 'Software has been deactivated', 'yith-plugin-upgrade-fw' ),
				'103'         => __( 'Maximum number of license activations reached', 'yith-plugin-upgrade-fw' ),
				'104'         => __( 'Invalid instance ID', 'yith-plugin-upgrade-fw' ),
				'105'         => __( 'Invalid security key', 'yith-plugin-upgrade-fw' ),
				'106'         => __( 'License key has expired', 'yith-plugin-upgrade-fw' ),
				'107'         => __( 'License key has been revoked', 'yith-plugin-upgrade-fw' ),
				'108'         => __( 'This product is not included in your YITH Club Subscription Plan', 'yith-plugin-upgrade-fw' ),
				'200'         => sprintf( '<strong>%s</strong>! %s', __( 'Great', 'yith-plugin-upgrade-fw' ), __( 'License successfully activated', 'yith-plugin-upgrade-fw' ) ),
				'deactivated' => sprintf( '%s <strong>%s</strong>', __( 'License key deactivated for website', 'yith-plugin-upgrade-fw' ), isset( $instance ) ? $instance : '' ),
				'999'         => 999, // Local use only.
			);

			return isset( $messages[ $code ] ) ? $messages[ $code ] : false;
		}

		/**
		 * Get the licence information
		 *
		 * @param string $code The error code.
		 *
		 * @return string The error code message.
		 * @since  4.3.0
		 * @author Francesco Licandro
		 */
		public function get_error_message( $code ) {
			return __( 'Error', 'yith-plugin-upgrade-fw' ) . ': ' . $this->get_response_code_message( $code );
		}

		/**
		 * Get the product name to display
		 *
		 * @param string $product_name The product name.
		 *
		 * @return string the product name
		 * @since    2.2
		 * @author   Andrea Grillo <andrea.grillo@yithemes.com>
		 */
		public function display_product_name( $product_name ) {
			return str_replace(
				array(
					'for WooCommerce',
					'for WordPress',
					'YITH',
					'WooCommerce',
					'Premium',
					'Theme',
					'WordPress',
					'Plugin',
				),
				'',
				$product_name
			);
		}

		/**
		 * Get the number of membership products
		 *
		 * @return integer
		 * @author   Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since    2.2
		 */
		public function get_number_of_membership_products() {
			$activated_products            = $this->get_activated_products();
			$num_members_products_activate = 0;
			foreach ( $activated_products as $activated_product ) {
				if ( isset( $activated_product['licence']['is_membership'] ) && $activated_product['licence']['is_membership'] ) {
					$num_members_products_activate ++;
				}
			}

			return $num_members_products_activate;
		}

		/**
		 * Do requests to yithemes licence network
		 *
		 * @param string $url    Url to call.
		 * @param array  $body   The request body.
		 * @param string $method The request method.
		 *
		 * @return WP_Error|array wp_remote_request response
		 */
		protected function do_request( $url, $body = array(), $method = 'POST' ) {

			$request_args = array(
				'method'  => $method,
				'timeout' => 30,
			);

			if ( 'GET' === $method ) {
				$request_args['body'] = $body;
			} else {
				$request_args['body'] = wp_json_encode( $body );
			}

			$request_args = apply_filters( 'yith_plugin_fw_do_request_args', $request_args );
			$response     = wp_remote_request( $url, $request_args );

			if ( is_wp_error( $response ) || ( isset( $response['response'] ) && isset( $response['response']['code'] ) && floor( $response['response']['code'] / 100 ) >= 4 ) ) {
				$alternative_url = esc_url_raw( add_query_arg( $body, 'https://casper.yithemes.com/wc-api/software-api/' ) );
				$response        = wp_remote_get( $alternative_url, array( 'timeout' => 30 ) );
			}

			return $response;
		}

		/**
		 * Get the licence activations url
		 *
		 * @param string $plugin_slug The plugin slug.
		 *
		 * @return boolean
		 * @author Francesco Licandro
		 */
		public static function get_license_activation_url( $plugin_slug = '' ) {
			return false;
		}

		/**
		 * Get the licence  url
		 *
		 * @param string $product_id The product ID.
		 *
		 * @return boolean
		 * @author Francesco Licandro
		 */
		public function get_license_url( $product_id = '' ) {
			return false;
		}

		/**
		 * Get the license option name
		 *
		 * @return string license option name
		 * @author Andrea Grillo <andrea.grillo@yithemes.com>
		 * @since  4.1.15
		 */
		public function get_licence_option_name() {
			return $this->licence_option;
		}

		/**
		 * Get a template
		 *
		 * @param string $template The template.
		 * @param array  $args     Arguments.
		 */
		protected function get_template( $template, $args = array() ) {
			$_template_args = array(
				'template'  => $template,
				'base_path' => trailingslashit( dirname( __DIR__ ) ) . 'templates/',
			);

			if ( isset( $args['_template_args'] ) ) {
				unset( $args['_template_args'] );
			}

			$_template_args['template_path'] = $_template_args['base_path'] . $_template_args['template'];

			if ( file_exists( $_template_args['template_path'] ) ) {
				extract( $args ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
				include $_template_args['template_path'];
			}
		}
	}
}
