<?php
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment

// Don't load directly
if (!defined('ABSPATH')) { exit; }

if (class_exists('R34ICS') && !class_exists('R34ICSProLicense')) {

	class R34ICSProLicense {
		
		public $plugin_slug = 'ics-calendar-pro';
		public $update_url = 'https://api.icscalendar.com/update.json.php';
		public $version = '';
		public $update_transient_key = 'r34icspro_update';
		public $update_use_transients = true;
		
		private $_dev_mode = false;
		private $_beta_updates = false;
		private $_beta_update_url = 'https://api.icscalendar.com/update-beta.json.php';
		private $_license_debug = false;
	
		public function __construct() {
		
			$this->version = get_option('r34icspro_version');
			
			// Set dev mode
			$this->_dev_mode = defined('R34ICSPRO_DEV_MODE');
			if (!empty($this->_dev_mode)) { $this->update_use_transients = false; }
				
			// Set beta updates
			$this->_beta_updates = get_option('r34icspro_beta_updates', defined('R34ICSPRO_BETA_UPDATES'));
			if (!empty($this->_beta_updates)) { $this->update_url = $this->_beta_update_url; }
			
			// Set license debug
			$this->_license_debug = get_option('r34icspro_license_debug', defined('R34ICSPRO_LICENSE_DEBUG'));
			
			// Add admin notices
			add_action('admin_notices', array(&$this, 'admin_notices'));
			
			// Initialize plugin updater
			// Based on: https://github.com/rudrastyh/misha-update-checker
			add_action('plugins_loaded', array(&$this, 'update_init'), 12);
	
		}
		
		
		public function admin_notices() {
			$current_screen = function_exists('get_current_screen') ? get_current_screen() : null;
		
			// Prepare deferred admin notices
			global $r34ics_deferred_admin_notices;
			if (empty($r34ics_deferred_admin_notices)) {
				$r34ics_deferred_admin_notices = get_option('r34ics_deferred_admin_notices', array());
			}
		
			// Only check the license on the Plugins and ICS Calendar screens
			if ($current_screen->base != 'plugins' && $current_screen->post_type != 'r34icspro_calendar') { return; }
			
			// Only show these to administrators!
			if (function_exists('r34ics_admin_full_access') && r34ics_admin_full_access()) {
			
				if (!empty($current_screen) && $current_screen->base == 'r34icspro_calendar_page_ics-calendar-pro-settings') {
					$license_link_open_tag = '<a href="#license">';
					$license_link_close_tag = '</a>';
				}
				else {
					$license_link_open_tag = '<a href="' . admin_url('edit.php?post_type=r34icspro_calendar&page=ics-calendar-pro-settings#license') . '">';
					$license_link_close_tag = '</a>';
				}
				
				// We've already determined that we can't connect to the license server so bail out now
				if (isset($r34ics_deferred_admin_notices['r34icspro_license_server_failure'])) { return; }
	
				// License has been modified -- needs to be re-entered
				if ($this->license_modified()) {
					unset($r34ics_deferred_admin_notices['r34icspro_license_expiring_soon']);
					$r34ics_deferred_admin_notices['r34icspro_license_configuration_changes_detected'] = array(
						'content' => '<p>' .
						sprintf(esc_html__('Due to detected site configuration changes, your %1$s license needs to be re-entered. Please check your order confirmation email or %2$slog into your account%3$s to obtain your license key, then %4$senter it here%5$s. Thank you!', 'ics-calendar-pro'), '<strong>ICS Calendar Pro</strong>', '<a href="https://icscalendar.com/my-account/api-keys/" target="_blank">', '</a>', $license_link_open_tag, $license_link_close_tag) .
						'</p>',
						'status' => 'error',
						'dismissible' => false,
					);
				}
				// Plugin is unlicensed
				elseif (!$this->licensed()) {
					// License has expired
					if ($this->license_expired()) {
						unset($r34ics_deferred_admin_notices['r34icspro_license_expiring_soon']);
						$r34ics_deferred_admin_notices['r34icspro_license_expired'] = array(
							'content' => '<p>' .
							sprintf(esc_html__('Your %1$s license has %2$sexpired%3$s. Please %4$srenew your license%5$s and update to the latest version (if available) to continue using this plugin. Existing calendars will continue to function, but you will no longer receive customer support or software updates, and access to some admin tools may be restricted without an active license. Thank you!', 'ics-calendar-pro'), '<strong>ICS Calendar Pro</strong>', '<strong style="color: var(--r34ics--color--ics-red);">', '</strong>', '<a href="https://icscalendar.com/shop/" target="_blank">', '</a>') .
							'</p>',
							'status' => 'error',
							'dismissible' => false,
						);
					}
					// No license exists
					else {
						unset($r34ics_deferred_admin_notices['r34icspro_license_expiring_soon']);
						$r34ics_deferred_admin_notices['r34icspro_unlicensed'] = array(
							'content' => '<p>' .
							sprintf(esc_html__('Your copy of %1$s is %2$sunlicensed%3$s. Without a valid license, some features will be limited, and you will not have access to plugin updates or support. %4$s If you have a license, please %5$senter it here%6$s. You can find your license key at: %7$s %8$s If you do not yet have a license, please purchase one at %9$s to continue using this plugin. Thank you!', 'ics-calendar-pro'), '<strong>ICS Calendar Pro</strong>', '<strong style="color: var(--r34ics--color--ics-red);">', '</strong>', '<br /><br />', $license_link_open_tag, $license_link_close_tag, '<a href="https://icscalendar.com/my-account/api-keys/" target="_blank">icscalendar.com/my-account/api-keys</a>', '<br /><br />', '<a href="https://icscalendar.com/shop/" target="_blank">icscalendar.com</a>') .
							'</p>',
							'status' => 'error',
							'dismissible' => false,
						);
					}
				}
				// Plugin is licensed
				else {
					// License is expiring soon
					$license_expires = $this->license_expires();
					$license_days_remaining = floor(abs(time() - $license_expires) / DAY_IN_SECONDS);
					if (!empty($license_expires) && $license_days_remaining < $this->_lwd) {
						$r34ics_deferred_admin_notices['r34icspro_license_expiring_soon'] = array(
							'content' => '<p>' .
							sprintf(esc_html__('Your %1$s license will expire in %2$s day(s)%3$s. Without a valid license, some features will be limited, and you will not have access to plugin updates or support. %4$s Please visit the %5$sLicense Keys%6$s page on our site and click the %7$sRenew%8$s button. %9$sRenew prior to your expiration date to receive a %10$s discount!%11$s', 'ics-calendar-pro'), '<strong>ICS Calendar Pro</strong>', '<strong>' . $license_days_remaining, '</strong>', '<br /><br />', '<a href="https://icscalendar.com/my-account/api-keys/" target="_blank">', '</a>', '<strong>', '</strong>', '<br /><br /><strong style="color: var(--r34ics--color--ics-red);">', wp_kses_post($this->_lrca), '</strong>') .
							'</p>',
							'status' => 'info',
							'dismissible' => false,
						);
					}
				}
			}		

			// Save deferred admin notices
			update_option('r34ics_deferred_admin_notices', $r34ics_deferred_admin_notices, false);
		}
	
		
		// Public wrapper methods
		public function delete_license() { return $this->_delete_license(); }
		public function get_license() { return $this->_get_license(); }
		public function license_expired() { return $this->_get_license() && !$this->_verify_license(); }
		public function licensed() { return $this->_get_license() && $this->_verify_license(); }
		public function set_license() { return $this->_set_license(); }
		public function verify_license() { return $this->_verify_license(); }
		
		
		public function license_debug($limited=false) {
			if (function_exists('r34ics_admin_full_access') && r34ics_admin_full_access()) {
				$license_data = array(
					'license' => $this->_get_license() ?: 'N/A',
					'status' => $this->_license_api_get_json('status') ?: 'unlicensed',
				);
				// Scrub sensitive data
				if (!empty($limited)) {
					// Mask license key
					if (isset($license_data['license']['key'])) {
						$license_data['license']['key'] = substr($license_data['license']['key'], 0, 4) . str_repeat('*', 32) . substr($license_data['license']['key'], -4);
					}
					// Remove license data that is repeated in resources list
					if (isset($license_data['license']['exp'])) { unset($license_data['license']['exp']); }
					if (isset($license_data['license']['product_id'])) { unset($license_data['license']['product_id']); }
					// Move non_wc_subs_resources from data to top level and remove 'non_wc_subs_'
					if (!empty($license_data['status']->data->api_key_expirations->non_wc_subs_resources)) {
						$license_data['resources'] = $license_data['status']->data->api_key_expirations->non_wc_subs_resources;
					}
					// Remove data
					if (isset($license_data['status']->data)) { unset($license_data['status']->data); }
				}
				// Append any saved diagnostics data
				if ($license_diagnostic_log = get_option('r34icspro_license_diagnostic_log')) {
					$license_data['log'] = $license_diagnostic_log;
				}
				return $license_data;
			}
			return false;
		}
		
		
		public function license_details($field=null) {
			if ($license = $this->_get_license()) {
				return (!empty($field) && isset($license[$field])) ? $license[$field] : $license;
			}
			return 'unlicensed';
		}
		
		
		public function license_expires($format='timestamp') {
			$license = $this->_get_license();
			$exp = null;
			switch ($format) {
				case 'display':
					if (empty($license)) { $exp = __('unlicensed', 'ics-calendar-pro'); }
					elseif ($license['exp'] == 0) { $exp = __('never', 'ics-calendar-pro'); }
					else { $exp = wp_date(get_option('date_format'), $license['exp']); }
					break;
				case 'timestamp':
				default:
					$exp = $license['exp']; break;
			}
			return $exp;
		}
		
		
		public function license_modified() {
			$modified = false;
			if ($license = $this->_get_license()) {
				// Compare license values with current site values
				// Multisite?
				if (function_exists('get_sites') && !empty($license['blog_id'])) { switch_to_blog($license['blog_id']); }
				if ($license['instance'] != get_option('r34icspro_instance')) { $modified = true; }
				elseif ($license['object'] != wp_parse_url(get_bloginfo('url'), PHP_URL_HOST)) { $modified = true; }
				if (!empty($license['blog_id'])) { restore_current_blog(); }
				// License has been modified! Delete it!
				if (!empty($modified)) {
					$this->_delete_license();
				}
			}
			return $modified;
		}
	
	
		public function update_init() {
			if ($license = $this->_get_license()) {
				$this->update_url .= '?licensed=' . $this->licensed() .
					'&api_key=' . @$license['key'] .
					'&instance=' . @$license['instance'] .
					'&product_id=' . @$license['product_id'];
			}
			add_filter('plugins_api', array(&$this, 'update_info'), 20, 3);
			add_filter('pre_set_site_transient_update_plugins', array(&$this, 'update_run'), 10, 1);
			add_action('upgrader_process_complete', array(&$this, 'update_purge'), 10, 2);
		}
		
		
		public function update_info($res, $action, $args) {
			if (@$action != 'plugin_information' || $this->plugin_slug != @$args->slug) { return $res; }
			return $this->update_request() ?: $res;
		}
		
		
		public function update_purge($upgrader, $options) {
			if ($this->update_use_transients && $options['action'] == 'update' && $options['type'] == 'plugin') {
				delete_transient($this->update_transient_key);
			}
		}
		
		
		public function update_request() {
			$update = get_transient($this->update_transient_key);
			if ($update == false || $this->update_use_transients == false) {
				if ($remote = wp_remote_get($this->update_url, array(
					'headers' => array('Accept' => 'application/json'),
					'sslverify' => false,
				))) {
					$update = json_decode(wp_remote_retrieve_body($remote));
					// Convert sub-objects to arrays so things like the "View details" lightbox don't break
					foreach ((array)$update as $key => $value) {
						if (is_object($value)) { $update->$key = (array)$value; }
					}
					set_transient($this->update_transient_key, $update, DAY_IN_SECONDS);
				}
			}
			return $update;
		}
		
		
		public function update_run($transient) {
			if (empty($transient->checked)) { return $transient; }
			$plugin = $this->plugin_slug . '/' . $this->plugin_slug . '.php';
			if ($remote = $this->update_request()) {
				// Build the response object
				$response = (object) array(
					'id' => $plugin,
					'slug' => $remote->slug,
					'plugin' => $plugin,
					'new_version' => $remote->version,
					'url' => $remote->homepage,
					'package' => $remote->download_url,
					'icons' => (array)@$remote->icons,
					'banners' => (array)@$remote->banners,
					'tested' => $remote->tested,
					'requires' => $remote->requires,
					'requires_php' => $remote->requires_php,
				);
				// A new version is available
				if (
					version_compare($this->version, @$remote->version, '<') &&
					version_compare($remote->requires, get_bloginfo('version'), '<=') &&
					version_compare($remote->requires_php, PHP_VERSION, '<=')
				) {
					$transient->response[$plugin] = $response;
				}
				// No new version
				else {
					$transient->no_update[$plugin] = $response;
				}
				$transient->checked[$plugin] = $this->version;
			}
			return $transient;
		}
		
		
		private function _delete_license() {
			$instance = get_option('r34icspro_instance');

			// Prepare deferred admin notices
			global $r34ics_deferred_admin_notices;
			if (empty($r34ics_deferred_admin_notices)) {
				$r34ics_deferred_admin_notices = get_option('r34ics_deferred_admin_notices', array());
			}

			// Collect diagnostics data
			if (!empty($this->_license_debug)) {
				$license_diagnostic_log = get_option('r34icspro_license_diagnostic_log', array());
			}

			if ($api_response = $this->_license_api_get_json('deactivate')) {
				if (!empty($api_response->success)) {
					unset($r34ics_deferred_admin_notices['r34icspro_license_expiring_soon']);
					if (!isset($r34ics_deferred_admin_notices['r34icspro_regenerate_instance'])) {
						$r34ics_deferred_admin_notices['r34icspro_license_decativated'] = array(
							'content' => '<p>' .
							sprintf(esc_html__('Your %1$s license has been deactivated.', 'ics-calendar-pro'), '<strong>ICS Calendar Pro</strong>') .
							'</p>',
							'status' => 'info',
							'dismissible' => false,
						);
						if (!empty($this->_license_debug)) {
							$license_diagnostic_log[r34ics_date('r')] = 'License deactivated (' . $instance . ')';
						}
					}
				}
				elseif (!empty($api_response->error)) {
					unset($r34ics_deferred_admin_notices['r34icspro_license_expiring_soon']);
					$r34ics_deferred_admin_notices['r34icspro_license_decativated_locally'] = array(
						'content' => '<p>' .
						sprintf(esc_html__('Your %1$s license has been deactivated locally. However, the licensing server returned an error:', 'ics-calendar-pro'), '<strong>ICS Calendar Pro</strong>') . '</p><p><code>' . wp_kses_post($api_response->error ?? '---') .
						'</code></p><p>' .
						sprintf(esc_html__('This may be due to the license activation having already been deleted on the server. Please log into %1$syour account%2$s if you have any concerns.', 'ics-calendar-pro'), '<a href="https://icscalendar.com/my-account/api-keys/" target="_blank">', '</a>') .
						'</p>',
						'status' => 'warning',
						'dismissible' => false,
					);
					if (!empty($this->_license_debug)) {
						$license_diagnostic_log[r34ics_date('r')] = 'Error: ' . wp_kses_post($api_response->error ?? '---', 'data');
					}
				}
				delete_option('r34icspro_license');
				delete_transient('R34ICSProLicense::_verify_license');
				// Handle multisite
				if (function_exists('get_sites') && $sites = get_sites()) {
					foreach ((array)$sites as $site) {
						switch_to_blog($site->blog_id);
						delete_option('r34icspro_license');
						delete_transient('R34ICSProLicense::_verify_license');
						restore_current_blog();
					}
				}
			}
			else {
				unset($r34ics_deferred_admin_notices['r34icspro_license_expiring_soon']);
				if (!isset($r34ics_deferred_admin_notices['r34icspro_regenerate_instance'])) {
					$r34ics_deferred_admin_notices['r34icspro_license_decativate_failure'] = array(
						'content' => '<p>' .
						sprintf(esc_html__('Could not retrieve license data. If this problem persists, please %1$scontact customer support%2$s.', 'ics-calendar-pro'), '<a href="https://icscalendar.com/support/" target="_blank">', '</a>') .
						'</p>',
						'status' => 'error',
						'dismissible' => false,
					);
					if (!empty($this->_license_debug)) {
						$license_diagnostic_log[r34ics_date('r')] = 'License deactivation error (no response)';
					}
				}
			}
			// Save deferred admin notices
			update_option('r34ics_deferred_admin_notices', $r34ics_deferred_admin_notices, false);
			
			// Save diagnostics data
			if (!empty($this->_license_debug)) {
				update_option('r34icspro_license_diagnostic_log', ($license_diagnostic_log ?? null), false);
			}
		}
		
		
		private function _get_api_request_url($action='status', $api_key='', $product_id='', $instance='', $object='') {
			// Use existing license data if not passed in
			if (empty($api_key) || empty($product_id) || empty($instance) || empty($object)) {
				if ($license = $this->_get_license()) {
					if (empty($api_key)) { $api_key = $license['key']; }
					if (empty($product_id)) { $product_id = $license['product_id']; }
					if (empty($instance)) { $instance = $license['instance']; }
					if (empty($object)) { $object = $license['object']; }
				}
			}
			return $this->_api_base_url .
				'&wc_am_action=' . rawurlencode(trim($action)) .
				'&api_key=' . rawurlencode(trim($api_key)) .
				'&product_id=' . rawurlencode(trim($product_id)) .
				'&instance=' . rawurlencode(trim($instance)) .
				'&object=' . rawurlencode(trim($object)) .
				'&plugin_name=ics-calendar-pro/ics-calendar-pro.php' .
				'&version=' . get_option('r34icspro_version');
		}
	
	
		private function _get_license() {
			$license = get_option('r34icspro_license');
			// Check multisite if no license found
			if (empty($license) && function_exists('get_sites') && $sites = get_sites()) {
				foreach ((array)$sites as $site) {
					switch_to_blog($site->blog_id);
					$license = get_option('r34icspro_license');
					restore_current_blog();
					if (!empty($license)) { break; }
				}
			}
			return !empty($license) ? unserialize(base64_decode($license)) : false;
		}
		
		
		private function _license_api_get_json($action, $api_key='', $product_id='', $instance='', $object='') {
			if (!empty($action)) {
				if ($license = $this->_get_license()) {
					if (empty($api_key)) { $api_key = $license['key']; }
					if (empty($product_id)) { $product_id = $license['product_id']; }
					if (empty($instance)) { $instance = $license['instance']; }
					if (empty($object)) { $object = $license['object']; }
				}
				// Simple test for API server access to bail out faster if the connection fails
				if ($this->_test_api_access()) {
					if (!empty($api_key) && !empty($product_id) && !empty($instance) && !empty($object)) {
						$api_request_url = $this->_get_api_request_url($action, $api_key, $product_id, $instance, $object);
						if ($api_json = $this->_url_get_contents($api_request_url)) {
							$api_response = json_decode($api_json);
							// Update expiration date if it has changed on server
							if (isset($license['exp']) && isset($api_response->data->resources[0]->access_expires) && $api_response->data->resources[0]->access_expires != $license['exp']) {
								$license['exp'] = $api_response->data->resources[0]->access_expires;
								update_option('r34icspro_license', base64_encode(serialize($license)), false);
							}
							return $api_response;
						}
					}
				}
			}
			return false;
		}
	
		
		private function _set_license() {
			delete_transient('R34ICSProLicense::_verify_license');

			// Prepare deferred admin notices
			global $r34ics_deferred_admin_notices;
			if (empty($r34ics_deferred_admin_notices)) {
				$r34ics_deferred_admin_notices = get_option('r34ics_deferred_admin_notices', array());
			}

			// Collect diagnostics data
			if (!empty($this->_license_debug)) {
				$license_diagnostic_log = get_option('r34icspro_license_diagnostic_log', array());
			}

			// Connect to API and activate license
			$api_key = filter_input(INPUT_POST, 'api_key', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
			$product_id = filter_input(INPUT_POST, 'product_id', FILTER_SANITIZE_NUMBER_INT);
			$instance = get_option('r34icspro_instance');
			$object = wp_parse_url(get_bloginfo('url'), PHP_URL_HOST);
			if ($api_response = $this->_license_api_get_json('activate', $api_key, $product_id, $instance, $object)) {
				if (!empty($api_response->success)) {
					$license = array(
						'key' => trim($api_key),
						'product_id' => intval($product_id),
						'instance' => trim($instance),
						'object' => trim($object),
						'exp' => trim($api_response->data->resources[0]->access_expires),
					);
					// Add blog_id to license if multisite
					if (function_exists('get_sites')) {
						$license['blog_id'] = get_current_blog_id();
					}
					update_option('r34icspro_license', base64_encode(serialize($license)), false);
					unset($r34ics_deferred_admin_notices['r34icspro_unlicensed']);
					$r34ics_deferred_admin_notices['r34icspro_licensed'] = array(
						'content' => '<p>' .
						sprintf(esc_html__('Your copy of %1$s is now licensed. All features are enabled and you will receive access to updates and support.', 'ics-calendar-pro'), '<strong>ICS Calendar Pro</strong> ') .
						'</p>',
						'status' => 'success',
						'dismissible' => 7,
					);
					if (!empty($this->_license_debug)) {
						$license_diagnostic_log[r34ics_date('r')] = 'License activated (' . $instance . ')';
					}
				}
				elseif (!empty($api_response->error)) {
					$r34ics_deferred_admin_notices['r34icspro_invalid_license_details'] = array(
						'content' => '<p>' . esc_html__('The licensing server returned the following error:', 'ics-calendar-pro') . '</p><p><code>' . wp_kses_post($api_response->error ?? '---') . '</code></p>',
						'status' => 'error',
						'dismissible' => false,
					);
					if (!empty($this->_license_debug)) {
						$license_diagnostic_log[r34ics_date('r')] = 'Error: ' . wp_kses($api_response->error ?? '---', 'data');
					}
				}
			}
			else {
				$r34ics_deferred_admin_notices['r34icspro_license_no_response'] = array(
					'content' => '<p>' .
					sprintf(esc_html__('An error occurred while attempting to connect to the licensing server. %1$sPlease verify that you have filled in both your Product ID and License Key in the form.%2$s If the problem persists, please %3$scontact support%4$s for assistance.', 'ics-calendar-pro'), '<strong>', '</strong><br />', '<a href="https://icscalendar.com/support/" target="_blank">', '</a>') .
					'</p>',
					'status' => 'error',
					'dismissible' => false,
				);
				if (!empty($this->_license_debug)) {
					$license_diagnostic_log[r34ics_date('r')] = 'No response/missing data';
				}
			}
			
			// Save deferred admin notices
			update_option('r34ics_deferred_admin_notices', $r34ics_deferred_admin_notices, false);
			
			// Save diagnostics data
			if (!empty($this->_license_debug)) {
				update_option('r34icspro_license_diagnostic_log', ($license_diagnostic_log ?? null), false);
			}
		}
		
		
		private function _test_api_access() {
			$status = strlen($this->_url_get_contents($this->_api_readme_url)) > 0;
			if (empty($status)) {

				// Prepare deferred admin notices
				global $r34ics_deferred_admin_notices;
				if (empty($r34ics_deferred_admin_notices)) {
					$r34ics_deferred_admin_notices = get_option('r34ics_deferred_admin_notices', array());
				}

				$r34ics_deferred_admin_notices['r34icspro_license_server_failure'] = array(
					'content' => '<p>' .
					sprintf(esc_html__('%1$s%2$s could not connect to the license server to verify your license.%3$s Some features may be limited temporarily. %4$s If this problem persists, please check that your %5$slicense key%6$s is entered correctly.', 'ics-calendar-pro'), '<strong>', 'ICS Calendar Pro', '</strong>', '<br /><br />', '<a href="' . admin_url('edit.php?post_type=r34icspro_calendar&page=ics-calendar-pro-settings#license') . '">', '</a>') .
					'</p>',
					'status' => 'warning',
					'dismissible' => false,
				);

				// Save deferred admin notices
				update_option('r34ics_deferred_admin_notices', $r34ics_deferred_admin_notices, false);
			}
			return $status;
		}
		
		
		/**
		 * Retrieve file from remote server (previous cURL/fopen methods replaced with wp_remote_get() in version 4.11.0)
		 */
		private function _url_get_contents($url) {
			$url_contents = '';
			if ($url = filter_var($url, FILTER_SANITIZE_URL)) {
				// Sanitize/validate URL
				$url_parsed = wp_parse_url($url);
				if	(
							!filter_var($url, FILTER_VALIDATE_URL) ||
							!wp_http_validate_url($url) ||
							!in_array($url_parsed['scheme'], array('http', 'https')) ||
							(
								filter_var($url_parsed['host'], FILTER_VALIDATE_IP) !== false &&
								filter_var($url_parsed['host'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false
							)
						)
						{ return false; }
				$response = wp_remote_get($url, array('sslverify' => false));
				$url_contents = wp_remote_retrieve_body($response);
			}
			return $url_contents;
		}
	
		
		private function _verify_license() {
			global $r34icspro_licensed;
			// Already checked on this page load
			if (isset($r34icspro_licensed) && $r34icspro_licensed !== null) { return $r34icspro_licensed; }
			// Set variables
			$r34icspro_licensed = null;
			$transient_expiration = (defined('R34ICSPRO_LICENSE_PERMANENT') && !empty(R34ICSPRO_LICENSE_PERMANENT) /*!*/) ? 0 : WEEK_IN_SECONDS;
			// Check against transient *and return immediately, if not null*
			if ($r34icspro_licensed === null && $transient = get_transient('R34ICSProLicense::_verify_license')) {
				if ($transient !== null) {
					$r34icspro_licensed = $transient;
					return $r34icspro_licensed;
				}
			}
			// Check against saved license data
			if ($r34icspro_licensed != true && $license = $this->_get_license()) {
				$r34icspro_licensed = (!empty($license['product_id']) && in_array($license['product_id'], array($this->_pidl, $this->_pidd)));
			}
			// Check against license data from API server
			if ($r34icspro_licensed != true && $api_response = $this->_license_api_get_json('status')) {
				$r34icspro_licensed = !empty($api_response->success) ? ($api_response->status_check == 'active') : false;
			}
			// Verification failed
			if ($r34icspro_licensed != true) { $r34icspro_licensed = false; }
			// Set transient
			set_transient('R34ICSProLicense::_verify_license', $r34icspro_licensed, $transient_expiration);
			// Return license verification status
			return $r34icspro_licensed;
		}
	
	
		// Connection failure test URLs
		//private $_api_base_url = 'https://httpstat.us/418?sleep=30000';
		//private $_api_readme_url = 'https://httpstat.us/418?sleep=30000';
		private $_api_base_url = 'https://icscalendar.com/?wc-api=wc-am-api';
		private $_api_readme_url = 'https://api.icscalendar.com/1.txt';
		private $_lwd = 45;
		private $_lrca = '15%';
		private $_pida = '1918';
		private $_pidl = '1919';
		private $_pidd = '2916';


	}	
	
}
