diff --git a/system/src/Grav/Common/Backup/ZipBackup.php b/system/src/Grav/Common/Backup/ZipBackup.php new file mode 100644 index 000000000..1836c56df --- /dev/null +++ b/system/src/Grav/Common/Backup/ZipBackup.php @@ -0,0 +1,103 @@ +findResource('cache://', true); + $destination = $destination . DS . 'tmp/Grav-' . uniqid(); + Folder::mkdir($destination); + } + + $name = basename(GRAV_ROOT); + + if (is_dir($destination)) { + $date = date('YmdHis', time()); + $filename = $name . '-' . $date . '.zip'; + $destination = rtrim($destination, DS) . DS . $filename; + } + + $messager && $messager([ + 'type' => 'message', + 'level' => 'info', + 'message' => 'Creating new Backup "' . $destination . '"' + ]); + $messager && $messager([ + 'type' => 'message', + 'level' => 'info', + 'message' => '' + ]); + + $zip = new \ZipArchive(); + $zip->open($destination, \ZipArchive::CREATE); + $zip->addEmptyDir($name); + + static::folderToZip(GRAV_ROOT, $zip, strlen(rtrim(GRAV_ROOT, DS) . DS), $messager); + + $messager && $messager([ + 'type' => 'progress', + 'percentage' => false, + 'complete' => true + ]); + + $messager && $messager([ + 'type' => 'message', + 'level' => 'info', + 'message' => '' + ]); + $messager && $messager([ + 'type' => 'message', + 'level' => 'info', + 'message' => 'Saving and compressing archive...' + ]); + + $zip->close(); + + return $destination; + } + + /** + * @param $folder + * @param $zipFile + * @param $exclusiveLength + * @param $messager + */ + private static function folderToZip($folder, \ZipArchive &$zipFile, $exclusiveLength, callable $messager = null) + { + $handle = opendir($folder); + while (false !== $f = readdir($handle)) { + if ($f != '.' && $f != '..') { + $filePath = "$folder/$f"; + // Remove prefix from file path before add to zip. + $localPath = substr($filePath, $exclusiveLength); + if (is_file($filePath)) { + $zipFile->addFile($filePath, $localPath); + + $messager && $messager([ + 'type' => 'progress', + 'percentage' => false, + 'complete' => false + ]); + } elseif (is_dir($filePath)) { + // Add sub-directory. + $zipFile->addEmptyDir($localPath); + static::folderToZip($filePath, $zipFile, $exclusiveLength, $messager); + } + } + } + closedir($handle); + } +} diff --git a/system/src/Grav/Console/Cli/BackupCommand.php b/system/src/Grav/Console/Cli/BackupCommand.php index 050301762..46590bf39 100644 --- a/system/src/Grav/Console/Cli/BackupCommand.php +++ b/system/src/Grav/Console/Cli/BackupCommand.php @@ -7,6 +7,7 @@ use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Grav\Common\Backup\ZipBackup; /** * Class BackupCommand @@ -23,6 +24,10 @@ class BackupCommand extends Command * @var */ protected $progress; + /** + * @var + */ + protected $output; /** * @@ -52,6 +57,8 @@ class BackupCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { + $this->output = $output; + $output->getFormatter()->setStyle('red', new OutputFormatterStyle('red')); $output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan')); $output->getFormatter()->setStyle('green', new OutputFormatterStyle('green')); @@ -60,25 +67,10 @@ class BackupCommand extends Command $this->progress = new ProgressBar($output); $this->progress->setFormat('Archiving %current% files [%bar%] %elapsed:6s% %memory:6s%'); - $name = basename($this->source); - $dir = dirname($this->source); - $date = date('YmdHis', time()); - $filename = $name . '-' . $date . '.zip'; - $destination = ($input->getArgument('destination')) ? $input->getArgument('destination') : ROOT_DIR; - $destination = rtrim($destination, DS) . DS . $filename; - $output->writeln(''); - $output->writeln('Creating new Backup "' . $destination . '"'); - $this->progress->start(); + ZipBackup::backup($destination, [$this, 'output']); - $zip = new \ZipArchive(); - $zip->open($destination, \ZipArchive::CREATE); - $zip->addEmptyDir($name); - - $this->folderToZip($this->source, $zip, strlen($dir . DS), $this->progress); - $zip->close(); - $this->progress->finish(); $output->writeln(''); $output->writeln(''); @@ -90,25 +82,20 @@ class BackupCommand extends Command * @param $exclusiveLength * @param $progress */ - private static function folderToZip($folder, \ZipArchive &$zipFile, $exclusiveLength, ProgressBar $progress) + public function output($args) { - $handle = opendir($folder); - while (false !== $f = readdir($handle)) { - if ($f != '.' && $f != '..') { - $filePath = "$folder/$f"; - // Remove prefix from file path before add to zip. - $localPath = substr($filePath, $exclusiveLength); - if (is_file($filePath)) { - $zipFile->addFile($filePath, $localPath); - $progress->advance(); - } elseif (is_dir($filePath)) { - // Add sub-directory. - $zipFile->addEmptyDir($localPath); - self::folderToZip($filePath, $zipFile, $exclusiveLength, $progress); + switch ($args['type']) { + case 'message': + $this->output->writeln($args['message']); + break; + case 'progress': + if ($args['complete']) { + $this->progress->finish(); + } else { + $this->progress->advance(); } - } + break; } - closedir($handle); } }