Opine-Org /
Config
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Opine\Config\Model |
||
| 4 | * |
||
| 5 | * Copyright (c)2013, 2014, 2015, 2016, 2017 Ryan Mahoney, https://github.com/Opine-Org <[email protected]> |
||
| 6 | * |
||
| 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
||
| 8 | * of this software and associated documentation files (the "Software"), to deal |
||
| 9 | * in the Software without restriction, including without limitation the rights |
||
| 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||
| 11 | * copies of the Software, and to permit persons to whom the Software is |
||
| 12 | * furnished to do so, subject to the following conditions: |
||
| 13 | * |
||
| 14 | * The above copyright notice and this permission notice shall be included in |
||
| 15 | * all copies or substantial portions of the Software. |
||
| 16 | * |
||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
| 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
| 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||
| 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
| 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||
| 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||
| 23 | * THE SOFTWARE. |
||
| 24 | */ |
||
| 25 | namespace Opine\Config; |
||
| 26 | |||
| 27 | use Exception; |
||
| 28 | use Opine\Interfaces\Cache as CacheInterface; |
||
| 29 | use Symfony\Component\Yaml\Yaml; |
||
| 30 | |||
| 31 | class Model |
||
| 32 | { |
||
| 33 | private $root; |
||
| 34 | private $cache; |
||
| 35 | private $cacheFile; |
||
| 36 | private $cacheFolder; |
||
| 37 | private $environment; |
||
| 38 | private $projectName; |
||
| 39 | private $cachePrefix; |
||
| 40 | |||
| 41 | 3 | public function __construct(string $root, CacheInterface $cache) |
|
| 42 | { |
||
| 43 | 3 | $this->root = $root; |
|
| 44 | 3 | $this->cache = $cache; |
|
| 45 | 3 | $this->cacheFile = $this->root.'/../var/cache/config.json'; |
|
| 46 | 3 | $this->cacheFolder = $this->root.'/../var/cache'; |
|
| 47 | |||
| 48 | // set environment |
||
| 49 | 3 | $this->environment = 'default'; |
|
| 50 | 3 | $test = getenv('OPINE_ENV'); |
|
| 51 | 3 | if ($test !== false) { |
|
| 52 | 2 | $this->environment = $test; |
|
| 53 | } |
||
| 54 | |||
| 55 | // set environment |
||
| 56 | 3 | $this->projectName = 'project'; |
|
| 57 | 3 | $test = getenv('OPINE_PROJECT'); |
|
| 58 | 3 | if ($test !== false) { |
|
| 59 | $this->projectName = $test; |
||
| 60 | } |
||
| 61 | |||
| 62 | 3 | $this->cachePrefix = $this->projectName . $this->environment; |
|
| 63 | 3 | } |
|
| 64 | |||
| 65 | 3 | public function getCacheFileData() |
|
| 66 | { |
||
| 67 | 3 | if (!file_exists($this->cacheFile)) { |
|
| 68 | return []; |
||
| 69 | } |
||
| 70 | 3 | $config = (array) json_decode(file_get_contents($this->cacheFile), true); |
|
| 71 | 3 | if (isset($config[$this->environment])) { |
|
| 72 | 3 | return $config[$this->environment]; |
|
| 73 | } elseif (isset($config['default'])) { |
||
| 74 | return $config['default']; |
||
| 75 | } |
||
| 76 | |||
| 77 | return []; |
||
| 78 | } |
||
| 79 | |||
| 80 | 3 | public function build() |
|
| 81 | { |
||
| 82 | // establish the default folder |
||
| 83 | 3 | $config['default'] = $this->processFolder($this->root.'/../config/settings'); |
|
|
0 ignored issues
–
show
|
|||
| 84 | |||
| 85 | // environments are represented by sub-folders with one level of depth |
||
| 86 | 3 | $environments = glob($this->root.'/../config/settings/*', GLOB_ONLYDIR) ?: []; |
|
| 87 | |||
| 88 | // loop through each environment |
||
| 89 | 3 | foreach ($environments as $directory) { |
|
| 90 | // the environment name is the last piece of each path |
||
| 91 | 3 | $env = explode('/', $directory); |
|
| 92 | 3 | $env = array_pop($env); |
|
| 93 | |||
| 94 | // process the sub-folder |
||
| 95 | 3 | $config[$env] = $this->processFolder($directory); |
|
| 96 | |||
| 97 | // merge the values with the default values for each config |
||
| 98 | 3 | foreach ($config[$env] as $configName => $value) { |
|
| 99 | 3 | if (!isset($config['default'][$configName])) { |
|
| 100 | continue; |
||
| 101 | } |
||
| 102 | 3 | $config[$env][$configName] = array_merge($config['default'][$configName], $config[$env][$configName]); |
|
| 103 | } |
||
| 104 | |||
| 105 | // if the default has any configurations not in the environment, add those too |
||
| 106 | 3 | foreach ($config['default'] as $configName => $value) { |
|
| 107 | 3 | if (isset($config[$env][$configName])) { |
|
| 108 | 3 | continue; |
|
| 109 | } |
||
| 110 | 3 | $config[$env][$configName] = $value; |
|
| 111 | } |
||
| 112 | } |
||
| 113 | |||
| 114 | // if the current environment is not present, derive it from the default |
||
| 115 | 3 | if (!isset($config[$this->environment])) { |
|
| 116 | $config[$this->environment] = $config['default']; |
||
| 117 | } |
||
| 118 | |||
| 119 | // cache this information for future reference |
||
| 120 | 3 | $this->cache->set($this->cachePrefix.'-config', json_encode($config)); |
|
|
0 ignored issues
–
show
|
|||
| 121 | 3 | if (!file_exists($this->cacheFolder)) { |
|
| 122 | mkdir($this->cacheFolder, 0777, true); |
||
| 123 | } |
||
| 124 | 3 | file_put_contents($this->cacheFile, json_encode($config, JSON_PRETTY_PRINT)); |
|
| 125 | 3 | } |
|
| 126 | |||
| 127 | 3 | private function processFolder($folder) |
|
| 128 | { |
||
| 129 | 3 | $files = glob($folder.'/*.yml'); |
|
| 130 | 3 | if ($files === false) { |
|
| 131 | return []; |
||
| 132 | } |
||
| 133 | 3 | $data = []; |
|
| 134 | 3 | foreach ($files as $configFile) { |
|
| 135 | 3 | $configName = basename($configFile, '.yml'); |
|
| 136 | 3 | $config = $this->yaml($configFile); |
|
| 137 | 3 | if ($config === false) { |
|
| 138 | throw new Exception('error in YAML file: '.$configFile); |
||
| 139 | } |
||
| 140 | 3 | if (!isset($config['settings'])) { |
|
| 141 | throw new Exception('all config files must be under the top level settings key: '.$configFile); |
||
| 142 | } |
||
| 143 | 3 | $data[$configName] = $config['settings']; |
|
| 144 | } |
||
| 145 | |||
| 146 | 3 | return $data; |
|
| 147 | } |
||
| 148 | |||
| 149 | 3 | private function yaml($configFile) |
|
| 150 | { |
||
| 151 | 3 | return Yaml::parse(file_get_contents($configFile)); |
|
| 152 | } |
||
| 153 | } |
||
| 154 |
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.
Let’s take a look at an example:
As you can see in this example, the array
$myArrayis initialized the first time when the foreach loop is entered. You can also see that the value of thebarkey is only written conditionally; thus, its value might result from a previous iteration.This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.