Security update for Core, with self-updated composer
[yaffs-website] / vendor / drupal / console / src / Command / Multisite / UpdateCommand.php
diff --git a/vendor/drupal/console/src/Command/Multisite/UpdateCommand.php b/vendor/drupal/console/src/Command/Multisite/UpdateCommand.php
new file mode 100644 (file)
index 0000000..44b4af0
--- /dev/null
@@ -0,0 +1,349 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\AppConsole\Command\Multisite\UpdateCommand.
+ */
+
+namespace Drupal\Console\Command\Multisite;
+
+use Drupal\Console\Core\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
+use Symfony\Component\Filesystem\Filesystem;
+
+/**
+ * Class UpdateCommand
+ *
+ * @package Drupal\Console\Command\Multisite
+ */
+class UpdateCommand extends Command
+{
+    protected $appRoot;
+
+    /**
+     * DebugCommand constructor.
+     *
+     * @param $appRoot
+     */
+    public function __construct($appRoot)
+    {
+        $this->appRoot = $appRoot;
+        parent::__construct();
+    }
+
+    /**
+     * @var Filesystem;
+     */
+    protected $fs;
+
+    /**
+     * @var string
+     */
+    protected $uri = '';
+
+    /**
+     * @var string
+     */
+    protected $directory = '';
+
+    /**
+     * @var array
+     */
+    protected $explodeUriDirectory = [];
+
+    /**
+     * @var array
+     */
+    protected $explodeDirectory = [];
+
+    /**
+     * {@inheritdoc}
+     */
+    public function configure()
+    {
+        $this->setName('multisite:update')
+            ->setDescription($this->trans('commands.multisite.update.description'))
+            ->setHelp($this->trans('commands.multisite.update.help'))
+            ->addOption(
+                'directory',
+                null,
+                InputOption::VALUE_REQUIRED,
+                $this->trans('commands.multisite.update.options.directory')
+            )
+            ->setAliases(['muu']);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function interact(InputInterface $input, OutputInterface $output)
+    {
+        $this->uri = parse_url($input->getParameterOption(['--uri', '-l'], 'default'), PHP_URL_HOST);
+
+        $sites = $this->getMultisite($this->uri);
+        if ($this->uri == "default") {
+            $this->uri = $this->getIo()->choice(
+                $this->trans('commands.multisite.update.questions.uri'),
+                $sites
+            );
+        } elseif (!array_key_exists($this->uri, $sites)) {
+            $this->getIo()->error(
+                $this->trans('commands.multisite.update.error.invalid-uri')
+            );
+
+            return 1;
+        }
+        $this->uri = $sites[$this->uri];
+
+        $directory = $input->getOption('directory');
+        if (!$directory) {
+            $directory = $this->getIo()->ask($this->trans('commands.multisite.update.questions.directory'));
+        }
+        $input->setOption('directory', $directory);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $this->fs = new Filesystem();
+
+        if (empty($this->uri)) {
+            $uri =  parse_url($input->getParameterOption(['--uri', '-l'], 'default'), PHP_URL_HOST);
+            $sites = $this->getMultisite($uri);
+            $this->uri = $sites[$uri];
+        }
+
+        $this->directory = $input->getOption('directory');
+        $this->explodeDirectory = explode('/', $this->directory);
+        $this->explodeUriDirectory = explode('/', $this->uri);
+
+        if (count($this->explodeDirectory) <= 2) {
+            try {
+                $multiSiteFile = sprintf(
+                    '%s/sites/sites.php',
+                    $this->appRoot
+                );
+                //Replace Multisite name in sites/sites.php
+                $string_to_replace="sites['".$this->explodeUriDirectory[0]."'] = '".$this->uri."';";
+                $replace_with="sites['".$this->explodeDirectory[0]."'] = '".$this->directory."';";
+                $content=file_get_contents($multiSiteFile);
+                $content_chunks=explode($string_to_replace, $content);
+                $content=implode($replace_with, $content_chunks);
+                file_put_contents($multiSiteFile, $content);
+            } catch (IOExceptionInterface $e) {
+                $this->getIo()->error(
+                    sprintf(
+                        $this->trans('commands.multisite.update.errors.write-fail'),
+                        $this->uri,
+                        $this->directory
+                    )
+                );
+                return 1;
+            }
+
+            //Directory == 1 folder
+            if (count($this->explodeDirectory) == 1) {
+                $this->recurse_copy(
+                    $this->appRoot.'/sites/'.$this->uri,
+                    $this->appRoot.'/sites/'.$this->directory
+                );
+
+                if ($this->explodeDirectory[0] != $this->explodeUriDirectory[0]
+                    && $this->fs->exists($this->appRoot.'/sites/'.$this->explodeUriDirectory[0].'/files')
+                ) {
+                    $this->fs->remove($this->appRoot.'/sites/'.$this->directory.'/files');
+
+                    $this->recurse_copy(
+                        $this->appRoot.'/sites/'.$this->explodeUriDirectory[0].'/files',
+                        $this->appRoot.'/sites/'.$this->directory.'/files'
+                    );
+                }
+
+                $this->fs->chmod($this->appRoot.'/sites/'.$this->uri, 0755);
+                $this->fs->remove($this->appRoot.'/sites/'.$this->uri);
+            } else {
+                //Directory == 2 folders && uri == 2 folders
+                if (count($this->explodeUriDirectory) != 1) {
+                    if (!$this->fs->exists($this->appRoot . '/sites/' . $this->directory)) {
+                        $this->fs->rename(
+                            $this->appRoot . '/sites/' . $this->uri,
+                            $this->appRoot . '/sites/' . $this->directory
+                        );
+                    }
+
+                    if (count(scandir($this->appRoot.'/sites/'.$this->explodeUriDirectory[0])) != 2) {
+                        $this->recurse_copy(
+                            $this->appRoot.'/sites/'.$this->explodeUriDirectory[0].'/files',
+                            $this->appRoot . '/sites/' . $this->explodeDirectory[0].'/files'
+                        );
+                    } else {
+                        $this->fs->remove($this->appRoot.'/sites/'.$this->explodeUriDirectory[0]);
+                    }
+                }
+                //Directory == 2 folders && uri == 1 folder
+                else {
+                    if (!$this->fs->exists($this->appRoot.'/sites/'.$this->directory)) {
+                        try {
+                            $this->fs->chmod($this->appRoot.'/sites/'.$this->uri, 0755);
+                            $this->fs->mkdir($this->appRoot.'/sites/'.$this->directory, 0755);
+
+                            if ($this->explodeUriDirectory[0] != $this->explodeDirectory[0]) {
+                                $this->recurse_copy(
+                                    $this->appRoot.'/sites/'.$this->uri,
+                                    $this->appRoot.'/sites/'.$this->explodeDirectory[0]
+                                );
+                                $this->fs->remove($this->appRoot.'/sites/'.$this->uri);
+                            }
+                        } catch (IOExceptionInterface $e) {
+                            $this->getIo()->error(
+                                sprintf(
+                                    $this->trans('commands.multisite.update.errors.mkdir-fail'),
+                                    $this->directory
+                                )
+                            );
+                        }
+                    }
+                    $this->moveSettings();
+                }
+            }
+
+            $this->editSettings();
+        } else {
+            $this->getIo()->error(
+                sprintf(
+                    $this->trans('commands.multisite.update.errors.invalid-new-dir'),
+                    $this->directory
+                )
+            );
+        }
+    }
+
+    /**
+     * Get all Multisites.
+     */
+    protected function getMultisite()
+    {
+        $sites = [];
+        $multiSiteFile = sprintf(
+            '%s/sites/sites.php',
+            $this->appRoot
+        );
+
+        if (file_exists($multiSiteFile)) {
+            include $multiSiteFile;
+        }
+
+        if (!$sites) {
+            $this->getIo()->error(
+                $this->trans('commands.debug.multisite.messages.no-multisites')
+            );
+
+            return 1;
+        }
+
+        return $sites;
+    }
+
+    /**
+     * Move the settings.php file to new directory.
+     */
+    protected function moveSettings()
+    {
+        try {
+            if (!$this->fs->exists($this->appRoot.'/sites/'.$this->directory.'/settings.php')) {
+                $this->fs->copy(
+                    $this->appRoot.'/sites/'.$this->uri.'/settings.php',
+                    $this->appRoot.'/sites/'.$this->directory.'/settings.php'
+                );
+                $this->fs->remove($this->appRoot.'/sites/'.$this->uri.'/settings.php');
+            }
+        } catch (IOExceptionInterface $e) {
+            $this->getIo()->error(
+                sprintf(
+                    $this->trans('commands.multisite.update.errors.copy-fail'),
+                    $this->appRoot.'/sites/'.$this->explodeDirectory[0].'/settings.php',
+                    $this->directory.'/settings.php'
+                )
+            );
+            return 1;
+        }
+    }
+
+    /**
+     * Edit the settings.php file to change the database parameters, because the settings.php file was moved.
+     */
+    protected function editSettings()
+    {
+        $multiSiteSettingsFile = sprintf(
+            '%s/sites/'.$this->explodeDirectory[0].'/settings.php',
+            $this->appRoot
+        );
+        if (!$this->fs->exists($multiSiteSettingsFile)) {
+            $multiSiteSettingsFile = sprintf(
+                '%s/sites/'.$this->directory.'/settings.php',
+                $this->appRoot
+            );
+        }
+
+        $databases = [];
+        $config_directories = [];
+
+        if (file_exists($multiSiteSettingsFile)) {
+            include $multiSiteSettingsFile;
+        }
+
+        try {
+            if (!empty($databases) || !empty($config_directories)) {
+                //Replace $databases['default']['default']['database']
+                $line = explode('/', $databases['default']['default']['database']);
+                $string_to_replace= $databases['default']['default']['database'];
+                $replace_with="sites/".$this->explodeDirectory[0]."/files/".end($line);
+                $content=file_get_contents($multiSiteSettingsFile);
+                $content_chunks=explode($string_to_replace, $content);
+                $content=implode($replace_with, $content_chunks);
+
+                //Replace $config_directories['sync']
+                $string_to_replace= $config_directories['sync'];
+                $replace_with=str_replace($this->uri, $this->directory, $config_directories['sync']);
+                $content_chunks=explode($string_to_replace, $content);
+                $content=implode($replace_with, $content_chunks);
+                file_put_contents($multiSiteSettingsFile, $content);
+            }
+        } catch (IOExceptionInterface $e) {
+            $this->getIo()->error(
+                sprintf(
+                    $this->trans('commands.multisite.update.messages.write-fail'),
+                    $multiSiteSettingsFile
+                )
+            );
+            return 1;
+        }
+    }
+
+    /**
+     * Custom function to recursively copy all file and folders in new destination
+     *
+     * @param $source
+     * @param $destination
+     */
+    public function recurse_copy($source, $destination)
+    {
+        $directory = opendir($source);
+        $this->fs->mkdir($destination, 0755);
+        while (false !== ($file = readdir($directory))) {
+            if (($file != '.') && ($file != '..')) {
+                if (is_dir($source . '/' . $file)) {
+                    $this->recurse_copy($source . '/' . $file, $destination . '/' . $file);
+                } else {
+                    $this->fs->copy($source . '/' . $file, $destination . '/' . $file);
+                }
+            }
+        }
+        closedir($directory);
+    }
+}