diff --git a/classes/class-lsx-api-manager.php b/classes/class-lsx-api-manager.php
new file mode 100644
index 0000000..f018533
--- /dev/null
+++ b/classes/class-lsx-api-manager.php
@@ -0,0 +1,505 @@
+dev_mode = true;
+ $api_array['api_key'] = preg_replace('/^(dev-)(.*)$/i', '${2}', $api_array['api_key']);
+ }
+ $this->api_key = $api_array['api_key'];
+ }
+ if(isset($api_array['email'])){
+ $this->email = trim($api_array['email']);
+ }
+ if(isset($api_array['product_id'])){
+ $this->product_id = $api_array['product_id'];
+ $this->product_slug = sanitize_title($api_array['product_id']);
+ }
+ if(isset($api_array['version'])){
+ $this->version = $api_array['version'];
+ }
+ if(isset($api_array['instance'])){
+ $this->password = $api_array['instance'];
+ }
+ if(isset($api_array['file'])){
+ $this->file = $api_array['file'];
+ }
+
+ if(isset($api_array['documentation'])){
+ $this->documentation = $api_array['documentation'];
+ }
+
+ if ($this->dev_mode) {
+ $this->api_url = 'https://dev.lsdev.biz/wc-api/product-key-api';
+ $this->products_api_url = 'https://dev.lsdev.biz/';
+ $this->license_check_url = 'https://dev.lsdev.biz/wc-api/license-status-check';
+ } else {
+ $this->api_url = 'https://www.lsdev.biz/wc-api/product-key-api';
+ $this->products_api_url = 'https://www.lsdev.biz/';
+ $this->license_check_url = 'https://www.lsdev.biz/wc-api/license-status-check';
+ }
+
+ add_filter( 'plugin_action_links_' . plugin_basename(str_replace('.php','',$this->file).'/'.$this->file), array($this,'add_action_links'));
+ $this->status = get_option($this->product_slug.'_status',false);
+
+ if(isset($_GET['page']) && in_array($_GET['page'],apply_filters('lsx_api_manager_options_pages',array(false)))){
+
+ //Maybe activate the software, do this before the status checks.
+ $this->activate_deactivate();
+
+ if(false === $this->status){
+ $this->status = $this->check_status();
+ update_option($this->product_slug.'_status',$this->status);
+ }
+
+ $button_url = ''.$button_label.'';
+ $this->button = $button_url;
+ }
+
+ add_filter('site_transient_update_plugins', array($this,'injectUpdate'));
+ add_action( "in_plugin_update_message-".$this->file,array($this,'plugin_update_message'),10,2);
+
+ if ( function_exists( 'tour_operator' ) ) {
+ add_action( 'lsx_to_framework_api_tab_content', array( $this, 'dashboard_tabs' ), 1, 1 );
+ } else {
+ add_action( 'lsx_framework_api_tab_content', array( $this, 'dashboard_tabs' ), 1, 1 );
+ }
+
+ add_action('wp_ajax_wc_api_'.$this->product_slug,array($this,'activate_deactivate'));
+ add_action('wp_ajax_nopriv_wc_api_'.$this->product_slug,array($this,'activate_deactivate'));
+ }
+
+ /**
+ * Return an instance of this class.
+ *
+ * @since 1.0.0
+ *
+ * @return object A single instance of this class.
+ */
+ public static function get_instance() {
+ // If the single instance hasn't been set, set it now.
+ if ( null == self::$instance ) {
+ self::$instance = new self;
+ }
+ return self::$instance;
+ }
+
+ /**
+ * Outputs the dashboard tab pages.
+ *
+ * @since 1.0.0
+ *
+ * @return object A single instance of this class.
+ */
+ public function dashboard_tabs($tab='general') {
+ if('api' !== $tab){ return false;}
+
+ if('active' === $this->status){
+ $description = __( 'Your license is now active', $this->product_slug );
+ }else{
+ $description = __( 'You can find your key on your My Account page.', $this->product_slug );
+ }
+
+ ?>
+
+
+
+ status){
+ $colour = 'green';
+ }
+ ?>
+
+
+ product_id; ?>
+ - version; ?>
+ - status; ?>
+ - button; ?>
+
+
+ dev_mode && is_array( $this->messages ) ) { ?>messages ); ?>
+
+ |
+
+
+
+
+ product_slug ); ?>
+ |
+
+ product_slug; ?>_email}} value="{{product_slug; ?>_email}}" {{/if}} name="product_slug; ?>_email" />
+ |
+
+
+
+
+ product_slug ); ?>
+ |
+
+ product_slug; ?>_api_key}} value="{{product_slug; ?>_api_key}}" {{/if}} name="product_slug; ?>_api_key" />
+ |
+
+
+ settings_page_scripts();
+ }
+
+ /**
+ * outputs the scripts for the dashboard settings pages.
+ */
+ public function settings_page_scripts(){ ?>
+ {{#script}}
+ jQuery( function( $ ){
+ $( '.product_slug; ?>-api-email-wrap input' ).on( 'change', function() {
+ $('input[name="product_slug; ?>_api_action"]').remove();
+
+ var action = 'activate';
+ if('' == $(this).val() || undefined == $(this).val()){
+ action = 'deactivate';
+ }
+ $('.product_slug; ?>-wrap').append('');
+ });
+
+ $( '.activate[data-product="product_slug; ?>"]' ).on( 'click', function() {
+ event.preventDefault();
+ console.log('hello');
+ var url = $(this).attr('href');
+ $( window ).on('uix.saved',function() {
+ window.location.href = url;
+ });
+ $('button[data-save-object="true"]').click();
+ });
+ });
+ {{/script}}
+ product_slug === $_GET['product']
+ && false !== $this->api_key && '' !== $this->api_key
+ && false !== $this->email && '' !== $this->email){
+
+
+ $response = $this->query('activation');
+ if(is_object($response) && isset($response->activated) && true === $response->activated){
+ update_option($this->product_slug.'_status','active');
+ $this->status = 'active';
+ }
+ }
+
+ if((isset($_GET['action']) && 'deactivate' === $_GET['action'] && isset($_GET['product']) && $this->product_slug === $_GET['product'])
+ || (false === $this->api_key || '' === $this->api_key || false === $this->email || '' === $this->email)){
+
+ if('active' === $this->status) {
+ $this->query('deactivation');
+ update_option($this->product_slug.'_status','inactive');
+ $this->status = 'inactive';
+ }
+ }
+ }
+
+ /**
+ * Generates the API URL
+ */
+ public function create_software_api_url( $args ) {
+
+ $endpoint = 'am-software-api';
+ if('pluginupdatecheck' === $args['request']){
+ $endpoint = 'upgrade-api';
+ }
+ $api_url = add_query_arg( 'wc-api', $endpoint, $this->products_api_url );
+ return $api_url . '&' . http_build_query( $args );
+ }
+
+ /**
+ * Checks if the software is activated or deactivated
+ * @return string
+ */
+ public function check_status($response = false) {
+ if(false === $response){
+ $response = $this->query('status');
+ }
+ if ( $this->dev_mode ) {
+ $this->messages[] = print_r( $response, true );
+ }
+ $status = 'inactive';
+ if(is_object($response)){
+
+ if(isset($response->error)){
+ $this->messages[] = $this->format_error_code($response->code);
+ }elseif(isset($response->status_check)){
+ $status = $response->status_check;
+ if(isset($response->activations_remaining)){
+ $this->messages[] = $response->activations_remaining;
+ }
+ if(isset($response->message)){
+ $this->messages[] = $response->message;
+ }
+ }
+ }
+ return $status;
+ }
+
+ /**
+ * Does the actual contacting to the API.
+ * @param string $action
+ * @return array
+ */
+ public function query($action='status') {
+ if ( 'status' === $action ) {
+ $transient_status_id = 'lsx_addon_' . $this->product_id . '_status';
+ $response = get_transient( $transient_status_id );
+ } else {
+ $response = false;
+ }
+
+ if ( ! $response ) {
+ $args = array(
+ 'request' => $action,
+ 'email' => $this->email,
+ 'licence_key' => $this->api_key,
+ 'product_id' => $this->product_id,
+ 'platform' => home_url(),
+ 'instance' => $this->password
+ );
+ $target_url = esc_url_raw( $this->create_software_api_url( $args ) );
+
+ $request = wp_remote_get( $target_url );
+ if( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) != 200 ) {
+ // Request failed
+ return false;
+ }
+ $response = wp_remote_retrieve_body( $request );
+ if ( $this->dev_mode ) {
+ $this->messages[] = print_r( $response, true );
+ }
+ set_transient( $transient_status_id, $response, MINUTE_IN_SECONDS );
+ }
+
+ return json_decode($response);
+ }
+
+ /**
+ * Formats the error code into a readable format.
+ * @param array $args
+ * @return array
+ */
+ public function format_error_code($code=false){
+ switch ( $code ) {
+ case '101' :
+ $error = array( 'error' => esc_html__( 'Invalid API License Key. Login to your My Account page to find a valid API License Key', $this->product_slug ), 'code' => '101' );
+ break;
+ case '102' :
+ $error = array( 'error' => esc_html__( 'Software has been deactivated', $this->product_slug ), 'code' => '102' );
+ break;
+ case '103' :
+ $error = array( 'error' => esc_html__( 'Exceeded maximum number of activations', $this->product_slug ), 'code' => '103' );
+ break;
+ case '104' :
+ $error = array( 'error' => esc_html__( 'Invalid Instance ID', $this->product_slug ), 'code' => '104' );
+ break;
+ case '105' :
+ $error = array( 'error' => esc_html__( 'Invalid API License Key', $this->product_slug ), 'code' => '105' );
+ break;
+ case '106' :
+ $error = array( 'error' => esc_html__( 'Subscription Is Not Active', $this->product_slug ), 'code' => '106' );
+ break;
+ default :
+ $error = array( 'error' => esc_html__( 'Invalid Request', $this->product_slug ), 'code' => '100' );
+ break;
+ }
+ }
+
+ public static function generatePassword($length = 20) {
+ $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $count = mb_strlen($chars);
+
+ for ($i = 0, $result = ''; $i < $length; $i++) {
+ $index = rand(0, $count - 1);
+ $result .= mb_substr($chars, $index, 1);
+ }
+
+ return $result;
+ }
+
+ public function set_update_status(){
+ $this->status = $this->check_status();
+ $this->upgrade_response = get_transient($this->product_slug.'_upgrade_response',false);
+
+ if(false !== $this->upgrade_response){
+ $this->upgrade_response = maybe_unserialize($this->upgrade_response);
+ }
+
+ if(isset($this->status) && 'active' === $this->status && false === $this->upgrade_response){
+ $args = array(
+ 'request' => 'pluginupdatecheck',
+ 'plugin_name' => $this->product_slug.'/'.$this->file,
+ 'version' => $this->product_slug,
+ 'activation_email' => $this->email,
+ 'api_key' => $this->api_key,
+ 'product_id' => $this->product_id,
+ 'domain' => home_url(),
+ 'instance' => $this->password,
+ 'software_version' => $this->version,
+ );
+ $target_url = esc_url_raw( $this->create_software_api_url( $args ) );
+ $request = wp_remote_get( $target_url );
+ if( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) != 200 ) {
+ // Request failed
+ $this->upgrade_response=false;
+ }
+ $response = wp_remote_retrieve_body( $request );
+ $this->upgrade_response = maybe_unserialize($response);
+ set_transient($this->product_slug . '_upgrade_response', $response, 60 * 30);
+ }
+ }
+
+ /**
+ * Insert the latest update (if any) into the update list maintained by WP.
+ *
+ * @param StdClass $updates Update list.
+ * @return StdClass Modified update list.
+ */
+ public function injectUpdate($updates=false){
+ $this->set_update_status();
+ if(isset($this->status) && 'active' === $this->status && null !== $this->upgrade_response && is_object($this->upgrade_response) && isset($this->upgrade_response->new_version) && version_compare ( $this->upgrade_response->new_version , $this->version , '>' )){
+
+ //setup the response if our plugin is the only one that needs updating.
+ if ( !is_object($updates) ) {
+ $updates = new StdClass();
+ $updates->response = array();
+ }
+ $updates->response[$this->product_slug.'/'.$this->file] = $this->upgrade_response;
+ }
+ return $updates;
+ }
+
+ /**
+ * Adds in the "settings" link for the plugins.php page
+ */
+ public function add_action_links ( $links ) {
+ $admin_url_base = function_exists( 'tour_operator' ) ? 'admin.php?page=lsx-to-settings' : 'themes.php?page=lsx-settings';
+ $documentation = $this->product_slug;
+ if(false !== $this->documentation){$documentation = $this->documentation; }
+ $mylinks = array(
+ ''.esc_html__('Settings',$this->product_slug).'',
+ ''.esc_html__('Documentation',$this->product_slug).'',
+ ''.esc_html__('Support',$this->product_slug).'',
+ );
+ return array_merge( $links, $mylinks );
+ }
+}