/** * 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; } }
/** * 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); }
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; }
/** * 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); }
/** * @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; }
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(); }