diff --git a/bin/grav b/bin/grav
index c33e0ba35..37b41e86c 100755
--- a/bin/grav
+++ b/bin/grav
@@ -19,6 +19,7 @@ $app->addCommands(array(
new Grav\Console\SetupCommand(),
new Grav\Console\CleanCommand(),
new Grav\Console\ClearCacheCommand(),
+ new Grav\Console\BackupCommand(),
new Grav\Console\NewProjectCommand(),
));
$app->run();
diff --git a/system/src/Grav/Console/BackupCommand.php b/system/src/Grav/Console/BackupCommand.php
new file mode 100644
index 000000000..9c27d501e
--- /dev/null
+++ b/system/src/Grav/Console/BackupCommand.php
@@ -0,0 +1,88 @@
+setName("backup")
+ ->addArgument(
+ 'destination',
+ InputArgument::OPTIONAL,
+ 'Where to store the backup'
+
+ )
+ ->setDescription("Creates a backup of the Grav instance")
+ ->setHelp('The backup creates a zipped backup');
+
+
+ $this->source = getcwd();
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $output->getFormatter()->setStyle('red', new OutputFormatterStyle('red'));
+ $output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan'));
+ $output->getFormatter()->setStyle('green', new OutputFormatterStyle('green'));
+ $output->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta'));
+
+ $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();
+
+ $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('');
+
+ }
+
+ private static function folderToZip($folder, &$zipFile, $exclusiveLength, $progress) {
+ $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);
+ }
+ }
+ }
+ closedir($handle);
+ }
+}
+