845 lines
22 KiB
PHP
845 lines
22 KiB
PHP
<?php
|
|
namespace AIOSEO\Plugin\Pro\Admin;
|
|
|
|
// Exit if accessed directly.
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* The License class to validate/activate/deactivate license keys.
|
|
*
|
|
* @since 4.2.5
|
|
*/
|
|
class NetworkLicense extends License {
|
|
/**
|
|
* The Action Scheduler action name for the recurring daily network license check.
|
|
*
|
|
* @since 4.9.5.2
|
|
*
|
|
* @var string
|
|
*/
|
|
public $licenseCheckAction = 'aioseo_network_license_check';
|
|
|
|
/**
|
|
* The Action Scheduler action name for the expired network license retry check.
|
|
*
|
|
* @since 4.9.5.2
|
|
*
|
|
* @var string
|
|
*/
|
|
public $licenseCheckExpiredAction = 'aioseo_network_license_check_expired';
|
|
|
|
/**
|
|
* The Action Scheduler action name for resetting AI access tokens across subsites.
|
|
*
|
|
* @since 4.9.5.2
|
|
*
|
|
* @var string
|
|
*/
|
|
private $resetSubsiteTokensAction = 'aioseo_ai_reset_subsite_tokens';
|
|
|
|
/**
|
|
* Class constructor.
|
|
*
|
|
* @since 4.2.5
|
|
*/
|
|
public function __construct() {
|
|
$this->options = aioseo()->networkOptions;
|
|
$this->internalOptions = aioseo()->internalNetworkOptions;
|
|
$this->sensitiveOptions = aioseo()->networkSensitiveOptions;
|
|
$this->sensitiveKeyName = 'networkLicenseKey';
|
|
|
|
add_action( 'admin_init', [ $this, 'maybeActivateFromConstant' ], 2 );
|
|
add_action( 'admin_init', [ $this, 'scheduleLicenseCheck' ], 3 );
|
|
add_action( $this->licenseCheckAction, [ $this, 'checkLicense' ] );
|
|
add_action( $this->licenseCheckExpiredAction, [ $this, 'checkLicense' ] );
|
|
add_action( $this->resetSubsiteTokensAction, [ $this, 'resetSubsiteTokens' ] );
|
|
|
|
include_once ABSPATH . 'wp-admin/includes/plugin.php';
|
|
if (
|
|
is_network_admin() &&
|
|
! is_plugin_active_for_network( plugin_basename( AIOSEO_FILE ) )
|
|
) {
|
|
return;
|
|
}
|
|
|
|
// phpcs:ignore HM.Security.ValidatedSanitizedInput.InputNotSanitized, HM.Security.NonceVerification.Recommended
|
|
if ( ! isset( $_GET['page'] ) || 'aioseo-settings' !== sanitize_text_field( wp_unslash( $_GET['page'] ) ) ) {
|
|
add_action( 'network_admin_notices', [ $this, 'notices' ] );
|
|
}
|
|
// phpcs:enable
|
|
|
|
add_action( 'after_plugin_row_' . AIOSEO_PLUGIN_BASENAME, [ $this, 'pluginRowNotice' ] );
|
|
add_action( 'in_plugin_update_message-' . AIOSEO_PLUGIN_BASENAME, [ $this, 'updateRowNotice' ] );
|
|
}
|
|
|
|
/**
|
|
* Activates the network license from the AIOSEO_LICENSE_KEY constant if defined and different from the stored key.
|
|
*
|
|
* Deferred to admin_init so the full aioseo() container (actionScheduler, etc.) is ready.
|
|
*
|
|
* @since 4.9.6.2
|
|
*
|
|
* @return void
|
|
*/
|
|
public function maybeActivateFromConstant() {
|
|
if ( ! defined( 'AIOSEO_LICENSE_KEY' ) || empty( AIOSEO_LICENSE_KEY ) ) {
|
|
return;
|
|
}
|
|
|
|
if ( AIOSEO_LICENSE_KEY === $this->sensitiveOptions->get( $this->sensitiveKeyName ) ) {
|
|
return;
|
|
}
|
|
|
|
$this->sensitiveOptions->set( $this->sensitiveKeyName, AIOSEO_LICENSE_KEY );
|
|
aioseo()->actionScheduler->unschedule( $this->licenseCheckAction );
|
|
$this->activate();
|
|
}
|
|
|
|
/**
|
|
* Validate the license keys for a multisite setup.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @param array $domains Domains for activation and deactivation.
|
|
* @return boolean Whether or not it was activated.
|
|
*/
|
|
public function multisite( $domains ) {
|
|
aioseo()->helpers->switchToBlog( aioseo()->helpers->getNetworkId() );
|
|
|
|
$this->internalOptions->internal->license->reset(
|
|
[
|
|
'expires',
|
|
'expired',
|
|
'invalid',
|
|
'disabled',
|
|
'activationsError',
|
|
'connectionError',
|
|
'requestError',
|
|
'level',
|
|
'addons',
|
|
'counts',
|
|
'upgradeUrl'
|
|
]
|
|
);
|
|
|
|
$licenseKey = aioseo()->networkSensitiveOptions->get( 'networkLicenseKey' );
|
|
if ( empty( $licenseKey ) ) {
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
$site = aioseo()->helpers->getSite();
|
|
$domains = ! empty( $domains )
|
|
? $domains
|
|
: [
|
|
[
|
|
'domain' => $site->domain,
|
|
'path' => $site->path
|
|
]
|
|
];
|
|
|
|
$response = $this->sendLicenseRequest( 'multisite', $licenseKey, $domains );
|
|
|
|
if ( empty( $response ) ) {
|
|
// Something bad happened, error unknown.
|
|
$this->internalOptions->internal->license->connectionError = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( ! empty( $response->error ) ) {
|
|
if ( 'missing-key-or-domain' === $response->error ) {
|
|
$this->internalOptions->internal->license->requestError = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'missing-license' === $response->error ) {
|
|
$this->internalOptions->internal->license->invalid = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'disabled' === $response->error ) {
|
|
$this->internalOptions->internal->license->disabled = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'activations' === $response->error ) {
|
|
$this->internalOptions->internal->license->activationsError = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'expired' === $response->error ) {
|
|
$this->internalOptions->internal->license->expires = strtotime( $response->expires );
|
|
$this->internalOptions->internal->license->expired = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Something bad happened, error unknown.
|
|
if ( empty( $response->success ) || empty( $response->level ) ) {
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
$this->internalOptions->internal->license->level = $response->level;
|
|
$this->internalOptions->internal->license->addons = wp_json_encode( $response->addons );
|
|
$this->internalOptions->internal->license->expires = strtotime( $response->expires );
|
|
$this->internalOptions->internal->license->features = wp_json_encode( $response->features );
|
|
|
|
// Store activation counts if provided.
|
|
if ( ! empty( $response->counts ) ) {
|
|
$this->internalOptions->internal->license->counts = wp_json_encode( $response->counts );
|
|
}
|
|
|
|
// Store upgrade URL if provided.
|
|
if ( ! empty( $response->upgradeUrl ) ) {
|
|
$this->internalOptions->internal->license->upgradeUrl = $response->upgradeUrl;
|
|
}
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
if ( aioseo()->internalOptions->internal->has( 'ai' ) ) {
|
|
$activatedIds = ! empty( $domains['activate'] ) ? array_column( $domains['activate'], 'blog_id' ) : [];
|
|
$deactivatedIds = ! empty( $domains['deactivate'] ) ? array_column( $domains['deactivate'], 'blog_id' ) : [];
|
|
$blogIds = array_values( array_filter( array_merge( $activatedIds, $deactivatedIds ) ) );
|
|
|
|
$this->scheduleTokenReset( $blogIds );
|
|
}
|
|
|
|
$this->clearSitesActiveCache( $domains );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* Validate the license key.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @param array $newDomains New domains to activate.
|
|
* @return boolean Whether or not it was activated.
|
|
*/
|
|
public function activate( $newDomains = [] ) {
|
|
aioseo()->helpers->switchToBlog( aioseo()->helpers->getNetworkId() );
|
|
|
|
$this->internalOptions->internal->license->reset(
|
|
[
|
|
'expires',
|
|
'expired',
|
|
'invalid',
|
|
'disabled',
|
|
'activationsError',
|
|
'connectionError',
|
|
'requestError',
|
|
'level',
|
|
'addons',
|
|
'features',
|
|
'counts',
|
|
'upgradeUrl'
|
|
]
|
|
);
|
|
|
|
$licenseKey = aioseo()->networkSensitiveOptions->get( 'networkLicenseKey' );
|
|
if ( empty( $licenseKey ) ) {
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
$site = aioseo()->helpers->getSite();
|
|
$domains = ! empty( $newDomains )
|
|
? $newDomains
|
|
: [
|
|
[
|
|
'domain' => $site->domain,
|
|
'path' => $site->path
|
|
]
|
|
];
|
|
|
|
$response = $this->sendLicenseRequest( 'activate', $licenseKey, $domains );
|
|
|
|
if ( empty( $response ) ) {
|
|
// Something bad happened, error unknown.
|
|
$this->internalOptions->internal->license->connectionError = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( ! empty( $response->error ) ) {
|
|
if ( 'missing-key-or-domain' === $response->error ) {
|
|
$this->internalOptions->internal->license->requestError = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'missing-license' === $response->error ) {
|
|
$this->internalOptions->internal->license->invalid = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'disabled' === $response->error ) {
|
|
$this->internalOptions->internal->license->disabled = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'domain-disabled' === $response->error ) {
|
|
$this->internalOptions->internal->license->domainDisabled = true;
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'activations' === $response->error ) {
|
|
$this->internalOptions->internal->license->activationsError = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'expired' === $response->error ) {
|
|
$this->internalOptions->internal->license->expires = strtotime( $response->expires );
|
|
$this->internalOptions->internal->license->expired = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Something bad happened, error unknown.
|
|
if ( empty( $response->success ) || empty( $response->level ) ) {
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
$this->internalOptions->internal->license->level = $response->level;
|
|
$this->internalOptions->internal->license->addons = wp_json_encode( $response->addons );
|
|
$this->internalOptions->internal->license->expires = strtotime( $response->expires );
|
|
$this->internalOptions->internal->license->features = wp_json_encode( $response->features );
|
|
|
|
// Store activation counts if provided.
|
|
if ( ! empty( $response->counts ) ) {
|
|
$this->internalOptions->internal->license->counts = wp_json_encode( $response->counts );
|
|
}
|
|
|
|
// Store upgrade URL if provided.
|
|
if ( ! empty( $response->upgradeUrl ) ) {
|
|
$this->internalOptions->internal->license->upgradeUrl = $response->upgradeUrl;
|
|
}
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
if ( aioseo()->internalOptions->internal->has( 'ai' ) ) {
|
|
$this->scheduleTokenReset();
|
|
}
|
|
|
|
$this->clearSitesActiveCache( $newDomains );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Deactivate the license key.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @param array $domains New domains to activate.
|
|
* @return boolean Whether it was deactivated.
|
|
*/
|
|
public function deactivate( $domains = [] ) {
|
|
aioseo()->helpers->switchToBlog( aioseo()->helpers->getNetworkId() );
|
|
|
|
$licenseKey = aioseo()->networkSensitiveOptions->get( 'networkLicenseKey' );
|
|
if ( empty( $licenseKey ) ) {
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
$site = aioseo()->helpers->getSite();
|
|
$domainsToDeactivate = ! empty( $domains )
|
|
? $domains
|
|
: [
|
|
[
|
|
'domain' => $site->domain,
|
|
'path' => $site->path
|
|
]
|
|
];
|
|
|
|
$response = $this->sendLicenseRequest( 'deactivate', $licenseKey, $domainsToDeactivate );
|
|
|
|
if ( empty( $response ) ) {
|
|
// Something bad happened, error unknown.
|
|
$this->internalOptions->internal->license->connectionError = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( ! empty( $response->error ) ) {
|
|
if ( 'missing-key-or-domain' === $response->error || 'not-activated' === $response->error ) {
|
|
$this->internalOptions->internal->license->requestError = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'missing-license' === $response->error ) {
|
|
$this->internalOptions->internal->license->invalid = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'disabled' === $response->error ) {
|
|
$this->internalOptions->internal->license->disabled = true;
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( 'domain-disabled' === $response->error ) {
|
|
$this->internalOptions->internal->license->domainDisabled = true;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
$this->internalOptions->internal->license->reset(
|
|
[
|
|
'expires',
|
|
'expired',
|
|
'invalid',
|
|
'disabled',
|
|
'activationsError',
|
|
'connectionError',
|
|
'requestError',
|
|
'level',
|
|
'addons'
|
|
]
|
|
);
|
|
|
|
$this->internalOptions->internal->license->level = $response->level;
|
|
$this->internalOptions->internal->license->addons = wp_json_encode( $response->addons );
|
|
$this->internalOptions->internal->license->expires = strtotime( $response->expires );
|
|
$this->internalOptions->internal->license->features = wp_json_encode( $response->features );
|
|
|
|
aioseo()->seoChecklist->uncompleteCheck( 'licenseActivated' );
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
|
|
if ( aioseo()->internalOptions->internal->has( 'ai' ) ) {
|
|
$this->scheduleTokenReset();
|
|
}
|
|
|
|
$this->clearSitesActiveCache( $domains );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Schedules a one-time action to clear AI access tokens for subsites.
|
|
*
|
|
* @since 4.9.5.2
|
|
*
|
|
* @param array $blogIds Specific blog IDs to reset. Empty clears all subsites.
|
|
* @return void
|
|
*/
|
|
private function scheduleTokenReset( $blogIds = [] ) {
|
|
aioseo()->actionScheduler->scheduleSingle( $this->resetSubsiteTokensAction, 0, [ $blogIds ] );
|
|
}
|
|
|
|
/**
|
|
* Resets all AI settings (access token, credits, etc.) for the given subsites (or all subsites if none specified).
|
|
* Hooked into `aioseo_ai_reset_subsite_tokens` action hook.
|
|
*
|
|
* Each affected subsite will fetch a fresh token and credits on its next admin load via
|
|
* the scheduled `aioseo_ai_get_access_token` action.
|
|
*
|
|
* @since 4.9.5.2
|
|
*
|
|
* @param array $blogIds Specific blog IDs to reset. Empty clears all subsites.
|
|
* @return void
|
|
*/
|
|
public function resetSubsiteTokens( $blogIds = [] ) {
|
|
if ( ! is_multisite() ) {
|
|
return;
|
|
}
|
|
|
|
$sites = ! empty( $blogIds )
|
|
? $blogIds
|
|
: get_sites( [
|
|
'fields' => 'ids',
|
|
'number' => 0
|
|
] );
|
|
|
|
$optionName = 'aioseo_options_internal';
|
|
foreach ( $sites as $blogId ) {
|
|
$json = get_blog_option( (int) $blogId, $optionName );
|
|
if ( ! $json ) {
|
|
continue;
|
|
}
|
|
|
|
$options = json_decode( $json, true );
|
|
if ( empty( $options['internal']['ai'] ) ) {
|
|
continue;
|
|
}
|
|
|
|
$options['internal']['ai'] = [];
|
|
update_blog_option( (int) $blogId, $optionName, wp_json_encode( $options ) );
|
|
}
|
|
|
|
$sensitiveOptionName = 'aioseo_sensitive_options';
|
|
foreach ( $sites as $blogId ) {
|
|
$json = get_blog_option( (int) $blogId, $sensitiveOptionName );
|
|
if ( ! $json ) {
|
|
continue;
|
|
}
|
|
|
|
$options = json_decode( $json, true );
|
|
if ( empty( $options['aiAccessToken'] ) ) {
|
|
continue;
|
|
}
|
|
|
|
$options['aiAccessToken'] = '';
|
|
update_blog_option( (int) $blogId, $sensitiveOptionName, wp_json_encode( $options ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validates the stored license within the main network site context.
|
|
*
|
|
* Overrides the parent method to ensure that `getSite()` returns the main
|
|
* network site's domain, not a random subsite that Action Scheduler may
|
|
* execute from.
|
|
*
|
|
* @since 4.9.5.2
|
|
*
|
|
* @return void
|
|
*/
|
|
public function checkLicense() {
|
|
aioseo()->helpers->switchToBlog( aioseo()->helpers->getNetworkId() );
|
|
|
|
parent::checkLicense();
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
}
|
|
|
|
/**
|
|
* Checks to see if the current license is expired.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @return bool True if expired, false if not.
|
|
*/
|
|
public function isExpired() {
|
|
if ( ! aioseo()->networkSensitiveOptions->hasValue( 'networkLicenseKey' ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( $this->internalOptions->internal->license->expired ) {
|
|
return true;
|
|
}
|
|
|
|
$expires = $this->internalOptions->internal->license->expires;
|
|
|
|
return 0 !== $expires && $expires < time();
|
|
}
|
|
|
|
/**
|
|
* Checks to see if the current license is disabled.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @return bool True if disabled, false if not.
|
|
*/
|
|
public function isDisabled() {
|
|
if ( ! aioseo()->networkSensitiveOptions->hasValue( 'networkLicenseKey' ) ) {
|
|
return false;
|
|
}
|
|
|
|
return $this->internalOptions->internal->license->disabled;
|
|
}
|
|
|
|
/**
|
|
* Checks to see if the current license is invalid.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @return bool True if invalid, false if not.
|
|
*/
|
|
public function isInvalid() {
|
|
if ( ! aioseo()->networkSensitiveOptions->hasValue( 'networkLicenseKey' ) ) {
|
|
return false;
|
|
}
|
|
|
|
return $this->internalOptions->internal->license->invalid;
|
|
}
|
|
|
|
/**
|
|
* Checks to see if the current license is disabled.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @param \WP_Site $site The site to check if the the license is active on.
|
|
* @return bool True if disabled, false if not.
|
|
*/
|
|
public function isActive( $site = null ) {
|
|
if ( ! aioseo()->networkSensitiveOptions->hasValue( 'networkLicenseKey' ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( ! $this->isSiteActive( $site ) ) {
|
|
return false;
|
|
}
|
|
|
|
return ! $this->isExpired() && ! $this->isDisabled() && ! $this->isInvalid();
|
|
}
|
|
|
|
/**
|
|
* Get the license level for the activated license.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @param \WP_Site $site The site to check if the the license is active on.
|
|
* @return string The license level.
|
|
*/
|
|
public function getLicenseLevel( $site = null ) {
|
|
if ( ! aioseo()->networkSensitiveOptions->hasValue( 'networkLicenseKey' ) ) {
|
|
return 'Unknown';
|
|
}
|
|
|
|
if ( ! $this->isSiteActive( $site ) ) {
|
|
return 'Unknown';
|
|
}
|
|
|
|
return $this->internalOptions->internal->license->level;
|
|
}
|
|
|
|
/**
|
|
* Checks if the current site is licensed at the network level.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @return bool True if licensed at the network level.
|
|
*/
|
|
public function isNetworkLicensed() {
|
|
// If we are already locally activated, then no it's not network licensed.
|
|
if ( aioseo()->license->isActive() ) {
|
|
return false;
|
|
}
|
|
|
|
if ( $this->isActive() ) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Checks if a given site (or the current one) is active.
|
|
*
|
|
* @since 4.2.5
|
|
* @version 4.4.0
|
|
*
|
|
* @param \WP_Site $site The site to check.
|
|
* @return bool True if active, false if not.
|
|
*/
|
|
public function isSiteActive( $site = null ) {
|
|
if ( ! aioseo()->networkSensitiveOptions->hasValue( 'networkLicenseKey' ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( empty( $site ) ) {
|
|
$site = \WP_Site::get_instance( get_current_blog_id() );
|
|
}
|
|
|
|
$urlHash = sha1( $site->domain . $site->path );
|
|
$cacheKey = "site_active_{$urlHash}";
|
|
$isActive = aioseo()->core->cache->get( $cacheKey );
|
|
if ( null !== $isActive ) {
|
|
return $isActive;
|
|
}
|
|
|
|
$licenseKey = aioseo()->networkSensitiveOptions->get( 'networkLicenseKey' );
|
|
$response = $this->sendLicenseRequest( 'activated', $licenseKey, [ $site ] );
|
|
if ( ! empty( $response->error ) || empty( $response->all_activations_and_paths ) ) {
|
|
aioseo()->core->cache->update( $cacheKey, false, DAY_IN_SECONDS );
|
|
|
|
return false;
|
|
}
|
|
|
|
$active = false;
|
|
foreach ( $response->all_activations_and_paths as $activeSite ) {
|
|
if ( $site->domain === $activeSite->domain && $site->path === $activeSite->path ) {
|
|
$active = true;
|
|
break;
|
|
}
|
|
|
|
if ( ! empty( $site->aliases ) ) {
|
|
foreach ( $site->aliases as $alias ) {
|
|
if ( $activeSite->domain === $alias['domain'] ) {
|
|
$active = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
aioseo()->core->cache->update( $cacheKey, $active, DAY_IN_SECONDS );
|
|
|
|
return $active;
|
|
}
|
|
|
|
/**
|
|
* Checks if the given sites are activated.
|
|
*
|
|
* @since 4.4.0
|
|
*
|
|
* @param array $domains The domains to check.
|
|
* @return array The domains with the active status.
|
|
*/
|
|
public function areSitesActive( $domains ) {
|
|
// Force domains to be objects.
|
|
$domains = json_decode( wp_json_encode( $domains ) );
|
|
|
|
$fullDomains = array_map( function( $domain ) {
|
|
return $domain->domain . $domain->path;
|
|
}, $domains );
|
|
$domainsHash = sha1( implode( ',', $fullDomains ) );
|
|
$cacheKey = "sites_active_{$domainsHash}";
|
|
$areActive = aioseo()->core->cache->get( $cacheKey );
|
|
if ( null !== $areActive ) {
|
|
return $areActive;
|
|
}
|
|
|
|
$licenseKey = aioseo()->networkSensitiveOptions->get( 'networkLicenseKey' );
|
|
$response = $this->sendLicenseRequest( 'activated', $licenseKey, $domains );
|
|
if ( ! empty( $response->error ) || empty( $response->all_activations_and_paths ) ) {
|
|
aioseo()->core->cache->update( $cacheKey, [], HOUR_IN_SECONDS );
|
|
|
|
return [];
|
|
}
|
|
|
|
$activeSites = [];
|
|
foreach ( $domains as $domain ) {
|
|
foreach ( $response->all_activations_and_paths as $activeSite ) {
|
|
if ( $domain->domain === $activeSite->domain && $domain->path === $activeSite->path ) {
|
|
$activeSites[] = $activeSite;
|
|
break;
|
|
}
|
|
|
|
if ( ! empty( $domain->aliases ) ) {
|
|
foreach ( $domain->aliases as $alias ) {
|
|
if ( $activeSite->domain === $alias['domain'] ) {
|
|
$activeSites[] = $activeSite;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
aioseo()->core->cache->update( $cacheKey, $activeSites, HOUR_IN_SECONDS );
|
|
|
|
return $activeSites;
|
|
}
|
|
|
|
/**
|
|
* Adds a notice to the update row for unlicensed users.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @return void
|
|
*/
|
|
public function updateRowNotice() {
|
|
if ( $this->isActive() ) {
|
|
return;
|
|
}
|
|
|
|
$this->outputUpdateRowNotice();
|
|
}
|
|
|
|
/**
|
|
* Add row to Plugins page with licensing information, if license key is invalid or not found.
|
|
*
|
|
* @since 4.2.5
|
|
*
|
|
* @return void
|
|
*/
|
|
public function pluginRowNotice() {
|
|
// Don't output the notice on subsites since to prevent duplicate notices.
|
|
if ( $this->isActive() || ! is_main_site() ) {
|
|
return;
|
|
}
|
|
|
|
$this->outputPluginRowNotice();
|
|
}
|
|
|
|
/**
|
|
* Clears the active site(s) cache.
|
|
*
|
|
* @since 4.4.0
|
|
*
|
|
* @return void
|
|
*/
|
|
private function clearSitesActiveCache( $domains = [] ) {
|
|
$cacheTableName = aioseo()->core->db->prefix . 'aioseo_cache';
|
|
aioseo()->core->db->execute( "DELETE FROM $cacheTableName WHERE `key` LIKE 'sites_active_%'" );
|
|
|
|
$allDomains = [];
|
|
if ( isset( $domains['activate'] ) ) {
|
|
$allDomains = array_merge( $allDomains, $domains['activate'] );
|
|
}
|
|
|
|
if ( isset( $domains['deactivate'] ) ) {
|
|
$allDomains = array_merge( $allDomains, $domains['deactivate'] );
|
|
}
|
|
|
|
foreach ( $allDomains as $domain ) {
|
|
aioseo()->helpers->switchToBlog( $domain['blog_id'] );
|
|
|
|
$cacheTableName = aioseo()->core->db->prefix . 'aioseo_cache';
|
|
aioseo()->core->db->execute( "DELETE FROM $cacheTableName WHERE `key` LIKE 'site_active_%'" );
|
|
|
|
aioseo()->helpers->restoreCurrentBlog();
|
|
}
|
|
}
|
|
} |