item_id = absint( $_item_id );
}
$give_options = give_get_settings();
$this->file = $_file;
$this->item_name = $_item_name;
$this->item_shortname = self::get_short_name( $this->item_name );
$this->version = $_version;
$this->license = isset( $give_options[ $this->item_shortname . '_license_key' ] ) ? trim( $give_options[ $this->item_shortname . '_license_key' ] ) : '';
$this->license_data = __give_get_active_license_info( $this->item_shortname );
$this->author = $_author;
$this->api_url = is_null( $_api_url ) ? $this->api_url : $_api_url;
$this->checkout_url = is_null( $_checkout_url ) ? $this->checkout_url : $_checkout_url;
$this->account_url = is_null( $_account_url ) ? $this->account_url : $_account_url;
$this->auto_updater_obj = null;
// Add Setting for Give Add-on activation status.
$is_addon_activated = get_option( 'give_is_addon_activated' );
if ( ! $is_addon_activated && is_object( $this ) ) {
update_option( 'give_is_addon_activated', true, false );
Give_Cache::set( 'give_cache_hide_license_notice_after_activation', true, DAY_IN_SECONDS );
}
// Add plugin to registered licenses list.
array_push( self::$licensed_addons, plugin_basename( $this->file ) );
// Setup hooks
$this->includes();
$this->hooks();
}
/**
* Get plugin shortname
*
* @since 2.1.0
* @access public
*
* @param $plugin_name
*
* @return string
*/
public static function get_short_name( $plugin_name ) {
$plugin_name = trim( str_replace( 'Give - ', '', $plugin_name ) );
$plugin_name = 'give_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $plugin_name ) ) );
return $plugin_name;
}
/**
* Includes
*
* Include the updater class.
*
* @access private
* @since 1.0
*
* @return void
*/
private function includes() {
if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
require_once 'admin/EDD_SL_Plugin_Updater.php';
}
}
/**
* Hooks
*
* Setup license hooks.
*
* @access private
* @since 1.0
*
* @return void
*/
private function hooks() {
// Register settings.
add_filter( 'give_settings_licenses', array( $this, 'settings' ), 1 );
// Activate license key on settings save.
add_action( 'admin_init', array( $this, 'activate_license' ), 10 );
// Deactivate license key.
add_action( 'admin_init', array( $this, 'deactivate_license' ), 11 );
// Updater.
add_action( 'admin_init', array( $this, 'auto_updater' ), 0 );
add_action( 'admin_notices', array( $this, 'notices' ) );
// Check license weekly.
Give_Cron::add_weekly_event( array( $this, 'weekly_license_check' ) );
// Check subscription weekly.
Give_Cron::add_weekly_event( array( $this, 'weekly_subscription_check' ) );
// Show addon notice on plugin page.
$plugin_name = explode( 'plugins/', $this->file );
$plugin_name = end( $plugin_name );
add_action( "after_plugin_row_{$plugin_name}", array( $this, 'plugin_page_notices' ), 10, 3 );
}
/**
* Auto Updater
*
* @access private
* @since 1.0
*
* @return void
*/
public function auto_updater() {
if ( ! empty( $this->item_id ) ) {
$args['item_id'] = $this->item_id;
} else {
$args['item_name'] = $this->item_name;
}
// Setup the updater.
$this->auto_updater_obj = new EDD_SL_Plugin_Updater(
$this->api_url,
$this->file,
array(
'version' => $this->version,
'license' => $this->license,
'item_name' => $this->item_name,
'author' => $this->author,
)
);
}
/**
* License Settings
*
* Add license field to settings.
*
* @access public
* @since 1.0
*
* @param array $settings License settings.
*
* @return array License settings.
*/
public function settings( $settings ) {
$give_license_settings = array(
array(
'name' => $this->item_name,
'id' => $this->item_shortname . '_license_key',
'desc' => '',
'type' => 'license_key',
'options' => array(
'license' => get_option( $this->item_shortname . '_license_active' ),
'shortname' => $this->item_shortname,
'item_name' => $this->item_name,
'api_url' => $this->api_url,
'checkout_url' => $this->checkout_url,
'account_url' => $this->account_url,
),
'size' => 'regular',
),
);
return array_merge( $settings, $give_license_settings );
}
/**
* License Settings Content
*
* Add Some Content to the Licensing Settings.
*
* @access public
* @since 1.0
*
* @param array $settings License settings content.
*
* @return array License settings content.
*/
public function license_settings_content( $settings ) {
$give_license_settings = array(
array(
'name' => __( 'Add-on Licenses', 'give' ),
'desc' => '
',
'type' => 'give_title',
'id' => 'give_title',
),
);
return array_merge( $settings, $give_license_settings );
}
/**
* Activate License
*
* Activate the license key.
*
* @access public
* @since 1.0
*
* @return void
*/
public function activate_license() {
// Bailout.
if ( ! $this->__is_user_can_edit_license() ) {
return;
}
// Allow third party addon developers to handle license activation.
if ( $this->__is_third_party_addon() ) {
do_action( 'give_activate_license', $this );
return;
}
// Delete previous license setting if a empty license key submitted.
if ( empty( $_POST[ "{$this->item_shortname}_license_key" ] ) ) {
$this->unset_license();
return;
}
// Do not simultaneously activate add-ons if the user want to deactivate a specific add-on.
if ( $this->is_deactivating_license() ) {
return;
}
// Check if plugin previously installed.
if ( $this->is_valid_license() ) {
return;
}
// Get license key.
$this->license = sanitize_text_field( $_POST[ $this->item_shortname . '_license_key' ] );
// Delete previous license key from subscription if previously added.
$this->__remove_license_key_from_subscriptions();
// Make sure there are no api errors.
if ( ! ( $license_data = $this->get_license_info( 'activate_license' ) ) ) {
return;
}
// Make sure license is valid.
// return because admin will want to activate license again.
if ( ! $this->is_license( $license_data ) ) {
// Add license key.
give_update_option( "{$this->item_shortname}_license_key", $this->license );
return;
}
// Tell WordPress to look for updates.
set_site_transient( 'update_plugins', null );
// Add license data.
update_option( "{$this->item_shortname}_license_active", $license_data, false );
// Add license key.
give_update_option( "{$this->item_shortname}_license_key", $this->license );
// Check subscription for license key and store this to db (if any).
$this->__single_subscription_check();
}
/**
* Deactivate License
*
* Deactivate the license key.
*
* @access public
* @since 1.0
*
* @return void
*/
public function deactivate_license() {
// Bailout.
if ( ! $this->__is_user_can_edit_license() ) {
return;
}
// Allow third party add-on developers to handle license deactivation.
if ( $this->__is_third_party_addon() ) {
do_action( 'give_deactivate_license', $this );
return;
}
// Run on deactivate button press.
if ( isset( $_POST[ $this->item_shortname . '_license_key_deactivate' ] ) ) {
$this->unset_license();
}
}
/**
* Check if license key is valid once per week.
*
* @access public
* @since 1.7
*
* @return void
*/
public function weekly_license_check() {
if (
! empty( $_POST['give_settings'] ) ||
empty( $this->license )
) {
return;
}
// Allow third party add-on developers to handle their license check.
if ( $this->__is_third_party_addon() ) {
do_action( 'give_weekly_license_check', $this );
return;
}
// Make sure there are no api errors.
if ( ! ( $license_data = $this->get_license_info( 'check_license' ) ) ) {
return;
}
// Bailout.
if ( ! $this->is_license( $license_data ) ) {
return;
}
update_option( $this->item_shortname . '_license_active', $license_data, false );
return;
}
/**
* Check subscription validation once per week
*
* @access public
* @since 1.7
*
* @return void
*/
public function weekly_subscription_check() {
// Bailout.
if (
! empty( $_POST['give_settings'] )
|| empty( $this->license )
) {
return;
}
// Remove old subscription data.
if ( absint( get_option( '_give_subscriptions_edit_last', true ) ) < current_time( 'timestamp', 1 ) ) {
delete_option( 'give_subscriptions' );
update_option( '_give_subscriptions_edit_last', strtotime( '+ 1 day', current_time( 'timestamp', 1 ) ), false );
}
// Allow third party add-on developers to handle their subscription check.
if ( $this->__is_third_party_addon() ) {
do_action( 'give_weekly_subscription_check', $this );
return;
}
$this->__single_subscription_check();
}
/**
* Check if license key is part of subscription or not
*
* @access private
* @since 1.7
*
* @return void
*/
private function __single_subscription_check() {
if ( empty( $this->license ) ) {
return;
}
/**
* Make sure there are no api errors.
*
* Do not get confused with edd_action check_subscription.
* By default edd software licensing api does not have api to check subscription.
* This is a custom feature to check subscriptions.
*/
$subscription_data = $this->get_license_info( 'check_subscription', true );
if ( ! empty( $subscription_data['success'] ) && absint( $subscription_data['success'] ) ) {
$subscriptions = get_option( 'give_subscriptions', array() );
// Update subscription data only if subscription does not exist already.
$subscriptions[ $subscription_data['id'] ] = $subscription_data;
// Initiate default set of license for subscription.
if ( ! isset( $subscriptions[ $subscription_data['id'] ]['licenses'] ) ) {
$subscriptions[ $subscription_data['id'] ]['licenses'] = array();
}
// Store licenses for subscription.
if ( ! in_array( $this->license, $subscriptions[ $subscription_data['id'] ]['licenses'] ) ) {
$subscriptions[ $subscription_data['id'] ]['licenses'][] = $this->license;
}
update_option( 'give_subscriptions', $subscriptions, false );
}
}
/**
* Admin notices for errors
*
* @access public
* @since 1.0
*
* @return void
*/
public function notices() {
if ( ! current_user_can( 'manage_give_settings' ) ) {
return;
}
// Do not show licenses notices on license tab.
if ( 'licenses' === give_get_current_setting_tab() ) {
return;
}
static $showed_invalid_message;
static $showed_subscriptions_message;
static $addon_license_key_in_subscriptions;
// Set default value.
$addon_license_key_in_subscriptions = ! empty( $addon_license_key_in_subscriptions ) ? $addon_license_key_in_subscriptions : array();
$messages = array();
// Check whether admin has Give Add-on activated since 24 hours?
$is_license_notice_hidden = Give_Cache::get( 'give_cache_hide_license_notice_after_activation' );
// Display Invalid License notice, if its more than 24 hours since first Give Add-on activation.
if (
empty( $this->license )
&& empty( $showed_invalid_message )
&& ( false === $is_license_notice_hidden )
) {
Give()->notices->register_notice(
array(
'id' => 'give-invalid-license',
'type' => 'error',
'description' => sprintf(
__( 'You have invalid or expired license keys for one or more Give Add-ons. Please go to the licenses page to correct this issue.', 'give' ),
admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' )
),
'dismissible_type' => 'user',
'dismiss_interval' => 'shortly',
)
);
$showed_invalid_message = true;
}
// Get subscriptions.
$subscriptions = get_option( 'give_subscriptions' );
// Show subscription messages.
if ( ! empty( $subscriptions ) && ! $showed_subscriptions_message ) {
foreach ( $subscriptions as $subscription ) {
// Subscription expires timestamp.
$subscription_expires = strtotime( $subscription['expires'] );
// Start showing subscriptions message before one week of renewal date.
if ( strtotime( '- 7 days', $subscription_expires ) > current_time( 'timestamp', 1 ) ) {
continue;
}
// Check if subscription message already exist in messages.
if ( array_key_exists( $subscription['id'], $messages ) ) {
continue;
}
// Check if license already expired.
if ( strtotime( $subscription['expires'] ) < current_time( 'timestamp', 1 ) ) {
Give()->notices->register_notice(
array(
'id' => "give-expired-subscription-{$subscription['id']}",
'type' => 'error',
'description' => sprintf(
__( 'Your Give add-on license expired for payment #%2$d. Click to renew an existing license or %4$s.', 'give' ),
urldecode( $subscription['invoice_url'] ),
$subscription['payment_id'],
"{$this->checkout_url}?edd_license_key={$subscription['license_key']}&utm_campaign=admin&utm_source=licenses&utm_medium=expired",
Give()->notices->get_dismiss_link(
array(
'title' => __( 'Click here if already renewed', 'give' ),
'dismissible_type' => 'user',
'dismiss_interval' => 'permanent',
)
)
),
'dismissible_type' => 'user',
'dismiss_interval' => 'shortly',
)
);
} else {
Give()->notices->register_notice(
array(
'id' => "give-expires-subscription-{$subscription['id']}",
'type' => 'error',
'description' => sprintf(
__( 'Your Give add-on license will expire in %1$s for payment #%3$d. Click to renew an existing license or %5$s.', 'give' ),
human_time_diff( current_time( 'timestamp', 1 ), strtotime( $subscription['expires'] ) ),
urldecode( $subscription['invoice_url'] ),
$subscription['payment_id'],
"{$this->checkout_url}?edd_license_key={$subscription['license_key']}&utm_campaign=admin&utm_source=licenses&utm_medium=expired",
Give()->notices->get_dismiss_link(
array(
'title' => __( 'Click here if already renewed', 'give' ),
'dismissible_type' => 'user',
'dismiss_interval' => 'permanent',
)
)
),
'dismissible_type' => 'user',
'dismiss_interval' => 'shortly',
)
);
}
// Stop validation for these license keys.
$addon_license_key_in_subscriptions = array_merge( $addon_license_key_in_subscriptions, $subscription['licenses'] );
}// End foreach().
$showed_subscriptions_message = true;
}// End if().
// Show Non Subscription Give Add-on messages.
if (
! in_array( $this->license, $addon_license_key_in_subscriptions )
&& ! empty( $this->license )
&& empty( $showed_invalid_message )
&& ! $this->is_valid_license()
) {
Give()->notices->register_notice(
array(
'id' => 'give-invalid-license',
'type' => 'error',
'description' => sprintf(
__( 'You have invalid or expired license keys for one or more Give Add-ons. Please go to the licenses page to correct this issue.', 'give' ),
admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' )
),
'dismissible_type' => 'user',
'dismiss_interval' => 'shortly',
)
);
$showed_invalid_message = true;
}
}
/**
* Check if license is valid or not.
*
* @since 1.7
* @access public
*
* @param null|object $licence_data
*
* @return bool
*/
public function is_valid_license( $licence_data = null ) {
$license_data = empty( $licence_data ) ? $this->license_data : $licence_data;
if ( apply_filters( 'give_is_valid_license', ( $this->is_license( $license_data ) && 'valid' === $license_data->license ) ) ) {
return true;
}
return false;
}
/**
* Check if license is license object of no.
*
* @since 1.7
* @access public
*
* @param null|object $licence_data
*
* @return bool
*/
public function is_license( $licence_data = null ) {
$license_data = empty( $licence_data ) ? $this->license_data : $licence_data;
if ( apply_filters( 'give_is_license', ( is_object( $license_data ) && ! empty( $license_data ) && property_exists( $license_data, 'license' ) ) ) ) {
return true;
}
return false;
}
/**
* Check if license is valid or not.
*
* @access private
* @since 1.7
*
* @return bool
*/
private function __is_third_party_addon() {
return ( false === strpos( $this->api_url, 'givewp.com/' ) );
}
/**
* Remove license key from subscription.
*
* This function mainly uses when admin user deactivate license key,
* then we do not need subscription information for that license key.
*
* @access private
* @since 1.7
*
* @return bool
*/
private function __remove_license_key_from_subscriptions() {
$subscriptions = get_option( 'give_subscriptions', array() );
// Bailout.
if ( empty( $this->license ) ) {
return false;
}
if ( ! empty( $subscriptions ) ) {
foreach ( $subscriptions as $subscription_id => $subscription ) {
$license_index = array_search( $this->license, $subscription['licenses'] );
if ( false !== $license_index ) {
// Remove license key.
unset( $subscriptions[ $subscription_id ]['licenses'][ $license_index ] );
// Rearrange license keys.
$subscriptions[ $subscription_id ]['licenses'] = array_values( $subscriptions[ $subscription_id ]['licenses'] );
// Update subscription information.
update_option( 'give_subscriptions', $subscriptions, false );
break;
}
}
}
}
/**
* Display plugin page licenses status notices.
*
* @param $plugin_file
* @param $plugin_data
* @param $status
*
* @return bool
*/
public function plugin_page_notices( $plugin_file, $plugin_data, $status ) {
// Bailout.
if ( $this->is_valid_license() ) {
return false;
}
$update_notice_wrap = ' |
';
$message = $this->license_state_message();
if ( ! empty( $message['message'] ) ) {
echo sprintf( $update_notice_wrap, $message['message'] );
}
}
/**
* Get message related to license state.
*
* @since 1.8.7
* @access public
* @return array
*/
public function license_state_message() {
$message_data = array();
if ( ! $this->is_valid_license() ) {
$message_data['message'] = sprintf(
'Please activate your license to receive updates and support for the %2$s add-on.',
esc_url( admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' ) ),
$this->item_name
);
}
return $message_data;
}
/**
* Check if admin can edit license or not.
*
* @since 1.8.9
* @access private
*/
private function __is_user_can_edit_license() {
// Bailout.
if (
! Give_Admin_Settings::verify_nonce()
|| ! current_user_can( 'manage_give_settings' )
|| 'licenses' !== give_get_current_setting_tab()
) {
return false;
}
// Security check.
if (
isset( $_POST[ $this->item_shortname . '_license_key-nonce' ] )
&& ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce' ], $this->item_shortname . '_license_key-nonce' )
) {
wp_die( __( 'Nonce verification failed.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
}
return true;
}
/**
* Get license information.
*
* @since 1.8.9
* @access public
*
* @param string $edd_action
* @param bool $response_in_array
*
* @return mixed
*/
public function get_license_info( $edd_action = '', $response_in_array = false ) {
if ( empty( $edd_action ) ) {
return false;
}
// Data to send to the API.
$api_params = array(
'edd_action' => $edd_action, // never change from "edd_" to "give_"!
'license' => $this->license,
'item_name' => urlencode( $this->item_name ),
'url' => home_url(),
);
// Call the API.
$response = wp_remote_post(
$this->api_url,
array(
'timeout' => 15,
'sslverify' => false,
'body' => $api_params,
)
);
// Make sure there are no errors.
if ( is_wp_error( $response ) ) {
return false;
}
return json_decode( wp_remote_retrieve_body( $response ), $response_in_array );
}
/**
* Unset license
*
* @since 1.8.14
* @access private
*/
private function unset_license() {
// Remove license key from subscriptions if exist.
$this->__remove_license_key_from_subscriptions();
// Remove license from database.
delete_option( "{$this->item_shortname}_license_active" );
give_delete_option( "{$this->item_shortname}_license_key" );
unset( $_POST[ "{$this->item_shortname}_license_key" ] );
// Unset license param.
$this->license = '';
}
/**
* Check if deactivating any license key or not.
*
* @since 1.8.17
* @access private
*
* @return bool
*/
private function is_deactivating_license() {
$status = false;
foreach ( $_POST as $key => $value ) {
if ( false !== strpos( $key, 'license_key_deactivate' ) ) {
$status = true;
break;
}
}
return $status;
}
/**
* Return licensed addons info
*
* Note: note only for internal logic
*
* @since 2.1.4
*
* @return array
*/
static function get_licensed_addons() {
return self::$licensed_addons;
}
}
endif; // end class_exists check.