/** * DUPLICATOR ZIP * Creates the zip file * * @param string $zipFilePath The full path to the zip file that will be made * @param string $folderPath The folder that will be zipped * @param string $sqlfilepath The path to the database file to include in the package */ function __construct($zipFilePath, $folderPath, $sqlfilepath) { try { $time_start = DuplicatorUtils::GetMicrotime(); duplicator_log("ARCHIVE FOLDER: {$folderPath}"); duplicator_log("ARCHIVE FILE: {$zipFilePath}"); $this->zipArchive = new ZipArchive(); $this->zipFilePath = duplicator_safe_path($zipFilePath); $this->rootFolder = rtrim(duplicator_safe_path($folderPath), '/'); $this->skipNames = $GLOBALS['duplicator_skip_ext-array']; $exts_list = implode(";", $this->skipNames); $path_list = implode(";", $GLOBALS['duplicator_bypass-array']); duplicator_log("FILTER EXTENSIONS: '{$exts_list}'"); duplicator_log("FILTER DIRECTORIES: '{$path_list}'"); duplicator_log($GLOBALS['DUPLICATOR_SEPERATOR2']); if ($this->zipArchive->open($this->zipFilePath, ZIPARCHIVE::CREATE) === TRUE) { duplicator_log("ZIPARCHIVE OPENED"); } else { $err = "CANNOT OPEN <{$this->zipFilePath}>"; duplicator_log($err); throw new Exception($err); } //ADD SQL File $sql_in_zip = $this->zipArchive->addFile($sqlfilepath, "/database.sql"); if ($sql_in_zip) { duplicator_log("DATABASE.SQL ADDED TO ZIP: {$sqlfilepath}"); } else { duplicator_log("{$GLOBALS['DUPLICATOR_SEPERATOR1']}\nERROR: Unable to add database.sql file to package from {$sqlfilepath} \n{$GLOBALS['DUPLICATOR_SEPERATOR1']}"); } //RECURSIVE CALL TO ALL FILES $this->resursiveZip($this->rootFolder); //LOG FINAL RESULTS duplicator_log("ARCHIVE INFO: " . print_r($this->zipArchive, true)); $zip_close_result = $this->zipArchive->close(); $status_msg = $zip_close_result ? "CLOSE RETURNED: '{$zip_close_result}'" : "{$GLOBALS['DUPLICATOR_SEPERATOR1']}\nWARNING: ZipArchive Class did not close successfully. This means you most likely have a disk quota issue on your server.\nPlease check your disk space usage to make sure you can store this zip file successfully.\n{$GLOBALS['DUPLICATOR_SEPERATOR1']}"; duplicator_log($status_msg); $time_end = DuplicatorUtils::GetMicrotime(); $time_sum = DuplicatorUtils::ElapsedTime($time_end, $time_start); duplicator_log("ZIP TOTAL RUNTIME: {$time_sum}"); } catch (Exception $e) { duplicator_log("LOG:CLASS.ZIP=>RUNTIME ERROR: " . $e); } }
/** * DUPLICATOR_CREATE * Creates the zip file, database entry, and installer file for the * new culmination of a 'Package Set' * * @return string A message about the action * - log:act__create=>done */ function duplicator_create() { global $wp_version; global $wpdb; global $current_user; $error_level = error_reporting(); error_reporting(E_ERROR); $fulltime_start = DuplicatorUtils::GetMicrotime(); $packname = isset($_POST['package_name']) ? trim($_POST['package_name']) : null; $secure_token = uniqid() . mt_rand(1000, 9999); $uniquename = "{$secure_token}_{$packname}"; foreach (glob(DUPLICATOR_SSDIR_PATH . '/*.log') as $log_file) { @unlink($log_file); } $logfilename = "{$uniquename}.log"; $GLOBALS['duplicator_package_log_handle'] = @fopen(DUPLICATOR_SSDIR_PATH . "/{$logfilename}", "c+"); duplicator_log("********************************************************************************"); duplicator_log("PACKAGE-LOG: " . @date('h:i:s')); duplicator_log("NOTICE: Do not post to public sites or forums"); duplicator_log("********************************************************************************"); duplicator_log("duplicator: " . DUPLICATOR_VERSION); duplicator_log("wordpress: {$wp_version}"); duplicator_log("php: " . phpversion()); duplicator_log("php sapi: " . php_sapi_name()); duplicator_log("server: {$_SERVER['SERVER_SOFTWARE']}"); duplicator_log("browser: {$_SERVER['HTTP_USER_AGENT']}"); duplicator_log("package name: {$packname}"); if ($packname) { $php_max_time = @ini_set("max_execution_time", DUPLICATOR_PHP_MAX_TIME); $php_max_memory = @ini_set('memory_limit', DUPLICATOR_PHP_MAX_MEMORY); $php_max_time = $php_max_time === false ? "Unabled to set php max_execution_time" : "from={$php_max_time} to=" . DUPLICATOR_PHP_MAX_TIME; $php_max_memory = $php_max_memory === false ? "Unabled to set php memory_limit" : "from={$php_max_memory} to=" . DUPLICATOR_PHP_MAX_MEMORY; @set_time_limit(0); duplicator_log("php_max_time: {$php_max_time}"); duplicator_log("php_max_memory: {$php_max_memory}"); duplicator_log("mysql wait_timeout:" . DUPLICATOR_PHP_MAX_TIME); $zipfilename = "{$uniquename}_package.zip"; $sqlfilename = "{$uniquename}_database.sql"; $exefilename = "{$uniquename}_installer.php"; $zipfilepath = DUPLICATOR_SSDIR_PATH . "/{$zipfilename}"; $sqlfilepath = DUPLICATOR_SSDIR_PATH . "/{$sqlfilename}"; $exefilepath = DUPLICATOR_SSDIR_PATH . "/{$exefilename}"; $zipsize = 0; $wpdb->query("SET session wait_timeout = " . DUPLICATOR_DB_MAX_TIME); duplicator_log("********************************************************************************"); duplicator_log("SQL SCRIPT"); duplicator_log("********************************************************************************"); duplicator_create_dbscript($sqlfilepath); //CREATE ZIP ARCHIVE duplicator_log("********************************************************************************"); duplicator_log("ZIP ARCHIVE:"); duplicator_log("********************************************************************************"); $zip = new Duplicator_Zip($zipfilepath, rtrim(DUPLICATOR_WPROOTPATH, '/'), $sqlfilepath); $zipsize = filesize($zipfilepath); $zipsize == false ? duplicator_log("WARNING: ZIPSIZE IS UNKNOWN.") : duplicator_log("ZIP FILE SIZE: " . duplicator_bytesize($zipsize)); //Serlized settings $settings = array('plugin_version' => DUPLICATOR_VERSION, 'type' => 'Manual'); $serialized_settings = serialize($settings); //Record archive info to database $results = $wpdb->insert($wpdb->prefix . "duplicator", array('token' => $secure_token, 'packname' => $packname, 'zipname' => $zipfilename, 'zipsize' => $zipsize, 'created' => current_time('mysql', get_option('gmt_offset')), 'owner' => $current_user->user_login, 'settings' => "{$serialized_settings}")); if ($wpdb->insert_id) { duplicator_log("RECORDED ARCHIVE ID: " . $wpdb->insert_id); } else { duplicator_log("WARNING: UNABLE TO RECORD TO DATABASE"); } $wpdb->flush(); //UPDATE INSTALL FILE duplicator_log("********************************************************************************"); duplicator_log("FINALIZATION ROUTINES:"); duplicator_log("********************************************************************************"); duplicator_build_installerFile(); duplicator_create_installerFile($uniquename); //SEND EMAIL //TODO: Send only SQL File via mail. Zip files can get too large if ($GLOBALS['duplicator_opts']['email-me'] == "1") { duplicator_log("log:act__create=>email started"); $status = $zipsize ? 'Success' : 'Failure'; $attachments = ""; //array(DUPLICATOR_SSDIR_PATH . '/' . $packname .'.zip'); $headers = 'From: Duplicator Plugin <*****@*****.**>' . "\r\n"; $subject = "Package '{$packname}' completed"; $message = "Run Status: {$status}\n\rSite Name: " . get_bloginfo('name') . "\n\rPackage Name: {$packname} \n\rCompleted at: " . current_time('mysql', get_option('gmt_offset')); wp_mail($current_user->user_email, $subject, $message, $headers, $attachments); duplicator_log("log:act__create=>sent email to: {$current_user->user_email}"); $other_emails = @preg_split("/[,;]/", $GLOBALS['duplicator_opts']['email_others']); if (count($other_emails)) { wp_mail($other_emails, $subject, $message, $headers, $attachments); duplicator_log("log:act__create=>other emails sent: {$GLOBALS['duplicator_opts']['email_others']}"); } duplicator_log("log:act__create=>email finished"); } } $fulltime_end = DuplicatorUtils::GetMicrotime(); $fulltime_sum = DuplicatorUtils::ElapsedTime($fulltime_end, $fulltime_start); duplicator_log("COMPLETE PACKAGE RUNTIME: {$fulltime_sum}"); duplicator_log("********************************************************************************"); duplicator_log("DONE PROCESSING => {$packname} " . @date('h:i:s')); duplicator_log("********************************************************************************"); @fclose($GLOBALS['duplicator_package_log_handle']); error_reporting($error_level); die; }
/** * DUPLICATOR_CREATE_DBSCRIPT * Create the SQL DataDump File * @param string $destination The full path and filname where the sql script will be written */ function duplicator_create_dbscript($destination) { try { global $wpdb; $time_start = DuplicatorUtils::GetMicrotime(); $handle = fopen($destination, 'w+'); $tables = $wpdb->get_col('SHOW TABLES'); $sql_header = "/* DUPLICATOR MYSQL SCRIPT CREATED ON : " . @date("F j, Y, g:i a") . " */\n\n"; $sql_header .= "SET FOREIGN_KEY_CHECKS = 0;\n\n"; @fwrite($handle, $sql_header); //BUILD CREATES: //All creates must be created before inserts do to foreign key constraints foreach ($tables as $table) { //$sql_del = ($GLOBALS['duplicator_opts']['dbadd_drop']) ? "DROP TABLE IF EXISTS {$table};\n\n" : ""; //@fwrite($handle, $sql_del); $create = $wpdb->get_row("SHOW CREATE TABLE `{$table}`", ARRAY_N); @fwrite($handle, "{$create[1]};\n\n"); } //BUILD INSERTS: //Create Insert in 100 row increments to better handle memory foreach ($tables as $table) { $row_count = $wpdb->get_var("SELECT Count(*) FROM `{$table}`"); duplicator_log("{$table} ({$row_count})"); if ($row_count > 100) { $row_count = ceil($row_count / 100); } else { if ($row_count > 0) { $row_count = 1; } } if ($row_count >= 1) { @fwrite($handle, "\n/* INSERT TABLE DATA: {$table} */\n"); } for ($i = 0; $i < $row_count; $i++) { $sql = ""; $limit = $i * 100; $query = "SELECT * FROM `{$table}` LIMIT {$limit}, 100"; $rows = $wpdb->get_results($query, ARRAY_A); if (is_array($rows)) { foreach ($rows as $row) { $sql .= "INSERT INTO `{$table}` VALUES("; $num_values = count($row); $num_counter = 1; foreach ($row as $value) { if (is_null($value) || !isset($value)) { $num_values == $num_counter ? $sql .= 'NULL' : ($sql .= 'NULL, '); } else { $num_values == $num_counter ? $sql .= '"' . @mysql_real_escape_string($value) . '"' : ($sql .= '"' . @mysql_real_escape_string($value) . '", '); } $num_counter++; } $sql .= ");\n"; } @fwrite($handle, $sql); duplicator_fcgi_flush(); } } } unset($sql); $sql_footer = "\nSET FOREIGN_KEY_CHECKS = 1;"; @fwrite($handle, $sql_footer); duplicator_log("SQL CREATED: {$destination}"); fclose($handle); $wpdb->flush(); $time_end = DuplicatorUtils::GetMicrotime(); $time_sum = DuplicatorUtils::ElapsedTime($time_end, $time_start); $sql_file_size = filesize($destination); if ($sql_file_size <= 0) { duplicator_error("ERROR: SQL file generated zero bytes. \nERROR INFO: No data was written to the sql file. Check permission on file and parent directory at [{$destination}]"); } duplicator_log("SQL FILE SIZE: " . duplicator_bytesize($sql_file_size)); duplicator_log("SQL RUNTIME: {$time_sum}"); } catch (Exception $e) { duplicator_error("ERROR: Runtime error in duplicator_create_dbscript \nERROR INFO: '{$e}'"); } }
/** * DUPLICATOR ZIP * Creates the zip file * * @param string $zipFilePath The full path to the zip file that will be made * @param string $folderPath The folder that will be zipped * @param string $sqlfilepath The path to the database file to include in the package */ function __construct($zipFilePath, $folderPath, $sqlfilepath) { try { $total_time_start = DuplicatorUtils::GetMicrotime(); duplicator_log("PACKAGE DIR: {$folderPath}"); duplicator_log("PACKAGE FILE: {$zipFilePath}"); $this->zipArchive = new ZipArchive(); $this->zipFilePath = duplicator_safe_path($zipFilePath); $this->rootFolder = rtrim(duplicator_safe_path($folderPath), '/'); $this->skipNames = $GLOBALS['duplicator_skip_ext-array']; $this->countDirs = 0; $this->countFiles = 0; $this->countLinks = 0; $exts_list = implode(";", $this->skipNames); $path_list = implode(";", $GLOBALS['duplicator_bypass-array']); $this->fileExtActive = strlen($exts_list); duplicator_log("FILTER EXTENSIONS: '{$exts_list}'"); duplicator_log("FILTER DIRECTORIES: '{$path_list}'"); duplicator_log($GLOBALS['DUPLICATOR_SEPERATOR2']); //CREATE ZIP FILE if ($this->zipArchive->open($this->zipFilePath, ZIPARCHIVE::CREATE) === TRUE) { duplicator_log("STARTING PACKAGE BUILD"); } else { duplicator_error("ERROR: Cannot open zip file with PHP ZipArchive. \nERROR INFO: Path location [{$this->zipFilePath}]"); } //ADD SQL File $sql_in_zip = $this->zipArchive->addFile($sqlfilepath, "/database.sql"); if ($sql_in_zip) { duplicator_log("ADDED=>SQL: {$sqlfilepath}"); } else { duplicator_error("ERROR: Unable to add database.sql file to package from. \nERROR INFO: SQL File Path [{$sqlfilepath}]"); } //RECURSIVE CALL TO ALL FILES $list_time_start = DuplicatorUtils::GetMicrotime(); duplicator_log("BUILDING FILE LIST"); $this->resursiveZip($this->rootFolder); $list_time_end = DuplicatorUtils::GetMicrotime(); $list_time_sum = DuplicatorUtils::ElapsedTime($list_time_end, $list_time_start); duplicator_log("FILE LIST COMPLETE: {$list_time_sum}"); duplicator_log("FILE LIST STATS: Dirs {$this->countDirs} | Files {$this->countFiles} | Links {$this->countLinks} | "); duplicator_log("\nPACKAGE INFO: " . print_r($this->zipArchive, true)); //LOG FINAL RESULTS duplicator_log("CREATING PACKAGE"); duplicator_fcgi_flush(); @set_time_limit(0); $zip_close_result = $this->zipArchive->close(); if ($zip_close_result) { duplicator_log("CLOSING PACKAGE RESULT: '{$zip_close_result}'"); } else { $err_info = 'This server or hosted segement might have a disk quota limit.\\nPlease check your disk space usage to make sure you can store this zip file successfully.'; duplicator_error("ERROR: ZipArchive Class did not close successfully. \nERROR INFO: {$err_info}"); } $total_time_end = DuplicatorUtils::GetMicrotime(); $total_time_sum = DuplicatorUtils::ElapsedTime($total_time_end, $total_time_start); $this->zipFileSize = @filesize($this->zipFilePath); duplicator_log("PACKAGE FILE SIZE: " . duplicator_bytesize($this->zipFileSize)); duplicator_log("PACKAGE RUNTIME: {$total_time_sum}"); } catch (Exception $e) { duplicator_error("ERROR: Runtime error in class.zip.php constructor. \nERROR INFO: {$e}"); } }
/** * DUPLICATOR_CREATE * Creates the zip file, database entry, and installer file for the * new culmination of a 'Package Set' * * @return string A message/waring/error about the action */ function duplicator_create() { global $wp_version; global $wpdb; global $current_user; //post data un-stripped, as WP magic quotes _POST for some reason... $post = stripslashes_deep($_POST); $error_level = error_reporting(); error_reporting(E_ERROR); $fulltime_start = DuplicatorUtils::GetMicrotime(); $packname = isset($post['package_name']) ? trim($post['package_name']) : 'package'; $packnotes = isset($post['package_notes']) ? trim(esc_html($post['package_notes'])) : ''; $secure_token = uniqid() . mt_rand(1000, 9999); $uniquename = "{$secure_token}_{$packname}"; $logfilename = "{$uniquename}.log"; $table_id = null; $GLOBALS['duplicator_package_log_handle'] = @fopen(DUPLICATOR_SSDIR_PATH . "/{$logfilename}", "c+"); duplicator_log("********************************************************************************"); duplicator_log("PACKAGE-LOG: " . @date('h:i:s')); duplicator_log("NOTICE: Do not post to public sites or forums"); duplicator_log("********************************************************************************"); duplicator_log("duplicator: " . DUPLICATOR_VERSION); duplicator_log("wordpress: {$wp_version}"); duplicator_log("php: " . phpversion()); duplicator_log("php sapi: " . php_sapi_name()); duplicator_log("server: {$_SERVER['SERVER_SOFTWARE']}"); duplicator_log("browser: {$_SERVER['HTTP_USER_AGENT']}"); duplicator_log("package name: {$packname}"); $php_max_time = @ini_set("max_execution_time", DUPLICATOR_PHP_MAX_TIME); $php_max_memory = @ini_set('memory_limit', DUPLICATOR_PHP_MAX_MEMORY); $php_max_time = $php_max_time === false ? "Unabled to set php max_execution_time" : "set from={$php_max_time} to=" . DUPLICATOR_PHP_MAX_TIME; $php_max_memory = $php_max_memory === false ? "Unabled to set php memory_limit" : "set from={$php_max_memory} to=" . DUPLICATOR_PHP_MAX_MEMORY; duplicator_log("php_max_time: {$php_max_time}"); duplicator_log("php_max_memory: {$php_max_memory}"); duplicator_log("mysql wait_timeout:" . DUPLICATOR_PHP_MAX_TIME); $zipfilename = "{$uniquename}_package.zip"; $sqlfilename = "{$uniquename}_database.sql"; $exefilename = "{$uniquename}_installer.php"; $zipfilepath = DUPLICATOR_SSDIR_PATH . "/{$zipfilename}"; $sqlfilepath = DUPLICATOR_SSDIR_PATH . "/{$sqlfilename}"; $exefilepath = DUPLICATOR_SSDIR_PATH . "/{$exefilename}"; @set_time_limit(0); $wpdb->query("SET session wait_timeout = " . DUPLICATOR_DB_MAX_TIME); //===================================================== //START: RECORD TRANSACTION $pack_settings = serialize(array('plugin_version' => DUPLICATOR_VERSION, 'type' => 'Manual', 'status' => 'Error', 'notes' => "{$packnotes}")); $results = $wpdb->insert($wpdb->prefix . "duplicator", array('token' => $secure_token, 'packname' => $packname, 'zipname' => $zipfilename, 'zipsize' => 0, 'created' => current_time('mysql', get_option('gmt_offset')), 'owner' => $current_user->user_login, 'settings' => "{$pack_settings}")); if ($wpdb->insert_id) { duplicator_log("recorded table id: " . $wpdb->insert_id); $table_id = $wpdb->insert_id; } else { $error_result = $wpdb->print_error(); duplicator_error("ERROR: Unable to insert into database table. \nERROR INFO: '{$error_result}'"); } duplicator_log("********************************************************************************"); duplicator_log("BUILD SQL SCRIPT:"); duplicator_log("********************************************************************************"); duplicator_create_dbscript($sqlfilepath); duplicator_log("********************************************************************************"); duplicator_log("BUILD ZIP PACKAGE:"); duplicator_log("********************************************************************************"); $zip = new Duplicator_Zip($zipfilepath, rtrim(DUPLICATOR_WPROOTPATH, '/'), $sqlfilepath); duplicator_log("********************************************************************************"); duplicator_log("BUILD INSTALLER FILE:"); duplicator_log("********************************************************************************"); duplicator_build_installerFile(); duplicator_create_installerFile($uniquename, $table_id); //VALIDATE FILE SIZE $zip_filesize = @filesize($zipfilepath); $sql_filesize = @filesize($sqlfilepath); $exe_filesize = @filesize($exefilepath); $zip_basicsize = duplicator_bytesize($zip_filesize); $sql_basicsize = duplicator_bytesize($sql_filesize); $exe_basicsize = duplicator_bytesize($exe_filesize); if ($zip_filesize && $sql_filesize && $sql_filesize) { $msg_complete_stats = "FILE SIZE: Zip:{$zip_basicsize} | SQL:{$sql_basicsize} | Installer:{$exe_basicsize}"; } else { duplicator_error("ERROR: A required file contains zero bytes. \nERROR INFO: Zip Size:{$zip_basicsize} | SQL Size:{$sql_basicsize} | Installer Size:{$exe_basicsize}"); } //SEND EMAIL //TODO: Send only SQL File via mail. Zip files can get too large if ($GLOBALS['duplicator_opts']['email-me'] == "1") { duplicator_log("---------------------------------"); duplicator_log("SENDING EMAIL"); $status = $zip->zipFileSize ? 'Success' : 'Failure'; $attachments = ""; //array(DUPLICATOR_SSDIR_PATH . '/' . $packname .'.zip'); $headers = 'From: Duplicator Plugin <*****@*****.**>' . "\r\n"; $subject = "Package '{$packname}' completed"; $message = "Run Status: {$status}\n\rSite Name: " . get_bloginfo('name') . "\n\rPackage Name: {$packname} \n\rCompleted at: " . current_time('mysql', get_option('gmt_offset')); $result = wp_mail($current_user->user_email, $subject, $message, $headers, $attachments); duplicator_log("EMAIL SENT TO: {$current_user->user_email}"); duplicator_log("EMAIL SEND STATUS: {$result}"); $other_emails = @preg_split("/[,;]/", $GLOBALS['duplicator_opts']['email_others']); if (count($other_emails)) { $result = wp_mail($other_emails, $subject, $message, $headers, $attachments); duplicator_log("OTHER EMAILS SENT: {$GLOBALS['duplicator_opts']['email_others']}"); duplicator_log("OTHER EMAIL SEND STATUS: {$result}"); } duplicator_log("EMAIL FINISHED"); } $fulltime_end = DuplicatorUtils::GetMicrotime(); $fulltime_sum = DuplicatorUtils::ElapsedTime($fulltime_end, $fulltime_start); duplicator_log("********************************************************************************"); duplicator_log($msg_complete_stats); duplicator_log("TOTAL PROCESS RUNTIME: {$fulltime_sum}"); duplicator_log("DONE PROCESSING => {$packname} " . @date('h:i:s')); duplicator_log("********************************************************************************"); @fclose($GLOBALS['duplicator_package_log_handle']); error_reporting($error_level); //===================================================== //DONE: UPDATE TRANSACTION $pack_settings = serialize(array('plugin_version' => DUPLICATOR_VERSION, 'type' => 'Manual', 'status' => 'Pass', 'notes' => "{$packnotes}")); $result = $wpdb->update($wpdb->prefix . "duplicator", array('zipsize' => $zip->zipFileSize, 'created' => current_time('mysql', get_option('gmt_offset')), 'owner' => $current_user->user_login, 'settings' => "{$pack_settings}"), array('id' => $table_id)); if ($result == false) { $error_result = $wpdb->print_error(); duplicator_error("ERROR: Unable to update database table. \nERROR INFO: '{$error_result}'"); } else { $add1_passcount = get_option('duplicator_add1_passcount', 0); $pack_passcount = get_option('duplicator_pack_passcount', 0); update_option('duplicator_add1_passcount', $add1_passcount + 1); update_option('duplicator_pack_passcount', $pack_passcount + 1); } die; }