laipower/wp-content/plugins/easy-digital-downloads/src/Extensions/Handler.php

408 lines
9.5 KiB
PHP

<?php
/**
* License handler for extensions using the ExtensionRegistry.
*
* @since 3.1.1.4
*/
namespace EDD\Extensions;
use EDD\Licensing\API;
use EDD\Licensing\License;
use EDD\Admin\Pass_Manager;
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Handler Class
*/
class Handler {
/**
* The license key.
*
* @var string
*/
private $license_key;
/**
* The plugin file.
*
* @var string
*/
private $file;
/**
* The extension name.
*
* @var string
*/
private $item_name;
/**
* The extension item ID.
*
* @var int
*/
private $item_id;
/**
* The extension shortname.
*
* @var string
*/
private $item_shortname;
/**
* The extension version.
*
* @var string
*/
private $version;
/**
* The pass manager.
*
* @var \EDD\Admin\Pass_Manager
*/
private $pass_manager;
/**
* The EDD license object.
* This contains standard license data (from the API response) and the license key.
*
* @var \EDD\Licensing\License
*/
private $edd_license;
/**
* Whether the license being checked is a pro license.
*
* @since 3.1.1
* @var bool
*/
private $is_pro_license = false;
/**
* Class constructor
*
* @param string $_file
* @param int $_item_id
* @param string $_item_name
* @param string $_version
* @param string $_optname
*/
public function __construct( $_file, $_item_id, $_item_name, $_version, $_optname = null ) {
$this->file = $_file;
$this->item_id = absint( $_item_id );
$this->item_name = $_item_name;
$this->item_shortname = $this->get_shortname();
$this->version = $_version;
$this->edd_license = new License( $this->item_name, $_optname );
if ( empty( $this->edd_license->key ) || empty( $this->edd_license->license ) ) {
$pro_license = new License( 'pro' );
if ( ! empty( $pro_license->key ) ) {
$this->is_pro_license = true;
$this->edd_license = $pro_license;
}
}
$this->license_key = $this->edd_license->key;
$this->pass_manager = new Pass_Manager();
$this->hooks();
$this->update_global();
}
/**
* Set up hooks.
*
* @access private
* @return void
*/
private function hooks() {
// Register settings.
add_filter( 'edd_settings_licenses', array( $this, 'settings' ), 1 );
// Check that license is valid once per week.
if ( ! $this->is_pro_license || ! $this->is_included_in_pass() ) {
add_action( 'edd_weekly_scheduled_events', array( $this, 'weekly_license_check' ) );
}
// Updater.
add_action( 'init', array( $this, 'auto_updater' ) );
// Display notices to admins.
add_action( 'admin_notices', array( $this, 'notices' ) );
add_action( 'in_plugin_update_message-' . plugin_basename( $this->file ), array( $this, 'plugin_row_license_missing' ), 10, 2 );
// Register plugins for beta support.
add_filter( 'edd_beta_enabled_extensions', array( $this, 'register_beta_support' ) );
}
/**
* Auto updater
*
* @return void
*/
public function auto_updater() {
if ( ! current_user_can( 'manage_options' ) && ! edd_doing_cron() ) {
return;
}
// Fall back to the highest license key if one is not saved for this extension or there isn't a pro license.
if ( empty( $this->license_key ) ) {
if ( $this->pass_manager->highest_license_key ) {
$this->license_key = $this->pass_manager->highest_license_key;
}
}
// Don't check for updates if there isn't a license key.
if ( empty( $this->license_key ) ) {
return;
}
$args = array(
'version' => $this->version,
'license' => $this->license_key,
'item_id' => $this->item_id,
'beta' => function_exists( 'edd_extension_has_beta_support' ) && edd_extension_has_beta_support( $this->item_shortname ),
);
// Set up the updater.
new Updater(
$this->file,
$args
);
}
/**
* Add license field to settings, unless the extension is included in the user's pass.
*
* @param array $settings
* @return array
*/
public function settings( $settings ) {
if ( $this->is_pro_license && $this->is_included_in_pass() ) {
return $settings;
}
return array_merge(
$settings,
array(
array(
'id' => "{$this->item_shortname}_license_key",
'name' => $this->item_name,
'type' => 'license_key',
'options' => array(
'is_valid_license_option' => "{$this->item_shortname}_license_active",
'item_id' => $this->item_id,
),
),
)
);
}
/**
* Check if license key is valid once per week
*
* @since 2.5
* @return void
*/
public function weekly_license_check() {
// Don't fire when saving settings.
if ( ! empty( $_POST['edd_settings'] ) ) {
return;
}
if ( empty( $this->license_key ) ) {
return;
}
if ( ! edd_doing_cron() ) {
return;
}
// data to send in our API request
$api_params = array(
'edd_action' => 'check_license',
'license' => $this->license_key,
'item_name' => urlencode( $this->item_name ),
'item_id' => $this->item_id,
);
$api_handler = new API();
$license_data = $api_handler->make_request( $api_params );
if ( ! $license_data ) {
return false;
}
$this->pass_manager->maybe_set_pass_flag( $this->license_key, $license_data );
$this->edd_license->save( $license_data );
}
/**
* Admin notices for errors.
*
* @return void
*/
public function notices() {
if ( ! $this->should_show_error_notice() ) {
return;
}
EDD()->notices->add_notice(
array(
'id' => 'edd-missing-license',
'class' => "error {$this->item_shortname}-license-error",
'message' => sprintf(
/* translators: 1. opening anchor tag; 2. closing anchor tag */
__( 'You have invalid or expired license keys for Easy Digital Downloads. %1$sActivate License(s)%2$s', 'easy-digital-downloads' ),
'<a href="' . esc_url( $this->get_license_tab_url() ) . '" class="button button-secondary">',
'</a>'
),
'is_dismissible' => false,
)
);
}
/**
* Displays message inline on plugin row that the license key is missing
*
* @since 2.5
* @return void
*/
public function plugin_row_license_missing( $plugin_data, $version_info ) {
static $showed_imissing_key_message = array();
if ( ! $this->is_license_valid() && empty( $showed_imissing_key_message[ $this->item_shortname ] ) ) {
echo '&nbsp;<strong><a href="' . esc_url( $this->get_license_tab_url() ) . '">' . esc_html__( 'Enter valid license key for automatic updates.', 'easy-digital-downloads' ) . '</a></strong>';
$showed_imissing_key_message[ $this->item_shortname ] = true;
}
}
/**
* Adds this plugin to the beta page
*
* @param array $products
* @since 2.6.11
* @return array
*/
public function register_beta_support( $products ) {
$products[ $this->item_shortname ] = $this->item_name;
return $products;
}
/**
* Gets the URL for the licensing tab.
*
* @since 3.1.1.4
* @return string
*/
private function get_license_tab_url() {
return edd_get_admin_url(
array(
'page' => 'edd-settings',
'tab' => 'licenses',
)
);
}
/**
* Whether the license is valid.
*
* @since 3.1.1.4
* @return bool
*/
private function is_license_valid() {
return ! empty( $this->license_key ) && 'valid' === $this->edd_license->license;
}
/**
* Gets the extension shortname.
*
* @since 3.1.1.4
* @return string
*/
private function get_shortname() {
return 'edd_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $this->item_name ) ) );
}
/**
* Maintain an array of active, licensed plugins that have a license key entered.
* This is to help us more easily determine if the site has a license key entered
* at all. Initializing it this way helps us limit the data to activated plugins only.
* If we relied on the options table (`edd_%_license_active`) then we could accidentally
* be picking up plugins that have since been deactivated.
*
* @see \EDD\Admin\Promos\Notices\License_Upgrade_Notice::__construct()
*/
private function update_global() {
if ( empty( $this->license_key ) ) {
return;
}
global $edd_licensed_products;
if ( ! is_array( $edd_licensed_products ) ) {
$edd_licensed_products = array();
}
$edd_licensed_products[] = $this->item_shortname;
}
/**
* Whether a given product is included in the customer's active pass.
* Note this is nearly a copy of what's in EDD\Licensing\Traits\Controls\is_included_in_pass().
*
* @since 3.1.1.4
* @return bool
*/
private function is_included_in_pass() {
// All Access and lifetime passes can access everything.
if ( $this->pass_manager->hasAllAccessPass() ) {
return true;
}
$api = new \EDD\Admin\Extensions\ExtensionsAPI();
$product_data = $api->get_product_data( array(), $this->item_id );
if ( ! $product_data || empty( $product_data->categories ) ) {
return false;
}
return (bool) $this->pass_manager->can_access_categories( $product_data->categories );
}
/**
* Helper method to determine if we should show the error notice.
*
* @since 3.1.1.4
* @return bool
*/
private function should_show_error_notice() {
// Included in pass.
if ( $this->is_included_in_pass() ) {
return false;
}
// Not a pro license, but valid.
if ( ! $this->is_pro_license && $this->is_license_valid() ) {
return false;
}
// Current user lacks permissions.
if ( ! current_user_can( 'manage_shop_settings' ) ) {
return false;
}
// It's the licenses tab.
if ( ! empty( $_GET['tab'] ) && 'licenses' === $_GET['tab'] ) {
return false;
}
return true;
}
}