Download all files FTP

This commit is contained in:
2026-04-13 15:50:16 +02:00
parent d8382136b2
commit cb5b386424
6906 changed files with 1956223 additions and 40713 deletions

View File

@@ -0,0 +1,180 @@
<?php
/**
* Version Pro Base addon class
*
* Name: Duplicator PRO base
* Version: 1
* Author: Duplicator
* Author URI: http://snapcreek.com
*
* PHP version 5.6.20
*
* @category Duplicator
* @package Plugin
* @author Duplicator
* @copyright 2011-2021 Snapcreek LLC
* @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
* @version GIT: $Id$
* @link https://duplicator.com/
*/
namespace Duplicator\Addons\ProBase;
// phpcs:disable
require_once __DIR__ . '/vendor/edd/EDD_SL_Plugin_Updater.php';
// phpcs:enable
use Duplicator\Controllers\SchedulePageController;
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Addons\ProBase\License\LicenseNotices;
use Duplicator\Addons\ProBase\Models\LicenseData;
use Duplicator\Core\Controllers\AbstractMenuPageController;
use Duplicator\Core\MigrationMng;
use Duplicator\Installer\Models\MigrateData;
use Duplicator\Libs\Snap\SnapLog;
/**
* Version Pro Base addon class
*
* @category Duplicator
* @package Plugin
* @author Snapcreek <admin@snapcreek.com>
* @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
* @link http://snapcreek.com
*/
class ProBase extends \Duplicator\Core\Addons\AbstractAddonCore
{
/**
* @return void
*/
public function init()
{
add_action('init', array($this, 'hookInit'));
add_action('duplicator_unistall', array($this, 'unistall'));
add_filter('duplicator_main_menu_label', function () {
return 'Duplicator Pro';
});
add_filter('duplicator_menu_pages', array($this, 'addScheduleMenuField'));
add_action(MigrationMng::HOOK_FIRST_LOGIN_AFTER_INSTALL, function (MigrateData $migrationData) {
License::clearVersionCache();
});
add_action('duplicator_pro_on_upgrade_version', [$this, 'onUpgradePlugin'], 10, 2);
add_action('duplicator_before_update_crypt_setting', [__CLASS__, 'beforeCryptUpdateSettings']);
add_action('duplicator_after_update_crypt_setting', [__CLASS__, 'afterCryptUpdateSettings']);
LicenseNotices::init();
LicensingController::init();
}
/**
* Unistall
*
* @return void
*/
public function unistall()
{
if (strlen(LicenseData::getInstance()->getKey()) > 0) {
switch (LicenseData::getInstance()->deactivate()) {
case LicenseData::ACTIVATION_RESPONSE_OK:
break;
case LicenseData::ACTIVATION_REQUEST_ERROR:
SnapLog::phpErr("Error deactivate license: ACTIVATION_RESPONSE_POST_ERROR");
break;
case LicenseData::ACTIVATION_RESPONSE_INVALID:
default:
SnapLog::phpErr("Error deactivate license: ACTIVATION_RESPONSE_INVALID");
break;
}
}
}
/**
* Add schedule menu page
*
* @param array<string, AbstractMenuPageController> $basicMenuPages menu pages
*
* @return array<string, AbstractMenuPageController>
*/
public function addScheduleMenuField($basicMenuPages)
{
$page = SchedulePageController::getInstance();
$basicMenuPages[$page->getSlug()] = $page;
return $basicMenuPages;
}
/**
* Function calle on duplicator_addons_loaded hook
*
* @return void
*/
public function hookInit()
{
License::check();
}
/**
* Function called on plugin upgrade
*
* @param false|string $currentVersion current version
* @param string $newVersion new version
*
* @return void
*/
public function onUpgradePlugin($currentVersion, $newVersion)
{
if ($currentVersion !== false && version_compare($currentVersion, '4.5.16-beta1', '<')) {
$legacyKey = get_option(LicenseData::LICENSE_OLD_KEY_OPTION_NAME, '');
if (!empty($legacyKey)) {
LicenseData::getInstance()->setKey($legacyKey);
}
delete_option(LicenseData::LICENSE_OLD_KEY_OPTION_NAME);
}
License::clearVersionCache();
}
/**
* Before crypt update settings
*
* @return void
*/
public static function beforeCryptUpdateSettings()
{
// make sure the license date si reade before the settings are updated
LicenseData::getInstance();
}
/**
* After crypt update settings
*
* @return void
*/
public static function afterCryptUpdateSettings()
{
LicenseData::getInstance()->save();
}
/**
*
* @return string
*/
public static function getAddonPath()
{
return __DIR__;
}
/**
*
* @return string
*/
public static function getAddonFile()
{
return __FILE__;
}
}

View File

@@ -0,0 +1,94 @@
<?php
/**
* Version Pro Base Installer addon class
*
* Name: Duplicator PRO base
* Version: 1
* Author: Snap Creek
* Author URI: http://snapcreek.com
*
* @category Duplicator
* @package Installer
* @author Snapcreek <admin@snapcreek.com>
* @copyright 2011-2021 Snapcreek LLC
* @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
* @version GIT: $Id$
* @link http://snapcreek.com
*/
namespace Duplicator\Installer\Addons\ProBase;
use Duplicator\Installer\Core\Hooks\HooksMng;
use Duplicator\Installer\Core\Params\Items\ParamItem;
/**
* Version Pro Base Installer addon class
*
* @category Duplicator
* @package Installer
* @author Snapcreek <admin@snapcreek.com>
* @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
* @link http://snapcreek.com
*/
class ProBase extends \Duplicator\Installer\Core\Addons\InstAbstractAddonCore
{
/**
* Main init addon
*
* @return void
*/
public function init()
{
HooksMng::getInstance()->addFilter(
'dupx_main_header',
function ($value) {
return 'Duplicator PRO';
}
);
HooksMng::getInstance()->addFilter('installer_get_init_params', array(__CLASS__, 'getInitParams'));
HooksMng::getInstance()->addAction(
'after_params_overwrite',
array(
'\\Duplicator\\Installer\\Addons\\ProBase\\AdvancedParams',
'updateParamsAfterOverwrite',
)
);
}
/**
* getInitParams
*
* @param ParamItem[] $params params list
*
* @return ParamItem[]
*/
public static function getInitParams($params)
{
$advParams = array();
AdvancedParams::init($advParams);
return array_merge($params, $advParams);
}
/**
* Get addon main folder
*
* @return string
*/
public static function getAddonPath()
{
return __DIR__;
}
/**
* Get addon main file
*
* @return string
*/
public static function getAddonFile()
{
return __FILE__;
}
}

View File

@@ -0,0 +1,256 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
namespace Duplicator\Installer\Addons\ProBase;
use Exception;
abstract class AbstractLicense
{
const TYPE_UNKNOWN = -1;
const TYPE_UNLICENSED = 0;
const TYPE_PERSONAL = 1;
const TYPE_FREELANCER = 2;
const TYPE_BUSINESS = 3;
const TYPE_PERSONAL_AUTO = 4;
const TYPE_FREELANCER_AUTO = 5;
const TYPE_BUSINESS_AUTO = 6;
const TYPE_GOLD = 7;
const TYPE_BASIC = 8;
const TYPE_PLUS = 9;
const TYPE_PRO = 10;
const TYPE_ELITE = 11;
const CAPABILITY_BRAND = 1000;
const CAPABILITY_IMPORT_SETTINGS = 1001;
const CAPABILITY_SHEDULE_HOURLY = 1002;
const CAPABILITY_MULTISITE = 1003;
const CAPABILITY_MULTISITE_PLUS = 1004;
const CAPABILITY_POWER_TOOLS = 1005;
const CAPABILITY_CHANGE_TABLE_PREFIX = 1006;
const CAPABILITY_UPDATE_AUTH = 1007;
const CAPABILITY_CAPABILITIES_MNG = 1008;
const CAPABILITY_CAPABILITIES_MNG_PLUS = 1009;
const CAPABILITY_PRO_BASE = 1010;
const CAPABILITY_PACKAGE_COMPONENTS_PLUS = 1011;
const CAPABILITY_IMPORT = 1012;
const CAPABILITY_SCHEDULE = 1013;
const CAPABILITY_STORAGE = 1014;
const CAPABILITY_TEMPLATE = 1015;
/**
* Returns the license type this installer file is made of.
*
* @return int Returns an enum type of License
*/
public static function getType()
{
// This is to avoid warnings in PHP 5.6 because isn't possibile declare an abstract static method.
throw new Exception('This method must be extended');
}
/**
* Return license limit
*
* @return int<0, max>
*/
public static function getLimit()
{
// This is to avoid warnings in PHP 5.6 because isn't possibile declare an abstract static method.
throw new Exception('This method must be extended');
}
/**
* Return upsell URL
*
* @return string
*/
public static function getUpsellURL()
{
// This is to avoid warnings in PHP 5.6 because isn't possibile declare an abstract static method.
throw new Exception('This method must be extended');
}
/**
* Return true if license is unlimited
*
* @return bool
*/
public static function isUnlimited()
{
return in_array(
static::getType(),
[
self::TYPE_BUSINESS,
self::TYPE_BUSINESS_AUTO,
self::TYPE_GOLD,
]
);
}
/**
* Return true if license have the capability
*
* @param int $capability capability key
* @param ?int $license ENUM license type, if null Get currnt licnse type
*
* @return bool
*/
public static function can($capability, $license = null)
{
if (is_null($license)) {
$license = static::getType();
}
switch ($capability) {
case self::CAPABILITY_PRO_BASE:
return true;
case self::CAPABILITY_IMPORT:
return $license > 0;
case self::CAPABILITY_MULTISITE:
return $license > 0;
case self::CAPABILITY_SCHEDULE:
return $license > 0;
case self::CAPABILITY_STORAGE:
return $license > 0;
case self::CAPABILITY_TEMPLATE:
return $license > 0;
case self::CAPABILITY_BRAND:
case self::CAPABILITY_IMPORT_SETTINGS:
case self::CAPABILITY_SHEDULE_HOURLY:
case self::CAPABILITY_POWER_TOOLS:
case self::CAPABILITY_UPDATE_AUTH:
case self::CAPABILITY_CHANGE_TABLE_PREFIX:
return in_array(
$license,
[
self::TYPE_FREELANCER,
self::TYPE_FREELANCER_AUTO,
self::TYPE_BUSINESS,
self::TYPE_BUSINESS_AUTO,
self::TYPE_GOLD,
self::TYPE_PLUS,
self::TYPE_PRO,
self::TYPE_ELITE,
]
);
case self::CAPABILITY_MULTISITE_PLUS:
case self::CAPABILITY_CAPABILITIES_MNG:
case self::CAPABILITY_CAPABILITIES_MNG_PLUS:
case self::CAPABILITY_PACKAGE_COMPONENTS_PLUS:
return in_array(
$license,
[
self::TYPE_BUSINESS,
self::TYPE_BUSINESS_AUTO,
self::TYPE_GOLD,
self::TYPE_PRO,
self::TYPE_ELITE,
]
);
default:
return false;
}
}
/**
* Return true if license can be upgraded
*
* @param ?int $license ENUM license type, if null Get currnt licnse type
*
* @return bool
*/
public static function canBeUpgraded($license = null)
{
if (is_null($license)) {
$license = static::getType();
}
return !in_array($license, [
self::TYPE_BUSINESS,
self::TYPE_BUSINESS_AUTO,
self::TYPE_GOLD,
self::TYPE_ELITE,
]);
}
/**
* Return license description
*
* @param ?int $license ENUM license type, if null Get currnt licnse type
* @param bool $article if true add article before description
*
* @return string
*/
public static function getLicenseToString($license = null, $article = false)
{
if (is_null($license)) {
$license = static::getType();
}
switch ($license) {
case self::TYPE_UNLICENSED:
return ($article ? 'an ' : '') . 'unlicensed';
case self::TYPE_PERSONAL:
case self::TYPE_PERSONAL_AUTO:
return ($article ? 'a ' : '') . 'Personal';
case self::TYPE_FREELANCER:
case self::TYPE_FREELANCER_AUTO:
return ($article ? 'a ' : '') . 'Freelancer';
case self::TYPE_BUSINESS:
case self::TYPE_BUSINESS_AUTO:
return ($article ? 'a ' : '') . 'Business';
case self::TYPE_GOLD:
return ($article ? 'a ' : '') . 'Gold';
case self::TYPE_BASIC:
return ($article ? 'a ' : '') . 'Basic';
case self::TYPE_PLUS:
return ($article ? 'a ' : '') . 'Plus';
case self::TYPE_PRO:
return ($article ? 'a ' : '') . 'Pro';
case self::TYPE_ELITE:
return ($article ? 'a ' : '') . 'Elite';
default:
return ($article ? 'an ' : '') . 'unknown license type';
}
}
/**
* Get best license from two given
*
* @param int $l1 ENUM license
* @param int $l2 ENUM license
*
* @return int ENUM license
*/
protected static function getBestLicense($l1, $l2)
{
$l1Weight = 0;
$l2Weight = 0;
$wheigts = [
self::TYPE_UNLICENSED => -1,
self::TYPE_BASIC => 0,
self::TYPE_PERSONAL => 1,
self::TYPE_PERSONAL_AUTO => 1,
self::TYPE_PLUS => 2,
self::TYPE_FREELANCER => 3,
self::TYPE_FREELANCER_AUTO => 3,
self::TYPE_PRO => 4,
self::TYPE_ELITE => 5,
self::TYPE_BUSINESS => 6,
self::TYPE_BUSINESS_AUTO => 6,
self::TYPE_GOLD => 7,
];
$l1Weight = (isset($wheigts[$l1]) ? $wheigts[$l1] : -1 );
$l2Weight = (isset($wheigts[$l2]) ? $wheigts[$l2] : -1 );
return ($l1Weight >= $l2Weight ? $l1 : $l2);
}
}

View File

@@ -0,0 +1,55 @@
<?php
/**
* License class
*
* @category Duplicator
* @package Installer
* @author Snapcreek <admin@snapcreek.com>
* @copyright 2011-2021 Snapcreek LLC
* @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
*/
namespace Duplicator\Installer\Addons\ProBase;
use Duplicator\Installer\Core\Params\Descriptors\DescriptorInterface;
use Duplicator\Installer\Core\Params\Items\ParamForm;
use Duplicator\Installer\Core\Params\PrmMng;
use DUPX_U;
class AdvancedParams implements DescriptorInterface
{
/**
* Init advanced params
*
* @param \Duplicator\Installer\Core\Params\Items\ParamItem[] $params params list
*
* @return void
*/
public static function init(&$params)
{
$params[PrmMng::PARAM_GEN_WP_AUTH_KEY] = new ParamForm(
PrmMng::PARAM_GEN_WP_AUTH_KEY,
ParamForm::TYPE_BOOL,
ParamForm::FORM_TYPE_CHECKBOX,
array('default' => false),
array(
'label' => 'Auth Keys:',
'checkboxLabel' => 'Generate New Unique Authentication Keys and Salts',
'status' => (License::can(License::CAPABILITY_UPDATE_AUTH) ? ParamForm::STATUS_ENABLED : ParamForm::STATUS_DISABLED),
'subNote' => (License::can(License::CAPABILITY_UPDATE_AUTH) ? '' : License::getLicenseUpdateText()),
)
);
}
/**
* Update params after overwrite
*
* @param \Duplicator\Installer\Core\Params\Items\ParamItem[] $params params list
*
* @return void
*/
public static function updateParamsAfterOverwrite($params)
{
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
namespace Duplicator\Installer\Addons\ProBase;
use Duplicator\Installer\Core\Params\PrmMng;
use DUPX_U;
class License extends AbstractLicense
{
/**
* Returns the license type this installer file is made of.
*
* @return int Returns an enum type of License
*/
public static function getType()
{
return self::getBestLicense(self::getImporterLicense(), self::getInstallerLicense());
}
/**
* Return license limit
*
* @return int<0, max>
*/
public static function getLimit()
{
return (int) max(0, (int) \DUPX_ArchiveConfig::getInstance()->license_limit);
}
/**
* Return upsell URL
*
* @return string
*/
public static function getUpsellURL()
{
return 'https://duplicator.com/my-account/';
}
/**
* Get license on installer from package data
*
* @return int Returns an enum type of License
*/
protected static function getInstallerLicense()
{
return \DUPX_ArchiveConfig::getInstance()->license_type;
}
/**
* Get importer license from params data
*
* @return int Returns an enum type of License
*/
protected static function getImporterLicense()
{
$overwriteData = PrmMng::getInstance()->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA);
return isset($overwriteData['dupLicense']) ? $overwriteData['dupLicense'] : self::TYPE_UNLICENSED;
}
/**
* Return license required note
*
* @return string
*/
public static function getLicenseUpdateText()
{
return 'This option isn\'t available at the <b>' . static::getLicenseToString() . '</b> license level.' .
'To enable this option ' .
'<a href="' . DUPX_U::esc_url(static::getUpsellURL()) . '" target="_blank">' . 'upgrade' . '</a>' .
' the License.';
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
namespace Duplicator\Addons\ProBase;
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Addons\ProBase\Models\LicenseData;
class DrmHandler
{
const SCHEDULE_DRM_DELAY_DAYS = 14;
/**
* Return DRM activation days
*
* @return int -1 if has already expired, days left otherwise
*/
public static function getDaysTillDRM()
{
$status = LicenseData::getInstance()->getStatus();
if ($status !== LicenseData::STATUS_VALID && $status !== LicenseData::STATUS_EXPIRED) {
return -1;
}
if (($expiresDays = LicenseData::getInstance()->getExpirationDays()) === false) {
return -1;
}
return (self::SCHEDULE_DRM_DELAY_DAYS + $expiresDays);
}
}

View File

@@ -0,0 +1,263 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
namespace Duplicator\Addons\ProBase\License;
use Duplicator\Addons\ProBase\Vendor\EDD\EDD_SL_Plugin_Updater;
use DUP_PRO_Schedule_Entity;
use Duplicator\Addons\ProBase\DrmHandler;
use Duplicator\Addons\ProBase\Models\LicenseData;
use Duplicator\Installer\Addons\ProBase\AbstractLicense;
use Duplicator\Utils\ExpireOptions;
final class License extends AbstractLicense
{
/**
* GENERAL SETTINGS
*/
const EDD_DUPPRO_STORE_URL = 'https://duplicator.com';
const EDD_DUPPRO_ITEM_NAME = 'Duplicator Pro';
const FRONTEND_CHECK_DELAY = 61; // Seconds, different fromgeneral frontend check to unsync
const FRONTEND_CHECK_DELAY_OPTION_KEY = 'license_check';
const VISIBILITY_INFO = 0;
const VISIBILITY_ALL = 1;
const VISIBILITY_NONE = 2;
/** @var ?EDD_SL_Plugin_Updater */
private static $edd_updater = null;
/**
* License check
*
* @return void
*/
public static function check()
{
if (
!is_admin() &&
ExpireOptions::getUpdate(
self::FRONTEND_CHECK_DELAY_OPTION_KEY,
true,
self::FRONTEND_CHECK_DELAY
) !== false
) {
return;
}
if (
in_array(
LicenseData::getInstance()->getStatus(),
[
LicenseData::STATUS_INVALID,
LicenseData::STATUS_UNKNOWN,
]
)
) {
return;
}
self::initEddUpdater();
}
/**
* Return true if license have the capability
*
* @param int $capability capability key
* @param ?int $license ENUM license type, if null Get currnt licnse type
*
* @return bool
*/
public static function can($capability, $license = null)
{
if (is_null($license)) {
$license = static::getType();
}
switch ($capability) {
case self::CAPABILITY_SCHEDULE:
if ($license > 0) {
return true;
}
if (count(DUP_PRO_Schedule_Entity::get_active()) > 0 && DrmHandler::getDaysTillDRM() > 0) {
return true;
}
return false;
default:
return parent::can($capability, $license);
}
}
/**
* Force upgrade check
*
* @return void
*/
public static function forceUpgradeCheck()
{
if (
in_array(
LicenseData::getInstance()->getStatus(),
[
LicenseData::STATUS_INVALID,
LicenseData::STATUS_UNKNOWN,
]
)
) {
return;
}
self::clearVersionCache();
}
/**
* Return latest version of the plugin
*
* @return string|false
*/
public static function getLatestVersion()
{
$version_info = null;
$edd_updater = self::getEddUpdater();
/** @var false|object */
$version_info = $edd_updater->get_cached_version_info();
if (is_object($version_info) && isset($version_info->new_version)) {
return $version_info->new_version;
} else {
return false;
}
}
/**
* Clear version cache
*
* @return void
*/
public static function clearVersionCache()
{
LicenseData::getInstance()->clearCache();
self::getEddUpdater()->set_version_info_cache(false);
}
/**
* Return license key
*
* @return string
*/
public static function getLicenseKey()
{
return LicenseData::getInstance()->getKey();
}
/**
* Get license status
*
* @return int
*/
public static function getLicenseStatus()
{
return LicenseData::getInstance()->getStatus();
}
/**
* Return license type
*
* @return int ENUM AbstractLicense::TYPE_*
*/
public static function getType()
{
return (
LicenseData::getInstance()->getStatus() == LicenseData::STATUS_VALID ?
LicenseData::getInstance()->getLicenseType() :
self::TYPE_UNLICENSED
);
}
/**
* Initialize the EDD Updater
*
* @return void
*/
private static function initEddUpdater()
{
if (self::$edd_updater !== null) {
return;
}
$dpro_edd_opts = array(
'version' => DUPLICATOR_PRO_VERSION,
'license' => self::getLicenseKey(),
'item_name' => self::EDD_DUPPRO_ITEM_NAME,
'author' => 'Snap Creek Software',
'wp_override' => true,
);
self::$edd_updater = new EDD_SL_Plugin_Updater(
self::EDD_DUPPRO_STORE_URL,
DUPLICATOR____FILE,
$dpro_edd_opts
);
}
/**
* Accessor that returns the EDD Updater singleton
*
* @return EDD_SL_Plugin_Updater
*/
private static function getEddUpdater()
{
if (self::$edd_updater === null) {
self::initEddUpdater();
}
return self::$edd_updater;
}
/**
* Return upsell URL
*
* @return string
*/
public static function getUpsellURL()
{
return DUPLICATOR_PRO_BLOG_URL . 'my-account/';
}
/**
* Return no activation left message
*
* @return string
*/
public static function getNoActivationLeftMessage()
{
if (self::isUnlimited()) {
$result = sprintf(__('%1$s site licenses are granted in batches of 500.', 'duplicator-pro'), License::getLicenseToString());
$result .= ' ';
$result .= sprintf(
_x(
'Please submit a %1$sticket request%2$s and we will grant you another batch.',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
'<a href="' . DUPLICATOR_PRO_BLOG_URL . 'my-account/support/" target="_blank">',
'</a>'
);
$result .= '<br>';
$result .= __('This process helps to ensure that licenses are not stolen or abused for users.', 'duplicator-pro');
return $result;
} else {
return __(
'Use the link above to login to your duplicator.com dashboard to manage your licenses or upgrade to a higher license.',
'duplicator-pro'
);
}
}
}

View File

@@ -0,0 +1,279 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
namespace Duplicator\Addons\ProBase\License;
use Duplicator\Addons\ProBase\DrmHandler;
use Duplicator\Addons\ProBase\LicensingController;
use Duplicator\Addons\ProBase\Models\LicenseData;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\CapMng;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Core\Views\TplMng;
use Duplicator\Views\AdminNotices;
class LicenseNotices
{
/**
* Init notice actions
*
* @return void
*/
public static function init()
{
add_action('admin_init', array(__CLASS__, 'adminInit'));
$path = plugin_basename(DUPLICATOR____FILE);
// Important to make this priority 11 or greater to ensure the version cache is up to date by EDD
add_action("after_plugin_row_{$path}", array(__CLASS__, 'noLicenseDisplay'), 11, 2);
}
/**
* Function called on hook admin_init
*
* @return void
*/
public static function adminInit()
{
$action = is_multisite() ? 'network_admin_notices' : 'admin_notices';
add_action($action, array(__CLASS__, 'licenseAlertCheck'));
}
/**
* Function called on hook admin_init
*
* @param string $file Path to the plugin file relative to the plugins directory
* @param array<string, mixed> $plugin An array of plugin data
*
* @return void
*/
public static function noLicenseDisplay($file, $plugin)
{
$latest_version = License::getLatestVersion();
// Only display this message when there is no update message
if (($latest_version === false) || version_compare(DUPLICATOR_PRO_VERSION, $latest_version, '>=')) {
$error_string = null;
$licenseSettingsUrl = SettingsPageController::getInstance()->getMenuLink(
LicensingController::L2_SLUG_LICENSING
);
$licenseStatus = LicenseData::getInstance()->getStatus();
if ($licenseStatus === LicenseData::STATUS_INVALID || $licenseStatus === LicenseData::STATUS_SITE_INACTIVE) {
$error_string = sprintf(
esc_html_x(
'Your Duplicator Pro license key is invalid so you aren\'t getting important updates!
%1$sActivate your license%2$s or %3$spurchase a license%4$s.',
'1,3: <a> tag, 2,4: </a> tag',
'duplicator-pro'
),
'<a href="' . esc_url($licenseSettingsUrl) . '">',
'</a>',
'<a target="_blank" href="' . esc_url(DUPLICATOR_PRO_BLOG_URL . 'pricing/') . '">',
'</a>'
);
} elseif ($licenseStatus === LicenseData::STATUS_EXPIRED) {
$license_key = License::getLicenseKey();
if ($license_key !== false) {
$renewal_url = DUPLICATOR_PRO_BLOG_URL . 'checkout?edd_license_key=' . $license_key;
$error_string = sprintf(
__(
'Your Duplicator Pro license key has expired so you aren\'t getting important updates! %1$sRenew your license now%2$s',
'duplicator-pro'
),
'<a target="_blank" href="' . esc_url($renewal_url) . '">',
'</a>'
);
}
}
if ($error_string != null) {
ob_start();
?>
<script>jQuery("[data-slug=\'duplicator-pro\']").addClass("update");</script>
<tr style="border-top-color:black" class="plugin-update-tr active" >
<td colspan="4" class="plugin-update colspanchange">
<div class="update-message notice inline notice-error notice-alt">
<p>
<?php
echo wp_kses(
$error_string,
[
'a' => [
'href' => [],
'target' => [],
],
]
);
?>
</p>
</div>
</td>
</tr>
<?php
ob_end_flush();
}
}
}
/**
* Used by the WP action hook to detect the state of the endpoint license
* which calls the various show* methods for which alert to display
*
* @return void
*/
public static function licenseAlertCheck()
{
if (
!CapMng::can(CapMng::CAP_BASIC, false) ||
ControllersManager::isCurrentPage(
ControllersManager::SETTINGS_SUBMENU_SLUG,
LicensingController::L2_SLUG_LICENSING
)
) {
return;
}
if (file_exists(DUPLICATOR_PRO_SSDIR_PATH . "/ovr.dup")) {
return;
}
//Style needs to be loaded here because css is global across wp-admin
wp_enqueue_style(
'dup-pro-plugin-style-notices',
DUPLICATOR_PRO_PLUGIN_URL . 'assets/css/admin-notices.css',
[],
DUPLICATOR_PRO_VERSION
);
$licenseData = LicenseData::getInstance();
switch ($licenseData->getStatus()) {
case LicenseData::STATUS_VALID:
break;
case LicenseData::STATUS_EXPIRED:
self::showExpired();
break;
case LicenseData::STATUS_UNKNOWN:
case LicenseData::STATUS_INVALID:
case LicenseData::STATUS_INACTIVE:
case LicenseData::STATUS_DISABLED:
case LicenseData::STATUS_SITE_INACTIVE:
default:
if ($licenseData->haveNoActivationsLeft()) {
self::showNoActivationsLeft();
} else {
self::showInvalidStandardNag();
}
break;
}
}
/**
* Shows the smaller standard nag screen
*
* @return void
*/
private static function showInvalidStandardNag()
{
$problem_text = 'missing';
$htmlMsg = TplMng::getInstance()->render(
'licensing/notices/inactive_message',
['problem' => $problem_text],
false
);
AdminNotices::displayGeneralAdminNotice(
$htmlMsg,
AdminNotices::GEN_ERROR_NOTICE,
false,
['dup-license-message'],
[],
true
);
}
/**
* Shows the license count used up alert
*
* @return void
*/
private static function showNoActivationsLeft()
{
$htmlMsg = TplMng::getInstance()->render(
'licensing/notices/no_activation_left',
[],
false
);
AdminNotices::displayGeneralAdminNotice(
$htmlMsg,
AdminNotices::GEN_ERROR_NOTICE,
false,
['dup-license-message'],
[],
true
);
}
/**
* Shows the expired message alert
*
* @return void
*/
private static function showExpired()
{
$renewal_url = DUPLICATOR_PRO_BLOG_URL . 'checkout?edd_license_key=' . License::getLicenseKey();
$htmlMsg = TplMng::getInstance()->render(
'licensing/notices/expired',
[
'renewal_url' => $renewal_url,
'schedule_disalbe_days_left' => DrmHandler::getDaysTillDRM(),
'active_schedule_present' => count(\DUP_PRO_Schedule_Entity::get_active()) > 0,
],
false
);
AdminNotices::displayGeneralAdminNotice(
$htmlMsg,
AdminNotices::GEN_ERROR_NOTICE,
false,
['dup-license-message'],
[],
true
);
}
/**
* Gets the upgrade link
*
* @param string $label The label of the link
* @param bool $echo Whether to echo the link or return it
*
* @return string
*/
public static function getUpsellLinkHTML($label = 'Upgrade', $echo = true)
{
ob_start();
?>
<a class="dup-upgrade-license-link" href="<?php echo esc_url(License::getUpsellURL()); ?>" target="_blank">
<?php echo esc_html($label); ?>
</a>
<?php
if ($echo) {
ob_end_flush();
return '';
} else {
return ob_get_clean();
}
}
}

View File

@@ -0,0 +1,13 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
namespace Duplicator\Addons\ProBase\License;
class LicenseUtils
{
}

View File

@@ -0,0 +1,532 @@
<?php
/**
* Version Pro Base functionalities
*
* Name: Duplicator PRO base
* Version: 1
* Author: Snap Creek
* Author URI: http://snapcreek.com
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
namespace Duplicator\Addons\ProBase;
use DUP_PRO_Log;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Addons\ProBase\License\LicenseNotices;
use Duplicator\Addons\ProBase\Models\LicenseData;
use Duplicator\Controllers\SettingsPageController;
use Duplicator\Core\CapMng;
use Duplicator\Core\Controllers\PageAction;
use Duplicator\Core\Controllers\SubMenuItem;
use Duplicator\Core\Views\TplMng;
use Duplicator\Libs\Snap\SnapUtil;
use Duplicator\Libs\Snap\SnapWP;
use Duplicator\Views\AdminNotices;
use Exception;
class LicensingController
{
const L2_SLUG_LICENSING = 'licensing';
//License actions
const ACTION_ACTIVATE_LICENSE = 'activate_license';
const ACTION_DEACTIVATE_LICENSE = 'deactivate_license';
const ACTION_CHANGE_VISIBILITY = 'change_visibility';
const ACTION_CLEAR_KEY = 'clear_key';
const LICENSE_KEY_OPTION_AUTO_ACTIVE = 'duplicator_pro_license_auto_active';
/**
* License controller init
*
* @return void
*/
public static function init()
{
add_action('admin_init', array(__CLASS__, 'licenseAutoActive'));
add_action('admin_init', array(__CLASS__, 'forceUpgradeCheckAction'));
add_filter('duplicator_sub_menu_items_' . ControllersManager::SETTINGS_SUBMENU_SLUG, array(__CLASS__, 'licenseSubMenu'));
add_action('duplicator_render_page_content_' . ControllersManager::SETTINGS_SUBMENU_SLUG, array(__CLASS__, 'renderLicenseContent'), 10, 2);
add_filter('duplicator_page_actions_' . ControllersManager::SETTINGS_SUBMENU_SLUG, array(__CLASS__, 'pageActions'));
add_filter('duplicator_template_file', array(__CLASS__, 'getTemplateFile'), 10, 2);
}
/**
* Method call on admin_init hook
*
* @return void
*/
public static function licenseAutoActive()
{
if (($lKey = get_option(self::LICENSE_KEY_OPTION_AUTO_ACTIVE, false)) === false) {
return;
}
if (!CapMng::getInstance()->can(CapMng::CAP_LICENSE)) {
return;
}
if (($action = SettingsPageController::getInstance()->getActionByKey(self::ACTION_ACTIVATE_LICENSE)) == false) {
return;
}
delete_option(self::LICENSE_KEY_OPTION_AUTO_ACTIVE);
$redirect = $action->getUrl(['_license_key' => $lKey]);
if (wp_redirect($redirect)) {
exit;
} else {
throw new Exception(__('Error redirecting to license activation page', 'duplicator-pro'));
}
}
/**
* Return force upgrade check URL
*
* @return string
*/
public static function getForceUpgradeCheckURL()
{
return SnapWP::adminUrl('update-core.php', ['force-check' => 1]);
}
/**
* Force upgrade check action
*
* @return void
*/
public static function forceUpgradeCheckAction()
{
global $pagenow;
if ($pagenow !== 'update-core.php') {
return;
}
if (!SnapUtil::sanitizeBoolInput(SnapUtil::INPUT_REQUEST, 'force-check')) {
return;
}
License::forceUpgradeCheck();
}
/**
* Add license sub menu page
*
* @param SubMenuItem[] $subMenus sub menus
*
* @return SubMenuItem[]
*/
public static function licenseSubMenu($subMenus)
{
$subMenus[] = new SubMenuItem(self::L2_SLUG_LICENSING, __('Licensing', 'duplicator-pro'), '', CapMng::CAP_LICENSE, 100);
return $subMenus;
}
/**
* Define actions related to the license
*
* @param PageAction[] $actions Page actions array from filter
*
* @return PageAction[] Updated page actions array
*/
public static function pageActions($actions)
{
$actions[] = new PageAction(
self::ACTION_ACTIVATE_LICENSE,
array(
__CLASS__,
'activateLicense',
),
array(
ControllersManager::SETTINGS_SUBMENU_SLUG,
self::L2_SLUG_LICENSING,
)
);
$actions[] = new PageAction(
self::ACTION_DEACTIVATE_LICENSE,
array(
__CLASS__,
'deactivateLicense',
),
array(
ControllersManager::SETTINGS_SUBMENU_SLUG,
self::L2_SLUG_LICENSING,
)
);
$actions[] = new PageAction(
self::ACTION_CLEAR_KEY,
array(
__CLASS__,
'clearLicenseKey',
),
array(
ControllersManager::SETTINGS_SUBMENU_SLUG,
self::L2_SLUG_LICENSING,
)
);
$actions[] = new PageAction(
self::ACTION_CHANGE_VISIBILITY,
array(
__CLASS__,
'changeLicenseVisibility',
),
array(
ControllersManager::SETTINGS_SUBMENU_SLUG,
self::L2_SLUG_LICENSING,
)
);
return $actions;
}
/**
* Action that changes the license visibility
*
* @return array<string, mixed>
*/
public static function changeLicenseVisibility()
{
$result = array(
'license_success' => false,
'license_message' => '',
);
$global = \DUP_PRO_Global_Entity::getInstance();
$sglobal = \DUP_PRO_Secure_Global_Entity::getInstance();
$oldVisibility = $global->license_key_visible;
$newVisibility = filter_input(INPUT_POST, 'license_key_visible', FILTER_VALIDATE_INT);
$newPassword = SnapUtil::sanitizeInput(INPUT_POST, '_key_password', '');
if ($oldVisibility === $newVisibility) {
return $result;
}
switch ($newVisibility) {
case License::VISIBILITY_ALL:
if ($sglobal->lkp !== $newPassword) {
$result['license_message'] = __("Wrong password entered. Please enter the correct password.", 'duplicator-pro');
return $result;
}
$newPassword = ''; // reset password
break;
case License::VISIBILITY_NONE:
case License::VISIBILITY_INFO:
if ($oldVisibility == License::VISIBILITY_ALL) {
$password_confirmation = SnapUtil::sanitizeInput(INPUT_POST, '_key_password_confirmation', '');
if (strlen($newPassword) === 0) {
$result['license_message'] = __('Password cannot be empty.', 'duplicator-pro');
return $result;
}
if ($newPassword !== $password_confirmation) {
$result['license_message'] = __("Passwords don't match.", 'duplicator-pro');
return $result;
}
} else {
if ($sglobal->lkp !== $newPassword) {
$result['license_message'] = __("Wrong password entered. Please enter the correct password.", 'duplicator-pro');
return $result;
}
}
break;
default:
throw new Exception(__('Invalid license visibility value.', 'duplicator-pro'));
}
$global->license_key_visible = $newVisibility;
$sglobal->lkp = $newPassword;
if ($global->save() && $sglobal->save()) {
return array(
'license_success' => true,
'license_message' => __("License visibility changed", 'duplicator-pro'),
);
} else {
return array(
'license_success' => false,
'license_message' => __("Couldn't change licnse vilisiblity.", 'duplicator-pro'),
);
}
}
/**
* Action that clears the license key
*
* @return array<string, mixed>
*/
public static function clearLicenseKey()
{
$global = \DUP_PRO_Global_Entity::getInstance();
$sglobal = \DUP_PRO_Secure_Global_Entity::getInstance();
LicenseData::getInstance()->setKey('');
License::clearVersionCache();
$global->license_key_visible = License::VISIBILITY_ALL;
$sglobal->lkp = '';
if ($global->save() && $sglobal->save()) {
return array(
'license_success' => true,
'license_message' => __("License key cleared", 'duplicator-pro'),
);
} else {
return array(
'license_success' => false,
'license_message' => __("Couldn't save changes", 'duplicator-pro'),
);
}
}
/**
* Action that deactivates the license
*
* @return array<string, mixed>
*/
public static function deactivateLicense()
{
$result = array(
'license_success' => true,
'license_message' => __("License Deactivated", 'duplicator-pro'),
);
try {
$lData = LicenseData::getInstance();
$lData->clearCache();
if ($lData->getStatus() !== LicenseData::STATUS_VALID) {
$result = array(
'license_success' => true,
'license_message' => __('License already deactivated.', 'duplicator-pro'),
);
return $result;
}
switch ($lData->deactivate()) {
case LicenseData::ACTIVATION_RESPONSE_OK:
break;
case LicenseData::ACTIVATION_RESPONSE_INVALID:
throw new Exception(__('Invalid license key.', 'duplicator-pro'));
case LicenseData::ACTIVATION_REQUEST_ERROR:
$result['license_request_error'] = $lData->getLastRequestError();
throw new Exception(self::getRequestErrorMessage());
default:
throw new Exception(__('Error activating license.', 'duplicator-pro'));
}
} catch (Exception $e) {
$result['license_success'] = false;
$result['license_message'] = $e->getMessage();
}
return $result;
}
/**
* Return template file path
*
* @param string $path path to the template file
* @param string $slugTpl slug of the template
*
* @return string
*/
public static function getTemplateFile($path, $slugTpl)
{
if (strpos($slugTpl, 'licensing/') === 0) {
return ProBase::getAddonPath() . '/template/' . $slugTpl . '.php';
}
return $path;
}
/**
* Action that activates the license
*
* @return array<string, mixed>
*/
public static function activateLicense()
{
$result = array(
'license_success' => true,
'license_message' => __("License Activated", 'duplicator-pro'),
);
try {
if (($licenseKey = SnapUtil::sanitizeDefaultInput(SnapUtil::INPUT_REQUEST, '_license_key')) === false) {
throw new Exception(__('Please enter a valid key. Key should be 32 characters long.', 'duplicator-pro'));
}
if (!preg_match('/^[a-f0-9]{32}$/i', $licenseKey)) {
throw new Exception(__('Please enter a valid key. Key should be 32 characters long.', 'duplicator-pro'));
}
$lData = LicenseData::getInstance();
// make sure reset old license key if exists
self::clearLicenseKey();
$lData->setKey($licenseKey);
switch ($lData->activate()) {
case LicenseData::ACTIVATION_RESPONSE_OK:
break;
case LicenseData::ACTIVATION_RESPONSE_INVALID:
throw new Exception(__('Invalid license key.', 'duplicator-pro'));
case LicenseData::ACTIVATION_REQUEST_ERROR:
$result['license_request_error'] = $lData->getLastRequestError();
DUP_PRO_Log::traceObject('License request error', $result['license_request_error']);
throw new Exception(self::getRequestErrorMessage());
default:
throw new Exception(__('Error activating license.', 'duplicator-pro'));
}
} catch (Exception $e) {
$result['license_success'] = false;
$result['license_message'] = $e->getMessage();
}
return $result;
}
/**
* Render page content
*
* @param string[] $currentLevelSlugs current menu slugs
* @param string $innerPage current inner page, empty if not set
*
* @return void
*/
public static function renderLicenseContent($currentLevelSlugs, $innerPage)
{
switch ($currentLevelSlugs[1]) {
case self::L2_SLUG_LICENSING:
self::renderLicenseMessage();
TplMng::getInstance()->render('licensing/main');
break;
}
}
/**
* Render activation/deactivation license message
*
* @return void
*/
protected static function renderLicenseMessage()
{
$tplData = TplMng::getInstance()->getGlobalData();
if (empty($tplData['license_message'])) {
return;
}
$success = (isset($tplData['license_success']) && $tplData['license_success'] === true);
AdminNotices::displayGeneralAdminNotice(
TplMng::getInstance()->render('licensing/notices/activation_message', [], false),
($success ? AdminNotices::GEN_SUCCESS_NOTICE : AdminNotices::GEN_ERROR_NOTICE),
false,
[],
[],
true
);
}
/**
* License type viewer
*
* @return void
*/
public static function displayLicenseInfo()
{
$license_type = License::getType();
if ($license_type === License::TYPE_UNLICENSED) {
echo sprintf('<b>%s</b>', esc_html__("Unlicensed", 'duplicator-pro'));
} else {
echo '<b>' . esc_html(License::getLicenseToString()) . '</b>&nbsp;';
if (License::canBeUpgraded()) {
LicenseNotices::getUpsellLinkHTML('[' . __('upgrade', 'duplicator-pro') . ']');
}
$pt_class = License::can(License::CAPABILITY_POWER_TOOLS) ? 'far fa-check-circle' : 'far fa-circle';
$mup_class = License::can(License::CAPABILITY_MULTISITE_PLUS) ? 'far fa-check-circle' : 'far fa-circle';
$txt_lic_hdr = __('Site Licenses', 'duplicator-pro');
$txt_lic_msg = __(
'Indicates the number of sites the plugin can be active on at any one time.
At any point you may deactivate/uninstall the plugin to free up the license and use the plugin elsewhere if needed.',
'duplicator-pro'
);
$txt_pt_hdr = __('Powertools', 'duplicator-pro');
$txt_pt_msg = __(
'Enhanced features that greatly improve the productivity of serious users. Include hourly schedules,
installer branding, salt & key replacement, priority support and more.',
'duplicator-pro'
);
$txt_mup_hdr = __('Multisite Plus+', 'duplicator-pro');
$txt_mup_msg = __(
'Adds the ability to install a subsite as a standalone site,
insert a standalone site into a multisite, or insert a subsite from the same/different multisite into a multisite.',
'duplicator-pro'
);
$lic_limit = (License::isUnlimited() ? __('unlimited', 'duplicator-pro') : LicenseData::getInstance()->getLicenseLimit());
$site_count = (LicenseData::getInstance()->getSiteCount() < 0 ? '?' : LicenseData::getInstance()->getSiteCount());
ob_start();
?>
<div class="dup-license-type-info">
<i class='far fa-check-circle'></i>
<?php echo esc_html($txt_lic_hdr) . ': ' . esc_html($site_count) . ' of ' . esc_html($lic_limit); ?>
<i
class='fa fa-question-circle fa-sm'
data-tooltip-title='<?php echo esc_attr($txt_lic_hdr) ?>'
data-tooltip='<?php echo esc_attr($txt_lic_msg) ?>'
>
</i>
<br/>
<i class="<?php echo esc_attr($pt_class); ?>"></i>
<?php echo esc_html($txt_pt_hdr) ?>
<i
class='fa fa-question-circle fa-sm'
data-tooltip-title='<?php echo esc_attr($txt_pt_hdr) ?>'
data-tooltip='<?php echo esc_attr($txt_pt_msg) ?>'
>
</i>
<br/>
<i class="<?php echo esc_attr($mup_class) ?>"></i>
<?php echo esc_html($txt_mup_hdr) ?>
<i
class='fa fa-question-circle fa-sm'
data-tooltip-title='<?php echo esc_attr($txt_mup_hdr) ?>'
data-tooltip='<?php echo esc_attr($txt_mup_msg) ?>'
>
</i>
<br/>
</div>
<?php
ob_end_flush();
}
}
/**
* Returns the communication error message
*
* @return string
*/
private static function getRequestErrorMessage()
{
$result = sprintf(
__('<b>License data request failed.</b> (URL: %1$s)', 'duplicator-pro'),
License::EDD_DUPPRO_STORE_URL
);
$result .= '<br>';
$result .= sprintf(
_x(
'Please see %1$sthis FAQ entry%2$s for possible causes and resolutions.',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
'<a href="' . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-resolve-license-activation-issues/" target="_blank">',
'</a>'
);
return $result;
}
}

View File

@@ -0,0 +1,447 @@
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
namespace Duplicator\Addons\ProBase\Models;
use DateTime;
use DUP_PRO_Global_Entity;
use DUP_PRO_Log;
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Core\Models\AbstractEntitySingleton;
use Duplicator\Installer\Addons\ProBase\AbstractLicense;
use Duplicator\Libs\Snap\SnapUtil;
use Duplicator\Utils\Crypt\CryptBlowfish;
use VendorDuplicator\Amk\JsonSerialize\JsonSerialize;
use WP_Error;
class LicenseData extends AbstractEntitySingleton
{
/**
* GENERAL SETTINGS
*/
const LICENSE_CACHE_TIME = 7 * DAY_IN_SECONDS;
const LICENSE_OLD_KEY_OPTION_NAME = 'duplicator_pro_license_key';
/**
* LICENSE STATUS
*/
const STATUS_UNKNOWN = -1;
const STATUS_VALID = 0;
const STATUS_INVALID = 1;
const STATUS_INACTIVE = 2;
const STATUS_DISABLED = 3;
const STATUS_SITE_INACTIVE = 4;
const STATUS_EXPIRED = 5;
/**
* ACTIVATION REPONSE
*/
const ACTIVATION_RESPONSE_OK = 0;
const ACTIVATION_REQUEST_ERROR = -1;
const ACTIVATION_RESPONSE_INVALID = -2;
const DEFAULT_LICENSE_DATA = [
'success' => false,
'license' => 'invalid',
'item_id' => false,
'item_name' => '',
'checksum' => '',
'expires' => '',
'payment_id' => -1,
'customer_name' => '',
'customer_email' => '',
'license_limit' => -1,
'site_count' => -1,
'activations_left' => -1,
'price_id' => AbstractLicense::TYPE_UNLICENSED,
'activeSubscription' => false,
];
/** @var string */
protected $licenseKey = '';
/** @var int */
protected $status = self::STATUS_INVALID;
/** @var int */
protected $type = AbstractLicense::TYPE_UNKNOWN;
/** @var array<string,scalar> License remote data */
protected $data = self::DEFAULT_LICENSE_DATA;
/** @var string timestamp YYYY-MM-DD HH:MM:SS UTC */
protected $lastRemoteUpdate = '';
/**
* Last error request
*
* @var array{code:int, message: string, details: string, requestDetails: string}
*/
protected $lastRequestError = [
'code' => 0,
'message' => '',
'details' => '',
'requestDetails' => '',
];
/**
* Class constructor
*/
protected function __construct()
{
}
/**
* Return entity type identifier
*
* @return string
*/
public static function getType()
{
return 'LicenseDataEntity';
}
/**
* Will be called, automatically, when Serialize
*
* @return array<string, mixed>
*/
public function __serialize() // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__serializeFound
{
$data = JsonSerialize::serializeToData($this, JsonSerialize::JSON_SKIP_MAGIC_METHODS | JsonSerialize::JSON_SKIP_CLASS_NAME);
if (DUP_PRO_Global_Entity::getInstance()->crypt) {
$data['licenseKey'] = CryptBlowfish::encrypt($data['licenseKey'], null, true);
$data['status'] = CryptBlowfish::encrypt($data['status'], null, true);
$data['type'] = CryptBlowfish::encrypt($data['type'], null, true);
$data['data'] = CryptBlowfish::encrypt(JsonSerialize::serialize($this->data), null, true);
}
unset($data['lastRequestError']);
return $data;
}
/**
* Serialize
*
* Wakeup method.
*
* @return void
*/
public function __wakeup()
{
if (DUP_PRO_Global_Entity::getInstance()->crypt) {
$this->licenseKey = CryptBlowfish::decrypt((string) $this->licenseKey, null, true);
$this->status = (int) CryptBlowfish::decrypt((string) $this->status, null, true);
$this->type = (int) CryptBlowfish::decrypt((string) $this->type, null, true);
/** @var string PHP stan fix*/
$dataString = $this->data;
$this->data = JsonSerialize::unserialize(CryptBlowfish::decrypt($dataString, null, true));
}
if (!is_array($this->data)) {
$this->data = self::DEFAULT_LICENSE_DATA;
}
}
/**
* Set license key
*
* @param string $licenseKey License key, if empty the license key will be removed
*
* @return bool return true if license key is valid and set
*/
public function setKey($licenseKey)
{
if ($this->licenseKey === $licenseKey) {
return true;
}
if ($this->getStatus() === self::STATUS_VALID) {
// Deactivate old license
$this->deactivate();
}
if (preg_match('/^[a-f0-9]{32}$/i', $licenseKey) === 1) {
$this->licenseKey = $licenseKey;
} else {
$this->licenseKey = '';
}
return $this->clearCache();
}
/**
* Get license key
*
* @return string
*/
public function getKey()
{
return $this->licenseKey;
}
/**
* Reset license data cache
*
* @param bool $save if true save the entity
*
* @return bool return true if license data cache is reset
*/
public function clearCache($save = true)
{
$this->data = self::DEFAULT_LICENSE_DATA;
$this->status = self::STATUS_INVALID;
$this->type = AbstractLicense::TYPE_UNKNOWN;
$this->lastRemoteUpdate = '';
return ($save ? $this->save() : true);
}
/**
* Get license data.
* This function manage the license data cache.
*
* @return false|array<string,scalar> License data
*/
public function getLicenseData() {
// Override default license data to simulate a valid license.
$this->data = [
'success' => true,
'license' => 'valid',
'item_id' => 31,
'item_name' => $this->plugin_name ?? '',
'checksum' => '1415b451be1a13c283ba771ea52d38bb',
'expires' => 'lifetime',
// 'payment_id' => 31,
'customer_name' => 'GPL',
'customer_email' => 'noreply@gmail.com',
'license_limit' => 1000,
'site_count' => 1,
'activations_left' => 999,
'price_id' => '11',
'activeSubscription' => true,
];
$this->status = self::STATUS_VALID;
$this->type = AbstractLicense::TYPE_ELITE;
$this->lastRemoteUpdate = gmdate("Y-m-d H:i:s"); // Update with the current time.
return $this->data;
}
/**
* Activate license key
*
* @return int license status
*/
public function activate() {
DUP_PRO_Log::trace("License considered activated.");
return self::ACTIVATION_RESPONSE_OK;
}
public function deactivate() {
DUP_PRO_Log::trace("License considered deactivated.");
return self::ACTIVATION_RESPONSE_OK;
}
/**
* Get license status
*
* @return int ENUM self::STATUS_*
*/
public function getStatus()
{
if ($this->getLicenseData() === false) {
return self::STATUS_INVALID;
}
return $this->status;
}
/**
* Get license type
*
* @return int ENUM AbstractLicense::TYPE_*
*/
public function getLicenseType()
{
if ($this->getLicenseData() === false) {
return AbstractLicense::TYPE_UNKNOWN;
}
return $this->type;
}
/**
* Get license websites limit
*
* @return int<0, max>
*/
public function getLicenseLimit()
{
if ($this->getLicenseData() === false) {
return 0;
}
return (int) max(0, (int) $this->data['license_limit']);
}
/**
* Get site count
*
* @return int<-1, max>
*/
public function getSiteCount()
{
if ($this->getLicenseData() === false) {
return -1;
}
return (int) max(-1, (int) $this->data['site_count']);
}
/**
* Deactivate license key
*
* @return int license status
*/
/**
* Get expiration date format
*
* @param string $format date format
*
* @return string return expirtation date formatted, Unknown if license data is not available or Lifetime if license is lifetime
*/
public function getExpirationDate($format = 'Y-m-d')
{
if ($this->getLicenseData() === false) {
return 'Unknown';
}
if ($this->data['expires'] === 'lifetime') {
return 'Lifetime';
}
if (empty($this->data['expires'])) {
return 'Unknown';
}
$expirationDate = new DateTime($this->data['expires']);
return $expirationDate->format($format);
}
/**
* Return expiration license days, if is expired a negative number is returned
*
* @return false|int reutrn false on fail or number of days to expire, PHP_INT_MAX is filetime
*/
public function getExpirationDays()
{
if ($this->getLicenseData() === false) {
return false;
}
if ($this->data['expires'] === 'lifetime') {
return PHP_INT_MAX;
}
if (empty($this->data['expires'])) {
return false;
}
$expirationDate = new DateTime($this->data['expires']);
return (-1 * intval($expirationDate->diff(new DateTime())->format('%r%a')));
}
/**
* check is have no activations left
*
* @return bool
*/
public function haveNoActivationsLeft()
{
return ($this->getStatus() === self::STATUS_SITE_INACTIVE && $this->data['activations_left'] === 0);
}
/**
* Return true if have active subscription
*
* @return bool
*/
public function haveActiveSubscription()
{
if ($this->getLicenseData() === false) {
return false;
}
return $this->data['activeSubscription'];
}
/**
* Get a license rquest
*
* @param mixed[] $params request params
*
* @return false|object
*/
public function request($params) {
// Simulate a successful license check response.
$response = (object)[
'license' => 'valid',
'item_name' => License::EDD_DUPPRO_ITEM_NAME,
// Add other necessary fields here.
];
return $response;
}
/**
* Get last error request
*
* @return array{code:int, message: string, details: string}
*/
public function getLastRequestError()
{
return $this->lastRequestError;
}
/**
* Get license status from status by string
*
* @param string $eddStatus license status string
*
* @return int
*/
private static function getStatusFromEDDStatus($eddStatus)
{
switch ($eddStatus) {
case 'valid':
return self::STATUS_VALID;
case 'invalid':
return self::STATUS_INVALID;
case 'expired':
return self::STATUS_EXPIRED;
case 'disabled':
return self::STATUS_DISABLED;
case 'site_inactive':
return self::STATUS_SITE_INACTIVE;
case 'inactive':
return self::STATUS_INACTIVE;
default:
return self::STATUS_UNKNOWN;
}
}
/**
* Return license statu string by status
*
* @return string
*/
public function getLicenseStatusString()
{
switch ($this->getStatus()) {
case self::STATUS_VALID:
return __('Valid', 'duplicator-pro');
case self::STATUS_INVALID:
return __('Invalid', 'duplicator-pro');
case self::STATUS_EXPIRED:
return __('Expired', 'duplicator-pro');
case self::STATUS_DISABLED:
return __('Disabled', 'duplicator-pro');
case self::STATUS_SITE_INACTIVE:
return __('Site Inactive', 'duplicator-pro');
case self::STATUS_EXPIRED:
return __('Expired', 'duplicator-pro');
default:
return __('Unknown', 'duplicator-pro');
}
}
}

View File

@@ -0,0 +1,216 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Addons\ProBase\LicensingController;
use Duplicator\Addons\ProBase\Models\LicenseData;
use Duplicator\Core\Controllers\ControllersManager;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = DUP_PRO_Global_Entity::getInstance();
LicenseData::getInstance()->clearCache();
$license_status = LicenseData::getInstance()->getStatus();
$license_type = License::getType();
$license_text_disabled = false;
$activate_button_text = __('Activate', 'duplicator-pro');
$license_status_text_alt = false;
switch ($license_status) {
case LicenseData::STATUS_VALID:
$license_status_style = 'color:#509B18';
$activate_button_text = __('Deactivate', 'duplicator-pro');
$license_text_disabled = true;
$license_key = License::getLicenseKey();
$license_status_text = '<b>' . __('Status: ', 'duplicator-pro') . '</b>' . __('Active', 'duplicator-pro');
$license_status_text .= '<br/>';
$license_status_text .= '<b>' . __('Expiration: ', 'duplicator-pro') . '</b>';
$license_status_text .= LicenseData::getInstance()->getExpirationDate(get_option('date_format'));
$expDays = LicenseData::getInstance()->getExpirationDays();
if ($expDays === false) {
$expDays = __('no data', 'duplicator-pro');
} elseif ($expDays <= 0) {
$expDays = __('expired', 'duplicator-pro');
} elseif ($expDays == PHP_INT_MAX) {
$expDays = __('no expiration', 'duplicator-pro');
} else {
$expDays = sprintf(__('%d days left', 'duplicator-pro'), $expDays);
}
$license_status_text .= ' (<b>' . $expDays . '</b>)';
break;
case LicenseData::STATUS_INACTIVE:
$license_status_style = 'color:#dd3d36;';
$license_status_text = __('Status: Inactive', 'duplicator-pro');
break;
case LicenseData::STATUS_SITE_INACTIVE:
$license_status_style = 'color:#dd3d36;';
$global = DUP_PRO_Global_Entity::getInstance();
if (LicenseData::getInstance()->haveNoActivationsLeft()) {
$license_status_text = __('Status: Inactive (out of site licenses).', 'duplicator-pro') . '<br>' . License::getNoActivationLeftMessage();
} else {
$license_status_text = __('Status: Inactive', 'duplicator-pro');
}
break;
case LicenseData::STATUS_EXPIRED:
$renewal_url = DUPLICATOR_PRO_BLOG_URL . 'checkout?edd_license_key=' . License::getLicenseKey();
$license_status_style = 'color:#dd3d36;';
$license_status_text = sprintf(
_x(
'Your Duplicator Pro license key has expired so you aren\'t getting important updates! %1$sRenew your license now%2$s',
'1: <a> tag, 2: </a> tag',
'duplicator-pro'
),
'<a target="_blank" href="' . $renewal_url . '">',
'</a>'
);
break;
default:
// https://duplicator.com/knowledge-base/how-to-resolve-license-activation-issues/
$license_status_style = 'color:#dd3d36;';
$license_status_text = '<b>' . __('Status: ', 'duplicator-pro') . '</b>' .
LicenseData::getInstance()->getLicenseStatusString() . '<br/>';
$license_status_text_alt = true;
break;
}
?>
<form
id="dup-license-activation-form"
action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>"
method="post"
data-parsley-validate
>
<h3 class="title"><?php esc_html_e('Activation', 'duplicator-pro') ?> </h3>
<hr size="1" />
<table class="form-table">
<?php
if ($global->license_key_visible !== License::VISIBILITY_NONE) : ?>
<tr valign="top" id="dup-tr-license-dashboard">
<th scope="row"><?php esc_html_e('Dashboard', 'duplicator-pro') ?></th>
<td>
<i class="fa fa-th-large fa-sm"></i>
<a target="_blank" href="<?php echo esc_url(DUPLICATOR_PRO_BLOG_URL . 'my-account'); ?>">
<?php
esc_html_e('Manage Account Online', 'duplicator-pro')
?>
</a>
</td>
</tr>
<tr valign="top" id="dup-tr-license-type">
<th scope="row"><?php esc_html_e('License Type', 'duplicator-pro') ?></th>
<td class="dup-license-type">
<?php LicensingController::displayLicenseInfo(); ?>
</td>
</tr>
<?php endif; ?>
<?php if ($global->license_key_visible === License::VISIBILITY_ALL) : ?>
<tr valign="top" id="dup-tr-license-key-and-description">
<th scope="row">
<label><?php esc_html_e('License Key', 'duplicator-pro'); ?></label>
</th>
<td class="dup-license-key-area">
<input
type="text"
class="dup-license-key-input"
name="_license_key"
id="_license_key"
value="<?php echo esc_attr(License::getLicenseKey()); ?>">
<br>
<p class="description">
<span style="<?php echo esc_attr($license_status_style); ?>" >
<?php
echo wp_kses(
$license_status_text,
[
'a' => [
'href' => [],
'target' => [],
],
'b' => [],
'br' => [],
]
);
?>
</span>
<?php
if ($license_status_text_alt) {
esc_html_e('If license activation fails please wait a few minutes and retry.', 'duplicator-pro');
?>
<div class="dup-license-status-notes ">
<?php
printf(
esc_html_x(
'- Failure to activate after several attempts please review %1$sfaq activation steps%2$s.',
'1 and 2 represent opening and closing anchor tags (<a> and </a>)',
'duplicator-pro'
),
'<a target="_blank" href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-resolve-license-activation-issues/') . '">',
'</a>'
);
?>
<br/>
<?php
printf(
esc_html_x(
'- To upgrade or renew your license visit %1$sduplicator.com%2$s.',
'1 and 2 represent opening and closing anchor tags (<a> and </a>)',
'duplicator-pro'
),
'<a target="_blank" href="' . esc_url(DUPLICATOR_PRO_BLOG_URL) . '">',
'</a>'
);
?>
<br/>
<?php esc_html_e('- A valid key is needed for plugin updates but not for functionality.', 'duplicator-pro'); ?>
</div>
<?php } ?>
</p>
</td>
</tr>
<?php endif;?>
<tr>
<th scope="row" class="dup-license-key-btns">
<label><?php esc_html_e('License Action', 'duplicator-pro'); ?></label>
</th>
<td class="dup-license-key-btns">
<?php $echostring = (($license_status != LicenseData::STATUS_VALID) ? 'true' : 'false'); ?>
<div class="dup-license-key-btns">
<?php if ($global->license_key_visible === License::VISIBILITY_ALL) : ?>
<button
id="dup-license-activation-btn"
class="button"
onclick="DupPro.Licensing.ChangeActivationStatus(<?php echo esc_js($echostring); ?>);return false;">
<?php echo esc_html($activate_button_text); ?>
</button>
<?php endif;?>
<button
id="dup-license-clear-btn"
class="button"
onclick="DupPro.Licensing.ClearActivationStatus();return false;"
>
<?php esc_html_e('Clear Key', 'duplicator-pro') ?>
</button>
</div>
</td>
</tr>
</table>
</form>

View File

@@ -0,0 +1,80 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Addons\ProBase\LicensingController;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$tplMng->render('licensing/activation');
$tplMng->render('licensing/visibility');
?>
<script>
jQuery(document).ready(function($) {
DupPro.Licensing = new Object();
DupPro.Licensing.VISIBILITY_ALL = <?php echo (int) License::VISIBILITY_ALL;?>;
DupPro.Licensing.VISIBILITY_INFO = <?php echo (int) License::VISIBILITY_INFO;?>;
DupPro.Licensing.VISIBILITY_NONE = <?php echo (int) License::VISIBILITY_NONE;?>;
$("#_key_password, #_key_password_confirmation").keyup(function(event) {
if (event.keyCode == 13) {
$("#show_hide").click();
}
});
DupPro.Licensing.ChangeActivationStatus = function(activate) {
if (activate) {
let licenseKey = $('.dup-license-key-input').val();
window.location.href =
<?php echo json_encode($tplData['actions'][LicensingController::ACTION_ACTIVATE_LICENSE]->getUrl()); ?> +
'&_license_key=' + encodeURIComponent(licenseKey);
} else {
window.location.href = <?php echo json_encode($tplData['actions'][LicensingController::ACTION_DEACTIVATE_LICENSE]->getUrl()); ?>;
}
return false;
}
DupPro.Licensing.ClearActivationStatus = function() {
window.location.href = <?php echo json_encode($tplData['actions'][LicensingController::ACTION_CLEAR_KEY]->getUrl()); ?>;
}
DupPro.Licensing.ChangeKeyVisibility = function(show) {
$('#dup-license-visibility-form').submit();
}
DupPro.Licensing.VisibilityTemporary = function(visibility) {
switch (visibility) {
case DupPro.Licensing.VISIBILITY_ALL:
$("#dup-tr-license-dashboard").show();
$("#dup-tr-license-type").show();
$("#dup-tr-license-key-and-description").show();
break;
case DupPro.Licensing.VISIBILITY_INFO:
$("#dup-tr-license-dashboard").show();
$("#dup-tr-license-type").show();
$("#dup-tr-license-key-and-description").hide();
break;
case DupPro.Licensing.VISIBILITY_NONE:
$("#dup-tr-license-dashboard").hide();
$("#dup-tr-license-type").hide();
$("#dup-tr-license-key-and-description").hide();
break;
default:
alert("Unexpected visibility value!");
}
}
});
</script>

View File

@@ -0,0 +1,68 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Libs\Snap\SnapUtil;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
if (empty($tplData['license_message'])) {
return;
}
$details = "";
if (isset($tplData['license_request_error'])) {
$details = 'Message: ' . $tplData['license_request_error']['message'] . "\n" .
'Error code: ' . $tplData['license_request_error']['code'] . "\n" .
"\n" . 'Request Details' . "\n" .
$tplData['license_request_error']['requestDetails'] .
"\n" . 'Response Details' . "\n" .
$tplData['license_request_error']['details'];
}
?>
<p>
<?php if (!$tplData['license_success']) { ?>
<i class="fa fa-exclamation-triangle"></i>&nbsp;
<?php } ?>
<?php echo esc_html($tplData['license_message']) ?>
</p>
<?php if (isset($tplData['license_request_error'])) {
?>
<textarea class="dup-error-message-textarea" disabled ><?php echo esc_textarea($details); ?></textarea>
<button
data-dup-copy-value="<?php echo esc_attr($details); ?>"
data-dup-copy-title="<?php echo esc_attr("Copy Error Message to clipboard"); ?>"
data-dup-copied-title="<?php echo esc_attr("Error Message copied to clipboard"); ?>"
class="button dup-btn-copy-error-message">
<?php esc_html_e('Copy error details', 'duplicator-pro'); ?>
</button>
<?php if (!SnapUtil::isCurlEnabled()) {
$tplMng->render('licensing/notices/curl_message');
} ?>
<p>
<?php
printf(
wp_kses(
__("If the error persists please open a ticket <a href=\"%s\">here</a> and attach the errors details.", 'duplicator-pro'),
array(
'a' => array(
'href' => array(),
),
)
),
esc_url(DUPLICATOR_PRO_BLOG_URL . 'my-account/support/')
);
?>
</p>
<?php } ?>

View File

@@ -0,0 +1,47 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
?>
<p>
<?php
echo wp_kses(
__(
'<b>CURL isn\'t enabled.</b> This module is far more reliable for remote communication.',
'duplicator-pro'
),
ViewHelper::GEN_KSES_TAGS
);
?>
</br>
<?php esc_html_e('A possible solution to the problem could be to activate it.', 'duplicator-pro'); ?>
</br>
<?php
printf(
wp_kses(
_x(
'For detailed steps on how to enable cURL please see <b>Solution 3, Issue A</b> in %1$sthis FAQ Entry%2$s.',
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
'duplicator-pro'
),
ViewHelper::GEN_KSES_TAGS
),
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-resolve-license-activation-issues/') . '" target="_blank">',
'</a>'
);
?>
<br/>
</p>

View File

@@ -0,0 +1,61 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Addons\ProBase\License\License;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$daysLeft = $tplData['schedule_disalbe_days_left'];
$activeSchedule = $tplData['active_schedule_present'];
if ($daysLeft === false) {
return;
}
if ($activeSchedule) {
?>
<u>
<?php
if (License::can(License::CAPABILITY_SCHEDULE)) {
$message = sprintf(
_n(
'Scheduled Backups are going to be disabled <b><em>in %d day</em></b>.',
'Scheduled Backups are going to be disabled <b><em>in %d days</em></b>.',
$daysLeft,
'duplicator-pro'
),
$daysLeft
);
$message .= __(' Please renew your license to assure your backups are not interrupted.', 'duplicator-pro');
echo wp_kses(
$message,
array(
'b' => array(),
'em' => array(),
)
);
} else {
esc_html_e(
'All automatic backups have been disabeld. Please renew your license to re-enable them.',
'duplicator-pro'
);
}
?>
</u>
<?php
} else {
esc_html_e(
'Scheduled Backups.',
'duplicator-pro'
);
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* @package Duplicator
*/
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$renewal_url = $tplData['renewal_url'];
?>
<span class='dashicons dashicons-warning'></span>
<div class="dup-sub-content">
<h3>
<?php esc_html_e('Warning! Your Duplicator Pro license has expired...', 'duplicator-pro');?>
</h3>
<?php esc_html_e('You\'re currently missing:', 'duplicator-pro'); ?>
<ul class="dup-pro-simple-style-disc" >
<li><?php esc_html_e('Access to Advanced Features', 'duplicator-pro'); ?></li>
<li><?php $tplMng->render('licensing/notices/drm_schedules_msg'); ?></li>
<li><?php esc_html_e('Storages Management', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Templates Management', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('New Features', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Important Updates for Security Patches', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Bug Fixes', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Support Requests', 'duplicator-pro'); ?></li>
</ul>
<a class="button" target="_blank" href="<?php echo esc_url($renewal_url); ?>">
<?php esc_html_e('Renew Now!', 'duplicator-pro'); ?>
</a>
</div>

View File

@@ -0,0 +1,62 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Addons\ProBase\LicensingController;
use Duplicator\Core\Controllers\ControllersManager;
use Duplicator\Views\ViewHelper;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$img_url = plugins_url('duplicator-pro/assets/img/warning.png');
$problem_text = $tplData['problem'];
$licensing_tab_url = ControllersManager::getMenuLink(ControllersManager::SETTINGS_SUBMENU_SLUG, LicensingController::L2_SLUG_LICENSING);
?>
<span class='dashicons dashicons-warning'></span>
<div class="dup-sub-content">
<h3>
<?php
printf(
esc_html_x('Your Duplicator Pro license key is %1$s ...', '%1$s represent the license status', 'duplicator-pro'),
esc_html($tplData['problem'])
);
?>
</h3>
<?php esc_html_e('You\'re currently missing:', 'duplicator-pro'); ?>
<ul class="dup-pro-simple-style-disc" >
<li><?php esc_html_e('Access to Advanced Features', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Scheduled Backups', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Storages Management', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Templates Management', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('New Features', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Important Updates for Security Patches', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Bug Fixes', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Support Requests', 'duplicator-pro'); ?></li>
</ul>
<?php
printf(
wp_kses(
_x(
'<b>Please %1$sActivate Your License%2$s</b>. If you do not have a license key go to %3$sduplicator.com%4$s to get it.',
'1 and 2 are opening and 3 and 4 are closing anchor tags (<a> and </a>)',
'duplicator-pro'
),
ViewHelper::GEN_KSES_TAGS
),
'<a href="' . esc_url($licensing_tab_url) . '">',
'</a>',
'<a target="_blank" href="' . esc_url(DUPLICATOR_PRO_BLOG_URL . 'my-account') . '">',
'</a>'
);
?>
</div>

View File

@@ -0,0 +1,60 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Addons\ProBase\LicensingController;
use Duplicator\Core\Controllers\ControllersManager;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$licensing_tab_url = ControllersManager::getMenuLink(ControllersManager::SETTINGS_SUBMENU_SLUG, LicensingController::L2_SLUG_LICENSING);
$dashboard_url = DUPLICATOR_PRO_BLOG_URL . 'my-account';
$img_url = plugins_url('duplicator-pro/assets/img/warning.png');
?>
<span class='dashicons dashicons-warning'></span>
<div class="dup-sub-content">
<h3>
<?php esc_html_e('Duplicator Pro\'s license is deactivated because you\'re out of site activations.', 'duplicator-pro'); ?>
</h3>
<?php esc_html_e('You\'re currently missing:', 'duplicator-pro'); ?>
<ul class="dup-pro-simple-style-disc" >
<li><?php esc_html_e('Access to Advanced Features', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Scheduled Backups', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Storages Management', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Templates Management', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('New Features', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Important Updates for Security Patches', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Bug Fixes', 'duplicator-pro'); ?></li>
<li><?php esc_html_e('Support Requests', 'duplicator-pro'); ?></li>
</ul>
<?php
printf(
wp_kses(
_x(
'Upgrade your license using the %1$sDuplicator Dashboard%2$s or deactivate plugin on old sites.<br/>
After making necessary changes %3$srefresh the license status%4$s.',
'1 and 2 are opening and 3 and 4 are closing anchor tags (<a> and </a>)',
'duplicator-pro'
),
[
'br' => [],
]
),
'<a href="' . esc_url($dashboard_url) . '" target="_blank">',
'</a>',
'<a href="' . esc_url($licensing_tab_url) . '">',
'</a>'
);
?>
</div>

View File

@@ -0,0 +1,113 @@
<?php
/**
* @package Duplicator
*/
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Addons\ProBase\LicensingController;
use Duplicator\Core\Controllers\ControllersManager;
defined("ABSPATH") or die("");
/**
* Variables
*
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
* @var Duplicator\Core\Views\TplMng $tplMng
* @var array<string, mixed> $tplData
*/
$global = DUP_PRO_Global_Entity::getInstance();
?>
<h3 class="title"><?php esc_html_e("Key Visibility", 'duplicator-pro') ?> </h3>
<small>
<?php
esc_html_e(
"This is an optional setting that prevents the 'License Key' from being copied.
Select the desired visibility mode, enter a password and hit the 'Change Visibility' button.",
'duplicator-pro'
);
echo '<br/>';
esc_html_e("Note: the password can be anything, it does not have to be the same as the WordPress user password.", 'duplicator-pro');
?>
</small>
<hr size="1" />
<form
id="dup-license-visibility-form"
action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>"
method="post"
data-parsley-validate
>
<?php $tplData['actions'][LicensingController::ACTION_CHANGE_VISIBILITY]->getActionNonceFileds(); ?>
<table class="form-table">
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Visibility", 'duplicator-pro'); ?></label></th>
<td>
<label class="margin-right-1">
<input
type="radio"
name="license_key_visible"
value="<?php echo (int) License::VISIBILITY_ALL;?>"
onclick="DupPro.Licensing.VisibilityTemporary(<?php echo (int) License::VISIBILITY_ALL;?>);"
<?php checked($global->license_key_visible, License::VISIBILITY_ALL); ?>
>
<?php esc_html_e("License Visible", 'duplicator-pro'); ?>
</label>
<label class="margin-right-1">
<input
type="radio"
name="license_key_visible"
value="<?php echo (int) License::VISIBILITY_INFO;?>"
onclick="DupPro.Licensing.VisibilityTemporary(<?php echo (int) License::VISIBILITY_INFO;?>);"
<?php checked($global->license_key_visible, License::VISIBILITY_INFO); ?>
>
<?php esc_html_e("Info Only", 'duplicator-pro'); ?>
</label>
<label>
<input
type="radio"
name="license_key_visible"
value="<?php echo (int) License::VISIBILITY_NONE;?>"
onclick="DupPro.Licensing.VisibilityTemporary(<?php echo (int) License::VISIBILITY_NONE;?>);"
<?php checked($global->license_key_visible, License::VISIBILITY_NONE); ?>
>
<?php esc_html_e("License Invisible", 'duplicator-pro'); ?>
</label>
</td>
</tr>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Password", 'duplicator-pro'); ?></label></th>
<td>
<input type="password" class="dup-wide-input" name="_key_password" id="_key_password" size="50" />
</td>
</tr>
<?php if ($global->license_key_visible == License::VISIBILITY_ALL) { ?>
<tr valign="top">
<th scope="row"><label><?php esc_html_e("Retype Password", 'duplicator-pro'); ?></label></th>
<td>
<input
type="password"
class="dup-wide-input"
name="_key_password_confirmation"
id="_key_password_confirmation"
data-parsley-equalto="#_key_password"
size="50"
>
</td>
</tr>
<?php } ?>
<tr valign="top">
<th scope="row"></th>
<td>
<button
class="button"
id="show_hide"
onclick="DupPro.Licensing.ChangeKeyVisibility(); return false;"
>
<?php esc_html_e('Change Visibility', 'duplicator-pro'); ?>
</button>
</td>
</tr>
</table>
</form>

View File

@@ -0,0 +1,660 @@
<?php
namespace Duplicator\Addons\ProBase\Vendor\EDD;
/**
* Duplicator Changes
*
* wp_remote_post => wp_remote_get
*/
use Duplicator\Libs\Snap\SnapLog;
use stdClass;
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Allows plugins to use their own update API.
*
* @author Easy Digital Downloads
* @version 1.9.1
*/
class EDD_SL_Plugin_Updater {
private $api_url = '';
private $api_data = array();
private $plugin_file = '';
private $name = '';
private $slug = '';
private $version = '';
private $wp_override = false;
private $beta = false;
private $failed_request_cache_key;
/**
* Class constructor.
*
* @uses plugin_basename()
* @uses hook()
*
* @param string $_api_url The URL pointing to the custom API endpoint.
* @param string $_plugin_file Path to the plugin file.
* @param array $_api_data Optional data to send with API calls.
*/
public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
global $edd_plugin_data;
$this->api_url = trailingslashit( $_api_url );
$this->api_data = $_api_data;
$this->plugin_file = $_plugin_file;
$this->name = plugin_basename( $_plugin_file );
$this->slug = basename( $_plugin_file, '.php' );
$this->version = $_api_data['version'];
$this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false;
$this->beta = ! empty( $this->api_data['beta'] ) ? true : false;
$this->failed_request_cache_key = 'edd_sl_failed_http_' . md5( $this->api_url );
$edd_plugin_data[ $this->slug ] = $this->api_data;
/**
* Fires after the $edd_plugin_data is setup.
*
* @since x.x.x
*
* @param array $edd_plugin_data Array of EDD SL plugin data.
*/
do_action( 'post_edd_sl_plugin_updater_setup', $edd_plugin_data );
// Set up hooks.
$this->init();
}
/**
* Set up WordPress filters to hook into WP's update process.
*
* @uses add_filter()
*
* @return void
*/
public function init() {
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
add_action( 'after_plugin_row', array( $this, 'show_update_notification' ), 10, 2 );
add_action( 'admin_init', array( $this, 'show_changelog' ) );
}
/**
* Check for Updates at the defined API endpoint and modify the update array.
*
* This function dives into the update API just when WordPress creates its update array,
* then adds a custom API call and injects the custom plugin data retrieved from the API.
* It is reassembled from parts of the native WordPress plugin update code.
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
*
* @uses api_request()
*
* @param array $_transient_data Update array build by WordPress.
* @return array Modified update array with custom plugin data.
*/
public function check_update( $_transient_data ) {
global $pagenow;
if ( ! is_object( $_transient_data ) ) {
$_transient_data = new stdClass();
}
if ( ! empty( $_transient_data->response ) && ! empty( $_transient_data->response[ $this->name ] ) && false === $this->wp_override ) {
return $_transient_data;
}
$current = $this->get_repo_api_data();
if ( false !== $current && is_object( $current ) && isset( $current->new_version ) ) {
if ( version_compare( $this->version, $current->new_version, '<' ) ) {
$_transient_data->response[ $this->name ] = $current;
} else {
// Populating the no_update information is required to support auto-updates in WordPress 5.5.
$_transient_data->no_update[ $this->name ] = $current;
}
}
$_transient_data->last_checked = time();
$_transient_data->checked[ $this->name ] = $this->version;
return $_transient_data;
}
/**
* Get repo API data from store.
* Save to cache.
*
* @return \stdClass
*/
public function get_repo_api_data() {
$version_info = $this->get_cached_version_info();
if ( false === $version_info ) {
$version_info = $this->api_request(
'plugin_latest_version',
array(
'slug' => $this->slug,
'beta' => $this->beta,
)
);
if ( ! $version_info ) {
return false;
}
// This is required for your plugin to support auto-updates in WordPress 5.5.
$version_info->plugin = $this->name;
$version_info->id = $this->name;
$this->set_version_info_cache( $version_info );
}
return $version_info;
}
/**
* Show the update notification on multisite subsites.
*
* @param string $file
* @param array $plugin
*/
public function show_update_notification( $file, $plugin ) {
// Return early if in the network admin, or if this is not a multisite install.
if ( is_network_admin() || ! is_multisite() ) {
return;
}
// Allow single site admins to see that an update is available.
if ( ! current_user_can( 'activate_plugins' ) ) {
return;
}
if ( $this->name !== $file ) {
return;
}
// Do not print any message if update does not exist.
$update_cache = get_site_transient( 'update_plugins' );
if ( ! isset( $update_cache->response[ $this->name ] ) ) {
if ( ! is_object( $update_cache ) ) {
$update_cache = new stdClass();
}
$update_cache->response[ $this->name ] = $this->get_repo_api_data();
}
// Return early if this plugin isn't in the transient->response or if the site is running the current or newer version of the plugin.
if ( empty( $update_cache->response[ $this->name ] ) || version_compare( $this->version, $update_cache->response[ $this->name ]->new_version, '>=' ) ) {
return;
}
printf(
'<tr class="plugin-update-tr %3$s" id="%1$s-update" data-slug="%1$s" data-plugin="%2$s">',
$this->slug,
$file,
in_array( $this->name, $this->get_active_plugins(), true ) ? 'active' : 'inactive'
);
echo '<td colspan="3" class="plugin-update colspanchange">';
echo '<div class="update-message notice inline notice-warning notice-alt"><p>';
$changelog_link = '';
if ( ! empty( $update_cache->response[ $this->name ]->sections->changelog ) ) {
$changelog_link = add_query_arg(
array(
'edd_sl_action' => 'view_plugin_changelog',
'plugin' => urlencode( $this->name ),
'slug' => urlencode( $this->slug ),
'TB_iframe' => 'true',
'width' => 77,
'height' => 911,
),
self_admin_url( 'index.php' )
);
}
$update_link = add_query_arg(
array(
'action' => 'upgrade-plugin',
'plugin' => urlencode( $this->name ),
),
self_admin_url( 'update.php' )
);
printf(
/* translators: the plugin name. */
esc_html__( 'There is a new version of %1$s available.', 'easy-digital-downloads', 'duplicator-pro' ),
esc_html( $plugin['Name'] )
);
if ( ! current_user_can( 'update_plugins' ) ) {
echo ' ';
esc_html_e( 'Contact your network administrator to install the update.', 'easy-digital-downloads', 'duplicator-pro' );
} elseif ( empty( $update_cache->response[ $this->name ]->package ) && ! empty( $changelog_link ) ) {
echo ' ';
printf(
/* translators: 1. opening anchor tag, do not translate 2. the new plugin version 3. closing anchor tag, do not translate. */
__( '%1$sView version %2$s details%3$s.', 'easy-digital-downloads', 'duplicator-pro' ),
'<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
esc_html( $update_cache->response[ $this->name ]->new_version ),
'</a>'
);
} elseif ( ! empty( $changelog_link ) ) {
echo ' ';
printf(
__( '%1$sView version %2$s details%3$s or %4$supdate now%5$s.', 'easy-digital-downloads', 'duplicator-pro' ),
'<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
esc_html( $update_cache->response[ $this->name ]->new_version ),
'</a>',
'<a target="_blank" class="update-link" href="' . esc_url( wp_nonce_url( $update_link, 'upgrade-plugin_' . $file ) ) . '">',
'</a>'
);
} else {
printf(
' %1$s%2$s%3$s',
'<a target="_blank" class="update-link" href="' . esc_url( wp_nonce_url( $update_link, 'upgrade-plugin_' . $file ) ) . '">',
esc_html__( 'Update now.', 'easy-digital-downloads', 'duplicator-pro' ),
'</a>'
);
}
do_action( "in_plugin_update_message-{$file}", $plugin, $plugin );
echo '</p></div></td></tr>';
}
/**
* Gets the plugins active in a multisite network.
*
* @return array
*/
private function get_active_plugins() {
$active_plugins = (array) get_option( 'active_plugins' );
$active_network_plugins = (array) get_site_option( 'active_sitewide_plugins' );
return array_merge( $active_plugins, array_keys( $active_network_plugins ) );
}
/**
* Updates information on the "View version x.x details" page with custom data.
*
* @uses api_request()
*
* @param mixed $_data
* @param string $_action
* @param object $_args
* @return object $_data
*/
public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
if ( 'plugin_information' !== $_action ) {
return $_data;
}
if ( ! isset( $_args->slug ) || ( $_args->slug !== $this->slug ) ) {
return $_data;
}
$to_send = array(
'slug' => $this->slug,
'is_ssl' => is_ssl(),
'fields' => array(
'banners' => array(),
'reviews' => false,
'icons' => array(),
),
);
// Get the transient where we store the api request for this plugin for 24 hours
$edd_api_request_transient = $this->get_cached_version_info();
//If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
if ( empty( $edd_api_request_transient ) ) {
$api_response = $this->api_request( 'plugin_information', $to_send );
// Expires in 3 hours
$this->set_version_info_cache( $api_response );
if ( false !== $api_response ) {
$_data = $api_response;
}
} else {
$_data = $edd_api_request_transient;
}
// Convert sections into an associative array, since we're getting an object, but Core expects an array.
if ( isset( $_data->sections ) && ! is_array( $_data->sections ) ) {
$_data->sections = $this->convert_object_to_array( $_data->sections );
}
// Convert banners into an associative array, since we're getting an object, but Core expects an array.
if ( isset( $_data->banners ) && ! is_array( $_data->banners ) ) {
$_data->banners = $this->convert_object_to_array( $_data->banners );
}
// Convert icons into an associative array, since we're getting an object, but Core expects an array.
if ( isset( $_data->icons ) && ! is_array( $_data->icons ) ) {
$_data->icons = $this->convert_object_to_array( $_data->icons );
}
// Convert contributors into an associative array, since we're getting an object, but Core expects an array.
if ( isset( $_data->contributors ) && ! is_array( $_data->contributors ) ) {
$_data->contributors = $this->convert_object_to_array( $_data->contributors );
}
if ( ! isset( $_data->plugin ) ) {
$_data->plugin = $this->name;
}
return $_data;
}
/**
* Convert some objects to arrays when injecting data into the update API
*
* Some data like sections, banners, and icons are expected to be an associative array, however due to the JSON
* decoding, they are objects. This method allows us to pass in the object and return an associative array.
*
* @since 3.6.5
*
* @param stdClass $data
*
* @return array
*/
private function convert_object_to_array( $data ) {
if ( ! is_array( $data ) && ! is_object( $data ) ) {
return array();
}
$new_data = array();
foreach ( $data as $key => $value ) {
$new_data[ $key ] = is_object( $value ) ? $this->convert_object_to_array( $value ) : $value;
}
return $new_data;
}
/**
* Disable SSL verification in order to prevent download update failures
*
* @param array $args
* @param string $url
* @return object $array
*/
public function http_request_args( $args, $url ) {
if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
$args['sslverify'] = $this->verify_ssl();
}
return $args;
}
/**
* Calls the API and, if successfull, returns the object delivered by the API.
*
* @uses get_bloginfo()
* @uses wp_remote_get()
* @uses is_wp_error()
*
* @param string $_action The requested action.
* @param array $_data Parameters for the API action.
* @return false|object|void
*/
private function api_request( $_action, $_data ) {
$data = array_merge( $this->api_data, $_data );
if ( $data['slug'] !== $this->slug ) {
return;
}
// Don't allow a plugin to ping itself
if ( trailingslashit( home_url() ) === $this->api_url ) {
return false;
}
if ( $this->request_recently_failed() ) {
return false;
}
return $this->get_version_from_remote();
}
/**
* Determines if a request has recently failed.
*
* @since 1.9.1
*
* @return bool
*/
private function request_recently_failed() {
$failed_request_details = get_option( $this->failed_request_cache_key );
// Request has never failed.
if ( empty( $failed_request_details ) || ! is_numeric( $failed_request_details ) ) {
return false;
}
/*
* Request previously failed, but the timeout has expired.
* This means we're allowed to try again.
*/
if ( time() > $failed_request_details ) {
delete_option( $this->failed_request_cache_key );
return false;
}
return true;
}
/**
* Logs a failed HTTP request for this API URL.
* We set a timestamp for 1 hour from now. This prevents future API requests from being
* made to this domain for 1 hour. Once the timestamp is in the past, API requests
* will be allowed again. This way if the site is down for some reason we don't bombard
* it with failed API requests.
*
* @see EDD_SL_Plugin_Updater::request_recently_failed
*
* @since 1.9.1
*/
private function log_failed_request() {
update_option( $this->failed_request_cache_key, strtotime( '+1 hour' ) );
}
/**
* If available, show the changelog for sites in a multisite install.
*/
public function show_changelog() {
if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' !== $_REQUEST['edd_sl_action'] ) {
return;
}
if ( empty( $_REQUEST['plugin'] ) ) {
return;
}
if ( empty( $_REQUEST['slug'] ) || $this->slug !== $_REQUEST['slug'] ) {
return;
}
if ( ! current_user_can( 'update_plugins' ) ) {
wp_die( esc_html__( 'You do not have permission to install plugin updates', 'easy-digital-downloads', 'duplicator-pro' ), esc_html__( 'Error', 'easy-digital-downloads', 'duplicator-pro' ), array( 'response' => 403 ) );
}
$version_info = $this->get_repo_api_data();
if ( isset( $version_info->sections ) ) {
$sections = $this->convert_object_to_array( $version_info->sections );
if ( ! empty( $sections['changelog'] ) ) {
echo '<div style="background:#fff;padding:10px;">' . wp_kses_post( $sections['changelog'] ) . '</div>';
}
}
exit;
}
/**
* Gets the current version information from the remote site.
*
* @return array|false
*/
private function get_version_from_remote() {
$api_params = array(
'edd_action' => 'get_version',
'license' => ! empty( $this->api_data['license'] ) ? $this->api_data['license'] : '',
'item_name' => isset( $this->api_data['item_name'] ) ? $this->api_data['item_name'] : false,
'item_id' => isset( $this->api_data['item_id'] ) ? $this->api_data['item_id'] : false,
'version' => isset( $this->api_data['version'] ) ? $this->api_data['version'] : false,
'slug' => $this->slug,
'author' => $this->api_data['author'],
'url' => home_url(),
'beta' => $this->beta,
'php_version' => phpversion(),
'wp_version' => get_bloginfo( 'version' ),
);
/**
* Filters the parameters sent in the API request.
*
* @param array $api_params The array of data sent in the request.
* @param array $this->api_data The array of data set up in the class constructor.
* @param string $this->plugin_file The full path and filename of the file.
*/
$api_params = apply_filters( 'edd_sl_plugin_updater_api_params', $api_params, $this->api_data, $this->plugin_file );
$request = wp_remote_get(
$this->api_url,
array(
'timeout' => 15,
'sslverify' => $this->verify_ssl(),
'body' => $api_params,
)
);
if ( is_wp_error( $request ) || ( 200 !== wp_remote_retrieve_response_code( $request ) ) ) {
$this->log_failed_request();
return false;
}
$request = json_decode( wp_remote_retrieve_body( $request ) );
if ( $request && isset( $request->sections ) ) {
$request->sections = maybe_unserialize( $request->sections );
} else {
$request = false;
}
if ( $request && isset( $request->banners ) ) {
$request->banners = maybe_unserialize( $request->banners );
}
if ( $request && isset( $request->icons ) ) {
$request->icons = maybe_unserialize( $request->icons );
}
if ( ! empty( $request->sections ) ) {
foreach ( $request->sections as $key => $section ) {
$request->$key = (array) $section;
}
}
return $request;
}
/**
* Get the version info from the cache, if it exists.
*
* @param string $cache_key
* @return object
*/
public function get_cached_version_info( $cache_key = '' ) {
if ( empty( $cache_key ) ) {
$cache_key = $this->get_cache_key();
}
$cache = get_option( $cache_key );
// Cache is expired
if ( empty( $cache['timeout'] ) || time() > $cache['timeout'] ) {
return false;
}
// We need to turn the icons into an array, thanks to WP Core forcing these into an object at some point.
$cache['value'] = json_decode( $cache['value'] );
if ( ! empty( $cache['value']->icons ) ) {
$cache['value']->icons = (array) $cache['value']->icons;
}
return $cache['value'];
}
/**
* Adds the plugin version information to the database.
*
* @param false|string $value
* @param string $cache_key
*/
public function set_version_info_cache( $value = '', $cache_key = '' ) {
if ( empty( $cache_key ) ) {
$cache_key = $this->get_cache_key();
}
if (function_exists('wp_json_encode')) {
$value = wp_json_encode( $value );
} else {
$value = json_encode( $value );
}
$data = array(
'timeout' => strtotime( '+3 hours', time() ),
'value' => $value
);
update_option( $cache_key, $data, 'no' );
// Delete the duplicate option
delete_option( 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) ) );
}
/**
* Returns if the SSL of the store should be verified.
*
* @since 1.6.13
* @return bool
*/
private function verify_ssl() {
return (bool) apply_filters( 'edd_sl_api_request_verify_ssl', true, $this );
}
/**
* Gets the unique key (option name) for a plugin.
*
* @since 1.9.0
* @return string
*/
private function get_cache_key() {
$string = $this->slug . $this->api_data['license'] . $this->beta;
return 'edd_sl_' . md5( serialize( $string ) );
}
}

View File

@@ -0,0 +1,3 @@
<?php
//silent