<?php
/**
 * Theme updater admin page and functions.
 *
 * @package WPJobster
 * @version 1.0.7
 */

class EDD_Theme_Updater_Admin extends \stdClass {

	/**
	 * Variables required for the theme updater
	 *
	 * @since 1.0.0
	 * @type string
	 */
	protected $remote_api_url = null;
	protected $theme_slug     = null;
	protected $version        = null;
	protected $author         = null;
	protected $download_id    = null;
	protected $renew_url      = null;
	protected $strings        = null;

	/**
	 * Initialize the class.
	 *
	 * @since 1.0.0
	 */
	function __construct( $config = array(), $strings = array() ) {
		$config = wp_parse_args( $config, array(
			'remote_api_url' => 'https://wpjobster.com',
			'theme_slug'     => get_template(),
			'item_name'      => '',
			'license'        => '',
			'version'        => '',
			'author'         => '',
			'download_id'    => '',
			'renew_url'      => '',
			'beta'           => false,
		) );

		// Set config arguments
		$this->remote_api_url = $config['remote_api_url'];
		$this->item_name      = $config['item_name'];
		$this->theme_slug     = sanitize_key( $config['theme_slug'] );
		$this->version        = $config['version'];
		$this->author         = $config['author'];
		$this->download_id    = $config['download_id'];
		$this->renew_url      = $config['renew_url'];
		$this->beta           = $config['beta'];

		// Populate version fallback
		if ( '' == $config['version'] ) {
			$theme         = wp_get_theme( $this->theme_slug );
			$this->version = $theme->get( 'Version' );
		}

		// Strings passed in from the updater config
		$this->strings = $strings;

		add_action( 'init', array( $this, 'updater' ) );

		add_action( 'wpjobster_display_license_status_text', array( $this, 'display_license_status' ) );
		add_action( 'wpjobster_display_license_action_button', array( $this, 'display_license_action_button' ) );

		add_action( 'admin_init', array( $this, 'license_action' ) );
		add_action( 'add_option_' . $this->theme_slug . '_license_key', array( $this, 'activate_license' ), 11, 2 );
		add_action( 'update_option_' . $this->theme_slug . '_license_key', array( $this, 'activate_license' ), 11, 2 );

		add_action( 'admin_init', array( $this, 'register_option' ) );
		add_filter( 'http_request_args', array( $this, 'disable_wporg_request' ), 5, 2 );
	}

	/* Creates the updater class */
	function updater() {
		if ( ! current_user_can( 'manage_options' ) ) return;

		/* If there is no valid license key status, don't allow updates. */
		if ( wpj_get_option( $this->theme_slug . '_license_key_status', false) != 'valid' ) return;

		if ( ! class_exists( 'EDD_Theme_Updater' ) ) {
			// Load our custom theme updater
			include( dirname( __FILE__ ) . '/theme-updater-class.php' );
		}

		new EDD_Theme_Updater(
			array(
				'remote_api_url' => $this->remote_api_url,
				'version'        => $this->version,
				'license'        => trim( wpj_get_option( $this->theme_slug . '_license_key' ) ),
				'item_name'      => $this->item_name,
				'author'         => $this->author,
				'beta'           => $this->beta,
			),
			$this->strings
		);
	}

	/* Display license status */
	function display_license_status() {
		$strings = $this->strings;
		$license = trim( wpj_get_option( $this->theme_slug . '_license_key' ) );
		$status  = wpj_get_option( $this->theme_slug . '_license_key_status', false );

		// Checks license status to display under license key
		if ( ! $license ) {
			$message = $strings['enter-key'];

		} else {
			if ( ! get_transient( $this->theme_slug . '_license_message', false ) ) {
				set_transient( $this->theme_slug . '_license_message', $this->check_license(), ( 60 * 60 * 24 ) );
			}
			$message = get_transient( $this->theme_slug . '_license_message' );

		}

		echo $message;
	}

	/* Display license activate/deactivate button */
	function display_license_action_button() {
		$strings = $this->strings;
		$status  = wpj_get_option( $this->theme_slug . '_license_key_status', false );

		wp_nonce_field( $this->theme_slug . '_nonce', $this->theme_slug . '_nonce' );

		if ( 'valid' == $status ) { ?>

			<input type="submit" class="button-secondary" name="<?php echo $this->theme_slug; ?>_license_deactivate" value="<?php esc_attr_e( $strings['deactivate-license'] ); ?>"/>

		<?php } else { ?>

			<input type="submit" class="button-secondary" name="<?php echo $this->theme_slug; ?>_license_activate" value="<?php esc_attr_e( $strings['activate-license'] ); ?>"/>

		<?php }

	}

	/* Sanitizes the license key */
	function sanitize_license( $new ) {

		$old = wpj_get_option( $this->theme_slug . '_license_key' );

		if ( $old && $old != $new ) {
			// New license has been entered, so must reactivate
			delete_option( $this->theme_slug . '_license_key_status' );
			delete_transient( $this->theme_slug . '_license_message' );
		}

		return $new;
	}

	/* Get the license URL */
	function license_url() {
		if ( isset( $_POST['jobster_settings']['redux-section'] ) && $_POST['jobster_settings']['redux-section'] == wpj_get_settings_tab_number_by_field_id( '1updater-settings' ) ) {
			$license_url = add_query_arg( array(
				'tab' => wpj_get_settings_tab_number_by_field_id( '1updater-settings' )
			), menu_page_url( 'jobster-settings', false ) );

		} else {
			$license_url = add_query_arg( array(
				'tab' => 1
			), menu_page_url( 'jobster-settings', false ) );
		}

		return $license_url;
	}

	/* Checks if a license action was submitted */
	function license_action() {

		if ( ! is_demo_admin() ) {

			if ( isset( $_POST[ $this->theme_slug . '_license_activate' ] ) ) {
				if ( check_admin_referer( $this->theme_slug . '_nonce', $this->theme_slug . '_nonce' ) ) {
					if ( isset( $_POST[ $this->theme_slug . '_license_key' ] ) ) {
						update_option( $this->theme_slug . '_license_key', trim( $_POST[ $this->theme_slug . '_license_key' ] ) );
					}
					$this->activate_license();
				}
			}

			if ( isset( $_POST[$this->theme_slug . '_license_deactivate'] ) ) {
				if ( check_admin_referer( $this->theme_slug . '_nonce', $this->theme_slug . '_nonce' ) ) {
					if ( isset( $_POST[ $this->theme_slug . '_license_key' ] ) ) {
						update_option( $this->theme_slug . '_license_key', trim( $_POST[ $this->theme_slug . '_license_key' ] ) );
					}
					$this->deactivate_license();
				}
			}

		}

	}

	/* Activates the license key */
	function activate_license() {

		do_action( 'wpjobster_edd_activate_license_before' );

		$license = trim( wpj_get_option( $this->theme_slug . '_license_key' ) );

		// Data to send in our API request.
		$api_params = array(
			'edd_action' => 'activate_license',
			'license'    => $license,
			'item_name'  => urlencode( $this->item_name )
		);

		$response = $this->get_api_response( $api_params );

		// make sure the response came back okay
		if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {

			if ( is_wp_error( $response ) )
				$message = $response->get_error_message();

			else
				$message = __( 'An error occurred, please try again.', 'wpjobster' );

		} else {

			$license_data = wpj_json_decode( wp_remote_retrieve_body( $response ) );

			if ( false === $license_data->success ) {

				switch( $license_data->error ) {

					case 'expired' :
						$message = sprintf(
							__( 'Your support and updates expired on %s. Your license is lifetime, so the site will keep working with the current version.', 'wpjobster' ),
							wpj_date( wpj_get_option( 'date_format' ), strtotime( $license_data->expires, current_time( 'timestamp' ) ) )
						);
						break;

					case 'revoked' :
						$message = __( 'Your license key has been disabled.', 'wpjobster' );
						break;

					case 'missing' :
						$message = __( 'Invalid license.', 'wpjobster' );
						break;

					case 'invalid' :
					case 'site_inactive' :
						$message = __( 'Your license is not active for this URL.', 'wpjobster' );
						break;

					case 'item_name_mismatch' :
						$message = sprintf( __( 'This appears to be an invalid license key for %s.', 'wpjobster' ), ( ! empty( $args['name'] ) ? $args['name'] : '' ) );
						break;

					case 'no_activations_left':
						$message = __( 'Your license key has reached its activation limit.', 'wpjobster' );
						break;

					default :
						$message = __( 'An error occurred, please try again.', 'wpjobster' );
						break;
				}

				if ( ! empty( $message ) && $license_data->error != 'item_name_mismatch' ) {

					do_action( 'wpjobster_edd_activate_license_after' );

					wp_redirect( add_query_arg( array(
						'sl_theme_activation' => 'false',
						'message'             => urlencode( $message ),
					), $this->license_url() ) );
					exit();
				}

			}

		}

		// $response->license will be either "active" or "inactive"
		if ( $license_data && isset( $license_data->license ) ) {
			update_option( $this->theme_slug . '_license_key_status', $license_data->license );
			delete_transient( $this->theme_slug . '_license_message' );
		}

		do_action( 'wpjobster_edd_activate_license_after' );

		wp_redirect( $this->license_url() ); exit();

	}

	/* Deactivates the license key */
	function deactivate_license() {

		do_action( 'wpjobster_edd_deactivate_license_before' );

		// Retrieve the license from the database.
		$license = trim( wpj_get_option( $this->theme_slug . '_license_key' ) );

		// Data to send in our API request.
		$api_params = array(
			'edd_action' => 'deactivate_license',
			'license'    => $license,
			'item_name'  => urlencode( $this->item_name )
		);

		$response = $this->get_api_response( $api_params );

		// make sure the response came back okay
		if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {

			if ( is_wp_error( $response ) )
				$message = $response->get_error_message();

			else
				$message = __( 'An error occurred, please try again.', 'wpjobster' );

		} else {

			$license_data = wpj_json_decode( wp_remote_retrieve_body( $response ) );

			// $license_data->license will be either "deactivated" or "failed"
			if ( $license_data && ( $license_data->license == 'deactivated' ) ) {
				delete_option( $this->theme_slug . '_license_key_status' );
				delete_transient( $this->theme_slug . '_license_message' );
			}

		}

		if ( ! empty( $message ) ) {

			do_action( 'wpjobster_edd_deactivate_license_after' );

			wp_redirect( add_query_arg( array(
				'sl_theme_activation' => 'false',
				'message'             => urlencode( $message ),
			), $this->license_url() ) );
			exit();
		}

		do_action( 'wpjobster_edd_deactivate_license_after' );

		wp_redirect( $this->license_url() ); exit();

	}

	/* Checks if license is valid and gets expire date */
	function check_license() {

		$license = trim( wpj_get_option( $this->theme_slug . '_license_key' ) );
		$strings = $this->strings;

		$api_params = array(
			'edd_action' => 'check_license',
			'license'    => $license,
			'item_name'  => urlencode( $this->item_name ),
			'url'        => home_url()
		);

		$response = $this->get_api_response( $api_params );

		// make sure the response came back okay
		if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {

			if ( is_wp_error( $response ) )
				$message = $response->get_error_message();

			else
				$message = $strings['license-status-unknown'];

		} else {

			$license_data = wpj_json_decode( wp_remote_retrieve_body( $response ) );

			// If response doesn't include license data, return
			if ( ! isset( $license_data->license ) ) {
				$message = $strings['license-status-unknown'];
				return $message;
			}

			// We need to update the license status at the same time the message is updated
			if ( $license_data && isset( $license_data->license ) ) {
				update_option( $this->theme_slug . '_license_key_status', $license_data->license );
			}

			// Get expire date
			$expires = false;
			if ( isset( $license_data->expires ) && 'lifetime' != $license_data->expires ) {
				$expires = wpj_date( wpj_get_option( 'date_format' ), strtotime( $license_data->expires ) );
				$renew_link = '<a href="' . esc_url( $this->get_renewal_link() ) . '" target="_blank">' . $strings['renew'] . '</a>';

			} elseif ( isset( $license_data->expires ) && 'lifetime' == $license_data->expires ) {
				$expires = 'lifetime';

			}

			// Get site counts
			$site_count    = $license_data->site_count;
			$license_limit = $license_data->license_limit;

			// If unlimited
			if ( 0 == $license_limit ) {
				$license_limit = $strings['unlimited'];
			}

			if ( $license_data->license == 'valid' ) {
				$message = $strings['license-key-is-active'] . ' ';
				if ( isset( $expires ) && 'lifetime' != $expires ) {
					$message .= sprintf( $strings['expires%s'], $expires ) . ' ';
				}

				if ( isset( $expires ) && 'lifetime' == $expires ) {
					$message .= $strings['expires-never'];
				}

				if ( $site_count && $license_limit ) {
					$message .= sprintf( $strings['%1$s/%2$-sites'], $site_count, $license_limit );
				}

			} else if ( $license_data->license == 'expired' ) {
				if ( $expires ) {
					$message = sprintf( $strings['license-key-expired-%s'], $expires );
				} else {
					$message = $strings['license-key-expired'];
				}

				if ( $renew_link ) {
					$message .= ' ' . $renew_link;
				}

			} else if ( $license_data->license == 'invalid' ) {
				$message = $strings['license-keys-do-not-match'];

			} else if ( $license_data->license == 'inactive' ) {
				$message = $strings['license-is-inactive'];

			} else if ( $license_data->license == 'disabled' ) {
				$message = $strings['license-key-is-disabled'];

			} else if ( $license_data->license == 'site_inactive' ) {
				// Site is inactive
				$message = $strings['site-is-inactive'];

			} else {
				$message = $strings['license-status-unknown'];

			}

		}

		return $message;
	}

	/* Registers the option used to store the license key in the options table */
	function register_option() {
		register_setting(
			$this->theme_slug . '-license',
			$this->theme_slug . '_license_key',
			array( $this, 'sanitize_license' )
		);
	}

	/* Constructs a renewal link */
	function get_renewal_link() {

		// If a renewal link was passed in the config, use that
		if ( '' != $this->renew_url ) return $this->renew_url;

		// If download_id was passed in the config, a renewal link can be constructed
		$license_key = trim( wpj_get_option( $this->theme_slug . '_license_key', false ) );
		if ( '' != $this->download_id && $license_key ) {
			$url  = esc_url( $this->remote_api_url );
			$url .= '/checkout/?edd_license_key=' . $license_key . '&download_id=' . $this->download_id;
			return $url;
		}

		// Otherwise return the remote_api_url
		return $this->remote_api_url;

	}

	/* Disable requests to wp.org repository for this theme */
	function disable_wporg_request( $r, $url ) {

		if ( is_string( $url ) ) {

			// If it's not a theme update request, bail.
			if ( 0 !== strpos( $url, 'https://api.wordpress.org/themes/update-check/1.1/' ) ) {
				return $r;
			}

			// Decode the JSON response
			$themes = wpj_json_decode( $r['body']['themes'] );

			// Remove the active parent and child themes from the check
			$parent = wpj_get_option( 'template' );
			$child  = wpj_get_option( 'stylesheet' );
			unset( $themes->themes->$parent );
			unset( $themes->themes->$child );

			// Encode the updated JSON response
			$r['body']['themes'] = json_encode( $themes );

		}

		return $r;
	}

	/* Makes a call to the API */
	function get_api_response( $api_params ) {

		// Call the custom API.
		$response = wp_remote_post( $this->remote_api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );

		// Make sure the response came back okay.
		if ( is_wp_error( $response ) ) {
			wp_die( $response->get_error_message(), __( 'Error', 'wpjobster' ) . $response->get_error_code() );
		}

		return $response;
	}
}

/**
 * This is a means of catching errors from the activation method above and displyaing it to the customer
 */
function edd_sample_theme_admin_notices() {
	if ( isset( $_GET['sl_theme_activation'] ) && ! empty( $_GET['message'] ) ) {

		switch( $_GET['sl_theme_activation'] ) {

			case 'false':
				$message = urldecode( $_GET['message'] ); ?>

				<div class="error"><p><?php echo $message; ?></p></div>
				<?php break;

			case 'true':
			default:
				break;

		}
	}
}
add_action( 'admin_notices', 'edd_sample_theme_admin_notices' );