Security update for Core, with self-updated composer
[yaffs-website] / vendor / drupal / console-core / src / Utils / ConfigurationManager.php
index abb2fe836db1164386091cffc6957ce816918002..da7f775a9c83e11b221986ca976b1f4a93f2a6e5 100644 (file)
@@ -7,6 +7,7 @@ use Symfony\Component\Console\Input\ArgvInput;
 use Symfony\Component\Finder\Finder;
 use Dflydev\DotAccessConfiguration\YamlFileConfigurationBuilder;
 use Dflydev\DotAccessConfiguration\ConfigurationInterface;
+use Webmozart\PathUtil\Path;
 
 /**
  * Class ConfigurationManager.
@@ -26,88 +27,65 @@ class ConfigurationManager
     /**
      * @var array
      */
-    private $missingConfigurationFiles = [];
+    private $configurationDirectories = [];
 
     /**
      * @var array
      */
-    private $configurationDirectories = [];
+    private $sites = [];
 
     /**
      * @var array
      */
-    private $sites = [];
+    private $configurationFiles = [];
 
     /**
-     * @param $applicationDirectory
+     * @param $directory
      * @return $this
      */
-    public function loadConfiguration($applicationDirectory)
+    public function loadConfiguration($directory)
     {
-        $homeConfig = $this->getHomeDirectory() . '/.console/';
-        if (!is_dir($homeConfig)) {
-            mkdir($homeConfig, 0777);
-        }
+        $this->locateConfigurationFiles();
 
-        $this->applicationDirectory = $applicationDirectory;
-        $input = new ArgvInput();
-        $root = $input->getParameterOption(['--root'], null);
-
-        $configurationDirectories[] = $applicationDirectory;
-        $configurationDirectories[] = $applicationDirectory.DRUPAL_CONSOLE_CORE;
-        $configurationDirectories[] = $applicationDirectory.DRUPAL_CONSOLE;
-        $configurationDirectories[] = '/etc/console/';
-        $configurationDirectories[] = $this->getHomeDirectory() . '/.console/';
-        $configurationDirectories[] = $applicationDirectory .'/console/';
-        if ($root) {
-            $configurationDirectories[] = $root . '/console/';
+        $this->applicationDirectory = $directory;
+        if ($directory && is_dir($directory) && strpos($directory, 'phar:')!==0) {
+            $this->addConfigurationFilesByDirectory(
+                $directory . '/console/',
+                true
+            );
         }
-        $configurationDirectories = array_unique($configurationDirectories);
-
-        $configurationFiles = [];
-        foreach ($configurationDirectories as $configurationDirectory) {
-            $file =  $configurationDirectory . 'config.yml';
-
-            if (stripos($configurationDirectory, '/vendor/') <= 0
-                && stripos($configurationDirectory, '/bin/') <= 0
-                && stripos($configurationDirectory, 'console/') > 0
-            ) {
-                $this->configurationDirectories[] = str_replace('//', '/', $configurationDirectory);
-            }
-
-            if (!file_exists($file)) {
-                $this->missingConfigurationFiles[] = $file;
-                continue;
-            }
-            if (file_get_contents($file)==='') {
-                $this->missingConfigurationFiles[] = $file;
-                continue;
-            }
-
-            $configurationFiles[] = $file;
+        $input = new ArgvInput();
+        $root = $input->getParameterOption(['--root']);
+        if ($root && is_dir($root)) {
+            $this->addConfigurationFilesByDirectory(
+                $root. '/console/',
+                true
+            );
         }
 
-        $this->configurationDirectories =
-            array_unique($this->configurationDirectories);
+        $builder = new YamlFileConfigurationBuilder(
+            $this->configurationFiles['config']
+        );
 
-        $builder = new YamlFileConfigurationBuilder($configurationFiles);
         $this->configuration = $builder->build();
-        $this->appendCommandAliases();
 
-        if ($configurationFiles) {
-            $this->missingConfigurationFiles = [];
+        $extras = [
+            'aliases',
+            'mappings',
+            'defaults'
+        ];
+
+        foreach ($extras as $extra) {
+            $extraKey = 'application.extras.'.$extra;
+            $extraFlag = $this->configuration->get($extraKey)?:'true';
+            if ($extraFlag === 'true') {
+                $this->appendExtraConfiguration($extra);
+            }
         }
 
         return $this;
     }
 
-    public function loadConfigurationFromDirectory($directory)
-    {
-        $builder = new YamlFileConfigurationBuilder([$directory.'/console/config.yml']);
-
-        return $builder->build();
-    }
-
     /**
      * @return ConfigurationInterface
      */
@@ -116,7 +94,7 @@ class ConfigurationManager
         return $this->configuration;
     }
 
-    public function readSite($siteFile)
+    private function readSite($siteFile)
     {
         if (!file_exists($siteFile)) {
             return [];
@@ -132,34 +110,31 @@ class ConfigurationManager
      */
     public function readTarget($target)
     {
-        if (!array_key_exists($target, $this->sites)) {
-            return [];
-        }
+        $site = $target;
+        $environment = null;
+        $exploded = explode('.', $target, 2);
 
-        $targetInformation = $this->sites[$target];
+        if (count($exploded)>1) {
+            $site = $exploded[0];
+            $environment = $exploded[1];
+        }
 
-        if (array_key_exists('host', $targetInformation) && $targetInformation['host'] != 'local') {
-            $targetInformation['remote'] = true;
+        $sites = $this->getSites();
+        if (!array_key_exists($site, $sites)) {
+            return [];
         }
 
-        return array_merge(
-            $this->configuration->get('application.remote'),
-            $targetInformation
-        );
-    }
+        $targetInformation = $sites[$site];
 
-    /**
-     * Return the user home directory.
-     *
-     * @return string
-     */
-    public function getHomeDirectory()
-    {
-        if (function_exists('posix_getuid')) {
-            return posix_getpwuid(posix_getuid())['dir'];
+        if ($environment) {
+            if (!array_key_exists($environment, $sites[$site])) {
+                return [];
+            }
+
+            $targetInformation = $sites[$site][$environment];
         }
 
-        return realpath(rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '/\\'));
+        return $targetInformation;
     }
 
     /**
@@ -177,25 +152,23 @@ class ConfigurationManager
      */
     private function getSitesDirectories()
     {
-        $configurationDirectories = $this->getConfigurationDirectories();
-        $configurationDirectories = array_map(
+        $sitesDirectories = array_map(
             function ($directory) {
-                return sprintf(
-                    '%s/sites',
-                    $directory
-                );
+                return $directory . 'sites';
             },
-            $configurationDirectories
+            $this->getConfigurationDirectories()
         );
 
-        $configurationDirectories = array_filter(
-            $configurationDirectories,
+        $sitesDirectories = array_filter(
+            $sitesDirectories,
             function ($directory) {
                 return is_dir($directory);
             }
         );
 
-        return $configurationDirectories;
+        $sitesDirectories = array_unique($sitesDirectories);
+
+        return $sitesDirectories;
     }
 
     /**
@@ -205,25 +178,27 @@ class ConfigurationManager
     public function readDrushEquivalents($commandName)
     {
         $equivalents = [];
-        $aliasInformation = Yaml::parse(
+        $drushMappings = Yaml::parse(
             file_get_contents(
-                $this->applicationDirectory.DRUPAL_CONSOLE_CORE.'config/drush.yml'
+                $this->applicationDirectory . DRUPAL_CONSOLE_CORE . 'config/drush.yml'
             )
         );
 
-        foreach ($aliasInformation['commands'] as $key => $commands) {
-            foreach ($commands as $drush => $console) {
-                $equivalents[$drush] = $console;
+        foreach ($drushMappings['commands'] as $key => $commands) {
+            foreach ($commands as $namespace => $command) {
+                if ($command) {
+                    $equivalents[$namespace] = $command;
+                }
             }
         }
 
         if (!$commandName) {
-            $aliasInformation = [];
+            $drushMappings = [];
             foreach ($equivalents as $key => $alternative) {
-                $aliasInformation[] = [$key, $alternative];
+                $drushMappings[] = [$key, $alternative];
             }
 
-            return $aliasInformation;
+            return $drushMappings;
         }
 
         if (array_key_exists($commandName, $equivalents)) {
@@ -233,60 +208,158 @@ class ConfigurationManager
         return [];
     }
 
+    public function getVendorCoreRoot()
+    {
+        $consoleCoreDirectory = dirname(dirname(dirname(__FILE__))) . '/';
+
+        if (is_dir($consoleCoreDirectory)) {
+            return $consoleCoreDirectory;
+        }
+
+        return null;
+    }
+
+    public function getVendorCoreDirectory()
+    {
+        $consoleCoreDirectory = dirname(dirname(dirname(__FILE__))) . '/config/';
+
+        if (is_dir($consoleCoreDirectory)) {
+            return $consoleCoreDirectory;
+        }
+
+        return null;
+    }
+
+    public function getSystemDirectory()
+    {
+        $systemDirectory = '/etc/console/';
+
+        if (is_dir($systemDirectory)) {
+            return $systemDirectory;
+        }
+
+        return null;
+    }
+
     /**
      * @return string
      */
     public function getConsoleDirectory()
     {
-        return sprintf('%s/.console/', $this->getHomeDirectory());
+        $consoleDirectory = sprintf(
+            '%s/.console/',
+            $this->getHomeDirectory()
+        );
+
+        if (is_dir($consoleDirectory)) {
+            return $consoleDirectory;
+        }
+
+        try {
+            mkdir($consoleDirectory, 0777, true);
+        } catch (\Exception $exception) {
+            return null;
+        }
+
+        return $consoleDirectory;
     }
 
     /**
+     * @param $includeVendorCore
+     *
      * @return array
      */
-    public function getMissingConfigurationFiles()
+    public function getConfigurationDirectories($includeVendorCore = false)
     {
-        return $this->missingConfigurationFiles;
+        if ($this->configurationDirectories) {
+            if ($includeVendorCore) {
+                return array_merge(
+                    [$this->getVendorCoreDirectory()],
+                    $this->configurationDirectories
+                );
+            }
+
+            return $this->configurationDirectories;
+        }
+
+        return [];
     }
 
-    /**
-     * @return array
-     */
-    public function getConfigurationDirectories()
+    private function addConfigurationFilesByDirectory(
+        $directory,
+        $addDirectory = false
+    ) {
+        if ($addDirectory) {
+            $this->configurationDirectories[] = $directory;
+        }
+        $configurationFiles = [
+            'config' => 'config.yml',
+            'drush' => 'drush.yml',
+            'aliases' => 'aliases.yml',
+            'mappings' => 'mappings.yml',
+            'defaults' => 'defaults.yml',
+        ];
+        foreach ($configurationFiles as $key => $file) {
+            $configFile = $directory.$file;
+            if (is_file($configFile)) {
+                $this->configurationFiles[$key][] = $configFile;
+            }
+        }
+    }
+
+    private function locateConfigurationFiles()
     {
-        return $this->configurationDirectories;
+        if ($this->getVendorCoreDirectory()) {
+            $this->addConfigurationFilesByDirectory(
+                $this->getVendorCoreDirectory()
+            );
+        }
+        if ($this->getSystemDirectory()) {
+            $this->addConfigurationFilesByDirectory(
+                $this->getSystemDirectory(),
+                true
+            );
+        }
+        if ($this->getConsoleDirectory()) {
+            $this->addConfigurationFilesByDirectory(
+                $this->getConsoleDirectory(),
+                true
+            );
+        }
     }
 
     /**
-     * @return string
+     * @return void
      */
-    public function appendCommandAliases()
+    private function appendExtraConfiguration($type)
     {
-        $configurationDirectories = array_merge(
-            [$this->applicationDirectory . DRUPAL_CONSOLE_CORE . 'config/dist/'],
-            $this->configurationDirectories
-        );
-        $aliases = [];
-        foreach ($configurationDirectories as $directory) {
-            $aliasFile = $directory . 'aliases.yml';
-            if (file_exists($aliasFile)) {
-                $aliases = array_merge(
-                    $aliases,
-                    Yaml::parse(file_get_contents($aliasFile))
-                );
+        if (!array_key_exists($type, $this->configurationFiles)) {
+            return;
+        }
+
+        $configData = [];
+        foreach ($this->configurationFiles[$type] as $configFile) {
+            if (file_get_contents($configFile)==='') {
+                continue;
             }
+            $parsed = Yaml::parse(file_get_contents($configFile));
+            $configData = array_merge(
+                $configData,
+                is_array($parsed)?$parsed:[]
+            );
         }
-        if (array_key_exists('commands', $aliases) && array_key_exists('aliases', $aliases['commands'])) {
+
+        if ($configData && array_key_exists($type, $configData)) {
             $this->configuration->set(
-                'application.commands.aliases',
-                $aliases['commands']['aliases']
+                'application.commands.'.$type,
+                $configData[$type]
             );
         }
     }
 
     public function loadExtendConfiguration()
     {
-        $directory = $this->getHomeDirectory() . '/.console/extend/';
+        $directory = $this->getConsoleDirectory() . '/extend/';
         if (!is_dir($directory)) {
             return null;
         }
@@ -296,16 +369,20 @@ class ConfigurationManager
             return null;
         }
         include_once $autoloadFile;
-        $extendFile= $directory . 'extend.console.config.yml';
+        $extendFile = $directory . 'extend.console.config.yml';
 
-        $this->importConfigurationFile($extendFile);
+        $this->importConfigurationFromFile($extendFile);
     }
 
-    public function importConfigurationFile($configFile)
+    private function importConfigurationFromFile($configFile)
     {
         if (is_file($configFile) && file_get_contents($configFile)!='') {
             $builder = new YamlFileConfigurationBuilder([$configFile]);
-            $this->configuration->import($builder->build());
+            if ($this->configuration) {
+                $this->configuration->import($builder->build());
+            } else {
+                $this->configuration = $builder->build();
+            }
         }
     }
 
@@ -319,6 +396,11 @@ class ConfigurationManager
         }
 
         $sitesDirectories = $this->getSitesDirectories();
+
+        if (!$sitesDirectories) {
+            return [];
+        }
+
         $finder = new Finder();
         $finder->in($sitesDirectories);
         $finder->name("*.yml");
@@ -331,12 +413,42 @@ class ConfigurationManager
                 continue;
             }
 
+            $this->sites[$siteName] = [
+                'file' => $site->getRealPath()
+            ];
+
             foreach ($environments as $environment => $config) {
-                $site = $siteName . '.' . $environment;
-                $this->sites[$site] = $config;
+                if (!array_key_exists('type', $config)) {
+                    throw new \UnexpectedValueException("The 'type' parameter is required in sites configuration.");
+                }
+                if ($config['type'] !== 'local') {
+                    if (array_key_exists('host', $config)) {
+                        $targetInformation['remote'] = true;
+                    }
+
+                    $config = array_merge(
+                        $this->configuration->get('application.remote')?:[],
+                        $config
+                    );
+                }
+
+                $this->sites[$siteName][$environment] = $config;
             }
         }
 
         return $this->sites;
     }
+
+    /**
+     * @return array
+     */
+    public function getConfigurationFiles()
+    {
+        return $this->configurationFiles;
+    }
+
+    public function getHomeDirectory()
+    {
+        return Path::getHomeDirectory();
+    }
 }