function resursiveZip($directory) { try { $folderPath = duplicator_safe_path($directory); //EXCLUDE: Snapshot directory if (strstr($folderPath, DUPLICATOR_SSDIR_PATH) || empty($folderPath)) { return; } //EXCLUDE: Directory Exclusions List if (is_array($GLOBALS['duplicator_bypass-array'])) { foreach ($GLOBALS['duplicator_bypass-array'] as $val) { if (duplicator_safe_path($val) == $folderPath) { duplicator_log("path filter found: {$val}", 2); return; } } } //Notes: $file->getExtension() is not reliable as it silently fails at least in php 5.2.17 //when a file has a permission such as 705 falling back to pathinfo is more stable $dh = new DirectoryIterator($folderPath); foreach ($dh as $file) { if (!$file->isDot()) { $fullpath = "{$folderPath}/{$file}"; $localpath = str_replace($this->rootFolder, '', $folderPath); $localname = empty($localpath) ? '' : ltrim("{$localpath}/", '/'); $filename = $file->getFilename(); if ($file->isDir()) { if (!in_array($fullpath, $GLOBALS['duplicator_bypass-array'])) { if ($file->isReadable() && $this->zipArchive->addEmptyDir("{$localname}{$filename}")) { $this->countDirs++; $this->resursiveZip($fullpath); } else { duplicator_log("WARNING: Unable to add directory: {$fullpath}"); } } } else { if ($file->isFile() && $file->isReadable()) { if ($this->fileExtActive) { $ext = @pathinfo($fullpath, PATHINFO_EXTENSION); if (!in_array($ext, $this->skipNames) || empty($ext)) { $this->zipArchive->addFile("{$folderPath}/{$filename}", "{$localname}{$filename}"); $this->countFiles++; } } else { $this->zipArchive->addFile("{$folderPath}/{$filename}", "{$localname}{$filename}"); $this->countFiles++; } } else { if ($file->isLink()) { $this->countLinks++; } } } $this->limitItems++; } } //Check if were over our count //This process seems to slow things down. /* if ($this->limitItems > $this->limit) { $currentfilecount = $this->countDirs + $this->countFiles; duplicator_log("ADDED=>ZIP HANDLE: ({$currentfilecount})"); $this->zipArchive->close(); $this->zipArchive->open($this->zipFilePath, ZIPARCHIVE::CREATE); $this->limitItems = 0; duplicator_fcgi_flush(); }*/ @closedir($dh); } catch (Exception $e) { duplicator_error("ERROR: Runtime error in class.zip.php resursiveZip. \nERROR INFO: {$e}"); } }
/** * DUPLICATOR_CREATE_INSTALLERFILE * Prep the Installer file for use. use %string% token for replacing * @param string $uniquename The unique name this installer file will be associated with */ function duplicator_create_installerFile($uniquename, $table_id) { duplicator_log("INSTALLER FILE: Preping for use"); global $wpdb; $result = $wpdb->get_results("SELECT * FROM `{$wpdb->prefix}duplicator` WHERE ID = {$table_id}", ARRAY_A); $result_row = $result[0]; $settings = unserialize($result_row['settings']); $notes = empty($settings['notes']) ? 'No notes found for package.' : $settings['notes']; $template = duplicator_safe_path(DUPLICATOR_PLUGIN_PATH . 'files/installer.template.php'); $installerCore = duplicator_safe_path(DUPLICATOR_SSDIR_PATH) . "/{$uniquename}_installer.php"; $err_msg = "ERROR: Unable to read/write installer. \nERROR INFO: Please check permission and owner on file and parent folder. \nInstaller File=<{$installerCore}>"; get_option('duplicator_options') == "" ? "" : ($duplicator_opts = unserialize(get_option('duplicator_options'))); $replace_items = array("fwrite_url_old" => get_option('siteurl'), "fwrite_package_name" => "{$uniquename}_package.zip", "fwrite_package_notes" => $notes, "fwrite_secure_name" => "{$uniquename}", "fwrite_url_new" => $duplicator_opts['url_new'], "fwrite_dbhost" => $duplicator_opts['dbhost'], "fwrite_dbname" => $duplicator_opts['dbname'], "fwrite_dbuser" => $duplicator_opts['dbuser'], "fwrite_dbpass" => '', "fwrite_ssl_admin" => $duplicator_opts['ssl_admin'], "fwrite_ssl_login" => $duplicator_opts['ssl_login'], "fwrite_cache_wp" => $duplicator_opts['cache_wp'], "fwrite_cache_path" => $duplicator_opts['cache_path'], "fwrite_wp_tableprefix" => $wpdb->prefix, "fwrite_blogname" => @addslashes(get_option('blogname')), "fwrite_wproot" => DUPLICATOR_WPROOTPATH, "fwrite_duplicator_version" => DUPLICATOR_VERSION); if (file_exists($template) && is_readable($template)) { $install_str = duplicator_parse_template($template, $replace_items); if (empty($install_str)) { duplicator_error("{$err_msg} \n duplicator_create_installerFile=>file-empty-read"); } //INSTALLER FILE if (!file_exists($installerCore)) { $fp2 = fopen($installerCore, 'x+') or duplicator_error("{$err_msg} \n duplicator_create_installerFile=>file-open-error-x"); } else { $fp2 = fopen($installerCore, 'w') or duplicator_error("{$err_msg} \n duplicator_create_installerFile=>file-open-error-w"); } if (!fwrite($fp2, $install_str, strlen($install_str))) { duplicator_error("{$err_msg} \n duplicator_create_installerFile=>file-write-error"); } @fclose($fp2); } else { duplicator_error("ERROR: Installer Template missing or unreadable. \nERROR INFO: Template [{$template}]"); } duplicator_log("INSTALLER FILE: Complete [{$installerCore}]"); }
/** * 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; }