first commit
This commit is contained in:
@@ -0,0 +1,536 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use VendorDuplicator\Amk\JsonSerialize\JsonSerialize;
|
||||
use Duplicator\Core\Models\AbstractEntityList;
|
||||
use Duplicator\Core\Models\UpdateFromInputInterface;
|
||||
use Duplicator\Installer\Package\ArchiveDescriptor;
|
||||
use Duplicator\Libs\Snap\SnapUtil;
|
||||
use Duplicator\Package\Create\BuildComponents;
|
||||
use Duplicator\Package\Recovery\RecoveryStatus;
|
||||
use Duplicator\Utils\Crypt\CryptBlowfish;
|
||||
use Duplicator\Utils\Settings\ModelMigrateSettingsInterface;
|
||||
|
||||
class DUP_PRO_Package_Template_Entity extends AbstractEntityList implements UpdateFromInputInterface, ModelMigrateSettingsInterface
|
||||
{
|
||||
/** @var string */
|
||||
public $name = '';
|
||||
/** @var string */
|
||||
public $notes = '';
|
||||
//MULTISITE:Filter
|
||||
/** @var int[] */
|
||||
public $filter_sites = array();
|
||||
//ARCHIVE:Files
|
||||
/** @var bool */
|
||||
public $archive_export_onlydb = false;
|
||||
/** @var bool */
|
||||
public $archive_filter_on = false;
|
||||
/** @var string */
|
||||
public $archive_filter_dirs = '';
|
||||
/** @var string */
|
||||
public $archive_filter_exts = '';
|
||||
/** @var string */
|
||||
public $archive_filter_files = '';
|
||||
/** @var bool */
|
||||
public $archive_filter_names = false;
|
||||
/** @var string[] */
|
||||
public $components = array();
|
||||
//ARCHIVE:Database
|
||||
/** @var bool */
|
||||
public $database_filter_on = false; // Enable Table Filters
|
||||
/** @var bool */
|
||||
public $databasePrefixFilter = false; // If true exclude tables without prefix
|
||||
/** @var bool */
|
||||
public $databasePrefixSubFilter = false; // If true exclude unexisting subsite id tables
|
||||
/** @var string */
|
||||
public $database_filter_tables = ''; // List of filtered tables
|
||||
/** @var string */
|
||||
public $database_compatibility_modes = ''; // Older style sql compatibility
|
||||
//INSTALLER
|
||||
//Setup
|
||||
/** @var int */
|
||||
public $installer_opts_secure_on = 0; // Enable Password Protection
|
||||
/** @var string */
|
||||
public $installer_opts_secure_pass = ''; // Old password Protection password, deprecated
|
||||
/** @var string */
|
||||
public $installerPassowrd = ''; // Password Protection password
|
||||
/** @var bool */
|
||||
public $installer_opts_skip_scan = false; // Skip Scanner
|
||||
//Basic DB
|
||||
/** @var string */
|
||||
public $installer_opts_db_host = ''; // MySQL Server Host
|
||||
/** @var string */
|
||||
public $installer_opts_db_name = ''; // Database
|
||||
/** @var string */
|
||||
public $installer_opts_db_user = ''; // User
|
||||
//cPanel Login
|
||||
/** @var bool */
|
||||
public $installer_opts_cpnl_enable = false;
|
||||
/** @var string */
|
||||
public $installer_opts_cpnl_host = '';
|
||||
/** @var string */
|
||||
public $installer_opts_cpnl_user = '';
|
||||
/** @var string */
|
||||
public $installer_opts_cpnl_pass = '';
|
||||
//cPanel DB
|
||||
/** @var string */
|
||||
public $installer_opts_cpnl_db_action = 'create';
|
||||
/** @var string */
|
||||
public $installer_opts_cpnl_db_host = '';
|
||||
/** @var string */
|
||||
public $installer_opts_cpnl_db_name = '';
|
||||
/** @var string */
|
||||
public $installer_opts_cpnl_db_user = '';
|
||||
//Brand
|
||||
/** @var int */
|
||||
public $installer_opts_brand = -2;
|
||||
/** @var bool */
|
||||
public $is_default = false;
|
||||
/** @var bool */
|
||||
public $is_manual = false;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->name = __('New Template', 'duplicator-pro');
|
||||
$this->components = BuildComponents::COMPONENTS_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entity type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getType()
|
||||
{
|
||||
return 'DUP_PRO_Package_Template_Entity';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
$data['installer_opts_secure_pass'] = '';
|
||||
$data['installerPassowrd'] = CryptBlowfish::encrypt($this->installerPassowrd, null, true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize
|
||||
*
|
||||
* Wakeup method.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
/*if ($obj->installer_opts_secure_on == ArchiveDescriptor::SECURE_MODE_ARC_ENCRYPT && !SettingsUtils::isArchiveEncryptionAvailable()) {
|
||||
$obj->installer_opts_secure_on = ArchiveDescriptor::SECURE_MODE_INST_PWD;
|
||||
}*/
|
||||
|
||||
if (strlen($this->installer_opts_secure_pass) > 0) {
|
||||
$this->installerPassowrd = base64_decode($this->installer_opts_secure_pass);
|
||||
} elseif (strlen($this->installerPassowrd) > 0) {
|
||||
$this->installerPassowrd = CryptBlowfish::decrypt($this->installerPassowrd, null, true);
|
||||
}
|
||||
|
||||
if (is_array($this->database_compatibility_modes)) {
|
||||
// for old version compatibility
|
||||
$this->database_compatibility_modes = implode(',', $this->database_compatibility_modes);
|
||||
}
|
||||
$this->installer_opts_secure_pass = '';
|
||||
$this->archive_filter_dirs = (string) $this->archive_filter_dirs;
|
||||
$this->archive_filter_files = (string) $this->archive_filter_files;
|
||||
$this->archive_filter_exts = (string) $this->archive_filter_exts;
|
||||
$this->archive_filter_on = filter_var($this->archive_filter_on, FILTER_VALIDATE_BOOLEAN);
|
||||
$this->database_filter_on = filter_var($this->database_filter_on, FILTER_VALIDATE_BOOLEAN);
|
||||
if (is_string($this->filter_sites)) {
|
||||
$this->filter_sites = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To export data
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function settingsExport()
|
||||
{
|
||||
return JsonSerialize::serializeToData($this, JsonSerialize::JSON_SKIP_MAGIC_METHODS | JsonSerialize::JSON_SKIP_CLASS_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'];
|
||||
|
||||
$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()]);
|
||||
}
|
||||
|
||||
if (!isset($data['components'])) {
|
||||
// Allow import of older templsates that did not have package components
|
||||
if ($this->archive_export_onlydb) {
|
||||
$this->components = [BuildComponents::COMP_DB];
|
||||
} else {
|
||||
$this->components = BuildComponents::COMPONENTS_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create default template
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function create_default()
|
||||
{
|
||||
if (self::get_default_template() == null) {
|
||||
$template = new self();
|
||||
|
||||
$template->name = __('Default', 'duplicator-pro');
|
||||
$template->notes = __('The default template.', 'duplicator-pro');
|
||||
$template->is_default = true;
|
||||
|
||||
$template->save();
|
||||
DUP_PRO_Log::trace('Created default template');
|
||||
} else {
|
||||
// Update it
|
||||
DUP_PRO_Log::trace('Default template already exists so not creating');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create manual mode template
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function create_manual()
|
||||
{
|
||||
if (self::get_manual_template() == null) {
|
||||
$template = new self();
|
||||
|
||||
$template->name = __('[Manual Mode]', 'duplicator-pro');
|
||||
$template->notes = '';
|
||||
$template->is_manual = true;
|
||||
|
||||
// Copy over the old temporary template settings into this - required for legacy manual
|
||||
$temp_package = DUP_PRO_Package::get_temporary_package(false);
|
||||
|
||||
if ($temp_package != null) {
|
||||
DUP_PRO_Log::trace('SET TEMPLATE FROM TEMP PACKAGE pwd ' . $temp_package->Installer->passowrd);
|
||||
$template->components = $temp_package->components;
|
||||
$template->filter_sites = $temp_package->Multisite->FilterSites;
|
||||
$template->archive_filter_on = $temp_package->Archive->FilterOn;
|
||||
$template->archive_filter_dirs = $temp_package->Archive->FilterDirs;
|
||||
$template->archive_filter_exts = $temp_package->Archive->FilterExts;
|
||||
$template->archive_filter_files = $temp_package->Archive->FilterFiles;
|
||||
$template->archive_filter_names = $temp_package->Archive->FilterNames;
|
||||
|
||||
$template->installer_opts_brand = $temp_package->Brand_ID;
|
||||
|
||||
$template->database_filter_on = $temp_package->Database->FilterOn;
|
||||
$template->databasePrefixFilter = $temp_package->Database->prefixFilter;
|
||||
$template->databasePrefixSubFilter = $temp_package->Database->prefixSubFilter;
|
||||
$template->database_filter_tables = $temp_package->Database->FilterTables;
|
||||
$template->database_compatibility_modes = $temp_package->Database->Compatible;
|
||||
|
||||
$template->installer_opts_db_host = $temp_package->Installer->OptsDBHost;
|
||||
$template->installer_opts_db_name = $temp_package->Installer->OptsDBName;
|
||||
$template->installer_opts_db_user = $temp_package->Installer->OptsDBUser;
|
||||
$template->installer_opts_secure_on = $temp_package->Installer->OptsSecureOn;
|
||||
$template->installerPassowrd = $temp_package->Installer->passowrd;
|
||||
$template->installer_opts_skip_scan = $temp_package->Installer->OptsSkipScan;
|
||||
|
||||
$global = DUP_PRO_Global_Entity::getInstance();
|
||||
|
||||
$storageIds = [];
|
||||
foreach ($temp_package->get_storages() as $storage) {
|
||||
$storageIds[] = $storage->getId();
|
||||
}
|
||||
$global->setManualModeStorageIds($storageIds);
|
||||
$global->save();
|
||||
}
|
||||
|
||||
$template->save();
|
||||
DUP_PRO_Log::trace('Created manual mode template');
|
||||
} else {
|
||||
// Update it
|
||||
DUP_PRO_Log::trace('Manual mode template already exists so not creating');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRecoveable()
|
||||
{
|
||||
$status = new RecoveryStatus($this);
|
||||
return $status->isRecoveable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display HTML info
|
||||
*
|
||||
* @param bool $isList is list
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function recoveableHtmlInfo($isList = false)
|
||||
{
|
||||
$template = $this;
|
||||
require DUPLICATOR____PATH . '/views/tools/templates/widget/recoveable-template-info.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data from query input
|
||||
*
|
||||
* @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, or INPUT_ENV, SnapUtil::INPUT_REQUEST
|
||||
*
|
||||
* @return bool true on success or false on failure
|
||||
*/
|
||||
public function setFromInput($type)
|
||||
{
|
||||
$input = SnapUtil::getInputFromType($type);
|
||||
$this->setFromArrayKey(
|
||||
$input,
|
||||
function ($key, $val) {
|
||||
if (is_string($val)) {
|
||||
$val = stripslashes($val);
|
||||
}
|
||||
return (is_scalar($val) ? SnapUtil::sanitizeNSChars($val) : $val);
|
||||
}
|
||||
);
|
||||
$this->components = BuildComponents::getFromInput($input);
|
||||
|
||||
$this->database_filter_tables = isset($input['dbtables-list']) ? SnapUtil::sanitizeNSCharsNewlineTrim($input['dbtables-list']) : '';
|
||||
|
||||
if (isset($input['filter-paths'])) {
|
||||
$filterPaths = SnapUtil::sanitizeNSChars($input['filter-paths']);
|
||||
$this->archive_filter_dirs = DUP_PRO_Archive::parseDirectoryFilter($filterPaths);
|
||||
$this->archive_filter_files = DUP_PRO_Archive::parseFileFilter($filterPaths);
|
||||
} else {
|
||||
$this->archive_filter_dirs = '';
|
||||
$this->archive_filter_files = '';
|
||||
}
|
||||
|
||||
if (isset($input['filter-exts'])) {
|
||||
$post_filter_exts = SnapUtil::sanitizeNSCharsNewlineTrim($input['filter-exts']);
|
||||
$this->archive_filter_exts = DUP_PRO_Archive::parseExtensionFilter($post_filter_exts);
|
||||
} else {
|
||||
$this->archive_filter_exts = '';
|
||||
}
|
||||
|
||||
|
||||
$this->filter_sites = !empty($input['_mu_exclude']) ? $input['_mu_exclude'] : [];
|
||||
|
||||
//Archive
|
||||
$this->archive_filter_on = isset($input['filter-on']);
|
||||
$this->database_filter_on = isset($input['dbfilter-on']);
|
||||
$this->databasePrefixFilter = isset($input['db-prefix-filter']);
|
||||
$this->databasePrefixSubFilter = isset($input['db-prefix-sub-filter']);
|
||||
$this->archive_filter_names = isset($input['archive_filter_names']);
|
||||
|
||||
//Installer
|
||||
$this->installer_opts_secure_on = filter_input(INPUT_POST, 'secure-on', FILTER_VALIDATE_INT);
|
||||
switch ($this->installer_opts_secure_on) {
|
||||
case ArchiveDescriptor::SECURE_MODE_NONE:
|
||||
case ArchiveDescriptor::SECURE_MODE_INST_PWD:
|
||||
case ArchiveDescriptor::SECURE_MODE_ARC_ENCRYPT:
|
||||
break;
|
||||
default:
|
||||
throw new Exception(__('Select valid secure mode', 'duplicator-pro'));
|
||||
}
|
||||
$this->installer_opts_skip_scan = isset($input['_installer_opts_skip_scan']);
|
||||
$this->installer_opts_cpnl_enable = isset($input['installer_opts_cpnl_enable']);
|
||||
|
||||
$this->installerPassowrd = SnapUtil::sanitizeNSCharsNewline(stripslashes($input['secure-pass']));
|
||||
$this->notes = SnapUtil::sanitizeNSCharsNewlineTrim(stripslashes($input['notes']));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy template from id
|
||||
*
|
||||
* @param int<0, max> $templateId template id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function copy_from_source_id($templateId)
|
||||
{
|
||||
if (($source = self::getById($templateId)) === false) {
|
||||
throw new Exception('Can\'t get tempalte id' . $templateId);
|
||||
}
|
||||
|
||||
$skipProps = [
|
||||
'id',
|
||||
'is_manual',
|
||||
'is_default',
|
||||
];
|
||||
|
||||
$reflect = new ReflectionClass($this);
|
||||
$props = $reflect->getProperties();
|
||||
|
||||
foreach ($props as $prop) {
|
||||
if (in_array($prop->getName(), $skipProps)) {
|
||||
continue;
|
||||
}
|
||||
$prop->setAccessible(true);
|
||||
$prop->setValue($this, $prop->getValue($source));
|
||||
}
|
||||
|
||||
$source_template_name = $source->is_manual ? __("Active Build Settings", 'duplicator-pro') : $source->name;
|
||||
$this->name = sprintf(__('%1$s - Copy', 'duplicator-pro'), $source_template_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of core WordPress folders that have been filtered
|
||||
*
|
||||
* @return string[] Returns and array of folders paths
|
||||
*/
|
||||
public function getWordPressCoreFilteredFoldersList()
|
||||
{
|
||||
return array_intersect(explode(';', $this->archive_filter_dirs), DUP_PRO_U::getWPCoreDirs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Is any of the WordPress core folders in the folder filter list
|
||||
*
|
||||
* @return bool Returns true if a WordPress core path is being filtered
|
||||
*/
|
||||
public function isWordPressCoreFolderFiltered()
|
||||
{
|
||||
return count($this->getWordPressCoreFilteredFoldersList()) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all entities of current type
|
||||
*
|
||||
* @param int<0, max> $page current page, if $pageSize is 0 o 1 $pase is the offset
|
||||
* @param int<0, max> $pageSize page size, 0 return all entities
|
||||
* @param callable $sortCallback sort function on items result
|
||||
* @param callable $filterCallback filter on items result
|
||||
* @param array{'col': string, 'mode': string} $orderby query ordder by
|
||||
*
|
||||
* @return static[]|false return entities list of false on failure
|
||||
*/
|
||||
public static function getAll(
|
||||
$page = 0,
|
||||
$pageSize = 0,
|
||||
$sortCallback = null,
|
||||
$filterCallback = null,
|
||||
$orderby = [
|
||||
'col' => 'id',
|
||||
'mode' => 'ASC',
|
||||
]
|
||||
) {
|
||||
if (is_null($sortCallback)) {
|
||||
$sortCallback = function (self $a, self $b) {
|
||||
if ($a->is_default) {
|
||||
return -1;
|
||||
} elseif ($b->is_default) {
|
||||
return 1;
|
||||
} else {
|
||||
return strcasecmp($a->name, $b->name);
|
||||
}
|
||||
};
|
||||
}
|
||||
return parent::getAll($page, $pageSize, $sortCallback, $filterCallback, $orderby);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list template json encoded data for javascript
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getTemplatesFrontendListData()
|
||||
{
|
||||
$templates = self::getAll();
|
||||
return JsonSerialize::serialize($templates, JsonSerialize::JSON_SKIP_MAGIC_METHODS | JsonSerialize::JSON_SKIP_CLASS_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all entities of current type
|
||||
*
|
||||
* @param int<0, max> $page current page, if $pageSize is 0 o 1 $pase is the offset
|
||||
* @param int<0, max> $pageSize page size, 0 return all entities
|
||||
*
|
||||
* @return static[]|false return entities list of false on failure
|
||||
*/
|
||||
public static function getAllWithoutManualMode(
|
||||
$page = 0,
|
||||
$pageSize = 0
|
||||
) {
|
||||
$filterManualCallback = function (self $obj) {
|
||||
return ($obj->is_manual === false);
|
||||
};
|
||||
return self::getAll($page, $pageSize, null, $filterManualCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default template if exists
|
||||
*
|
||||
* @return null|self
|
||||
*/
|
||||
public static function get_default_template()
|
||||
{
|
||||
$templates = self::getAll();
|
||||
|
||||
foreach ($templates as $template) {
|
||||
if ($template->is_default) {
|
||||
return $template;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return manual template entity if exists
|
||||
*
|
||||
* @return null|self
|
||||
*/
|
||||
public static function get_manual_template()
|
||||
{
|
||||
$templates = self::getAll();
|
||||
|
||||
foreach ($templates as $template) {
|
||||
if ($template->is_manual) {
|
||||
return $template;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user