first commit
This commit is contained in:
@@ -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__;
|
||||
}
|
||||
}
|
||||
@@ -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__;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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.';
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\ProBase\License;
|
||||
|
||||
class LicenseUtils
|
||||
{
|
||||
}
|
||||
@@ -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> ';
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
<?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 } ?>
|
||||
@@ -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>
|
||||
@@ -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'
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user