X-Git-Url: http://source.bookstackapp.com/system-cli/blobdiff_plain/0632ad4355078352b430a395e69b10cd790d739a..3992a6b67871ea32c9a2e85fd8824bdd4f2bdeaa:/scripts/Commands/RestoreCommand.php
diff --git a/scripts/Commands/RestoreCommand.php b/scripts/Commands/RestoreCommand.php
index 1f83045..c181ff8 100644
--- a/scripts/Commands/RestoreCommand.php
+++ b/scripts/Commands/RestoreCommand.php
@@ -4,6 +4,9 @@ namespace Cli\Commands;
use Cli\Services\AppLocator;
use Cli\Services\ArtisanRunner;
+use Cli\Services\BackupZip;
+use Cli\Services\EnvironmentLoader;
+use Cli\Services\InteractiveConsole;
use Cli\Services\RequirementsValidator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
@@ -26,16 +29,52 @@ class RestoreCommand extends Command
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
+ $interactions = new InteractiveConsole($this->getHelper('question'), $input, $output);
+
+ $output->writeln("Warning!");
+ $output->writeln("- A restore operation will overwrite and remove files & content from an existing instance.");
+ $output->writeln("- Any existing tables within the configured database will be dropped.");
+ $output->writeln("- You should only restore into an instance of the same or newer BookStack version.");
+ $output->writeln("- This command won't handle, restore or address any server configuration.");
+
$appDir = AppLocator::require($input->getOption('app-directory'));
$output->writeln("Checking system requirements...");
RequirementsValidator::validate();
- // TODO - Warn that potentially dangerous,
- // warn for same/forward versions only,
- // warn this won't handle server-level stuff
+ $zipPath = realpath($input->getArgument('backup-zip'));
+ $zip = new BackupZip($zipPath);
+ $contents = $zip->getContentsOverview();
+
+ $output->writeln("\nContents found in the backup ZIP:");
+ $hasContent = false;
+ foreach ($contents as $info) {
+ $output->writeln(($info['exists'] ? 'â ' : 'â ') . $info['desc']);
+ if ($info['exists']) {
+ $hasContent = true;
+ }
+ }
+
+ if (!$hasContent) {
+ throw new CommandError("Provided ZIP backup [{$zipPath}] does not have any expected restore-able content.");
+ }
+
+ $output->writeln("The checked elements will be restored into [{$appDir}].");
+ $output->writeln("Existing content may be overwritten.");
+ $output->writeln("Do you want to continue?");
+
+ if (!$interactions->confirm("Do you want to continue?")) {
+ $output->writeln("Stopping restore operation.");
+ return Command::SUCCESS;
+ }
- // TODO - Validate provided backup zip contents
- // - Display and prompt to user
+ $output->writeln("Extracting ZIP into temporary directory...");
+ $extractDir = $appDir . DIRECTORY_SEPARATOR . 'restore-temp-' . time();
+ if (!mkdir($extractDir)) {
+ throw new CommandError("Could not create temporary extraction directory at [{$extractDir}].");
+ }
+ $zip->extractInto($extractDir);
+
+ // TODO - Cleanup temp extract dir
// TODO - Environment handling
// - Restore of old .env
@@ -60,4 +99,14 @@ class RestoreCommand extends Command
return Command::SUCCESS;
}
+
+ protected function restoreEnv(string $extractDir, string $appDir, InteractiveConsole $interactions)
+ {
+ $extractEnv = EnvironmentLoader::load($extractDir);
+ $appEnv = EnvironmentLoader::load($appDir); // TODO - Probably pass in since we'll need the APP_URL later on.
+
+ // TODO - Create mysql runner to take variables to a programrunner instance.
+ // Then test each, backup existing env, then replace env with old then overwrite
+ // db options if the new app env options are the valid ones.
+ }
}