1402 lines
48 KiB
PHP
1402 lines
48 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @package Duplicator
|
|
* @copyright (c) 2022, Snap Creek LLC
|
|
*/
|
|
|
|
use Duplicator\Addons\ProBase\License\License;
|
|
use Duplicator\Core\MigrationMng;
|
|
use Duplicator\Core\Models\AbstractEntitySingleton;
|
|
use Duplicator\Libs\Snap\SnapIO;
|
|
use Duplicator\Libs\Snap\SnapLog;
|
|
use Duplicator\Libs\Snap\SnapURL;
|
|
use Duplicator\Libs\Snap\SnapWP;
|
|
use Duplicator\Libs\Snap\SnapUtil;
|
|
use Duplicator\Models\DynamicGlobalEntity;
|
|
use Duplicator\Models\Storages\Local\LocalStorage;
|
|
use Duplicator\Models\Storages\StoragesUtil;
|
|
use Duplicator\Utils\Crypt\CryptBlowfish;
|
|
use Duplicator\Utils\Email\EmailSummaryBootstrap;
|
|
use Duplicator\Utils\Email\EmailSummary;
|
|
use Duplicator\Utils\ZipArchiveExtended;
|
|
use VendorDuplicator\Amk\JsonSerialize\JsonSerialize;
|
|
use Duplicator\Utils\GroupOptions;
|
|
use Duplicator\Utils\PathUtil;
|
|
use Duplicator\Utils\Settings\ModelMigrateSettingsInterface;
|
|
use Duplicator\Utils\UsageStatistics\CommStats;
|
|
|
|
abstract class DUP_PRO_Dropbox_Transfer_Mode
|
|
{
|
|
const Unconfigured = -1;
|
|
const Disabled = 0;
|
|
const cURL = 1;
|
|
const FOpen_URL = 2;
|
|
}
|
|
|
|
abstract class DUP_PRO_Google_Drive_Transfer_Mode
|
|
{
|
|
const Unconfigured = -1;
|
|
const Auto = 0;
|
|
const FOpen_URL = 1;
|
|
}
|
|
|
|
abstract class DUP_PRO_Thread_Lock_Mode
|
|
{
|
|
const Flock = 0;
|
|
const SQL_Lock = 1;
|
|
}
|
|
|
|
abstract class DUP_PRO_Sql_Lock_Check
|
|
{
|
|
const Sql_Success = 1;
|
|
const Sql_Fail = -1;
|
|
}
|
|
|
|
abstract class DUP_PRO_Email_Build_Mode
|
|
{
|
|
const No_Emails = 0;
|
|
const Email_On_Failure = 1;
|
|
const Email_On_All_Builds = 2;
|
|
}
|
|
|
|
abstract class DUP_PRO_Archive_Build_Mode
|
|
{
|
|
const Unconfigured = -1;
|
|
const Shell_Exec = 1;
|
|
const ZipArchive = 2;
|
|
const DupArchive = 3;
|
|
}
|
|
|
|
class DUP_PRO_Server_Load_Reduction
|
|
{
|
|
const None = 0;
|
|
const A_Bit = 1;
|
|
const More = 2;
|
|
const A_Lot = 3;
|
|
|
|
/**
|
|
* @param int $reduction ENUM::Server_Load_Reduction
|
|
*
|
|
* @return int<0,max> microseconds
|
|
*/
|
|
public static function microseconds_from_reduction($reduction)
|
|
{
|
|
switch ($reduction) {
|
|
case self::A_Bit:
|
|
return 20;
|
|
case self::More:
|
|
return 100;
|
|
case self::A_Lot:
|
|
return 500;
|
|
case self::None:
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
abstract class DUP_PRO_ZipArchive_Mode
|
|
{
|
|
const Multithreaded = 0;
|
|
const SingleThread = 1;
|
|
}
|
|
|
|
class DUP_PRO_Global_Entity extends AbstractEntitySingleton implements ModelMigrateSettingsInterface
|
|
{
|
|
const INSTALLER_NAME_MODE_WITH_HASH = 'withhash';
|
|
const INSTALLER_NAME_MODE_SIMPLE = 'simple';
|
|
|
|
const CLEANUP_HOOK = 'dup_pro_cleanup_hook';
|
|
const CLEANUP_INTERVAL_NAME = 'dup_pro_custom_interval';
|
|
const CLEANUP_FILE_TIME_DELAY = 81000; // In seconds, 22.5 hours
|
|
const CLEANUP_EMAIL_NOTICE_INTERVAL = 24; // In hours
|
|
|
|
const CLEANUP_MODE_OFF = 0;
|
|
const CLEANUP_MODE_MAIL = 1;
|
|
const CLEANUP_MODE_AUTO = 2;
|
|
|
|
const UNINSTALL_PACKAGE_OPTION_KEY = 'duplicator_pro_uninstall_package';
|
|
const UNINSTALL_SETTINGS_OPTION_KEY = 'duplicator_pro_uninstall_settings';
|
|
|
|
const INPUT_MYSQLDUMP_OPTION_PREFIX = 'package_mysqldump_';
|
|
|
|
//GENERAL
|
|
/** @var bool */
|
|
public $uninstall_settings = false;
|
|
/** @var bool */
|
|
public $uninstall_packages = false;
|
|
/** @var bool */
|
|
public $crypt = true;
|
|
/** @var string email summary frequency */
|
|
private $email_summary_frequency = EmailSummary::SEND_FREQ_WEEKLY;
|
|
/** @var string[] email summary recipients */
|
|
private $email_summary_recipients = [];
|
|
/** @var bool */
|
|
private $usageTracking = true;
|
|
/** @var bool if true AM Notifications are enabled */
|
|
private $amNotices = true;
|
|
//PACKAGES::Visual
|
|
/** @var bool */
|
|
public $package_mysqldump = false;
|
|
/** @var string */
|
|
public $package_mysqldump_path = '';
|
|
/** @var int<0, 1> ENUM */
|
|
public $package_phpdump_mode = DUP_PRO_DB::PHPDUMP_MODE_MULTI;
|
|
/** @var int<0, max> */
|
|
public $package_mysqldump_qrylimit = DUP_PRO_Constants::DEFAULT_MYSQL_DUMP_CHUNK_SIZE;
|
|
/** @var GroupOptions[] */
|
|
private $packageMysqldumpOptions = [];
|
|
/** @var int<-1, 3> ENUM */
|
|
public $archive_build_mode = DUP_PRO_Archive_Build_Mode::Unconfigured;
|
|
/** @var bool */
|
|
public $archive_compression = true;
|
|
/** @var bool */
|
|
public $ziparchive_validation = false;
|
|
/** @var int<0, 1> ENUM */
|
|
public $ziparchive_mode = DUP_PRO_ZipArchive_Mode::Multithreaded;
|
|
/** @var int<0, max> */
|
|
public $ziparchive_chunk_size_in_mb = DUP_PRO_Constants::DEFAULT_ZIP_ARCHIVE_CHUNK;
|
|
/** @var bool */
|
|
public $homepath_as_abspath = false;
|
|
//PACKAGES::Basic::Processing
|
|
/** @var int<0, 3> ENUM */
|
|
public $server_load_reduction = DUP_PRO_Server_Load_Reduction::None;
|
|
/** @var int<0, max> */
|
|
public $max_package_runtime_in_min = DUP_PRO_Constants::DEFAULT_MAX_PACKAGE_RUNTIME_IN_MIN;
|
|
/** @var int<0, max> */
|
|
public $php_max_worker_time_in_sec = DUP_PRO_Constants::DEFAULT_MAX_WORKER_TIME;
|
|
//PACKAGES::Basic::Cleanup
|
|
/** @var int<0, 2> ENUM */
|
|
public $cleanup_mode = self::CLEANUP_MODE_OFF;
|
|
/** @var string */
|
|
public $cleanup_email = '';
|
|
/** @var int<0, max> */
|
|
public $auto_cleanup_hours = 24;
|
|
//PACKAGES::Adanced
|
|
/** @var int<0, 1> ENUM */
|
|
public $lock_mode = DUP_PRO_Thread_Lock_Mode::SQL_Lock;
|
|
/** @var string */
|
|
public $ajax_protocol = '';
|
|
/** @var string */
|
|
public $custom_ajax_url = '';
|
|
/** @var bool */
|
|
public $clientside_kickoff = false;
|
|
/** @var bool */
|
|
public $basic_auth_enabled = false;
|
|
/** @var string */
|
|
public $basic_auth_user = ''; // Not actively used but required for upgrade
|
|
/** @var string */
|
|
public $basic_auth_password = '';
|
|
/** @var string ENUM */
|
|
public $installer_name_mode = self::INSTALLER_NAME_MODE_SIMPLE;
|
|
/** @var string */
|
|
public $installer_base_name = DUP_PRO_Installer::DEFAULT_INSTALLER_FILE_NAME_WITHOUT_HASH;
|
|
/** @var int<0, max> */
|
|
public $chunk_size = 2048;
|
|
/** @var bool */
|
|
public $skip_archive_scan = false;
|
|
//SCHEDULES
|
|
/** @var int<0, 2> ENUM */
|
|
public $send_email_on_build_mode = DUP_PRO_Email_Build_Mode::Email_On_Failure;
|
|
/** @var string */
|
|
public $notification_email_address = '';
|
|
//STORAGE
|
|
/** @var bool */
|
|
public $storage_htaccess_off = false;
|
|
/** @var int<0, max> */
|
|
public $max_storage_retries = 10;
|
|
/**
|
|
* Used on old versions before 4.5.13, mantained for upgrade. Remove on 4.5.14 or later
|
|
*
|
|
* @deprecated since 4.5.13
|
|
*
|
|
* @var int<0, max>
|
|
**/
|
|
public $max_default_store_files = 20;
|
|
/**
|
|
* Used on old versions before 4.5.13, mantained for upgrade. Remove on 4.5.14 or later
|
|
*
|
|
* @deprecated since 4.5.13
|
|
*
|
|
* @var bool
|
|
**/
|
|
public $purge_default_package_record = false;
|
|
|
|
/**
|
|
* @deprecated 4.5.15 use {@see DynamicEntity::get()} instead
|
|
* @var null|int<0, max>
|
|
*/
|
|
public $dropbox_upload_chunksize_in_kb = 2000;
|
|
|
|
/**
|
|
* @deprecated 4.5.15 use {@see DynamicEntity::get()} instead
|
|
* @var null|int<-1, 2> ENUM
|
|
*/
|
|
public $dropbox_transfer_mode = DUP_PRO_Dropbox_Transfer_Mode::Unconfigured;
|
|
|
|
/**
|
|
* @deprecated 4.5.15 use {@see DynamicEntity::get()} instead
|
|
* @var null|int<0, max>
|
|
*/
|
|
public $gdrive_upload_chunksize_in_kb = 1024; // Not exposed through the UI (yet)
|
|
|
|
/**
|
|
* @deprecated 4.5.15 use {@see DynamicEntity::get()} instead
|
|
* @var null|int<-1, 1> ENUM
|
|
*/
|
|
public $gdrive_transfer_mode = DUP_PRO_Google_Drive_Transfer_Mode::Auto;
|
|
|
|
/**
|
|
* @deprecated 4.5.15 use {@see DynamicEntity::get()} instead
|
|
* @var null|int<0, max>
|
|
*/
|
|
public $s3_upload_part_size_in_kb = 6000;
|
|
|
|
/**
|
|
* @deprecated 4.5.15 use {@see DynamicEntity::get()} instead
|
|
* @var null|int<0, max>
|
|
*/
|
|
public $onedrive_upload_chunksize_in_kb = DUPLICATOR_PRO_ONEDRIVE_UPLOAD_CHUNK_DEFAULT_SIZE_IN_KB;
|
|
|
|
/**
|
|
* @deprecated 4.5.15 use {@see DynamicEntity::get()} instead
|
|
* @var null|int<0, max>
|
|
*/
|
|
public $local_upload_chunksize_in_MB = LocalStorage::LOCAL_STORAGE_CHUNK_SIZE_IN_MB;
|
|
|
|
/** @var int[] */
|
|
protected $manual_mode_storage_ids = [];
|
|
//LICENSING
|
|
/** @var int<0, 2> License Visibility ENUM */
|
|
public $license_key_visible = License::VISIBILITY_ALL;
|
|
/** @var string */
|
|
public $lkp = ''; // Not actively used but required for upgrade
|
|
//UPDATE CACHING
|
|
/** @var int<0, max> */
|
|
public $last_system_check_timestamp = 0;
|
|
/** @var int<0, max> */
|
|
public $initial_activation_timestamp = 0;
|
|
/** @var bool */
|
|
public $ssl_useservercerts = true;
|
|
/** @var bool */
|
|
public $ssl_disableverify = true;
|
|
/** @var int<0, max> */
|
|
public $import_chunk_size = DUPLICATOR_PRO_DEFAULT_CHUNK_UPLOAD_SIZE; // in KB, 0 no chunk
|
|
/** @var string */
|
|
public $import_custom_path = '';
|
|
/** @var bool */
|
|
public $ipv4_only = false;
|
|
/** @var bool */
|
|
public $unhook_third_party_js = false;
|
|
/** @var bool */
|
|
public $unhook_third_party_css = false;
|
|
/** @var string if empty custom path is disabled */
|
|
private $recoveryCustomPath = '';
|
|
|
|
/**
|
|
* Class constructor
|
|
*/
|
|
protected function __construct()
|
|
{
|
|
$this->packageMysqldumpOptions = $this->getDefaultMysqlDumpOptions();
|
|
}
|
|
|
|
/**
|
|
* Return entity type identifier
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function getType()
|
|
{
|
|
return 'DUP_PRO_Global_Entity';
|
|
}
|
|
|
|
/**
|
|
* Will be called, automatically, when Serialize
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function __serialize() // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__serializeFound
|
|
{
|
|
update_option(self::UNINSTALL_PACKAGE_OPTION_KEY, $this->uninstall_packages);
|
|
update_option(self::UNINSTALL_SETTINGS_OPTION_KEY, $this->uninstall_settings);
|
|
|
|
$data = JsonSerialize::serializeToData($this, JsonSerialize::JSON_SKIP_MAGIC_METHODS | JsonSerialize::JSON_SKIP_CLASS_NAME);
|
|
if ($this->crypt && strlen($this->basic_auth_password)) {
|
|
$data['basic_auth_password'] = CryptBlowfish::encrypt($this->basic_auth_password);
|
|
}
|
|
if ($this->crypt && strlen($this->lkp)) {
|
|
$data['lkp'] = CryptBlowfish::encrypt($this->lkp);
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Serialize
|
|
*
|
|
* Wakeup method.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __wakeup()
|
|
{
|
|
// fix boolean value from old version
|
|
$this->license_key_visible = (int) $this->license_key_visible;
|
|
|
|
$loadedOptionNames = [];
|
|
foreach ($this->packageMysqldumpOptions as $index => $data) {
|
|
$this->packageMysqldumpOptions[$index] = GroupOptions::getObjectFromArray($data); // @phpstan-ignore-line
|
|
$loadedOptionNames[] = $this->packageMysqldumpOptions[$index]->getOptionName();
|
|
}
|
|
foreach ($this->getDefaultMysqlDumpOptions() as $defOpt) {
|
|
if (in_array($defOpt->getOptionName(), $loadedOptionNames)) {
|
|
continue;
|
|
}
|
|
$this->packageMysqldumpOptions[] = $defOpt;
|
|
}
|
|
|
|
if ($this->crypt && strlen($this->basic_auth_password)) {
|
|
$this->basic_auth_password = CryptBlowfish::decrypt($this->basic_auth_password);
|
|
}
|
|
|
|
if ($this->crypt && strlen($this->lkp)) {
|
|
$this->lkp = CryptBlowfish::decrypt($this->lkp);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return default options
|
|
*
|
|
* @return GroupOptions[]
|
|
*/
|
|
private function getDefaultMysqlDumpOptions()
|
|
{
|
|
return [
|
|
new GroupOptions('quick', self::INPUT_MYSQLDUMP_OPTION_PREFIX, false),
|
|
new GroupOptions('extended-insert', self::INPUT_MYSQLDUMP_OPTION_PREFIX, false),
|
|
new GroupOptions('routines', self::INPUT_MYSQLDUMP_OPTION_PREFIX, true),
|
|
new GroupOptions('disable-keys', self::INPUT_MYSQLDUMP_OPTION_PREFIX, false),
|
|
new GroupOptions('compact', self::INPUT_MYSQLDUMP_OPTION_PREFIX, false),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* This function is called on first istance of singletion object
|
|
* Can be used to set dynamic properties values
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function firstIstanceInit()
|
|
{
|
|
$result = $this->reset(
|
|
[],
|
|
[
|
|
__CLASS__,
|
|
'getDefaultPropInitVal',
|
|
],
|
|
function () {
|
|
$this->set_build_mode();
|
|
}
|
|
);
|
|
if ($result === false) {
|
|
throw new Exception('Can\'t reset the user settings');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return default prop val by system config
|
|
*
|
|
* @param string $name prop nam
|
|
* @param mixed $val prop val
|
|
*
|
|
* @return mixed
|
|
*/
|
|
protected static function getDefaultPropInitVal($name, $val)
|
|
{
|
|
switch ($name) {
|
|
case 'cleanup_email':
|
|
return get_option('admin_email');
|
|
case 'lock_mode':
|
|
return self::getDefaultLockType();
|
|
case 'ajax_protocol':
|
|
return strtolower(parse_url(network_admin_url(), PHP_URL_SCHEME));
|
|
case 'php_max_worker_time_in_sec':
|
|
// Default is just a bit under the .7 max
|
|
return min(
|
|
floor(0.7 * SnapUtil::phpIniGet("max_execution_time", 30, 'int')),
|
|
DUP_PRO_Constants::DEFAULT_MAX_WORKER_TIME
|
|
);
|
|
case 'crypt':
|
|
$test_str = 'aaa';
|
|
$encrypted_str = CryptBlowfish::encrypt($test_str);
|
|
$decrypted_str = CryptBlowfish::decrypt($encrypted_str);
|
|
return ($test_str == $decrypted_str) ? true : false;
|
|
case 'custom_ajax_url':
|
|
return admin_url('admin-ajax.php');
|
|
case 'email_summary_recipients':
|
|
return EmailSummary::getDefaultRecipients();
|
|
}
|
|
return $val;
|
|
}
|
|
|
|
/**
|
|
* Reset default values
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function resetUserSettings()
|
|
{
|
|
try {
|
|
$result = $this->reset(
|
|
[
|
|
'manual_mode_storage_ids',
|
|
'license_key_visible',
|
|
'lkp',
|
|
'last_system_check_timestamp',
|
|
'initial_activation_timestamp',
|
|
],
|
|
[
|
|
__CLASS__,
|
|
'getDefaultPropInitVal',
|
|
],
|
|
function () {
|
|
$this->set_build_mode();
|
|
}
|
|
);
|
|
|
|
if ($result == false) {
|
|
throw new Exception('Can\'t reset global entity values');
|
|
}
|
|
|
|
$sglobal = DUP_PRO_Secure_Global_Entity::getInstance();
|
|
if ($sglobal->save() == false) {
|
|
throw new Exception('Can\'t save secure global');
|
|
}
|
|
} catch (Exception $e) {
|
|
DUP_PRO_Log::traceError('Reset user settings error mrg: ' . $e->getMessage());
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Get usage tracking
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function getUsageTracking()
|
|
{
|
|
return $this->usageTracking;
|
|
}
|
|
|
|
/**
|
|
* Set usage tracking
|
|
*
|
|
* @param bool $value value
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setUsageTracking($value)
|
|
{
|
|
if (DUPLICATOR_USTATS_DISALLOW) { // @phpstan-ignore-line
|
|
// If usagfe tracking is hardcoded disabled, don't change the setting value
|
|
return;
|
|
}
|
|
|
|
$value = (bool) $value;
|
|
$oldValue = $this->usageTracking;
|
|
$this->usageTracking = $value;
|
|
|
|
if ($value == false && $oldValue != $value) {
|
|
CommStats::disableUsageTracking();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return recovery custom path
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getRecoveryCustomPath()
|
|
{
|
|
return $this->recoveryCustomPath;
|
|
}
|
|
|
|
/**
|
|
* Return recovery custom URL
|
|
*
|
|
* @return string return empty URL if custom path isn't set
|
|
*/
|
|
public function getRecoveryCustomURL()
|
|
{
|
|
if (strlen($this->recoveryCustomPath) == 0) {
|
|
return '';
|
|
}
|
|
|
|
if (SnapIO::isChildPath($this->recoveryCustomPath, DUP_PRO_Archive::getArchiveListPaths('wpcontent'), false, true, true)) {
|
|
$mainPath = DUP_PRO_Archive::getArchiveListPaths('wpcontent');
|
|
$mainURL = DUP_PRO_Archive::getOriginalUrls('wpcontent');
|
|
} else {
|
|
$mainPath = DUP_PRO_Archive::getArchiveListPaths('home');
|
|
$mainURL = DUP_PRO_Archive::getOriginalUrls('home');
|
|
}
|
|
|
|
return $mainURL . '/' . SnapIo::getRelativePath($this->recoveryCustomPath, $mainPath, true);
|
|
}
|
|
|
|
/**
|
|
* Set recovery custom path
|
|
*
|
|
* @param string $path path
|
|
* @param string $failMessage return fail message
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function setRecoveryCustomPath($path, &$failMessage = '')
|
|
{
|
|
$remove = false;
|
|
|
|
try {
|
|
$this->recoveryCustomPath = '';
|
|
|
|
if (strlen($path) == 0) {
|
|
return true;
|
|
}
|
|
|
|
if (file_exists($path)) {
|
|
if (
|
|
!is_dir($path) ||
|
|
!is_writable($path)
|
|
) {
|
|
throw new Exception(__('The Recovery custom path must be a folder with write permissions.', 'duplicator-pro'));
|
|
}
|
|
} else {
|
|
if (wp_mkdir_p($path) == false) {
|
|
throw new Exception(sprintf(__('It is not possible to create the folder %s', 'duplicator-pro'), $path));
|
|
}
|
|
}
|
|
|
|
if (
|
|
!SnapIO::isChildPath($path, DUP_PRO_Archive::getArchiveListPaths('home'), false, false, true) &&
|
|
!SnapIO::isChildPath($path, DUP_PRO_Archive::getArchiveListPaths('wpcontent'), false, false, true)
|
|
) {
|
|
throw new Exception(__('The custom Recovery path must be a child folder of the home path or wp-content', 'duplicator-pro'));
|
|
}
|
|
|
|
if (PathUtil::isPathInCoreDirs($path)) {
|
|
throw new Exception(__('The Recovery custom path cannot be a wordpress core folder.', 'duplicator-pro'));
|
|
}
|
|
} catch (Exception $e) {
|
|
$remove = true;
|
|
$failMessage = $e->getMessage();
|
|
return false;
|
|
} finally {
|
|
if ($remove) {
|
|
rmdir($path);
|
|
}
|
|
}
|
|
|
|
$this->recoveryCustomPath = $path;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Update global settings after install
|
|
*
|
|
* @return bool true on success false on failure
|
|
*/
|
|
public function updateAftreInstall()
|
|
{
|
|
$this->lock_mode = DUP_PRO_Global_Entity::getDefaultLockType();
|
|
$this->ajax_protocol = DUPLICATOR_PRO_DEFAULT_AJAX_PROTOCOL;
|
|
if ($this->getBuildMode() !== DUP_PRO_Archive_Build_Mode::DupArchive) {
|
|
$this->set_build_mode();
|
|
}
|
|
return $this->save();
|
|
}
|
|
|
|
/**
|
|
* Return default lock
|
|
*
|
|
* @return int Enum lock type
|
|
*/
|
|
protected static function getDefaultLockType()
|
|
{
|
|
$lockType = DUP_PRO_Thread_Lock_Mode::Flock;
|
|
|
|
if (DUP_PRO_U::getSqlLock(DUPLICATOR_PRO_TEST_SQL_LOCK_NAME)) {
|
|
$lockType = (DUP_PRO_U::checkSqlLock(DUPLICATOR_PRO_TEST_SQL_LOCK_NAME) ? DUP_PRO_Thread_Lock_Mode::SQL_Lock : DUP_PRO_Thread_Lock_Mode::Flock);
|
|
DUP_PRO_U::releaseSqlLock(DUPLICATOR_PRO_TEST_SQL_LOCK_NAME);
|
|
}
|
|
DUP_PRO_Log::trace("Lock type auto set to {$lockType}");
|
|
return $lockType;
|
|
}
|
|
|
|
/**
|
|
* To export data
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function settingsExport()
|
|
{
|
|
$skipProps = [
|
|
'id',
|
|
'last_system_check_timestamp',
|
|
'initial_activation_timestamp',
|
|
'manual_mode_storage_ids',
|
|
'license_key_visible',
|
|
'lkp',
|
|
];
|
|
|
|
$data = JsonSerialize::serializeToData($this, JsonSerialize::JSON_SKIP_MAGIC_METHODS | JsonSerialize::JSON_SKIP_CLASS_NAME);
|
|
foreach ($skipProps as $prop) {
|
|
unset($data[$prop]);
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Update object properties from import data
|
|
*
|
|
* @param array<string, mixed> $data data to import
|
|
* @param string $dataVersion version of data
|
|
* @param array<string, mixed> $extraData extra data, useful form id mapping etc.
|
|
*
|
|
* @return bool True if success, otherwise false
|
|
*/
|
|
public function settingsImport($data, $dataVersion, array $extraData = [])
|
|
{
|
|
$skipProps = [
|
|
'id',
|
|
'last_system_check_timestamp',
|
|
'initial_activation_timestamp',
|
|
'manual_mode_storage_ids',
|
|
'license_key_visible',
|
|
'lkp',
|
|
];
|
|
|
|
$reflect = new ReflectionClass(self::class);
|
|
$props = $reflect->getProperties();
|
|
|
|
foreach ($props as $prop) {
|
|
if (in_array($prop->getName(), $skipProps)) {
|
|
continue;
|
|
}
|
|
if (!isset($data[$prop->getName()])) {
|
|
continue;
|
|
}
|
|
$prop->setAccessible(true);
|
|
$prop->setValue($this, $data[$prop->getName()]);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Set from object
|
|
*
|
|
* @param self $global_data global data
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setFromImportData(self $global_data)
|
|
{
|
|
$reflect = new ReflectionClass(self::class);
|
|
$props = $reflect->getProperties();
|
|
|
|
$skipProps = [
|
|
'id',
|
|
'last_system_check_timestamp',
|
|
'initial_activation_timestamp',
|
|
'manual_mode_storage_ids',
|
|
'license_key_visible',
|
|
'lkp',
|
|
];
|
|
|
|
foreach ($props as $prop) {
|
|
if (in_array($prop->getName(), $skipProps)) {
|
|
continue;
|
|
}
|
|
$prop->setAccessible(true);
|
|
$prop->setValue($this, $prop->getValue($global_data));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if build mode is available
|
|
*
|
|
* @param int $buildMode build mode constant
|
|
*
|
|
* @return bool
|
|
*/
|
|
public static function isBuildModeAvailable($buildMode)
|
|
{
|
|
switch ($buildMode) {
|
|
case DUP_PRO_Archive_Build_Mode::Unconfigured:
|
|
return false;
|
|
case DUP_PRO_Archive_Build_Mode::Shell_Exec:
|
|
return (DUP_PRO_Zip_U::getShellExecZipPath() != null);
|
|
case DUP_PRO_Archive_Build_Mode::ZipArchive:
|
|
return ZipArchiveExtended::isPhpZipAvailable();
|
|
case DUP_PRO_Archive_Build_Mode::DupArchive:
|
|
return true;
|
|
default:
|
|
throw new Exception('Invalid engine');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return package build mode
|
|
*
|
|
* @return int Return enum DUP_PRO_Archive_Build_Mode
|
|
*/
|
|
public function getBuildMode()
|
|
{
|
|
$archive_build_mode = $this->archive_build_mode;
|
|
|
|
switch ($archive_build_mode) {
|
|
case DUP_PRO_Archive_Build_Mode::Unconfigured:
|
|
if (self::isBuildModeAvailable(DUP_PRO_Archive_Build_Mode::Shell_Exec)) {
|
|
$archive_build_mode = DUP_PRO_Archive_Build_Mode::Shell_Exec;
|
|
} elseif (self::isBuildModeAvailable(DUP_PRO_Archive_Build_Mode::ZipArchive)) {
|
|
$archive_build_mode = DUP_PRO_Archive_Build_Mode::ZipArchive;
|
|
} else {
|
|
$archive_build_mode = DUP_PRO_Archive_Build_Mode::DupArchive;
|
|
}
|
|
break;
|
|
case DUP_PRO_Archive_Build_Mode::Shell_Exec:
|
|
if (!self::isBuildModeAvailable(DUP_PRO_Archive_Build_Mode::Shell_Exec)) {
|
|
if (self::isBuildModeAvailable(DUP_PRO_Archive_Build_Mode::ZipArchive)) {
|
|
$archive_build_mode = DUP_PRO_Archive_Build_Mode::ZipArchive;
|
|
} else {
|
|
$archive_build_mode = DUP_PRO_Archive_Build_Mode::DupArchive;
|
|
}
|
|
}
|
|
break;
|
|
case DUP_PRO_Archive_Build_Mode::ZipArchive:
|
|
if (!self::isBuildModeAvailable(DUP_PRO_Archive_Build_Mode::ZipArchive)) {
|
|
if (self::isBuildModeAvailable(DUP_PRO_Archive_Build_Mode::Shell_Exec)) {
|
|
$archive_build_mode = DUP_PRO_Archive_Build_Mode::Shell_Exec;
|
|
} else {
|
|
$archive_build_mode = DUP_PRO_Archive_Build_Mode::DupArchive;
|
|
}
|
|
}
|
|
break;
|
|
case DUP_PRO_Archive_Build_Mode::DupArchive:
|
|
break;
|
|
default:
|
|
throw new Exception('Invalid engine');
|
|
}
|
|
return $archive_build_mode;
|
|
}
|
|
|
|
/**
|
|
* Selt build mode and return it
|
|
*
|
|
* @param bool $save if true save update global entity only if build mode is changed
|
|
*
|
|
* @return int Return enum DUP_PRO_Archive_Build_Mode
|
|
*/
|
|
public function set_build_mode($save = false)
|
|
{
|
|
$newBuildMode = apply_filters('duplicator_pro_default_archive_build_mode', $this->getBuildMode());
|
|
if ($newBuildMode != $this->archive_build_mode) {
|
|
$this->archive_build_mode = $newBuildMode;
|
|
if ($save) {
|
|
$this->save();
|
|
}
|
|
}
|
|
return $this->archive_build_mode;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @return int<0,max> microsenconds
|
|
*/
|
|
public function getMicrosecLoadReduction()
|
|
{
|
|
return DUP_PRO_Server_Load_Reduction::microseconds_from_reduction($this->server_load_reduction);
|
|
}
|
|
|
|
/**
|
|
* set db mode ant all related params.
|
|
* check mysqldump
|
|
*
|
|
* @param null|string $dbMode if null get INPUT_POST
|
|
* @param null|int $phpDumpMode if null get INPUT_POST
|
|
* @param null|int $dbPhpQueryLimit if null get INPUT_POST
|
|
* @param null|string $packageMysqldumpPath if null get INPUT_POST
|
|
* @param null|int $dbMysqlDumpQueryLimit if null get INPUT_POST
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setDbMode(
|
|
$dbMode = null,
|
|
$phpDumpMode = null,
|
|
$dbPhpQueryLimit = null,
|
|
$packageMysqldumpPath = null,
|
|
$dbMysqlDumpQueryLimit = null
|
|
) {
|
|
//DATABASE
|
|
$dbMode = is_null($dbMode) ? SnapUtil::sanitizeDefaultInput(INPUT_POST, '_package_dbmode') : $dbMode;
|
|
$phpDumpMode = is_null($phpDumpMode) ? filter_input(
|
|
INPUT_POST,
|
|
'_phpdump_mode',
|
|
FILTER_VALIDATE_INT,
|
|
array(
|
|
'options' => array(
|
|
'default' => 0,
|
|
'min_range' => 0,
|
|
'max_range' => 1,
|
|
),
|
|
)
|
|
) : $phpDumpMode;
|
|
$dbMysqlDumpQueryLimit = is_null($dbMysqlDumpQueryLimit) ? filter_input(
|
|
INPUT_POST,
|
|
'_package_mysqldump_qrylimit',
|
|
FILTER_VALIDATE_INT,
|
|
array(
|
|
'options' => array(
|
|
'default' => DUP_PRO_Constants::DEFAULT_MYSQL_DUMP_CHUNK_SIZE,
|
|
'min_range' => DUP_PRO_Constants::MYSQL_DUMP_CHUNK_SIZE_MIN_LIMIT,
|
|
'max_range' => DUP_PRO_Constants::MYSQL_DUMP_CHUNK_SIZE_MAX_LIMIT,
|
|
),
|
|
)
|
|
) : $dbMysqlDumpQueryLimit;
|
|
|
|
$packageMysqldumpPath = is_null($packageMysqldumpPath) ?
|
|
SnapUtil::sanitizeDefaultInput(INPUT_POST, '_package_mysqldump_path') :
|
|
$packageMysqldumpPath;
|
|
$packageMysqldumpPath = SnapUtil::sanitizeNSCharsNewlineTabs($packageMysqldumpPath);
|
|
$packageMysqldumpPath = preg_match('/^([A-Za-z]\:)?[\/\\\\]/', $packageMysqldumpPath) ? $packageMysqldumpPath : '';
|
|
$packageMysqldumpPath = preg_replace('/[\'"]/m', '', $packageMysqldumpPath);
|
|
$packageMysqldumpPath = SnapIO::safePathUntrailingslashit($packageMysqldumpPath);
|
|
|
|
$mysqlDumpPath = empty($packageMysqldumpPath) ? DUP_PRO_DB::getMySqlDumpPath() : $packageMysqldumpPath;
|
|
if ($dbMode == 'mysql' && empty($mysqlDumpPath)) {
|
|
$dbMode = 'php';
|
|
}
|
|
|
|
$this->package_mysqldump = ($dbMode == 'mysql');
|
|
$this->package_phpdump_mode = $phpDumpMode;
|
|
$this->package_mysqldump_path = $packageMysqldumpPath;
|
|
$this->package_mysqldump_qrylimit = $dbMysqlDumpQueryLimit;
|
|
|
|
array_map(function ($option) {
|
|
$option->update();
|
|
}, $this->getMysqldumpOptions());
|
|
}
|
|
|
|
/**
|
|
* Sets cleanup fields and configures WP Cron accordingly
|
|
*
|
|
* @param int $cleanup_mode Cleanup mode to set
|
|
* @param string $cleanup_email Email address to send cleanup notification to
|
|
* @param int $auto_cleanup_hours Number of hours after which cleanup should be performed
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setCleanupFields($cleanup_mode = null, $cleanup_email = null, $auto_cleanup_hours = null)
|
|
{
|
|
$this->cleanup_mode = is_null($cleanup_mode) ? filter_input(
|
|
INPUT_POST,
|
|
'cleanup_mode',
|
|
FILTER_VALIDATE_INT,
|
|
array(
|
|
'options' => array(
|
|
'default' => self::CLEANUP_MODE_OFF,
|
|
'min_range' => 0,
|
|
'max_range' => 2,
|
|
),
|
|
)
|
|
) : $cleanup_mode;
|
|
|
|
$this->cleanup_email = is_null($cleanup_email) ? $_REQUEST['cleanup_email'] : $cleanup_email;
|
|
|
|
$this->auto_cleanup_hours = is_null($auto_cleanup_hours) ? filter_input(
|
|
INPUT_POST,
|
|
'auto_cleanup_hours',
|
|
FILTER_VALIDATE_INT,
|
|
array(
|
|
'options' => array(
|
|
'default' => 24,
|
|
'min_range' => 1,
|
|
),
|
|
)
|
|
) : $auto_cleanup_hours;
|
|
|
|
self::cleanupScheduleSetup();
|
|
}
|
|
|
|
/**
|
|
* Schedules cron event for installer files cleanup purposes,
|
|
* and unschedules it if it's not needed anymore.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function cleanupScheduleSetup()
|
|
{
|
|
$global = self::getInstance();
|
|
SnapWP::unscheduleEvent(self::CLEANUP_HOOK);
|
|
if ($global->cleanup_mode == self::CLEANUP_MODE_MAIL) {
|
|
$nextRunTime = time() + self::CLEANUP_EMAIL_NOTICE_INTERVAL * 3600;
|
|
SnapWP::scheduleEvent($nextRunTime, self::CLEANUP_INTERVAL_NAME, self::CLEANUP_HOOK);
|
|
} elseif ($global->cleanup_mode == self::CLEANUP_MODE_AUTO) {
|
|
$nextRunTime = time() + $global->auto_cleanup_hours * 3600;
|
|
SnapWP::scheduleEvent($nextRunTime, self::CLEANUP_INTERVAL_NAME, self::CLEANUP_HOOK);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Customizes schedules according to current cleanup_mode. If necessary, it
|
|
* adds a custom cron schedule that will run every N hours.
|
|
*
|
|
* @param array<string,array{interval:int,display:string}> $schedules An array of non-default cron schedules.
|
|
*
|
|
* @return array<string,array{interval:int,display:string}> Filtered array of non-default cron schedules.
|
|
*/
|
|
public static function customCleanupCronInterval($schedules)
|
|
{
|
|
$global = self::getInstance();
|
|
|
|
switch ($global->cleanup_mode) {
|
|
case self::CLEANUP_MODE_OFF:
|
|
// No need to modify anything
|
|
break;
|
|
case self::CLEANUP_MODE_MAIL:
|
|
$schedules[self::CLEANUP_INTERVAL_NAME] = array(
|
|
'interval' => self::CLEANUP_EMAIL_NOTICE_INTERVAL * 3600, // In seconds, every N hours
|
|
'display' => sprintf(esc_html__('Every %1$d hours', 'duplicator-pro'), self::CLEANUP_EMAIL_NOTICE_INTERVAL),
|
|
);
|
|
break;
|
|
case self::CLEANUP_MODE_AUTO:
|
|
$schedules[self::CLEANUP_INTERVAL_NAME] = array(
|
|
'interval' => $global->auto_cleanup_hours * 3600, // In seconds, every N hours
|
|
'display' => sprintf(esc_html__('Every %1$d hours', 'duplicator-pro'), $global->auto_cleanup_hours),
|
|
);
|
|
break;
|
|
default:
|
|
throw new Exception('Invalid cleanup mode:' . SnapLog::v2str($global->cleanup_mode));
|
|
}
|
|
return $schedules;
|
|
}
|
|
|
|
/**
|
|
* The function that gets executed by WP Cron for cleanup of installer files.
|
|
* It does different tasks based on current cleanup_mode setting.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function cleanupCronJob()
|
|
{
|
|
$global = self::getInstance();
|
|
|
|
$websiteUrl = SnapURL::getCurrentUrl(false, false, 1);
|
|
$to = $global->cleanup_email;
|
|
if (empty($to)) {
|
|
$to = get_option('admin_email');
|
|
}
|
|
|
|
switch ($global->cleanup_mode) {
|
|
case self::CLEANUP_MODE_MAIL:
|
|
// Email Notice cron job routine for cleanup of installer files
|
|
$listOfInstallerFiles = MigrationMng::checkInstallerFilesList();
|
|
$filesToRemove = array();
|
|
|
|
foreach ($listOfInstallerFiles as $path) {
|
|
if (time() - filectime($path) > self::CLEANUP_FILE_TIME_DELAY) {
|
|
$filesToRemove[] = $path;
|
|
}
|
|
}
|
|
|
|
if (count($filesToRemove) > 0 && !empty($to)) {
|
|
// Send an Email Notice
|
|
$subject = __("Action required", 'duplicator-pro');
|
|
$message = sprintf(__('This email is sent by your Wordpress plugin "Duplicator Pro" from website: %1$s. ', 'duplicator-pro'), $websiteUrl);
|
|
$message .= __('You received this email because Cleanup mode is set to "Email Notice". ', 'duplicator-pro');
|
|
$message .= __('Cleanup routine discovered that some installer files (leftovers from migration) were not removed. ', 'duplicator-pro');
|
|
$message .= __('We strongly advise you to remove these files. ', 'duplicator-pro');
|
|
$message .= __('Here is the list of files found on your website that you should remove:', 'duplicator-pro') . "<br/>";
|
|
foreach ($filesToRemove as $path) {
|
|
$message .= "-> $path<br/>";
|
|
}
|
|
$message .= "<br/>";
|
|
$message .= __('Note: You could enable "Auto Cleanup" mode if you go to:', 'duplicator-pro') . "<br/>";
|
|
$message .= __('WordPress Admin > Duplicator Pro > Settings > Packages Tab > Cleanup.', 'duplicator-pro') . "<br/>";
|
|
$message .= __('That mode will do cleanup of those files automatically for you.', 'duplicator-pro') . "<br/>";
|
|
$message .= "<br/>";
|
|
$message .= __('Best regards,', 'duplicator-pro') . "<br/>";
|
|
$message .= __('Duplicator Pro', 'duplicator-pro');
|
|
|
|
if (wp_mail($to, $subject, $message, array('Content-Type: text/html; charset=UTF-8'))) {
|
|
// OK
|
|
\DUP_PRO_Log::trace('wp_mail sent email notice regarding cleanup of installer files');
|
|
} else {
|
|
\DUP_PRO_Log::trace("Problem sending email notice regarding cleanup of installer files to {$to}");
|
|
}
|
|
}
|
|
break;
|
|
case self::CLEANUP_MODE_AUTO:
|
|
// Auto Cleanup cron job routine for cleanup of installer files
|
|
$installerFiles = MigrationMng::cleanMigrationFiles(false, self::CLEANUP_FILE_TIME_DELAY);
|
|
if (count($installerFiles) == 0) {
|
|
// No installer files were found, so we do nothing else
|
|
return;
|
|
}
|
|
|
|
$filesFailedRemoval = array();
|
|
foreach ($installerFiles as $path => $success) {
|
|
if (!$success) {
|
|
$filesFailedRemoval[] = $path;
|
|
}
|
|
}
|
|
if (count($filesFailedRemoval) == 0) {
|
|
// All found installer files were removed successfully,
|
|
// or they did not even need to be removed yet because of CLEANUP_FILE_TIME_DELAY
|
|
return;
|
|
}
|
|
|
|
// If this is executed that means that some of installer files
|
|
// could not be removed for some reason (permission issues?)
|
|
if (!empty($to)) {
|
|
// Send an Email Notice about files that could not be removed during auto cleanup
|
|
$subject = __("Action required", 'duplicator-pro');
|
|
$message = sprintf(__('This email is sent by your Wordpress plugin "Duplicator Pro" from website: %1$s. ', 'duplicator-pro'), $websiteUrl);
|
|
$message .= __('"Auto Cleanup" mode is ON, ', 'duplicator-pro');
|
|
$message .= __('however cleanup routine discovered that some installer files (leftovers from migration) could not be removed. ', 'duplicator-pro');
|
|
$message .= __('We strongly advise you to remove those files manually. ', 'duplicator-pro');
|
|
$message .= __('Here is the list of files found on your website that you should remove:', 'duplicator-pro') . "<br/>";
|
|
foreach ($filesFailedRemoval as $path) {
|
|
$message .= "-> $path<br/>";
|
|
}
|
|
$message .= "<br/>";
|
|
$message .= __('Those files probably could not be removed due to permission issues. ', 'duplicator-pro');
|
|
$message .= sprintf(
|
|
__('You can find more info in FAQ %1$son this link%2$s.', 'duplicator-pro'),
|
|
"<a href='" . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . "how-to-fix-file-permissions-issues' target='_blank'>",
|
|
"</a>"
|
|
) . "<br/>";
|
|
$message .= "<br/>";
|
|
$message .= __('Note: To edit "Cleanup" settings go to:', 'duplicator-pro') . "<br/>";
|
|
$message .= __('WordPress Admin > Duplicator Pro > Settings > Packages Tab > Cleanup.', 'duplicator-pro') . "<br/>";
|
|
$message .= "<br/>";
|
|
$message .= __('Best regards,', 'duplicator-pro') . "<br/>";
|
|
$message .= __('Duplicator Pro', 'duplicator-pro');
|
|
|
|
if (wp_mail($to, $subject, $message, array('Content-Type: text/html; charset=UTF-8'))) {
|
|
// OK
|
|
\DUP_PRO_Log::trace('wp_mail sent email notice regarding failed auto cleanup of installer files');
|
|
} else {
|
|
\DUP_PRO_Log::trace("Problem sending email notice regarding failed auto cleanup of installer files to {$to}");
|
|
}
|
|
}
|
|
break;
|
|
case self::CLEANUP_MODE_OFF:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set archive mode
|
|
*
|
|
* @param ?int $archiveBuildMode Archive build mode, if null get INPUT_POST
|
|
* @param ?int $zipArchiveMode Zip archive mode, if null get INPUT_POST
|
|
* @param ?bool $archiveCompression Archive compression, if null get INPUT_POST
|
|
* @param ?bool $ziparchiveValidation Zip archive validation, if null get INPUT_POST
|
|
* @param ?int $ziparchiveChunkSizeInMb Zip archive chunk size in MB, if null get INPUT_POST
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setArchiveMode(
|
|
$archiveBuildMode = null,
|
|
$zipArchiveMode = null,
|
|
$archiveCompression = null,
|
|
$ziparchiveValidation = null,
|
|
$ziparchiveChunkSizeInMb = null
|
|
) {
|
|
$isZipAvailable = (DUP_PRO_Zip_U::getShellExecZipPath() != null);
|
|
|
|
$prelimBuildMode = is_null($archiveBuildMode) ? filter_input(
|
|
INPUT_POST,
|
|
'archive_build_mode',
|
|
FILTER_VALIDATE_INT,
|
|
array(
|
|
'options' => array(
|
|
'min_range' => 1,
|
|
'max_range' => 3,
|
|
),
|
|
)
|
|
) : $archiveBuildMode;
|
|
|
|
// Something has changed which invalidates Shell exec so move it to ZA
|
|
$this->archive_build_mode = (!$isZipAvailable && ($prelimBuildMode == DUP_PRO_Archive_Build_Mode::Shell_Exec)) ? DUP_PRO_Archive_Build_Mode::ZipArchive : $prelimBuildMode;
|
|
$this->ziparchive_mode = is_null($zipArchiveMode) ? filter_input(
|
|
INPUT_POST,
|
|
'ziparchive_mode',
|
|
FILTER_VALIDATE_INT,
|
|
array(
|
|
'options' => array(
|
|
'default' => 0,
|
|
'min_range' => 0,
|
|
'max_range' => 1,
|
|
),
|
|
)
|
|
) : $zipArchiveMode;
|
|
|
|
$this->archive_compression = is_null($archiveCompression) ? filter_input(INPUT_POST, 'archive_compression', FILTER_VALIDATE_BOOLEAN) : $archiveCompression;
|
|
$this->ziparchive_validation = is_null($ziparchiveValidation) ? filter_input(INPUT_POST, 'ziparchive_validation', FILTER_VALIDATE_BOOLEAN) : $ziparchiveValidation;
|
|
$this->ziparchive_chunk_size_in_mb = is_null($ziparchiveChunkSizeInMb) ? filter_input(
|
|
INPUT_POST,
|
|
'ziparchive_chunk_size_in_mb',
|
|
FILTER_VALIDATE_INT,
|
|
array(
|
|
'options' => array(
|
|
'default' => DUP_PRO_Constants::DEFAULT_ZIP_ARCHIVE_CHUNK,
|
|
'min_range' => 1,
|
|
),
|
|
)
|
|
) : $ziparchiveChunkSizeInMb;
|
|
}
|
|
|
|
/**
|
|
* Set clientside kickoff
|
|
*
|
|
* @param bool $enable enable or disable
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setClientsideKickoff($enable)
|
|
{
|
|
if ($this->clientside_kickoff != $enable) {
|
|
$this->clientside_kickoff = $enable;
|
|
|
|
if ($this->clientside_kickoff) {
|
|
// Auto setting the max package runtime in case of client kickoff is turned on and
|
|
// the max package runtime is less than 480 minutes - 8 hours
|
|
$this->max_package_runtime_in_min = max(480, $this->max_package_runtime_in_min);
|
|
$this->setDbMode('mysql');
|
|
|
|
// RSR 4/29/19 not setting archive mode for now - too risky
|
|
// $mode = (DUP_PRO_Zip_U::getShellExecZipPath() != null) ? DUP_PRO_Archive_Build_Mode::Shell_Exec : DUP_PRO_Archive_Build_Mode::DupArchive;
|
|
// $this->setArchiveMode($mode);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Configure dropbox transfer mode
|
|
*
|
|
* @return void
|
|
*/
|
|
public function configure_dropbox_transfer_mode()
|
|
{
|
|
$dGlobal = DynamicGlobalEntity::getInstance();
|
|
if ($dGlobal->getVal('dropbox_transfer_mode') == DUP_PRO_Dropbox_Transfer_Mode::Unconfigured) {
|
|
$mode = DUP_PRO_Dropbox_Transfer_Mode::Disabled;
|
|
if (SnapUtil::isCurlEnabled()) {
|
|
$mode = DUP_PRO_Dropbox_Transfer_Mode::cURL;
|
|
} elseif (DUP_PRO_Server::isURLFopenEnabled()) {
|
|
$mode = DUP_PRO_Dropbox_Transfer_Mode::FOpen_URL;
|
|
}
|
|
$dGlobal->setVal('dropbox_transfer_mode', $mode, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get installer backup filename
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_installer_backup_filename()
|
|
{
|
|
$installer_extension = $this->get_installer_extension();
|
|
|
|
if (trim($installer_extension) == '') {
|
|
return 'installer-backup';
|
|
} else {
|
|
return "installer-backup.$installer_extension";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get installer extension
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_installer_extension()
|
|
{
|
|
return pathinfo($this->installer_base_name, PATHINFO_EXTENSION);
|
|
}
|
|
|
|
/**
|
|
* Get archive engine label
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_archive_engine()
|
|
{
|
|
$mode = '';
|
|
switch ($this->archive_build_mode) {
|
|
case DUP_PRO_Archive_Build_Mode::ZipArchive:
|
|
$mode = ($this->ziparchive_mode == DUP_PRO_ZipArchive_Mode::Multithreaded) ?
|
|
__("ZipArchive: multi-thread", 'duplicator-pro') :
|
|
__("ZipArchive: single-thread", 'duplicator-pro');
|
|
break;
|
|
|
|
case DUP_PRO_Archive_Build_Mode::DupArchive:
|
|
$mode = __('DupArchive', 'duplicator-pro');
|
|
break;
|
|
|
|
default:
|
|
$mode = __("Shell Zip", 'duplicator-pro');
|
|
break;
|
|
}
|
|
|
|
return $mode;
|
|
}
|
|
|
|
/**
|
|
* Return archive extension type
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_archive_extension_type()
|
|
{
|
|
$mode = 'zip';
|
|
if ($this->archive_build_mode == DUP_PRO_Archive_Build_Mode::DupArchive) {
|
|
$mode = 'daf';
|
|
}
|
|
return $mode;
|
|
}
|
|
|
|
/**
|
|
* Return Mysqldump options
|
|
*
|
|
* @return GroupOptions[]
|
|
*/
|
|
public function getMysqldumpOptions()
|
|
{
|
|
return $this->packageMysqldumpOptions;
|
|
}
|
|
|
|
/**
|
|
* Get manual mode storage ids
|
|
*
|
|
* @return int[]
|
|
*/
|
|
public function getManualModeStorageIds()
|
|
{
|
|
if (count($this->manual_mode_storage_ids) == 0) {
|
|
$this->manual_mode_storage_ids = [StoragesUtil::getDefaultStorageId()];
|
|
}
|
|
return $this->manual_mode_storage_ids;
|
|
}
|
|
|
|
/**
|
|
* Set manual mode storage ids
|
|
*
|
|
* @param int[] $storageIds Storage ids
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setManualModeStorageIds(array $storageIds)
|
|
{
|
|
$this->manual_mode_storage_ids = [];
|
|
foreach ($storageIds as $id) {
|
|
$id = (int) $id;
|
|
if ($id <= 0) {
|
|
continue;
|
|
}
|
|
$this->manual_mode_storage_ids[] = $id;
|
|
}
|
|
if (count($this->manual_mode_storage_ids) == 0) {
|
|
$this->manual_mode_storage_ids = [StoragesUtil::getDefaultStorageId()];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get Email Summary Recipients
|
|
*
|
|
* @return string[]
|
|
*/
|
|
public function getEmailSummaryRecipients()
|
|
{
|
|
return $this->email_summary_recipients;
|
|
}
|
|
|
|
/**
|
|
* Set Email Summary Recipients
|
|
*
|
|
* @param string[] $recipients List of recipient email addreses
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setEmailSummaryRecipients($recipients)
|
|
{
|
|
$recipients = filter_var($recipients, FILTER_VALIDATE_EMAIL, FILTER_REQUIRE_ARRAY);
|
|
if ($recipients === false) {
|
|
$recipients = array();
|
|
}
|
|
|
|
foreach ($recipients as $key => $recipient) {
|
|
if ($recipient === false) {
|
|
continue;
|
|
}
|
|
|
|
$recipients[$key] = sanitize_email($recipient);
|
|
}
|
|
|
|
$this->email_summary_recipients = array_values(array_unique($recipients));
|
|
}
|
|
|
|
/**
|
|
* Get email summary frequency
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getEmailSummaryFrequency()
|
|
{
|
|
return $this->email_summary_frequency;
|
|
}
|
|
|
|
/**
|
|
* Set email summary frequency
|
|
*
|
|
* @param string $frequency The frequency
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setEmailSummaryFrequency($frequency)
|
|
{
|
|
if (EmailSummaryBootstrap::updateFrequency($this->email_summary_frequency, $frequency) === false) {
|
|
DUP_PRO_Log::trace("Invalid email summary frequency: {$frequency}");
|
|
return;
|
|
}
|
|
$this->email_summary_frequency = $frequency;
|
|
}
|
|
|
|
/**
|
|
* True if AM notifications are enabled
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isAmNoticesEnabled()
|
|
{
|
|
return $this->amNotices;
|
|
}
|
|
|
|
/**
|
|
* Set notifications enabled
|
|
*
|
|
* @param bool $enable true if enabled
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setAmNotices($enable)
|
|
{
|
|
$this->amNotices = $enable;
|
|
}
|
|
}
|