diff --git a/README.md b/README.md index 370d8ff..1330674 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ This should print the Kirby CLI version and a list of available commands ## Available core commands ``` +- kirby backup - kirby clean:content - kirby clear:cache - kirby clear:lock diff --git a/commands/backup.php b/commands/backup.php new file mode 100644 index 0000000..409cd0a --- /dev/null +++ b/commands/backup.php @@ -0,0 +1,81 @@ + 'Creates backup of application files', + 'args' => [ + 'root' => [ + 'description' => 'Selects the kirby root, which should be backuped' + ] + ], + 'command' => static function (CLI $cli): void { + if (class_exists('ZipArchive') === false) { + throw new Exception('ZipArchive library could not be found'); + } + + $root = $cli->argOrPrompt( + 'root', + 'Which root should be backuped? (press to backup your entire site)', + false + ); + + $root = empty($root) === true ? 'index' : $root; + $rootPath = $cli->kirby()->root($root); + + if ($rootPath === null) { + throw new Exception('Invalid root entered: ' . $root); + } + + if (is_dir($rootPath) === false) { + throw new Exception('The root does not exist: ' . $root); + } + + $kirbyPath = $cli->kirby()->root('index'); + $backupPath = $kirbyPath . '/backup'; + $backupFile = $backupPath . '/' . $root . '-' . date('Y-m-d-His') . '.zip'; + + if (is_file($backupFile) === true) { + throw new Exception('The backup file exists'); + } + + // create backup directory before the process + Dir::make($backupPath); + + $zip = new ZipArchive(); + if ($zip->open($backupFile, ZipArchive::CREATE) !== true) { + throw new Exception('Failed to create backup file'); + } + + $files = new RecursiveIteratorIterator( + new RecursiveCallbackFilterIterator( + new RecursiveDirectoryIterator( + $rootPath, + FilesystemIterator::SKIP_DOTS + ), + fn ($file) => $file->isFile() || in_array($file->getBaseName(), ['.git', 'backup']) === false + ) + ); + + foreach ($files as $file) { + // skip directories, will be added automatically + if ($file->isDir() === false) { + // get real and relative path for current file + $filePath = $file->getRealPath(); + $relativePath = substr($filePath, strlen($rootPath) + 1); + + // add current file to archive + $zip->addFile($filePath, $relativePath); + } + } + + if ($zip->close() === false) { + throw new Exception('There was a problem writing the backup file'); + } + + $cli->success('The backup has been created: ' . substr($backupFile, strlen($kirbyPath))); + } +];