Model::getCacheFileData()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 5.4042

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 14
ccs 5
cts 9
cp 0.5556
rs 9.2
cc 4
eloc 9
nc 4
nop 0
crap 5.4042
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
Coding Style Comprehensibility introduced by
$config was never initialized. Although not strictly required by PHP, it is generally a good practice to add $config = array(); before regardless.

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:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key 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.

Loading history...
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
Bug introduced by
The call to set() misses a required argument $expire.

This check looks for function calls that miss required arguments.

Loading history...
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