first commit

This commit is contained in:
Roman Pyrih
2026-04-21 15:48:41 +02:00
commit 7483681901
10216 changed files with 3236626 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\Params\PrmMng;
class DUPX_Validation_test_addon_sites extends DUPX_Validation_abstract_item
{
/**
*
* @return int
*/
protected function runTest(): int
{
$list = self::getAddonsListsFolders();
if (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ACTION) === DUPX_Extraction::ACTION_DO_NOTHING) {
return self::LV_GOOD;
}
if (count($list) > 0) {
return self::LV_SOFT_WARNING;
} else {
return self::LV_GOOD;
}
}
/**
*
* @staticvar string[] $addonListFolder
*
* @return string[]
*/
public static function getAddonsListsFolders()
{
static $addonListFolder = null;
if (is_null($addonListFolder)) {
$addonListFolder = DUPX_Server::getWpAddonsSiteLists();
}
return $addonListFolder;
}
public function getTitle(): string
{
return 'Addon Sites';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/addon-sites', [
'testResult' => $this->testResult,
'pathsList' => self::getAddonsListsFolders(),
], false);
}
protected function goodContent()
{
return $this->swarnContent();
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_archive_check extends DUPX_Validation_abstract_item
{
protected function runTest(): int
{
if (DUPX_Conf_Utils::archiveExists()) {
return self::LV_PASS;
} else {
return self::LV_SOFT_WARNING;
}
}
public function getTitle(): string
{
return 'Archive Check';
}
protected function failContent()
{
return dupxTplRender('parts/validation/tests/archive-check', [
'testResult' => $this->testResult,
], false);
}
protected function swarnContent()
{
return $this->failContent();
}
protected function passContent()
{
return $this->failContent();
}
}

View File

@@ -0,0 +1,43 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_dbonly_iswordpress extends DUPX_Validation_abstract_item
{
protected function runTest(): int
{
if (!DUPX_ArchiveConfig::getInstance()->isDBOnly()) {
return self::LV_SKIP;
}
if (DUPX_Server::isWordPress()) {
return self::LV_GOOD;
} else {
return self::LV_SOFT_WARNING;
}
}
public function getTitle(): string
{
return 'Database Only';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/dbonly-iswordpress', [], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/dbonly-iswordpress', [], false);
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\InstState;
use Duplicator\Installer\Core\Params\PrmMng;
use Duplicator\Installer\Models\ScanInfo;
use Duplicator\Libs\Snap\SnapIO;
class DUPX_Validation_test_disk_space extends DUPX_Validation_abstract_item
{
/** @var int */
private $freeSpace = 0;
/** @var int */
private $archiveSize = 0;
/** @var int */
private $extractedSize = 0;
protected function runTest(): int
{
if (!function_exists('disk_free_space') || InstState::isRecoveryMode()) {
return self::LV_SKIP;
}
// if home path is root path is necessary do a trailingslashit
$realPath = SnapIO::safePathTrailingslashit(PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW));
$this->freeSpace = (int) @disk_free_space($realPath);
$this->archiveSize = DUPX_Conf_Utils::archiveExists() ? DUPX_Conf_Utils::archiveSize() : 1;
$this->extractedSize = ScanInfo::getInstance()->getUSize();
if ($this->freeSpace && $this->archiveSize > 0 && $this->freeSpace > ($this->extractedSize + $this->archiveSize)) {
return self::LV_GOOD;
} else {
return self::LV_SOFT_WARNING;
}
}
public function getTitle(): string
{
return 'Disk Space';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/diskspace', [
'freeSpace' => DUPX_U::readableByteSize($this->freeSpace),
'requiredSpace' => DUPX_U::readableByteSize($this->archiveSize + $this->extractedSize),
'isOk' => false,
], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/diskspace', [
'freeSpace' => DUPX_U::readableByteSize($this->freeSpace),
'requiredSpace' => DUPX_U::readableByteSize($this->archiveSize + $this->extractedSize),
'isOk' => true,
], false);
}
}

View File

@@ -0,0 +1,170 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\InstState;
use Duplicator\Installer\Models\ScanInfo;
use Duplicator\Installer\Package\PComponents;
class DUPX_Validation_test_importable extends DUPX_Validation_abstract_item
{
/** @var string[] */
protected $failMessages = [];
/**
* Run test
*
* @return int test status enum
*/
protected function runTest(): int
{
$archiveConf = DUPX_ArchiveConfig::getInstance();
$coreFoldersCheck = false;
$subsitesCheck = false;
$globalTablesCheck = false;
$partialSubsitesCheck = false;
switch (InstState::getInstType()) {
case InstState::TYPE_SINGLE:
case InstState::TYPE_RBACKUP_SINGLE:
case InstState::TYPE_RECOVERY_SINGLE:
$coreFoldersCheck = true;
$globalTablesCheck = true;
break;
case InstState::TYPE_MSUBDOMAIN:
case InstState::TYPE_MSUBFOLDER:
case InstState::TYPE_RBACKUP_MSUBDOMAIN:
case InstState::TYPE_RBACKUP_MSUBFOLDER:
case InstState::TYPE_RECOVERY_MSUBDOMAIN:
case InstState::TYPE_RECOVERY_MSUBFOLDER:
$coreFoldersCheck = true;
$subsitesCheck = true;
$globalTablesCheck = true;
$partialSubsitesCheck = true;
break;
case InstState::TYPE_STANDALONE:
$coreFoldersCheck = true;
$subsitesCheck = true;
break;
case InstState::TYPE_SINGLE_ON_SUBDOMAIN:
case InstState::TYPE_SINGLE_ON_SUBFOLDER:
$globalTablesCheck = true;
break;
case InstState::TYPE_SUBSITE_ON_SUBDOMAIN:
case InstState::TYPE_SUBSITE_ON_SUBFOLDER:
$subsitesCheck = true;
break;
case InstState::TYPE_NOT_SET:
default:
throw new Exception('Unknown mode');
}
$result = self::LV_PASS;
foreach (PComponents::COMPONENTS_DEFAULT as $component) {
if (
in_array($component, $archiveConf->components)
) {
$this->failMessages[] = 'Component <b>' . PComponents::getLabel($component) . '</b> ' .
'<i class="fas fa-check-circle green"></i>' . ' included.';
} else {
$this->failMessages[] = 'Component <b>' . PComponents::getLabel($component) . '</b> ' .
'<i class="fas fa-times-circle maroon"></i>' . ' excluded.';
if ($component != PComponents::COMP_OTHER) {
$result = self::LV_HARD_WARNING;
}
}
}
if ($coreFoldersCheck) {
if (ScanInfo::getInstance()->hasFilteredCoreFolders()) {
$this->failMessages[] = '<i class="fas fa-times-circle maroon"></i>' .
' Some Wordpress core folders are missing. (e.g. wp-admin, wp-content, wp-includes, uploads, plugins, and themes folders)';
$result = self::LV_HARD_WARNING;
}
}
if ($partialSubsitesCheck) {
if ($archiveConf->mu_is_filtered) {
$this->failMessages[] = '<i class="fas fa-times-circle maroon"></i>' .
' In This Backup, some sub-sites of the multisite installation have been excluded.';
$result = self::LV_HARD_WARNING;
}
}
if ($subsitesCheck) {
for ($i = 0; $i < count($archiveConf->subsites); $i++) {
if (
empty($archiveConf->subsites[$i]->filteredTables) &&
empty($archiveConf->subsites[$i]->filteredPaths)
) {
break;
}
}
if ($i >= count($archiveConf->subsites)) {
$this->failMessages[] = '<i class="fas fa-times-circle maroon"></i>' .
' The Backup does not have any importable subsite.';
$result = self::LV_HARD_WARNING;
}
}
if ($globalTablesCheck && !InstState::dbDoNothing()) {
if ($archiveConf->dbInfo->tablesBaseCount != $archiveConf->dbInfo->tablesFinalCount) {
$this->failMessages[] = '<i class="fas fa-times-circle maroon"></i>' .
' The Backup is missing some of the site tables.';
$result = self::LV_HARD_WARNING;
}
}
return $result;
}
/**
* Get test title
*
* @return string
*/
public function getTitle(): string
{
return 'Partial Backup Check';
}
/**
* Render fail content
*
* @return string
*/
protected function hwarnContent()
{
return dupxTplRender(
'parts/validation/tests/importable-package',
[
'testResult' => $this->testResult,
'failMessages' => $this->failMessages,
],
false
);
}
/**
* Render pass content
*
* @return string
*/
protected function passContent()
{
return $this->hwarnContent();
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
use Duplicator\Installer\Core\InstState;
use Duplicator\Installer\Core\Params\PrmMng;
use Duplicator\Libs\Snap\SnapUtil;
class DUPX_Validation_test_importer_version extends DUPX_Validation_abstract_item
{
/**
*
* @return int
*/
protected function runTest(): int
{
if (!InstState::isImportFromBackendMode()) {
return self::LV_SKIP;
}
$overwriteData = PrmMng::getInstance()->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA);
if (SnapUtil::versionCompare($overwriteData['dupVersion'], DUPX_VERSION, '<', 3)) {
return self::LV_FAIL;
}
return self::LV_PASS;
}
/**
* Return test ticekt
*
* @return string
*/
public function getTitle(): string
{
return 'Duplicator importer version';
}
protected function failContent()
{
$overwriteData = PrmMng::getInstance()->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA);
return dupxTplRender('parts/validation/tests/importer-version', [
'testResult' => $this->testResult,
'importerVer' => ($overwriteData['dupVersion'] == '0' ? 'Unknown' : $overwriteData['dupVersion']),
], false);
}
protected function passContent()
{
return $this->failContent();
}
}

View File

@@ -0,0 +1,131 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\InstState;
use Duplicator\Installer\Core\Params\PrmMng;
use Duplicator\Libs\Snap\SnapIO;
class DUPX_Validation_test_iswritable_configs extends DUPX_Validation_abstract_item
{
/** @var bool[] */
protected $configsCheck = [
'wpconfig' => false,
'htaccess' => false,
'other' => false,
];
/** @var string[] */
protected $notWritableConfigsList = [];
/**
* Run test
*
* @return int
*/
protected function runTest(): int
{
$this->configsCheck = self::configsWritableChecks();
foreach ($this->configsCheck as $check) {
if ($check === false) {
if (
InstState::isRestoreBackup() ||
DUPX_Custom_Host_Manager::getInstance()->isManaged() !== false
) {
return self::LV_SOFT_WARNING;
} else {
return self::LV_HARD_WARNING;
}
}
}
return self::LV_PASS;
}
/**
* try to set wigth config permission and check if configs files are writeable
*
* @return array<string, bool>
*/
public static function configsWritableChecks(): array
{
$result = [];
// if home path is root path is necessary do a trailingslashit
$homePath = SnapIO::safePathTrailingslashit(PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW));
if (!SnapIO::dirAddFullPermsAndCheckResult($homePath)) {
$result['wpconfig'] = false;
$result['htaccess'] = false;
$result['other'] = false;
} else {
$configFile = $homePath . 'wp-config.php';
if (file_exists($configFile)) {
$result['wpconfig'] = SnapIO::fileAddFullPermsAndCheckResult($configFile);
} else {
$result['wpconfig'] = true;
}
$configFile = $homePath . '.htaccess';
if (file_exists($configFile)) {
$result['htaccess'] = SnapIO::fileAddFullPermsAndCheckResult($configFile);
} else {
$result['htaccess'] = true;
}
$result['other'] = true;
$configFile = $homePath . 'web.config';
if (file_exists($configFile) && !SnapIO::fileAddFullPermsAndCheckResult($configFile)) {
$result['other'] = false;
}
$configFile = $homePath . '.user.ini';
if (file_exists($configFile) && !SnapIO::fileAddFullPermsAndCheckResult($configFile)) {
$result['other'] = false;
}
$configFile = $homePath . 'php.ini';
if (file_exists($configFile) && !SnapIO::fileAddFullPermsAndCheckResult($configFile)) {
$result['other'] = false;
}
}
return $result;
}
/**
*
* @return string
*/
public function getTitle(): string
{
return 'Permissions: Configs Files ';
}
protected function hwarnContent()
{
return dupxTplRender('parts/validation/tests/configs-is-writable', [
'testResult' => $this->testResult,
'configsCheck' => $this->configsCheck,
], false);
}
protected function swarnContent()
{
return $this->hwarnContent();
}
protected function passContent()
{
return $this->hwarnContent();
}
}

View File

@@ -0,0 +1,184 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\InstState;
use Duplicator\Installer\Core\Params\PrmMng;
use Duplicator\Libs\Index\FileIndexManager;
use Duplicator\Libs\Snap\SnapIO;
use Duplicator\Libs\Snap\SnapWP;
class DUPX_Validation_test_iswritable extends DUPX_Validation_abstract_item
{
const TEMP_PHP_FILE_NAME = 'dup_tmp_php_file_test.php';
/** @var string[] */
protected $faildDirPerms = [];
/** @var mixed[] */
protected $phpPerms = [];
/**
* Runs Test
*
* @return int
* @throws Exception
*/
protected function runTest(): int
{
$this->faildDirPerms = $this->checkWritePermissions();
$testPass = (count($this->faildDirPerms) == 0);
$prmMng = PrmMng::getInstance();
if ($prmMng->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES) === DUPX_Extraction::FILTER_NONE) {
$abspath = $prmMng->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW);
$this->phpPerms = [
[
'dir' => $abspath . '/wp-admin',
'pass' => false,
'message' => '',
],
[
'dir' => $abspath . '/wp-includes',
'pass' => false,
'message' => '',
],
];
for ($i = 0; $i < count($this->phpPerms); $i++) {
$this->phpPerms[$i]['pass'] = self::checkPhpFileCreation(
$this->phpPerms[$i]['dir'],
$this->phpPerms[$i]['message']
);
if ($this->phpPerms[$i]['pass'] == false) {
$testPass = false;
}
}
}
if ($testPass) {
return self::LV_PASS;
} else {
if (InstState::isRecoveryMode() || DUPX_Custom_Host_Manager::getInstance()->isManaged()) {
return self::LV_SOFT_WARNING;
} else {
return self::LV_HARD_WARNING;
}
}
}
/**
* Returns list of paths that we don't have "write" permissions on
*
* @return string[]
* @throws Exception
*/
protected function checkWritePermissions(): array
{
$prmMng = PrmMng::getInstance();
$failResult = [];
$archiveConfig = DUPX_ArchiveConfig::getInstance();
$skipWpCore = ($prmMng->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES) !== DUPX_Extraction::FILTER_NONE);
foreach (DUPX_Package::getIndexManager()->iteratePaths(FileIndexManager::LIST_TYPE_DIRS) as $path) {
if ($skipWpCore && SnapWP::isWpCore($path, SnapWP::PATH_RELATIVE)) {
continue;
}
$destPath = $archiveConfig->destFileFromArchiveName($path);
if (file_exists($destPath) && !SnapIO::dirAddFullPermsAndCheckResult($destPath)) {
$failResult[] = $destPath;
}
}
return $failResult;
}
/**
* Check if PHP files can be creatend in passed folder
*
* @param string $dir folder to check
* @param string $message error message
*
* @return bool
*/
protected static function checkPhpFileCreation($dir, &$message = ''): bool
{
$removeDir = false;
$exception = null;
try {
if (!file_exists($dir)) {
if (!SnapIO::mkdirP($dir)) {
throw new Exception('Don\'t have permissition to create folder "' . $dir . '"');
}
$removeDir = true;
} elseif (!is_dir($dir)) {
throw new Exception('"' . $dir . '" must be a folder');
} elseif (!is_writable($dir) || !is_executable($dir)) {
if (SnapIO::chmod($dir, 'u+rwx') == false) {
throw new Exception('"' . $dir . '" don\'t have write permissions');
}
}
$tmpFile = SnapIO::trailingslashit($dir) . self::TEMP_PHP_FILE_NAME;
if (file_exists($tmpFile) && unlink($tmpFile) == false) {
throw new Exception('Can\'t remove temp php file \"' . $tmpFile . '\" to check if php files are writable');
}
if (file_put_contents($tmpFile, "<?php\n\n//silent") == false) {
throw new Exception('Cannot create PHP files even if the "' . basename($dir) . '" folder has permissions');
}
unlink($tmpFile);
} catch (Exception $e) {
$exception = $e;
}
if ($removeDir) {
rmdir($dir);
}
if (is_null($exception)) {
return true;
} else {
$message = $exception->getMessage();
return false;
}
}
public function getTitle(): string
{
return 'Permissions: General';
}
protected function hwarnContent()
{
return dupxTplRender('parts/validation/tests/writeable-checks', [
'testResult' => $this->testResult,
'phpPerms' => $this->phpPerms,
'faildDirPerms' => $this->faildDirPerms,
], false);
}
protected function swarnContent()
{
return $this->hwarnContent();
}
protected function passContent()
{
return $this->hwarnContent();
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
use Duplicator\Installer\Core\InstState;
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_managed_supported extends DUPX_Validation_abstract_item
{
/** @var bool */
private $managed = false;
/** @var string */
private $failMessage = '';
protected function runTest(): int
{
if (!($this->managed = DUPX_Custom_Host_Manager::getInstance()->isManaged())) {
return self::LV_SKIP;
}
if (InstState::isRecoveryMode()) {
return self::LV_PASS;
}
if (InstState::isNewSiteIsMultisite()) {
$this->failMessage = "Installing multisites on managed hosts is not supported";
return self::LV_FAIL;
}
if (InstState::isImportFromBackendMode()) {
return self::LV_PASS;
}
switch ($this->managed) {
case DUPX_Custom_Host_Manager::HOST_GODADDY:
case DUPX_Custom_Host_Manager::HOST_LIQUIDWEB:
case DUPX_Custom_Host_Manager::HOST_WPENGINE:
return self::LV_PASS;
case DUPX_Custom_Host_Manager::HOST_PANTHEON:
case DUPX_Custom_Host_Manager::HOST_WORDPRESSCOM:
case DUPX_Custom_Host_Manager::HOST_FLYWHEEL:
$this->failMessage = 'Standard installations on this managed host are not supported because it uses a non-standard configuration that can ' .
'only be read at runtime. Use Drop and Drop install to overwrite the site instead.';
return self::LV_FAIL;
default:
$this->failMessage = "Unknown managed host type.";
return self::LV_FAIL;
}
}
public function getTitle(): string
{
return 'Managed hosting supported';
}
protected function failContent()
{
return dupxTplRender(
'parts/validation/tests/managed-supported',
[
'isOk' => false,
'managedHosting' => $this->managed,
'failMessage' => $this->failMessage,
],
false
);
}
protected function passContent()
{
return dupxTplRender(
'parts/validation/tests/managed-supported',
[
'isOk' => true,
'managedHosting' => $this->managed,
'failMessage' => $this->failMessage,
],
false
);
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\Params\PrmMng;
class DUPX_Validation_test_managed_tprefix extends DUPX_Validation_abstract_item
{
protected function runTest(): int
{
if (!DUPX_Custom_Host_Manager::getInstance()->isManaged()) {
return self::LV_SKIP;
}
$overwriteData = PrmMng::getInstance()->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA);
if (DUPX_ArchiveConfig::getInstance()->wp_tableprefix != $overwriteData['table_prefix']) {
return self::LV_SOFT_WARNING;
} else {
return self::LV_GOOD;
}
}
public function getTitle(): string
{
return 'Table prefix of managed hosting';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/managed-tprefix', ['isOk' => false], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/managed-tprefix', ['isOk' => true], false);
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_manual_extraction extends DUPX_Validation_abstract_item
{
protected function runTest(): int
{
if (DUPX_Conf_Utils::isManualExtractFilePresent()) {
return self::LV_SOFT_WARNING;
} else {
return self::LV_GOOD;
}
}
public function getTitle(): string
{
return 'Manual extraction detected';
}
public function display()
{
if ($this->testResult === self::LV_SKIP) {
return false;
} else {
return DUPX_Conf_Utils::isManualExtractFilePresent();
}
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/manual-extraction', [], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/manual-extraction', [], false);
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Libs\Snap\SnapUtil;
class DUPX_Validation_test_memory_limit extends DUPX_Validation_abstract_item
{
const MIN_MEMORY_LIMIT = '256M';
/** @var int */
private $memoryLimit = -1;
protected function runTest(): int
{
if (($memoryLimit = @ini_get('memory_limit')) === false || strlen($memoryLimit) == 0) {
return self::LV_SKIP;
}
$this->memoryLimit = is_numeric($memoryLimit) ? (int) $memoryLimit : SnapUtil::convertToBytes($memoryLimit);
if ($this->memoryLimit < 0) {
return self::LV_SKIP;
}
if ($this->memoryLimit >= SnapUtil::convertToBytes(self::MIN_MEMORY_LIMIT)) {
return self::LV_GOOD;
}
return self::LV_SOFT_WARNING;
}
public function getTitle(): string
{
return 'PHP Memory Limit';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/memory-limit', [
'memoryLimit' => $this->memoryLimit,
'minMemoryLimit' => self::MIN_MEMORY_LIMIT,
'isOk' => false,
], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/memory-limit', [
'memoryLimit' => DUPX_U::readableByteSize($this->memoryLimit),
'minMemoryLimit' => self::MIN_MEMORY_LIMIT,
'isOk' => true,
], false);
}
}

View File

@@ -0,0 +1,57 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\InstState;
use Duplicator\Installer\Core\Params\PrmMng;
class DUPX_Validation_test_multisite_subfolder extends DUPX_Validation_abstract_item
{
protected function runTest(): int
{
if (InstState::isRecoveryMode() || !InstState::isNewSiteIsMultisite()) {
return self::LV_SKIP;
}
if (InstState::isInstType(InstState::TYPE_MSUBDOMAIN) && $this->newUrlIsInSubFolder()) {
return self::LV_HARD_WARNING;
}
return self::LV_PASS;
}
/**
* Check if the new url is in a subfolder
*
* @return bool
*/
private function newUrlIsInSubFolder(): bool
{
return parse_url(PrmMng::getInstance()->getValue(PrmMng::PARAM_URL_NEW), PHP_URL_PATH) !== null;
}
public function getTitle(): string
{
return 'Subomain multisite installation in subfolder';
}
protected function hwarnContent()
{
return dupxTplRender('parts/validation/tests/multisite-subfolder', ["isOk" => false], false);
}
protected function passContent()
{
return dupxTplRender('parts/validation/tests/multisite-subfolder', ["isOk" => true], false);
}
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_mysql_connect extends DUPX_Validation_abstract_item
{
protected function runTest(): int
{
if (function_exists('mysqli_connect')) {
return self::LV_PASS;
} else {
return self::LV_FAIL;
}
}
public function getTitle(): string
{
return 'PHP Mysqli';
}
protected function failContent()
{
return dupxTplRender('parts/validation/tests/mysql-connect', [], false);
}
protected function passContent()
{
return dupxTplRender('parts/validation/tests/mysql-connect', [], false);
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\InstState;
use Duplicator\Libs\Snap\SnapOpenBasedir;
class DUPX_Validation_test_open_basedir extends DUPX_Validation_abstract_item
{
/** @var bool */
private $openBaseDirEnabled = false;
/** @var string[] */
private $pathsOutsideOpenBaseDir = [];
protected function runTest(): int
{
if (InstState::isRecoveryMode()) {
return self::LV_SKIP;
}
if (($this->openBaseDirEnabled = SnapOpenBasedir::isEnabled()) === false) {
return self::LV_GOOD;
}
$archivePaths = [];
$pathMapping = DUPX_ArchiveConfig::getInstance()->getPathsMapping();
if (is_array($pathMapping)) {
$archivePaths = $pathMapping;
} else {
$archivePaths[] = $pathMapping;
}
foreach ($archivePaths as $archivePath) {
if (SnapOpenBasedir::getRootOfPath($archivePath) === false) {
$this->pathsOutsideOpenBaseDir[] = $archivePath;
}
}
if (empty($this->pathsOutsideOpenBaseDir)) {
return self::LV_GOOD;
} else {
return self::LV_HARD_WARNING;
}
}
public function getTitle(): string
{
return 'PHP Open Base';
}
protected function hwarnContent()
{
return dupxTplRender('parts/validation/tests/open-basedir', [
'openBaseDirEnabled' => $this->openBaseDirEnabled,
'pathsOutsideOpenBaseDir' => $this->pathsOutsideOpenBaseDir,
'isOk' => false,
], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/open-basedir', [
'openBaseDirEnabled' => $this->openBaseDirEnabled,
'pathsOutsideOpenBaseDir' => $this->pathsOutsideOpenBaseDir,
'isOk' => true,
], false);
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
use Duplicator\Installer\Core\InstState;
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_owrinstall extends DUPX_Validation_abstract_item
{
protected function runTest(): int
{
if (
InstState::isRecoveryMode() ||
InstState::isImportFromBackendMode()
) {
return self::LV_SKIP;
}
if (InstState::getInstance()->getMode() === InstState::MODE_OVR_INSTALL) {
return self::LV_SOFT_WARNING;
} else {
return self::LV_GOOD;
}
}
public function getTitle(): string
{
return 'Overwrite Install';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/overwrite-install', [], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/overwrite-install', [], false);
}
}

View File

@@ -0,0 +1,58 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_package_age extends DUPX_Validation_abstract_item
{
const PACKAGE_DAYS_BEFORE_WARNING = 180;
protected function runTest(): int
{
if ($this->getPackageDays() <= self::PACKAGE_DAYS_BEFORE_WARNING) {
return self::LV_GOOD;
} else {
return self::LV_SOFT_WARNING;
}
}
/**
* Get package age in days
*
* @return int
*/
protected function getPackageDays(): int
{
return (int) round((time() - strtotime(DUPX_ArchiveConfig::getInstance()->created)) / 86400);
}
public function getTitle(): string
{
return 'Package Age';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/package-age', [
'packageDays' => $this->getPackageDays(),
'maxPackageDays' => self::PACKAGE_DAYS_BEFORE_WARNING,
], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/package-age', [
'packageDays' => $this->getPackageDays(),
'maxPackageDays' => self::PACKAGE_DAYS_BEFORE_WARNING,
], false);
}
}

View File

@@ -0,0 +1,76 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Utils\Log\Log;
class DUPX_Validation_test_extensions extends DUPX_Validation_abstract_item
{
/** @var array<string, mixed> */
public $extensionTests = [
"json" => [
"failLevel" => self::LV_FAIL,
"pass" => false,
],
];
protected function runTest()
{
$result = self::LV_GOOD;
foreach ($this->extensionTests as $extensionName => $extensionTest) {
$this->extensionTests[$extensionName]["pass"] = extension_loaded($extensionName);
if (!$this->extensionTests[$extensionName]["pass"]) {
Log::info("The '{$extensionName}' extension is not loaded.");
//update fail level
if ($extensionTest["failLevel"] < $result) {
$result = $extensionTest["failLevel"];
}
}
}
return $result;
}
public function getTitle(): string
{
return 'PHP Extensions';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/php-extensions', [
'extensionTests' => $this->extensionTests,
], false);
}
protected function hwarnContent()
{
return dupxTplRender('parts/validation/tests/php-extensions', [
'extensionTests' => $this->extensionTests,
], false);
}
protected function failContent()
{
return dupxTplRender('parts/validation/tests/php-extensions', [
'extensionTests' => $this->extensionTests,
], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/php-extensions', [
'extensionTests' => $this->extensionTests,
], false);
}
}

View File

@@ -0,0 +1,135 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\Params\PrmMng;
use Duplicator\Libs\Snap\FunctionalityCheck;
class DUPX_Validation_test_php_functionalities extends DUPX_Validation_abstract_item
{
/** @var FunctionalityCheck[] */
protected array $functionalities;
/**
* Class contructor
*
* @param string $category Category
*/
public function __construct($category = '')
{
parent::__construct($category);
$this->functionalities = self::getFunctionalitiesCheckList();
}
protected function runTest(): int
{
if (FunctionalityCheck::checkList($this->functionalities)) {
return self::LV_PASS;
} elseif (FunctionalityCheck::checkList($this->functionalities, true)) {
return self::LV_HARD_WARNING;
} else {
return self::LV_FAIL;
}
}
public function getTitle(): string
{
return 'PHP Functions and Classes';
}
protected function failContent()
{
return dupxTplRender('parts/validation/tests/php-functionalities', [
'functionalities' => $this->functionalities,
'testResult' => $this->testResult,
], false);
}
protected function passContent()
{
return $this->failContent();
}
protected function hwarnContent()
{
return $this->failContent();
}
/**
* Get list of functionalities to check
*
* @return FunctionalityCheck[]
*/
protected static function getFunctionalitiesCheckList(): array
{
$result = [];
$archiveEngine = PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE);
if ($archiveEngine == DUPX_Extraction::ENGINE_ZIP || $archiveEngine == DUPX_Extraction::ENGINE_ZIP_CHUNK) {
$result[] = new FunctionalityCheck(
FunctionalityCheck::TYPE_CLASS,
\ZipArchive::class,
true,
'https://www.php.net/manual/en/class.ziparchive.php',
'<i style="font-size:12px">'
. '<a href="' . DUPX_Constants::FAQ_URL . 'how-to-work-with-the-different-zip-engines" target="_blank">'
. 'Overview on how to enable ZipArchive</i></a>'
);
}
$result[] = new FunctionalityCheck(
FunctionalityCheck::TYPE_FUNCTION,
'json_encode',
true,
'https://www.php.net/manual/en/function.json-encode.php'
);
$functionality = new FunctionalityCheck(
FunctionalityCheck::TYPE_FUNCTION,
'token_get_all',
false,
'https://www.php.net/manual/en/function.token-get-all',
"Required for parsing the contents of the wp-config.php file. "
. "If test failed, to avoid problems during the installation the handling of the wp-config.php "
. "file has been disabled (the setting 'Wordpress wp-config.php' under Advanced Mode > Options > "
. "Advanced > Configuration files has been set to 'Do nothing'.)"
);
$functionality->setFailCallback(function (FunctionalityCheck $item): void {
PrmMng::getInstance()->setValue(PrmMng::PARAM_WP_CONFIG, 'nothing');
PrmMng::getInstance()->save();
});
$result[] = $functionality;
$result[] = new FunctionalityCheck(
FunctionalityCheck::TYPE_FUNCTION,
'file_get_contents',
true,
'https://www.php.net/manual/en/function.file-get-contents.php'
);
$result[] = new FunctionalityCheck(
FunctionalityCheck::TYPE_FUNCTION,
'file_put_contents',
true,
'https://www.php.net/manual/en/function.file-put-contents.php'
);
$result[] = new FunctionalityCheck(
FunctionalityCheck::TYPE_FUNCTION,
'mb_strlen',
true,
'https://www.php.net/manual/en/mbstring.installation.php'
);
return $result;
}
}

View File

@@ -0,0 +1,67 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
use Duplicator\Installer\Core\InstState;
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_php_version extends DUPX_Validation_abstract_item
{
protected function runTest(): int
{
$archiveConfig = DUPX_ArchiveConfig::getInstance();
if ($archiveConfig->isDBOnly()) {
return self::LV_GOOD;
}
// compare only major version ex 5 and 7 not 5.6 and 5.5
if (intval($archiveConfig->version_php) === intval(phpversion())) {
return self::LV_GOOD;
} elseif (InstState::isImportFromBackendMode()) {
return self::LV_HARD_WARNING;
} else {
return self::LV_SOFT_WARNING;
}
}
public function getTitle(): string
{
return 'PHP Version Mismatch';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/php-version', [
'fromPhp' => DUPX_ArchiveConfig::getInstance()->version_php,
'toPhp' => phpversion(),
'isOk' => false,
], false);
}
protected function hwarnContent()
{
return dupxTplRender('parts/validation/tests/php-version', [
'fromPhp' => DUPX_ArchiveConfig::getInstance()->version_php,
'toPhp' => phpversion(),
'isOk' => false,
], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/php-version', [
'fromPhp' => DUPX_ArchiveConfig::getInstance()->version_php,
'toPhp' => phpversion(),
'isOk' => true,
], false);
}
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\InstState;
use Duplicator\Installer\Core\Params\PrmMng;
class DUPX_Validation_test_recovery extends DUPX_Validation_abstract_item
{
/** @var array<string, mixed> */
protected $importSiteInfo = [];
/** @var bool */
protected $recoveryPage = false;
/** @var bool */
protected $importPage = false;
/** @var bool */
protected $recoveryIsOutToDate = false;
/** @var int */
protected $recoveryPackageLife = -1;
protected function runTest(): int
{
$paramsManager = PrmMng::getInstance();
if (!InstState::isImportFromBackendMode()) {
return self::LV_SKIP;
}
$this->importSiteInfo = PrmMng::getInstance()->getValue(PrmMng::PARAM_FROM_SITE_IMPORT_INFO);
$this->importPage = $this->importSiteInfo['import_page'];
$this->recoveryPage = $this->importSiteInfo['recovery_page'];
$this->recoveryIsOutToDate = $this->importSiteInfo['recovery_is_out_to_date'];
$this->recoveryPackageLife = $this->importSiteInfo['recovery_package_life'];
$recoveryLink = $paramsManager->getValue(PrmMng::PARAM_RECOVERY_LINK);
if (empty($recoveryLink)) {
return self::LV_HARD_WARNING;
} else {
if ($this->importSiteInfo['recovery_is_out_to_date']) {
return self::LV_SOFT_WARNING;
} else {
return self::LV_GOOD;
}
}
}
public function getTitle(): string
{
return 'Disaster Recovery';
}
protected function hwarnContent()
{
return dupxTplRender('parts/validation/tests/recovery', [
'testResult' => $this->testResult,
'importPage' => $this->importPage,
'recoveryPage' => $this->recoveryPage,
'recoveryIsOutToDate' => $this->recoveryIsOutToDate,
'recoveryPackageLife' => $this->recoveryPackageLife,
], false);
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/recovery', [
'testResult' => $this->testResult,
'importPage' => $this->importPage,
'recoveryPage' => $this->recoveryPage,
'recoveryIsOutToDate' => $this->recoveryIsOutToDate,
'recoveryPackageLife' => $this->recoveryPackageLife,
], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/recovery', [
'testResult' => $this->testResult,
'importPage' => $this->importPage,
'recoveryPage' => $this->recoveryPage,
'recoveryIsOutToDate' => $this->recoveryIsOutToDate,
'recoveryPackageLife' => $this->recoveryPackageLife,
], false);
}
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\Params\PrmMng;
class DUPX_Validation_test_replace_paths extends DUPX_Validation_abstract_item
{
/** @var string */
protected $message = '';
protected function runTest(): int
{
$paramsManager = PrmMng::getInstance();
if (
$paramsManager->getValue(PrmMng::PARAM_REPLACE_ENGINE) === DUPX_S3_Funcs::MODE_SKIP ||
$paramsManager->getValue(PrmMng::PARAM_SKIP_PATH_REPLACE) === false
) {
return self::LV_SKIP;
}
$archivePaths = DUPX_ArchiveConfig::getInstance()->getRealValue("archivePaths");
if (strlen($archivePaths->home) == 0) {
// if new path is equal at old path the replace isn't necessary so skip message
if (strlen($paramsManager->getValue(PrmMng::PARAM_PATH_NEW)) === 0) {
return self::LV_SKIP;
}
$this->message = "It was found that the home path of the source was equal to '/'. In this case it's" .
" impossible to automatically replace paths, because of that path replacements have been disabled.";
}
return self::LV_HARD_WARNING;
}
public function getTitle(): string
{
return 'Replace PATHs in database';
}
protected function hwarnContent()
{
return dupxTplRender(
'parts/validation/tests/replace-paths',
[
"message" => $this->message,
"isOk" => false,
],
false
);
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
use Duplicator\Installer\Core\InstState;
use Duplicator\Installer\Core\Params\PrmMng;
use Duplicator\Installer\REST\RESTPoints;
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_rest_api extends DUPX_Validation_abstract_item
{
/** @var string */
protected $errorMessage = '';
/** @var string */
protected $restUrl = '';
protected function runTest(): int
{
if (!InstState::isAddSiteOnMultisite()) {
return self::LV_SKIP;
}
$overwriteData = PrmMng::getInstance()->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA);
if (is_array($overwriteData) && isset($overwriteData['restUrl']) && strlen($overwriteData['restUrl']) > 0) {
$this->restUrl = $overwriteData['restUrl'];
} else {
$this->restUrl = PrmMng::getInstance()->getValue(PrmMng::PARAM_URL_NEW) . '/wp-json';
}
$this->errorMessage = "REST API call to WordPress backend failed";
if (RESTPoints::getInstance()->checkRest(true, $this->errorMessage)) {
return self::LV_PASS;
}
return self::LV_FAIL;
}
public function getTitle(): string
{
return 'REST API test';
}
protected function passContent()
{
return dupxTplRender(
'parts/validation/tests/rest-api',
[
"isOk" => true,
"restUrl" => $this->restUrl,
],
false
);
}
protected function failContent()
{
return dupxTplRender(
'parts/validation/tests/rest-api',
[
"isOk" => false,
"errorMessage" => $this->errorMessage,
"restUrl" => $this->restUrl,
],
false
);
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_siteground extends DUPX_Validation_abstract_item
{
protected function runTest(): int
{
if (!DUPX_Custom_Host_Manager::getInstance()->isHosting(DUPX_Custom_Host_Manager::HOST_SITEGROUND)) {
return self::LV_SKIP;
}
return self::LV_SOFT_WARNING;
}
public function getTitle(): string
{
return 'Siteground';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/siteground', [], false);
}
}

View File

@@ -0,0 +1,140 @@
<?php
/**
* Validation object for staging sites
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\InstState;
use Duplicator\Installer\Core\Params\PrmMng;
class DUPX_Validation_test_staging_sites extends DUPX_Validation_abstract_item
{
/** @var string[] staging table prefixes found */
protected $stagingPrefixes = [];
/** @var string[] staging folder paths found */
protected $stagingPaths = [];
/**
* Run staging sites validation test
*
* @return int
*/
protected function runTest(): int
{
if (InstState::dbDoNothing()) {
return self::LV_SKIP;
}
if (DUPX_Validation_database_service::getInstance()->skipDatabaseTests()) {
return self::LV_SKIP;
}
if (InstState::isStagingMode()) {
return self::LV_SKIP;
}
$this->stagingPrefixes = $this->getStagingTablePrefixes();
$this->stagingPaths = $this->getStagingFolderPaths();
// If no staging sites detected, pass
if (empty($this->stagingPrefixes) && empty($this->stagingPaths)) {
return self::LV_PASS;
}
// Show hard warning if staging sites exist
return self::LV_HARD_WARNING;
}
/**
* Get staging table prefixes from current database
*
* @return string[]
*/
protected function getStagingTablePrefixes(): array
{
$dbService = DUPX_Validation_database_service::getInstance();
$dbh = $dbService->getDbConnection();
if (!$dbh) {
return [];
}
$escapedDbName = mysqli_real_escape_string($dbh, PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_NAME));
$allTables = DUPX_DB::queryColumnToArray($dbh, 'SHOW TABLES FROM `' . $escapedDbName . '`');
if (empty($allTables)) {
return [];
}
// Use helper function to filter staging table prefixes
return DUPX_DB_Functions::getStagingTablePrefixes($allTables);
}
/**
* Get staging folder paths from filesystem
*
* @return string[]
*/
protected function getStagingFolderPaths(): array
{
$stagingPaths = [];
// Get paths from addon sites list
$addonSites = DUPX_Validation_test_addon_sites::getAddonsListsFolders();
// Filter only staging folders (containing /dup_staging/)
foreach ($addonSites as $path) {
if (strpos($path, '/dup_staging/') !== false) {
$stagingPaths[] = $path;
}
}
return $stagingPaths;
}
/**
* Get test title
*
* @return string
*/
public function getTitle(): string
{
return 'Staging Sites';
}
/**
* Render hard warning content
*
* @return string
*/
protected function hwarnContent()
{
return dupxTplRender('parts/validation/tests/staging-sites', [
'testResult' => $this->testResult,
'stagingPrefixes' => $this->stagingPrefixes,
'stagingPaths' => $this->stagingPaths,
], false);
}
/**
* Render pass content
*
* @return string
*/
protected function passContent()
{
return dupxTplRender('parts/validation/tests/staging-sites', [
'testResult' => $this->testResult,
'stagingPrefixes' => [],
'stagingPaths' => [],
'isHardWarning' => false,
], false);
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
class DUPX_Validation_test_timeout extends DUPX_Validation_abstract_item
{
const MAX_TIME_SIZE = 314572800; //300MB
/** @var bool|int */
protected $maxTimeZero = false;
protected function runTest(): int
{
$max_time_ini = ini_get('max_execution_time');
$this->maxTimeZero = ($GLOBALS['DUPX_ENFORCE_PHP_INI']) ? false : @set_time_limit(0);
if ((is_numeric($max_time_ini) && $max_time_ini < 31 && $max_time_ini > 0) && DUPX_Conf_Utils::archiveSize() > self::MAX_TIME_SIZE) {
return self::LV_SOFT_WARNING;
} else {
return self::LV_GOOD;
}
}
public function getTitle(): string
{
return 'PHP Timeout';
}
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/timeout', [
'maxTimeZero' => $this->maxTimeZero,
'maxTimeIni' => ini_get('max_execution_time'),
'archiveSize' => DUPX_U::readableByteSize(DUPX_Conf_Utils::archiveSize()),
'maxSize' => DUPX_U::readableByteSize(self::MAX_TIME_SIZE),
'isOk' => true,
], false);
}
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/timeout', [
'maxTimeZero' => $this->maxTimeZero,
'maxTimeIni' => ini_get('max_execution_time'),
'archiveSize' => DUPX_U::readableByteSize(DUPX_Conf_Utils::archiveSize()),
'maxSize' => DUPX_U::readableByteSize(self::MAX_TIME_SIZE),
'isOk' => true,
], false);
}
}

View File

@@ -0,0 +1,138 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Utils\Log\LogHandler;
use Duplicator\Installer\Core\Params\PrmMng;
use Duplicator\Libs\Snap\SnapIO;
class DUPX_Validation_test_wordfence extends DUPX_Validation_abstract_item
{
/** @var string */
private $wordFencePath = "";
protected function runTest(): int
{
return $this->parentHasWordfence() ? self::LV_HARD_WARNING : self::LV_GOOD;
}
/**
* Get test title
*
* @return string
*/
public function getTitle(): string
{
return 'Wordfence';
}
/**
* Return content for test status
*
* @return string
*/
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/wordfence/wordfence-detected', [
'wordFencePath' => $this->wordFencePath,
], false);
}
/**
* Return content for test status
*
* @return string
*/
protected function hwarnContent()
{
return dupxTplRender('parts/validation/tests/wordfence/wordfence-detected', [
'wordFencePath' => $this->wordFencePath,
], false);
}
/**
* Return content for test status
*
* @return string
*/
protected function goodContent()
{
return dupxTplRender('parts/validation/tests/wordfence/wordfence-not-detected', [], false);
}
/**
* Check if the Wordfence firewall is enabled in the parent path
*
* @return bool
*/
protected function parentHasWordfence()
{
$scanPath = PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW);
$rootPath = SnapIO::getMaxAllowedRootOfPath($scanPath);
$result = false;
if ($rootPath === false) {
//$scanPath is not contained in open_basedir paths skip
return false;
}
LogHandler::setMode(LogHandler::MODE_OFF);
$continueScan = true;
while ($continueScan) {
if ($this->wordFenceFirewallEnabled($scanPath)) {
$this->wordFencePath = $scanPath;
$result = true;
break;
}
$continueScan = $scanPath !== $rootPath && $scanPath != dirname($scanPath);
$scanPath = dirname($scanPath);
}
LogHandler::setMode();
return $result;
}
/**
* Check if the Wordfence firewall is enabled in the given path
*
* @param string $path The path to check
*
* @return bool
*/
protected function wordFenceFirewallEnabled($path): bool
{
$configFiles = [
'php.ini',
'.user.ini',
'.htaccess',
];
foreach ($configFiles as $configFile) {
$file = $path . '/' . $configFile;
if (!@is_readable($file)) {
continue;
}
if (($content = @file_get_contents($file)) === false) {
continue;
}
if (strpos($content, 'wordfence-waf.php') !== false) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* Validation object
*
* Standard: PSR-2
*
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
*
* @package SC\DUPX\U
*/
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
use Duplicator\Installer\Core\Deploy\ServerConfigs;
use Duplicator\Installer\Core\InstState;
class DUPX_Validation_test_wp_config extends DUPX_Validation_abstract_item
{
/**
* @return int
* @throws Exception
*/
protected function runTest(): int
{
if (!InstState::isClassicInstall()) {
return self::LV_SKIP;
}
if (DUPX_WPConfig::isSourceWpConfigValid()) {
return self::LV_PASS;
} else {
return self::LV_SOFT_WARNING;
}
}
/**
* @return string
*/
public function getTitle(): string
{
return 'Wordpress Configuration';
}
/**
* @return string
*/
protected function swarnContent()
{
return dupxTplRender('parts/validation/tests/wp-config-check', [
'testResult' => $this->testResult,
'configPath' => ServerConfigs::getSourceWpConfigPath(),
], false);
}
/**
* @return string
*/
protected function passContent()
{
return $this->swarnContent();
}
}