public static function handle_option($option_name) { $ignores = backupbuddy_live::getOption('options_excludes', true); $ignores = array_merge(self::$_options_exclusions, $ignores); // Add hard-coded exclusions. foreach ($ignores as $ignore) { if ($ignore[0] == '/') { if (preg_match($ignore, $option_name)) { // Excluding this option. return $option_name; } } else { if ($option_name == $ignore) { //error_log( 'exclude: ' . $ignore ); return $option_name; } } } if ('' != $option_name) { self::dbqueue('options', 'option_name', $option_name); } return $option_name; }
private static function _step_update_files_list($custom_root = '', $startAt = 0, $items = array()) { $start_time = microtime(true); pb_backupbuddy::status('details', 'Starting to process files; updating files list.'); if (false === self::_load_catalog()) { return false; } if ('' != $custom_root) { pb_backupbuddy::status('details', 'Scanning custom directory: `' . $custom_root . '`.'); sleep(3); // Give WordPress time to make thumbnails, etc. } if (0 == $startAt && '' == $custom_root) { // Reset stats when starting from the beginning of a full file scan (not for custom roots). self::$_state['stats']['files_pending_delete'] = 0; self::$_state['stats']['files_pending_send'] = 0; self::$_state['stats']['files_total_count'] = 0; self::$_state['stats']['files_total_size'] = 0; } // Get Live-specific excludes. $excludes = backupbuddy_live::getOption('file_excludes', true); // Add standard BB excludes we always apply. $excludes = array_unique(array_merge(self::$_default_excludes, backupbuddy_core::get_directory_exclusions(pb_backupbuddy::$options['profiles'][0], $trim_suffix = false, $serial = ''), backupbuddy_core::get_directory_exclusions(array('excludes' => $excludes), $trim_suffix = false, $serial = ''))); pb_backupbuddy::status('details', 'Excluding directories: `' . implode(', ', $excludes) . '`.'); // Generate list of files. if ('' != $custom_root) { $root = $custom_root; } else { $root = ABSPATH; } $root = rtrim($root, '/\\'); // Make sure no trailing slash. $root_len = strlen($root); $custom_root_diff = ''; if ('' != $custom_root) { $custom_root_diff = substr($root, strlen(ABSPATH) - 1); } $destination_settings = self::get_destination_settings(); pb_backupbuddy::status('details', 'Starting deep file scan.'); $max_time = $destination_settings['max_time'] - self::TIME_WIGGLE_ROOM; $files = pb_backupbuddy::$filesystem->deepscandir($root, $excludes, $startAt, $items, $start_time, $max_time - 8); // Additional 5 seconds so that we can add files into catalog after this completes. if (!is_array($files)) { backupbuddy_core::addNotification('live_error', 'BackupBuddy Stash Live Error', $files); pb_backupbuddy::status('error', 'Error #84393434: Halting Stash Live due to error returned by deepscandir: `' . $files . '`.'); return $files; } if (false === $files[0]) { // Format when chunking: array( $finished = false, array( $startAt, $items ) ) pb_backupbuddy::status('details', 'Deep file scan requires chunking.'); return array('File scanning', array($custom_root, $files[1][0], $files[1][1])); } else { pb_backupbuddy::status('details', 'Deep file scan complete.'); } // Remove root from path AND remote directories.. foreach ($files as $i => &$file) { if (is_dir($file)) { // Don't track directories, only actual files. unset($files[$i]); continue 1; } $file = substr($file, $root_len); } // Flip array. $files = array_flip($files); // Check if this file is already in the list or not. $filesAdded = 0; //$addedSinceOutput = 0; //$outputEvery = 20; // Log every X number of files added into catalog. foreach ($files as $file => $ignoreID) { if ('' == $custom_root) { // Only increment existing files if scanning from root (because stats were reset for fresh count). self::$_state['stats']['files_total_count']++; } $pathed_file = $custom_root_diff . $file; // Applies custom root portion if applicable. if (!isset(self::$_catalog[$pathed_file])) { // File not already in signature list. Add it in with initial values. if ('' != $custom_root) { // Was not added earlier yet. self::$_state['stats']['files_total_count']++; } self::$_catalog[$pathed_file] = self::$_signatureDefaults; self::$_catalog[$pathed_file]['a'] = microtime(true); $filesAdded++; self::$_state['stats']['files_pending_send']++; //$addedSinceOutput++; /* if ( ( pb_backupbuddy::$options['log_level'] == '3' ) || ( $addedSinceOutput > $outputEvery ) ) { // Full logging enabled. pb_backupbuddy::status( 'details', 'Added `' . $addedSinceOutput . '` more files. Last file: `' . $pathed_file . '`.' ); if ( $addedSinceOutput > $outputEvery ) { $addedSinceOutput = 0; } } */ if ($filesAdded % 2000 == 0) { self::$_state['stats']['files_to_catalog_percentage'] = round(number_format($filesAdded / count($files) * 100, 2)); self::$_stateObj->save(); } if ('3' == pb_backupbuddy::$options['log_level']) { // Full logging enabled. pb_backupbuddy::status('details', 'Add to catalog: `' . $pathed_file . '`.'); } } else { // Already exists in catalog. if (0 == self::$_catalog[$pathed_file]['b']) { // File not backed up to server yet (pending send). if (true !== self::$_catalog[$pathed_file]['d']) { // Not pending deletion already. if ('' == $custom_root) { // Only increment existing files if scanning from root (because stats were reset for fresh count). self::$_state['stats']['files_pending_send']++; } } } else { // Local file already exists in catalog and on server. Make sure not marked for deletion. if (true === self::$_catalog[$pathed_file]['d']) { // Was marked to delete. Remove deltion mark BUT do rescan in case this is a new version of the file since it was for some reason marked to delete. self::$_catalog[$pathed_file]['d'] = false; // Don't immediately delete. self::$_catalog[$pathed_file]['r'] = 0; // Reset last scan time so it gets re-checked. } } } } // Checking existing catalog files with new scan to see if anything needs deletion. $filesDeleted = 0; //$sinceLogTrim = 0; foreach (self::$_catalog as $signatureFile => &$signatureDetails) { if (true === $signatureDetails['d']) { // Already marked for deletion. continue; } if ('' != $custom_root) { // Custom root. Ignore removing any files not within the custom root since we did not scan those so they are not in the $files array. if ($root != substr($signatureFile, 0, $root_len)) { // Beginning of filename does not match root so not applicable for this scan. Skip. continue; } } if (!isset($files[$signatureFile])) { // File no longer exists in new scan. Mark for deletion. //$sinceLogTrim++; $filesDeleted++; $signatureDetails['d'] = true; self::$_state['stats']['files_pending_delete']++; // If it was not yet backed up, decrease pending count. if (0 == $signatureDetails['b']) { self::$_state['stats']['files_pending_send']--; if (self::$_state['stats']['files_pending_send'] < 0) { self::$_state['stats']['files_pending_send'] = 0; } } self::$_state['stats']['files_total_count']--; if (self::$_state['stats']['files_total_count'] < 0) { self::$_state['stats']['files_total_count'] = 0; } pb_backupbuddy::status('details', 'Remove file that no longer exists locally. Flagging `' . $signatureFile . '` for deletion.'); /* if ( $sinceLogTrim > 1000 ) { $sinceLogTrim = 0; self::$_catalogObj->save(); // In case it dies. self::_truncate_log(); } */ } } self::$_catalogObj->save(); pb_backupbuddy::status('details', 'Signatures saved. Added `' . $filesAdded++ . '` files to local catalog. Marked `' . $filesDeleted . '` files deleted. Took `' . (microtime(true) - $start_time) . '` seconds.'); return true; }