public/wordpress/wp-content/plugins/backupbuddy/classes/backup.php
/* deploy_getFile()
	 *
	 * Supports chunked retrieval.
	 *
	 * @param	string	$destinationPath	Path to store file in locally. Inlude trailing slash.
	 *
	 */
deploy_getFile()
Supports chunked retrieval.

@param       string  $destinationPath        Path to store file in locally. Inlude trailing slash.
deploy_getFile () Supports chunked retrieval . @param string $destinationPath Path to store file in locally . Inlude trailing slash .
public function deploy_getFile( $state, $destinationPath, $sendFile, $sendType, $finalNextStep, $seekTo = 0 ) {
		$TIME_WIGGLE_ROOM = 5; 
		$numSentThisRound = 0;
		require_once( pb_backupbuddy::plugin_path() . '/classes/remote_api.php' );
		$timeStart = microtime( true );
		$maxPayload = $state['destinationSettings']['max_payload']; 
		$saveFile = $destinationPath . $sendFile;
		$keepSending = true;
		while( true == $keepSending ) {
			if ( false === ( $response = backupbuddy_remote_api::remoteCall( $state['destination'], 'getFile_' . $sendType, array( 'filename' => $sendFile, 'seekto' => $seekTo, 'maxPayload' => $maxPayload ), $state['minimumExecutionTime'] ) ) ) {
				pb_backupbuddy::status( 'error', 'Error #2373273: Unable to initiate file get via remote API.' );
				return false;
			}
			if ( ! is_array( $response ) ) {
				pb_backupbuddy::status( 'error', 'Error #38937324: Expected return array. Response: `' . htmlentities( $response ) . '`.' );
				return false;
			}
			$numSentThisRound++;
			if ( ( 0 == $seekTo ) && ( is_file( $saveFile ) ) ) { 
				if ( true !== unlink( $saveFile ) ) {
					$message = 'Error #83832983: Unable to deleting existing local file to overwrite. Check permissions on file/directory `' . $saveFile . '`.';
					pb_backupbuddy::status( 'error', $message );
					return false;
				}
			}
			$saveDir = dirname( $saveFile );
			if ( ! is_dir( $saveDir ) ) {
				if ( true !== pb_backupbuddy::$filesystem->mkdir( $saveDir ) ) {
					$message = 'Error #327832: Unable to create directory `' . $saveDir . '`. Check permissions or manually create. Halting to preserve deployment integrity';
					pb_backupbuddy::status( 'error', $message );
					return false;
				}
			}
			if ( false === ( $fs = fopen( $saveFile, 'a' ) )) {
				$message = 'Error #43834984: Unable to fopen file `' . $sendFile . '` in directory `' . $$destinationPath . '`.';
				pb_backupbuddy::status( 'error', $message );
				return false;
			}
			if ( 0 != fseek( $fs, $seekTo ) ) {
				@fclose( $fs );
				$message = 'Error #2373792: Unable to fseek file.';
				pb_backupbuddy::status( 'error', $message );
				return false;
			}
			if ( false === ( $bytesWritten = fwrite( $fs, $response['data'] ) ) ) { 
				@fclose( $fs );
				@unlink( $saveFile );
				$message = 'Error #4873474: Error writing to file `' . $saveFile . '`.';
				pb_backupbuddy::status( 'error', $message );
				return false;
			} else { 
				@fclose( $fs );
				$message = 'Wrote `' . $bytesWritten . '` bytes to `' . $saveFile . '`.';
				pb_backupbuddy::status( 'details', $message );
			}
			$elapsed = microtime( true ) - $timeStart;
			if ( '1' == $response['filedone'] ) { 
				pb_backupbuddy::status( 'deployFileSent', 'File sent.' );
				pb_backupbuddy::status( 'details', 'Retrieval of complete file + writing took `' . $elapsed .'` secs.');
				$keepSending = false;
				$this->insert_next_step( $finalNextStep );
				return true;
			} else { 
				pb_backupbuddy::status( 'details', 'Retrieval of chunk + writing took `' . $elapsed . '` seconds. Wrote `' . pb_backupbuddy::$format->file_size( $bytesWritten ) . '` of max limit of `' . pb_backupbuddy::$format->file_size( $maxPayload ) . '` MB per chunk after seeking to `' . $seekTo . '`. Encoded size received: `' . strlen( $response['data'] ) . '` bytes.');
				$seekTo = $response['resumepoint']; 
				if ( ( ( $elapsed + $TIME_WIGGLE_ROOM ) * ( $numSentThisRound + 1 ) ) >= $state['minimumExecutionTime'] ) { 					pb_backupbuddy::status( 'details', 'Not enough time to request more data this pass. Chunking.' );
					$keepSending = false;
					$nextStep = array(
						'function'		=>	'deploy_getFile',
						'args'			=>	array( $state, $destinationPath, $sendFile, $sendType, $finalNextStep, $seekTo ),
						'start_time'	=>	0,
						'finish_time'	=>	0,
						'attempts'		=>	0,
					);
					$this->insert_next_step( $nextStep );
					return true;
				} else {
					pb_backupbuddy::status( 'details', 'There appears to be enough time to get more data this pass.' );
					$keepSending = true;
				}
			}
		} 
	}
public function deploy_getFile ( $ state , $ destinationPath , $ sendFile , $ sendType , $ finalNextStep , $ seekTo = 0 ) { $ TIME_WIGGLE_ROOM = 5 ; $ numSentThisRound = 0 ; require_once ( pb_backupbuddy :: plugin_path ( ) . '/classes/remote_api.php' ) ; $ timeStart = microtime ( true ) ; $ maxPayload = $ state [ 'destinationSettings' ] [ 'max_payload' ] ; $ saveFile = $ destinationPath . $ sendFile ; $ keepSending = true ; while ( true == $ keepSending ) { if ( false === ( $ response = backupbuddy_remote_api :: remoteCall ( $ state [ 'destination' ] , 'getFile_' . $ sendType , array ( 'filename' => $ sendFile , 'seekto' => $ seekTo , 'maxPayload' => $ maxPayload ) , $ state [ 'minimumExecutionTime' ] ) ) ) { pb_backupbuddy :: status ( 'error' , 'Error #2373273: Unable to initiate file get via remote API.' ) ; return false ; } if ( ! is_array ( $ response ) ) { pb_backupbuddy :: status ( 'error' , 'Error #38937324: Expected return array. Response: `' . htmlentities ( $ response ) . '`.' ) ; return false ; } $ numSentThisRound ++ ; if ( ( 0 == $ seekTo ) && ( is_file ( $ saveFile ) ) ) { if ( true !== unlink ( $ saveFile ) ) { $ message = 'Error #83832983: Unable to deleting existing local file to overwrite. Check permissions on file/directory `' . $ saveFile . '`.' ; pb_backupbuddy :: status ( 'error' , $ message ) ; return false ; } } $ saveDir = dirname ( $ saveFile ) ; if ( ! is_dir ( $ saveDir ) ) { if ( true !== pb_backupbuddy :: $ filesystem -> mkdir ( $ saveDir ) ) { $ message = 'Error #327832: Unable to create directory `' . $ saveDir . '`. Check permissions or manually create. Halting to preserve deployment integrity' ; pb_backupbuddy :: status ( 'error' , $ message ) ; return false ; } } if ( false === ( $ fs = fopen ( $ saveFile , 'a' ) ) ) { $ message = 'Error #43834984: Unable to fopen file `' . $ sendFile . '` in directory `' . $ $ destinationPath . '`.' ; pb_backupbuddy :: status ( 'error' , $ message ) ; return false ; } if ( 0 != fseek ( $ fs , $ seekTo ) ) { @ fclose ( $ fs ) ; $ message = 'Error #2373792: Unable to fseek file.' ; pb_backupbuddy :: status ( 'error' , $ message ) ; return false ; } if ( false === ( $ bytesWritten = fwrite ( $ fs , $ response [ 'data' ] ) ) ) { @ fclose ( $ fs ) ; @ unlink ( $ saveFile ) ; $ message = 'Error #4873474: Error writing to file `' . $ saveFile . '`.' ; pb_backupbuddy :: status ( 'error' , $ message ) ; return false ; } else { @ fclose ( $ fs ) ; $ message = 'Wrote `' . $ bytesWritten . '` bytes to `' . $ saveFile . '`.' ; pb_backupbuddy :: status ( 'details' , $ message ) ; } $ elapsed = microtime ( true ) - $ timeStart ; if ( '1' == $ response [ 'filedone' ] ) { pb_backupbuddy :: status ( 'deployFileSent' , 'File sent.' ) ; pb_backupbuddy :: status ( 'details' , 'Retrieval of complete file + writing took `' . $ elapsed . '` secs.' ) ; $ keepSending = false ; $ this -> insert_next_step ( $ finalNextStep ) ; return true ; } else { pb_backupbuddy :: status ( 'details' , 'Retrieval of chunk + writing took `' . $ elapsed . '` seconds. Wrote `' . pb_backupbuddy :: $ format -> file_size ( $ bytesWritten ) . '` of max limit of `' . pb_backupbuddy :: $ format -> file_size ( $ maxPayload ) . '` MB per chunk after seeking to `' . $ seekTo . '`. Encoded size received: `' . strlen ( $ response [ 'data' ] ) . '` bytes.' ) ; $ seekTo = $ response [ 'resumepoint' ] ; if ( ( ( $ elapsed + $ TIME_WIGGLE_ROOM ) * ( $ numSentThisRound + 1 ) ) >= $ state [ 'minimumExecutionTime' ] ) { pb_backupbuddy :: status ( 'details' , 'Not enough time to request more data this pass. Chunking.' ) ; $ keepSending = false ; $ nextStep = array ( 'function' => 'deploy_getFile' , 'args' => array ( $ state , $ destinationPath , $ sendFile , $ sendType , $ finalNextStep , $ seekTo ) , 'start_time' => 0 , 'finish_time' => 0 , 'attempts' => 0 , ) ; $ this -> insert_next_step ( $ nextStep ) ; return true ; } else { pb_backupbuddy :: status ( 'details' , 'There appears to be enough time to get more data this pass.' ) ; $ keepSending = true ; } } } }
deploy_getFile()
 Supports chunked retrieval.
deploy_getFile () Supports chunked retrieval .
// seconds of wiggle room around sending. /*
		pb_backupbuddy::status( 'details', 'Path: `' . $destinationPath . '`.' );
		pb_backupbuddy::status( 'details', 'File: `' . $sendFile . '`.' );
		pb_backupbuddy::status( 'details', 'Type: `' . $sendType . '`.' );
		*/ // in MB. convert to bytes. /* $response now contains an array from the server.
			 *	data			string		Binary file contents.
			 *	datalen			int			length of the filedata param.
			 *	done				bool			true if this is the last of the file.
			 *	size			int			Total file size in bytes.
			 *	resumepoint		int			ftell resume point to pass to next fseek. 0 if done = true.
			 *	encoded			bool			True if filename needs to be utf8_decoded
			 
			 each files => array(
			 'file'    => '',
			 'data'    => '',
			 'datalen' => 0,
			 'size'    => '',
			 'done'    => false,
			 'test'    => false,
			 'encoded' => false,
			 )
			 */ // First or only part so delete if already exists & is a file (not directory &; not a resumed chunk). // Make sure containing directory exists. // Open/create file for write/append. // Seek to specific location. fseeking rather than direct append in case there's some sort of race condition and this gets out of order in some way. Best to be specific. // Write to file. // Failed writing. // Success writing. // Handle finishing up or chunking if needed. // Transfer finished. // More chunks remain. // Next chunk fseek to this point (got by ftell). // Could we have time to send another piece based on average send time?
 // end while( true == $keepSending ).