Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Testwork / ServiceContainer / Configuration / ConfigurationLoader.php
1 <?php
2
3 /*
4  * This file is part of the Behat Testwork.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\Testwork\ServiceContainer\Configuration;
12
13 use Behat\Testwork\ServiceContainer\Exception\ConfigurationLoadingException;
14 use Symfony\Component\Yaml\Yaml;
15
16 /**
17  * Loads configuration from different sources.
18  *
19  * @author Konstantin Kudryashov <ever.zet@gmail.com>
20  */
21 final class ConfigurationLoader
22 {
23     /**
24      * @var null|string
25      */
26     private $configurationPath;
27     /**
28      * @var null|string
29      */
30     private $environmentVariable;
31     /**
32      * @var Boolean
33      */
34     private $profileFound;
35     /**
36      * @var array
37      */
38     private $debugInformation = array(
39         'environment_variable_name' => 'none',
40         'environment_variable_content' => 'none',
41         'configuration_file_path' => 'none'
42     );
43
44     /**
45      * Constructs reader.
46      *
47      * @param string $environmentVariableName Environment variable name
48      * @param string $configurationPath       Configuration file path
49      */
50     public function __construct($environmentVariableName = null, $configurationPath = null)
51     {
52         $this->environmentVariable = $environmentVariableName;
53         $this->configurationPath = $configurationPath;
54     }
55
56     /**
57      * Sets environment variable name.
58      *
59      * @param null|string $variable
60      */
61     public function setEnvironmentVariableName($variable)
62     {
63         $this->environmentVariable = $variable;
64     }
65
66     /**
67      * Returns environment variable name.
68      *
69      * @return null|string
70      */
71     public function getEnvironmentVariableName()
72     {
73         return $this->environmentVariable;
74     }
75
76     /**
77      * Sets configuration file path.
78      *
79      * @param null|string $path
80      */
81     public function setConfigurationFilePath($path)
82     {
83         $this->configurationPath = $path;
84     }
85
86     /**
87      * Returns configuration file path.
88      *
89      * @return null|string
90      */
91     public function getConfigurationFilePath()
92     {
93         return $this->configurationPath;
94     }
95
96     /**
97      * Reads configuration sequence for specific profile.
98      *
99      * @param string $profile Profile name
100      *
101      * @return array
102      *
103      * @throws ConfigurationLoadingException
104      */
105     public function loadConfiguration($profile = 'default')
106     {
107         $configs = array();
108         $this->profileFound = false;
109
110         // first is ENV config
111         foreach ($this->loadEnvironmentConfiguration() as $config) {
112             $configs[] = $config;
113         }
114
115         // second is file configuration (if there is some)
116         if ($this->configurationPath) {
117             $this->debugInformation['configuration_file_path'] = $this->configurationPath;
118
119             foreach ($this->loadFileConfiguration($this->configurationPath, $profile) as $config) {
120                 $configs[] = $config;
121             }
122         }
123
124         // if specific profile has not been found
125         if ('default' !== $profile && !$this->profileFound) {
126             throw new ConfigurationLoadingException(sprintf(
127                 'Can not find configuration for `%s` profile.',
128                 $profile
129             ));
130         }
131
132         return $configs;
133     }
134
135     /**
136      * Returns array with configuration debug information.
137      *
138      * @return array
139      */
140     public function debugInformation()
141     {
142         return $this->debugInformation;
143     }
144
145     /**
146      * Loads information from environment variable.
147      *
148      * @return array
149      *
150      * @throws ConfigurationLoadingException If environment variable environment var is set to invalid JSON
151      */
152     protected function loadEnvironmentConfiguration()
153     {
154         $configs = array();
155
156         if (!$this->environmentVariable) {
157             return $configs;
158         }
159
160         $this->debugInformation['environment_variable_name'] = $this->environmentVariable;
161
162         if ($envConfig = getenv($this->environmentVariable)) {
163             $config = @json_decode($envConfig, true);
164
165             $this->debugInformation['environment_variable_content'] = $envConfig;
166
167             if (!$config) {
168                 throw new ConfigurationLoadingException(sprintf(
169                     'Environment variable `%s` should contain a valid JSON, but it is set to `%s`.',
170                     $this->environmentVariable,
171                     $envConfig
172                 ));
173             }
174
175             $configs[] = $config;
176         }
177
178         return $configs;
179     }
180
181     /**
182      * Loads information from YAML configuration file.
183      *
184      * @param string $configPath Config file path
185      * @param string $profile    Profile name
186      *
187      * @return array
188      *
189      * @throws ConfigurationLoadingException If config file is not found
190      */
191     protected function loadFileConfiguration($configPath, $profile)
192     {
193         if (!is_file($configPath) || !is_readable($configPath)) {
194             throw new ConfigurationLoadingException(sprintf('Configuration file `%s` not found.', $configPath));
195         }
196
197         $basePath = rtrim(dirname($configPath), DIRECTORY_SEPARATOR);
198         $config = (array) Yaml::parse(file_get_contents($configPath));
199
200         return $this->loadConfigs($basePath, $config, $profile);
201     }
202
203     /**
204      * Loads configs for provided config and profile.
205      *
206      * @param string $basePath
207      * @param array  $config
208      * @param string $profile
209      *
210      * @return array
211      */
212     private function loadConfigs($basePath, array $config, $profile)
213     {
214         $configs = array();
215
216         // first load default profile from current config, but only if custom profile requested
217         if ('default' !== $profile && isset($config['default'])) {
218             $configs[] = $config['default'];
219         }
220
221         // then recursively load profiles from imports
222         if (isset($config['imports']) && is_array($config['imports'])) {
223             $configs = array_merge($configs, $this->loadImports($basePath, $config['imports'], $profile));
224         }
225
226         // then load specific profile from current config
227         if (isset($config[$profile])) {
228             $configs[] = $config[$profile];
229             $this->profileFound = true;
230         }
231
232         return $configs;
233     }
234
235     /**
236      * Loads all provided imports.
237      *
238      * @param string $basePath
239      * @param array  $paths
240      * @param string $profile
241      *
242      * @return array
243      */
244     private function loadImports($basePath, array $paths, $profile)
245     {
246         $configs = array();
247         foreach ($paths as $path) {
248             foreach ($this->parseImport($basePath, $path, $profile) as $importConfig) {
249                 $configs[] = $importConfig;
250             }
251         }
252
253         return $configs;
254     }
255
256     /**
257      * Parses import.
258      *
259      * @param string $basePath
260      * @param string $path
261      * @param string $profile
262      *
263      * @return array
264      *
265      * @throws ConfigurationLoadingException If import file not found
266      */
267     private function parseImport($basePath, $path, $profile)
268     {
269         if (!file_exists($path) && file_exists($basePath . DIRECTORY_SEPARATOR . $path)) {
270             $path = $basePath . DIRECTORY_SEPARATOR . $path;
271         }
272
273         if (!file_exists($path)) {
274             throw new ConfigurationLoadingException(sprintf(
275                 'Can not import `%s` configuration file. File not found.',
276                 $path
277             ));
278         }
279
280         return $this->loadFileConfiguration($path, $profile);
281     }
282 }