Completed
Push — master ( b13fbb...147fe9 )
by Ryan
03:17
created

Model::build()   D

Complexity

Conditions 9
Paths 4

Size

Total Lines 33
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 9.1796

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 33
ccs 20
cts 23
cp 0.8696
rs 4.909
cc 9
eloc 22
nc 4
nop 0
crap 9.1796
1
<?php
2
/**
3
 * Opine\Config\Model
4
 *
5
 * Copyright (c)2013, 2014 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 2
    public function __construct(string $root, CacheInterface $cache)
42
    {
43 2
        $this->root = $root;
44 2
        $this->cache = $cache;
45 2
        $this->cacheFile = $this->root.'/../var/cache/config.json';
46 2
        $this->cacheFolder = $this->root.'/../var/cache';
47
48
        // set environment
49 2
        $this->environment = 'default';
50 2
        $test = getenv('OPINE_ENV');
51 2
        if ($test !== false) {
52 1
            $this->environment = $test;
53
        }
54
55
        // set environment
56 2
        $this->projectName = 'project';
57 2
        $test = getenv('OPINE_PROJECT');
58 2
        if ($test !== false) {
59
            $this->projectName = $test;
60
        }
61
62 2
        $this->cachePrefix = $this->projectName . $this->environment;
63 2
    }
64
65 2
    public function getCacheFileData()
66
    {
67 2
        if (!file_exists($this->cacheFile)) {
68
            return [];
69
        }
70 2
        $config = (array) json_decode(file_get_contents($this->cacheFile), true);
71 2
        if (isset($config[$this->environment])) {
72 2
            return $config[$this->environment];
73
        } elseif (isset($config['default'])) {
74
            return $config['default'];
75
        }
76
77
        return [];
78
    }
79
80 2
    public function build()
81
    {
82 2
        $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...
83 2
        $environments = glob($this->root.'/../config/settings/*', GLOB_ONLYDIR);
84 2
        if ($environments != false) {
85 2
            foreach ($environments as $directory) {
86 2
                $env = explode('/', $directory);
87 2
                $env = array_pop($env);
88 2
                if (in_array($env, ['layouts', 'managers', 'collections', 'forms'])) {
89
                    continue;
90
                }
91 2
                $config[$env] = $this->processFolder($directory);
92 2
                foreach ($config[$env] as $configName => $value) {
93 2
                    if (!isset($config['default'][$configName])) {
94
                        continue;
95
                    }
96 2
                    $config[$env][$configName] = array_merge($config['default'][$configName], $config[$env][$configName]);
97
                }
98 2
                foreach ($config['default'] as $configName => $value) {
99 2
                    if (isset($config[$env][$configName])) {
100 2
                        continue;
101
                    }
102 2
                    $config[$env][$configName] = $value;
103
                }
104
            }
105
        }
106
107 2
        $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...
108 2
        if (!file_exists($this->cacheFolder)) {
109
            mkdir($this->cacheFolder, 0777, true);
110
        }
111 2
        file_put_contents($this->cacheFile, json_encode($config, JSON_PRETTY_PRINT));
112 2
    }
113
114 2
    private function processFolder($folder)
115
    {
116 2
        $files = glob($folder.'/*.yml');
117 2
        if ($files === false) {
118
            return [];
119
        }
120 2
        $data = [];
121 2
        foreach ($files as $configFile) {
122 2
            $configName = basename($configFile, '.yml');
123 2
            $config = $this->yaml($configFile);
124 2
            if ($config === false) {
125
                throw new Exception('error in YAML file: '.$configFile);
126
            }
127 2
            if (!isset($config['settings'])) {
128
                throw new Exception('all config files must be under the settings key: '.$configFile);
129
            }
130 2
            $data[$configName] = $config['settings'];
131
        }
132
133 2
        return $data;
134
    }
135
136 2
    private function yaml($configFile)
137
    {
138 2
        return Yaml::parse(file_get_contents($configFile));
139
    }
140
}
141