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);
}
}