# propertyhive/2.3.1/includes/class-ph-licenses.php

Property Hive, version 2.3.1. 1,078 lines.

- Page: https://pluginprobe.com/plugins/propertyhive/2.3.1/code/includes/class-ph-licenses.php
- Raw: https://pluginprobe.com/plugins/propertyhive/2.3.1/raw/includes/class-ph-licenses.php
- Modified: 2026-09-18T10:26:10+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/propertyhive/2.3.1/code/includes/class-ph-licenses.php#L10-L20`.

```php
<?php

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

/**
 * Licenses Controller
 *
 * Property Hive Licenses Class which handles the storing and checking of licenses
 *
 * @class 		PH_Licenses
 * @version		1.0.0
 * @package		PropertyHive/Classes/Licenses
 * @category	Class
 * @author 		PropertyHive
 */
class PH_Licenses {
	
	/** @var PH_Licenses The single instance of the class */
	protected static $_instance = null;

	private $pro_license_status = array();

	/**
	 * Main PH_Licenses Instance.
	 *
	 * Ensures only one instance of PH_Licenses is loaded or can be loaded.
	 *
	 * @since 1.0.0
	 * @static
	 * @return PH_Licenses Main instance
	 */
	public static function instance() {
		if ( is_null( self::$_instance ) ) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	/**
	 * Cloning is forbidden.
	 *
	 * @since 1.0.0
	 */
	public function __clone() {
		_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; huh?', 'propertyhive' ), '1.0.0' );
	}

	/**
	 * Unserializing instances of this class is forbidden.
	 *
	 * @since 1.0.0
	 */
	public function __wakeup() {
		_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; huh?', 'propertyhive' ), '1.0.0' );
	}

	/**
	 * Constructor for the licenses class
	 *
	 */
	public function __construct() {
		add_action( 'propertyhive_check_licenses', array( $this, 'ph_check_licenses' ) );
		add_filter( 'propertyhive_add_on_can_be_used', array( $this, 'ph_check_add_on_can_be_used' ), 10, 2 );
		add_filter( 'propertyhive_add_on_can_be_updated', array( $this, 'ph_check_add_on_can_be_updated' ), 10, 2 );
	}

	public function ph_check_add_on_can_be_used( $can, $slug )
	{
		// Check add on wasn't active before
		$pre_pro_add_ons = get_option( 'propertyhive_pre_pro_add_ons', array() );

		if ( !empty($pre_pro_add_ons) )
		{
			foreach ( $pre_pro_add_ons as $pre_pro_add_on )
			{
				if ( isset($pre_pro_add_on['slug']) && $pre_pro_add_on['slug'] == $slug )
				{
					// Yes! This add on was being used pre pro so should still be able to be used without license checks
					return true;
				}
			}
		}
		
        // Check we have the right kind of license key to operate this add on

        $license_type = $this->get_license_type();

        if ( $license_type == 'pro' )
        {
            if ( get_option('propertyhive_pro_license_key', '') != '' ) 
            { 
                if ( !$this->is_valid_pro_license_key() )
                {
                    // show warning
                    return false;
                }

                // Valid license. Check this plugin is valid for the purchased type of plan (i.e. map search can't be used with an 'import only' plan)
                $feature = get_ph_pro_feature( $slug );
                $product_id_and_package = PH()->license->get_pro_license_product_id_and_package();

                if ( isset($product_id_and_package['success']) && $product_id_and_package['success'] === true )
                {
                    if ( 
                        isset($feature['plans']) && 
                        isset($product_id_and_package['package']) &&
                        in_array($product_id_and_package['package'], $feature['plans'])
                    )
                    {
                        
                    }
                    else
                    {
                    	// show warning
                    	return false;
                    }
                }
            }
        }

        return $can;
	}

	public function ph_check_add_on_can_be_updated( $can, $slug )
	{
        $license_type = $this->get_license_type();

		if ( $license_type == 'old' )
		{
			$license = get_option( 'propertyhive_license_key_details', array() );

			if ( !is_array( $license ) ) { $license = array(); }

		    if ( isset($license['active']) && $license['active'] == '1' && isset($license['expires_at']) && $license['expires_at'] != '' && strtotime($license['expires_at']) > time() )
		    {
		    	return true;
		    }
		}
		elseif ( $license_type == 'pro' )
		{
			// get new license information
			if ( get_option('propertyhive_pro_license_key', '') != '' ) 
			{ 
				if ( $this->is_valid_pro_license_key() )
				{
					// Valid license. Check this plugin is valid for the purchased type of plan (i.e. map search can't be used with an 'import only' plan)
	                $feature = get_ph_pro_feature( $slug );
	                $product_id_and_package = PH()->license->get_pro_license_product_id_and_package();

	                if ( isset($product_id_and_package['success']) && $product_id_and_package['success'] === true )
	                {
	                	if ( ( $product_id_and_package['is_trial'] ?? null ) !== false ) 
	                	{
						    return false;
						}

	                    if ( 
	                        isset($feature['plans']) && 
	                        isset($product_id_and_package['package']) &&
	                        in_array($product_id_and_package['package'], $feature['plans'])
	                    )
	                    {
	                        return true;
	                    }
	                }
				}
			}
		}

        return $can;
	}

	public function get_license_type()
	{
		$license_type = get_option( 'propertyhive_license_type', '' );

		if ( $license_type == '' )
		{
			// We don't know. Let's work it out by seeing if they have a license key
			$existing_license_key = get_option( 'propertyhive_license_key', '' );

			if ( $existing_license_key != '' )
			{
				$license = PH()->license->get_current_license();

				if ( isset($license['active']) && $license['active'] == '1' )
				{
					return 'old';
				}
			}
		}

		return $license_type; // pro / old
	}

	private function get_data_for_license_check()
	{
		global $wpdb;

		$license_type = $this->get_license_type();

		$data = array();
		$data['license_key_type'] = $license_type;
		$data['license_key'] = ( $license_type == 'old' ? get_option( 'propertyhive_license_key', '' ) : get_option( 'propertyhive_pro_license_key', '' ) );
		$data['url']         = home_url();

		if ( get_option( 'propertyhive_data_sharing' ) != 'no' )
		{
			// Not opted-out

			// Retrieve current theme info
			$theme_data = wp_get_theme();
			$theme      = $theme_data->Name . ' ' . $theme_data->Version;

			$data['php_version'] = phpversion();
			$data['ph_version'] = PH_VERSION;
			$data['wp_version']  = get_bloginfo( 'version' );
			$data['server']      = isset( $_SERVER['SERVER_SOFTWARE'] ) && is_string( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '';

			$data['install_date'] = get_option('propertyhive_install_timestamp', '');
			if ( $data['install_date'] != '' && $data['install_date'] != 0 )
			{
				$data['install_date'] = gmdate("jS F Y", $data['install_date']);
			}

			$data['multisite']   = is_multisite();
			$data['theme']       = $theme;
			$data['email']       = get_bloginfo( 'admin_email' );

			// Retrieve current plugin information
			if ( !function_exists( 'get_plugins' ) ) {
				include ABSPATH . '/wp-admin/includes/plugin.php';
			}

			$plugins        = get_plugins(); // Fetch all plugins with details
			$active_plugins = get_option('active_plugins', array());

			$active_plugins_data = [];
			$inactive_plugins_data = [];

			// Loop through plugins to separate active and inactive along with version
			foreach ($plugins as $plugin_path => $plugin_data) 
			{
			    $plugin_info = [
			        'name'    => isset($plugin_data['Name']) ? $plugin_data['Name'] : '',
			        'version' => isset($plugin_data['Version']) ? $plugin_data['Version'] : '',
			        'path'    => $plugin_path,
			    ];

			    if (in_array($plugin_path, $active_plugins)) 
			    {
			        $active_plugins_data[] = $plugin_info;
			    }
			    else
			    {
			        $inactive_plugins_data[] = $plugin_info;
			    }
			}

			$data['active_plugins']   = $active_plugins_data;
			$data['inactive_plugins'] = $inactive_plugins_data;

			$data['locale']           = get_locale();

			// Import info
			$property_import = get_option( 'propertyhive_property_import', array() );
			if ( !is_array($property_import) )
			{
				$property_import = array();
			}
			$formats = array();
            foreach ( $property_import as $import_id => $options )
            {
            	if ( $options['running'] == '1' )
            	{
            		if ( $options['format'] == 'xml' )
            		{
            			$options['format'] .= ' (' . esc_url($options['xml_url']) . ')';
            		}
            		elseif ( $options['format'] == 'csv' )
            		{
            			$options['format'] .= ' (' . esc_url($options['csv_url']) . ')';
            		}
            		$formats[] = $options['format'];
            	}
			}
			$data['property_import_formats'] = $formats;

			// Exports
			$formats = array();

			$exports = array(
			    'propertyhive_realtimefeed' => array(
			        'label' => 'RTDF',
			        'field' => 'send_property_api_url',
			    ),
			    'propertyhive_zooplarealtimefeed' => array(
			        'label' => 'Zoopla',
			        'field' => 'send_property_api_url',
			    ),
			    'propertyhive_blmexport' => array(
			        'label' => 'BLM',
			        'field' => 'ftp_host',
			    ),
			);

			foreach ( $exports as $option_name => $config )
			{
			    $property_export = get_option( $option_name, array() );

			    if ( ! is_array( $property_export ) ) {
			    	continue;
			    }

		        if ( ! isset( $property_export['portals'] ) ) {
		            continue;
		        }

		        if ( ! is_array( $property_export['portals'] ) ) {
		            continue;
		        }

		        $portals = isset( $property_export['portals'] ) && is_array( $property_export['portals'] )
		            ? $property_export['portals']
		            : array();

		        foreach ( $portals as $portal_id => $portal )
		        {
		            if ( ! is_array( $portal ) ) {
		                continue;
		            }

		            if ( ! is_array( $portal ) || ( $portal['mode'] ?? '' ) !== 'live' ) {
		                continue;
		            }

		            $destination = $portal[ $config['field'] ] ?? '';

		            $formats[] = sprintf(
		                '%s (%s)',
		                $config['label'],
		                $destination
		            );
		        }
			}

			$data['property_export_formats'] = $formats;

			// Locrating
			$locrating_settings = get_option( 'propertyhive_locrating', array() );
			if ( !empty($locrating_settings) && isset($locrating_settings['enabled']) )
			{
				$data['locrating_enabled'] = ( $locrating_settings['enabled'] == 1 ? $locrating_settings['enabled'] : 0 );
			}

			// Search analytics

			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Aggregate current custom-table analytics for the license report; new search events and retention change these counts independently.
			$counts = $wpdb->get_row(
				"SELECT
					COALESCE(
						SUM(searched_at >= UTC_TIMESTAMP() - INTERVAL 7 DAY),
						0
					) AS last_7_days,
					COALESCE(
						SUM(searched_at >= UTC_TIMESTAMP() - INTERVAL 30 DAY),
						0
					) AS last_30_days,
					COUNT(*) AS last_90_days
				FROM {$wpdb->prefix}ph_search_log
				WHERE searched_at >= UTC_TIMESTAMP() - INTERVAL 90 DAY",
				ARRAY_A
			);

			if ( is_array($counts) )
			{
				$data['searches_last_7_days'] = (int) ( $counts['last_7_days'] ?? 0 );
				$data['searches_last_30_days'] = (int) ( $counts['last_30_days'] ?? 0 );
				$data['searches_last_90_days'] = (int) ( $counts['last_90_days'] ?? 0 );
			}

			// get counts
			$post_types = array('office', 'property', 'contact', 'appraisal', 'viewing', 'offer', 'sale', 'tenancy', 'key_date');
			foreach ( $post_types as $post_type )
			{
				$args = array(
					'post_type' => $post_type,
					'fields' => 'ids',
					'posts_per_page' => 1,
					'post_status' => 'publish'
				);
				if ( $post_type == 'property' )
				{
					// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- On-market state is stored in property metadata; retrieve one ID and use found_posts for the aggregate count.
					$args['meta_query'] = array(
						array(
							'key' => '_on_market',
							'value' => 'yes'
						)
					);
				}

				$post_query = new WP_Query( $args );

				$data['post_type_count_' . $post_type] = $post_query->found_posts;

				wp_reset_postdata();
			}

			$departments = array_keys( ph_get_departments() );
			foreach ( $departments as $department )
			{
				$department_option = 'propertyhive_active_departments_' . str_replace( 'residential-', '', $department );
				if ( get_option( $department_option ) != 'yes' )
				{
					continue;
				}

				$args = array(
					'post_type' => 'property',
					'fields' => 'ids',
					'posts_per_page' => 1,
					'post_status' => 'publish',
					// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Department and on-market state use property metadata; retrieve one ID and use found_posts for the opted-in aggregate count.
					'meta_query' => array(
						array(
							'key' => '_on_market',
							'value' => 'yes'
						),
						array(
							'key' => '_department',
							'value' => $department
						)
					)
				);

				$post_query = new WP_Query( $args );

				$data['property_count_by_department_' . $department] = $post_query->found_posts;

				wp_reset_postdata();
			}

			$data = apply_filters( 'propertyhive_license_check_data', $data );
		}

		return $data;
	}

	/**
	 * Automated check for licenses
	 *
	 */
	public function ph_check_licenses( $force_check = false )
	{
		// Do a maximum of once per week
		$last_send = get_option( 'propertyhive_last_license_check', '' );
		if( !$force_check && is_numeric( $last_send ) && $last_send > strtotime( '-1 week' ) ) {
			return false;
		}

		update_option( 'propertyhive_last_license_check', time() );

		// Retain last-known license details during outages; replace them only with a valid HTTPS response.
		update_option( 'propertyhive_license_key_error', '', 'no' );

		$data = $this->get_data_for_license_check();

		$request = wp_remote_post( 'http://license.wp-property-hive.com/check-license.php', array(
			'method'      => 'POST',
			'timeout'     => 20,
			'redirection' => 1,
			'httpversion' => '1.1',
			'blocking'    => true,
			'body'        => $data,
			'user-agent'  => 'PH/' . PH_VERSION . '; ' . get_bloginfo( 'url' )
		) );

		if ( is_wp_error( $request ) )
		{
			update_option( 'propertyhive_license_key_error', __( 'The license service could not be reached securely. Your saved license details have been retained.', 'propertyhive' ) . ' ' . $request->get_error_message(), 'no' );
			return false;
		}

		if ( 200 !== wp_remote_retrieve_response_code( $request ) || '' === wp_remote_retrieve_body( $request ) )
		{
			update_option( 'propertyhive_license_key_error', __( 'The license service returned an invalid response.', 'propertyhive' ) . ' ' . wp_remote_retrieve_response_code( $request ), 'no' );
			return false;
		}

		$body = @unserialize($request['body'], ['allowed_classes' => false]);
		if ( $body !== FALSE && is_array($body) )
		{
			update_option( 'propertyhive_license_key_details', $body, 'no' );
		}
		else
		{
			update_option( 'propertyhive_license_key_error', __( 'The license service returned invalid license data.', 'propertyhive' ) . ' ' . print_r($body, true), 'no' );
		}
	}

	public function get_current_license()
	{
		$license = get_option( 'propertyhive_license_key_details', array() );

		if ( !is_array( $license ) ) { $license = array(); }

		return $license;
	}

	public function is_valid_pro_license_key($force = false)
	{
		$license = $this->get_current_pro_license($force);
		if ( isset($license['success']) && $license['success'] === true )
		{
			return true;
		}

		return false;
	}

	public function activate_pro_license_key()
	{
		$license = $this->get_pro_license_product_id_and_package(true);

		if ( isset($license['success']) && $license['success'] === true )
		{
			$license_key = get_option( 'propertyhive_pro_license_key', '' );

			$instance_id = get_option( 'propertyhive_pro_instance_id', '' );

	    	if ( empty($instance_id) )
	    	{
	    		$instance_id = wp_generate_password( 12, false ); // disable specialchars
	    		update_option('propertyhive_pro_instance_id', $instance_id );
	    	}

	    	$data = array();

			// found API key. It's product ID will be stored in product_id
			$url = 'https://wp-property-hive.com/?';
	    	$url .= 'wc-api=wc-am-api&';
	    	$url .= 'wc_am_action=activate&';
	    	$url .= 'instance=' . $instance_id . '&';
            $url .= 'object=' . wp_parse_url( get_site_url(), PHP_URL_HOST ) . '&';
	    	$url .= 'product_id=' . $license['product_id'] . '&';
	    	$url .= 'api_key=' . $license_key;

	    	$response = wp_remote_post( $url, array(
	    		'body' => $data,
	    	) );

	    	if ( is_wp_error($response) )
	    	{
	  			$return = array(
	        		'success' => false,
	        		'error' => __( 'Failed to activate license status', 'propertyhive' ) . ': ' . $response->get_error_message()
	        	);
	        	return $return;
			}

			if ( 200 !== wp_remote_retrieve_response_code( $response ) )
			{
				$return = array(
	        		'success' => false,
	        		'error' => sprintf( 
	        			/* translators: %s: HTTP header response code */
	        			__( 'Received response code %s when activating license key status', 'propertyhive' ), 
	        			wp_remote_retrieve_response_code( $response ) 
	        		)
	        	);
	        	return $return;
			}

			$result = $response['body'];

			$body = json_decode($result, true);

			if ( json_last_error() !== JSON_ERROR_NONE ) 
			{
				$return = array(
	        		'success' => false,
                    'error' => __( 'Failed to decode response when activating license key status. Please try again', 'propertyhive' ) . ': ' . wp_json_encode( $result )
	        	);
	        	return $return;
			}

			if ( isset($body['success']) )
			{
				if ( $body['success'] === true )
				{
					$return = array(
		        		'success' => true,
		        	);
					return $return;
				}
				else
				{
					$return = array(
		        		'success' => false,
		        		'error' => __( 'Error when activating license key', 'propertyhive' ) . ': ' . $body['error']
		        	);
					return $return;
				}
			}
			else
			{
				$return = array(
	        		'success' => false,
                    'error' => __( 'Something went wrong when trying to activate license key', 'propertyhive' ) . ': ' . wp_json_encode( $body )
	        	);
				return $return;
			}
		}
		else
		{
			return $license;
		}
	}

	public function deactivate_pro_license_key()
	{
		$license = $this->get_pro_license_product_id_and_package(true);

		if ( isset($license['success']) && $license['success'] === true )
		{
			$license_key = get_option( 'propertyhive_pro_license_key', '' );

			$instance_id = get_option( 'propertyhive_pro_instance_id', '' );

	    	if ( empty($instance_id) )
	    	{
	    		$instance_id = wp_generate_password( 12, false ); // disable specialchars
	    		update_option('propertyhive_pro_instance_id', $instance_id );
	    	}

	    	$data = array();

			// found API key. It's product ID will be stored in product_id
			$url = 'https://wp-property-hive.com/?';
	    	$url .= 'wc-api=wc-am-api&';
	    	$url .= 'wc_am_action=deactivate&';
	    	$url .= 'instance=' . $instance_id . '&';
            $url .= 'object=' . wp_parse_url( get_site_url(), PHP_URL_HOST ) . '&';
	    	$url .= 'product_id=' . $license['product_id'] . '&';
	    	$url .= 'api_key=' . $license_key;

	    	$response = wp_remote_post( $url, array(
	    		'body' => $data,
	    	) );

	    	if ( is_wp_error($response) )
	    	{
	  			$return = array(
	        		'success' => false,
	        		'error' => __( 'Failed to deactivate license status', 'propertyhive' ) . ': ' . $response->get_error_message()
	        	);
	        	return $return;
			}

			if ( 200 !== wp_remote_retrieve_response_code( $response ) )
			{
				$return = array(
	        		'success' => false,
	        		'error' => sprintf( 
	        			/* translators: %s: HTTP header response code */
	        			__( 'Received response code %s when deactivating license key status', 'propertyhive' ), 
	        			wp_remote_retrieve_response_code( $response ) 
	        		)
	        	);
	        	return $return;
			}

			$result = $response['body'];

			$body = json_decode($result, true);

			if ( json_last_error() !== JSON_ERROR_NONE ) 
			{
				$return = array(
	        		'success' => false,
                    'error' => __( 'Failed to decode response when deactivating license key status. Please try again', 'propertyhive' ) . ': ' . wp_json_encode( $result )
	        	);
	        	return $return;
			}

			if ( isset($body['success']) )
			{
				if ( $body['success'] === true )
				{
					$return = array(
		        		'success' => true,
		        	);
					return $return;
				}
				else
				{
					$return = array(
		        		'success' => false,
		        		'error' => __( 'Error when deactivating license key', 'propertyhive' ) . ': ' . $body['error']
		        	);
					return $return;
				}
			}
			else
			{
				$return = array(
	        		'success' => false,
                    'error' => __( 'Something went wrong when trying to deactivate license key', 'propertyhive' ) . ': ' . wp_json_encode( $body )
	        	);
				return $return;
			}
		}
		else
		{
			return $license;
		}
	}

	public function get_pro_license_product_id_and_package($force = false)
	{
		if ( $force !== true )
    	{
    		// Not forcing. Get from transient if possible
    		$pro_license_product_id_and_package = get_transient( 'ph_pro_license_product_id_and_package' );

    		if ( $pro_license_product_id_and_package !== false ) 
    		{
    			// return transient value
				return $pro_license_product_id_and_package;
			}
    	}

    	$license_key = get_option( 'propertyhive_pro_license_key', '' );

        if ( empty($license_key) )
        {
        	$return = array(
        		'success' => false,
        		'error' => __( 'No license key entered', 'propertyhive' )
        	);
        	set_transient( 'ph_pro_license_product_id_and_package', $return, HOUR_IN_SECONDS );
        	return $return;
        }

        $instance_id = get_option( 'propertyhive_pro_instance_id', '' );

        if ( empty($instance_id) )
    	{
    		$instance_id = wp_generate_password( 12, false ); // disable specialchars
    		update_option('propertyhive_pro_instance_id', $instance_id );
    	}

        $data = $this->get_data_for_license_check();

        $url = 'https://wp-property-hive.com/?';
    	$url .= 'wc-api=wc-am-api&';
    	$url .= 'wc_am_action=product_list&';
    	$url .= 'instance=' . $instance_id . '&';
    	$url .= 'api_key=' . $license_key;

    	$response = wp_remote_post( $url, array(
    		'body' => $data,
    	) );
    	
    	if ( is_wp_error($response) )
    	{
        	$return = array(
        		'success' => false,
        		'error' => __( 'Failed to request license product list', 'propertyhive' ) . ': ' . $response->get_error_message()
        	);

        	$last_known = get_option('ph_pro_last_known_license_product_id_and_package', array());
        	if ( !empty($last_known) )
        	{
        		set_transient( 'ph_pro_license_product_id_and_package', $last_known, HOUR_IN_SECONDS );
        		return $last_known;
        	}

        	return $return;
		}

		if ( 200 !== wp_remote_retrieve_response_code( $response ) )
		{
        	$return = array(
        		'success' => false,
        		'error' => sprintf( 
        			/* translators: %s: HTTP header response code */
        			__( 'Received response code %s when requesting license key product list', 'propertyhive' ), 
        			wp_remote_retrieve_response_code( $response ) 
        		)
        	);
        	
        	$last_known = get_option('ph_pro_last_known_license_product_id_and_package', array());
        	if ( !empty($last_known) )
        	{
        		set_transient( 'ph_pro_license_product_id_and_package', $last_known, HOUR_IN_SECONDS );
        		return $last_known;
        	}

        	return $return;
		}

		$result = $response['body'];

		$body = json_decode($result, true);

		if ( json_last_error() !== JSON_ERROR_NONE ) 
		{
        	$return = array(
        		'success' => false,
                'error' => __( 'Failed to decode response when requesting license key product list. Please try again', 'propertyhive' ) . ': ' . wp_json_encode( $result )
        	);
        	
        	$last_known = get_option('ph_pro_last_known_license_product_id_and_package', array());
        	if ( !empty($last_known) )
        	{
        		set_transient( 'ph_pro_license_product_id_and_package', $last_known, HOUR_IN_SECONDS );
        		return $last_known;
        	}

        	return $return;
		}

		if ( isset($body['success']) )
		{
			if ( $body['success'] === true )
			{
				if ( isset($body['data']['product_list']['wc_subs_resources']) && !empty($body['data']['product_list']['wc_subs_resources']) )
				{
					$package = false;
					$product_id = '';
					$is_trial = null;

					foreach ( $body['data']['product_list']['wc_subs_resources'] as $resource )
					{
						if ( isset($resource['product_id']) )
						{
							if ( in_array($resource['product_id'], array(14492, 14493, 14494)) )
							{
								$package = 'import';
							}
							elseif ( in_array($resource['product_id'], array(14495, 14496, 14497)) )
							{
								$package = 'complete';
							}
							$product_id = $resource['product_id'];
							$is_trial = isset( $resource['is_trial'] )
							    && is_bool( $resource['is_trial'] )
							        ? $resource['is_trial']
							        : null;
						}
					}

					if ( $package !== FALSE )
					{
						$return = array(
			        		'success' => true,
			        		'package' => $package,
			        		'product_id' => $product_id,
			        		'is_trial'   => $is_trial,
			        	);
					}
					else
					{
						$return = array(
			        		'success' => false,
			        		'error' => __( 'API key exists but unable to establish the plan', 'propertyhive' )
			        	);
					}
				}
				else
				{
					$return = array(
		        		'success' => false,
                        'error' => __( 'API key doesn\'t appear to belong to any orders', 'propertyhive' ) . ': ' . wp_json_encode( $body )
		        	);
				}
			}
			else
			{
				$return = array(
	        		'success' => false,
	        		'error' => __( 'Error when requesting license key product list', 'propertyhive' ) . ': ' . $body['error']
	        	);
			}

			set_transient( 'ph_pro_license_product_id_and_package', $return, HOUR_IN_SECONDS * 3 );
			update_option( 'ph_pro_last_known_license_product_id_and_package', $return );
			return $return;
		}
		else
		{
			$return = array(
        		'success' => false,
                'error' => __( 'Something went wrong when requesting license key product list', 'propertyhive' ) . ': ' . wp_json_encode( $body )
        	);
        	
			$last_known = get_option('ph_pro_last_known_license_product_id_and_package', array());
        	if ( !empty($last_known) )
        	{
        		set_transient( 'ph_pro_license_product_id_and_package', $last_known, HOUR_IN_SECONDS );
        		return $last_known;
        	}

			return $return;
		}
	}

	public function get_current_pro_license($force = false)
	{
		if ( $force !== true )
    	{
    		// Not forcing. Get from transient if possible
    		$pro_license_status = get_transient( 'ph_pro_license_status' );

    		if ( $pro_license_status !== false ) 
    		{
    			// return transient value
				return $pro_license_status;
			}
    	}

    	$product_id_and_package = $this->get_pro_license_product_id_and_package($force);

    	if ( !isset($product_id_and_package['success']) || ( isset($product_id_and_package['success']) && $product_id_and_package['success'] === false ) )
    	{
    		return $product_id_and_package;
    	}
    	
        $license_key = get_option( 'propertyhive_pro_license_key', '' );

        if ( empty($license_key) )
        {
        	$return = array(
        		'success' => false,
        		'error' => __( 'No license key entered', 'propertyhive' )
        	);
        	set_transient( 'ph_pro_license_status', $return, HOUR_IN_SECONDS );
        	return $return;
        }

        $instance_id = get_option( 'propertyhive_pro_instance_id', '' );

        if ( empty($instance_id) )
    	{
    		$instance_id = wp_generate_password( 12, false ); // disable specialchars
    		update_option('propertyhive_pro_instance_id', $instance_id );
    	}

        $data = $this->get_data_for_license_check();

        $url = 'https://wp-property-hive.com/?';
    	$url .= 'wc-api=wc-am-api&';
    	$url .= 'wc_am_action=status&';
    	$url .= 'product_id=' . $product_id_and_package['product_id'] . '&';
    	$url .= 'instance=' . $instance_id . '&';
    	$url .= 'api_key=' . $license_key;

    	$response = wp_remote_post( $url, array(
    		'body' => $data,
    	) );
    	
    	if ( is_wp_error($response) )
    	{
    		// error for some reason. Return last known status
    		$previous_license_key_status = get_option( 'propertyhive_pro_license_key_status', '' );
    		if ( !empty($previous_license_key_status) )
    		{
    			set_transient( 'ph_pro_license_status', $previous_license_key_status, HOUR_IN_SECONDS );
    			return $previous_license_key_status;
    		}

        	$return = array(
        		'success' => false,
        		'error' => __( 'Failed to request license status', 'propertyhive' ) . ': ' . $response->get_error_message()
        	);
        	return $return;
		}

		if ( 200 !== wp_remote_retrieve_response_code( $response ) )
		{
			// error for some reason. Return last known status
    		$previous_license_key_status = get_option( 'propertyhive_pro_license_key_status', '' );
    		if ( !empty($previous_license_key_status) )
    		{
    			set_transient( 'ph_pro_license_status', $previous_license_key_status, HOUR_IN_SECONDS );
    			return $previous_license_key_status;
    		}

        	$return = array(
        		'success' => false,
        		'error' => sprintf( 
        			/* translators: %s: HTTP header response code */
        			__( 'Received response code %s when requesting license key status', 'propertyhive' ), 
        			wp_remote_retrieve_response_code( $response ) 
        		)
        	);

        	return $return;
		}

		$result = $response['body'];

		$body = json_decode($result, true);

		if ( json_last_error() !== JSON_ERROR_NONE ) 
		{
        	$return = array(
        		'success' => false,
                'error' => __( 'Failed to decode response when requesting license key status. Please try again', 'propertyhive' ) . ': ' . wp_json_encode( $result )
        	);
        	
        	// error for some reason. Return last known status
    		$previous_license_key_status = get_option( 'propertyhive_pro_license_key_status', '' );
    		if ( !empty($previous_license_key_status) )
    		{
    			set_transient( 'ph_pro_license_status', $previous_license_key_status, HOUR_IN_SECONDS );
    			return $previous_license_key_status;
    		}

        	return $return;
		}

		if ( isset($body['success']) )
		{
			if ( $body['success'] === true )
			{
				if ( isset($body['status_check']) && $body['status_check'] === 'active' )
				{
					$return = array(
		        		'success' => true
		        	);
				}
				else
				{
					$return = array(
		        		'success' => false,
		        		'error' => __( 'License key inactive', 'propertyhive' )
		        	);
				}
			}
			else
			{
				$return = array(
	        		'success' => false,
	        		'error' => __( 'Error when requesting license key status', 'propertyhive' ) . ': ' . $body['error']
	        	);
			}

			update_option( 'propertyhive_pro_license_key_last_checked', time() );
			update_option( 'propertyhive_pro_license_key_status', $return );

			set_transient( 'ph_pro_license_status', $return, HOUR_IN_SECONDS * 3 );
			return $return;
		}
		else
		{
			$return = array(
        		'success' => false,
                'error' => __( 'Something went wrong when requesting license key status', 'propertyhive' ) . ': ' . wp_json_encode( $body )
        	);
        	
			// error for some reason. Return last known status
    		$previous_license_key_status = get_option( 'propertyhive_pro_license_key_status', '' );
    		if ( !empty($previous_license_key_status) )
    		{
    			set_transient( 'ph_pro_license_status', $previous_license_key_status, HOUR_IN_SECONDS );
    			return $previous_license_key_status;
    		}

			return $return;
		}
	}
}

```
