Exemplo n.º 1
0
 function register_cron($run_immediately = false)
 {
     if ($this->check_cron_registered()) {
         $this->unregister_cron();
     }
     wp_schedule_event($this->o['cron_time'], $this->o['refresh_period'], $this->cron_event);
     if ($run_immediately) {
         spawn_cron();
     }
 }
 private function handle_subscription()
 {
     if ($_SERVER['REQUEST_METHOD'] == 'GET') {
         Header('Content-Type: text/plain');
         $this->send_text('200 OK', $_GET['hub_challenge']);
     } else {
         wp_schedule_single_event(time(), 'degg_instagram_fetch', array($this->client_id, $this->tag));
         spawn_cron(time());
         $this->send_text('200 OK', "OK");
     }
 }
Exemplo n.º 3
0
 function cron_next_step($spawn_cron = true)
 {
     $this->status('details', 'Scheduling Cron for ' . $this->_backup['serial'] . '.');
     $this->log('Scheduling Cron for ' . $this->_backup['serial'] . '.');
     wp_schedule_single_event(time(), $this->_parent->_var . '-cron_process_backup', array($this->_backup['serial']));
     if ($spawn_cron === true) {
         spawn_cron(time() + 150);
         // Adds > 60 seconds to get around once per minute cron running limit.
     }
     update_option('_transient_doing_cron', 0);
     // Prevent cron-blocking for next item.
 }
 /**
  * Schedule a run at time "$time" unless a it's already scheduled or running
  *
  * @param integer $time     Unix timestamp
  * @param bool    $forceRun If true, schedule a run regardless of whether it's already running and/or scheduled
  * @param array   $args
  *
  * @return bool
  */
 function runAt($time, $forceRun = false, $args = array())
 {
     if ($forceRun || !$this->isScheduled()) {
         if ($forceRun || !$this->isRunning()) {
             $this->log->info("{$this->cronHook}: schedule at {$time}");
             $this->timestamp = $time;
             $this->args = $args;
             wp_schedule_single_event($time, $this->cronHook, $args);
             spawn_cron();
             return true;
         } else {
             $this->log->info("{$this->cronHook}: schedule at {$time} but is already running");
         }
     } else {
         $this->log->info("{$this->cronHook}: schedule at {$time} but is already scheduled");
     }
     return false;
 }
 /**
  * Kicks of an import or export cronjob.
  *
  * @param $type
  */
 protected function start_cron($type)
 {
     update_option('_wpghs_' . $type . '_started', 'yes');
     wp_schedule_single_event(time(), 'wpghs_' . $type . '');
     spawn_cron();
 }
Exemplo n.º 6
0
function wp_cron() {
	// Prevent infinite loops caused by lack of wp-cron.php
	if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false )
		return;

	$crons = _get_cron_array();

	if ( !is_array($crons) )
		return;

	$keys = array_keys( $crons );
	if ( isset($keys[0]) && $keys[0] > time() )
		return;

	$schedules = wp_get_schedules();
	foreach ( $crons as $timestamp => $cronhooks ) {
		if ( $timestamp > time() ) break;
		foreach ( $cronhooks as $hook => $args ) {
			if ( isset($schedules[$hook]['callback']) && !call_user_func( $schedules[$hook]['callback'] ) )
				continue;
			spawn_cron();
			break 2;
		}
	}
}
Exemplo n.º 7
0
 public static function send($settings = array(), $files = array(), $clear_uploads = false)
 {
     global $pb_backupbuddy_destination_errors;
     if (!is_array($files)) {
         $files = array($files);
     }
     if ($clear_uploads === false) {
         // Uncomment the following line to override and always clear.
         //$clear_uploads = true;
     }
     $itxapi_username = $settings['itxapi_username'];
     $itxapi_password = $settings['itxapi_password'];
     $db_archive_limit = $settings['db_archive_limit'];
     $full_archive_limit = $settings['full_archive_limit'];
     $max_chunk_size = $settings['max_chunk_size'];
     $remote_path = self::get_remote_path($settings['directory']);
     // Has leading and trailng slashes.
     if ($settings['ssl'] == '0') {
         $disable_ssl = true;
     } else {
         $disable_ssl = false;
     }
     $multipart_id = $settings['_multipart_id'];
     $multipart_counts = $settings['_multipart_counts'];
     pb_backupbuddy::status('details', 'Stash remote path set to `' . $remote_path . '`.');
     require_once dirname(__FILE__) . '/lib/class.itx_helper.php';
     require_once dirname(__FILE__) . '/lib/aws-sdk/sdk.class.php';
     // Stash API talk.
     $stash = new ITXAPI_Helper(pb_backupbuddy_destination_stash::ITXAPI_KEY, pb_backupbuddy_destination_stash::ITXAPI_URL, $itxapi_username, $itxapi_password);
     $manage_data = pb_backupbuddy_destination_stash::get_manage_data($settings);
     // Wipe all current uploads.
     if ($clear_uploads === true) {
         pb_backupbuddy::status('details', 'Clearing any current uploads via Stash call to `abort-all`.');
         $abort_url = $stash->get_upload_url(null, 'abort-all');
         $request = new RequestCore($abort_url);
         //pb_backupbuddy::status('details', print_r( $request , true ) );
         $response = $request->send_request(true);
     }
     // Process multipart transfer that we already initiated in a previous PHP load.
     if ($multipart_id != '') {
         // Multipart upload initiated and needs parts sent.
         // Create S3 instance.
         pb_backupbuddy::status('details', 'Creating Stash S3 instance.');
         $s3 = new AmazonS3($settings['_multipart_upload_data']['credentials']);
         // the key, secret, token
         if ($disable_ssl === true) {
             @$s3->disable_ssl(true);
         }
         pb_backupbuddy::status('details', 'Stash S3 instance created.');
         $this_part_number = $settings['_multipart_partnumber'] + 1;
         pb_backupbuddy::status('details', 'Stash beginning upload of part `' . $this_part_number . '` of `' . count($settings['_multipart_counts']) . '` parts of file `' . $settings['_multipart_file'] . '` with multipart ID `' . $settings['_multipart_id'] . '`.');
         $response = $s3->upload_part($settings['_multipart_upload_data']['bucket'], $settings['_multipart_upload_data']['object'], $settings['_multipart_id'], array('expect' => '100-continue', 'fileUpload' => $settings['_multipart_file'], 'partNumber' => $this_part_number, 'seekTo' => (int) $settings['_multipart_counts'][$settings['_multipart_partnumber']]['seekTo'], 'length' => (int) $settings['_multipart_counts'][$settings['_multipart_partnumber']]['length']));
         if (!$response->isOK()) {
             $this_error = 'Stash unable to upload file part for multipart upload `' . $settings['_multipart_id'] . '`. Details: `' . print_r($response, true) . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         }
         // Update stats.
         foreach (pb_backupbuddy::$options['remote_sends'] as $identifier => $remote_send) {
             if (isset($remote_send['_multipart_id']) && $remote_send['_multipart_id'] == $multipart_id) {
                 // this item.
                 pb_backupbuddy::$options['remote_sends'][$identifier]['_multipart_status'] = 'Sent part ' . $this_part_number . ' of ' . count($settings['_multipart_counts']) . '.';
                 if ($this_part_number == count($settings['_multipart_counts'])) {
                     pb_backupbuddy::$options['remote_sends'][$identifier]['_multipart_status'] .= '<br>Success.';
                     pb_backupbuddy::$options['remote_sends'][$identifier]['finish_time'] = time();
                 }
                 pb_backupbuddy::save();
                 break;
             }
         }
         // Made it here so success sending part. Increment for next part to send.
         $settings['_multipart_partnumber']++;
         if (!isset($settings['_multipart_counts'][$settings['_multipart_partnumber']])) {
             // No more parts exist for this file. Tell S3 the multipart upload is complete and move on.
             pb_backupbuddy::status('details', 'Stash getting parts with etags to notify S3 of completed multipart send.');
             $etag_parts = $s3->list_parts($settings['_multipart_upload_data']['bucket'], $settings['_multipart_upload_data']['object'], $settings['_multipart_id']);
             pb_backupbuddy::status('details', 'Stash got parts list. Notifying S3 of multipart upload completion.');
             $response = $s3->complete_multipart_upload($settings['_multipart_upload_data']['bucket'], $settings['_multipart_upload_data']['object'], $settings['_multipart_id'], $etag_parts);
             if (!$response->isOK()) {
                 $this_error = 'Stash unable to notify S3 of completion of all parts for multipart upload `' . $settings['_multipart_id'] . '`.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 pb_backupbuddy::status('details', 'Stash notified S3 of multipart completion.');
             }
             // Notify Stash API that things were succesful.
             $done_url = $stash->get_upload_url($settings['_multipart_file'], 'done', $remote_path . $settings['_multipart_backup_type_dir'] . basename($settings['_multipart_file']));
             pb_backupbuddy::status('details', 'Notifying Stash of completed multipart upload with done url `' . $done_url . '`.');
             $request = new RequestCore($done_url);
             $response = $request->send_request(true);
             if (!$response->isOK()) {
                 $this_error = 'Error #756834682. Could not finalize Stash upload. Response code: `' . $response->get_response_code() . '`; Response body: `' . $response->get_response_body() . '`; Response headers: `' . $response->get_response_header() . '`.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 // Good server response.
                 // See if we got an optional json response.
                 $upload_data = @json_decode($response->body, true);
                 if (isset($upload_data['error'])) {
                     $this_error = 'Stash error(s): `' . implode(' - ', $upload_data['error']) . '`.';
                     $pb_backupbuddy_destination_errors[] = $this_error;
                     pb_backupbuddy::status('error', $this_error);
                     return false;
                 }
                 pb_backupbuddy::status('details', 'Stash success sending file `' . basename($settings['_multipart_file']) . '`. File uploaded via multipart across `' . $this_part_number . '` parts and reported to Stash as completed.');
             }
             pb_backupbuddy::status('details', 'Stash has no more parts left for this multipart upload. Clearing multipart instance variables.');
             $settings['_multipart_partnumber'] = 0;
             $settings['_multipart_id'] = '';
             $settings['_multipart_file'] = '';
             $settings['_multipart_counts'] = array();
             $settings['_multipart_upload_data'] = array();
         }
         delete_transient('pb_backupbuddy_stashquota_' . $settings['itxapi_username']);
         // Delete quota transient since it probably has changed now.
         // Schedule to continue if anything is left to upload for this multipart of any individual files.
         if ($settings['_multipart_id'] != '' || count($files) > 0) {
             pb_backupbuddy::status('details', 'Stash multipart upload has more parts left. Scheduling next part send.');
             wp_schedule_single_event(time(), pb_backupbuddy::cron_tag('destination_send'), array($settings, $files, 'multipart', false));
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             pb_backupbuddy::status('details', 'Stash scheduled send of next part(s). Done for this cycle.');
             return array($settings['_multipart_id'], 'Sent ' . $this_part_number . ' of ' . count($multipart_destination_settings['_multipart_counts'] . ' parts.'));
         }
     }
     // Upload each file.
     foreach ($files as $file_id => $file) {
         // Determine backup type directory (if zip).
         $backup_type_dir = '';
         $backup_type = '';
         if (stristr($file, '.zip') !== false) {
             // If a zip try to determine backup type.
             pb_backupbuddy::status('details', 'Stash: Zip file. Detecting backup type if possible.');
             $serial = pb_backupbuddy::$classes['core']->get_serial_from_file($file);
             if (isset(pb_backupbuddy::$options['backups'][$serial]['integrity']['detected_type'])) {
                 pb_backupbuddy::status('details', 'Stash: Detected backup type as `' . pb_backupbuddy::$options['backups'][$serial]['integrity']['detected_type'] . '` via integrity check data.');
                 $backup_type_dir = pb_backupbuddy::$options['backups'][$serial]['integrity']['detected_type'] . '/';
                 $backup_type = pb_backupbuddy::$options['backups'][$serial]['integrity']['detected_type'];
             } else {
                 if (stristr($file, '-db-') !== false) {
                     pb_backupbuddy::status('details', 'Stash: Detected backup type as `db` via filename.');
                     $backup_type_dir = 'db/';
                     $backup_type = 'db';
                 } elseif (stristr($file, '-full-') !== false) {
                     pb_backupbuddy::status('details', 'Stash: Detected backup type as `full` via filename.');
                     $backup_type_dir = 'full/';
                     $backup_type = 'full';
                 } else {
                     pb_backupbuddy::status('details', 'Stash: Could not detect backup type via integrity details nor filename.');
                 }
             }
         }
         // Interact with Stash API.
         pb_backupbuddy::status('details', 'Determining Stash upload URL for `' . $file . '`.` with destination remote path `' . $remote_path . $backup_type_dir . basename($file) . '`.');
         $upload_url = $stash->get_upload_url($file, 'request', $remote_path . $backup_type_dir . basename($file));
         pb_backupbuddy::status('details', 'Determined upload url: `' . $upload_url . '`.');
         $request = new RequestCore($upload_url);
         pb_backupbuddy::status('details', 'Sending Stash API request.');
         $response = $request->send_request(true);
         // Validate response.
         if (!$response->isOK()) {
             $this_error = 'Stash request for upload credentials failed.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         }
         if (!($upload_data = json_decode($response->body, true))) {
             $this_error = 'Stash API did not give a valid JSON response.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         }
         if (isset($upload_data['error'])) {
             $this_error = 'Stash error(s): `' . implode(' - ', $upload_data['error']) . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         }
         // Calculate meta data to send.
         /*
         $meta_array = array();
         if ( stristr( $file, '.zip' ) !== false ) { // If a zip try to determine backup type.
         	pb_backupbuddy::status( 'details', 'Stash: Zip file. Detecting backup type if possible.' );
         	$serial = pb_backupbuddy::$classes['core']->get_serial_from_file( $file );
         	if ( isset( pb_backupbuddy::$options['backups'][$serial]['integrity']['detected_type'] ) ) {
         		pb_backupbuddy::status( 'details', 'Stash: Detected backup type as `' . pb_backupbuddy::$options['backups'][$serial]['integrity']['detected_type'] . '` via integrity check data.' );
         		$meta_array['backup_type'] = pb_backupbuddy::$options['backups'][$serial]['integrity']['detected_type'];
         	} else {
         		if ( stristr( $file, '-db-' ) !== false ) {
         			pb_backupbuddy::status( 'details', 'Stash: Detected backup type as `db` via filename.' );
         			$meta_array['backup_type'] = 'db';
         		} elseif ( stristr( $file, '-full-' ) !== false ) {
         			pb_backupbuddy::status( 'details', 'Stash: Detected backup type as `full` via filename.' );
         			$meta_array['backup_type'] = 'full';
         		} else {
         			pb_backupbuddy::status( 'details', 'Stash: Could not detect backup type via integrity details nor filename.' );
         		}
         	}
         }
         */
         // Create S3 instance.
         pb_backupbuddy::status('details', 'Creating Stash S3 instance.');
         $s3 = new AmazonS3($upload_data['credentials']);
         // the key, secret, token
         if ($disable_ssl === true) {
             @$s3->disable_ssl(true);
         }
         pb_backupbuddy::status('details', 'Stash S3 instance created.');
         // Handle chunking of file into a multipart upload (if applicable).
         $file_size = filesize($file);
         if ($max_chunk_size >= 5 && $file_size / 1024 / 1024 > $max_chunk_size) {
             // minimum chunk size is 5mb. Anything under 5mb we will not chunk.
             pb_backupbuddy::status('details', 'Stash file size of ' . $file_size / 1024 / 1024 . 'MB exceeds max chunk size of ' . $max_chunk_size . 'MB set in settings for sending file as multipart upload.');
             // Initiate multipart upload with S3.
             pb_backupbuddy::status('details', 'Initiating Stash multipart upload.');
             $response = $s3->initiate_multipart_upload($upload_data['bucket'], $upload_data['object'], array('encryption' => 'AES256'));
             if (!$response->isOK()) {
                 $this_error = 'Stash was unable to initiate multipart upload.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 $upload_id = (string) $response->body->UploadId;
                 pb_backupbuddy::status('details', 'Stash initiated multipart upload with ID `' . $upload_id . '`.');
             }
             // Get chunk parts for multipart transfer.
             pb_backupbuddy::status('details', 'Stash getting multipart counts.');
             $parts = $s3->get_multipart_counts($file_size, $max_chunk_size * 1024 * 1024);
             // Size of chunks expected to be in bytes.
             $multipart_destination_settings = $settings;
             $multipart_destination_settings['_multipart_id'] = $upload_id;
             $multipart_destination_settings['_multipart_partnumber'] = 0;
             $multipart_destination_settings['_multipart_file'] = $file;
             $multipart_destination_settings['_multipart_counts'] = $parts;
             $multipart_destination_settings['_multipart_upload_data'] = $upload_data;
             $multipart_destination_settings['_multipart_backup_type_dir'] = $backup_type_dir;
             pb_backupbuddy::status('details', 'Stash multipart settings to pass:'******'details', 'Stash scheduling send of next part(s).');
             wp_schedule_single_event(time(), pb_backupbuddy::cron_tag('destination_send'), array($multipart_destination_settings, $files, 'multipart', false));
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             pb_backupbuddy::status('details', 'Stash scheduled send of next part(s). Done for this cycle.');
             return array($upload_id, 'Starting send of ' . count($multipart_destination_settings['_multipart_counts']) . ' parts.');
         } else {
             if ($max_chunk_size != '0') {
                 pb_backupbuddy::status('details', 'File size of ' . $file_size / 1024 / 1024 . 'MB is less than the max chunk size of ' . $max_chunk_size . 'MB; not chunking into multipart upload.');
             } else {
                 pb_backupbuddy::status('details', 'Max chunk size set to zero so not chunking into multipart upload.');
             }
         }
         // SEND file.
         pb_backupbuddy::status('details', 'About to put (upload) object to Stash.');
         $response = $s3->create_object($upload_data['bucket'], $upload_data['object'], array('fileUpload' => $file, 'encryption' => 'AES256'));
         //  we can also utilize the multi-part-upload to create an object
         //  $response = $s3->create_mpu_object($upload_data['bucket'], $upload_data['object'], array('fileUpload'=>$upload_file));
         // Validate response. On failure notify Stash API that things went wrong.
         if (!$response->isOK()) {
             pb_backupbuddy::status('details', 'Sending upload abort.');
             $request = new RequestCore($abort_url);
             $response = $request->send_request(true);
             $this_error = 'Could not upload to Stash, attempt aborted.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             //	pb_backupbuddy::status( 'details', 'Stash file upload speed: ' . ( $response->header['_info']['speed_upload'] / 1024 / 1024 ) . 'MB/sec. This number may be invalid for small file transfers.' );
             pb_backupbuddy::status('details', 'Stash put success. Need to nofity Stash of upload completion. Details: `' . print_r($response, true) . '`.');
         }
         delete_transient('pb_backupbuddy_stashquota_' . $settings['itxapi_username']);
         // Delete quota transient since it probably has changed now.
         // Notify Stash API that things were succesful.
         $done_url = $stash->get_upload_url($file, 'done', $remote_path . $backup_type_dir . basename($file));
         pb_backupbuddy::status('details', 'Notifying Stash of completed upload with done url `' . $done_url . '`.');
         $request = new RequestCore($done_url);
         $response = $request->send_request(true);
         if (!$response->isOK()) {
             $this_error = 'Error #756834682. Could not finalize Stash upload. Response code: `' . $response->get_response_code() . '`; Response body: `' . $response->get_response_body() . '`; Response headers: `' . $response->get_response_header() . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             // Good server response.
             // See if we got an optional json response.
             $upload_data = @json_decode($response->body, true);
             if (isset($upload_data['error'])) {
                 // Some kind of error.
                 $this_error = 'Stash error(s): `' . implode(' - ', $upload_data['error']) . '`.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             }
             unset($files[$file_id]);
             // Remove from list of files we have not sent yet.
             pb_backupbuddy::status('details', 'Stash success sending file `' . basename($file) . '`. File uploaded and reported to Stash as completed.');
         }
         // Enforce archive limits if applicable.
         if ($backup_type == 'full') {
             $limit = $full_archive_limit;
             pb_backupbuddy::status('details', 'Stash full backup archive limit of `' . $limit . '` based on destination settings.');
         } elseif ($backup_type == 'db') {
             $limit = $db_archive_limit;
             pb_backupbuddy::status('details', 'Stash database backup archive limit of `' . $limit . '` based on destination settings.');
         } else {
             $limit = 0;
             pb_backupbuddy::status('error', 'Error #54854895. Stash was unable to determine backup type so archive limits NOT enforced for this backup.');
         }
         if ($limit > 0) {
             pb_backupbuddy::status('details', 'Stash archive limit enforcement beginning.');
             // S3 object for managing files.
             $s3_manage = new AmazonS3($manage_data['credentials']);
             if ($disable_ssl === true) {
                 @$s3_manage->disable_ssl(true);
             }
             // Get file listing.
             $response_manage = $s3_manage->list_objects($manage_data['bucket'], array('prefix' => $manage_data['subkey'] . $remote_path . $backup_type_dir));
             // list all the files in the subscriber account
             // Create array of backups and organize by date
             $prefix = pb_backupbuddy::$classes['core']->backup_prefix();
             // List backups associated with this site by date.
             $backups = array();
             foreach ($response_manage->body->Contents as $object) {
                 $file = str_replace($manage_data['subkey'] . $remote_path . $backup_type_dir, '', $object->Key);
                 // Stash stores files in a directory per site so no need to check prefix here! if ( false !== strpos( $file, 'backup-' . $prefix . '-' ) ) { // if backup has this site prefix...
                 $backups[$file] = strtotime($object->LastModified);
                 //}
             }
             arsort($backups);
             //error_log( 'backups: ' . print_r( $backups, true ) );
             pb_backupbuddy::status('details', 'Stash found `' . count($backups) . '` backups of this type when checking archive limits.');
             if (count($backups) > $limit) {
                 pb_backupbuddy::status('details', 'More archives (' . count($backups) . ') than limit (' . $limit . ') allows. Trimming...');
                 $i = 0;
                 $delete_fail_count = 0;
                 foreach ($backups as $buname => $butime) {
                     $i++;
                     if ($i > $limit) {
                         pb_backupbuddy::status('details', 'Trimming excess file `' . $buname . '`...');
                         $response = $s3_manage->delete_object($manage_data['bucket'], $manage_data['subkey'] . $remote_path . $backup_type_dir . $buname);
                         if (!$response->isOK()) {
                             pb_backupbuddy::status('details', 'Unable to delete excess Stash file `' . $buname . '`. Details: `' . print_r($response, true) . '`.');
                             $delete_fail_count++;
                         }
                     }
                 }
                 pb_backupbuddy::status('details', 'Finished trimming excess backups.');
                 if ($delete_fail_count !== 0) {
                     $error_message = 'Stash remote limit could not delete ' . $delete_fail_count . ' backups.';
                     pb_backupbuddy::status('error', $error_message);
                     pb_backupbuddy::$classes['core']->mail_error($error_message);
                 }
             }
             pb_backupbuddy::status('details', 'Stash completed archive limiting.');
         } else {
             pb_backupbuddy::status('details', 'No Stash archive file limit to enforce.');
         }
         // End remote backup limit
     }
     // end foreach.
     // Success if we made it this far.
     return true;
 }
Exemplo n.º 8
0
function wp_cron() {
	$crons = _get_cron_array();
	
	if ( !is_array($crons) )
		return;

	$keys = array_keys( $crons );
	if ( isset($keys[0]) && $keys[0] > time() )
		return;

	$schedules = wp_get_schedules();
	foreach ( $crons as $timestamp => $cronhooks ) {
		if ( $timestamp > time() ) break;
		foreach ( $cronhooks as $hook => $args ) {
			if ( isset($schedules[$hook]['callback']) && !call_user_func( $schedules[$hook]['callback'] ) )
				continue;
			spawn_cron();
			break 2;
		}
	}
}
Exemplo n.º 9
0
 public static function send($settings = array(), $files = array(), $send_id = '', $delete_after = false)
 {
     global $pb_backupbuddy_destination_errors;
     if ('1' == $settings['disabled']) {
         $pb_backupbuddy_destination_errors[] = __('Error #48933: This destination is currently disabled. Enable it under this destination\'s Advanced Settings.', 'it-l10n-backupbuddy');
         return false;
     }
     if (!is_array($files)) {
         $files = array($files);
     }
     self::$_timeStart = microtime(true);
     if (count($files) > 1) {
         $message = 'Error #84545894585: This destination currently only supports one file per send.';
         pb_backupbuddy::status('error', $message);
         global $pb_backupbuddy_destination_errors;
         $pb_backupbuddy_destination_errors[] = $message;
         return false;
     }
     require_once pb_backupbuddy::plugin_path() . '/classes/remote_api.php';
     $apiSettings = backupbuddy_remote_api::key_to_array($settings['api_key']);
     if (site_url() == $apiSettings['siteurl']) {
         $message = 'Error #4389843. You are trying to use this site\'s own API key. You must use the API key from the remote destination site.';
         pb_backupbuddy::status('error', $message);
         global $pb_backupbuddy_destination_errors;
         $pb_backupbuddy_destination_errors[] = $message;
         return false;
     }
     $apiURL = $apiSettings['siteurl'];
     $file = $files[0];
     $filePath = '';
     if ('' != $settings['sendFilePath']) {
         $filePath = $settings['sendFilePath'];
     }
     $maxPayload = $settings['max_payload'] * 1024 * 1024;
     // Convert to bytes.
     $encodeReducedPayload = floor(($settings['max_payload'] - $settings['max_payload'] * 0.37) * 1024 * 1024);
     // Take into account 37% base64 encoding overhead. Convert to bytes. Remove any decimals down via floor.
     // Open file for reading.
     if (FALSE === ($fs = @fopen($file, 'r'))) {
         pb_backupbuddy::status('error', 'Error #438934894: Unable to open file `' . $file . '` for reading.');
         return false;
     }
     // If chunked resuming then seek to the correct place in the file.
     if ('' != $settings['resume_point'] && $settings['resume_point'] > 0) {
         // Resuming send of a partially transferred file.
         if (0 !== fseek($fs, $settings['resume_point'])) {
             // Returns 0 on success.
             pb_backupbuddy::status('error', 'Error #327834783: Failed to seek file to resume point `' . $settings['resume_point'] . '` via fseek().');
             return false;
         }
         $prevPointer = $settings['resume_point'];
     } else {
         // New file send.
         $size = filesize($file);
         $encodedSize = $size * 0.37 + $size;
         pb_backupbuddy::status('details', 'File size of file to send: ' . pb_backupbuddy::$format->file_size($size) . '. After encoding overhead: ' . pb_backupbuddy::$format->file_size($encodedSize));
         if ($encodedSize > $maxPayload) {
             $settings['chunks_total'] = ceil($encodedSize / $maxPayload);
             // $maxPayload );
             pb_backupbuddy::status('details', 'This file + encoding exceeds the maximum per-chunk payload size so will be read in and sent in chunks of ' . $settings['max_payload'] . 'MB (' . $maxPayload . ' bytes) totaling approximately ' . $settings['chunks_total'] . ' chunks.');
         } else {
             pb_backupbuddy::status('details', 'This file + encoding does not exceed per-chunk payload size of ' . $settings['max_payload'] . 'MB (' . $maxPayload . ' bytes) so sending in one pass.');
         }
         $prevPointer = 0;
     }
     pb_backupbuddy::status('details', 'Reading in `' . $encodeReducedPayload . '` bytes at a time to send.');
     $dataRemains = true;
     //$loopCount = 0;
     //$loopTimeSum = 0; // Used for average send time per chunk.
     while (TRUE === $dataRemains && FALSE !== ($fileData = fread($fs, $encodeReducedPayload))) {
         // Grab one chunk of data at a time.
         pb_backupbuddy::status('details', 'Read in file data.');
         if (feof($fs)) {
             pb_backupbuddy::status('details', 'Read to end of file (feof true). No more chunks left after this send.');
             $dataRemains = false;
         }
         $isFileTest = false;
         if (false !== stristr(basename($file), 'remote-send-test.php')) {
             $isFileTest = true;
             $settings['sendType'] = 'test';
         }
         if (true === $dataRemains) {
             $isFileDone = false;
         } else {
             $isFileDone = true;
         }
         if (!isset($size)) {
             $size = '';
         }
         pb_backupbuddy::status('details', 'Connecting to remote server to send data.');
         $response = backupbuddy_remote_api::remoteCall($apiSettings, 'sendFile_' . $settings['sendType'], array(), $settings['max_time'], $file, $fileData, $prevPointer, $isFileTest, $isFileDone, $size, $filePath);
         unset($fileData);
         // Free up memory.
         $settings['chunks_sent']++;
         if (true === $dataRemains) {
             // More chunks remain.
             pb_backupbuddy::status('details', 'Connection finished sending part ' . $settings['chunks_sent'] . ' of ~' . $settings['chunks_total'] . '.');
         } else {
             // No more chunks remain.
             pb_backupbuddy::status('details', 'Connection finished sending final part ' . $settings['chunks_sent'] . '.');
         }
         if (false === $response) {
             echo implode(', ', backupbuddy_remote_api::getErrors()) . ' ';
             pb_backupbuddy::status('error', 'Errors encountered details: ' . implode(', ', backupbuddy_remote_api::getErrors()));
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = backupbuddy_remote_api::getErrors();
             return false;
             //implode( ', ', backupbuddy_remote_api::getErrors() );
         }
         if (FALSE === ($prevPointer = ftell($fs))) {
             pb_backupbuddy::status('error', 'Error #438347844: Unable to get ftell pointer of file handle for passing to prevPointer.');
             @fclose($fs);
             return false;
         } else {
             pb_backupbuddy::status('details', 'File pointer: `' . $prevPointer . '`.');
         }
         if (true === $dataRemains) {
             // More data remains so see if we need to consider chunking to a new PHP process.
             // If we are within X second of reaching maximum PHP runtime then stop here so that it can be picked up in another PHP process...
             if (microtime(true) - self::$_timeStart + self::TIME_WIGGLE_ROOM >= $settings['max_time']) {
                 pb_backupbuddy::status('message', 'Approaching limit of available PHP chunking time of `' . $settings['max_time'] . '` sec. Ran for ' . round(microtime(true) - self::$_timeStart, 3) . ' sec. Proceeding to use chunking.');
                 @fclose($fs);
                 // Tells next chunk where to pick up.
                 $settings['resume_point'] = $prevPointer;
                 // Schedule cron.
                 $cronTime = time();
                 $cronArgs = array($settings, $files, $send_id, $delete_after);
                 $cronHashID = md5($cronTime . serialize($cronArgs));
                 $cronArgs[] = $cronHashID;
                 $schedule_result = backupbuddy_core::schedule_single_event($cronTime, pb_backupbuddy::cron_tag('destination_send'), $cronArgs);
                 if (true === $schedule_result) {
                     pb_backupbuddy::status('details', 'Next Site chunk step cron event scheduled.');
                 } else {
                     pb_backupbuddy::status('error', 'Next Site chunk step cron even FAILED to be scheduled.');
                 }
                 spawn_cron(time() + 150);
                 // Adds > 60 seconds to get around once per minute cron running limit.
                 update_option('_transient_doing_cron', 0);
                 // Prevent cron-blocking for next item.
                 return array($prevPointer, 'Sent part ' . $settings['chunks_sent'] . ' of ~' . $settings['chunks_total'] . ' parts.');
                 // filepointer location, elapsed time during the import
             } else {
                 // End if.
                 pb_backupbuddy::status('details', 'Not approaching time limit.');
             }
         } else {
             pb_backupbuddy::status('details', 'No more data remains (eg for chunking) so finishing up.');
         }
     }
     // end while data remains in file.
     // Update fileoptions stats.
     pb_backupbuddy::status('details', 'About to load fileoptions data.');
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     pb_backupbuddy::status('details', 'Fileoptions instance #20.');
     $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
     if (true !== ($result = $fileoptions_obj->is_ok())) {
         pb_backupbuddy::status('error', __('Fatal Error #9034.279327. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
         return false;
     }
     pb_backupbuddy::status('details', 'Fileoptions data loaded.');
     $fileoptions =& $fileoptions_obj->options;
     $fileoptions['finish_time'] = microtime(true);
     $fileoptions['status'] = 'success';
     $fileoptions['_multipart_status'] = 'Sent all parts.';
     if (isset($uploaded_speed)) {
         $fileoptions['write_speed'] = $uploaded_speed;
     }
     $fileoptions_obj->save();
     unset($fileoptions);
     // Made it this far so completed!
     pb_backupbuddy::status('message', 'Finished sending file. Took ' . round(microtime(true) - self::$_timeStart, 3) . ' seconds this round.');
     pb_backupbuddy::status('deployFileSent', 'File sent.');
     return true;
 }
Exemplo n.º 10
0
 /**
  * Schedule the loading of attachments
  */
 function ScheduleReloadAttachments()
 {
     wp_schedule_single_event(time(), 'wishlistmember_attachments_load');
     spawn_cron(time());
 }
 private static function _verb_getBackupStatus()
 {
     $backupSerial = pb_backupbuddy::_POST('serial');
     pb_backupbuddy::status('details', '*** End Remote Backup Log section', $backupSerial);
     // Place at end of log.
     backupbuddy_api::getBackupStatus($backupSerial);
     // echos out. Use $returnRaw = true for remote_api call for this special verb that does not return json.
     // Fix missing WP cron constant.
     if (!defined('WP_CRON_LOCK_TIMEOUT')) {
         define('WP_CRON_LOCK_TIMEOUT', 60);
         // In seconds
     }
     // Try to force cron to run so that we can push the backup along.
     spawn_cron(time() + 150);
     // Adds > 60 seconds to get around once per minute cron running limit.
 }
Exemplo n.º 12
0
 function ajax_remotesend()
 {
     wp_schedule_single_event(time(), 'pb_backupbuddy-cron_remotesend', array($_POST['destination_id'], $this->_options['backup_directory'] . $_POST['file']));
     spawn_cron(time() + 150);
     // Adds > 60 seconds to get around once per minute cron running limit.
     update_option('_transient_doing_cron', 0);
     // Prevent cron-blocking for next item.
     echo 1;
     die;
 }
Exemplo n.º 13
0
 function cron_next_step($spawn_cron = true, $future_offset = 0)
 {
     pb_backupbuddy::status('details', 'Scheduling Cron for `' . $this->_backup['serial'] . '`.');
     // 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', __('Database Server has gone away, unable to schedule next backup step. The backup cannot continue. This is most often caused by mysql running out of memory or timing out far too early. Please contact your host.', 'it-l10n-backupbuddy'));
             pb_backupbuddy::status('action', 'halt_script');
             // Halt JS on page.
             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'));
     }
     // Schedule event.
     $cron_time = time() + $future_offset;
     $cron_tag = pb_backupbuddy::cron_tag('process_backup');
     $cron_args = array($this->_backup['serial']);
     pb_backupbuddy::status('details', 'Scheduling next step to run at `' . $cron_time . '` (localized time: ' . pb_backupbuddy::$format->date(pb_backupbuddy::$format->localize_time($cron_time)) . ') with cron tag `' . $cron_tag . '` and serial arguments `' . implode(',', $cron_args) . '`.');
     $schedule_result = backupbuddy_core::schedule_single_event($cron_time, $cron_tag, $cron_args);
     if ($schedule_result === false) {
         pb_backupbuddy::status('error', 'Unable to schedule next cron step. Verify that another plugin is not preventing / conflicting.');
     } else {
         pb_backupbuddy::status('details', 'Next step scheduled.');
     }
     // Spawn cron.
     if ($spawn_cron === true) {
         spawn_cron(time() + 150);
         // Adds > 60 seconds to get around once per minute cron running limit.
     }
     update_option('_transient_doing_cron', 0);
     // Prevent cron-blocking for next item.
     pb_backupbuddy::status('details', 'About to run next step. If the backup stalls at this point then something is interfering with the WordPress CRON system such as a caching or scheduling plugin. Try disabling other plugins to see if it resolves issue.  Check the Server Information page cron section to see if the next BackupBuddy step is scheduled to run. Enable "Classic" backup mode on the "Settings" page to rule out non-cron issues.');
     return;
 }
Exemplo n.º 14
0
 public function remote_send()
 {
     if (defined('PB_DEMO_MODE')) {
         die('Access denied in demo mode.');
     }
     if (pb_backupbuddy::_POST('send_importbuddy') == '1') {
         $send_importbuddy = true;
     } else {
         $send_importbuddy = false;
     }
     wp_schedule_single_event(time(), pb_backupbuddy::cron_tag('remote_send'), array($_POST['destination_id'], pb_backupbuddy::$options['backup_directory'] . $_POST['file'], $_POST['trigger'], $send_importbuddy));
     spawn_cron(time() + 150);
     // Adds > 60 seconds to get around once per minute cron running limit.
     update_option('_transient_doing_cron', 0);
     // Prevent cron-blocking for next item.
     echo 1;
     die;
 }
Exemplo n.º 15
0
Arquivo: init.php Projeto: russtx/tac
 public static function send($settings = array(), $files = array(), $send_id = '', $delete_after = false)
 {
     if (!is_array($files)) {
         $files = array($files);
     }
     global $pb_backupbuddy_destination_errors;
     $backup_type_dir = '';
     $region = '';
     $settings['bucket'] = strtolower($settings['bucket']);
     // Buckets must be lowercase.
     if (!is_array($files)) {
         $files = array($files);
     }
     $limit = $settings['archive_limit'];
     $max_chunk_size = $settings['max_chunk_size'];
     $remote_path = self::get_remote_path($settings['directory']);
     // Has leading and trailng slashes.
     if ($settings['ssl'] == '0') {
         $disable_ssl = true;
     } else {
         $disable_ssl = false;
     }
     $multipart_id = $settings['_multipart_id'];
     $multipart_counts = $settings['_multipart_counts'];
     pb_backupbuddy::status('details', 'S3 remote path set to `' . $remote_path . '`.');
     pb_backupbuddy::status('details', 'Loading S3 SDK library file...');
     require_once dirname(dirname(__FILE__)) . '/_s3lib/aws-sdk/sdk.class.php';
     pb_backupbuddy::status('details', 'S3 SDK file loaded.');
     // S3 API talk.
     $manage_data = pb_backupbuddy_destination_s3::get_credentials($settings);
     // Process multipart transfer that we already initiated in a previous PHP load.
     if ($multipart_id != '') {
         // Multipart upload initiated and needs parts sent.
         // Create S3 instance.
         pb_backupbuddy::status('details', 'Creating S3 instance.');
         $s3 = new AmazonS3($manage_data);
         // the key, secret, token
         if ($disable_ssl === true) {
             @$s3->disable_ssl(true);
         }
         pb_backupbuddy::status('details', 'S3 instance created.');
         // Verify bucket exists; create if not. Also set region to the region bucket exists in.
         if (false === self::_prepareBucketAndRegion($s3, $settings)) {
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = 'Could not prepare bucket.';
             return false;
         }
         $this_part_number = $settings['_multipart_partnumber'] + 1;
         pb_backupbuddy::status('details', 'S3 beginning upload of part `' . $this_part_number . '` of `' . count($settings['_multipart_counts']) . '` parts of file `' . $settings['_multipart_file'] . '` to remote location `' . $settings['_multipart_remotefile'] . '` with multipart ID `' . $settings['_multipart_id'] . '`.');
         $response = $s3->upload_part($manage_data['bucket'], $settings['_multipart_remotefile'], $settings['_multipart_id'], array('expect' => '100-continue', 'fileUpload' => $settings['_multipart_file'], 'partNumber' => $this_part_number, 'seekTo' => (int) $settings['_multipart_counts'][$settings['_multipart_partnumber']]['seekTo'], 'length' => (int) $settings['_multipart_counts'][$settings['_multipart_partnumber']]['length']));
         if (!$response->isOK()) {
             $this_error = 'S3 unable to upload file part for multipart upload `' . $settings['_multipart_id'] . '`. Details: `' . print_r($response, true) . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             // Send success.
             pb_backupbuddy::status('details', 'Success sending chunk. Upload details: `' . print_r($response, true) . '`.');
             $uploaded_size = $response->header['_info']['size_upload'];
             $uploaded_speed = $response->header['_info']['speed_upload'];
             pb_backupbuddy::status('details', 'Uploaded size: ' . pb_backupbuddy::$format->file_size($uploaded_size) . ', Speed: ' . pb_backupbuddy::$format->file_size($uploaded_speed) . '/sec.');
         }
         // Load fileoptions to the send.
         pb_backupbuddy::status('details', 'About to load fileoptions data.');
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         pb_backupbuddy::status('details', 'Fileoptions instance #10.');
         $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
         if (true !== ($result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Fatal Error #9034.2344848. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = '#9034.2344848';
             return false;
         }
         pb_backupbuddy::status('details', 'Fileoptions data loaded.');
         $fileoptions =& $fileoptions_obj->options;
         $update_status = 'Sent part ' . $this_part_number . ' of ' . count($settings['_multipart_counts']) . '.';
         // Made it here so success sending part. Increment for next part to send.
         $settings['_multipart_partnumber']++;
         if (!isset($settings['_multipart_counts'][$settings['_multipart_partnumber']])) {
             // No more parts exist for this file. Tell S3 the multipart upload is complete and move on.
             pb_backupbuddy::status('details', 'S3 getting parts with etags to notify S3 of completed multipart send.');
             $etag_parts = $s3->list_parts($manage_data['bucket'], $settings['_multipart_remotefile'], $settings['_multipart_id']);
             pb_backupbuddy::status('details', 'S3 got parts list. Details: ' . print_r($etag_parts, true));
             pb_backupbuddy::status('details', 'Notifying S3 of multipart upload completion.');
             $response = $s3->complete_multipart_upload($manage_data['bucket'], $settings['_multipart_remotefile'], $settings['_multipart_id'], $etag_parts);
             if (!$response->isOK()) {
                 $this_error = 'S3 unable to notify S3 of completion of all parts for multipart upload `' . $settings['_multipart_id'] . '`.';
                 global $pb_backupbuddy_destination_errors;
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 pb_backupbuddy::status('details', 'S3 notified S3 of multipart completion.');
             }
             pb_backupbuddy::status('details', 'S3 has no more parts left for this multipart upload. Clearing multipart instance variables.');
             $settings['_multipart_partnumber'] = 0;
             $settings['_multipart_id'] = '';
             $settings['_multipart_file'] = '';
             $settings['_multipart_remotefile'] = '';
             // Multipart completed so safe to prevent housekeeping of incomplete multipart uploads.
             $settings['_multipart_transferspeeds'][] = $uploaded_speed;
             // Overall upload speed average.
             $uploaded_speed = array_sum($settings['_multipart_transferspeeds']) / count($settings['_multipart_counts']);
             pb_backupbuddy::status('details', 'Upload speed average of all chunks: `' . pb_backupbuddy::$format->file_size($uploaded_speed) . '`.');
             $settings['_multipart_counts'] = array();
             // Update stats.
             $fileoptions['_multipart_status'] = $update_status;
             $fileoptions['finish_time'] = time();
             $fileoptions['status'] = 'success';
             if (isset($uploaded_speed)) {
                 $fileoptions['write_speed'] = $uploaded_speed;
             }
             $fileoptions_obj->save();
             unset($fileoptions);
         }
         // Schedule to continue if anything is left to upload for this multipart of any individual files.
         if ($settings['_multipart_id'] != '' || count($files) > 0) {
             pb_backupbuddy::status('details', 'S3 multipart upload has more parts left. Scheduling next part send.');
             $cronTime = time();
             $cronArgs = array($settings, $files, $send_id, $delete_after);
             $cronHashID = md5($cronTime . serialize($cronArgs));
             $cronArgs[] = $cronHashID;
             $schedule_result = backupbuddy_core::schedule_single_event($cronTime, pb_backupbuddy::cron_tag('destination_send'), $cronArgs);
             if (true === $schedule_result) {
                 pb_backupbuddy::status('details', 'Next S3 chunk step cron event scheduled.');
             } else {
                 pb_backupbuddy::status('error', 'Next S3 chunk step cron even FAILED to be scheduled.');
             }
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             return array($settings['_multipart_id'], 'Sent part ' . $this_part_number . ' of ' . count($settings['_multipart_counts']) . ' parts.');
         }
     }
     // end if multipart continuation.
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     // Upload each file.
     foreach ($files as $file_id => $file) {
         // Determine backup type directory (if zip).
         $backup_type_dir = '';
         $backup_type = '';
         if (stristr($file, '.zip') !== false) {
             // If a zip try to determine backup type.
             pb_backupbuddy::status('details', 'S3: Zip file. Detecting backup type if possible.');
             $serial = backupbuddy_core::get_serial_from_file($file);
             // See if we can get backup type from fileoptions data.
             pb_backupbuddy::status('details', 'Fileoptions instance #9.');
             $backup_options = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt', $read_only = true, $ignore_lock = true);
             if (true !== ($result = $backup_options->is_ok())) {
                 pb_backupbuddy::status('error', 'Unable to open fileoptions file `' . backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt' . '`.');
             } else {
                 if (isset($backup_options->options['integrity']['detected_type'])) {
                     pb_backupbuddy::status('details', 'S3: Detected backup type as `' . $backup_options->options['integrity']['detected_type'] . '` via integrity check data.');
                     //$backup_type_dir = $backup_options->options['integrity']['detected_type'] . '/';
                     $backup_type = $backup_options->options['integrity']['detected_type'];
                 }
             }
             // If still do not know backup type then attempt to deduce it from filename.
             if ($backup_type == '') {
                 if (stristr($file, '-db-') !== false) {
                     pb_backupbuddy::status('details', 'S3: Detected backup type as `db` via filename.');
                     //$backup_type_dir = 'db/';
                     $backup_type = 'db';
                 } elseif (stristr($file, '-full-') !== false) {
                     pb_backupbuddy::status('details', 'S3: Detected backup type as `full` via filename.');
                     //$backup_type_dir = 'full/';
                     $backup_type = 'full';
                 } else {
                     pb_backupbuddy::status('details', 'S3: Could not detect backup type via integrity details nor filename.');
                 }
             }
         }
         $credentials = pb_backupbuddy_destination_s3::get_credentials($settings);
         // Create S3 instance.
         pb_backupbuddy::status('details', 'Creating S3 instance.');
         $s3 = new AmazonS3($credentials);
         // the key, secret, token
         if ($disable_ssl === true) {
             @$s3->disable_ssl(true);
         }
         pb_backupbuddy::status('details', 'S3 instance created.');
         // Verify bucket exists; create if not. Also set region to the region bucket exists in.
         if (false === self::_prepareBucketAndRegion($s3, $settings)) {
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = 'Could not prepare bucket.';
             return false;
         }
         // Handle chunking of file into a multipart upload (if applicable).
         $file_size = filesize($file);
         if ($max_chunk_size >= self::MINIMUM_CHUNK_SIZE && $file_size / 1024 / 1024 > $max_chunk_size) {
             // minimum chunk size is 5mb. Anything under 5mb we will not chunk.
             // About to chunk so cleanup any previous hanging multipart transfers.
             self::multipart_cleanup($settings, $lessLogs = false);
             pb_backupbuddy::status('details', 'S3 file size of ' . pb_backupbuddy::$format->file_size($file_size) . ' exceeds max chunk size of ' . $max_chunk_size . 'MB set in settings for sending file as multipart upload.');
             // Initiate multipart upload with S3.
             pb_backupbuddy::status('details', 'Initiating S3 multipart upload.');
             $response = $s3->initiate_multipart_upload($settings['bucket'], $remote_path . $backup_type_dir . basename($file), array('encryption' => 'AES256'));
             if (!$response->isOK()) {
                 $this_error = 'S3 was unable to initiate multipart upload.';
                 global $pb_backupbuddy_destination_errors;
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 $upload_id = (string) $response->body->UploadId;
                 pb_backupbuddy::status('details', 'S3 initiated multipart upload with ID `' . $upload_id . '`.');
             }
             // Get chunk parts for multipart transfer.
             pb_backupbuddy::status('details', 'S3 getting multipart counts.');
             $parts = $s3->get_multipart_counts($file_size, $max_chunk_size * 1024 * 1024);
             // Size of chunks expected to be in bytes.
             $multipart_destination_settings = $settings;
             $multipart_destination_settings['_multipart_id'] = $upload_id;
             $multipart_destination_settings['_multipart_partnumber'] = 0;
             $multipart_destination_settings['_multipart_file'] = $file;
             $multipart_destination_settings['_multipart_remotefile'] = $remote_path . basename($file);
             $multipart_destination_settings['_multipart_counts'] = $parts;
             pb_backupbuddy::status('details', 'S3 multipart settings to pass:'******'details', 'S3 scheduling send of next part(s).');
             $cronTime = time();
             $cronArgs = array($multipart_destination_settings, $files, $send_id, $delete_after);
             $cronHashID = md5($cronTime . serialize($cronArgs));
             $cronArgs[] = $cronHashID;
             backupbuddy_core::schedule_single_event($cronTime, pb_backupbuddy::cron_tag('destination_send'), $cronArgs);
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             pb_backupbuddy::status('details', 'S3 scheduled send of next part(s). Done for this cycle.');
             return array($upload_id, 'Starting send of ' . count($multipart_destination_settings['_multipart_counts']) . ' parts.');
         } else {
             // did not meet chunking criteria.
             if ($max_chunk_size != '0') {
                 if ($file_size / 1024 / 1024 > self::MINIMUM_CHUNK_SIZE) {
                     pb_backupbuddy::status('details', 'File size of ' . pb_backupbuddy::$format->file_size($file_size) . ' is less than the max chunk size of ' . $max_chunk_size . 'MB; not chunking into multipart upload.');
                 } else {
                     pb_backupbuddy::status('details', 'File size of ' . pb_backupbuddy::$format->file_size($file_size) . ' is less than the minimum allowed chunk size of ' . self::MINIMUM_CHUNK_SIZE . 'MB; not chunking into multipart upload.');
                 }
             } else {
                 pb_backupbuddy::status('details', 'Max chunk size set to zero so not chunking into multipart upload.');
             }
         }
         // SEND file.
         if ('standard' == $settings['storage']) {
             $storageVal = AmazonS3::STORAGE_STANDARD;
         } elseif ('reduced' == $settings['storage']) {
             $storageVal = AmazonS3::STORAGE_REDUCED;
         } else {
             pb_backupbuddy::status('error', 'Error #854784: Unknown S3 storage type: `' . $settings['storage'] . '`.');
         }
         pb_backupbuddy::status('details', 'About to put (upload) object to S3: `' . $remote_path . $backup_type_dir . basename($file) . '`. Storage type: `' . $settings['storage'] . ' (' . $storageVal . ')`.');
         $response = $s3->create_object($settings['bucket'], $remote_path . $backup_type_dir . basename($file), array('fileUpload' => $file, 'encryption' => 'AES256', 'storage' => $storageVal));
         unset($storageVal);
         // Validate response. On failure notify S3 API that things went wrong.
         if (!$response->isOK()) {
             // Send FAILED.
             $this_error = 'Failure uploading file to S3 storage. Failure details: `' . print_r($response, true) . '`';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             // Send SUCCESS.
             pb_backupbuddy::status('details', 'Success uploading file to S3 storage. Upload details: `' . print_r($response, true) . '`.');
             $uploaded_size = $response->header['_info']['size_upload'];
             $uploaded_speed = $response->header['_info']['speed_upload'];
             pb_backupbuddy::status('details', 'Uploaded size: ' . pb_backupbuddy::$format->file_size($uploaded_size) . ', Speed: ' . pb_backupbuddy::$format->file_size($uploaded_speed) . '/sec.');
         }
         unset($files[$file_id]);
         // Remove from list of files we have not sent yet.
         pb_backupbuddy::status('details', 'S3 success sending file `' . basename($file) . '`. File uploaded and reported to S3 as completed.');
         // Load destination fileoptions.
         pb_backupbuddy::status('details', 'About to load fileoptions data.');
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         pb_backupbuddy::status('details', 'Fileoptions instance #8.');
         $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
         if (true !== ($result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Fatal Error #9034.84838. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = '#9034.84838';
             return false;
         }
         pb_backupbuddy::status('details', 'Fileoptions data loaded.');
         $fileoptions =& $fileoptions_obj->options;
         // Save stats.
         if (isset($uploaded_speed)) {
             $fileoptions['write_speed'] = $uploaded_speed;
             $fileoptions_obj->save();
         }
         unset($fileoptions_obj);
     }
     // end foreach.
     // BEGIN backup limits.
     if ($limit > 0) {
         pb_backupbuddy::status('details', 'S3 archive limit enforcement to `' . $limit . '` archives beginning.');
         // S3 object for managing files.
         $s3_manage = new AmazonS3($manage_data);
         if ($disable_ssl === true) {
             @$s3_manage->disable_ssl(true);
         }
         if (false === self::_prepareBucketAndRegion($s3_manage, $settings)) {
             global $pb_backupbuddy_destination_errors;
             $pb_backupbuddy_destination_errors[] = 'Could not prepare bucket.';
             return false;
         }
         // Get file listing.
         $response_manage = $s3_manage->list_objects($manage_data['bucket'], array('prefix' => $remote_path . $backup_type_dir));
         // list all the files in the subscriber account
         // Create array of backups and organize by date
         $prefix = backupbuddy_core::backup_prefix();
         // List backups associated with this site by date.
         $backups = array();
         foreach ($response_manage->body->Contents as $object) {
             $file = str_replace($remote_path . $backup_type_dir, '', $object->Key);
             if (FALSE !== stristr($file, '/')) {
                 // CRITICAL CODE! Subdir found due to slash. Do NOT display any files within a deeper subdirectory. Without this files could be deleted not belonging to this destination!
                 continue;
             }
             if (!preg_match(self::BACKUP_FILENAME_PATTERN, $file)) {
                 // CRITICAL CODE! Safety against accidental deletion of non-BB files. Do NOT delete files that do not look like a BackupBuddy backup filename.
                 continue;
             }
             if (FALSE === strpos($file, 'backup-' . $prefix . '-')) {
                 // Not a backup for THIS site. Skip interacting with for limits.
                 continue;
             }
             // S3 stores files in a directory per site so no need to check prefix here! if ( false !== strpos( $file, 'backup-' . $prefix . '-' ) ) { // if backup has this site prefix...
             $backups[$file] = strtotime($object->LastModified);
         }
         arsort($backups);
         pb_backupbuddy::status('details', 'S3 found `' . count($backups) . '` backups when checking archive limits.');
         if (count($backups) > $limit) {
             pb_backupbuddy::status('details', 'More archives (' . count($backups) . ') than limit (' . $limit . ') allows. Trimming...');
             $i = 0;
             $delete_fail_count = 0;
             foreach ($backups as $buname => $butime) {
                 $i++;
                 if ($i > $limit) {
                     pb_backupbuddy::status('details', 'Trimming excess file `' . $buname . '`...');
                     $response = $s3_manage->delete_object($manage_data['bucket'], $remote_path . $backup_type_dir . $buname);
                     if (!$response->isOK()) {
                         pb_backupbuddy::status('details', 'Unable to delete excess S3 file `' . $buname . '`. Details: `' . print_r($response, true) . '`.');
                         $delete_fail_count++;
                     }
                 }
             }
             pb_backupbuddy::status('details', 'Finished trimming excess backups.');
             if ($delete_fail_count !== 0) {
                 $error_message = 'S3 remote limit could not delete ' . $delete_fail_count . ' backups.';
                 pb_backupbuddy::status('error', $error_message);
                 backupbuddy_core::mail_error($error_message);
             }
         }
         pb_backupbuddy::status('details', 'S3 completed archive limiting.');
     } else {
         pb_backupbuddy::status('details', 'No S3 archive file limit to enforce.');
     }
     // End remote backup limit
     // END backup limits.
     if (isset($fileoptions_obj)) {
         unset($fileoptions_obj);
     }
     // Success if we made it this far.
     return true;
 }
Exemplo n.º 16
0
 /**
  * Sets and kicks off the import cronjob
  */
 public function start_import()
 {
     update_option('_wpghs_import_started', 'yes');
     WordPress_GitHub_Sync::write_log(__('Starting import from GitHub.', WordPress_GitHub_Sync::$text_domain));
     wp_schedule_single_event(time(), 'wpghs_import');
     spawn_cron();
 }
 /**
  * Schedule a site scan immediately unless it's already scheduled or already running
  *
  * @return bool TRUE if the scan was scheduled, false if it wasn't (because it's already scheduled or running)
  */
 function scanSchedule()
 {
     if (!wp_next_scheduled(self::FOODERIFIC_SCAN)) {
         if (get_transient(self::FOODERIFIC_SCAN) != 'run') {
             /**
              * Tell fooderific a scan was scheduled
              * Really only for debugging so we can tell if scans aren't being run
              */
             $data = new stdClass();
             $data->action = 'scheduled';
             $data->wpurl = get_bloginfo("wpurl");
             $data->count = 0;
             $args = array('body' => array('data' => serialize($data)));
             wp_remote_post(self::FOODERIFIC_URL, $args);
             wp_schedule_single_event(time(), self::FOODERIFIC_SCAN, array(0));
             spawn_cron();
             return true;
         } else {
         }
     } else {
     }
     return false;
 }
Exemplo n.º 18
0
 public function remote_send()
 {
     $success_output = false;
     // Set to true onece a leading 1 has been sent to the javascript to indicate success.
     $destination_id = pb_backupbuddy::_POST('destination_id');
     if (pb_backupbuddy::_POST('file') != 'importbuddy.php') {
         $backup_file = backupbuddy_core::getBackupDirectory() . pb_backupbuddy::_POST('file');
         if (!file_exists($backup_file)) {
             // Error if file to send did not exist!
             $error_message = 'Unable to find file `' . $backup_file . '` to send. File does not appear to exist. You can try again in a moment or turn on full error logging and try again to log for support.';
             pb_backupbuddy::status('error', $error_message);
             pb_backupbuddy::alert($error_message, true);
             die;
         }
     } else {
         $backup_file = '';
     }
     // Send ImportBuddy along-side?
     if (pb_backupbuddy::_POST('send_importbuddy') == '1') {
         $send_importbuddy = true;
         pb_backupbuddy::status('details', 'Cron send to be scheduled with importbuddy sending.');
     } else {
         $send_importbuddy = false;
         pb_backupbuddy::status('details', 'Cron send to be scheduled WITHOUT importbuddy sending.');
     }
     // Delete local copy after send completes?
     if (pb_backupbuddy::_POST('delete_after') == 'true') {
         $delete_after = true;
         pb_backupbuddy::status('details', 'Remote send set to delete after successful send.');
     } else {
         $delete_after = false;
         pb_backupbuddy::status('details', 'Remote send NOT set to delete after successful send.');
     }
     // For Stash we will check the quota prior to initiating send.
     if (pb_backupbuddy::$options['remote_destinations'][$destination_id]['type'] == 'stash') {
         // Pass off to destination handler.
         require_once pb_backupbuddy::plugin_path() . '/destinations/bootstrap.php';
         $send_result = pb_backupbuddy_destinations::get_info('stash');
         // Used to kick the Stash destination into life.
         $stash_quota = pb_backupbuddy_destination_stash::get_quota(pb_backupbuddy::$options['remote_destinations'][$destination_id], true);
         if (isset($stash_quota['error'])) {
             echo ' Error accessing Stash account. Send aborted. Details: `' . implode(' - ', $stash_quota['error']) . '`.';
             die;
         }
         if ($backup_file != '') {
             $backup_file_size = filesize($backup_file);
         } else {
             $backup_file_size = 50000;
         }
         if ($backup_file_size + $stash_quota['quota_used'] > $stash_quota['quota_total']) {
             echo "You do not have enough Stash storage space to send this file. Please upgrade your Stash storage or delete files to make space.\n\n";
             echo 'Attempting to send file of size ' . pb_backupbuddy::$format->file_size($backup_file_size) . ' but you only have ' . $stash_quota['quota_available_nice'] . ' available. ';
             echo 'Currently using ' . $stash_quota['quota_used_nice'] . ' of ' . $stash_quota['quota_total_nice'] . ' (' . $stash_quota['quota_used_percent'] . '%).';
             die;
         } else {
             if (isset($stash_quota['quota_warning']) && $stash_quota['quota_warning'] != '') {
                 echo '1Warning: ' . $stash_quota['quota_warning'] . "\n\n";
                 $success_output = true;
             }
         }
     }
     // end if Stash.
     pb_backupbuddy::status('details', 'Scheduling cron to send to this remote destination...');
     $schedule_result = backupbuddy_core::schedule_single_event(time(), pb_backupbuddy::cron_tag('remote_send'), array($destination_id, $backup_file, pb_backupbuddy::_POST('trigger'), $send_importbuddy, $delete_after));
     if ($schedule_result === FALSE) {
         $error = 'Error scheduling file transfer. Please check your BackupBuddy error log for details. A plugin may have prevented scheduling or the database rejected it.';
         pb_backupbuddy::status('error', $error);
         echo $error;
     } else {
         pb_backupbuddy::status('details', 'Cron to send to remote destination scheduled.');
     }
     spawn_cron(time() + 150);
     // Adds > 60 seconds to get around once per minute cron running limit.
     update_option('_transient_doing_cron', 0);
     // Prevent cron-blocking for next item.
     // SEE cron.php remote_send() for sending function that we pass to via the cron above.
     if ($success_output === false) {
         echo 1;
     }
     die;
 }
Exemplo n.º 19
0
 *          it under the terms of the GNU General Public License as published by
 *          the Free Software Foundation; either version 2 of the License, or
 *          (at your option) any later version.
 *
 *          This program is distributed in the hope that it will be useful,
 *          but WITHOUT ANY WARRANTY; without even the implied warranty of
 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *          GNU General Public License for more details.
 *
 *          You should have received a copy of the GNU General Public License
 *          along with this program; if not, write to the Free Software
 *          Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
 */
$config = WPB2D_Factory::get('config');
if (!$config->get_option('in_progress')) {
    spawn_cron();
}
$log = WPB2D_Factory::get('logger')->get_log();
if (empty($log)) {
    ?>
    <p><?php 
    _e('You have not run a backup yet. When you do you will see a log of it here.');
    ?>
</p>
<?php 
} else {
    ?>
    <ul>
        <?php 
    foreach (array_reverse($log) as $log_item) {
        ?>
Exemplo n.º 20
0
 public static function send($settings = array(), $file, $send_id = '', $delete_after = false)
 {
     global $pb_backupbuddy_destination_errors;
     if ('1' == $settings['disabled']) {
         $pb_backupbuddy_destination_errors[] = __('Error #48933: This destination is currently disabled. Enable it under this destination\'s Advanced Settings.', 'it-l10n-backupbuddy');
         return false;
     }
     $settings = self::_init($settings);
     // Handles formatting & sanitizing settings.
     $chunkSizeBytes = $settings['max_burst'] * 1024 * 1024;
     // Send X mb at a time to limit memory usage.
     self::$_timeStart = microtime(true);
     if (pb_backupbuddy::$options['log_level'] == '3') {
         // Full logging enabled.
         pb_backupbuddy::status('details', 'Settings due to log level: `' . print_r($settings, true) . '`.');
     }
     // Initiate multipart upload.
     if ('' == $settings['_multipart_id']) {
         // New transfer. Note: All transfers are handled as presumed multiparts for ease.
         // Handle chunking of file into a multipart upload (if applicable).
         $file_size = filesize($file);
         pb_backupbuddy::status('details', 'File size of `' . pb_backupbuddy::$format->file_size($file_size) . '`.');
         if ('1' != $settings['stash_mode']) {
             // About to chunk so cleanup any previous hanging multipart transfers.
             self::multipart_cleanup($settings);
         }
         // Initiate multipart upload with S3.
         pb_backupbuddy::status('details', 'Initiating multipart transfer.');
         $thisCall = array('Bucket' => $settings['bucket'], 'Key' => $settings['directory'] . basename($file), 'StorageClass' => $settings['storage'], 'ServerSideEncryption' => 'AES256');
         if ('1' == $settings['stash_mode']) {
             $thisCall['Key'] = $settings['_stash_object'];
             unset($thisCall['StorageClass']);
         }
         try {
             $response = self::$_client->createMultipartUpload($thisCall);
         } catch (Exception $e) {
             if (pb_backupbuddy::$options['log_level'] == '3') {
                 // Full logging enabled.
                 pb_backupbuddy::status('details', 'Call details due to logging level: `' . print_r($thisCall, true) . '`.');
             }
             return self::_error('Error #389383: Unable to initiate multipart upload. Details: `' . $e->getMessage() . '`.');
         }
         // Made it here so SUCCESS initiating multipart!
         $upload_id = (string) $response['UploadId'];
         pb_backupbuddy::status('details', 'Initiated multipart upload with ID `' . $upload_id . '`.');
         $backup_type = backupbuddy_core::getBackupTypeFromFile($file);
         // Calculate multipart settings.
         $multipart_destination_settings = $settings;
         $multipart_destination_settings['_multipart_id'] = $upload_id;
         $multipart_destination_settings['_multipart_partnumber'] = 0;
         $multipart_destination_settings['_multipart_file'] = $file;
         $multipart_destination_settings['_multipart_remotefile'] = $settings['directory'] . basename($file);
         if ('1' == $settings['stash_mode']) {
             $multipart_destination_settings['_multipart_remotefile'] = $settings['_stash_object'];
         }
         $multipart_destination_settings['_multipart_counts'] = self::_get_multipart_counts($file_size, $settings['max_burst'] * 1024 * 1024);
         // Size of chunks expected to be in bytes.
         $multipart_destination_settings['_multipart_backup_type'] = $backup_type;
         $multipart_destination_settings['_multipart_backup_size'] = $file_size;
         $multipart_destination_settings['_multipart_etag_parts'] = array();
         //pb_backupbuddy::status( 'details', 'Multipart settings to pass:'******'_multipart_status'] = 'Starting send of ' . count( $multipart_destination_settings['_multipart_counts'] ) . ' parts.';
         pb_backupbuddy::status('details', 'Multipart initiated; passing over to send first chunk this run.');
         $settings = $multipart_destination_settings;
         // Copy over settings.
         unset($multipart_destination_settings);
     }
     // end initiating multipart.
     // Send parts.
     $backup_type = str_replace('/', '', $settings['_multipart_backup_type']);
     // For use later by file limiting.
     $backup_size = $settings['_multipart_backup_size'];
     $maxTime = $settings['max_time'];
     if ('' == $maxTime || !is_numeric($maxTime)) {
         pb_backupbuddy::status('details', 'Max time not set in settings so detecting server max PHP runtime.');
         $maxTime = backupbuddy_core::detectMaxExecutionTime();
     }
     pb_backupbuddy::status('details', 'Using max runtime: `' . $maxTime . '`.');
     // Open file for streaming.
     $f = @fopen($settings['_multipart_file'], 'r');
     if (false === $f) {
         return self::_error('Error #437734. Unable to open file `' . $settings['_multipart_file'] . '` to send. Did it get deleted?');
     }
     $fileDone = false;
     while (!$fileDone && !feof($f)) {
         $sendStart = microtime(true);
         if (!isset($settings['_retry_stash_confirm']) || true !== $settings['_retry_stash_confirm']) {
             // Skip send if only needing to confirm.
             // Made it here so success sending part. Increment for next part to send.
             $settings['_multipart_partnumber']++;
             if (!isset($settings['_multipart_counts'][$settings['_multipart_partnumber'] - 1]['seekTo'])) {
                 pb_backupbuddy::status('error', 'Error #8239933: Missing multipart partnumber to seek to. Settings array: `' . print_r($settings, true) . '`.');
             }
             if (-1 == fseek($f, (int) $settings['_multipart_counts'][$settings['_multipart_partnumber'] - 1]['seekTo'])) {
                 return self::_error('Error #833838: Unable to fseek file.');
             }
             pb_backupbuddy::status('details', 'Beginning upload of part `' . $settings['_multipart_partnumber'] . '` of `' . count($settings['_multipart_counts']) . '` parts of file `' . $settings['_multipart_file'] . '` to remote location `' . $settings['_multipart_remotefile'] . '` with multipart ID `' . $settings['_multipart_id'] . '`.');
             $contentLength = (int) $settings['_multipart_counts'][$settings['_multipart_partnumber'] - 1]['length'];
             $uploadArr = array('Bucket' => $settings['bucket'], 'Key' => $settings['_multipart_remotefile'], 'UploadId' => $settings['_multipart_id'], 'PartNumber' => $settings['_multipart_partnumber'], 'ContentLength' => $contentLength, 'Body' => fread($f, $contentLength));
             //pb_backupbuddy::status( 'details', 'Send array: `' . print_r( $uploadArr, true ) . '`.' );
             //error_log( print_r( $uploadArr, true ) );
             try {
                 $response = self::$_client->uploadPart($uploadArr);
             } catch (Exception $e) {
                 @fclose($f);
                 return self::_error('Error #3897923: Unable to upload file part for multipart upload of ID `' . $settings['_multipart_id'] . '`. Details: `' . $e->getMessage() . '`.');
             }
             self::$_chunksSentThisRound++;
             $settings['_multipart_etag_parts'][] = array('PartNumber' => $settings['_multipart_partnumber'], 'ETag' => $response['ETag']);
             if (pb_backupbuddy::$options['log_level'] == '3') {
                 // Full logging enabled.
                 pb_backupbuddy::status('details', 'Success sending chunk. Upload details due to log level: `' . print_r($response, true) . '`.');
             } else {
                 pb_backupbuddy::status('details', 'Success sending chunk. Enable full logging for upload result details.');
             }
             $uploaded_size = $contentLength;
             $elapseTime = microtime(true) - $sendStart;
             if (0 == $elapseTime) {
                 $elapseTime = 1;
             }
             $uploaded_speed = $uploaded_size / $elapseTime;
             pb_backupbuddy::status('details', 'Uploaded size this burst: `' . pb_backupbuddy::$format->file_size($uploaded_size) . '`, Start time: `' . $sendStart . '`. Finish time: `' . microtime(true) . '`. Elapsed: `' . (microtime(true) - $sendStart) . '`. Speed: `' . pb_backupbuddy::$format->file_size($uploaded_speed) . '`/sec.');
         }
         // Load fileoptions to the send.
         if (isset($fileoptions_obj)) {
             pb_backupbuddy::status('details', 'fileoptions already loaded from prior pass.');
         } else {
             // load fileoptions
             pb_backupbuddy::status('details', 'About to load fileoptions data.');
             require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
             pb_backupbuddy::status('details', 'Fileoptions instance #10.');
             $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
             if (true !== ($result = $fileoptions_obj->is_ok())) {
                 return self::_error(__('Fatal Error #9034.23788723. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
             }
             pb_backupbuddy::status('details', 'Fileoptions data loaded.');
             $fileoptions =& $fileoptions_obj->options;
         }
         //$update_status = 'Sent part ' . $settings['_multipart_partnumber'] . ' of ' . count( $settings['_multipart_counts'] ) . '.';
         if (!isset($settings['_multipart_counts'][$settings['_multipart_partnumber']])) {
             // No more parts exist for this file. Tell S3 the multipart upload is complete and move on.
             if (isset($settings['_retry_stash_confirm']) && true === $settings['_retry_stash_confirm']) {
                 // Need to retry checking that the file confirm was a success.
                 // Grab array of files from customer's stash directory
                 $files = pb_backupbuddy_destination_stash2::listFiles($settings, $settings['_multipart_file']);
                 if (count($files) > 0) {
                     pb_backupbuddy::status('details', 'Stash confirmed upload completition was successful.');
                 } else {
                     pb_backupbuddy::status('error', 'Error #23972793: Error notifying Stash of upload success even after wait. Details: `' . print_r($response, true) . '`.');
                     return false;
                 }
             } else {
                 // Normal Stash part send.
                 $update_status = 'Sent part ' . $settings['_multipart_partnumber'] . ' of ' . count($settings['_multipart_counts']) . ' parts.';
                 pb_backupbuddy::status('details', 'Getting etags and notifying of multipart upload completion.');
                 try {
                     $response = self::$_client->completeMultipartUpload(array('Bucket' => $settings['bucket'], 'UploadId' => $settings['_multipart_id'], 'Key' => $settings['_multipart_remotefile'], 'Parts' => $settings['_multipart_etag_parts']));
                 } catch (Exception $e) {
                     return self::_error('Unable to notify server of completion of all parts for multipart upload `' . $settings['_multipart_id'] . '`. Details: `' . $e->getMessage() . '`.');
                 }
                 pb_backupbuddy::status('details', 'Server notified of multipart completion.');
                 if ('1' == $settings['stash_mode']) {
                     // Stash send confirm.
                     pb_backupbuddy::status('details', 'Notifying Stash of upload completion.');
                     $additionalParams = array('upload_id' => $settings['_stash_upload_id']);
                     $response = pb_backupbuddy_destination_stash2::stashAPI($settings, 'upload-complete', $additionalParams);
                     if (!is_array($response) || !isset($response['success'])) {
                         // If not array OR success key missing. May be a timeout or waiting on AWS system to combine multipart still. Check for file later.
                         $settings['_retry_stash_confirm'] = true;
                         $settings['_multipart_counts'] = array();
                         // No more parts remain.
                         $cronTime = time() + self::STASH_CONFIRM_RETRY_DELAY;
                         $cronArgs = array($settings, $file, $send_id, $delete_after);
                         $cronHashID = md5($cronTime . serialize($cronArgs));
                         $cronArgs[] = $cronHashID;
                         $schedule_result = backupbuddy_core::schedule_single_event($cronTime, 'destination_send', $cronArgs);
                         if (true === $schedule_result) {
                             pb_backupbuddy::status('details', 'Scheduled retry attempt to confirm send in `' . self::STASH_CONFIRM_RETRY_DELAY . '` seconds.');
                         } else {
                             pb_backupbuddy::status('error', 'Scheduled retry attempt FAILED to be scheduled.');
                         }
                         /*
                          *		TODO:	Once PING API is available, request a ping in the future so we make sure this actually runs reasonably soon.
                          *				Because we need a delay we are not firing off the cron here immediately so there will be no chaining of PHP
                          *				which may result in large delays before the next process if there's little site traffic.
                          */
                         return array($settings['_multipart_id'], 'Pending multipart send confirmation.');
                     } else {
                         // Array.
                         if (isset($response['success']) && true !== $response['success']) {
                             // Success key set AND not true.
                             pb_backupbuddy::status('error', 'Error #83298932: Error notifying Stash of upload success. Details: `' . print_r($response, true) . '`.');
                             return false;
                         } else {
                             // Success.
                             pb_backupbuddy::status('details', 'Stash notified of upload completition.');
                         }
                     }
                 }
             }
             // end not a Stash confirm retry.
             pb_backupbuddy::status('details', 'No more parts left for this multipart upload. Clearing multipart instance variables.');
             $settings['_multipart_partnumber'] = 0;
             $settings['_multipart_id'] = '';
             $settings['_multipart_file'] = '';
             $settings['_multipart_remotefile'] = '';
             // Multipart completed so safe to prevent housekeeping of incomplete multipart uploads.
             $settings['_multipart_transferspeeds'][] = $uploaded_speed;
             // Overall upload speed average.
             $uploaded_speed = array_sum($settings['_multipart_transferspeeds']) / count($settings['_multipart_counts']);
             pb_backupbuddy::status('details', 'Upload speed average of all chunks: `' . pb_backupbuddy::$format->file_size($uploaded_speed) . '`.');
             $settings['_multipart_counts'] = array();
             // Update stats.
             $fileoptions['_multipart_status'] = $update_status;
             $fileoptions['finish_time'] = microtime(true);
             $fileoptions['status'] = 'success';
             if (isset($uploaded_speed)) {
                 $fileoptions['write_speed'] = $uploaded_speed;
             }
             $fileoptions_obj->save();
             unset($fileoptions);
             $fileDone = true;
             @fclose($f);
         } else {
             // Parts remain. Schedule to continue if anything is left to upload for this multipart of any individual files.
             pb_backupbuddy::status('details', 'S3 multipart upload has more parts left.');
             $update_status = '<br>';
             $totalSent = 0;
             for ($i = 0; $i < $settings['_multipart_partnumber']; $i++) {
                 $totalSent += $settings['_multipart_counts'][$i]['length'];
             }
             $percentSent = ceil($totalSent / $settings['_multipart_backup_size'] * 100);
             $update_status .= '<div class="backupbuddy-progressbar" data-percent="' . $percentSent . '"><div class="backupbuddy-progressbar-label"></div></div>';
             if ('0' != $maxTime) {
                 // Not unlimited time so see if we can send more bursts this time or if we need to chunk.
                 // If we are within X second of reaching maximum PHP runtime then stop here so that it can be picked up in another PHP process...
                 $totalSizeSent = self::$_chunksSentThisRound * $chunkSizeBytes;
                 // Total bytes sent this PHP load.
                 $bytesPerSec = $totalSizeSent / (microtime(true) - $sendStart);
                 $timeRemaining = $maxTime - (microtime(true) - self::$_timeStart + self::TIME_WIGGLE_ROOM);
                 if ($timeRemaining < 0) {
                     $timeRemaining = 0;
                 }
                 $bytesWeCouldSendWithTimeLeft = $bytesPerSec * $timeRemaining;
                 //pb_backupbuddy::status( 'details', 'Sent this burst: `' . pb_backupbuddy::$format->file_size( $totalSizeSent ) .'` in `' . (microtime(true) - $sendStart ) . '` secs. Speed: `' . pb_backupbuddy::$format->file_size( $bytesPerSec ) . '`/sec. Time Remaining (w/ wiggle): `' . $timeRemaining . '`. Size that could potentially be sent with remaining time: `' . pb_backupbuddy::$format->file_size( $bytesWeCouldSendWithTimeLeft ) . '` with chunk size of `' . pb_backupbuddy::$format->file_size( $chunkSizeBytes ) . '`.' );
                 if ($bytesWeCouldSendWithTimeLeft < $chunkSizeBytes) {
                     // We can send more than a whole chunk (including wiggle room) so send another bit.
                     pb_backupbuddy::status('message', 'Not enough time left (~`' . $timeRemaining . '`) with max time of `' . $maxTime . '` sec to send another chunk at `' . pb_backupbuddy::$format->file_size($bytesPerSec) . '` / sec. Ran for ' . round(microtime(true) - self::$_timeStart, 3) . ' sec. Proceeding to use chunking.');
                     @fclose($fs);
                     $cronTime = time();
                     $cronArgs = array($settings, $file, $send_id, $delete_after);
                     $cronHashID = md5($cronTime . serialize($cronArgs));
                     $cronArgs[] = $cronHashID;
                     $schedule_result = backupbuddy_core::schedule_single_event($cronTime, 'destination_send', $cronArgs);
                     if (true === $schedule_result) {
                         pb_backupbuddy::status('details', 'Next S3 chunk step cron event scheduled.');
                     } else {
                         pb_backupbuddy::status('error', 'Next S3 chunk step cron even FAILED to be scheduled.');
                     }
                     spawn_cron(time() + 150);
                     // Adds > 60 seconds to get around once per minute cron running limit.
                     update_option('_transient_doing_cron', 0);
                     // Prevent cron-blocking for next item.
                     @fclose($f);
                     unset($fileoptions);
                     return array($settings['_multipart_id'], 'Sent part ' . $settings['_multipart_partnumber'] . ' of ' . count($settings['_multipart_counts']) . ' parts.' . $update_status);
                 } else {
                     // End if.
                     pb_backupbuddy::status('details', 'Not approaching limits. Proceeding to next burst this run.');
                 }
             } else {
                 pb_backupbuddy::status('details', 'Max time of zero (0) so assuming unlimited time.');
             }
             $fileoptions['_multipart_status'] = 'Sent part ' . $settings['_multipart_partnumber'] . ' of ' . count($settings['_multipart_counts']) . ' parts.' . $update_status;
             $fileoptions_obj->save();
             //unset( $fileoptions );
         }
         // end no more parts remain.
     }
     // End while not feof.
     /***** BEGIN FILE ARCHIVE LIMITS *****/
     if ('1' == $settings['stash_mode']) {
         // This is being wrapped by the Stash destination. Stash uses a different method of handling archive limiting due to using Stash API.
         pb_backupbuddy_destination_stash2::archiveLimit($settings, $backup_type);
     } else {
         // Normal. This is just a s32 destination.
         self::archiveLimit($settings, $backup_type);
     }
     /***** END FILE ARCHIVE LIMITS *****/
     if (isset($fileoptions_obj)) {
         unset($fileoptions_obj);
     }
     // Success if we made it this far.
     return true;
 }
Exemplo n.º 21
0
 public static function remoteSendRetry(&$fileoptions_obj, $send_id, $maximumRetries = 1)
 {
     // Destination settings are stored for this destination so see if we can retry sending it (if settings permit).
     if (isset($fileoptions_obj->options['destinationSettings']) && count($fileoptions_obj->options['destinationSettings']) > 0) {
         /*
         echo '<pre>';
         print_r( $fileoptions_obj->options );
         echo '</pre>';
         */
         $destination_settings = $fileoptions_obj->options['destinationSettings'];
         // these are the latest; includes info needed for chunking too.
         //$send_id = $fileoptions_obj->options['sendID'];
         $delete_after = $fileoptions_obj->options['deleteAfter'];
         $retries = $fileoptions_obj->options['retries'];
         $file = $fileoptions_obj->options['file'];
         if ($retries < $maximumRetries) {
             pb_backupbuddy::status('details', 'Timed out remote send has not exceeded retry limit (`' . $maximumRetries . '`). Trying to send again.');
             //$fileoptions_obj->options['retries']++;
             //$fileoptions_obj->save(); // NOTE: Retry count now updates in bootstrap.php send() function. Only leaving this here temporarily to help get rid of failed resends from accumulating with old format.
             // Schedule send of this piece.
             pb_backupbuddy::status('details', 'Scheduling cron to send to this remote destination...');
             $cronArgs = array($destination_settings, $file, $send_id, $delete_after, $identifier = '', $isRetry = true);
             /*
             echo 'cronargs: ';
             echo '<pre>';
             print_r( $cronArgs );
             echo '</pre>';
             */
             $schedule_result = backupbuddy_core::schedule_single_event(time(), pb_backupbuddy::cron_tag('destination_send'), $cronArgs);
             if ($schedule_result === FALSE) {
                 $error = 'Error scheduling file transfer. Please check your BackupBuddy error log for details. A plugin may have prevented scheduling or the database rejected it.';
                 pb_backupbuddy::status('error', $error);
                 echo $error;
             } else {
                 pb_backupbuddy::status('details', 'Cron to send to remote destination scheduled.');
             }
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             return true;
         } else {
             pb_backupbuddy::status('details', 'Maximum remote send timeout retries (`' . $maximumRetries . '`) passed to function met. Not resending.');
             return false;
         }
     }
 }
Exemplo n.º 22
0
Arquivo: init.php Projeto: russtx/tac
 public static function send($settings = array(), $files = array(), $send_id = '', $delete_after = false)
 {
     if (!is_array($files)) {
         $files = array($files);
     }
     pb_backupbuddy::status('details', 'Dropbox2 send function started. Remote send id: `' . $send_id . '`.');
     // Normalize settings, apply defaults, etc.
     $settings = self::_normalizeSettings($settings);
     // Connect to Dropbox.
     if (false === self::_connect($settings['access_token'])) {
         // Try to connect. Return false if fail.
         return false;
     }
     $max_chunk_size_bytes = $settings['max_chunk_size'] * 1024 * 1024;
     /***** BEGIN MULTIPART CHUNKED CONTINUE *****/
     // Continue Multipart Chunked Upload
     if ($settings['_chunk_upload_id'] != '') {
         $file = $settings['_chunk_file'];
         pb_backupbuddy::status('details', 'Dropbox (PHP 5.3+) preparing to send chunked multipart upload part ' . ($settings['_chunk_sent_count'] + 1) . ' of ' . $settings['_chunk_total_count'] . ' with set chunk size of `' . $settings['max_chunk_size'] . '` MB. Dropbox Upload ID: `' . $settings['_chunk_upload_id'] . '`.');
         pb_backupbuddy::status('details', 'Opening file `' . basename($file) . '` to send.');
         $f = @fopen($file, 'rb');
         if (false === $f) {
             pb_backupbuddy::status('error', 'Error #87954435. Unable to open file `' . $file . '` to send to Dropbox.');
             return false;
         }
         // Seek to next chunk location.
         pb_backupbuddy::status('details', 'Seeking file to byte `' . $settings['_chunk_next_offset'] . '`.');
         if (0 != fseek($f, $settings['_chunk_next_offset'])) {
             // return of 0 is success.
             pb_backupbuddy::status('error', 'Unable to seek file to proper location offset `' . $settings['_chunk_next_offset'] . '`.');
         } else {
             pb_backupbuddy::status('details', 'Seek success.');
         }
         // Read this file chunk into memory.
         pb_backupbuddy::status('details', 'Reading chunk into memory.');
         try {
             $data = self::readFully($f, $settings['_chunk_maxsize']);
         } catch (\Exception $e) {
             pb_backupbuddy::status('error', 'Dropbox Error #484938376: ' . $e->getMessage());
             return false;
         }
         pb_backupbuddy::status('details', 'About to put chunk to Dropbox for continuation.');
         $send_time = -microtime(true);
         try {
             $result = self::$_dbxClient->chunkedUploadContinue($settings['_chunk_upload_id'], $settings['_chunk_next_offset'], $data);
         } catch (\Exception $e) {
             pb_backupbuddy::status('error', 'Dropbox Error #8754646: ' . $e->getMessage());
             return false;
         }
         // Examine response from Dropbox.
         if (true === $result) {
             // Upload success.
             pb_backupbuddy::status('details', 'Chunk upload continuation success with valid offset.');
         } elseif (false === $result) {
             // Failed.
             pb_backupbuddy::status('error', 'Chunk upload continuation failed at offset `' . $settings['_chunk_next_offset'] . '`.');
             return false;
         } elseif (is_numeric($result)) {
             // offset wrong. Update to use this.
             pb_backupbuddy::status('details', 'Chunk upload continuation received an updated offset response of `' . $result . '` when we tried `' . $settings['_chunk_next_offset'] . '`.');
             $settings['_chunk_next_offset'] = $result;
             // Try resending with corrected offset.
             try {
                 $result = self::$_dbxClient->chunkedUploadContinue($settings['_chunk_upload_id'], $settings['_chunk_next_offset'], $data);
             } catch (\Exception $e) {
                 pb_backupbuddy::status('error', 'Dropbox Error #8263836: ' . $e->getMessage());
                 return false;
             }
         }
         $send_time += microtime(true);
         $data_length = strlen($data);
         unset($data);
         // Calculate some stats to log.
         $chunk_transfer_speed = $data_length / $send_time;
         pb_backupbuddy::status('details', 'Dropbox chunk transfer stats - Sent: `' . pb_backupbuddy::$format->file_size($data_length) . '`, Transfer duration: `' . $send_time . '`, Speed: `' . pb_backupbuddy::$format->file_size($chunk_transfer_speed) . '`.');
         // Set options for subsequent step chunks.
         $chunked_destination_settings = $settings;
         $chunked_destination_settings['_chunk_offset'] = $data_length;
         $chunked_destination_settings['_chunk_sent_count']++;
         $chunked_destination_settings['_chunk_next_offset'] = $data_length * $chunked_destination_settings['_chunk_sent_count'];
         // First chunk was sent initiationg multipart send.
         $chunked_destination_settings['_chunk_transfer_speeds'][] = $chunk_transfer_speed;
         // Load destination fileoptions.
         pb_backupbuddy::status('details', 'About to load fileoptions data.');
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         pb_backupbuddy::status('details', 'Fileoptions instance #15.');
         $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
         if (true !== ($result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Fatal Error #9034.84838. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
             return false;
         }
         pb_backupbuddy::status('details', 'Fileoptions data loaded.');
         $fileoptions =& $fileoptions_obj->options;
         // Multipart send completed. Send finished signal to Dropbox to seal the deal.
         if (true === feof($f)) {
             pb_backupbuddy::status('details', 'At end of file. Finishing transfer and notifying Dropbox of file transfer completion.');
             $chunked_destination_settings['_chunk_upload_id'] = '';
             // Unset since chunking finished.
             try {
                 $result = self::$_dbxClient->chunkedUploadFinish($settings['_chunk_upload_id'], $settings['directory'] . '/' . basename($file), dbx\WriteMode::add());
             } catch (\Exception $e) {
                 pb_backupbuddy::status('error', 'Dropbox Error #549838979: ' . $e->getMessage());
                 return false;
             }
             pb_backupbuddy::status('details', 'Chunked upload finish results: `' . print_r($result, true) . '`.');
             if (filesize($settings['_chunk_file']) != $result['bytes']) {
                 pb_backupbuddy::status('error', 'Error #8958944. Dropbox reported file size differs from local size. The file upload may have been corrupted.');
                 return false;
             }
             $fileoptions['write_speed'] = array_sum($chunked_destination_settings['_chunk_transfer_speeds']) / $chunked_destination_settings['_chunk_sent_count'];
             $fileoptions['_multipart_status'] = 'Sent part ' . $chunked_destination_settings['_chunk_sent_count'] . ' of ' . $chunked_destination_settings['_chunk_total_count'] . '.';
             $fileoptions['finish_time'] = time();
             $fileoptions['status'] = 'success';
             $fileoptions_obj->save();
             unset($fileoptions_obj);
         }
         fclose($f);
         pb_backupbuddy::status('details', 'Sent chunk number `' . $chunked_destination_settings['_chunk_sent_count'] . '` to Dropbox with upload ID: `' . $chunked_destination_settings['_chunk_upload_id'] . '`. Next offset: `' . $chunked_destination_settings['_chunk_next_offset'] . '`.');
         // Schedule to continue if anything is left to upload for this multipart of any individual files.
         if ($chunked_destination_settings['_chunk_upload_id'] != '' || count($files) > 0) {
             pb_backupbuddy::status('details', 'Dropbox multipart upload has more parts left. Scheduling next part send.');
             $cronTime = time();
             $cronArgs = array($chunked_destination_settings, $files, $send_id, $delete_after);
             $cronHashID = md5($cronTime . serialize($cronArgs));
             $cronArgs[] = $cronHashID;
             $schedule_result = backupbuddy_core::schedule_single_event($cronTime, pb_backupbuddy::cron_tag('destination_send'), $cronArgs);
             if (true === $schedule_result) {
                 pb_backupbuddy::status('details', 'Next Dropbox chunk step cron event scheduled.');
             } else {
                 pb_backupbuddy::status('error', 'Next Dropbox chunk step cron even FAILED to be scheduled.');
             }
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             return array($chunked_destination_settings['_chunk_upload_id'], 'Sent ' . $chunked_destination_settings['_chunk_sent_count'] . ' of ' . $chunked_destination_settings['_chunk_total_count'] . ' parts.');
         }
     }
     // end continue multipart chunked upload.
     /***** END MULTIPART CHUNKED CONTINUE *****/
     pb_backupbuddy::status('details', 'Looping through files to send to Dropbox.');
     foreach ($files as $file_id => $file) {
         $file_size = filesize($file);
         pb_backupbuddy::status('details', 'Opening file `' . basename($file) . '` to send.');
         $f = @fopen($file, 'rb');
         if (false === $f) {
             pb_backupbuddy::status('error', 'Error #8457573. Unable to open file `' . $file . '` to send to Dropbox.');
             return false;
         }
         if ($settings['max_chunk_size'] >= 5 && $file_size / 1024 / 1024 > $settings['max_chunk_size']) {
             // chunked send.
             pb_backupbuddy::status('details', 'File exceeds chunking limit of `' . $settings['max_chunk_size'] . '` MB. Using chunked upload for this file transfer.');
             // Read first file chunk into memory.
             pb_backupbuddy::status('details', 'Reading first chunk into memory.');
             try {
                 $data = self::readFully($f, $max_chunk_size_bytes);
             } catch (\Exception $e) {
                 pb_backupbuddy::status('error', 'Dropbox Error #5684574373: ' . $e->getMessage());
                 return false;
             }
             // Start chunk upload to get upload ID. Sends first chunk piece.
             $send_time = -microtime(true);
             pb_backupbuddy::status('details', 'About to start chunked upload & put first chunk of file `' . basename($file) . '` to Dropbox (PHP 5.3+).');
             try {
                 $result = self::$_dbxClient->chunkedUploadStart($data);
             } catch (\Exception $e) {
                 pb_backupbuddy::status('error', 'Dropbox Error: ' . $e->getMessage());
                 return false;
             }
             $send_time += microtime(true);
             @fclose($f);
             $data_length = strlen($data);
             unset($data);
             // Calculate some stats to log.
             $chunk_transfer_speed = $data_length / $send_time;
             pb_backupbuddy::status('details', 'Dropbox chunk transfer stats - Sent: `' . pb_backupbuddy::$format->file_size($data_length) . '`, Transfer duration: `' . $send_time . '`, Speed: `' . pb_backupbuddy::$format->file_size($chunk_transfer_speed) . '`.');
             // Set options for subsequent step chunks.
             $chunked_destination_settings = $settings;
             $chunked_destination_settings['_chunk_file'] = $file;
             $chunked_destination_settings['_chunk_maxsize'] = $max_chunk_size_bytes;
             $chunked_destination_settings['_chunk_upload_id'] = $result;
             $chunked_destination_settings['_chunk_offset'] = $data_length;
             $chunked_destination_settings['_chunk_next_offset'] = $data_length;
             // First chunk was sent initiationg multipart send.
             $chunked_destination_settings['_chunk_sent_count'] = 1;
             $chunked_destination_settings['_chunk_total_count'] = ceil($file_size / $max_chunk_size_bytes);
             $chunked_destination_settings['_chunk_transfer_speeds'][] = $chunk_transfer_speed;
             pb_backupbuddy::status('details', 'Sent first chunk to Dropbox with upload ID: `' . $chunked_destination_settings['_chunk_upload_id'] . '`. Offset: `' . $chunked_destination_settings['_chunk_offset'] . '`.');
             // Remove this file from list to send before passing $files to schedule next cron. Multipart will handle this from here on out.
             unset($files[$file_id]);
             // Schedule next chunk to send.
             pb_backupbuddy::status('details', 'Dropbox (PHP 5.3+) scheduling send of next part(s).');
             $cronTime = time();
             $cronArgs = array($chunked_destination_settings, $files, $send_id, $delete_after);
             $cronHashID = md5($cronTime . serialize($cronArgs));
             $cronArgs[] = $cronHashID;
             if (false === backupbuddy_core::schedule_single_event($cronTime, pb_backupbuddy::cron_tag('destination_send'), $cronArgs)) {
                 pb_backupbuddy::status('error', 'Error #948844: Unable to schedule next Dropbox2 cron chunk.');
                 return false;
             } else {
                 pb_backupbuddy::status('details', 'Success scheduling next cron chunk.');
             }
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             pb_backupbuddy::status('details', 'Dropbox (PHP 5.3+) scheduled send of next part(s). Done for this cycle.');
             return array($chunked_destination_settings['_chunk_upload_id'], 'Sent 1 of ' . $chunked_destination_settings['_chunk_total_count'] . ' parts.');
         } else {
             // normal (non-chunked) send.
             pb_backupbuddy::status('details', 'Dropbox send not set to be chunked.');
             pb_backupbuddy::status('details', 'About to put file `' . basename($file) . '` (' . pb_backupbuddy::$format->file_size($file_size) . ') to Dropbox (PHP 5.3+).');
             $send_time = -microtime(true);
             try {
                 $result = self::$_dbxClient->uploadFile($settings['directory'] . '/' . basename($file), dbx\WriteMode::add(), $f);
             } catch (\Exception $e) {
                 pb_backupbuddy::status('error', 'Dropbox Error: ' . $e->getMessage());
                 return false;
             }
             $send_time += microtime(true);
             @fclose($f);
             pb_backupbuddy::status('details', 'About to load fileoptions data.');
             require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
             pb_backupbuddy::status('details', 'Fileoptions instance #14.');
             $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
             if (true !== ($result = $fileoptions_obj->is_ok())) {
                 pb_backupbuddy::status('error', __('Fatal Error #9034.2344848. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
                 return false;
             }
             pb_backupbuddy::status('details', 'Fileoptions data loaded.');
             $fileoptions =& $fileoptions_obj->options;
             // Calculate some stats to log.
             $data_length = $file_size;
             $transfer_speed = $data_length / $send_time;
             pb_backupbuddy::status('details', 'Dropbox (non-chunked) transfer stats - Sent: `' . pb_backupbuddy::$format->file_size($data_length) . '`, Transfer duration: `' . $send_time . '`, Speed: `' . pb_backupbuddy::$format->file_size($transfer_speed) . '/sec`.');
             $fileoptions['write_speed'] = $transfer_speed;
             $fileoptions_obj->save();
             unset($fileoptions_obj);
         }
         // end normal (non-chunked) send.
         pb_backupbuddy::status('message', 'Success sending `' . basename($file) . '` to Dropbox!');
         // Start remote backup limit
         if ($settings['archive_limit'] > 0) {
             pb_backupbuddy::status('details', 'Dropbox file limit in place. Proceeding with enforcement.');
             $meta_data = self::$_dbxClient->getMetadataWithChildren($settings['directory']);
             // Create array of backups and organize by date
             $bkupprefix = backupbuddy_core::backup_prefix();
             $backups = array();
             foreach ((array) $meta_data['contents'] as $looping_file) {
                 if ($looping_file['is_dir'] == '1') {
                     // JUST IN CASE. IGNORE anything that is a directory.
                     continue;
                 }
                 // check if file is backup
                 if (strpos($looping_file['path'], 'backup-' . $bkupprefix . '-') !== false) {
                     // Appears to be a backup file.
                     $backups[$looping_file['path']] = strtotime($looping_file['modified']);
                 }
             }
             arsort($backups);
             if (count($backups) > $settings['archive_limit']) {
                 pb_backupbuddy::status('details', 'Dropbox backup file count of `' . count($backups) . '` exceeds limit of `' . $settings['archive_limit'] . '`.');
                 $i = 0;
                 $delete_fail_count = 0;
                 foreach ($backups as $buname => $butime) {
                     $i++;
                     if ($i > $settings['archive_limit']) {
                         if (!self::$_dbxClient->delete($buname)) {
                             // Try to delete backup on Dropbox. Increment failure count if unable to.
                             pb_backupbuddy::status('details', 'Unable to delete excess Dropbox file: `' . $buname . '`');
                             $delete_fail_count++;
                         } else {
                             pb_backupbuddy::status('details', 'Deleted excess Dropbox file: `' . $buname . '`');
                         }
                     }
                 }
                 if ($delete_fail_count !== 0) {
                     backupbuddy_core::mail_error(sprintf(__('Dropbox remote limit could not delete %s backups.', 'it-l10n-backupbuddy'), $delete_fail_count));
                 }
             }
         } else {
             pb_backupbuddy::status('details', 'No Dropbox file limit to enforce.');
         }
         // End remote backup limit
     }
     // end foreach.
     pb_backupbuddy::status('details', 'All files sent.');
     return true;
     // Success if made it this far.
 }
Exemplo n.º 23
0
 public function remote_send()
 {
     if (defined('PB_DEMO_MODE')) {
         die('Access denied in demo mode.');
     }
     $success_output = false;
     // Set to true onece a leading 1 has been sent to the javascript to indicate success.
     $destination_id = pb_backupbuddy::_POST('destination_id');
     if (pb_backupbuddy::_POST('file') != 'importbuddy.php') {
         $backup_file = pb_backupbuddy::$options['backup_directory'] . pb_backupbuddy::_POST('file');
     } else {
         $backup_file = '';
     }
     if (pb_backupbuddy::_POST('send_importbuddy') == '1') {
         $send_importbuddy = true;
         pb_backupbuddy::status('details', 'Cron send to be scheduled with importbuddy sending.');
     } else {
         $send_importbuddy = false;
         pb_backupbuddy::status('details', 'Cron send to be scheduled WITHOUT importbuddy sending.');
     }
     // For Stash we will check the quota prior to initiating send.
     if (pb_backupbuddy::$options['remote_destinations'][$destination_id]['type'] == 'stash') {
         // Pass off to destination handler.
         require_once pb_backupbuddy::plugin_path() . '/destinations/bootstrap.php';
         $send_result = pb_backupbuddy_destinations::get_info('stash');
         // Used to kick the Stash destination into life.
         $stash_quota = pb_backupbuddy_destination_stash::get_quota(pb_backupbuddy::$options['remote_destinations'][$destination_id], true);
         //print_r( $stash_quota );
         if ($backup_file != '') {
             $backup_file_size = filesize($backup_file);
         } else {
             $backip_file_size = 50000;
         }
         if ($backup_file_size + $stash_quota['quota_used'] > $stash_quota['quota_total']) {
             echo "You do not have enough Stash storage space to send this file. Please upgrade your Stash storage or delete files to make space.\n\n";
             echo 'Attempting to send file of size ' . pb_backupbuddy::$format->file_size($backup_file_size) . ' but you only have ' . $stash_quota['quota_available_nice'] . ' available. ';
             echo 'Currently using ' . $stash_quota['quota_used_nice'] . ' of ' . $stash_quota['quota_total_nice'] . ' (' . $stash_quota['quota_used_percent'] . '%).';
             die;
         } else {
             if (isset($stash_quota['quota_warning']) && $stash_quota['quota_warning'] != '') {
                 echo '1Warning: ' . $stash_quota['quota_warning'] . "\n\n";
                 $success_output = true;
             }
         }
     }
     wp_schedule_single_event(time(), pb_backupbuddy::cron_tag('remote_send'), array($destination_id, $backup_file, pb_backupbuddy::_POST('trigger'), $send_importbuddy));
     spawn_cron(time() + 150);
     // Adds > 60 seconds to get around once per minute cron running limit.
     update_option('_transient_doing_cron', 0);
     // Prevent cron-blocking for next item.
     // SEE cron.php remote_send() for sending function that we pass to via the cron above.
     if ($success_output === false) {
         echo 1;
     }
     die;
 }
Exemplo n.º 24
0
 static function schedule_full_sync($modules = null, $time_offset = 1)
 {
     if (!self::sync_allowed()) {
         return false;
     }
     if (self::is_scheduled_full_sync()) {
         self::unschedule_all_full_syncs();
     }
     if ($modules) {
         wp_schedule_single_event(time() + $time_offset, 'jetpack_sync_full', array($modules));
     } else {
         wp_schedule_single_event(time() + $time_offset, 'jetpack_sync_full');
     }
     if ($time_offset === 1) {
         spawn_cron();
     }
     return true;
 }
Exemplo n.º 25
0
        }
    }
    if (count($deleted_files) > 0) {
        pb_backupbuddy::alert('Deleted ' . implode(', ', $deleted_files) . '.');
        delete_transient('pb_backupbuddy_stashquota_' . $itxapi_username);
        // Delete quota transient since it probably has changed now.
    }
    echo '<br>';
}
// Handle copying files to local
if (pb_backupbuddy::_GET('cpy_file') != '') {
    pb_backupbuddy::alert('The remote file is now being copied to your local backups. If the backup gets marked as bad during copying, please wait a bit then click the `Refresh` icon to rescan after the transfer is complete.');
    echo '<br>';
    pb_backupbuddy::status('details', 'Scheduling Cron for creating Stash copy.');
    backupbuddy_core::schedule_single_event(time(), 'process_remote_copy', array('stash', pb_backupbuddy::_GET('cpy_file'), $settings));
    spawn_cron(time() + 150);
    // Adds > 60 seconds to get around once per minute cron running limit.
    update_option('_transient_doing_cron', 0);
    // Prevent cron-blocking for next item.
}
// Handle download link
if (pb_backupbuddy::_GET('downloadlink_file') != '') {
    $link = $s3->get_object($manage_data['bucket'], $manage_data['subkey'] . $remote_path . pb_backupbuddy::_GET('downloadlink_file'), array('preauth' => time() + 3600));
    pb_backupbuddy::alert('You may download this backup (' . pb_backupbuddy::_GET('downloadlink_file') . ') with <a href="' . $link . '">this link</a>. The link is valid for one hour.');
    echo '<br>';
}
// QUOTA INFORMATION.
$account_info = pb_backupbuddy_destination_stash::get_quota(array('itxapi_username' => $itxapi_username, 'itxapi_password' => $itxapi_password), false);
/*
echo '<pre>';
print_r( $account_info );
 static function schedule_full_sync($modules = null, $time_offset = 1)
 {
     if (!self::sync_allowed()) {
         return false;
     }
     if (Jetpack_Sync_Settings::get_setting('avoid_wp_cron')) {
         // run queuing inline
         set_time_limit(0);
         self::do_full_sync($modules);
         return false;
     }
     if (self::is_scheduled_full_sync()) {
         self::unschedule_all_full_syncs();
     }
     if ($modules) {
         wp_schedule_single_event(time() + $time_offset, 'jetpack_sync_full', array($modules));
     } else {
         wp_schedule_single_event(time() + $time_offset, 'jetpack_sync_full');
     }
     if ($time_offset === 1) {
         spawn_cron();
     }
     return true;
 }
Exemplo n.º 27
0
/**
 * Run scheduled callbacks or spawn cron for all scheduled events.
 *
 * @since 2.1.0
 *
 * @return null When doesn't need to run Cron.
 */
function wp_cron()
{
    // Prevent infinite loops caused by lack of wp-cron.php
    if (strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false || defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
        return;
    }
    if (false === ($crons = _get_cron_array())) {
        return;
    }
    $local_time = microtime(true);
    $keys = array_keys($crons);
    if (isset($keys[0]) && $keys[0] > $local_time) {
        return;
    }
    $schedules = wp_get_schedules();
    foreach ($crons as $timestamp => $cronhooks) {
        if ($timestamp > $local_time) {
            break;
        }
        foreach ((array) $cronhooks as $hook => $args) {
            if (isset($schedules[$hook]['callback']) && !call_user_func($schedules[$hook]['callback'])) {
                continue;
            }
            spawn_cron($local_time);
            break 2;
        }
    }
}
Exemplo n.º 28
0
 function cron_next_step($spawn_cron = true, $future_offset = 0)
 {
     if ('1' == pb_backupbuddy::$options['skip_spawn_cron_call']) {
         pb_backupbuddy::status('details', 'Advanced option to skip call to spawn cron enabled. Setting to skip spawn_cron() call.');
         $spawn_cron = false;
     }
     pb_backupbuddy::status('details', 'Scheduling Cron for `' . $this->_backup['serial'] . '`.');
     // 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')) {
         global $wpdb;
         $dbhelper = new pluginbuddy_wpdbutils($wpdb);
         if (!$dbhelper->kick()) {
             pb_backupbuddy::status('error', __('Database Server has gone away, unable to schedule next backup step. The backup cannot continue. This is most often caused by mysql running out of memory or timing out far too early. Please contact your host.', 'it-l10n-backupbuddy'));
             pb_backupbuddy::status('haltScript', '');
             // Halt JS on page.
             return false;
         }
     } else {
         pb_backupbuddy::status('details', __('Database Server connection status unverified.', 'it-l10n-backupbuddy'));
     }
     // Schedule event.
     $cron_time = time() + $future_offset;
     $cron_tag = pb_backupbuddy::cron_tag('process_backup');
     $cron_args = array($this->_backup['serial']);
     pb_backupbuddy::status('details', 'Scheduling next step to run at `' . $cron_time . '` (localized time: ' . pb_backupbuddy::$format->date(pb_backupbuddy::$format->localize_time($cron_time)) . ') with cron tag `' . $cron_tag . '` and serial arguments `' . implode(',', $cron_args) . '`.');
     $schedule_result = backupbuddy_core::schedule_single_event($cron_time, $cron_tag, $cron_args);
     if ($schedule_result === false) {
         pb_backupbuddy::status('error', 'Unable to schedule next cron step. Verify that another plugin is not preventing / conflicting.');
     } else {
         pb_backupbuddy::status('details', 'Next step scheduled.');
         pb_backupbuddy::status('startAction', 'cronPass');
         pb_backupbuddy::status('cronParams', base64_encode(json_encode(array('time' => $cron_time, 'tag' => $cron_tag, 'args' => $cron_args))));
     }
     update_option('_transient_doing_cron', 0);
     // Prevent cron-blocking for next item.
     // Spawn cron.
     if ($spawn_cron === true) {
         pb_backupbuddy::status('details', 'Calling spawn_cron().');
         spawn_cron(time() + 150);
         // Adds > 60 seconds to get around once per minute cron running limit.
     } else {
         pb_backupbuddy::status('details', 'Not calling spawn_cron().');
     }
     pb_backupbuddy::status('details', 'About to run next step. If the backup does not proceed within 15 seconds then something is interfering with the WordPress CRON system such as: server loopback issues, caching plugins, or scheduling plugins. Try disabling other plugins to see if it resolves issue.  Check the Server Information page cron section to see if the next BackupBuddy step is scheduled to run. Enable "Classic" backup mode on the "Settings" page to rule out non-cron issues.');
     return;
 }
Exemplo n.º 29
0
 public static function send($settings = array(), $files = array(), $send_id = '', $clear_uploads = false)
 {
     global $pb_backupbuddy_destination_errors;
     if (!is_array($files)) {
         $files = array($files);
     }
     if ($clear_uploads === false) {
         // Uncomment the following line to override and always clear.
         //$clear_uploads = true;
     }
     $itxapi_username = $settings['itxapi_username'];
     $itxapi_password = $settings['itxapi_password'];
     $db_archive_limit = $settings['db_archive_limit'];
     $full_archive_limit = $settings['full_archive_limit'];
     $files_archive_limit = $settings['files_archive_limit'];
     $max_chunk_size = $settings['max_chunk_size'];
     $remote_path = self::get_remote_path($settings['directory']);
     // Has leading and trailng slashes.
     if ($settings['ssl'] == '0') {
         $disable_ssl = true;
     } else {
         $disable_ssl = false;
     }
     $multipart_id = $settings['_multipart_id'];
     $multipart_counts = $settings['_multipart_counts'];
     pb_backupbuddy::status('details', 'Stash remote path set to `' . $remote_path . '`.');
     require_once dirname(__FILE__) . '/lib/class.itx_helper.php';
     require_once dirname(dirname(__FILE__)) . '/_s3lib/aws-sdk/sdk.class.php';
     // Stash API talk.
     $stash = new ITXAPI_Helper(pb_backupbuddy_destination_stash::ITXAPI_KEY, pb_backupbuddy_destination_stash::ITXAPI_URL, $itxapi_username, $itxapi_password);
     $manage_data = pb_backupbuddy_destination_stash::get_manage_data($settings);
     if (!is_array($manage_data['credentials'])) {
         pb_backupbuddy::status('error', 'Error #8484383b: Your authentication credentials for Stash failed. Verify your login and password to Stash. You may need to update the Stash destination settings. Perhaps you recently changed your password?');
         return false;
     }
     // Wipe all current uploads.
     if ($clear_uploads === true) {
         pb_backupbuddy::status('details', 'Clearing any current uploads via Stash call to `abort-all`.');
         $abort_url = $stash->get_upload_url(null, 'abort-all');
         $request = new RequestCore($abort_url);
         $response = $request->send_request(true);
     }
     // Process multipart transfer that we already initiated in a previous PHP load.
     if ($multipart_id != '') {
         // Multipart upload initiated and needs parts sent.
         // Create S3 instance.
         pb_backupbuddy::status('details', 'Creating Stash S3 instance.');
         $s3 = new AmazonS3($settings['_multipart_upload_data']['credentials']);
         // the key, secret, token
         if ($disable_ssl === true) {
             @$s3->disable_ssl(true);
         }
         pb_backupbuddy::status('details', 'Stash S3 instance created.');
         $backup_type = str_replace('/', '', $settings['_multipart_backup_type_dir']);
         // For use later by file limiting.
         $this_part_number = $settings['_multipart_partnumber'] + 1;
         pb_backupbuddy::status('details', 'Stash beginning upload of part `' . $this_part_number . '` of `' . count($settings['_multipart_counts']) . '` parts of file `' . $settings['_multipart_file'] . '` with multipart ID `' . $settings['_multipart_id'] . '`.');
         $response = $s3->upload_part($settings['_multipart_upload_data']['bucket'], $settings['_multipart_upload_data']['object'], $settings['_multipart_id'], array('expect' => '100-continue', 'fileUpload' => $settings['_multipart_file'], 'partNumber' => $this_part_number, 'seekTo' => (int) $settings['_multipart_counts'][$settings['_multipart_partnumber']]['seekTo'], 'length' => (int) $settings['_multipart_counts'][$settings['_multipart_partnumber']]['length']));
         if (!$response->isOK()) {
             $this_error = 'Stash unable to upload file part for multipart upload `' . $settings['_multipart_id'] . '`. Details: `' . print_r($response, true) . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             $uploaded_size = $response->header['_info']['size_upload'];
             $uploaded_speed = $response->header['_info']['speed_upload'];
             pb_backupbuddy::status('details', 'Uploaded size: ' . pb_backupbuddy::$format->file_size($uploaded_size) . ', Speed: ' . pb_backupbuddy::$format->file_size($uploaded_speed) . '/sec.');
         }
         // Load fileoptions to the send.
         pb_backupbuddy::status('details', 'About to load fileoptions data.');
         require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
         $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
         if (true !== ($result = $fileoptions_obj->is_ok())) {
             pb_backupbuddy::status('error', __('Fatal Error #9034.2344848. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
             return false;
         }
         pb_backupbuddy::status('details', 'Fileoptions data loaded.');
         $fileoptions =& $fileoptions_obj->options;
         $update_status = 'Sent part ' . $this_part_number . ' of ' . count($settings['_multipart_counts']) . '.';
         // Made it here so success sending part. Increment for next part to send.
         $settings['_multipart_partnumber']++;
         if (!isset($settings['_multipart_counts'][$settings['_multipart_partnumber']])) {
             // No more parts exist for this file. Tell S3 the multipart upload is complete and move on.
             pb_backupbuddy::status('details', 'Stash getting parts with etags to notify S3 of completed multipart send.');
             $etag_parts = $s3->list_parts($settings['_multipart_upload_data']['bucket'], $settings['_multipart_upload_data']['object'], $settings['_multipart_id']);
             pb_backupbuddy::status('details', 'Stash got parts list. Notifying S3 of multipart upload completion.');
             $response = $s3->complete_multipart_upload($settings['_multipart_upload_data']['bucket'], $settings['_multipart_upload_data']['object'], $settings['_multipart_id'], $etag_parts);
             if (!$response->isOK()) {
                 $this_error = 'Stash unable to notify S3 of completion of all parts for multipart upload `' . $settings['_multipart_id'] . '`.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 pb_backupbuddy::status('details', 'Stash notified S3 of multipart completion.');
             }
             $backup_type_dir = $settings['_multipart_backup_type_dir'];
             // Notify Stash API that things were succesful.
             $done_url = $stash->get_upload_url($settings['_multipart_file'], 'done', $remote_path . $backup_type_dir . basename($settings['_multipart_file']));
             pb_backupbuddy::status('details', 'Notifying Stash of completed multipart upload with done url `' . $done_url . '`.');
             $request = new RequestCore($done_url);
             $response = $request->send_request(true);
             if (!$response->isOK()) {
                 $this_error = 'Error #756834682. Could not finalize Stash upload. Response code: `' . $response->get_response_code() . '`; Response body: `' . $response->get_response_body() . '`; Response headers: `' . $response->get_response_header() . '`.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 // Good server response.
                 // See if we got an optional json response.
                 $upload_data = @json_decode($response->body, true);
                 if (isset($upload_data['error'])) {
                     $this_error = 'Stash error(s): `' . implode(' - ', $upload_data['error']) . '`.';
                     $pb_backupbuddy_destination_errors[] = $this_error;
                     pb_backupbuddy::status('error', $this_error);
                     return false;
                 }
                 pb_backupbuddy::status('details', 'Stash success sending file `' . basename($settings['_multipart_file']) . '`. File uploaded via multipart across `' . $this_part_number . '` parts and reported to Stash as completed.');
             }
             pb_backupbuddy::status('details', 'Stash has no more parts left for this multipart upload. Clearing multipart instance variables.');
             $settings['_multipart_partnumber'] = 0;
             $settings['_multipart_id'] = '';
             $settings['_multipart_file'] = '';
             $settings['_multipart_upload_data'] = array();
             $settings['_multipart_transferspeeds'][] = $uploaded_speed;
             // Overall upload speed average.
             $uploaded_speed = array_sum($settings['_multipart_transferspeeds']) / count($settings['_multipart_counts']);
             pb_backupbuddy::status('details', 'Upload speed average of all chunks: `' . pb_backupbuddy::$format->file_size($uploaded_speed) . '`.');
             $settings['_multipart_counts'] = array();
             // Update stats.
             $fileoptions['_multipart_status'] = $update_status;
             $fileoptions['finish_time'] = time();
             $fileoptions['status'] = 'success';
             if (isset($uploaded_speed)) {
                 $fileoptions['write_speed'] = $uploaded_speed;
             }
             $fileoptions_obj->save();
             unset($fileoptions);
         }
         delete_transient('pb_backupbuddy_stashquota_' . $settings['itxapi_username']);
         // Delete quota transient since it probably has changed now.
         // Schedule to continue if anything is left to upload for this multipart of any individual files.
         if ($settings['_multipart_id'] != '' || count($files) > 0) {
             pb_backupbuddy::status('details', 'Stash multipart upload has more parts left. Scheduling next part send.');
             $schedule_result = backupbuddy_core::schedule_single_event(time(), pb_backupbuddy::cron_tag('destination_send'), array($settings, $files, $send_id));
             if (true === $schedule_result) {
                 pb_backupbuddy::status('details', 'Next Stash chunk step cron event scheduled.');
             } else {
                 pb_backupbuddy::status('error', 'Next Stash chunk step cron even FAILED to be scheduled.');
             }
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             return array($settings['_multipart_id'], 'Sent part ' . $this_part_number . ' of ' . count($settings['_multipart_counts']) . ' parts.');
         }
     }
     // end if multipart continuation.
     require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
     // Upload each file.
     foreach ($files as $file_id => $file) {
         // Determine backup type directory (if zip).
         $backup_type_dir = '';
         $backup_type = '';
         if (stristr($file, '.zip') !== false) {
             // If a zip try to determine backup type.
             pb_backupbuddy::status('details', 'Stash: Zip file. Detecting backup type if possible.');
             $serial = backupbuddy_core::get_serial_from_file($file);
             // See if we can get backup type from fileoptions data.
             $backup_options = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt', $read_only = true, $ignore_lock = true);
             if (true !== ($result = $backup_options->is_ok())) {
                 pb_backupbuddy::status('error', 'Unable to open fileoptions file `' . backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt' . '`.');
             } else {
                 if (isset($backup_options->options['integrity']['detected_type'])) {
                     pb_backupbuddy::status('details', 'Stash: Detected backup type as `' . $backup_options->options['integrity']['detected_type'] . '` via integrity check data.');
                     $backup_type_dir = $backup_options->options['integrity']['detected_type'] . '/';
                     $backup_type = $backup_options->options['integrity']['detected_type'];
                 }
             }
             // If still do not know backup type then attempt to deduce it from filename.
             if ($backup_type == '') {
                 if (stristr($file, '-db-') !== false) {
                     pb_backupbuddy::status('details', 'Stash: Detected backup type as `db` via filename.');
                     $backup_type_dir = 'db/';
                     $backup_type = 'db';
                 } elseif (stristr($file, '-full-') !== false) {
                     pb_backupbuddy::status('details', 'Stash: Detected backup type as `full` via filename.');
                     $backup_type_dir = 'full/';
                     $backup_type = 'full';
                 } elseif (stristr($file, '-files-') !== false) {
                     pb_backupbuddy::status('details', 'Stash: Detected backup type as `files` via filename.');
                     $backup_type_dir = 'files/';
                     $backup_type = 'files';
                 } else {
                     pb_backupbuddy::status('details', 'Stash: Could not detect backup type via integrity details nor filename.');
                 }
             }
         }
         // Interact with Stash API.
         pb_backupbuddy::status('details', 'Determining Stash upload URL for `' . $file . '`.` with destination remote path `' . $remote_path . $backup_type_dir . basename($file) . '`.');
         $upload_url = $stash->get_upload_url($file, 'request', $remote_path . $backup_type_dir . basename($file));
         pb_backupbuddy::status('details', 'Determined upload url: `' . $upload_url . '`.');
         $request = new RequestCore($upload_url);
         pb_backupbuddy::status('details', 'Sending Stash API request.');
         $response = $request->send_request(true);
         // Validate response.
         if (!$response->isOK()) {
             $this_error = 'Stash request for upload credentials failed.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         }
         if (!($upload_data = json_decode($response->body, true))) {
             $this_error = 'Stash API did not give a valid JSON response.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         }
         if (isset($upload_data['error'])) {
             $this_error = 'Stash error(s): `' . implode(' - ', $upload_data['error']) . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         }
         // Create S3 instance.
         pb_backupbuddy::status('details', 'Creating Stash S3 instance.');
         $s3 = new AmazonS3($upload_data['credentials']);
         // the key, secret, token
         if ($disable_ssl === true) {
             @$s3->disable_ssl(true);
         }
         pb_backupbuddy::status('details', 'Stash S3 instance created.');
         // Handle chunking of file into a multipart upload (if applicable).
         $file_size = filesize($file);
         if ($max_chunk_size >= self::MINIMUM_CHUNK_SIZE && $file_size / 1024 / 1024 > $max_chunk_size) {
             // minimum chunk size is 5mb. Anything under 5mb we will not chunk.
             pb_backupbuddy::status('details', 'Stash file size of ' . pb_backupbuddy::$format->file_size($file_size) . ' exceeds max chunk size of ' . $max_chunk_size . 'MB set in settings for sending file as multipart upload.');
             // Initiate multipart upload with S3.
             pb_backupbuddy::status('details', 'Initiating Stash multipart upload.');
             $response = $s3->initiate_multipart_upload($upload_data['bucket'], $upload_data['object'], array('encryption' => 'AES256'));
             if (!$response->isOK()) {
                 $this_error = 'Stash was unable to initiate multipart upload.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             } else {
                 $upload_id = (string) $response->body->UploadId;
                 pb_backupbuddy::status('details', 'Stash initiated multipart upload with ID `' . $upload_id . '`.');
             }
             // Get chunk parts for multipart transfer.
             pb_backupbuddy::status('details', 'Stash getting multipart counts.');
             $parts = $s3->get_multipart_counts($file_size, $max_chunk_size * 1024 * 1024);
             // Size of chunks expected to be in bytes.
             $multipart_destination_settings = $settings;
             $multipart_destination_settings['_multipart_id'] = $upload_id;
             $multipart_destination_settings['_multipart_partnumber'] = 0;
             $multipart_destination_settings['_multipart_file'] = $file;
             $multipart_destination_settings['_multipart_counts'] = $parts;
             $multipart_destination_settings['_multipart_upload_data'] = $upload_data;
             $multipart_destination_settings['_multipart_backup_type_dir'] = $backup_type_dir;
             pb_backupbuddy::status('details', 'Stash multipart settings to pass:'******'details', 'Stash scheduling send of next part(s).');
             backupbuddy_core::schedule_single_event(time(), pb_backupbuddy::cron_tag('destination_send'), array($multipart_destination_settings, $files, $send_id));
             spawn_cron(time() + 150);
             // Adds > 60 seconds to get around once per minute cron running limit.
             update_option('_transient_doing_cron', 0);
             // Prevent cron-blocking for next item.
             pb_backupbuddy::status('details', 'Stash scheduled send of next part(s). Done for this cycle.');
             return array($upload_id, 'Starting send of ' . count($multipart_destination_settings['_multipart_counts']) . ' parts.');
         } else {
             // did not meet chunking criteria.
             if ($max_chunk_size != '0') {
                 if ($file_size / 1024 / 1024 > self::MINIMUM_CHUNK_SIZE) {
                     pb_backupbuddy::status('details', 'File size of ' . pb_backupbuddy::$format->file_size($file_size) . ' is less than the max chunk size of ' . $max_chunk_size . 'MB; not chunking into multipart upload.');
                 } else {
                     pb_backupbuddy::status('details', 'File size of ' . pb_backupbuddy::$format->file_size($file_size) . ' is less than the minimum allowed chunk size of ' . self::MINIMUM_CHUNK_SIZE . 'MB; not chunking into multipart upload.');
                 }
             } else {
                 pb_backupbuddy::status('details', 'Max chunk size set to zero so not chunking into multipart upload.');
             }
         }
         // SEND file.
         pb_backupbuddy::status('details', 'About to put (upload) object to Stash.');
         $response = $s3->create_object($upload_data['bucket'], $upload_data['object'], array('fileUpload' => $file, 'encryption' => 'AES256'));
         // Validate response. On failure notify Stash API that things went wrong.
         if (!$response->isOK()) {
             // Send FAILED.
             pb_backupbuddy::status('details', 'Sending upload abort.');
             $request = new RequestCore($abort_url);
             $response = $request->send_request(true);
             $this_error = 'Could not upload to Stash, attempt aborted.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             // Send SUCCESS.
             pb_backupbuddy::status('details', 'Success uploading file to Stash storage. Notifying Stash API next. Upload details: `' . print_r($response, true) . '`.');
             $uploaded_size = $response->header['_info']['size_upload'];
             $uploaded_speed = $response->header['_info']['speed_upload'];
             pb_backupbuddy::status('details', 'Uploaded size: ' . pb_backupbuddy::$format->file_size($uploaded_size) . ', Speed: ' . pb_backupbuddy::$format->file_size($uploaded_speed) . '/sec.');
         }
         delete_transient('pb_backupbuddy_stashquota_' . $settings['itxapi_username']);
         // Delete quota transient since it probably has changed now.
         // Notify Stash API that things were succesful.
         $done_url = $stash->get_upload_url($file, 'done', $remote_path . $backup_type_dir . basename($file));
         pb_backupbuddy::status('details', 'Notifying Stash of completed upload with done url `' . $done_url . '`.');
         $request = new RequestCore($done_url);
         $response = $request->send_request(true);
         if (!$response->isOK()) {
             $this_error = 'Error #247568834682. Could not finalize Stash upload. Response code: `' . $response->get_response_code() . '`; Response body: `' . $response->get_response_body() . '`; Response headers: `' . $response->get_response_header() . '`.';
             $pb_backupbuddy_destination_errors[] = $this_error;
             pb_backupbuddy::status('error', $this_error);
             return false;
         } else {
             // Good server response.
             // See if we got an optional json response.
             $upload_data = @json_decode($response->body, true);
             if (isset($upload_data['error'])) {
                 // Some kind of error.
                 $this_error = 'Stash error(s): `' . implode(' - ', $upload_data['error']) . '`.';
                 $pb_backupbuddy_destination_errors[] = $this_error;
                 pb_backupbuddy::status('error', $this_error);
                 return false;
             }
             unset($files[$file_id]);
             // Remove from list of files we have not sent yet.
             pb_backupbuddy::status('details', 'Stash success sending file `' . basename($file) . '`. File uploaded and reported to Stash as completed.');
             // Load destination fileoptions.
             pb_backupbuddy::status('details', 'About to load fileoptions data.');
             require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
             $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = false, $ignore_lock = false, $create_file = false);
             if (true !== ($result = $fileoptions_obj->is_ok())) {
                 pb_backupbuddy::status('error', __('Fatal Error #9034.84838. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
                 return false;
             }
             pb_backupbuddy::status('details', 'Fileoptions data loaded.');
             $fileoptions =& $fileoptions_obj->options;
             // Save stats.
             if (isset($uploaded_speed)) {
                 $fileoptions['write_speed'] = $uploaded_speed;
                 $fileoptions_obj->save();
             }
             //$fileoptions['finish_time'] = time();
             //$fileoptions['status'] = 'success';
             unset($fileoptions_obj);
         }
     }
     // end foreach.
     // BEGIN FILE LIMIT PROCESSING. Enforce archive limits if applicable.
     if ($backup_type == 'full') {
         $limit = $full_archive_limit;
         pb_backupbuddy::status('details', 'Stash full backup archive limit of `' . $limit . '` of type `full` based on destination settings.');
     } elseif ($backup_type == 'db') {
         $limit = $db_archive_limit;
         pb_backupbuddy::status('details', 'Stash database backup archive limit of `' . $limit . '` of type `db` based on destination settings.');
     } elseif ($backup_type == 'files') {
         $limit = $db_archive_limit;
         pb_backupbuddy::status('details', 'Stash database backup archive limit of `' . $limit . '` of type `files` based on destination settings.');
     } else {
         $limit = 0;
         pb_backupbuddy::status('warning', 'Warning #54854895. Stash was unable to determine backup type (reported: `' . $backup_type . '`) so archive limits NOT enforced for this backup.');
     }
     if ($limit > 0) {
         pb_backupbuddy::status('details', 'Stash archive limit enforcement beginning.');
         // S3 object for managing files.
         $s3_manage = new AmazonS3($manage_data['credentials']);
         if ($disable_ssl === true) {
             @$s3_manage->disable_ssl(true);
         }
         // Get file listing.
         $response_manage = $s3_manage->list_objects($manage_data['bucket'], array('prefix' => $manage_data['subkey'] . $remote_path . $backup_type_dir));
         // list all the files in the subscriber account
         // Create array of backups and organize by date
         $prefix = backupbuddy_core::backup_prefix();
         // List backups associated with this site by date.
         $backups = array();
         foreach ($response_manage->body->Contents as $object) {
             $file = str_replace($manage_data['subkey'] . $remote_path . $backup_type_dir, '', $object->Key);
             // Stash stores files in a directory per site so no need to check prefix here! if ( false !== strpos( $file, 'backup-' . $prefix . '-' ) ) { // if backup has this site prefix...
             $backups[$file] = strtotime($object->LastModified);
         }
         arsort($backups);
         pb_backupbuddy::status('details', 'Stash found `' . count($backups) . '` backups of this type when checking archive limits.');
         if (count($backups) > $limit) {
             pb_backupbuddy::status('details', 'More archives (' . count($backups) . ') than limit (' . $limit . ') allows. Trimming...');
             $i = 0;
             $delete_fail_count = 0;
             foreach ($backups as $buname => $butime) {
                 $i++;
                 if ($i > $limit) {
                     pb_backupbuddy::status('details', 'Trimming excess file `' . $buname . '`...');
                     $response = $s3_manage->delete_object($manage_data['bucket'], $manage_data['subkey'] . $remote_path . $backup_type_dir . $buname);
                     if (!$response->isOK()) {
                         pb_backupbuddy::status('details', 'Unable to delete excess Stash file `' . $buname . '`. Details: `' . print_r($response, true) . '`.');
                         $delete_fail_count++;
                     }
                 }
             }
             pb_backupbuddy::status('details', 'Finished trimming excess backups.');
             if ($delete_fail_count !== 0) {
                 $error_message = 'Stash remote limit could not delete ' . $delete_fail_count . ' backups.';
                 pb_backupbuddy::status('error', $error_message);
                 backupbuddy_core::mail_error($error_message);
             }
         }
         pb_backupbuddy::status('details', 'Stash completed archive limiting.');
     } else {
         pb_backupbuddy::status('details', 'No Stash archive file limit to enforce.');
     }
     // End remote backup limit
     if (isset($fileoptions_obj)) {
         unset($fileoptions_obj);
     }
     // END FILE LIMIT PROCESSING.
     // Success if we made it this far.
     return true;
 }
Exemplo n.º 30
0
 /**
  * Executes a cron event immediately.
  *
  * Executes an event by scheduling a new single event with the same arguments.
  *
  * @param string $hookname The hookname of the cron event to run
  */
 function run_cron($hookname, $sig)
 {
     $crons = _get_cron_array();
     foreach ($crons as $time => $cron) {
         if (isset($cron[$hookname][$sig])) {
             $args = $cron[$hookname][$sig]['args'];
             delete_transient('doing_cron');
             wp_schedule_single_event(time() - 1, $hookname, $args);
             spawn_cron();
             return true;
         }
     }
     return false;
 }