/** * Implements the _run() abstract method */ function _run() { if ($this->getState() == 'postrun') { Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . " :: Already finished"); $this->setStep(''); $this->setSubstep(''); } else { $this->setState('running'); } // Try to step the archiver $archive = Factory::getArchiverEngine(); $ret = $archive->transformJPA($this->xformIndex, $this->offset); // Error propagation $this->propagateFromObject($archive); if ($ret !== false && $archive->getError() == '') { $this->offset = $ret['offset']; $this->xformIndex = $ret['index']; $this->setStep($ret['filename']); } // Check for completion if ($ret['done']) { Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . ":: archive is initialized"); $this->setState('finished'); } // Calculate percentage $this->runningSize += $ret['chunkProcessed']; if ($ret['filesize'] > 0) { $this->progress = $this->runningSize / $ret['filesize']; } }
/** * Steps the files scanning of the current directory * * @return boolean True on success, false on fatal error */ protected function scanFiles() { $engine = Factory::getScanEngine(); list($root, $translated_root, $dir) = $this->getCleanDirectoryComponents(); // Get a filters instance $filters = Factory::getFilters(); if (is_null($this->getFiles_position)) { Factory::getLog()->log(LogLevel::INFO, "Scanning files of " . $this->current_directory); $this->processed_files_counter = 0; } else { Factory::getLog()->log(LogLevel::INFO, "Resuming scanning files of " . $this->current_directory); } // Get file listing $fileList = $engine->getFiles($this->current_directory, $this->getFiles_position); // Error propagation $this->propagateFromObject($engine); // If the list contains "too many" items, please break this step! if (Factory::getConfiguration()->get('volatile.breakflag', false)) { // Log the step break decision, for debugging reasons Factory::getLog()->log(LogLevel::INFO, "Large directory " . $this->current_directory . " while scanning for files; I will resume scanning in next step."); // Return immediately, marking that we are not done yet! return true; } // Error control if ($this->getError()) { return false; } // Do I have an unreadable directory? if ($fileList === false) { $this->setWarning('Unreadable directory ' . $this->current_directory); $this->done_file_scanning = true; } else { if (is_array($fileList) && !empty($fileList)) { // Add required trailing slash to $dir if (!empty($dir)) { $dir .= '/'; } // Scan all directory entries foreach ($fileList as $fileName) { $check = $dir . basename($fileName); if (_AKEEBA_IS_WINDOWS) { $check = Factory::getFilesystemTools()->TranslateWinPath($check); } // Do I need this? $dir contains a path relative to the root anyway... $check = ltrim(str_replace($translated_root, '', $check), '/'); $byFilter = ''; $skipThisFile = $filters->isFilteredExtended($check, $root, 'file', 'all', $byFilter); if ($skipThisFile) { Factory::getLog()->log(LogLevel::INFO, "Skipping file {$fileName} (filter: {$byFilter})"); } else { $this->file_list[] = $fileName; $this->processed_files_counter++; $this->progressAddFile(); } } } } // If the scanner engine nullified the next position we are done // scanning for files if (is_null($this->getFiles_position)) { $this->done_file_scanning = true; } // If the directory was genuinely empty we will have to add an empty // directory entry in the archive, otherwise this directory will never // be restored. if ($this->done_file_scanning && $this->processed_files_counter == 0) { Factory::getLog()->log(LogLevel::INFO, "Empty directory " . $this->current_directory); $archiver = Factory::getArchiverEngine(); if ($this->current_directory != $this->remove_path_prefix) { $archiver->addFile($this->current_directory, $this->remove_path_prefix, $this->path_prefix); } // Error propagation $this->propagateFromObject($archiver); // Check for errors if ($this->getError()) { return false; } unset($archiver); } return true; }
/** * Returns the relative and absolute path to the archive */ protected function getArchiveName() { $registry = Factory::getConfiguration(); // Import volatile scripting keys to the registry Factory::getEngineParamsProvider()->importScriptingToRegistry(); // Determine the extension $force_extension = Factory::getEngineParamsProvider()->getScriptingParameter('core.forceextension', null); if (is_null($force_extension)) { $archiver = Factory::getArchiverEngine(); $extension = $archiver->getExtension(); } else { $extension = $force_extension; } // Get the template name $templateName = $registry->get('akeeba.basic.archive_name'); Factory::getLog()->log(LogLevel::DEBUG, "Archive template name: {$templateName}"); // Parse all tags $fsUtils = Factory::getFilesystemTools(); $templateName = $fsUtils->replace_archive_name_variables($templateName); Factory::getLog()->log(LogLevel::DEBUG, "Expanded template name: {$templateName}"); $ds = DIRECTORY_SEPARATOR; $relative_path = $templateName . $extension; $absolute_path = $fsUtils->TranslateWinPath($registry->get('akeeba.basic.output_directory') . $ds . $relative_path); return array($relative_path, $absolute_path); }
/** * Implements the _finalize() abstract method * * @return void */ protected function _finalize() { $this->setState('finished'); // If we are in db backup mode, don't create a databases.ini $configuration = Factory::getConfiguration(); if (!Factory::getEngineParamsProvider()->getScriptingParameter('db.databasesini', 1)) { Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . " :: Skipping databases.ini"); } elseif ($this->installerSettings->databasesini) { $this->createDatabasesINI(); Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . " :: Creating databases.ini"); // Create a new string $databasesINI = $this->databases_ini; // BEGIN FIX 1.2 Stable -- databases.ini isn't written on disk Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . " :: Writing databases.ini contents"); $archiver = Factory::getArchiverEngine(); $virtualLocation = Factory::getEngineParamsProvider()->getScriptingParameter('db.saveasname', 'normal') == 'short' ? '' : $this->installerSettings->sqlroot; $archiver->addVirtualFile('databases.ini', $virtualLocation, $databasesINI); // Error propagation $this->propagateFromObject($archiver); if ($this->getError()) { return; } } // On alldb mode, we have to finalize the archive as well if (Factory::getEngineParamsProvider()->getScriptingParameter('db.finalizearchive', 0)) { Factory::getLog()->log(LogLevel::INFO, "Finalizing database dump archive"); $archiver = Factory::getArchiverEngine(); $archiver->finalize(); // Error propagation $this->propagateFromObject($archiver); if ($this->getError()) { return; } } // In CLI mode we'll also close the database connection if (defined('AKEEBACLI')) { Factory::getLog()->log(LogLevel::INFO, "Closing the database connection to the main database"); Factory::unsetDatabase(); } return; }
/** * Set up the Akeeba Restore engine for the current archive */ private function setUpAkeebaRestore() { $config = Factory::getConfiguration(); $maxTime = Factory::getTimer()->getTimeLeft(); $maxTime = floor($maxTime); $maxTime = max(2, $maxTime); $statistics = Factory::getStatistics(); $stat = $statistics->getRecord(); $backup_parts = Factory::getStatistics()->get_all_filenames($stat, false); $filePath = array_shift($backup_parts); $specialDirs = Platform::getInstance()->get_stock_directories(); $tmpPath = $specialDirs['[SITETMP]']; $archiver = Factory::getArchiverEngine(); $extension = $archiver->getExtension(); $extension = strtoupper($extension); $extension = ltrim($extension, '.'); $ksOptions = array('kickstart.tuning.max_exec_time' => $maxTime, 'kickstart.tuning.run_time_bias' => $config->get('akeeba.tuning.run_time_bias', 75), 'kickstart.tuning.min_exec_time' => '0', 'kickstart.procengine' => 'direct', 'kickstart.setup.sourcefile' => $filePath, 'kickstart.setup.destdir' => $tmpPath, 'kickstart.setup.restoreperms' => '0', 'kickstart.setup.filetype' => $extension, 'kickstart.setup.dryrun' => '1', 'kickstart.jps.password' => $config->get('engine.archiver.jps.key', '', false)); \AKFactory::nuke(); foreach ($ksOptions as $k => $v) { \AKFactory::set($k, $v); } \AKFactory::set('kickstart.enabled', true); }
/** * Creates a new dump part */ protected function getNextDumpPart() { // On database dump only mode we mustn't create part files! if (Factory::getEngineParamsProvider()->getScriptingParameter('db.saveasname', 'normal') == 'output') { return false; } // If the archiver is still processing, quit $finished = true; $configuration = Factory::getConfiguration(); $archiver = Factory::getArchiverEngine(); if ($configuration->get('volatile.engine.archiver.processingfile', false)) { return false; } // We have to add the dump file to the archive $this->closeFile(); Factory::getLog()->log(LogLevel::DEBUG, "Adding the SQL dump part to the archive"); $archiver->addFileRenamed($this->tempFile, $this->saveAsName); if ($this->getError()) { return false; } $finished = !$configuration->get('volatile.engine.archiver.processingfile', false); if (!$finished) { return false; } // Return if the file didn't finish getting added to the archive // Remove the old file Factory::getLog()->log(LogLevel::DEBUG, "Removing dump part's temporary file"); Factory::getTempFiles()->unregisterAndDeleteTempFile($this->tempFile, true); // Create the new dump part $this->partNumber++; $this->getBackupFilePaths($this->partNumber); $null = null; $this->writeline($null); return true; }