/**
  * Runs a custom API call for the selected post-processing engine
  * 
  * @return boolean 
  */
 public function dpeCustomAPICall()
 {
     $engine = $this->getState('engine');
     $method = $this->getState('method');
     $params = $this->getState('params', array());
     $engine = AEFactory::getPostprocEngine($engine);
     if ($engine === false) {
         return false;
     }
     return $engine->customApiCall($method, $params);
 }
 /**
  * Downloads a file from the remote storage to the user's browsers
  */
 public function dlfromremote()
 {
     $id = $this->getAndCheckId();
     $part = $this->input->get('part', 0, 'int');
     if ($id === false) {
         $url = 'index.php?option=com_akeeba&view=remotefiles&tmpl=component&task=listactions&id=' . $id;
         $this->setRedirect($url, JText::_('REMOTEFILES_ERR_INVALIDID'), 'error');
         return true;
     }
     $stat = AEPlatform::getInstance()->get_statistics($id);
     $remoteFilename = $stat['remote_filename'];
     $rfparts = explode('://', $remoteFilename);
     $engine = AEFactory::getPostprocEngine($rfparts[0]);
     $remote_filename = $rfparts[1];
     $basename = basename($remote_filename);
     $extension = strtolower(str_replace(".", "", strrchr($basename, ".")));
     if ($part > 0) {
         $new_extension = substr($extension, 0, 1) . sprintf('%02u', $part);
     } else {
         $new_extension = $extension;
     }
     $filename = $basename . '.' . $new_extension;
     $remote_filename = substr($remote_filename, 0, -strlen($extension)) . $new_extension;
     if ($engine->downloads_to_browser_inline) {
         @ob_end_clean();
         @clearstatcache();
         // Send MIME headers
         header('MIME-Version: 1.0');
         header('Content-Disposition: attachment; filename="' . $filename . '"');
         header('Content-Transfer-Encoding: binary');
         switch ($extension) {
             case 'zip':
                 // ZIP MIME type
                 header('Content-Type: application/zip');
                 break;
             default:
                 // Generic binary data MIME type
                 header('Content-Type: application/octet-stream');
                 break;
         }
         // Disable caching
         header('Expires: Mon, 20 Dec 1998 01:00:00 GMT');
         header('Cache-Control: no-cache, must-revalidate');
         header('Pragma: no-cache');
     }
     AEPlatform::getInstance()->load_configuration($stat['profile_id']);
     $result = $engine->downloadToBrowser($remote_filename);
     if (is_string($result) && $result !== true && $result !== false) {
         // We have to redirect
         $result = str_replace('://%2F', '://', $result);
         @ob_end_clean();
         header('Location: ' . $result);
         flush();
         JFactory::getApplication()->close();
     } elseif ($result === false) {
         // Failed to download
         $url = 'index.php?option=com_akeeba&view=remotefiles&tmpl=component&task=listactions&id=' . $id;
         $this->setRedirect($url, $engine->getWarning(), 'error');
     }
     return true;
 }
 public function deleteRemoteFiles()
 {
     $id = $this->getState('id', -1);
     $part = $this->getState('part', -1);
     $ret = array('error' => false, 'finished' => false, 'id' => $id, 'part' => $part);
     // Gather the necessary information to perform the delete
     $stat = AEPlatform::getInstance()->get_statistics($id);
     $remoteFilename = $stat['remote_filename'];
     $rfparts = explode('://', $remoteFilename);
     $engine = AEFactory::getPostprocEngine($rfparts[0]);
     $remote_filename = $rfparts[1];
     // Load the correct backup profile
     AEPlatform::getInstance()->load_configuration($stat['profile_id']);
     $config = AEFactory::getConfiguration();
     // Start timing ourselves
     $timer = AEFactory::getTimer();
     // The core timer object
     $start = $timer->getRunningTime();
     // Mark the start of this download
     $break = false;
     // Don't break the step
     while ($timer->getTimeLeft() && !$break && $part < $stat['multipart']) {
         // Get the remote filename
         $basename = basename($remote_filename);
         $extension = strtolower(str_replace(".", "", strrchr($basename, ".")));
         if ($part > 0) {
             $new_extension = substr($extension, 0, 1) . sprintf('%02u', $part);
         } else {
             $new_extension = $extension;
         }
         $filename = $basename . '.' . $new_extension;
         $remote_filename = substr($remote_filename, 0, -strlen($extension)) . $new_extension;
         // Do we have to initialize the process?
         if ($part == -1) {
             // Init
             $part = 0;
         }
         // Try to delete the part
         $required_time = 1.0;
         $result = $engine->delete($remote_filename);
         if (!$result) {
             $ret['error'] = JText::_('REMOTEFILES_ERR_CANTDELETE') . $engine->getWarning();
             return $ret;
             return;
         } else {
             // Successful delete
             $end = $timer->getRunningTime();
             $part++;
         }
         // Do we predict that we have enough time?
         $required_time = max(1.1 * ($end - $start), $required_time);
         if ($timer->getTimeLeft() < $required_time) {
             $break = true;
         }
         $start = $end;
     }
     if ($part >= $stat['multipart']) {
         // Just finished!
         $stat['remote_filename'] = '';
         AEPlatform::getInstance()->set_or_update_statistics($id, $stat, $engine);
         $ret['finished'] = true;
         return $ret;
     } else {
         // More work to do...
         $ret['id'] = $id;
         $ret['part'] = $part;
         return $ret;
     }
 }
예제 #4
0
 /**
  * Try to pack some files in the $file_list, restraining ourselves not to reach the max
  * number of files or max fragment size while doing so. If this process is over and we are
  * left without any more files, reset $done_scanning to false in order to instruct the class
  * to scan for more files.
  *
  * @return bool True if there were files packed, false otherwise (empty filelist)
  */
 private function pack_files()
 {
     // Get a reference to the archiver and the timer classes
     $archiver = AEFactory::getArchiverEngine();
     $timer = AEFactory::getTimer();
     $configuration = AEFactory::getConfiguration();
     // If post-processing after part creation is enabled, make sure we do post-process each part before moving on
     if ($configuration->get('engine.postproc.common.after_part', 0)) {
         if (!empty($archiver->finishedPart)) {
             $filename = array_shift($archiver->finishedPart);
             AEUtilLogger::WriteLog(_AE_LOG_INFO, 'Preparing to post process ' . basename($filename));
             $post_proc = AEFactory::getPostprocEngine();
             $result = $post_proc->processPart($filename);
             $this->propagateFromObject($post_proc);
             if ($result === false) {
                 $this->setWarning('Failed to process file ' . basename($filename));
             } else {
                 AEUtilLogger::WriteLog(_AE_LOG_INFO, 'Successfully processed file ' . basename($filename));
             }
             // Should we delete the file afterwards?
             if ($configuration->get('engine.postproc.common.delete_after', false) && $post_proc->allow_deletes && $result !== false) {
                 AEUtilLogger::WriteLog(_AE_LOG_DEBUG, 'Deleting already processed file ' . basename($filename));
                 AEPlatform::getInstance()->unlink($filename);
             }
             if ($post_proc->break_after && $result !== false) {
                 $configuration->set('volatile.breakflag', true);
                 return true;
             }
             // This is required to let the backup continue even after a post-proc failure
             $this->resetErrors();
             $this->setState('running');
         }
     }
     // If the archiver has work to do, make sure it finished up before continuing
     if ($configuration->get('volatile.engine.archiver.processingfile', false)) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Continuing file packing from previous step");
         $result = $archiver->addFile('', '', '');
         $this->propagateFromObject($archiver);
         if ($this->getError()) {
             return false;
         }
         // If that was the last step, mark a file done
         if (!$configuration->get('volatile.engine.archiver.processingfile', false)) {
             $this->progressMarkFileDone();
         }
     }
     // Did it finish, or does it have more work to do?
     if ($configuration->get('volatile.engine.archiver.processingfile', false)) {
         // More work to do. Let's just tell our parent that we finished up successfully.
         return true;
     }
     // Normal file backup loop; we keep on processing the file list, packing files as we go.
     if (count($this->file_list) == 0) {
         // No files left to pack -- This should never happen! We catch this condition at the end of this method!
         $this->done_scanning = false;
         $this->progressMarkFolderDone();
         return false;
     } else {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Packing files");
         $packedSize = 0;
         $numberOfFiles = 0;
         list($usec, $sec) = explode(" ", microtime());
         $opStartTime = (double) $usec + (double) $sec;
         while (count($this->file_list) > 0) {
             $file = @array_shift($this->file_list);
             $size = 0;
             if (file_exists($file)) {
                 $size = @filesize($file);
             }
             // Anticipatory file size algorithm
             if ($numberOfFiles > 0 && $size > AELargeFileThreshold) {
                 if (!AEFactory::getConfiguration()->get('akeeba.tuning.nobreak.beforelargefile', 0)) {
                     // If the file is bigger than the big file threshold, break the step
                     // to avoid potential timeouts
                     $this->setBreakFlag();
                     AEUtilLogger::WriteLog(_AE_LOG_INFO, "Breaking step _before_ large file: " . $file . " - size: " . $size);
                     // Push the file back to the list.
                     array_unshift($this->file_list, $file);
                     // Mark that we are not done packing files
                     $this->done_scanning = true;
                     return true;
                 }
             }
             // Proactive potential timeout detection
             // Rough estimation of packing speed in bytes per second
             list($usec, $sec) = explode(" ", microtime());
             $opEndTime = (double) $usec + (double) $sec;
             if ($opEndTime - $opStartTime == 0) {
                 $_packSpeed = 0;
             } else {
                 $_packSpeed = $packedSize / ($opEndTime - $opStartTime);
             }
             // Estimate required time to pack next file. If it's the first file of this operation,
             // do not impose any limitations.
             $_reqTime = $_packSpeed - 0.01 <= 0 ? 0 : $size / $_packSpeed;
             // Do we have enough time?
             if ($timer->getTimeLeft() < $_reqTime) {
                 if (!AEFactory::getConfiguration()->get('akeeba.tuning.nobreak.proactive', 0)) {
                     array_unshift($this->file_list, $file);
                     AEUtilLogger::WriteLog(_AE_LOG_INFO, "Proactive step break - file: " . $file . " - size: " . $size . " - req. time " . sprintf('%2.2f', $_reqTime));
                     $this->setBreakFlag();
                     $this->done_scanning = true;
                     return true;
                 }
             }
             $packedSize += $size;
             $numberOfFiles++;
             $ret = $archiver->addFile($file, $this->remove_path_prefix, $this->path_prefix);
             // If no more processing steps are required, mark a done file
             if (!$configuration->get('volatile.engine.archiver.processingfile', false)) {
                 $this->progressMarkFileDone();
             }
             // Error propagation
             $this->propagateFromObject($archiver);
             if ($this->getError()) {
                 return false;
             }
             // If this was the first file of the fragment and it exceeded the fragment's capacity,
             // break the step. Continuing with more operations after packing such a big file is
             // increasing the risk to hit a timeout.
             if ($packedSize > AELargeFileThreshold && $numberOfFiles == 1) {
                 if (!AEFactory::getConfiguration()->get('akeeba.tuning.nobreak.afterlargefile', 0)) {
                     AEUtilLogger::WriteLog(_AE_LOG_INFO, "Breaking step *after* large file: " . $file . " - size: " . $size);
                     $this->setBreakFlag();
                     return true;
                 }
             }
             // If we have to continue processing the file, break the file packing loop forcibly
             if ($configuration->get('volatile.engine.archiver.processingfile', false)) {
                 return true;
             }
         }
         $this->done_scanning = count($this->file_list) > 0;
         if (!$this->done_scanning) {
             $this->progressMarkFolderDone();
         }
         return true;
     }
 }
 /**
  * Implements the _run() abstract method
  */
 protected function _run()
 {
     // Check if we are already done
     if ($this->getState() == 'postrun') {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . " :: Already finished");
         $this->setStep("");
         $this->setSubstep("");
         return;
     }
     // Mark ourselves as still running (we will test if we actually do towards the end ;) )
     $this->setState('running');
     // Check if we are still adding a database dump part to the archive, or if
     // we have to post-process a part
     if (AEUtilScripting::getScriptingParameter('db.saveasname', 'normal') != 'output') {
         $archiver = AEFactory::getArchiverEngine();
         $configuration = AEFactory::getConfiguration();
         if ($configuration->get('engine.postproc.common.after_part', 0)) {
             if (!empty($archiver->finishedPart)) {
                 $filename = array_shift($archiver->finishedPart);
                 AEUtilLogger::WriteLog(_AE_LOG_INFO, 'Preparing to post process ' . basename($filename));
                 $post_proc = AEFactory::getPostprocEngine();
                 $result = $post_proc->processPart($filename);
                 $this->propagateFromObject($post_proc);
                 if ($result === false) {
                     $this->setWarning('Failed to process file ' . basename($filename));
                 } else {
                     AEUtilLogger::WriteLog(_AE_LOG_INFO, 'Successfully processed file ' . basename($filename));
                 }
                 // Should we delete the file afterwards?
                 if ($configuration->get('engine.postproc.common.delete_after', false) && $post_proc->allow_deletes && $result !== false) {
                     AEUtilLogger::WriteLog(_AE_LOG_DEBUG, 'Deleting already processed file ' . basename($filename));
                     AEPlatform::getInstance()->unlink($filename);
                 }
                 if ($post_proc->break_after) {
                     $configuration->set('volatile.breakflag', true);
                     return;
                 }
             }
         }
         if ($configuration->get('volatile.engine.archiver.processingfile', false)) {
             // We had already started archiving the db file, but it needs more time
             $finished = true;
             AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Continuing adding the SQL dump part to the archive");
             $archiver->addFile(null, null, null);
             $this->propagateFromObject($archiver);
             if ($this->getError()) {
                 return;
             }
             $finished = !$configuration->get('volatile.engine.archiver.processingfile', false);
             if ($finished) {
                 $this->getNextDumpPart();
             } else {
                 return;
             }
         }
     }
     $this->stepDatabaseDump();
     $null = null;
     $this->writeline($null);
 }
예제 #6
0
파일: finalization.php 프로젝트: 01J/topm
 private function apply_remote_quotas()
 {
     $this->setStep('Applying remote storage quotas');
     $this->setSubstep('');
     // Make sure we are enabled
     $config = AEFactory::getConfiguration();
     $enableRemote = $config->get('akeeba.quota.remote', 0);
     if (!$enableRemote) {
         return true;
     }
     // Get the list of files to kill
     if (empty($this->remote_files_killlist)) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, 'Applying remote file quotas');
         $this->remote_files_killlist = $this->get_remote_quotas();
         if (empty($this->remote_files_killlist)) {
             AEUtilLogger::WriteLog(_AE_LOG_DEBUG, 'No remote files to apply quotas to were found');
             return true;
         }
     }
     // Remove the files
     $timer = AEFactory::getTimer();
     while ($timer->getRunningTime() && count($this->remote_files_killlist)) {
         $filename = array_shift($this->remote_files_killlist);
         list($engineName, $path) = explode('://', $filename);
         $engine = AEFactory::getPostprocEngine($engineName);
         if (!$engine->can_delete) {
             continue;
         }
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Removing {$filename}");
         $result = $engine->delete($path);
         if (!$result) {
             AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Removal failed: " . $engine->getWarning());
         }
     }
     // Return false if we have more work to do or true if we're done
     if (count($this->remote_files_killlist)) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Remote file removal will continue in the next step");
         return false;
     } else {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Remote file quotas applied successfully");
         return true;
     }
 }
 public function upload()
 {
     $id = $this->getState('id', -1);
     $part = $this->getState('part', -1);
     $frag = $this->getState('frag', -1);
     // Calculate the filenames
     $stat = AEPlatform::getInstance()->get_statistics($id);
     $local_filename = $stat['absolute_path'];
     $basename = basename($local_filename);
     $extension = strtolower(str_replace(".", "", strrchr($basename, ".")));
     if ($part > 0) {
         $new_extension = substr($extension, 0, 1) . sprintf('%02u', $part);
     } else {
         $new_extension = $extension;
     }
     $filename = $basename . '.' . $new_extension;
     $local_filename = substr($local_filename, 0, -strlen($extension)) . $new_extension;
     // Load the post-processing engine
     AEPlatform::getInstance()->load_configuration($stat['profile_id']);
     $config = AEFactory::getConfiguration();
     $session = JFactory::getSession();
     $engine = null;
     if (!empty($savedEngine) && $frag != -1) {
         // If it's not the first fragment, try to revive the saved engine
         $savedEngine = $session->get('postproc_engine', null, 'akeeba');
         $engine = unserialize($savedEngine);
     }
     if (empty($engine)) {
         $engine_name = $config->get('akeeba.advanced.proc_engine');
         $engine = AEFactory::getPostprocEngine($engine_name);
     }
     // Start uploading
     $result = $engine->processPart($local_filename);
     switch ($result) {
         case true:
             $part++;
             break;
         case 1:
             $frag++;
             $savedEngine = serialize($engine);
             $session->set('postproc_engine', null, 'akeeba');
             break;
         case false:
             $part = -1;
             return;
             break;
     }
     $remote_filename = $config->get('akeeba.advanced.proc_engine', '') . '://';
     $remote_filename .= $engine->remote_path;
     if ($part >= 0) {
         if ($part >= $stat['multipart']) {
             // Update stats with remote filename
             $data = array('remote_filename' => $remote_filename);
             AEPlatform::getInstance()->set_or_update_statistics($id, $data, $engine);
         }
     }
     $this->setState('id', $id);
     $this->setState('part', $part);
     $this->setState('frag', $frag);
     $this->setState('stat', $stat);
     $this->setState('remotename', $remote_filename);
     return $result;
 }
예제 #8
0
	/**
	 * Implements the _run() abstract method
	 */
	protected function _run()
	{
		// Check if we are already done
		if ($this->getState() == 'postrun') {
			AEUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__." :: Already finished");
			$this->setStep("");
			$this->setSubstep("");
			return;
		}

		// Mark ourselves as still running (we will test if we actually do towards the end ;) )
		$this->setState('running');

		// Check if we are still adding a database dump part to the archive, or if
		// we have to post-process a part
		if( AEUtilScripting::getScriptingParameter('db.saveasname','normal') != 'output' )
		{
			$archiver =& AEFactory::getArchiverEngine();
			$configuration =& AEFactory::getConfiguration();

			if($configuration->get('engine.postproc.common.after_part',0))
			{
				if(!empty($archiver->finishedPart))
				{
					$filename = array_shift($archiver->finishedPart);
					AEUtilLogger::WriteLog(_AE_LOG_INFO, 'Preparing to post process '.basename($filename));
					$post_proc =& AEFactory::getPostprocEngine();
					$result = $post_proc->processPart( $filename );
					$this->propagateFromObject($post_proc);

					if($result === false)
					{
						$this->setWarning('Failed to process file '.basename($filename));
					}
					else
					{
						AEUtilLogger::WriteLog(_AE_LOG_INFO, 'Successfully processed file '.basename($filename));
					}

					// Should we delete the file afterwards?
					if(
						$configuration->get('engine.postproc.common.delete_after',false)
						&& $post_proc->allow_deletes
						&& ($result !== false)
					)
					{
						AEUtilLogger::WriteLog(_AE_LOG_DEBUG, 'Deleting already processed file '.basename($filename));
						AEPlatform::unlink($filename);
					}

					if($post_proc->break_after) {
						$configuration->set('volatile.breakflag', true);
						return;
					}
				}
			}

			if($configuration->get('volatile.engine.archiver.processingfile',false))
			{
				// We had already started archiving the db file, but it needs more time
				$finished = true;
				AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Continuing adding the SQL dump part to the archive");
				$archiver->addFile(null,null,null);
				$this->propagateFromObject($archiver);
				if($this->getError()) return;
				$finished = !$configuration->get('volatile.engine.archiver.processingfile',false);
				if($finished)
				{
					$this->getNextDumpPart();
				}
				else
				{
					return;
				}
			}
		}

		// Initialize local variables
		$db =& $this->getDB();
		if($this->getError()) return;

		if( !is_object($db) || ($db === false) )
		{
			$this->setError(__CLASS__.'::_run() Could not connect to database?!');
			return;
		}

		$outData	= ''; // Used for outputting INSERT INTO commands

		$this->enforceSQLCompatibility(); // Apply MySQL compatibility option
		if($this->getError()) return;

		// Touch SQL dump file
		$nada = "";
		$this->writeline($nada);

		// Get this table's information
		$tableName = $this->nextTable;
		$tableAbstract = trim( $this->table_name_map[$tableName] );
		$dump_records = $this->tables_data[$tableName]['dump_records'];

		// If it is the first run, find number of rows and get the CREATE TABLE command
		if( $this->nextRange == 0 )
		{
			if($this->getError()) return;
			$outCreate = '';
			if(is_array($this->tables_data[$tableName])) {
				if(array_key_exists('create', $this->tables_data[$tableName])) {
					$outCreate = $this->tables_data[$tableName]['create'];
				}
			}
			
			if(empty($outCreate) && !empty($tableName)) {
				// The CREATE command wasn't cached. Time to create it. The $type and $dependencies
				// variables will be thrown away.
				$type = 'table';
				$outCreate = $this->get_create($tableAbstract, $tableName, $type, $dependencies);
			}

			// Write the CREATE command
			if(!$this->writeDump($outCreate)) return;

			// Create drop statements if required (the key is defined by the scripting engine)
			$configuration =& AEFactory::getConfiguration();
			if( AEUtilScripting::getScriptingParameter('db.dropstatements',0) )
			{
				if(array_key_exists('create', $this->tables_data[$tableName])) {
					// @todo This looks cheesy...
					$dropStatement = $this->createDrop($this->tables_data[$tableName]['create']);
				} else {
					$type = 'table';
					$createStatement = $this->get_create($tableAbstract, $tableName, $type, $dependencies);
					$dropStatement = $this->createDrop($createStatement);
				}
				if(!empty($dropStatement))
				{
					if(!$this->writeDump($outCreate)) return;
				}
			}

			if( $dump_records )
			{
				// We are dumping data from a table, get the row count
				$this->getRowCount( $tableAbstract );
			}
			else
			{
				// We should not dump any data
				AEUtilLogger::WriteLog(_AE_LOG_INFO, "Skipping dumping data of " . $tableAbstract);
				$this->maxRange = 0;
				$this->nextRange = 1;
				$outData = '';
				$numRows = 0;
			}
		}

		// Check if we have more work to do on this table
		$configuration =& AEFactory::getConfiguration();
		$batchsize = intval($configuration->get('engine.dump.common.batchsize', 1000));
		if($batchsize <= 0) $batchsize = 1000;
		if( ($this->nextRange < $this->maxRange) )
		{
			$timer =& AEFactory::getTimer();

			// Get the number of rows left to dump from the current table
			$sql = "SELECT * FROM `$tableAbstract`";
			if( $this->nextRange == 0 )
			{
				// First run, get a cursor to all records
				$db->setQuery( $sql, 0, $batchsize );
				AEUtilLogger::WriteLog(_AE_LOG_INFO, "Beginning dump of " . $tableAbstract);
			}
			else
			{
				// Subsequent runs, get a cursor to the rest of the records
				$db->setQuery( $sql, $this->nextRange, $batchsize );
				AEUtilLogger::WriteLog(_AE_LOG_INFO, "Continuing dump of " . $tableAbstract . " from record #{$this->nextRange}");
			}

			$this->query = '';
			$numRows = 0;
			$use_abstract = AEUtilScripting::getScriptingParameter('db.abstractnames', 1);
			while( is_array($myRow = $db->loadAssoc(false)) && ( $numRows < ($this->maxRange - $this->nextRange) ) ) {
				$this->createNewPartIfRequired();
				$numRows++;
				$numOfFields = count( $myRow );

				if(
					(!$this->extendedInserts) || // Add header on simple INSERTs, or...
					( $this->extendedInserts && empty($this->query) ) //...on extended INSERTs if there are no other data, yet
				)
				{
					$newQuery = true;
					if( $numOfFields > 0 ) $this->query = "INSERT INTO `" . (!$use_abstract ? $tableName : $tableAbstract) . "` VALUES ";
				}
				else
				{
					// On other cases, just mark that we should add a comma and start a new VALUES entry
					$newQuery = false;
				}

				$outData = '(';

				// Step through each of the row's values
				$fieldID = 0;

				// Used in running backup fix
				$isCurrentBackupEntry = false;

				// Fix 1.2a - NULL values were being skipped
				if( $numOfFields > 0 ) foreach( $myRow as $value )
				{
					// The ID of the field, used to determine placement of commas
					$fieldID++;

					// Fix 2.0: Mark currently running backup as successful in the DB snapshot
					if($tableAbstract == '#__ak_stats')
					{
						if($fieldID == 1)
						{
							// Compare the ID to the currently running
							$statistics =& AEFactory::getStatistics();
							$isCurrentBackupEntry = ($value == $statistics->getId());
						}
						elseif ($fieldID == 6)
						{
							// Treat the status field
							$value = $isCurrentBackupEntry ? 'complete' : $value;
						}
					}

					// Post-process the value
					if( is_null($value) )
					{
						$outData .= "NULL"; // Cope with null values
					} else {
						// Accommodate for runtime magic quotes
						$value = @get_magic_quotes_runtime() ? stripslashes( $value ) : $value;
						$outData .= $db->Quote($value);
					}
					if( $fieldID < $numOfFields ) $outData .= ', ';
				} // foreach
				$outData .= ')';

				if( $numOfFields )
				{
					// If it's an existing query and we have extended inserts
					if($this->extendedInserts && !$newQuery)
					{
						// Check the existing query size
						$query_length = strlen($this->query);
						$data_length = strlen($outData);
						if( ($query_length + $data_length) > $this->packetSize )
						{
							// We are about to exceed the packet size. Write the data so far.
							$this->query .= ";\n";
							if(!$this->writeDump($this->query)) return;
							// Then, start a new query
							$this->query = '';
							$this->query = "INSERT INTO `" . (!$use_abstract ? $tableName : $tableAbstract) . "` VALUES ";
							$this->query .= $outData;
						}
						else
						{
							// We have room for more data. Append $outData to the query.
							$this->query .= ', ';
							$this->query .= $outData;
						}
					}
					elseif($this->extendedInserts && $newQuery)
					// If it's a brand new insert statement in an extended INSERTs set
					{
						// Append the data to the INSERT statement
						$this->query .= $outData;
						// Let's see the size of the dumped data...
						$query_length = strlen($this->query);
						if($query_length >= $this->packetSize)
						{
							// This was a BIG query. Write the data to disk.
							$this->query .= ";\n";
							if(!$this->writeDump($this->query)) return;
							// Then, start a new query
							$this->query = '';
						}
					}
					else
					// It's a normal (not extended) INSERT statement
					{
						// Append the data to the INSERT statement
						$this->query .= $outData;
						// Write the data to disk.
						$this->query .= ";\n";
						if(!$this->writeDump($this->query)) return;
						// Then, start a new query
						$this->query = '';
					}
				}
				$outData = '';

				// Check for imminent timeout
				if( $timer->getTimeLeft() <= 0 ) {
					AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Breaking dump of $tableAbstract after $numRows rows; will continue on next step");
					break;
				}
			} // for (all rows left)

			// Advance the _nextRange pointer
			$this->nextRange += ($numRows != 0) ? $numRows : 1;

			$this->setStep($tableName);
			$this->setSubstep($this->nextRange . ' / ' . $this->maxRange);
		} // if more work on the table

		// Finalize any pending query
		// WARNING! If we do not do that now, the query will be emptied in the next operation and all
		// accumulated data will go away...
		if(!empty($this->query))
		{
			$this->query .= ";\n";
			if(!$this->writeDump($this->query)) return;
			$this->query = '';
		}

		// Check for end of table dump (so that it happens inside the same operation)
		if( !($this->nextRange < $this->maxRange) )
		{
			// Tell the user we are done with the table
			AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Done dumping " . $tableAbstract);

			if(count($this->tables) == 0)
			{
				// We have finished dumping the database!
				AEUtilLogger::WriteLog(_AE_LOG_INFO, "End of database detected; flushing the dump buffers...");
				$null = null;
				$this->writeDump($null);
				AEUtilLogger::WriteLog(_AE_LOG_INFO, "Database has been successfully dumped to SQL file(s)");
				$this->setState('postrun');
				$this->setStep('');
				$this->setSubstep('');
				$this->nextTable = '';
				$this->nextRange = 0;
			} elseif(count($this->tables) != 0) {
				// Switch tables
				$this->nextTable = array_shift( $this->tables );
				$this->nextRange = 0;
				$this->setStep($this->nextTable);
				$this->setSubstep('');
			}
		}

		$null = null;
		$this->writeline($null);
	}
예제 #9
0
 /**
  * @param $archiver
  * @param $configuration
  *
  * @return bool
  */
 private function postProcessDonePartFile($archiver, $configuration)
 {
     $filename = array_shift($archiver->finishedPart);
     AEUtilLogger::WriteLog(_AE_LOG_INFO, 'Preparing to post process ' . basename($filename));
     $post_proc = AEFactory::getPostprocEngine();
     $result = $post_proc->processPart($filename);
     $this->propagateFromObject($post_proc);
     if ($result === false) {
         $this->setWarning('Failed to process file ' . basename($filename));
     } else {
         AEUtilLogger::WriteLog(_AE_LOG_INFO, 'Successfully processed file ' . basename($filename));
     }
     // Should we delete the file afterwards?
     if ($configuration->get('engine.postproc.common.delete_after', false) && $post_proc->allow_deletes && $result !== false) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, 'Deleting already processed file ' . basename($filename));
         AEPlatform::getInstance()->unlink($filename);
     }
     if ($post_proc->break_after && $result !== false) {
         $configuration->set('volatile.breakflag', true);
         return true;
     }
     // This is required to let the backup continue even after a post-proc failure
     $this->resetErrors();
     $this->setState('running');
     return false;
 }
예제 #10
0
	public function upload()
	{
		// Get the parameters
		$id = $this->getAndCheckId();
		$part = JRequest::getInt('part', 0);
		$frag = JRequest::getInt('frag', 0);

		// Check the backup stat ID
		if($id === false) {
			$url = 'index.php?option=com_akeeba&view=upload&tmpl=component&task=cancelled&id='.$id;
			$this->setRedirect($url, JText::_('AKEEBA_TRANSFER_ERR_INVALIDID'), 'error');
			return;
		}
		
		// Calculate the filenames
		$stat = AEPlatform::get_statistics($id);
		$local_filename = $stat['absolute_path'];
		$basename = basename($local_filename);
		$extension = strtolower(str_replace(".", "", strrchr($basename, ".")));
		
		if($part > 0) {
			$new_extension = substr($extension,0,1) . sprintf('%02u', $part); 
		} else {
			$new_extension = $extension;
		}
		
		$filename = $basename.'.'.$new_extension;
		$local_filename = substr($local_filename, 0, -strlen($extension)).$new_extension;
		
		// Load the post-processing engine
		AEPlatform::load_configuration($stat['profile_id']);
		$config = AEFactory::getConfiguration();
		
		$session = JFactory::getSession();
		$engine = null;
		if(!empty($savedEngine) && ($frag != -1)) {
			// If it's not the first fragment, try to revive the saved engine
			$savedEngine = $session->get('postproc_engine', null, 'akeeba');
			$engine = unserialize($savedEngine);
		}
		if(empty($engine)) {
			$engine_name = $config->get('akeeba.advanced.proc_engine');
			$engine = AEFactory::getPostprocEngine($engine_name);
		}
		
		// Start uploading
		$result = $engine->processPart($local_filename);
		switch($result) {
			case true:
				$part++;
				break;
			
			case 1:
				$frag++;
				$savedEngine = serialize($engine);
				$session->set('postproc_engine', null, 'akeeba');
				break;
			
			case false;
				$part = -1;
				return;
				break;
		}
		
		if(version_compare(JVERSION, '1.6.0', 'ge')) {
			$view = & $this->getView( 'upload', 'html', '', array('base_path' => $this->basePath));
		} else {
			$view = & $this->getView( 'upload', 'html', '', array( 'base_path'=>$this->_basePath));
		}

		if($part >= 0) {
			if($part < $stat['multipart']) {
				$view->setLayout('uploading');
				$view->assign('parts',$stat['multipart']);
				$view->assign('part', $part);
				$view->assign('frag', $frag);
				$view->assign('id', $id);
			} else {
				// Update stats with remote filename
				$remote_filename = $config->get('akeeba.advanced.proc_engine','').'://';
				$remote_filename .= $engine->remote_path;
				$data = array(
					'remote_filename'	=> $remote_filename
				);
				AEPlatform::set_or_update_statistics($id, $data, $engine);
				
				$view->setLayout('done');
			}
		} else {
			$view->setLayout('error');
		}
		$view->display();
	}