set_slug( $slug );
$this->set_pue_update_url( $pue_update_url );
$this->set_plugin_file( $plugin_file );
$this->set_options( $options );
$this->hooks();
}
/**
* Install the hooks required to run periodic update checks and inject update info
* into WP data structures.
* Also other hooks related to the automatic updates (such as checking agains API and what not (@from Darren)
*/
public function hooks() {
// Override requests for plugin information
add_filter( 'plugins_api', array( $this, 'inject_info' ), 10, 3 );
// Check for updates when the WP updates are checked and inject our update if needed.
// Only add filter if the TRIBE_DISABLE_PUE constant is not set as true and where
// the context is not 'service'
if ( ( ! defined( 'TRIBE_DISABLE_PUE' ) || TRIBE_DISABLE_PUE !== true ) && 'service' !== $this->context ) {
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_for_updates' ) );
}
add_filter( 'tribe_licensable_addons', array( $this, 'build_addon_list' ) );
add_action( 'tribe_license_fields', array( $this, 'do_license_key_fields' ) );
add_action( 'tribe_settings_after_content_tab_licenses', array( $this, 'do_license_key_javascript' ) );
add_action( 'tribe_settings_success_message', array( $this, 'do_license_key_success_message' ), 10, 2 );
add_action( 'load-plugins.php', array( $this, 'remove_default_inline_update_msg' ), 50 );
add_action( 'update_option_' . $this->pue_install_key, array( $this, 'check_for_api_key_error' ), 10, 2 );
add_action( 'update_site_option_' . $this->pue_install_key, array( $this, 'check_for_api_key_error' ), 10, 2 );
// Key validation
add_action( 'wp_ajax_pue-validate-key_' . $this->get_slug(), array( $this, 'ajax_validate_key' ) );
add_filter( 'tribe-pue-install-keys', array( $this, 'return_install_key' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'maybe_display_json_error_on_plugins_page' ), 1 );
add_action( 'admin_init', array( $this, 'general_notifications' ) );
// Package name
add_filter( 'upgrader_pre_download', array( Tribe__PUE__Package_Handler::instance(), 'filter_upgrader_pre_download' ), 5, 3 );
}
/********************** Getter / Setter Functions **********************/
/**
* Get the slug
*
* @return string
*/
public function get_slug() {
return apply_filters( 'pue_get_slug', $this->slug );
}
/**
* Set the slug
*
* @param string $slug
*/
private function set_slug( $slug = '' ) {
$this->slug = $slug;
$clean_slug = str_replace( '-', '_', $this->slug );
$this->dismiss_upgrade = 'pu_dismissed_upgrade_' . $clean_slug;
$this->pue_install_key = 'pue_install_key_' . $clean_slug;
}
/**
* Get the PUE update API endpoint url
*
* @return string
*/
public function get_pue_update_url() {
return apply_filters( 'pue_get_update_url', $this->pue_update_url, $this->get_slug() );
}
/**
* Set the PUE update URL
*
* This can be overridden using the global constant 'PUE_UPDATE_URL'
*
* @param string $pue_update_url
*/
private function set_pue_update_url( $pue_update_url ) {
$this->pue_update_url = ( defined( 'PUE_UPDATE_URL' ) ) ? trailingslashit( PUE_UPDATE_URL ) : trailingslashit( $pue_update_url );
}
/**
* Get the plugin file path
*
* @return string
*/
public function get_plugin_file() {
return apply_filters( 'pue_get_plugin_file', $this->plugin_file, $this->get_slug() );
}
/**
* Set the plugin file path
*
* @param string $plugin_file
*/
private function set_plugin_file( $plugin_file = '' ) {
if ( ! empty( $plugin_file ) ) {
$this->plugin_file = $plugin_file;
return;
}
$slug = $this->get_slug();
if ( ! empty( $slug ) ) {
$this->plugin_file = $slug . '/' . $slug . '.php';
}
}
/**
* Set the plugin name
*
* @param string $plugin_name
*/
private function set_plugin_name( $plugin_name = '' ) {
if ( ! empty( $plugin_name ) ) {
$this->plugin_name = $plugin_name;
} else {
//get name from plugin file itself
if ( ! function_exists( 'get_plugins' ) ) {
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
// Prevents get_plugins from throwing a weird notice
if ( ! file_exists( WP_PLUGIN_DIR . '/' . $this->get_plugin_file() ) ) {
return;
}
$plugin_details = explode( '/', $this->get_plugin_file() );
$plugin_folder = get_plugins( '/' . $plugin_details[0] );
$this->plugin_name = isset( $plugin_details[1] ) && isset( $plugin_folder[ $plugin_details[1] ] ) ? $plugin_folder[ $plugin_details[1] ]['Name'] : null;
}
}
/**
* Get the plugin name
*
* @return string
*/
public function get_plugin_name() {
if ( empty( $this->plugin_name ) ) {
$this->set_plugin_name();
}
return apply_filters( 'pue_get_plugin_name', $this->plugin_name, $this->get_slug() );
}
/**
* Set all the PUE instantiation options
*
* @param array $options
*/
private function set_options( $options = array() ) {
$options = wp_parse_args(
$options, array(
'pue_option_name' => 'external_updates-' . $this->get_slug(),
'apikey' => '',
'installkey' => false,
'check_period' => 12,
'context' => 'component',
)
);
$this->pue_option_name = $options['pue_option_name'];
$this->check_period = (int) $options['check_period'];
$this->api_secret_key = $options['apikey'];
$this->context = $options['context'];
if ( isset( $options['installkey'] ) && $options['installkey'] ) {
$this->install_key = trim( $options['installkey'] );
} else {
$this->install_key = trim( $this->get_option( $this->pue_install_key ) );
}
}
/**
* Set all the download query array
*
* @param array $download_query
*/
private function set_download_query( $download_query = array() ) {
if ( ! empty( $download_query ) ) {
$this->download_query = $download_query;
return;
}
//download query flag
$this->download_query['pu_get_download'] = 1;
//include current version
if ( $version = $this->get_installed_version() ) {
$this->download_query['pue_active_version'] = $version;
}
//the following is for install key inclusion (will apply later with PUE addons.)
if ( isset( $this->install_key ) ) {
$this->download_query['pu_install_key'] = $this->install_key;
}
if ( ! empty( $this->api_secret_key ) ) {
$this->download_query['pu_plugin_api'] = $this->api_secret_key;
}
}
/**
* Get the download_query args
*
* @return array
*/
public function get_download_query() {
if ( empty( $this->download_query ) ) {
$this->set_download_query();
}
return apply_filters( 'pue_get_download_query', $this->download_query, $this->get_slug() );
}
/********************** General Functions **********************/
/**
* Compile a list of addons
*
* @param array $addons list of addons
*
* @return array list of addons
*/
public function build_addon_list( $addons = array() ) {
$addons[] = $this->get_plugin_name();
return $addons;
}
/**
* Inserts license key fields on license key page
*
* @param array $fields List of fields
*
* @return array Modified list of fields.
*/
public function do_license_key_fields( $fields ) {
// common fields whether licenses should be hidden or not
$to_insert = array(
$this->pue_install_key . '-heading' => array(
'type' => 'heading',
'label' => $this->get_plugin_name(),
)
);
// we want to inject the following license settings at the end of the licenses tab
if($this->should_show_network_editable_license() ){
$to_insert[$this->pue_install_key ] = array(
'type' => 'license_key',
'size' => 'large',
'validation_type' => 'license_key',
'label' => sprintf( esc_attr__( 'License Key', 'tribe-common' ) ),
'tooltip' => esc_html__(
'A valid license key is required for support and updates', 'tribe-common'
),
'parent_option' => false,
'network_option' => true,
);
} elseif($this->should_show_subsite_editable_license()){
$to_insert[$this->pue_install_key ] = array(
'type' => 'license_key',
'size' => 'large',
'validation_type' => 'license_key',
'label' => sprintf( esc_attr__( 'License Key', 'tribe-common' ) ),
'tooltip' => esc_html__(
'A valid license key is required for support and updates', 'tribe-common'
),
'parent_option' => false,
'network_option' => false,
);
} elseif($this->should_show_overrideable_license()){
$to_insert[$this->pue_install_key. '-state' ] = array(
'type' => 'html',
'label' => sprintf( esc_attr__( 'License Key Status:', 'tribe-common' ) ),
'label_attributes' => array( 'style' => 'width:auto;' ),
'html' => sprintf( '
%s
', $this->get_network_license_state_string() ),
);
$override_id = $this->pue_install_key . '-override';
$to_insert[ $override_id ] = array(
'type' => 'checkbox_bool',
'label' => esc_html__( 'Override network license key', 'tribe-common' ),
'tooltip' => esc_html__( 'Check this box if you wish to override the network license key with your own', 'tribe-common' ),
'default' => false,
'validation_type' => 'boolean',
'parent_option' => false,
'attributes' => array( 'id' => $override_id . '-field' ),
);
$to_insert[ $this->pue_install_key ] = array(
'type' => 'license_key',
'size' => 'large',
'validation_type' => 'license_key',
'label' => sprintf( esc_attr__( 'Site License Key', 'tribe-common' ) ),
'tooltip' => esc_html__(
'A valid license key is required for support and updates', 'tribe-common'
),
'parent_option' => false,
'network_option' => false,
'class' => 'tribe-dependent',
'fieldset_attributes' => array(
'data-depends' => '#' . $override_id . '-field',
'data-condition-checked' => true,
),
);
} else {
$to_insert[$this->pue_install_key. '-state' ] = array(
'type' => 'html',
'label' => sprintf( esc_attr__( 'License Key Status:', 'tribe-common' ) ),
'label_attributes' => array( 'style' => 'width:auto;' ),
'html' => sprintf( '%s
', $this->get_network_license_state_string() ),
);
}
$fields = self::array_insert_after_key( 'tribe-form-content-start', $fields, $to_insert );
return $fields;
}
/**
* Inserts the javascript that makes the ajax checking
* work on the license key page
*
*/
public function do_license_key_javascript() {
?>
' . esc_html__( 'License key(s) updated.', 'tribe-common' ) . '
';
}
/**
* Checks for the license key status with MT servers.
*
* @param string $key
* @param bool $network Whether the key to check for is a network one or not.
*
* @return array An associative array containing the license status response.
*/
public function validate_key( $key, $network = false ) {
$response = array();
$response['status'] = 0;
if ( ! $key ) {
$response['message'] = sprintf( esc_html__( 'Hmmm... something\'s wrong with this validator. Please contact %ssupport%s.', 'tribe-common' ), '', '' );
return $response;
}
$queryArgs = array(
'pu_install_key' => trim( $key ),
'pu_checking_for_updates' => '1',
);
//include version info
$queryArgs['pue_active_version'] = $this->get_installed_version();
global $wp_version;
$queryArgs['wp_version'] = $wp_version;
// For multisite, return the network-level siteurl ... in
// all other cases return the actual URL being serviced
$queryArgs['domain'] = is_multisite() ? $this->get_network_domain() : $_SERVER['SERVER_NAME'];
if ( is_multisite() ) {
$queryArgs['multisite'] = 1;
$queryArgs['network_activated'] = is_plugin_active_for_network( $this->get_plugin_file() );
global $wpdb;
$queryArgs['active_sites'] = $wpdb->get_var( "SELECT count(blog_id) FROM $wpdb->blogs WHERE public = '1' AND archived = '0' AND spam = '0' AND deleted = '0'" );
} else {
$queryArgs['multisite'] = 0;
$queryArgs['network_activated'] = 0;
$queryArgs['active_sites'] = 1;
}
// This method is primarily used during when validating keys by ajax, before they are
// formally committed or saved by the user: for that reason we call request_info()
// rather than license_key_status() as at this stage invalid or missing keys should
// not result in admin notices being generated
$plugin_info = $this->request_info( $queryArgs );
$expiration = isset( $plugin_info->expiration ) ? $plugin_info->expiration : esc_html__( 'unknown date', 'tribe-common' );
$pue_notices = Tribe__Main::instance()->pue_notices();
$plugin_name = $this->get_plugin_name();
if ( empty( $plugin_info ) ) {
$response['message'] = esc_html__( 'Sorry, key validation server is not available.', 'tribe-common' );
} elseif ( isset( $plugin_info->api_expired ) && $plugin_info->api_expired == 1 ) {
$response['message'] = $this->get_license_expired_message();
$response['api_expired'] = true;
} elseif ( isset( $plugin_info->api_upgrade ) && $plugin_info->api_upgrade == 1 ) {
$response['message'] = $this->get_api_message( $plugin_info );
$response['api_upgrade'] = true;
} elseif ( isset( $plugin_info->api_invalid ) && $plugin_info->api_invalid == 1 ) {
$response['message'] = $this->get_api_message( $plugin_info );
$response['api_invalid'] = true;
} else {
if ( $network && is_multisite() ) {
$api_secret_key = get_network_option( null, $this->pue_install_key );
} else {
$api_secret_key = get_option( $this->pue_install_key );
}
if ( $api_secret_key && $api_secret_key === $queryArgs['pu_install_key'] ){
$default_success_msg = sprintf( esc_html__( 'Valid Key! Expires on %s', 'tribe-common' ), $expiration );
} else {
// Set the key
if ( $network && is_multisite() ) {
update_network_option( null, $this->pue_install_key, $queryArgs['pu_install_key'] );
} else {
update_option( $this->pue_install_key, $queryArgs['pu_install_key'] );
}
$default_success_msg = sprintf( esc_html__( 'Thanks for setting up a valid key. It will expire on %s', 'tribe-common' ), $expiration );
//Set SysInfo Key on Tec.com After Successful Validation of License
$optin_key = get_option( 'tribe_systeminfo_optin' );
if ( $optin_key ) {
Tribe__Support::send_sysinfo_key( $optin_key, $queryArgs['domain'], false, true );
}
}
$pue_notices->clear_notices( $plugin_name );
$response['status'] = isset( $plugin_info->api_message ) ? 2 : 1;
$response['message'] = isset( $plugin_info->api_message ) ? wp_kses( $plugin_info->api_message, 'data' ) : $default_success_msg;
$response['expiration'] = $expiration;
if ( isset( $plugin_info->daily_limit ) ) {
$response['daily_limit'] = intval( $plugin_info->daily_limit );
}
}
return $response;
}
public function get_license_expired_message() {
return '' .
__( 'Renew Your License Now', 'tribe-common' ) .
'' .
__( ' (opens in a new window)', 'tribe-common' ) .
'';
}
/**
* Echo JSON results for key validation
*/
public function ajax_validate_key() {
$key = isset( $_POST['key'] ) ? $_POST['key'] : null;
$response = $this->validate_key( $key );
echo json_encode( $response );
exit;
}
/**
* Processes variable substitutions for server-side API message.
*
* @param Tribe__PUE__Plugin_Info $info
*
* @return string
*/
private function get_api_message( $info ) {
// this default message should never show, but is here as a fallback just in case.
$message = sprintf(
esc_html__( 'There is an update for %s. You\'ll need to %scheck your license%s to have access to updates, downloads, and support.', 'tribe-common' ),
$this->get_plugin_name(),
'',
''
);
if ( ! empty( $info->api_inline_invalid_message ) ) {
$message = wp_kses( $info->api_inline_invalid_message, 'post' );
}
$message = str_replace( '%plugin_name%', $this->get_plugin_name(), $message );
$message = str_replace( '%plugin_slug%', $this->get_slug(), $message );
$message = str_replace( '%update_url%', $this->get_pue_update_url(), $message );
$message = str_replace( '%version%', $info->version, $message );
$message = str_replace( '%changelog%', 'what\'s new', $message );
return $message;
}
/**
* Whether the plugin is network activated and licensed or not.
*
* @return bool
*/
public function is_network_licensed() {
if ( is_multisite()
&& ! is_network_admin()
&& is_plugin_active_for_network( $this->get_real_plugin_file( $this->plugin_file ) )
) {
$network_key = get_network_option( null, $this->pue_install_key );
$local_key = get_option( $this->pue_install_key );
return ! ( ! empty( $local_key ) && ( empty( $network_key ) || (string) $network_key != (string) $local_key ) );
}
return false;
}
/**
* Returns tet name of the option that stores the license key.
*
* @return string
*/
public function get_license_option_key() {
return $this->pue_install_key;
}
private function get_api_update_message() {
$plugin_info = $this->plugin_info;
if ( ! isset( $plugin_info->api_invalid_message ) ) {
return false;
}
$message = sprintf(
esc_html__( 'There is an update for %s. %sRenew your license%s to get access to bug fixes, security updates, and new features.', 'tribe-common' ),
$this->get_plugin_name(),
'',
''
);
return $message;
}
/**
* Displays a PUE message on the page if it is relevant
*
* @param string $page
*/
public function maybe_display_json_error_on_plugins_page( $page ) {
if ( 'plugins.php' !== $page ) {
return;
}
$state = $this->get_option( $this->pue_option_name, false, false );
if ( empty( $state->update->license_error ) ) {
return;
}
$this->plugin_notice = array(
'slug' => $this->get_slug(),
'message_row_html' => "
|
{$state->update->license_error}
|
",
);
add_filter( 'tribe_plugin_notices', array( $this, 'add_notice_to_plugin_notices' ) );
}
public function add_notice_to_plugin_notices( $notices ) {
if ( ! $this->plugin_notice || $this->is_network_licensed() ) {
return $notices;
}
$notices[ $this->plugin_notice['slug'] ] = $this->plugin_notice;
return $notices;
}
/**
* Returns plugin/license key data based on the provided query arguments.
*
* Calling this method will also take care of setting up admin notices for any
* keys that are invalid or have expired, etc.
*
* @see Tribe__PUE__Checker::request_info()
*
* @param $query_args
*
* @return Tribe__PUE__Plugin_Info|null
*/
public function license_key_status( $query_args ) {
$pue_notices = Tribe__Main::instance()->pue_notices();
$plugin_info = $this->request_info( $query_args );
$plugin_name = empty( $this->plugin_name ) ? $this->get_plugin_name() : $this->plugin_name;
if ( empty( $plugin_name ) ) {
return $plugin_info;
}
// Check for expired keys
if ( ! empty( $plugin_info->api_expired ) ) {
$pue_notices->add_notice( Tribe__PUE__Notices::EXPIRED_KEY, $plugin_name );
}
// Check for keys that are out of installs (*must* happen before the api_invalid test)
elseif ( ! empty( $plugin_info->api_upgrade ) ) {
$pue_notices->add_notice( Tribe__PUE__Notices::UPGRADE_KEY, $plugin_name );
}
// Check for invalid keys last of all (upgrades/empty keys will be flagged as invalid)
elseif (
! empty( $plugin_info->api_invalid )
&& (
'component' === $this->context
|| (
'service' === $this->context
&& $this->install_key
)
)
) {
$pue_notices->add_notice( Tribe__PUE__Notices::INVALID_KEY, $plugin_name );
}
// If none of the above were satisfied we can assume the key is valid
else {
$pue_notices->clear_notices( $plugin_name );
}
return $plugin_info;
}
/**
* Sets up and manages those license key notifications which don't depend on communicating with a remote
* PUE server, etc.
*/
public function general_notifications() {
$plugin_name = empty( $this->plugin_name ) ? $this->get_plugin_name() : $this->plugin_name;
// Register our plugin name for use in messages (thus if we're deactivated, any previously
// added persistent messaging can be cleared)
Tribe__Main::instance()->pue_notices()->register_name( $plugin_name );
// Detect and setup notices for missing keys
if ( empty( $this->install_key ) && 'service' !== $this->context ) {
Tribe__Main::instance()->pue_notices()->add_notice( Tribe__PUE__Notices::INVALID_KEY, $plugin_name );
}
}
/**
* Retrieve plugin info from the configured API endpoint.
*
* In general, this method should not be called directly and it is preferable to call
* the license_key_status() method instead. That method returns the same result, but
* also analyses each response to set up appropriate license key notifications in the
* admin environment.
*
* @uses wp_remote_get()
* @see Tribe__PUE__Checker::license_key_status()
*
* @param array $queryArgs Additional query arguments to append to the request. Optional.
*
* @return string $plugin_info
*/
public function request_info( $queryArgs = array() ) {
//Query args to append to the URL. Plugins can add their own by using a filter callback (see add_query_arg_filter()).
$queryArgs['installed_version'] = $this->get_installed_version();
$queryArgs['pu_request_plugin'] = $this->get_slug();
if ( empty( $queryArgs['pu_plugin_api'] ) && ! empty( $this->api_secret_key ) ) {
$queryArgs['pu_plugin_api'] = $this->api_secret_key;
}
if ( empty( $queryArgs['pu_install_key'] ) && ! empty( $this->install_key ) ) {
$queryArgs['pu_install_key'] = $this->install_key;
}
//include version info
$queryArgs['pue_active_version'] = $this->get_installed_version();
global $wp_version;
$queryArgs['wp_version'] = $wp_version;
//include domain and multisite stats
$queryArgs['domain'] = is_multisite() ? $this->get_network_domain() : $this->get_site_domain();
if ( is_multisite() ) {
$queryArgs['multisite'] = 1;
$queryArgs['network_activated'] = is_plugin_active_for_network( $this->get_plugin_file() );
global $wpdb;
$queryArgs['active_sites'] = $wpdb->get_var( "SELECT count(blog_id) FROM $wpdb->blogs WHERE public = '1' AND archived = '0' AND spam = '0' AND deleted = '0'" );
} else {
$queryArgs['multisite'] = 0;
$queryArgs['network_activated'] = 0;
$queryArgs['active_sites'] = 1;
}
$queryArgs = apply_filters( 'tribe_puc_request_info_query_args-' . $this->get_slug(), $queryArgs );
//Various options for the wp_remote_get() call. Plugins can filter these, too.
$options = array(
'timeout' => 15, //seconds
'headers' => array(
'Accept' => 'application/json',
),
);
$options = apply_filters( 'tribe_puc_request_info_options-' . $this->get_slug(), $options );
$url = $this->get_pue_update_url();
if ( ! empty( $queryArgs ) ) {
$url = esc_url_raw( add_query_arg( $queryArgs, $url ) );
}
// Cache the API call so it only needs to be made once per plugin per page load.
static $plugin_info_cache;
$key = crc32( implode( '', $queryArgs ) );
if ( isset( $plugin_info_cache[ $key ] ) ) {
return $plugin_info_cache[ $key ];
}
$result = wp_remote_get(
$url,
$options
);
//Try to parse the response
$plugin_info = null;
if ( ! is_wp_error( $result ) && isset( $result['response']['code'] ) && ( $result['response']['code'] == 200 ) && ! empty( $result['body'] ) ) {
$plugin_info = Tribe__PUE__Plugin_Info::from_json( $result['body'] );
}
$plugin_info = apply_filters( 'tribe_puc_request_info_result-' . $this->get_slug(), $plugin_info, $result );
$plugin_info_cache[ $key ] = $plugin_info;
return $plugin_info;
}
/**
* Returns the domain contained in the network's siteurl option (not the full URL).
*
* @return string
*/
public function get_network_domain() {
$site_url = parse_url( get_site_option( 'siteurl' ) );
if ( ! $site_url || ! isset( $site_url['host'] ) ) {
return '';
} else {
return strtolower( $site_url['host'] );
}
}
/**
* Retrieve the latest update (if any) from the configured API endpoint.
*
* @uses Tribe__PUE__Checker::request_info()
*
* @return Tribe__PUE__Utility An instance of Tribe__PUE__Utility, or NULL when no updates are available.
*/
public function request_update() {
// For the sake of simplicity, this function just calls request_info()
// and transforms the result accordingly.
$args = array(
'pu_checking_for_updates' => 1,
);
if ( ! empty( $_POST['key'] ) ) {
$args['pu_install_key'] = $_POST['key'];
} elseif ( ! empty( $_POST[ $this->pue_install_key ] ) ) {
$args['pu_install_key'] = $_POST[ $this->pue_install_key ];
}
$this->plugin_info = $plugin_info = $this->license_key_status( $args );
if ( null === $plugin_info ) {
return null;
}
// admin display for if the update check reveals that there is a new version but the API key isn't valid.
if ( isset( $plugin_info->api_invalid ) ) {
$plugin_info = Tribe__PUE__Utility::from_plugin_info( $plugin_info );
$plugin_info->license_error = $this->get_api_message( $plugin_info );
return $plugin_info;
}
if ( isset( $plugin_info->new_install_key ) ) {
$this->update_option( $this->pue_install_key, $plugin_info->new_install_key );
}
//need to correct the download url so it contains the custom user data (i.e. api and any other paramaters)
$download_query = $this->get_download_query();
if ( ! empty( $download_query ) ) {
$plugin_info->download_url = esc_url_raw( add_query_arg( $download_query, $plugin_info->download_url ) );
}
// Add plugin dirname/file (this will be expected by WordPress when it builds the plugin list table)
$plugin_info->plugin = $this->get_plugin_file();
return Tribe__PUE__Utility::from_plugin_info( $plugin_info );
}
/**
* Display a changelog when the api key is missing.
*/
public function display_changelog() {
//contents of changelog display page when api-key is invalid or missing. It will ONLY show the changelog (hook into existing thickbox?)
}
/**
* Get the currently installed version of the plugin.
*
* @return string Version number.
*/
public function get_installed_version() {
if ( function_exists( 'get_plugins' ) ) {
$allPlugins = get_plugins();
if ( array_key_exists( $this->get_plugin_file(), $allPlugins ) && array_key_exists( 'Version', $allPlugins[ $this->get_plugin_file() ] ) ) {
return $allPlugins[ $this->get_plugin_file() ]['Version'];
}
}
}
/**
* Get MU compatible options.
*
* @param string $option_key
* @param bool|mixed $default
* @param bool $use_cache
*
* @return null|mixed
*/
public function get_option( $option_key, $default = false, $use_cache = true ) {
return get_site_option( $option_key, $default, $use_cache );
}
/**
* Update MU compatible options.
*
* @param mixed $option_key
* @param mixed $value
*/
public function update_option( $option_key, $value ) {
update_site_option( $option_key, $value );
}
/**
* Check for plugin updates.
*
* The results are stored in the DB option specified in $pue_option_name.
*
* @param array $updates
*
*/
public function check_for_updates( $updates = array() ) {
$state = $this->get_option( $this->pue_option_name, false, false );
if ( empty( $state ) ) {
$state = new StdClass;
$state->lastCheck = 0;
$state->checkedVersion = '';
$state->update = null;
}
$state->lastCheck = time();
$state->checkedVersion = $this->get_installed_version();
$this->update_option( $this->pue_option_name, $state ); //Save before checking in case something goes wrong
$state->update = $this->request_update();
// If a null update was returned, skip the end of the function.
if ( $state->update == null ) {
$this->update_option( $this->pue_option_name, $state );
return $updates;
}
//Is there an update to insert?
if ( version_compare( $state->update->version, $this->get_installed_version(), '>' ) ) {
if ( empty( $updates ) ) {
$updates = (object) array( 'response' => array() );
}
$updates->response[ $this->get_plugin_file() ] = $state->update->to_wp_format();
// If the key has expired we should register an appropriate admin notice
if ( $this->plugin_info->api_expired ) {
Tribe__Main::instance()->pue_notices()->add_notice( Tribe__PUE__Notices::EXPIRED_KEY, $this->plugin_name );
}
}
$this->update_option( $this->pue_option_name, $state );
return $updates;
}
/**
* Clears out the site external site option and re-checks the license key
*/
public function check_for_api_key_error( $old_value, $value ) {
if ( 'service' !== $this->context ) {
delete_site_option( $this->pue_option_name );
$this->check_for_updates();
}
// are we saving THIS PUE key to the options table?
if ( empty( $_POST[ $this->pue_install_key ] ) || $value !== $_POST[ $this->pue_install_key ] ) {
return;
}
// if we are saving this PUE key, we need to make sure we update the license key notices
// appropriately. Otherwise, we could have an invalid license key in place but the notices
// aren't being thrown globally
$args = array(
'pu_checking_for_updates' => 1,
'pu_install_key' => $_POST[ $this->pue_install_key ],
);
$this->license_key_status( $args );
}
/**
* Intercept plugins_api() calls that request information about our plugin and
* use the configured API endpoint to satisfy them.
*
* @see plugins_api()
*
* @param mixed $result
* @param string $action
* @param array|object $args
*
* @return mixed
*/
public function inject_info( $result, $action = null, $args = null ) {
$relevant = ( $action == 'plugin_information' ) && isset( $args->slug ) && ( $args->slug == $this->slug );
if ( ! $relevant ) {
return $result;
}
$plugin_info = $this->license_key_status( array( 'pu_checking_for_updates' => '1' ) );
if ( $plugin_info ) {
return $plugin_info->to_wp_format();
}
return $result;
}
/**
* Register a callback for filtering query arguments.
*
* The callback function should take one argument - an associative array of query arguments.
* It should return a modified array of query arguments.
*
* @uses add_filter() This method is a convenience wrapper for add_filter().
*
* @param callback $callback
*
*/
public function add_query_arg_filter( $callback ) {
add_filter( 'tribe_puc_request_info_query_args-' . $this->get_slug(), $callback );
}
/**
* Register a callback for filtering arguments passed to wp_remote_get().
*
* The callback function should take one argument - an associative array of arguments -
* and return a modified array or arguments. See the WP documentation on wp_remote_get()
* for details on what arguments are available and how they work.
*
* @uses add_filter() This method is a convenience wrapper for add_filter().
*
* @param callback $callback
*
*/
public function add_http_request_arg_filter( $callback ) {
add_filter( 'tribe_puc_request_info_options-' . $this->get_slug(), $callback );
}
/**
* Register a callback for filtering the plugin info retrieved from the external API.
*
* The callback function should take two arguments. If the plugin info was retrieved
* successfully, the first argument passed will be an instance of Tribe__PUE__Plugin_Info. Otherwise,
* it will be NULL. The second argument will be the corresponding return value of
* wp_remote_get (see WP docs for details).
*
* The callback function should return a new or modified instance of Tribe__PUE__Plugin_Info or NULL.
*
* @uses add_filter() This method is a convenience wrapper for add_filter().
*
* @param callback $callback
*
*/
public function add_result_filter( $callback ) {
add_filter( 'tribe_puc_request_info_result-' . $this->get_slug(), $callback, 10, 2 );
}
/**
* Insert an array after a specified key within another array.
*
* @param $key
* @param $source_array
* @param $insert_array
*
* @return array
*
*/
public static function array_insert_after_key( $key, $source_array, $insert_array ) {
if ( array_key_exists( $key, $source_array ) ) {
$position = array_search( $key, array_keys( $source_array ) ) + 1;
$source_array = array_slice( $source_array, 0, $position, true ) + $insert_array + array_slice( $source_array, $position, null, true );
} else {
// If no key is found, then add it to the end of the array.
$source_array += $insert_array;
}
return $source_array;
}
/**
* Add this plugin key to the list of keys
*
* @param array $keys
*
* @return array $keys
*
*/
public function return_install_key( $keys = array() ) {
if ( ! empty( $this->install_key ) ) {
$keys[ $this->get_slug() ] = $this->install_key;
}
return $keys;
}
/**
* Prevent the default inline update-available messages from appearing, as we
* have implemented our own.
*
* @see resources/js/pue-notices.js
*/
public function remove_default_inline_update_msg() {
remove_action( "after_plugin_row_{$this->plugin_file}", 'wp_plugin_update_row' );
}
/**
* Returns the domain of the single site installation
*
* Will try to read it from the $_SERVER['SERVER_NAME'] variable
* and fall back on the one contained in the siteurl option.
*
* @return string
*/
protected function get_site_domain() {
if ( isset( $_SERVER['SERVER_NAME'] ) ) {
return $_SERVER['SERVER_NAME'];
}
$site_url = parse_url( get_option( 'siteurl' ) );
if ( ! $site_url || ! isset( $site_url['host'] ) ) {
return '';
} else {
return strtolower( $site_url['host'] );
}
}
/**
* Returns the plugin file to use when checking for the licensed component or plugin.
*
* @param string $plugin_file The component or plugin file in the `/.php` format.
*
* @return string A component or plugins file in the `/.php` format.
*/
protected function get_real_plugin_file( $plugin_file ) {
$map = array(
'event-aggregator/event-aggregator.php' => 'the-events-calendar/the-events-calendar.php',
);
return isset( $map[ $plugin_file ] ) ? $map[ $plugin_file ] : $plugin_file;
}
/**
* Returns the localized string for a plugin or component license state.
*
* @return string The localized state string.
*/
protected function get_network_license_state_string() {
$states = array(
'licensed' => esc_html__( 'A valid license has been entered by your network administrator.', 'tribe-common' ),
'not-licensed' => esc_html__( 'No license entered. Consult your network administrator.', 'tribe-common' ),
'expired' => esc_html__( 'Expired license. Consult your network administrator.', 'tribe-common' ),
);
$response = $this->validate_key( get_network_option( null, $this->pue_install_key ), true );
if ( isset( $response['status'] ) && $response['status'] === 1 ) {
$state = 'licensed';
} else if ( isset( $response['api_expired'] ) && $response['api_expired'] == true ) {
$state = 'expired';
} else {
$state = 'not-licensed';
}
return $states[ $state ];
}
/**
* Whether the user should be shown the fully editable subsite license field or not.
*
* This check will happen in the context of the plugin administration area; checks on the user
* capability to edit the plugin settings have been made before.
*
* @return bool
*/
public function should_show_subsite_editable_license() {
if ( ! is_multisite() ) {
return true;
}
if ( is_network_admin() ) {
return false;
}
if ( is_plugin_active_for_network( $this->get_real_plugin_file( $this->plugin_file ) ) && ! is_super_admin() ) {
return false;
}
return true;
}
/**
* Whether the user should be shown the override control to override the network license key or not.
*
* This check will happen in the context of the plugin administration area; checks on the user
* capability to edit the plugin settings have been made before.
*
* @return bool
*/
public function should_show_overrideable_license() {
if ( is_network_admin() ) {
return false;
}
if (is_super_admin()) {
return false;
}
if ( ! is_plugin_active_for_network( $this->get_real_plugin_file( $this->plugin_file ) ) ) {
return false;
}
return true;
}
/**
* Whether the user should be shown the fully editable network license field or not.
*
* This check will happen in the context of the network plugin administration area; checks on the user
* capability to edit the network plugin settings have been made before.
*
* @return bool
*/
public function should_show_network_editable_license() {
return is_network_admin() && is_super_admin();
}
}
}