load_textdomain(); $this->wpo_update_api = apply_filters( 'wpovernight_api_url', 'https://wpovernight.com/license-api/' ); $this->plugin_item_name = $_item_name; $this->plugin_file = $_file; $this->plugin_basename = plugin_basename( $_file ); $this->plugin_slug = dirname( $this->plugin_basename ); $this->plugin_license_slug = $_license_slug; $this->plugin_version = $_version; $this->plugin_author = $_author; $this->license_keys_option_name = 'wpocore_settings'; $this->license_key = $this->get_license_key(); if( ! class_exists( '\\WPO\\EDD_SL_Plugin_Updater' ) ) { // load the EDD updater class include( dirname( __FILE__ ) . '/EDD_SL_Plugin_Updater.php' ); } add_filter( 'edd_sl_plugin_updater_api_params', array( $this, 'set_url_for_version_request' ), 10, 3 ); $this->load_edd_updater(); add_action( 'admin_init', array( $this, 'disable_subsite_update_notifications' ) ); add_action( 'wp_ajax_wpo_updater_licence_key_action_'.$this->plugin_license_slug, array( $this, 'ajax_remote_license_actions' ) ); add_filter( 'http_response', array( $this, 'unauthorized_response'), 10, 3 ); add_filter( 'network_admin_plugin_action_links_' . $this->plugin_basename, array( $this, 'add_license_activation_link' ), 10, 4 ); add_filter( 'plugin_action_links_' . $this->plugin_basename, array( $this, 'add_license_activation_link' ), 10, 4 ); add_action( 'after_plugin_row_' . $this->plugin_basename, array( $this, 'plugin_license_field' ), 10, 3 ); add_action( 'admin_enqueue_scripts', array( $this, 'scripts_styles' ) ); } public function load_textdomain() { load_plugin_textdomain( 'wpo-updater', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); } public function scripts_styles( $hook ) { if ( $hook === 'plugins.php' && ! wp_script_is( 'wpo-update-helper', 'enqueued' ) ) { wp_enqueue_style( 'wpo-update-helper', plugin_dir_url( __FILE__ ) . 'assets/style.css', array(), $this->version ); wp_enqueue_script( 'wpo-update-helper', plugin_dir_url( __FILE__ ) . 'assets/script.js', array( 'jquery' ), $this->version ); wp_localize_script( 'wpo-update-helper', 'wpo_update_helper', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'wpo_update_helper' ), ) ); } } public function add_license_activation_link( $actions, $plugin_file = '', $plugin_data = array(), $context = '' ) { if ( $this->should_show_license_manager() ) { $actions['wpo_license'] = sprintf( '%3$s', esc_attr( $this->plugin_license_slug ), esc_attr( $this->plugin_slug ), esc_html__( 'Manage license', 'wpo-updater' ) ); } return $actions; } public function plugin_license_field( $file, $plugin, $status = '' ) { if ( ! $this->should_show_license_manager() ) { return; } ?> license_key ) ) { $this->plugin_license_field_content(); } else { ?>
plugin_basename ) ) { // multisite & network active: show only on network admin $show = is_network_admin(); } else { // single site OR multisite and not active on network: only show on the subsite $show = ! is_network_admin(); } return apply_filters( 'wpo_updater_show_license_manager', $show, $this->plugin_slug ); } public function plugin_license_field_content( $action_args = array() ) { $name = "wpocore_settings[{$this->plugin_license_slug}]"; if ( array_key_exists( 'license_key', $action_args ) ) { $this->license_key = $action_args['license_key']; } if ( empty( $action_args ) ) { if ( ! empty( $this->license_key ) ) { $action_args = array( 'edd_action' => 'check_license', 'license_key' => trim( $this->license_key ), ); } else { $action_args = array(); } } $status = $this->remote_license_actions( $action_args ); if ( is_object( $status ) && isset( $status->license ) ) { $activation_status = $status->license; } elseif ( is_string( $status ) ) { $activation_status = $status; } else { $activation_status = ''; } if ( empty( $this->license_key ) ) { $notice_class = 'notice-warning notice-alt'; } else { $notice_class = 'notice-alt'; } // allow setting license field to password if ( apply_filters( 'wpo_update_helper_shield_license_field', false ) ) { $license_field_type = 'password'; } else { $license_field_type = 'text'; } ?>

license_key ) ): ?>

license_state_message ) ? esc_html( $status->license_state_message ) : ''; ?> action_message ) ): ?>
action_message ); ?>

license_info ) ? wp_kses_post( $status->license_info ) : ''; ?>

license_key ) ) { return false; } else { return true; } } /** * Load the EDD Updater class */ public function load_edd_updater() { // setup the updater if ( ! empty( $this->license_key ) ) { $this->edd_updater = new \WPO\EDD_SL_Plugin_Updater( $this->wpo_update_api, $this->plugin_file, array( 'version' => $this->plugin_version, // current version number 'license' => $this->license_key, // license key (used get_option above to retrieve from DB) 'item_name' => $this->plugin_item_name, // name of this plugin 'author' => $this->plugin_author // author of this plugin ) ); } } /** * Don't show update notifications on subsites when plugin is network activated */ public function disable_subsite_update_notifications() { if ( is_multisite() && ! is_network_admin() && is_plugin_active_for_network( $this->plugin_basename ) && ! empty( $this->edd_updater ) && method_exists( $this->edd_updater, 'show_update_notification' ) ) { remove_action( 'after_plugin_row', array( $this->edd_updater, 'show_update_notification' ) ); } } public function ajax_remote_license_actions() { check_ajax_referer( "wpo_update_helper", 'security' ); if ( empty( $_POST['remote_edd_action'] ) ) { return; } if ($_POST['remote_edd_action'] == 'show_license') { $args = array( 'edd_action' => 'check_license', 'license_key' => trim( $this->license_key ), ); } else { $args = array( 'edd_action' => $_POST['remote_edd_action'], 'license_key' => trim( $_POST['license_key'] ), ); } ob_start(); $this->plugin_license_field_content( $args ); $html = ob_get_clean(); wp_send_json( array('html' => $html ) ); } /************************************ * Activate/deactivate license key *************************************/ public function remote_license_actions( $args ) { if ( empty( $args['edd_action'] ) ) { return; } // retrieve the license from the database $this->save_license_key( $args['license_key'] ); if ( empty( $args['license_key'] ) ) { $response = array( 'action_message' => __( 'Please enter a license key.', 'wpo-updater' ), 'license_info' => '', 'license_state' => 'incomplete', 'license_state_message' => __( 'invalid', 'wpo-updater' ), ); return (object) $response; } // data to send in our API request $api_params = array( 'edd_action' => $args['edd_action'], 'license' => $args['license_key'], 'item_name' => urlencode( $this->plugin_item_name ), // the name of our product in EDD 'url' => $this->get_home_url(), // License server has a fallback to the User-Agent, but this could have been filtered so we can't rely on it ); $response = $this->edd_api_action( $api_params ); if ( isset( $response->wp_error ) ) { /* translators: 1. error message, 2. error code, 3. host IP */ $message = sprintf( __( 'API Error: %1$s (%2$s), IP: %3$s', 'wpo-updater' ), $response->wp_error, $response->error_code, $this->get_host_ip() ); $response->action_message = $message; $response->license_state = 'incomplete'; $response->license_state_message = __( 'unknown', 'wpo-updater' ); $response->license_info = '-'; return $response; } if ( isset( $response->expires ) ) { if ( $response->expires == 'lifetime' ) { $exp_date = __( 'Forever', 'wpo-updater' ); } else { $exp_date = date_i18n( get_option( 'date_format' ), strtotime( $response->expires ) ); } } switch ( $response->license ) { case 'valid': if ( $args['edd_action'] == 'activate_licese' ) { $response->action_message = __( 'Activated your license for this site.', 'wpo-updater' ); } $response->license_state = 'valid'; $response->license_state_message = __( 'valid', 'wpo-updater' ); /* translators: 1. expiration date, 2. active sites count, 3. license limit count */ $response->license_info = sprintf( __( 'This license is valid until: %1$s (Active sites: %2$s / %3$s)', 'wpo-updater' ), $exp_date, $response->site_count, $response->license_limit ); break; case 'deactivated': // get activation count & limit $api_params = array( 'edd_action'=> 'check_license', 'license' => $args['license_key'], 'item_name' => urlencode( $this->plugin_item_name ), // the name of our product in EDD ); $check_response = $this->edd_api_action( $api_params ); $exp_date = date_i18n( get_option( 'date_format' ), strtotime( $check_response->expires ) ); $license_limit = $check_response->license_limit; $site_count = $check_response->site_count; $response->action_message = __( 'Deactivated your license for this site.', 'wpo-updater' ); $response->license_state = 'invalid'; $response->license_state_message = __( 'deactivated', 'wpo-updater' ); $response->license_info = sprintf( __( 'This license is valid until: %1$s (Active sites: %2$s / %3$s)', 'wpo-updater' ), $exp_date, $site_count, $license_limit ); break; case 'expired': $response->license_state = 'invalid'; $response->license_state_message = __( 'expired', 'wpo-updater' ); $response->license_info = __( 'This license was valid until: ' . $exp_date, 'wpo-updater' ); break; case 'inactive': case 'site_inactive': $response->license_state = 'valid'; $response->license_state_message = __( 'valid', 'wpo-updater' ); $response->license_info = sprintf( __( 'This license is valid until: %1$s (Active sites: %2$s / %3$s)', 'wpo-updater' ), $exp_date, $response->site_count, $response->license_limit ); break; case 'failed': $response->action_message = __( 'Deactivated your license for this site.', 'wpo-updater' ); $response->license_state = 'invalid'; $response->license_state_message = __( 'invalid', 'wpo-updater' ); $response->license_info = ''; break; case 'invalid': $error = ! empty( $response->error ) ? $response->error : ''; if ( $error == 'missing' ) { $response->action_message = __( 'Your license key was incorrect.', 'wpo-updater' ); $response->license_state = 'incomplete'; $response->license_state_message = __( 'invalid', 'wpo-updater' ); $response->license_info = __( 'Please enter the correct license key.', 'wpo-updater' ); } elseif ( $error == 'expired' ) { $response->action_message = __( 'Your license key is expired.', 'wpo-updater' ); $response->license_state = 'incomplete'; $response->license_state_message = __( 'expired', 'wpo-updater' ); /* translators: expiration date */ $response->license_info = sprintf( __( 'This license was valid until: %s', 'wpo-updater' ), $exp_date ); } elseif ($error == 'no_activations_left') { /* translators: tags */ $response->action_message = sprintf( __( 'No Activations Left — Please visit %1$sMy Account%2$s to upgrade your license or deactivate a previous activation.', 'wpo-updater' ), '', '' ); $response->license_state = 'incomplete'; $response->license_state_message = __( 'invalid', 'wpo-updater' ); $response->license_info = ''; } else { $response->action_message = __( 'Please enter the correct license key.', 'wpo-updater' ); $response->license_info = ''; $response->license_state = 'incomplete'; $response->license_state_message = __( 'invalid', 'wpo-updater' ); } break; default: break; } return $response; } public function edd_api_action( $api_params ) { // Call the WPO API. $response = wp_remote_get( esc_url_raw( add_query_arg( $api_params, $this->wpo_update_api ) ), array( 'timeout' => 15, 'sslverify' => true ) ); // make sure the response came back okay if ( is_wp_error( $response ) ) { $error_response = new stdClass(); $error_response->wp_error = $response->get_error_message(); $error_response->error_code = $response->get_error_code(); return $error_response; } if ( wp_remote_retrieve_response_code( $response ) !== 200 ) { $error_response = new stdClass(); $error_body = wp_remote_retrieve_body( $response ); if ( strpos( $error_body, 'Wordfence' ) !== false ) { $error_response->wp_error = __( 'Your site host is blocked by the Wordfence network, please contact support@wpovernight.com with this error message.', 'wpo-updater' ); } else { $error_response->wp_error = esc_html( sanitize_text_field( strip_tags( $error_body ) ) ); } $error_response->error_code = wp_remote_retrieve_response_code( $response ); return $error_response; } // decode the license data $response = json_decode( wp_remote_retrieve_body( $response ) ); return $response; } public function unauthorized_response( $response, $args, $url ) { if ( ! is_wp_error( $response ) && is_array( $response ) && isset( $response['response'] ) && is_array( $response['response'] ) ) { if ( isset( $response['response']['code'] ) && $response['response']['code'] == 401 ) { // we have a 401 response, check if it's ours $license_server = 'https://wpovernight.com'; if ( strpos( $url, $license_server ) !== false && strpos( $url, 'package_download' ) !== false ) { // this is our request // extract values from token $url_parts = parse_url( $url ); $paths = array_values( explode( '/', $url_parts['path'] ) ); $token = end( $paths ); $values = explode( ':', base64_decode( $token ) ); if ( count( $values ) !== 6 ) { $response['response']['message'] = __( 'Invalid token supplied', 'wpo-updater' ); return $response; } $expires = $values[0]; $license_key = $values[1]; $download_id = (int) $values[2]; $url = str_replace( '@', ':', $values[4] ); $download_beta = (bool) $values[5]; // Check_license response with the above vars // data to send in our API request $api_params = array( 'edd_action' => 'check_license', 'url' => $url, 'license' => $license_key, 'item_id' => $download_id, ); if ( $check_response = $this->edd_api_action( $api_params ) ) { if ( isset( $check_response->license ) ) { switch( $check_response->license ) { case 'expired': $message = __( 'Your license has expired, please renew it to install this update.', 'wpo-updater' ); break; case 'inactive': case 'site_inactive': /* translators: site URL */ $message = sprintf( __( 'Your license has not been activated for this site (%s), please activate it first.', 'wpo-updater' ), str_replace( array('http://','https://'), '', $url ) ); break; case 'disabled': $message = __( 'Your license has been disabled.', 'wpo-updater' ); break; case 'valid': $message = ""; break; default: $message = __( 'Your license could not be validated.', 'wpo-updater' ); break; } } elseif ( isset( $check_response->wp_error ) ) { $message = sprintf( __( 'API Error: %1$s (%2$s), IP: %3$s', 'wpo-updater' ), $check_response->wp_error, $check_response->error_code, $this->get_host_ip() ); } } else { $message = __( 'License key expired or not activated for URL', 'wpo-updater' ); } $response['response']['message'] = esc_html( $message ); return $response; } } } return $response; } public function get_host_ip() { $response = wp_remote_get( 'https://icanhazip.com', array( 'timeout' => 15, 'sslverify' => true ) ); if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) { $ip = __( 'unknown', 'wpo-updater' ); } else { $ip = wp_remote_retrieve_body( $response ); // get v4 if we only have v6 if ( strpos( $ip, ':' ) !== false ) { $response = wp_remote_get( 'https://ipv4.icanhazip.com', array( 'timeout' => 15, 'sslverify' => true ) ); if ( !is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) { $ipv4 = wp_remote_retrieve_body( $response ); $ip = "{$ip} / {$ipv4}"; } } } return $ip; } /** * Sets the URL parameter sent in the API request that gets the current version information, * so that it matches what we pass during activation * * @since 2.1.2 * @param array $api_params The array of data sent in the request. * @param array $api_data The array of data set up in the class constructor. * @param string $plugin_file The full path and filename of the file. * * @return array $api_params */ public function set_url_for_version_request( $api_params, $api_data, $plugin_file ) { if ( $plugin_file === $this->plugin_file ) { $api_params['url'] = $this->get_home_url(); } return $api_params; } /** * Gets the "Site Address (URL)", using the default language in case WPML is installed * * @since 2.1.2 * @return string */ public function get_home_url() { global $sitepress; if ( is_callable( array( $sitepress, 'language_url' ) ) && is_callable( array( $sitepress, 'get_default_language' ) ) ) { // this is the same function that is used when using the wpml_home_url filter, // except that filter always passes $sitepress->get_current_language() $home_url = $sitepress->language_url( $sitepress->get_default_language() ); } else { $home_url = home_url(); } return $home_url; } /** * Get the license key * * @since 2.1.3 * @return string */ public function get_license_key() { if ( ! function_exists( 'is_plugin_active_for_network' ) ) { include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); } if ( is_multisite() && is_plugin_active_for_network( $this->plugin_basename ) ) { $wpo_license_keys = get_blog_option( get_main_site_id(), $this->license_keys_option_name, array() ); } elseif ( is_multisite() && ! is_plugin_active_for_network( $this->plugin_basename ) ) { $wpo_license_keys = get_blog_option( get_current_blog_id(), $this->license_keys_option_name, array() ); } else { $wpo_license_keys = get_option( $this->license_keys_option_name, array() ); } $license_key = isset( $wpo_license_keys[$this->plugin_license_slug] ) ? $wpo_license_keys[$this->plugin_license_slug] : ''; return $license_key; } /** * Save the license key * * @since 2.1.3 * @param string $license_key The plugin license key. * @return void */ public function save_license_key( $license_key ) { if ( ! function_exists( 'is_plugin_active_for_network' ) ) { include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); } if ( is_multisite() && is_plugin_active_for_network( $this->plugin_basename ) ) { $wpo_license_keys = get_blog_option( get_main_site_id(), $this->license_keys_option_name, array() ); $wpo_license_keys[$this->plugin_license_slug] = $license_key; update_blog_option( get_main_site_id(), $this->license_keys_option_name, $wpo_license_keys ); } elseif ( is_multisite() && ! is_plugin_active_for_network( $this->plugin_basename ) ) { $wpo_license_keys = get_blog_option( get_current_blog_id(), $this->license_keys_option_name, array() ); $wpo_license_keys[$this->plugin_license_slug] = $license_key; update_blog_option( get_current_blog_id(), $this->license_keys_option_name, $wpo_license_keys ); } else { $wpo_license_keys = get_option( $this->license_keys_option_name, array() ); $wpo_license_keys[$this->plugin_license_slug] = $license_key; update_option( $this->license_keys_option_name, $wpo_license_keys ); } } }