/** * DUPLICATOR_PACKAGE_SCAN * Returns the directory size and file count for the root directory minus * any of the filters * * @return json size and file count of directory * @example to test: admin-ajax.php?action=duplicator_package_scan * */ function duplicator_package_scan() { @set_time_limit(0); $errLevel = error_reporting(); error_reporting(E_ERROR); $json = array(); $Package = new DUP_Package(); $Package = $Package->GetActive(); //SERVER $srv = $Package->GetServerChecks(); $json['SRV']['OpenBase'] = $srv['CHK-SRV-100']; $json['SRV']['CacheOn'] = $srv['CHK-SRV-101']; $json['SRV']['TimeOuts'] = $srv['CHK-SRV-102']; //DATABASE $db = $Package->Database->Stats(); $json['DB']['Status'] = $db['Status']; $json['DB']['Size'] = DUP_Util::ByteSize($db['Size']) or "unknown"; $json['DB']['Rows'] = number_format($db['Rows']) or "unknown"; $json['DB']['TableCount'] = $db['TableCount'] or "unknown"; $json['DB']['TableList'] = $db['TableList'] or "unknown"; //FILES $Package->Archive->GetStats(); $json['ARC']['Size'] = DUP_Util::ByteSize($Package->Archive->Size) or "unknown"; $json['ARC']['DirCount'] = empty($Package->Archive->DirCount) ? '0' : number_format($Package->Archive->DirCount); $json['ARC']['FileCount'] = empty($Package->Archive->FileCount) ? '0' : number_format($Package->Archive->FileCount); $json['ARC']['LinkCount'] = empty($Package->Archive->LinkCount) ? '0' : number_format($Package->Archive->LinkCount); $json['ARC']['InvalidFiles'] = is_array($Package->Archive->InvalidFileList) ? $Package->Archive->InvalidFileList : "unknown"; $json['ARC']['BigFiles'] = is_array($Package->Archive->BigFileList) ? $Package->Archive->BigFileList : "unknown"; $json['ARC']['Status']['Size'] = $Package->Archive->Size > DUPLICATOR_SCAN_SITE ? 'Warn' : 'Good'; $json['ARC']['Status']['Names'] = count($Package->Archive->InvalidFileList) ? 'Warn' : 'Good'; $json['ARC']['Status']['Big'] = count($Package->Archive->BigFileList) ? 'Warn' : 'Good'; ///die(str_repeat("To force error message uncomment this line", 100)); $json_response = json_encode($json); error_reporting($errLevel); die($json_response); }
/** * Starts the package build process * @return DUP_Package */ public function Build() { global $wp_version; global $wpdb; global $current_user; $timerStart = DUP_Util::GetMicrotime(); $this->Archive->File = "{$this->NameHash}_archive.zip"; $this->Installer->File = "{$this->NameHash}_installer.php"; $this->Database->File = "{$this->NameHash}_database.sql"; //START LOGGING DUP_Log::Open($this->NameHash); $php_max_time = @ini_get("max_execution_time"); $php_max_memory = @ini_set('memory_limit', DUPLICATOR_PHP_MAX_MEMORY); $php_max_time = $php_max_time == 0 ? "(0) no time limit imposed" : "[{$php_max_time}] not allowed"; $php_max_memory = $php_max_memory === false ? "Unabled to set php memory_limit" : DUPLICATOR_PHP_MAX_MEMORY . " ({$php_max_memory} default)"; $info = "********************************************************************************\n"; $info .= "PACKAGE-LOG: " . @date("Y-m-d H:i:s") . "\n"; $info .= "NOTICE: Do NOT post to public sites or forums \n"; $info .= "********************************************************************************\n"; $info .= "VERSION:\t" . DUPLICATOR_VERSION . "\n"; $info .= "WORDPRESS:\t{$wp_version}\n"; $info .= "PHP INFO:\t" . phpversion() . ' | ' . 'SAPI: ' . php_sapi_name() . "\n"; $info .= "SERVER:\t\t{$_SERVER['SERVER_SOFTWARE']} \n"; $info .= "PHP TIME LIMIT: {$php_max_time} \n"; $info .= "PHP MAX MEMORY: {$php_max_memory} \n"; $info .= "MEMORY STACK: " . DUP_Server::GetPHPMemory(); DUP_Log::Info($info); $info = null; //CREATE DB RECORD $packageObj = serialize($this); if (!$packageObj) { DUP_Log::Error("Unable to serialize pacakge object while building record."); } $this->ID = $this->FindHashKey($this->Hash); if ($this->ID != 0) { $this->SetStatus(DUP_PackageStatus::START); } else { $results = $wpdb->insert($wpdb->prefix . "duplicator_packages", array('name' => $this->Name, 'hash' => $this->Hash, 'status' => DUP_PackageStatus::START, 'created' => current_time('mysql', get_option('gmt_offset', 1)), 'owner' => isset($current_user->user_login) ? $current_user->user_login : '******', 'package' => $packageObj)); if ($results == false) { $error_result = $wpdb->print_error(); DUP_Log::Error("Duplicator is unable to insert a package record into the database table.", "'{$error_result}'"); } $this->ID = $wpdb->insert_id; } //START BUILD //PHPs serialze method will return the object, but the ID above is not passed //for one reason or another so passing the object back in seems to do the trick $this->Database->Build($this); $this->Archive->Build($this); $this->Installer->Build($this); //INTEGRITY CHECKS DUP_Log::Info("\n********************************************************************************"); DUP_Log::Info("INTEGRITY CHECKS:"); DUP_Log::Info("********************************************************************************"); $dbSizeRead = DUP_Util::ByteSize($this->Database->Size); $zipSizeRead = DUP_Util::ByteSize($this->Archive->Size); $exeSizeRead = DUP_Util::ByteSize($this->Installer->Size); DUP_Log::Info("SQL File: {$dbSizeRead}"); DUP_Log::Info("Installer File: {$exeSizeRead}"); DUP_Log::Info("Archive File: {$zipSizeRead} "); if (!($this->Archive->Size && $this->Database->Size && $this->Installer->Size)) { DUP_Log::Error("A required file contains zero bytes.", "Archive Size: {$zipSizeRead} | SQL Size: {$dbSizeRead} | Installer Size: {$exeSizeRead}"); } //Validate SQL files completed $sql_tmp_path = DUP_UTIL::SafePath(DUPLICATOR_SSDIR_PATH_TMP . '/' . $this->Database->File); $sql_complete_txt = DUP_Util::TailFile($sql_tmp_path, 3); if (!strstr($sql_complete_txt, 'DUPLICATOR_MYSQLDUMP_EOF')) { DUP_Log::Error("ERROR: SQL file not complete. The end of file marker was not found. Please try to re-create the package."); } $timerEnd = DUP_Util::GetMicrotime(); $timerSum = DUP_Util::ElapsedTime($timerEnd, $timerStart); $this->Runtime = $timerSum; $this->ExeSize = $exeSizeRead; $this->ZipSize = $zipSizeRead; $this->buildCleanup(); //FINAL REPORT $info = "\n********************************************************************************\n"; $info .= "RECORD ID:[{$this->ID}]\n"; $info .= "TOTAL PROCESS RUNTIME: {$timerSum}\n"; $info .= "PEAK PHP MEMORY USED: " . DUP_Server::GetPHPMemory(true) . "\n"; $info .= "DONE PROCESSING => {$this->Name} " . @date("Y-m-d H:i:s") . "\n"; DUP_Log::Info($info); DUP_Log::Close(); $this->SetStatus(DUP_PackageStatus::COMPLETE); return $this; }
?> </td> </tr> <tr valign="top"> <td><?php _e('Free space', 'hyper-cache'); ?> </td> <td><?php echo $perc; ?> % -- <?php echo DUP_Util::ByteSize($space_free); ?> from <?php echo DUP_Util::ByteSize($space); ?> <br/> <small> <?php _e("Note: This value is the physical servers hard-drive allocation.", 'wpduplicator'); ?> <br/> <?php _e("On shared hosts check your control panel for the 'TRUE' disk space quota value.", 'wpduplicator'); ?> </small> </td> </tr> </table><br/>
/** * CREATE * Creates the zip file and adds the SQL file to the archive */ public static function Create(DUP_Archive $archive) { try { $timerAllStart = DUP_Util::GetMicrotime(); $package_zip_flush = DUP_Settings::Get('package_zip_flush'); self::$compressDir = rtrim(DUP_Util::SafePath($archive->PackDir), '/'); self::$sqlPath = DUP_Util::SafePath("{$archive->Package->StorePath}/{$archive->Package->Database->File}"); self::$zipPath = DUP_Util::SafePath("{$archive->Package->StorePath}/{$archive->File}"); self::$zipArchive = new ZipArchive(); self::$networkFlush = empty($package_zip_flush) ? false : $package_zip_flush; $filterDirs = empty($archive->FilterDirs) ? 'not set' : $archive->FilterDirs; $filterExts = empty($archive->FilterExts) ? 'not set' : $archive->FilterExts; $filterOn = $archive->FilterOn ? 'ON' : 'OFF'; //LOAD SCAN REPORT $json = file_get_contents(DUPLICATOR_SSDIR_PATH_TMP . "/{$archive->Package->NameHash}_scan.json"); self::$scanReport = json_decode($json); DUP_Log::Info("\n********************************************************************************"); DUP_Log::Info("ARCHIVE (ZIP):"); DUP_Log::Info("********************************************************************************"); $isZipOpen = self::$zipArchive->open(self::$zipPath, ZIPARCHIVE::CREATE) === TRUE; if (!$isZipOpen) { DUP_Log::Error("Cannot open zip file with PHP ZipArchive.", "Path location [" . self::$zipPath . "]"); } DUP_Log::Info("ARCHIVE DIR: " . self::$compressDir); DUP_Log::Info("ARCHIVE FILE: " . basename(self::$zipPath)); DUP_Log::Info("FILTERS: *{$filterOn}*"); DUP_Log::Info("DIRS: {$filterDirs}"); DUP_Log::Info("EXTS: {$filterExts}"); DUP_Log::Info("----------------------------------------"); DUP_Log::Info("COMPRESSING"); DUP_Log::Info("SIZE:\t" . self::$scanReport->ARC->Size); DUP_Log::Info("STATS:\tDirs " . self::$scanReport->ARC->DirCount . " | Files " . self::$scanReport->ARC->FileCount); //ADD SQL $isSQLInZip = self::$zipArchive->addFile(self::$sqlPath, "database.sql"); if ($isSQLInZip) { DUP_Log::Info("SQL ADDED: " . basename(self::$sqlPath)); } else { DUP_Log::Error("Unable to add database.sql to archive.", "SQL File Path [" . self::$sqlath . "]"); } self::$zipArchive->close(); self::$zipArchive->open(self::$zipPath, ZipArchive::CREATE); //ZIP DIRECTORIES foreach (self::$scanReport->ARC->Dirs as $dir) { if (self::$zipArchive->addEmptyDir(ltrim(str_replace(self::$compressDir, '', $dir), '/'))) { self::$countDirs++; } else { //Don't warn when dirtory is the root path if (strcmp($dir, rtrim(self::$compressDir, '/')) != 0) { DUP_Log::Info("WARNING: Unable to zip directory: '{$dir}'" . rtrim(self::$compressDir, '/')); } } } /* ZIP FILES: Network Flush * This allows the process to not timeout on fcgi * setups that need a response every X seconds */ if (self::$networkFlush) { foreach (self::$scanReport->ARC->Files as $file) { if (self::$zipArchive->addFile($file, ltrim(str_replace(self::$compressDir, '', $file), '/'))) { self::$limitItems++; self::$countFiles++; } else { DUP_Log::Info("WARNING: Unable to zip file: {$file}"); } //Trigger a flush to the web server after so many files have been loaded. if (self::$limitItems > DUPLICATOR_ZIP_FLUSH_TRIGGER) { $sumItems = self::$countDirs + self::$countFiles; self::$zipArchive->close(); self::$zipArchive->open(self::$zipPath); self::$limitItems = 0; DUP_Util::FcgiFlush(); DUP_Log::Info("Items archived [{$sumItems}] flushing response."); } } //Normal } else { foreach (self::$scanReport->ARC->Files as $file) { if (self::$zipArchive->addFile($file, ltrim(str_replace(self::$compressDir, '', $file), '/'))) { self::$countFiles++; } else { DUP_Log::Info("WARNING: Unable to zip file: {$file}"); } } } DUP_Log::Info(print_r(self::$zipArchive, true)); //-------------------------------- //LOG FINAL RESULTS DUP_Util::FcgiFlush(); $zipCloseResult = self::$zipArchive->close(); $zipCloseResult ? DUP_Log::Info("COMPRESSION RESULT: '{$zipCloseResult}'") : DUP_Log::Error("ZipArchive close failure.", "This hosted server may have a disk quota limit.\nCheck to make sure this archive file can be stored."); $timerAllEnd = DUP_Util::GetMicrotime(); $timerAllSum = DUP_Util::ElapsedTime($timerAllEnd, $timerAllStart); self::$zipFileSize = @filesize(self::$zipPath); DUP_Log::Info("COMPRESSED SIZE: " . DUP_Util::ByteSize(self::$zipFileSize)); DUP_Log::Info("ARCHIVE RUNTIME: {$timerAllSum}"); DUP_Log::Info("MEMORY STACK: " . DUP_Server::GetPHPMemory()); } catch (Exception $e) { DUP_Log::Error("Runtime error in package.archive.zip.php constructor.", "Exception: {$e}"); } }
/** * Get the database stats */ public function Stats() { global $wpdb; $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : null; $tblCount = 0; $tables = $wpdb->get_results("SHOW TABLE STATUS", ARRAY_A); $info = array(); $info['Status']['Success'] = is_null($tables) ? false : true; $info['Status']['Size'] = 'Good'; $info['Status']['Rows'] = 'Good'; $info['Size'] = 0; $info['Rows'] = 0; $info['TableCount'] = 0; $info['TableList'] = array(); //Only return what we really need foreach ($tables as $table) { $name = $table["Name"]; if ($this->FilterOn && is_array($filterTables)) { if (in_array($name, $filterTables)) { continue; } } $size = $table["Data_length"] + $table["Index_length"]; $info['Size'] += $size; $info['Rows'] += $table["Rows"]; $info['TableList'][$name]['Rows'] = empty($table["Rows"]) ? '0' : number_format($table["Rows"]); $info['TableList'][$name]['Size'] = DUP_Util::ByteSize($size); $tblCount++; } $info['Status']['Size'] = $info['Size'] > 100000000 ? 'Warn' : 'Good'; $info['Status']['Rows'] = $info['Rows'] > 1000000 ? 'Warn' : 'Good'; $info['TableCount'] = $tblCount; return $info; }
<button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_installer; ?> ', this);return false;"><i class="fa fa-bolt"></i> Installer</button> <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_archive; ?> ', this);return false;"><i class="fa fa-file-archive-o"></i> Archive - <?php echo $package->ZipSize; ?> </button> <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_sql; ?> ', this);return false;"><i class="fa fa-table"></i> SQL - <?php echo DUP_Util::ByteSize($package->Database->Size); ?> </button> <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_log; ?> ', this);return false;"><i class="fa fa-list-alt"></i> Log </button> <button class="button" onclick="Duplicator.Pack.ShowLinksDialog(<?php echo "'{$link_sql}','{$link_archive}','{$link_installer}','{$link_log}'"; ?> );" class="thickbox"><i class="fa fa-lock"></i> <?php _e("Share", 'duplicator'); ?> </button> <?php } else {
private function getFiles() { foreach ($this->Dirs as $key => $val) { foreach (glob("{$val}/{,.}*", GLOB_NOSORT | GLOB_BRACE) as $filePath) { $fileName = basename($filePath); $valid = true; if (!is_dir($filePath)) { if (!in_array(@pathinfo($filePath, PATHINFO_EXTENSION), $this->filterExtsArray) && is_readable($filePath)) { $fileSize = @filesize($filePath); $fileSize = empty($fileSize) ? 0 : $fileSize; if (strlen($filePath) > 250 || preg_match('/(\\/|\\*|\\?|\\>|\\<|\\:|\\|\\|)/', $fileName) || trim($fileName) == "") { array_push($this->WarnFileName, $filePath); $valid = false; } if ($fileSize > DUPLICATOR_SCAN_WARNFILESIZE) { array_push($this->WarnFileSize, $filePath . ' [' . DUP_Util::ByteSize($fileSize) . ']'); } if ($valid) { $this->Size += $fileSize; $this->Files[] = $filePath; } else { $this->OmitFiles[] = $filePath; } } else { $this->OmitFiles[] = $filePath; } } } } }
private function getFiles() { foreach ($this->Dirs as $key => $val) { $files = DUP_Util::ListFiles($val); foreach ($files as $filePath) { $fileName = basename($filePath); if (!is_dir($filePath)) { if (!in_array(@pathinfo($filePath, PATHINFO_EXTENSION), $this->FilterExtsAll)) { //Unreadable if (!is_readable($filePath)) { $this->FilterInfo->Files->Unreadable[] = $filePath; continue; } $fileSize = @filesize($filePath); $fileSize = empty($fileSize) ? 0 : $fileSize; $invalid_test = strlen($filePath) > 250 || preg_match('/(\\/|\\*|\\?|\\>|\\<|\\:|\\|\\|)/', $fileName) || trim($fileName) == ""; if ($invalid_test || preg_match('/[^\\x20-\\x7f]/', $fileName)) { $this->FilterInfo->Files->Warning[] = DUP_Encoding::toUTF8($filePath); } else { $this->Size += $fileSize; $this->Files[] = $filePath; } if ($fileSize > DUPLICATOR_SCAN_WARNFILESIZE) { $this->FilterInfo->Files->Size[] = $filePath . ' [' . DUP_Util::ByteSize($fileSize) . ']'; } } } } } }
} ?> <?php $totalSize = $totalSize + $pack_archive_size; $rowCount++; } ?> <tfoot> <tr> <th colspan="8" style='text-align:right; font-size:12px'> <?php echo _e("Packages", 'wpduplicator') . ': ' . $totalElements; ?> | <?php echo _e("Total Size", 'wpduplicator') . ': ' . DUP_Util::ByteSize($totalSize); ?> </th> </tr> </tfoot> </table> <?php } ?> </form> <!--form id="dup-paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank" style="display:none"> <input name="cmd" type="hidden" value="_s-xclick" />
<div class='dup-scan-info dup-info-box'> <b><?php DUP_Util::_e('Tables'); ?> :</b> <span id="data-db-tablecount"></span> | <b><?php DUP_Util::_e('Records'); ?> :</b> <span id="data-db-rows"></span> | <b><?php DUP_Util::_e('Size'); ?> :</b> <span id="data-db-size2"></span> <br/><br/> <?php $lnk = '<a href="maint/repair.php" target="_blank">' . DUP_Util::__('repair and optimization') . '</a>'; printf(DUP_Util::__('Total size and row count for all database tables are approximate values. The thresholds that trigger warnings are %1$s and %2$s records. Large databases take time to process and can cause issues with server timeout and memory settings. Running a %3$s on your database can also help improve the overall size and performance. If your server supports shell_exec and mysqldump you can try to enable this option from the settings menu.'), DUP_Util::ByteSize(DUPLICATOR_SCAN_DBSIZE), number_format(DUPLICATOR_SCAN_DBROWS), $lnk); ?> </div> </div> <!-- ============ TABLE DETAILS --> <div> <div class='dup-scan-title'> <a><?php DUP_Util::_e('Table Details'); ?> </a> <div id="data-db-status-size2"></div> </div> <div class='dup-scan-info dup-info-box'>
/** * Starts the package build process * @return DUP_Package */ public function Build() { global $wp_version; global $wpdb; global $current_user; $timerStart = DUP_Util::GetMicrotime(); $this->Archive->File = "{$this->NameHash}_archive.zip"; $this->Installer->File = "{$this->NameHash}_installer.php"; $this->Database->File = "{$this->NameHash}_database.sql"; //START LOGGING DUP_Log::Open($this->NameHash); $php_max_time = @ini_get("max_execution_time"); $php_max_memory = @ini_set('memory_limit', DUPLICATOR_PHP_MAX_MEMORY); $php_max_time = $php_max_time == 0 ? "(0) no time limit imposed" : "[{$php_max_time}] not allowed"; $php_max_memory = $php_max_memory === false ? "Unabled to set php memory_limit" : DUPLICATOR_PHP_MAX_MEMORY . " ({$php_max_memory} default)"; $info = "********************************************************************************\n"; $info .= "PACKAGE-LOG: " . @date("Y-m-d H:i:s") . "\n"; $info .= "NOTICE: Do NOT post to public sites or forums \n"; $info .= "********************************************************************************\n"; $info .= "VERSION:\t" . DUPLICATOR_VERSION . "\n"; $info .= "WORDPRESS:\t{$wp_version}\n"; $info .= "PHP INFO:\t" . phpversion() . ' | ' . 'SAPI: ' . php_sapi_name() . "\n"; $info .= "SERVER:\t\t{$_SERVER['SERVER_SOFTWARE']} \n"; $info .= "PHP TIME LIMIT: {$php_max_time} \n"; $info .= "PHP MAX MEMORY: {$php_max_memory}"; DUP_Log::Info($info); unset($info); //CREATE DB RECORD $packageObj = serialize($this); if (!$packageObj) { DUP_Log::Error("Unable to serialize pacakge object while building record."); } $this->ID = $this->FindHashKey($this->Hash); if ($this->ID != 0) { $this->SetStatus(DUP_PackageStatus::START); } else { $results = $wpdb->insert($wpdb->prefix . "duplicator_packages", array('name' => $this->Name, 'hash' => $this->Hash, 'status' => DUP_PackageStatus::START, 'created' => current_time('mysql', get_option('gmt_offset', 1)), 'owner' => isset($current_user->user_login) ? $current_user->user_login : '******', 'package' => $packageObj)); if ($results == false) { $error_result = $wpdb->print_error(); DUP_Log::Error("Unable to insert record into database table.", "'{$error_result}'"); } $this->ID = $wpdb->insert_id; } //START BUILD //PHPs serialze method will return the object but the ID above is not passed //for one reason or another so passing the object back in seems to do the trick $this->Database->Build($this); $this->Archive->Build($this); $this->Installer->Build($this); //VALIDATE FILE SIZE $dbSizeRead = DUP_Util::ByteSize($this->Database->Size); $zipSizeRead = DUP_Util::ByteSize($this->Archive->Size); $exeSizeRead = DUP_Util::ByteSize($this->Installer->Size); if (!($this->Archive->Size && $this->Database->Size && $this->Installer->Size)) { DUP_Log::Error("A required file contains zero bytes.", "Archive Size: {$zipSizeRead} | SQL Size: {$dbSizeRead} | Installer Size: {$exeSizeRead}"); } $this->SetStatus(DUP_PackageStatus::COMPLETE); $timerEnd = DUP_Util::GetMicrotime(); $timerSum = DUP_Util::ElapsedTime($timerEnd, $timerStart); $this->Runtime = $timerSum; $this->ExeSize = $exeSizeRead; $this->ZipSize = $zipSizeRead; $this->buildCleanup(); $info = "\n********************************************************************************\n"; $info .= "RECORD ID:[{$this->ID}]\n"; $info .= "FILE SIZE: Archive:{$zipSizeRead} | SQL:{$dbSizeRead} | Installer:{$exeSizeRead}\n"; $info .= "TOTAL PROCESS RUNTIME: {$timerSum}\n"; $info .= "DONE PROCESSING => {$this->Name} " . @date("Y-m-d H:i:s") . "\n"; $info .= "********************************************************************************\n"; DUP_Log::Info($info); DUP_Log::Close(); return $this; }
/** * Get PHP memory useage * @return string Returns human readable memory useage. */ public static function GetPHPMemory($peak = false) { if ($peak) { $result = 'Unable to read PHP peak memory usage'; if (function_exists('memory_get_peak_usage')) { $result = DUP_Util::ByteSize(memory_get_peak_usage(true)); } } else { $result = 'Unable to read PHP memory usage'; if (function_exists('memory_get_usage')) { $result = DUP_Util::ByteSize(memory_get_usage(true)); } } return $result; }
/** * CREATE * Creates the zip file and adds the SQL file to the archive */ public static function Create(DUP_Archive $archive) { try { $timerAllStart = DUP_Util::GetMicrotime(); $package_zip_flush = DUP_Settings::Get('package_zip_flush'); self::$compressDir = rtrim(DUP_Util::SafePath($archive->PackDir), '/'); self::$filterDirsArray = array_map('DUP_Util::SafePath', explode(";", $archive->FilterDirs, -1)); self::$filterDirsList = $archive->FilterDirs; self::$filterExtsArray = explode(";", $archive->FilterExts, -1); self::$filterExtsList = $archive->FilterExts; self::$filterOn = $archive->FilterOn; self::$sqlPath = DUP_Util::SafePath("{$archive->Package->StorePath}/{$archive->Package->Database->File}"); self::$zipPath = DUP_Util::SafePath("{$archive->Package->StorePath}/{$archive->File}"); self::$zipArchive = new ZipArchive(); self::$filterDirsOn = count(self::$filterDirsArray); self::$filterExtsOn = count(self::$filterExtsArray); self::$networkFlush = empty($package_zip_flush) ? false : $package_zip_flush; DUP_Log::Info("\n********************************************************************************"); DUP_Log::Info("ARCHIVE (ZIP):"); DUP_Log::Info("********************************************************************************"); DUP_Log::Info("ARCHIVE DIR: " . self::$compressDir); DUP_Log::Info("ARCHIVE FILE: " . basename(self::$zipPath)); DUP_Log::Info("FILTER DIRS: " . self::$filterDirsList); DUP_Log::Info("FILTER EXTS: " . self::$filterExtsList); //-------------------------------- //OPEN ZIP $isZipOpen = self::$zipArchive->open(self::$zipPath, ZIPARCHIVE::CREATE) === TRUE; if (!$isZipOpen) { DUP_Log::Error("Cannot open zip file with PHP ZipArchive.", "Path location [" . self::$zipPath . "]"); } //-------------------------------- //ADD FILES DUP_Log::Info("----------------------------------------"); DUP_Log::Info("SCANNING"); $timerFilesStart = DUP_Util::GetMicrotime(); if (self::$filterOn && (self::$filterDirsOn || self::$filterExtsOn)) { DUP_Log::Info("FILTERS *ON*"); !in_array(self::$compressDir, self::$filterDirsArray) ? self::recurseDirsWithFilters(self::$compressDir) : DUP_Log::Info("-filter@[" . self::$compressDir . "]"); } else { DUP_Log::Info("FILTERS *OFF*"); self::recurseDirs(self::$compressDir); } $timerFilesEnd = DUP_Util::GetMicrotime(); $timerFilesSum = DUP_Util::ElapsedTime($timerFilesEnd, $timerFilesStart); DUP_Log::Info("STATS:\tDirs " . self::$countDirs . " | Files " . self::$countFiles . " | Links " . self::$countLinks); DUP_Log::Info("SIZE:\t" . DUP_Util::ByteSize(self::$size)); DUP_Log::Info("TIME:\t{$timerFilesSum}"); DUP_Log::Info("----------------------------------------"); DUP_Log::Info("COMPRESSING"); //-------------------------------- //ADD SQL $isSQLInZip = self::$zipArchive->addFile(self::$sqlPath, "database.sql"); if ($isSQLInZip) { DUP_Log::Info("SQL ADDED: " . basename(self::$sqlPath)); } else { DUP_Log::Error("Unable to add database.sql file to archive.", "SQL File Path [" . self::$sqlath . "]"); } self::$zipArchive->close(); self::$zipArchive->open(self::$zipPath, ZipArchive::CREATE); DUP_Log::Info(print_r(self::$zipArchive, true)); //-------------------------------- //LOG FINAL RESULTS DUP_Util::FcgiFlush(); $zipCloseResult = self::$zipArchive->close(); $zipCloseResult ? DUP_Log::Info("COMPRESSION RESULT: '{$zipCloseResult}'") : DUP_Log::Error("ZipArchive close failure.", "This hosted server may have a disk quota limit.\nCheck to make sure this archive file can be stored."); $timerAllEnd = DUP_Util::GetMicrotime(); $timerAllSum = DUP_Util::ElapsedTime($timerAllEnd, $timerAllStart); self::$zipFileSize = @filesize(self::$zipPath); DUP_Log::Info("COMPRESSED SIZE: " . DUP_Util::ByteSize(self::$zipFileSize)); DUP_Log::Info("ARCHIVE RUNTIME: {$timerAllSum}"); } catch (Exception $e) { DUP_Log::Error("Runtime error in package.archive.zip.php constructor.", "Exception: {$e}"); } }
private function runDirStats($directory) { $currentPath = DUP_Util::SafePath($directory); //EXCLUDE: Snapshot directory if (strstr($currentPath, DUPLICATOR_SSDIR_PATH) || empty($currentPath)) { return; } $dh = new DirectoryIterator($currentPath); foreach ($dh as $file) { if (!$file->isDot()) { $nextpath = "{$currentPath}/{$file}"; if ($file->isDir()) { if (!in_array($nextpath, $this->filterDirsArray)) { if (preg_match('/(\\/|\\*|\\?|\\>|\\<|\\:|\\|\\|)/', $file) || trim($file) == "") { array_push($this->InvalidFileList, $nextpath); } $result = $this->runDirStats($nextpath); $this->DirCount++; } } else { if ($file->isFile() && $file->isReadable()) { if (!in_array(@pathinfo($nextpath, PATHINFO_EXTENSION), $this->filterExtsArray)) { $fileSize = filesize($nextpath); $fileSize = $fileSize ? $fileSize : 0; $this->Size += $fileSize; $this->FileCount++; if (strlen($nextpath) > 200 || preg_match('/(\\/|\\*|\\?|\\>|\\<|\\:|\\|\\|)/', $file)) { array_push($this->InvalidFileList, $nextpath); } if ($fileSize > DUPLICATOR_SCAN_BIGFILE) { array_push($this->BigFileList, $nextpath . ' [' . DUP_Util::ByteSize($fileSize) . ']'); } } } else { if ($file->isLink()) { $this->LinkCount++; } } } } } @closedir($dh); }
<!-- ============ TABLE DETAILS --> <div> <div class='dup-scan-title'> <a><?php _e('Table Details', 'duplicator'); ?> </a> <div id="data-db-status-details"></div> </div> <div class='dup-scan-info dup-info-box'> <?php //OVERVIEW echo '<b>' . __('Overview:', 'duplicator') . '</b><br/>'; printf(__('The thresholds that trigger warnings for individual tables are %1$s OR %2$s records OR tables names with upper-case characters. The larger the table the more time it takes to process and execute. This can cause issues with budget hosts that have cpu/memory limits, and timeout constraints.', 'duplicator'), DUP_Util::ByteSize(DUPLICATOR_SCAN_DB_TBL_SIZE), number_format(DUPLICATOR_SCAN_DB_TBL_ROWS)); //OPTIONS echo '<br/><br/>'; echo '<b>' . __('Options:', 'duplicator') . '</b><br/>'; $lnk = '<a href="maint/repair.php" target="_blank">' . __('Repair and Optimization', 'duplicator') . '</a>'; printf(__('1. Run a %1$s on the table to improve the overall size and performance.', 'duplicator'), $lnk); echo '<br/><br/>'; _e('2. Remove stale date from tables such as logging, statistical or other non-critical data.', 'duplicator'); echo '<br/><br/>'; $lnk = '<a href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_lower_case_table_names" target="_blank">' . __('lower_case_table_names', 'duplicator') . '</a>'; printf(__('3. For table name case sensitivity issues either rename the table with lower case characters or be prepared to work with the %1$s system variable setting.', 'duplicator'), $lnk); echo '<br/><br/>'; echo '<b>' . __('Tables:', 'duplicator') . '</b><br/>'; ?>
/** * Get the database stats */ public function Stats() { global $wpdb; $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : null; $tblCount = 0; $tables = $wpdb->get_results("SHOW TABLE STATUS", ARRAY_A); $info = array(); $info['Status']['Success'] = is_null($tables) ? false : true; //DB_Case for the database name is never checked on $info['Status']['DB_Case'] = 'Good'; $info['Status']['DB_Rows'] = 'Good'; $info['Status']['DB_Size'] = 'Good'; $info['Status']['TBL_Case'] = 'Good'; $info['Status']['TBL_Rows'] = 'Good'; $info['Status']['TBL_Size'] = 'Good'; $info['Size'] = 0; $info['Rows'] = 0; $info['TableCount'] = 0; $info['TableList'] = array(); $tblCaseFound = 0; $tblRowsFound = 0; $tblSizeFound = 0; //Grab Table Stats foreach ($tables as $table) { $name = $table["Name"]; if ($this->FilterOn && is_array($filterTables)) { if (in_array($name, $filterTables)) { continue; } } $size = $table["Data_length"] + $table["Index_length"]; $rows = empty($table["Rows"]) ? '0' : $table["Rows"]; $info['Size'] += $size; $info['Rows'] += $table["Rows"]; $info['TableList'][$name]['Case'] = preg_match('/[A-Z]/', $name) ? 1 : 0; $info['TableList'][$name]['Rows'] = number_format($rows); $info['TableList'][$name]['Size'] = DUP_Util::ByteSize($size); $tblCount++; //Table Uppercase if ($info['TableList'][$name]['Case']) { if (!$tblCaseFound) { $tblCaseFound = 1; } } //Table Row Count if ($rows > DUPLICATOR_SCAN_DB_TBL_ROWS) { if (!$tblRowsFound) { $tblRowsFound = 1; } } //Table Size if ($size > DUPLICATOR_SCAN_DB_TBL_SIZE) { if (!$tblSizeFound) { $tblSizeFound = 1; } } } $info['Status']['DB_Case'] = preg_match('/[A-Z]/', $wpdb->dbname) ? 'Warn' : 'Good'; $info['Status']['DB_Rows'] = $info['Rows'] > DUPLICATOR_SCAN_DB_ALL_ROWS ? 'Warn' : 'Good'; $info['Status']['DB_Size'] = $info['Size'] > DUPLICATOR_SCAN_DB_ALL_SIZE ? 'Warn' : 'Good'; $info['Status']['TBL_Case'] = $tblCaseFound ? 'Warn' : 'Good'; $info['Status']['TBL_Rows'] = $tblRowsFound ? 'Warn' : 'Good'; $info['Status']['TBL_Size'] = $tblSizeFound ? 'Warn' : 'Good'; $info['Size'] = DUP_Util::ByteSize($info['Size']) or "unknown"; $info['Rows'] = number_format($info['Rows']) or "unknown"; $info['TableList'] = $info['TableList'] or "unknown"; $info['TableCount'] = $tblCount; return $info; }