private function _dump_php($output_directory, $tables, $resume_starting_row = 0)
 {
     //, $base_dump_mode, $additional_excludes ) {
     $this->time_start = microtime(true);
     $last_file_size_output = microtime(true);
     $output_file_size_every_max = 5;
     // Output current SQL file size no more often than this. Only checks if it has been enough time once each burst of max rows per select is processed.
     $max_rows_per_select = $this->_max_rows_per_select;
     if ($resume_starting_row > 0) {
         pb_backupbuddy::status('details', 'Resuming chunked dump at row `' . $resume_starting_row . '`.');
     }
     global $wpdb;
     if (!is_object($wpdb)) {
         pb_backupbuddy::status('error', 'WordPress database object $wpdb did not exist. This should not happen.');
         error_log('WordPress database object $wpdb did not exist. This should not happen. BackupBuddy Error #8945587973.');
         return false;
     }
     // Connect if not connected for importbuddy.
     if (defined('PB_IMPORTBUDDY')) {
         if (!mysql_ping($wpdb->dbh)) {
             $maybePort = '';
             if ('' != $this->_database_port) {
                 $maybePort = ':' . $this->_database_port;
                 pb_backupbuddy::status('details', 'Using custom specified port `' . $this->_database_port . '` in DB_HOST.');
             }
             $wpdb->dbh = mysql_connect($this->_database_host . $maybePort, $this->_database_user, $this->_database_pass);
             mysql_select_db($this->_database_name, $wpdb->dbh);
         }
     }
     $insert_sql = '';
     pb_backupbuddy::status('details', 'Loading DB kicker for use leter in case database goes away.');
     @(include_once pb_backupbuddy::plugin_path() . '/lib/wpdbutils/wpdbutils.php');
     if (class_exists('pluginbuddy_wpdbutils')) {
         global $wpdb;
         $dbhelper = new pluginbuddy_wpdbutils($wpdb);
     } else {
         pb_backupbuddy::status('details', __('Database Server connection status will not be verified as kicker is not available.', 'it-l10n-backupbuddy'));
     }
     global $wpdb;
     // Used later for checking that we are still connected to DB.
     // Iterate through all the tables to backup.
     // TODO: Future ability to break up DB exporting to multiple page loads if needed.
     $remainingTables = $tables;
     foreach ($tables as $table_key => $table) {
         $_count = 0;
         $insert_sql = '';
         if ($resume_starting_row > 0) {
             pb_backupbuddy::status('details', 'Chunked resume on dumping `' . $table . '`. Resuming where left off.');
             $rows_start = $resume_starting_row;
             $resume_starting_row = 0;
             // Don't want to skip anything on next table.
         } else {
             $rows_start = 0;
         }
         pb_backupbuddy::status('details', 'Dumping database table `' . $table . '`. Max rows per select: ' . $max_rows_per_select . '. Starting at row `' . $resume_starting_row . '`.');
         pb_backupbuddy::status('startTableDump', $table);
         if (false === $this->_force_single_db_file) {
             $output_file = $output_directory . $table . '.sql';
         } else {
             pb_backupbuddy::status('details', 'Advanced option to force to single .sql file enabled.');
             $output_file = $output_directory . 'db_1.sql';
         }
         pb_backupbuddy::status('details', 'SQL dump file `' . $output_file . '`.');
         if ('-1' == $this->_maxExecutionTime) {
             pb_backupbuddy::status('details', 'Database max execution time chunking disabled based on -1 passed.');
         } else {
             pb_backupbuddy::status('details', 'mysqlbuddy: PHP-based database dump with max execution time for this run: ' . $this->_maxExecutionTime . ' seconds.');
         }
         if (false === ($file_handle = fopen($output_file, 'a'))) {
             pb_backupbuddy::status('error', 'Error #9018: Database file is not creatable/writable. Check your permissions for file `' . $output_file . '` in directory `' . $output_directory . '`.');
             return false;
         }
         pb_backupbuddy::status('sqlFile', basename($output_file));
         // Tells status checker which file to request size data for when polling server.
         if (0 == $rows_start) {
             $create_table = $wpdb->get_results("SHOW CREATE TABLE `{$table}`", ARRAY_N);
             if ($create_table === false) {
                 pb_backupbuddy::status('error', 'Unable to access and dump database table `' . $table . '`. Table may not exist. Skipping backup of this table.');
                 //backupbuddy_core::mail_error( 'Error #4537384: Unable to access and dump database table `' . $table . '`. Table may not exist. Skipping backup of this table.' );
                 continue;
                 // Skip this iteration as accessing this table failed.
             }
             // Table creation text
             if (!isset($create_table[0])) {
                 pb_backupbuddy::status('error', 'Error #857835: Unable to get table creation SQL for table `' . $table . '`. Result: `' . print_r($create_table) . '`.');
                 return false;
             }
             $create_table_array = $create_table[0];
             unset($create_table);
             $insert_sql .= str_replace("\n", '', $create_table_array[1]) . ";\n";
             // Remove internal linebreaks; only put one at end.
             unset($create_table_array);
             // Disable keys for this table.
             $insert_sql .= "/*!40000 ALTER TABLE `{$table}` DISABLE KEYS */;\n";
         }
         $queryCount = 0;
         $rows_remain = true;
         while (true === $rows_remain) {
             // Row creation text for all rows within this table.
             $query = "SELECT * FROM `{$table}` LIMIT " . $rows_start . ',' . $max_rows_per_select;
             $table_query = $wpdb->get_results($query, ARRAY_N);
             $rows_start += $max_rows_per_select;
             // Next loop we will begin at this offset.
             if ($table_query === false) {
                 pb_backupbuddy::status('error', 'ERROR #85449745. Unable to retrieve data from table `' . $table . '`. This table may be corrupt (try repairing the database) or too large to hold in memory (increase mysql and/or PHP memory). Check your PHP error log for further errors which may provide further information. Not continuing database dump to insure backup integrity.');
                 return false;
             }
             $tableCount = count($table_query);
             pb_backupbuddy::status('details', 'Got `' . $tableCount . '` rows from `' . $table . '` of `' . $max_rows_per_select . '` max.');
             if (0 == $tableCount || $tableCount < $max_rows_per_select) {
                 $rows_remain = false;
             }
             $columns = $wpdb->get_col_info();
             $num_fields = count($columns);
             foreach ($table_query as $fetch_row) {
                 $insert_sql .= "INSERT INTO `{$table}` VALUES(";
                 for ($n = 1; $n <= $num_fields; $n++) {
                     $m = $n - 1;
                     if ($fetch_row[$m] === NULL) {
                         $insert_sql .= "NULL, ";
                     } else {
                         $insert_sql .= "'" . backupbuddy_core::dbEscape($fetch_row[$m]) . "', ";
                     }
                 }
                 $insert_sql = substr($insert_sql, 0, -2);
                 $insert_sql .= ");\n";
                 $writeReturn = fwrite($file_handle, $insert_sql);
                 if (false === $writeReturn || 0 == $writeReturn) {
                     pb_backupbuddy::status('error', 'Error #843948: Unable to write to SQL file. Return error/bytes written: `' . $writeReturn . '`.');
                     @fclose($file_handle);
                     return false;
                 }
                 $insert_sql = '';
                 $_count++;
                 // Show a heartbeat to keep user up to date [and entertained ;)].
                 if (0 === $_count % self::HEARTBEAT_COUNT_LIMIT || 0 === $_count % ceil($max_rows_per_select / 2)) {
                     // Display every X queries based on heartbeat OR at least display every half max rows per select.
                     pb_backupbuddy::status('details', 'Working... Dumped `' . $_count . '` rows from `' . $table . '` so far.');
                 }
             }
             // end foreach table row.
             if (false === $rows_remain) {
                 pb_backupbuddy::status('details', 'Dumped `' . $_count . '` rows total from `' . $table . '`. No rows remain.');
             } else {
                 if (microtime(true) - $last_file_size_output > $output_file_size_every_max) {
                     // It's been long enough to get the current file size of SQL file.
                     // Display final SQL file size.
                     $sql_filesize = pb_backupbuddy::$format->file_size(filesize($output_file));
                     pb_backupbuddy::status('details', 'Current database dump file `' . basename($output_file) . '` size: ' . $sql_filesize . '.');
                     $last_file_size_output = microtime(true);
                 }
             }
             // If we are within X seconds (self::TIME_WIGGLE_ROOM) of reaching maximum PHP runtime then stop here so that it can be picked up in another PHP process...
             if ('-1' != $this->_maxExecutionTime) {
                 if (microtime(true) - pb_backupbuddy::$start_time + self::TIME_WIGGLE_ROOM >= $this->_maxExecutionTime) {
                     // used to use $this->time_start but this did not take into account time used prior to db step.
                     pb_backupbuddy::status('details', 'Approaching limit of available PHP chunking time of `' . $this->_maxExecutionTime . '` sec. PHP ran for ' . round(microtime(true) - pb_backupbuddy::$start_time, 3) . ' sec, database dumping ran for ' . round(microtime(true) - $this->time_start, 3) . ' sec having dumped `' . $_count . '` rows. Proceeding to use chunking on remaining tables: ' . implode(',', $remainingTables));
                     @fclose($file_handle);
                     return array($remainingTables, $rows_start);
                 }
                 // End if.
             }
             // Verify database is still connected and working properly. Sometimes mysql runs out of memory and dies in the above foreach.
             // No point in reconnecting as we can NOT trust that our dump was succesful anymore (it most likely was not).
             if (isset($dbhelper)) {
                 if (!$dbhelper->kick()) {
                     pb_backupbuddy::status('error', __('ERROR #9026: The mySQL server went away unexpectedly during database dump of table `' . $table . '`. This is almost always caused by mySQL running out of memory. The backup integrity can no longer be guaranteed so the backup has been halted.') . ' ' . __('Last table dumped before database server went away: ') . '`' . $table . '`.');
                     @fclose($file_handle);
                     return false;
                 }
             } else {
                 pb_backupbuddy::status('details', 'Database kicker unavailable so connection status unverified.');
             }
         }
         // End while rows remain.
         // Remove the current table from the list of tables to dump as it is done.
         unset($remainingTables[$table_key]);
         // Re-enable keys for this table.
         $insert_sql .= "/*!40000 ALTER TABLE `{$table}` ENABLE KEYS */;\n";
         $writeReturn = fwrite($file_handle, $insert_sql);
         if (false === $writeReturn || 0 == $writeReturn) {
             pb_backupbuddy::status('error', 'Error #843948: Unable to write to SQL file. Return error/bytes written: `' . $writeReturn . '`.');
             @fclose($file_handle);
             return false;
         }
         $insert_sql = '';
         @fclose($file_handle);
         pb_backupbuddy::status('details', 'Finished dumping database table `' . $table . '`.');
         pb_backupbuddy::status('finishTableDump', $table);
         if (isset($output_file)) {
             $stats = stat($output_file);
             pb_backupbuddy::status('details', 'Database SQL dump file (' . basename($output_file) . ') size: ' . pb_backupbuddy::$format->file_size($stats['size']));
             pb_backupbuddy::status('sqlSize', $stats['size']);
         }
         pb_backupbuddy::status('details', 'About to flush...');
         pb_backupbuddy::flush();
         //unset( $tables[$table_key] );
     }
     // end foreach table.
     @fclose($file_handle);
     unset($file_handle);
     pb_backupbuddy::status('details', __('Finished PHP based SQL dump method. Ran for ' . round(microtime(true) - $this->time_start, 3) . ' sec.', 'it-l10n-backupbuddy'));
     return true;
 }
 protected function backup_zip_files_alternate($state = array())
 {
     // Dependent on the zip build strategy chosen we will need to set various operational
     // parameters on the zipbuddy object to be used by the method building the zip. Eventually
     // we can use strategy objects but for now we'll do it the old-fashioned way.
     // Strategies are:
     // Single-Burst/Single-Step: Step Period = Infinite; Min/Max Burst Content Size = Infinite;
     // Multi-Burst/Single-Step: Step Period = Infinite; Min/Max Burst Content Size = Per-Config;
     // Multi-Burst/Multi-Step: Step Period = Per-Config; Min/Max Burst Content Size = Per-Config;
     $zip_build_strategy_name = array(self::ZIP_BUILD_STRATEGY_SBSS => 'Single-Burst/Single-Step', self::ZIP_BUILD_STRATEGY_MBSS => 'Multi-Burst/Single-Step', self::ZIP_BUILD_STRATEGY_MBMS => 'Multi-Burst/Multi-Step');
     // Get the current strategy
     if (isset(pb_backupbuddy::$options['zip_build_strategy'])) {
         $zip_build_strategy = pb_backupbuddy::$options['zip_build_strategy'];
         if (self::ZIP_BUILD_STRATEGY_MIN > $zip_build_strategy || self::ZIP_BUILD_STRATEGY_MAX < $zip_build_strategy) {
             // Hmm, not valid - have to revert to default
             $zip_build_strategy = self::ZIP_BUILD_STRATEGY_MBSS;
             pb_backupbuddy::status('details', 'Zip Build Strategy not recognized - reverting to: ' . $zip_build_strategy_name[$zip_build_strategy]);
         } else {
             pb_backupbuddy::status('details', 'Zip Build Strategy: ' . $zip_build_strategy_name[$zip_build_strategy]);
         }
     } else {
         // Hmm, should be set - have to revert to default
         $zip_build_strategy = self::ZIP_BUILD_STRATEGY_MBSS;
         pb_backupbuddy::status('details', 'Zip Build Strategy not set - reverting to: ' . $zip_build_strategy_name[$zip_build_strategy]);
     }
     // Now we haev to check if running in Classic mode. If yes then we cannot use multi-step without continually
     // resetting the "start" time for the zip monitor. The better approach is to override the zip build strategy
     // if it is a multi-step strategy and at least revert it to multi-burst/single-step. If it is already this
     // or single-burst/single-step we can leave it as it is
     // The backup mode details _should_ be available through this class variable created in pre_backup() function.
     if ($this->_backup['profile']['backup_mode'] == '1') {
         // Running in Classic mode...
         if (self::ZIP_BUILD_STRATEGY_MBSS < $zip_build_strategy) {
             $zip_build_strategy = self::ZIP_BUILD_STRATEGY_MBSS;
             pb_backupbuddy::status('details', 'Zip Build Strategy overridden as incompatible with Classic backup mode - reverting to: ' . $zip_build_strategy_name[$zip_build_strategy]);
         }
     }
     // Now based on the stratgy set build parameters that we will set on the zipbuddy object that
     // define the zip build behaviour
     switch ($zip_build_strategy) {
         case self::ZIP_BUILD_STRATEGY_SBSS:
             $step_period = PHP_INT_MAX;
             // Effectively infinite
             $burst_min_content = 4 == PHP_INT_SIZE ? (double) (pow(2, 63) - 1) : (double) PHP_INT_MAX;
             // Hack to get large value for either 32 or 64 bit PHP
             $burst_max_content = 4 == PHP_INT_SIZE ? (double) (pow(2, 63) - 1) : (double) PHP_INT_MAX;
             break;
         case self::ZIP_BUILD_STRATEGY_MBSS:
             $step_period = PHP_INT_MAX;
             $burst_min_content = null;
             $burst_max_content = null;
             break;
         case self::ZIP_BUILD_STRATEGY_MBMS:
             $step_period = null;
             // Force the option value to be used
             $burst_min_content = null;
             $burst_max_content = null;
             break;
     }
     // We can set the values on the zipbuddy object at this point
     pb_backupbuddy::$classes['zipbuddy']->set_step_period($step_period);
     pb_backupbuddy::$classes['zipbuddy']->set_min_burst_content($burst_min_content);
     pb_backupbuddy::$classes['zipbuddy']->set_max_burst_content($burst_max_content);
     if (empty($state)) {
         // This is our first (and perhaps only) call, so do first time stuff
         pb_backupbuddy::status('milestone', 'start_files');
         pb_backupbuddy::status('details', 'Backup root: `' . $this->_backup['backup_root'] . '`.');
         // Set compression on / off.
         //pb_backupbuddy::$classes['zipbuddy']->set_compression( $this->_backup['compression'] );
         // Currently we'll still allow skipping the addition of the meta data in the comment
         // but eventually this will become mandatory (in al likelihood)
         // Save meta information in comment.
         if ('0' == pb_backupbuddy::$options['save_comment_meta']) {
             pb_backupbuddy::status('details', 'Skipping saving meta data to zip comment based on settings.');
             $comment = '';
         } else {
             pb_backupbuddy::status('details', 'Saving meta data to zip comment.');
             // Calculate some statistics to store in meta later. These need to be calculated before zipping in case the DB goes away later to prevent a possible failure.
             $totalPosts = 0;
             foreach (wp_count_posts('post') as $type => $count) {
                 $totalPosts += $count;
             }
             $totalPages = 0;
             foreach (wp_count_posts('page') as $type => $count) {
                 $totalPages += $count;
             }
             $totalComments = 0;
             foreach (wp_count_comments() as $type => $count) {
                 $totalComments += $count;
             }
             $totalUsers = count_users();
             $totalUsers = $totalUsers['total_users'];
             global $wpdb;
             $db_prefix = $wpdb->prefix;
             global $wp_version;
             $meta = array('serial' => $this->_backup['serial'], 'siteurl' => site_url(), 'type' => $this->_backup['type'], 'profile' => $this->_backup['profile']['title'], 'created' => $this->_backup['start_time'], 'db_prefix' => $db_prefix, 'bb_version' => pb_backupbuddy::settings('version'), 'wp_version' => $wp_version, 'dat_path' => str_replace($this->_backup['backup_root'], '', $this->_backup['temp_directory'] . 'backupbuddy_dat.php'), 'posts' => $totalPosts, 'pages' => $totalPages, 'comments' => $totalComments, 'users' => $totalUsers, 'note' => '');
             $comment = backupbuddy_core::normalize_comment_data($meta);
         }
         // Always create the empty zip archive with the optional meta data comment added at this point.
         // This is method independent so is done just in zipbuddy.
         $zip_response = pb_backupbuddy::$classes['zipbuddy']->create_empty_zip($this->_backup['archive_file'], $this->_backup['temporary_zip_directory'], $comment);
         if (false === $zip_response) {
             // Delete temporary data directory.
             if (file_exists($this->_backup['temp_directory'])) {
                 pb_backupbuddy::status('details', __('Removing temp data directory.', 'it-l10n-backupbuddy'));
                 pb_backupbuddy::$filesystem->unlink_recursive($this->_backup['temp_directory']);
             }
             // Delete temporary ZIP directory.
             if (file_exists($this->_backup['temporary_zip_directory'])) {
                 pb_backupbuddy::status('details', __('Removing temp zip directory.', 'it-l10n-backupbuddy'));
                 pb_backupbuddy::$filesystem->unlink_recursive($this->_backup['temporary_zip_directory']);
             }
             pb_backupbuddy::status('error', __('Error #4001: Unable to successfully generate ZIP archive. Backup FAILED. See logs above for more information.', 'it-l10n-backupbuddy'));
             pb_backupbuddy::status('haltScript', '');
             // Halt JS on page.
             return false;
         }
         // Create zip file!
         $zip_response = pb_backupbuddy::$classes['zipbuddy']->add_directory_to_zip($this->_backup['archive_file'], $this->_backup['backup_root'], $this->_backup['directory_exclusions'], $this->_backup['temporary_zip_directory']);
         // Zip results.
         if ($zip_response === true) {
             // Zip success.
             pb_backupbuddy::status('message', __('Backup ZIP file successfully created.', 'it-l10n-backupbuddy'));
             if (chmod($this->_backup['archive_file'], 0644)) {
                 pb_backupbuddy::status('details', __('Chmod of ZIP file to 0644 succeeded.', 'it-l10n-backupbuddy'));
             } else {
                 pb_backupbuddy::status('details', __('Chmod of ZIP file to 0644 failed.', 'it-l10n-backupbuddy'));
             }
         } elseif (is_array($zip_response)) {
             // First step returned a continuation state so we only do some stuff and then queue
             // a continuation step
             // Now recover the returned state and queue the next step.
             $newStep = array('function' => 'backup_zip_files', 'args' => array($zip_response), 'start_time' => 0, 'finish_time' => 0, 'attempts' => 0);
             //error_log( print_r( $this->_backup_options->options['steps'], true ) );
             array_splice($this->_backup_options->options['steps'], $this->_currentStepIndex + 1, 0, array($newStep));
             //error_log( print_r( $this->_backup_options->options['steps'], true ) );
             $this->_backup_options->save();
             pb_backupbuddy::status('details', 'Inserted additional zip grow step at `' . ($this->_currentStepIndex + 1) . '` to resume at index `' . $zip_response['zipper']['fp'] . '`. The next chunk will proceed shortly.');
         } else {
             // Zip failure.
             // Delete temporary data directory.
             if (file_exists($this->_backup['temp_directory'])) {
                 pb_backupbuddy::status('details', __('Removing temp data directory.', 'it-l10n-backupbuddy'));
                 pb_backupbuddy::$filesystem->unlink_recursive($this->_backup['temp_directory']);
             }
             // Delete temporary ZIP directory.
             if (file_exists($this->_backup['temporary_zip_directory'])) {
                 pb_backupbuddy::status('details', __('Removing temp zip directory.', 'it-l10n-backupbuddy'));
                 pb_backupbuddy::$filesystem->unlink_recursive($this->_backup['temporary_zip_directory']);
             }
             pb_backupbuddy::status('error', __('Error #4001: Unable to successfully generate ZIP archive. Backup FAILED. See logs above for more information.', 'it-l10n-backupbuddy'));
             pb_backupbuddy::status('haltScript', '');
             // Halt JS on page.
             return false;
         }
         // end zip failure.
     } else {
         // Continuation step with a state
         $zip_response = pb_backupbuddy::$classes['zipbuddy']->grow_zip($this->_backup['archive_file'], $this->_backup['temporary_zip_directory'], $state);
         if ($zip_response === true) {
             // Zip success.
             pb_backupbuddy::status('message', __('Backup ZIP file successfully created.', 'it-l10n-backupbuddy'));
             if (chmod($this->_backup['archive_file'], 0644)) {
                 pb_backupbuddy::status('details', __('Chmod of ZIP file to 0644 succeeded.', 'it-l10n-backupbuddy'));
             } else {
                 pb_backupbuddy::status('details', __('Chmod of ZIP file to 0644 failed.', 'it-l10n-backupbuddy'));
             }
         } elseif (is_array($zip_response)) {
             // First step returned a continuation state so we only do some stuff and then queue
             // a continuation step
             // Now recover the returned state and queue the next step.
             $newStep = array('function' => 'backup_zip_files', 'args' => array($zip_response), 'start_time' => 0, 'finish_time' => 0, 'attempts' => 0);
             //error_log( print_r( $this->_backup_options->options['steps'], true ) );
             array_splice($this->_backup_options->options['steps'], $this->_currentStepIndex + 1, 0, array($newStep));
             //error_log( print_r( $this->_backup_options->options['steps'], true ) );
             $this->_backup_options->save();
             pb_backupbuddy::status('details', 'Inserted additional zip grow step at `' . ($this->_currentStepIndex + 1) . '` to resume at index `' . $zip_response['zipper']['fp'] . '`. The next chunk will proceed shortly.');
         } else {
             // Zip failure.
             // Delete temporary data directory.
             if (file_exists($this->_backup['temp_directory'])) {
                 pb_backupbuddy::status('details', __('Removing temp data directory.', 'it-l10n-backupbuddy'));
                 pb_backupbuddy::$filesystem->unlink_recursive($this->_backup['temp_directory']);
             }
             // Delete temporary ZIP directory.
             if (file_exists($this->_backup['temporary_zip_directory'])) {
                 pb_backupbuddy::status('details', __('Removing temp zip directory.', 'it-l10n-backupbuddy'));
                 pb_backupbuddy::$filesystem->unlink_recursive($this->_backup['temporary_zip_directory']);
             }
             pb_backupbuddy::status('error', __('Error #4001: Unable to successfully generate ZIP archive. Backup FAILED. See logs above for more information.', 'it-l10n-backupbuddy'));
             pb_backupbuddy::status('haltScript', '');
             // Halt JS on page.
             return false;
         }
         // end zip failure.
     }
     // Need to make sure the database connection is active. Sometimes it goes away during long bouts doing other things -- sigh.
     // This is not essential so use include and not require (suppress any warning)
     @(include_once pb_backupbuddy::plugin_path() . '/lib/wpdbutils/wpdbutils.php');
     if (class_exists('pluginbuddy_wpdbutils')) {
         // This is the database object we want to use
         global $wpdb;
         // Get our helper object and let it use us to output status messages
         $dbhelper = new pluginbuddy_wpdbutils($wpdb);
         // If we cannot kick the database into life then signal the error and return false which will stop the backup
         // Otherwise all is ok and we can just fall through and let the function return true
         if (!$dbhelper->kick()) {
             pb_backupbuddy::status('error', __('Backup FAILED. Backup file produced but Database Server has gone away, unable to schedule next backup step', 'it-l10n-backupbuddy'));
             return false;
         } else {
             //pb_backupbuddy::status( 'details', 'Database seems to still be connected.' );
         }
     } else {
         // Utils not available so cannot verify database connection status - just notify
         pb_backupbuddy::status('details', __('Database Server connection status unverified.', 'it-l10n-backupbuddy'));
     }
     return $zip_response;
 }
Beispiel #3
0
 public static function kick_db()
 {
     $kick_db = true;
     // Change true to false for debugging purposes to disable kicker.
     // Need to make sure the database connection is active. Sometimes it goes away during long bouts doing other things -- sigh.
     // This is not essential so use include and not require (suppress any warning)
     if ($kick_db === true) {
         @(include_once pb_backupbuddy::plugin_path() . '/lib/wpdbutils/wpdbutils.php');
         if (class_exists('pluginbuddy_wpdbutils')) {
             // This is the database object we want to use
             global $wpdb;
             // Get our helper object and let it use us to output status messages
             $dbhelper = new pluginbuddy_wpdbutils($wpdb);
             // If we cannot kick the database into life then signal the error and return false which will stop the backup
             // Otherwise all is ok and we can just fall through and let the function return true
             if (!$dbhelper->kick()) {
                 pb_backupbuddy::status('error', __('Database Server has gone away, unable to update remote destination transfer status. This is most often caused by mysql running out of memory or timing out far too early. Please contact your host.', 'it-l10n-backupbuddy'));
             }
         } else {
             // Utils not available so cannot verify database connection status - just notify
             pb_backupbuddy::status('details', __('Database Server connection status unverified.', 'it-l10n-backupbuddy'));
         }
     }
 }
 private function _dump_php($output_directory, $tables)
 {
     //, $base_dump_mode, $additional_excludes ) {
     $max_rows_per_select = $this->_max_rows_per_select;
     $output_file = $output_directory . 'db_1.sql';
     pb_backupbuddy::status('details', 'mysqlbuddy: Preparing to run PHP mysqldump compatibility mode.');
     if (false === ($file_handle = fopen($output_file, 'a'))) {
         pb_backupbuddy::status('error', 'Error #9018: Database file is not creatable/writable. Check your permissions for file `' . $output_file . '` in directory `' . $output_directory . '`.');
         return false;
     }
     global $wpdb;
     if (!is_object($wpdb)) {
         pb_backupbuddy::status('error', 'WordPress database object $wpdb did not exist. This should not happen.');
         error_log('WordPress database object $wpdb did not exist. This should not happen. BackupBuddy Error #8945587973.');
         return false;
     }
     // Connect if not connected for importbuddy.
     if (defined('PB_IMPORTBUDDY')) {
         if (!mysql_ping($wpdb->dbh)) {
             $wpdb->dbh = mysql_connect($this->_database_host, $this->_database_user, $this->_database_pass);
             mysql_select_db($this->_database_name, $wpdb->dbh);
         }
     }
     $_count = 0;
     $insert_sql = '';
     pb_backupbuddy::status('details', 'Loading DB kicker for use leter in case database goes away.');
     @(include_once pb_backupbuddy::plugin_path() . '/lib/wpdbutils/wpdbutils.php');
     if (class_exists('pluginbuddy_wpdbutils')) {
         global $wpdb;
         $dbhelper = new pluginbuddy_wpdbutils($wpdb);
     } else {
         pb_backupbuddy::status('details', __('Database Server connection status will not be verified as kicker is not available.', 'it-l10n-backupbuddy'));
     }
     global $wpdb;
     // Used later for checking that we are still connected to DB.
     // Iterate through all the tables to backup.
     // TODO: Future ability to break up DB exporting to multiple page loads if needed.
     foreach ($tables as $table_key => $table) {
         pb_backupbuddy::status('details', 'Starting to dump database table `' . $table . '`. Max rows per select: ' . $max_rows_per_select . '.');
         $create_table = $wpdb->get_results("SHOW CREATE TABLE `{$table}`", ARRAY_N);
         if ($create_table === false) {
             pb_backupbuddy::status('error', 'Unable to access and dump database table `' . $table . '`. Table may not exist. Skipping backup of this table.');
             //backupbuddy_core::mail_error( 'Error #4537384: Unable to access and dump database table `' . $table . '`. Table may not exist. Skipping backup of this table.' );
             continue;
             // Skip this iteration as accessing this table failed.
         }
         // Table creation text
         if (!isset($create_table[0])) {
             pb_backupbuddy::status('error', 'Error #857835: Unable to get table creation SQL for table `' . $table . '`. Result: `' . print_r($create_table) . '`.');
             return false;
         }
         $create_table_array = $create_table[0];
         unset($create_table);
         $insert_sql .= str_replace("\n", '', $create_table_array[1]) . ";\n";
         // Remove internal linebreaks; only put one at end.
         unset($create_table_array);
         // Disable keys for this table.
         $insert_sql .= "/*!40000 ALTER TABLE `{$table}` DISABLE KEYS */;\n";
         $rows_remain = true;
         $rows_start = 0;
         while (true === $rows_remain) {
             // Row creation text for all rows within this table.
             $query = "SELECT * FROM `{$table}` LIMIT " . $rows_start . ',' . $max_rows_per_select;
             //pb_backupbuddy::status( 'details', 'Query: `' . $query . '`' );
             $table_query = $wpdb->get_results($query, ARRAY_N);
             $rows_start += $max_rows_per_select;
             // Next loop we will begin at this offset.
             if ($table_query === false) {
                 pb_backupbuddy::status('error', 'ERROR #85449745. Unable to retrieve data from table `' . $table . '`. This table may be corrupt (try repairing the database) or too large to hold in memory (increase mysql and/or PHP memory). Check your PHP error log for further errors which may provide further information. Not continuing database dump to insure backup integrity.');
                 return false;
             }
             $tableCount = count($table_query);
             if (0 == $tableCount || $tableCount < $max_rows_per_select) {
                 $rows_remain = false;
             }
             $columns = $wpdb->get_col_info();
             $num_fields = count($columns);
             foreach ($table_query as $fetch_row) {
                 $insert_sql .= "INSERT INTO `{$table}` VALUES(";
                 for ($n = 1; $n <= $num_fields; $n++) {
                     $m = $n - 1;
                     if ($fetch_row[$m] === NULL) {
                         $insert_sql .= "NULL, ";
                     } else {
                         $insert_sql .= "'" . backupbuddy_core::dbEscape($fetch_row[$m]) . "', ";
                     }
                 }
                 $insert_sql = substr($insert_sql, 0, -2);
                 $insert_sql .= ");\n";
                 $writeReturn = fwrite($file_handle, $insert_sql);
                 if (false === $writeReturn || 0 == $writeReturn) {
                     pb_backupbuddy::status('error', 'Error #843948: Unable to write to SQL file. Return error/bytes written: `' . $writeReturn . '`.');
                     return false;
                 }
                 $insert_sql = '';
                 // Help keep HTTP alive.
                 $_count++;
                 if ($_count >= 500) {
                     echo ' ';
                     pb_backupbuddy::status('details', 'Dumped 500 more rows. About to flush...');
                     pb_backupbuddy::flush();
                     pb_backupbuddy::status('details', 'Flush complete.');
                     $_count = 0;
                 }
             }
             // end while $rows_remain is true.
             // Verify database is still connected and working properly. Sometimes mysql runs out of memory and dies in the above foreach.
             // No point in reconnecting as we can NOT trust that our dump was succesful anymore (it most likely was not).
             if (isset($dbhelper)) {
                 if ($dbhelper->kick()) {
                     pb_backupbuddy::status('details', 'Database seems to still be connected.');
                 } else {
                     // Database not connected.
                     pb_backupbuddy::status('error', __('ERROR #9026: The mySQL server went away unexpectedly during database dump of table `' . $table . '`. This is almost always caused by mySQL running out of memory. The backup integrity can no longer be guaranteed so the backup has been halted.') . ' ' . __('Last table dumped before database server went away: ') . '`' . $table . '`.');
                     return false;
                 }
             } else {
                 pb_backupbuddy::status('details', 'Database kicker unavailable so connection status unverified.');
             }
         }
         // End foreach $tables.
         // Re-enable keys for this table.
         $insert_sql .= "/*!40000 ALTER TABLE `{$table}` ENABLE KEYS */;\n";
         // Help keep HTTP alive.
         echo ' ';
         pb_backupbuddy::status('details', 'Finished dumping database table `' . $table . '`.');
         pb_backupbuddy::status('details', 'About to flush...');
         pb_backupbuddy::flush();
         pb_backupbuddy::status('details', 'Flushed.');
         //unset( $tables[$table_key] );
     }
     // end foreach table.
     @fclose($file_handle);
     unset($file_handle);
     pb_backupbuddy::status('details', __('Finished PHP based SQL dump method.', 'it-l10n-backupbuddy'));
     $stats = stat($output_file);
     pb_backupbuddy::status('details', __('SQL dump file size', 'it-l10n-backupbuddy') . ': ' . pb_backupbuddy::$format->file_size($stats['size']));
     return true;
 }
Beispiel #5
0
 function backup_zip_files()
 {
     pb_backupbuddy::status('action', 'start_files');
     pb_backupbuddy::status('details', 'Backup root: `' . $this->_backup['backup_root'] . '`.');
     // Set compression on / off.
     //pb_backupbuddy::$classes['zipbuddy']->set_compression( $this->_backup['compression'] );
     // Create zip file!
     $zip_response = pb_backupbuddy::$classes['zipbuddy']->add_directory_to_zip($this->_backup['archive_file'], $this->_backup['backup_root'], $this->_backup['directory_exclusions'], $this->_backup['temporary_zip_directory']);
     // Zip results.
     if ($zip_response === true) {
         // Zip success.
         pb_backupbuddy::status('message', __('Backup ZIP file successfully created.', 'it-l10n-backupbuddy'));
         if (chmod($this->_backup['archive_file'], 0644)) {
             pb_backupbuddy::status('details', __('Chmod of ZIP file to 0644 succeeded.', 'it-l10n-backupbuddy'));
         } else {
             pb_backupbuddy::status('details', __('Chmod of ZIP file to 0644 failed.', 'it-l10n-backupbuddy'));
         }
         // Save meta information in comment.
         if ('0' == pb_backupbuddy::$options['save_comment_meta']) {
             pb_backupbuddy::status('details', 'Skipping saving meta data to zip comment based on settings.');
         } else {
             pb_backupbuddy::status('details', 'Saving meta data to zip comment.');
             $totalPosts = 0;
             foreach (wp_count_posts('post') as $type => $count) {
                 $totalPosts += $count;
             }
             $totalPages = 0;
             foreach (wp_count_posts('page') as $type => $count) {
                 $totalPages += $count;
             }
             $totalComments = 0;
             foreach (wp_count_comments() as $type => $count) {
                 $totalComments += $count;
             }
             $totalUsers = count_users();
             $totalUsers = $totalUsers['total_users'];
             global $wp_version;
             global $wpdb;
             $meta = array('serial' => $this->_backup['serial'], 'siteurl' => site_url(), 'type' => $this->_backup['type'], 'profile' => $this->_backup['profile']['title'], 'created' => $this->_backup['start_time'], 'db_prefix' => $wpdb->prefix, 'bb_version' => pb_backupbuddy::settings('version'), 'wp_version' => $wp_version, 'dat_path' => str_replace($this->_backup['backup_root'], '', $this->_backup['temp_directory'] . 'backupbuddy_dat.php'), 'posts' => $totalPosts, 'pages' => $totalPages, 'comments' => $totalComments, 'users' => $totalUsers, 'note' => '');
             $comment = backupbuddy_core::normalize_comment_data($meta);
             $comment_result = pb_backupbuddy::$classes['zipbuddy']->set_comment($this->_backup['archive_file'], $comment);
             if ($comment_result !== true) {
                 pb_backupbuddy::status('warning', 'Unable to save meta data to zip comment. This is not a fatal warning & will not impact the backup itself.');
             } else {
                 pb_backupbuddy::status('details', 'Saved meta data to zip comment.');
             }
         }
     } else {
         // Zip failure.
         // Delete temporary data directory.
         if (file_exists($this->_backup['temp_directory'])) {
             pb_backupbuddy::status('details', __('Removing temp data directory.', 'it-l10n-backupbuddy'));
             pb_backupbuddy::$filesystem->unlink_recursive($this->_backup['temp_directory']);
         }
         // Delete temporary ZIP directory.
         if (file_exists($this->_backup['temporary_zip_directory'])) {
             pb_backupbuddy::status('details', __('Removing temp zip directory.', 'it-l10n-backupbuddy'));
             pb_backupbuddy::$filesystem->unlink_recursive($this->_backup['temporary_zip_directory']);
         }
         pb_backupbuddy::status('error', __('Error #3382: Backup FAILED. Unable to successfully generate ZIP archive.', 'it-l10n-backupbuddy'));
         pb_backupbuddy::status('error', __('Error #3382 help: http://ithemes.com/codex/page/BackupBuddy:_Error_Codes#3382', 'it-l10n-backupbuddy'));
         pb_backupbuddy::status('action', 'halt_script');
         // Halt JS on page.
         return false;
     }
     // end zip failure.
     // Need to make sure the database connection is active. Sometimes it goes away during long bouts doing other things -- sigh.
     // This is not essential so use include and not require (suppress any warning)
     pb_backupbuddy::status('details', 'Loading DB kicker in case database has gone away.');
     @(include_once pb_backupbuddy::plugin_path() . '/lib/wpdbutils/wpdbutils.php');
     if (class_exists('pluginbuddy_wpdbutils')) {
         // This is the database object we want to use
         global $wpdb;
         // Get our helper object and let it use us to output status messages
         $dbhelper = new pluginbuddy_wpdbutils($wpdb);
         // If we cannot kick the database into life then signal the error and return false which will stop the backup
         // Otherwise all is ok and we can just fall through and let the function return true
         if (!$dbhelper->kick()) {
             pb_backupbuddy::status('error', __('Backup FAILED. Backup file produced but Database Server has gone away, unable to schedule next backup step', 'it-l10n-backupbuddy'));
             return false;
         } else {
             pb_backupbuddy::status('details', 'Database seems to still be connected.');
         }
     } else {
         // Utils not available so cannot verify database connection status - just notify
         pb_backupbuddy::status('details', __('Database Server connection status unverified.', 'it-l10n-backupbuddy'));
     }
     return true;
 }
Beispiel #6
0
 function backup_zip_files()
 {
     pb_backupbuddy::status('action', 'start_files');
     if (!isset(pb_backupbuddy::$classes['core'])) {
         require_once pb_backupbuddy::plugin_path() . '/classes/core.php';
         pb_backupbuddy::$classes['core'] = new pb_backupbuddy_core();
     }
     // Calculate user-defined directory exclusions AND additional internal BB exclusions such as backup archive directory and temp directory.
     $exclusions = pb_backupbuddy_core::get_directory_exclusions();
     // Use compression?
     if (pb_backupbuddy::$options['compression'] == '1') {
         $compression = true;
     } else {
         $compression = false;
     }
     pb_backupbuddy::status('details', 'Backup root: `' . $this->_backup['backup_root'] . '`.');
     // Additional logging?
     if (pb_backupbuddy::$options['log_level'] == 3) {
         // Also shows debugging consolse.
         $quiet_response = false;
     } else {
         $quiet_response = true;
     }
     // MAKE THE ZIP!
     if (pb_backupbuddy::$classes['zipbuddy']->add_directory_to_zip($this->_backup['archive_file'], $this->_backup['backup_root'], $compression, $exclusions, $this->_backup['temporary_zip_directory'], $this->_backup['force_compatibility'], $quiet_response) === true) {
         pb_backupbuddy::status('message', __('Backup ZIP file successfully created.', 'it-l10n-backupbuddy'));
         if (chmod($this->_backup['archive_file'], 0644)) {
             pb_backupbuddy::status('details', __('Chmod of ZIP file to 0644 succeeded.', 'it-l10n-backupbuddy'));
         } else {
             pb_backupbuddy::status('details', __('Chmod of ZIP file to 0644 failed.', 'it-l10n-backupbuddy'));
         }
     } else {
         pb_backupbuddy::status('error', __('Backup FAILED. Unable to successfully generate ZIP archive. Error #3382.', 'it-l10n-backupbuddy'));
         pb_backupbuddy::status('error', __('Error #3382 help: http://ithemes.com/codex/page/BackupBuddy:_Error_Codes#3382', 'it-l10n-backupbuddy'));
         pb_backupbuddy::status('action', 'halt_script');
         // Halt JS on page.
         return false;
     }
     // Need to make sure the database connection is active. Sometimes it goes away during long bouts doing other things -- sigh.
     // This is not essential so use include and not require (suppress any warning)
     @(include_once pb_backupbuddy::plugin_path() . '/lib/wpdbutils/wpdbutils.php');
     if (class_exists('pluginbuddy_wpdbutils')) {
         // This is the database object we want to use
         global $wpdb;
         // Get our helper object and let it use us to output status messages
         $dbhelper = new pluginbuddy_wpdbutils($wpdb);
         // If we cannot kick the database into life then signal the error and return false which will stop the backup
         // Otherwise all is ok and we can just fall through and let the function return true
         if (!$dbhelper->kick()) {
             pb_backupbuddy::status('error', __('Backup FAILED. Backup file produced but Database Server has gone away, unable to schedule next backup step', 'it-l10n-backupbuddy'));
             return false;
         }
     } else {
         // Utils not available so cannot verify database connection status - just notify
         pb_backupbuddy::status('details', __('Database Server connection status unverified.', 'it-l10n-backupbuddy'));
     }
     return true;
 }
Beispiel #7
0
 function backup_zip_files()
 {
     pb_backupbuddy::status('action', 'start_files');
     pb_backupbuddy::status('details', 'Backup root: `' . $this->_backup['backup_root'] . '`.');
     // Use compression?
     if (pb_backupbuddy::$options['compression'] == '1') {
         $compression = true;
     } else {
         $compression = false;
     }
     // Create zip file!
     $zip_response = pb_backupbuddy::$classes['zipbuddy']->add_directory_to_zip($this->_backup['archive_file'], $this->_backup['backup_root'], $compression, $this->_backup['directory_exclusions'], $this->_backup['temporary_zip_directory'], $this->_backup['force_compatibility']);
     // Zip results.
     if ($zip_response === true) {
         pb_backupbuddy::status('message', __('Backup ZIP file successfully created.', 'it-l10n-backupbuddy'));
         if (chmod($this->_backup['archive_file'], 0644)) {
             pb_backupbuddy::status('details', __('Chmod of ZIP file to 0644 succeeded.', 'it-l10n-backupbuddy'));
         } else {
             pb_backupbuddy::status('details', __('Chmod of ZIP file to 0644 failed.', 'it-l10n-backupbuddy'));
         }
     } else {
         pb_backupbuddy::status('error', __('Error #3382: Backup FAILED. Unable to successfully generate ZIP archive.', 'it-l10n-backupbuddy'));
         pb_backupbuddy::status('error', __('Error #3382 help: http://ithemes.com/codex/page/BackupBuddy:_Error_Codes#3382', 'it-l10n-backupbuddy'));
         pb_backupbuddy::status('action', 'halt_script');
         // Halt JS on page.
         return false;
     }
     // Need to make sure the database connection is active. Sometimes it goes away during long bouts doing other things -- sigh.
     // This is not essential so use include and not require (suppress any warning)
     pb_backupbuddy::status('details', 'Loading DB kicker in case database has gone away.');
     @(include_once pb_backupbuddy::plugin_path() . '/lib/wpdbutils/wpdbutils.php');
     if (class_exists('pluginbuddy_wpdbutils')) {
         // This is the database object we want to use
         global $wpdb;
         // Get our helper object and let it use us to output status messages
         $dbhelper = new pluginbuddy_wpdbutils($wpdb);
         // If we cannot kick the database into life then signal the error and return false which will stop the backup
         // Otherwise all is ok and we can just fall through and let the function return true
         if (!$dbhelper->kick()) {
             pb_backupbuddy::status('error', __('Backup FAILED. Backup file produced but Database Server has gone away, unable to schedule next backup step', 'it-l10n-backupbuddy'));
             return false;
         } else {
             pb_backupbuddy::status('details', 'Database seems to still be connected.');
         }
     } else {
         // Utils not available so cannot verify database connection status - just notify
         pb_backupbuddy::status('details', __('Database Server connection status unverified.', 'it-l10n-backupbuddy'));
     }
     return true;
 }
Beispiel #8
0
 function backup_zip_files()
 {
     $this->status('action', 'start_files');
     //sleep(7);
     $excludes = trim($this->_options['excludes']);
     $excludes = explode("\n", $excludes);
     //Clean up directory exclusions.
     foreach ($excludes as $exclude_id => $exclude_value) {
         if (empty($exclude_value)) {
             unset($excludes[$exclude_id]);
         }
     }
     // Add backup archive directory to be excluded.
     array_push($excludes, ltrim(str_replace(rtrim(ABSPATH, '\\\\/'), '', $this->_options['backup_directory']), ' \\/'));
     // Exclude backup directory with other archives.
     /*
     if ( $this->_options['force_compatibility'] == 1 ) {
     	$this->status( 'message', 'Forcing compatibility mode (PCLZip) based on settings. This is slower and less reliable.' );
     	$this->_parent->_zipbuddy->set_zip_methods( array( 'pclzip' ) );
     }
     */
     if ($this->_options['compression'] == '1') {
         $compression = true;
     } else {
         $compression = false;
     }
     if ($this->_backup['type'] == 'full') {
         $directory_to_add = ABSPATH;
     } elseif ($this->_backup['type'] == 'db') {
         $directory_to_add = $this->_backup['temp_directory'];
     } else {
         $this->status('error', __('Backup FAILED. Unknown backup type.', 'it-l10n-backupbuddy'));
         $this->status('action', 'halt_script');
         // Halt JS on page.
     }
     if ($this->_options['log_level'] == 3) {
         // If full logging mode then output exec() response to details.
         $quiet_response = false;
     } else {
         $quiet_response = true;
     }
     $this->_parent->_zipbuddy->set_status_callback(array(&$this, 'status'));
     // Set logging callback.
     if (defined('PB_DEMO_MODE')) {
         $this->status('message', 'Operating in demonstration mode. Backup file creation will be skipped.');
     } else {
         if ($this->_parent->_zipbuddy->add_directory_to_zip($this->_backup['archive_file'], $directory_to_add, $compression, $excludes, $this->_backup['temporary_zip_directory'], $this->_backup['force_compatibility'], $quiet_response) === true) {
             $this->status('message', __('Backup ZIP file successfully created.', 'it-l10n-backupbuddy'));
             if (chmod($this->_backup['archive_file'], 0644)) {
                 $this->status('details', __('Chmod to 0644 succeeded.', 'it-l10n-backupbuddy'));
             } else {
                 $this->status('details', __('Chmod to 0644 failed.', 'it-l10n-backupbuddy'));
             }
         } else {
             $this->status('error', __('Backup FAILED. Unable to successfully generate ZIP archive. Error #3382.', 'it-l10n-backupbuddy'));
             $this->status('error', __('Error #3382 help: http://ithemes.com/codex/page/BackupBuddy:_Error_Codes#3382', 'it-l10n-backupbuddy'));
             $this->status('action', 'halt_script');
             // Halt JS on page.
             return false;
         }
     }
     // Need to make sure the database connection is active
     // This is not essential so use include and not require (suppress any warning)
     @(include_once $this->_pluginPath . '/lib/wpdbutils/wpdbutils.php');
     if (class_exists('pluginbuddy_wpdbutils')) {
         // This is the database object we want to use
         global $wpdb;
         // Get our helper object and let it use us to output status messages
         $dbhelper = new pluginbuddy_wpdbutils($wpdb, $this);
         $dbhelper->set_status_callback(array(&$this, 'status'));
         // If we cannot kick the database into life then signal the error and return false which will stop the backup
         // Otherwise all is ok and we can just fall through and let the function return true
         if (!$dbhelper->kick()) {
             $this->status('error', __('Backup FAILED. Backup file produced but Database Server has gone away, unable to schedule next backup step', 'it-l10n-backupbuddy'));
             return false;
         }
     } else {
         // Utils not available so cannot verify database connection status - just notify
         $this->status('details', __('Database Server connection status unverified.', 'it-l10n-backupbuddy'));
     }
     return true;
 }