Файловый менеджер - Редактировать - /var/www/html/administrator/components/com_akeebabackup/vendor/akeeba/engine/dev_platform/Command/BackupTake.php
Ðазад
<?php /** * Akeeba Engine * * @package akeebaengine * @copyright Copyright (c)2006-2024 Nicholas K. Dionysopoulos / Akeeba Ltd * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License version 3, or later * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, version 3. * * 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, see * <https://www.gnu.org/licenses/>. */ namespace Akeeba\Engine\DevPlatform\Command; use Akeeba\Engine\Base\Part; use Akeeba\Engine\DevPlatform\Translate\Text; use Akeeba\Engine\Factory; use Akeeba\Engine\Platform; use Akeeba\Engine\Psr\Log\LogLevel; use Silly\Application; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; class BackupTake { private float $startTime; private float $lastStep; public static function register(Application $app) { $app ->command('backup:take [description] [--profile=]', new self()) ->defaults( [ 'description' => null, 'profile' => 1, ] ) ->descriptions( 'Take a backup', [ '--profile' => 'Profile ID', ] ); } public function __invoke( ?string $description, int $profile, InputInterface $input, OutputInterface $output, SymfonyStyle $io ) { $outputStyle = new OutputFormatterStyle('red', null, ['bold']); $output->getFormatter()->setStyle('borked', $outputStyle); define('AKEEBA_PROFILE', $profile); $platform = Platform::getInstance(); $platform->load_configuration($profile); $description ??= Text::_('COM_AKEEBA_BACKUP_DEFAULT_DESCRIPTION') . ' ' . (new \DateTime())->format( Text::_('DATE_FORMAT_LC2') ); $backupId = $this->getBackupId(); $tag = Platform::getInstance()->get_backup_origin(); Factory::resetState(['maxrun' => 0]); $tempVarsTag = $tag . (empty($backupId) ? '' : ('.' . $backupId)); Factory::getFactoryStorage()->reset($tempVarsTag); Factory::nuke(); Factory::getLog()->log(LogLevel::DEBUG, " -- Resetting Akeeba Engine factory ($tag.$backupId)"); Platform::getInstance()->load_configuration(); $kettenrad = Factory::getKettenrad(); $kettenrad->setBackupId($backupId); $kettenrad->setup( [ 'description' => $description, ] ); $firstTime = true; $this->startTime = microtime(true); $this->lastStep = microtime(true); do { if (!$firstTime) { Factory::loadState($tag, $backupId, true); } else { $io->section('Starting backup'); $firstTime = false; /** * We need to run tick() twice in the first backup step. * * The first tick() will reset the backup engine and start a new backup. However, no backup record is created * at this point. This means that Factory::loadState() cannot find a backup record, therefore it cannot read * the backup profile being used, therefore it will assume it's profile #1. * * The second tick() creates the backup record without doing much else, fixing this issue. * * However, if you have conservative settings where the min exec time is MORE than the max exec time the second * tick would never run. Therefore we need to tell the first tick to ignore the time settings (since it only * takes a few milliseconds to execute anyway) and then apply the time settings on the second tick (which also * only takes a few milliseconds). This is why we have setIgnoreMinimumExecutionTime before and after the first * tick. DO NOT REMOVE THESE. * * Furthermore, if the first tick reaches the end of backup or an error condition we MUST NOT run the second * tick() since the engine state will be invalid. Hence the check for the state that performs a hard break. This * could happen if you have a sufficiently high max execution time, no break between steps and we fail to * execute any step, e.g. the installer image is missing, a database error occurred or we can not list the files * and directories to back up. * * THEREFORE, DO NOT REMOVE THE LOOP OR THE if-BLOCK IN IT, THEY ARE THERE FOR A GOOD REASON! */ $kettenrad->setIgnoreMinimumExecutionTime(true); for ($i = 0; $i < 2; $i++) { $kettenrad->tick(); if (in_array($kettenrad->getState(), [Part::STATE_FINISHED, Part::STATE_ERROR])) { break; } $kettenrad->setIgnoreMinimumExecutionTime(false); } $retArray = $kettenrad->getStatusArray(); $retArray = $this->backupProgress($io, $retArray); // If we are already finished or errored out we need to break immediately. if ($retArray['HasRun'] || $retArray['Error']) { break; } } $io->section('Stepping backup'); Factory::getTimer()->resetTime(); $kettenrad->tick(); $retArray = $kettenrad->getStatusArray(); if (empty($retArray['Error']) && ($retArray['HasRun'] != 1)) { Factory::saveState($tag, $backupId); } // TODO Fix me if ($retArray['Domain'] === 'finale' && $retArray['stepState'] === 'finished') { $weirdnessCounter ??= 0; $weirdnessCounter++; if ($weirdnessCounter > 3) { $io->warning( [ 'FIX ME: THIS SHOULD NOT BE HAPPENING!', '', 'We are in the finished state of the finalisation domain for more than three steps.', 'This is a bug. Fix me.', ] ); $retArray['HasRun'] = 1; } } $retArray = $this->backupProgress($io, $retArray); } while (!$retArray['HasRun'] && empty($retArray['Error'])); Factory::nuke(); Factory::getFactoryStorage()->reset($tempVarsTag); if (!$retArray['Error'] && $retArray['HasRun'] == 1) { $io->success('The backup finished successfully.'); } } private function getBackupId(): string { $microtime = explode(' ', microtime(false)); $microseconds = (int) ($microtime[0] * 1000000); return 'id-' . gmdate('Ymd-His') . '-' . $microseconds; } private function recursiveDebugReport(\Throwable $e, SymfonyStyle $io) { $io->writeln(str_repeat('-', 78)); $io->writeln('<borked>' . $e->getMessage() . '</borked>'); $io->writeln('<comment>' . $e->getFile() . ':' . $e->getLine() . '</comment>'); $io->writeln(''); $io->writeln($e->getTraceAsString()); $io->writeln(''); if ($e->getPrevious() instanceof \Throwable) { $this->recursiveDebugReport($e->getPrevious(), $io); } } private function backupProgress(SymfonyStyle $io, ?array $retArray): ?array { $stateText = !$retArray['HasRun'] ? '<fg=yellow>Running</> ▶️' : '<fg=green>Done</> ✅'; $stateText = !empty($retArray['Error']) ? '<fg=red>Error</> 💀' : $stateText; $now = microtime(true); $totalElapsed = $now - $this->startTime; $lastStep = $now - $this->lastStep; $this->lastStep = $now; $io->text( [ "<options=bold>Elapsed</> : " . $this->formatTime($totalElapsed) . ' <fg=gray>(' . $this->formatTime($lastStep) . ')</>', "<options=bold>State</> : " . $stateText, "<options=bold>Domain</> : " . $retArray['Domain'], "<options=bold>Step</> : " . $retArray['Step'], "<options=bold>Substep</> : " . $retArray['Substep'], ] ); if ($retArray['Warnings']) { $io->warning($retArray['Warnings']); } if ($retArray['Error']) { $io->error($retArray['Error']); } if (isset($retArray['ErrorException']) && $retArray['ErrorException'] instanceof \Throwable) { $this->recursiveDebugReport($retArray['ErrorException'], $io); } return $retArray; } private function formatTime(float $elapsed) { $msec = floor(1000 * ($elapsed - floor($elapsed))); $sec = (int)floor($elapsed); $hours = (int) floor($sec / 3600); $minutes = (int) floor(($sec % 3600) / 60); $seconds = (int) floor($sec % 60); if ($hours > 0) { return sprintf('%02d:%02d:%02d.%03d', $hours, $minutes, $seconds, $msec); } return sprintf('%02d:%02d.%03d', $minutes, $seconds, $msec); } }
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка