]> BookStack Code Mirror - system-cli/blobdiff - scripts/Commands/RestoreCommand.php
Progressed restore command a little
[system-cli] / scripts / Commands / RestoreCommand.php
index 1f830455ed8dc84c90832d2dfd17787d404b3126..c181ff84eb40c259812e9751a312d282a044e6e8 100644 (file)
@@ -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("<info>Warning!</info>");
+        $output->writeln("<info>- A restore operation will overwrite and remove files & content from an existing instance.</info>");
+        $output->writeln("<info>- Any existing tables within the configured database will be dropped.</info>");
+        $output->writeln("<info>- You should only restore into an instance of the same or newer BookStack version.</info>");
+        $output->writeln("<info>- This command won't handle, restore or address any server configuration.</info>");
+
         $appDir = AppLocator::require($input->getOption('app-directory'));
         $output->writeln("<info>Checking system requirements...</info>");
         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("\n<info>Contents found in the backup ZIP:</info>");
+        $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("<info>The checked elements will be restored into [{$appDir}].</info>");
+        $output->writeln("<info>Existing content may be overwritten.</info>");
+        $output->writeln("<info>Do you want to continue?</info>");
+
+        if (!$interactions->confirm("Do you want to continue?")) {
+            $output->writeln("<info>Stopping restore operation.</info>");
+            return Command::SUCCESS;
+        }
 
-        // TODO - Validate provided backup zip contents
-        //  - Display and prompt to user
+        $output->writeln("<info>Extracting ZIP into temporary directory...</info>");
+        $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.
+    }
 }