Completed
Pull Request — master (#428)
by personal
01:57
created

ConfigFileReaderJson::read()   B

Complexity

Conditions 8
Paths 18

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 18
nop 1
dl 0
loc 44
rs 7.9715
c 0
b 0
f 0
1
<?php
2
3
namespace Hal\Application\Config\File;
4
5
use Hal\Application\Config\Config;
6
use RecursiveArrayIterator;
7
use RecursiveIteratorIterator;
8
9
class ConfigFileReaderJson implements ConfigFileReaderInterface
10
{
11
    /**
12
     * @var string
13
     */
14
    private $filename;
15
16
    /**
17
     * @param string $filename
18
     */
19
    public function __construct($filename)
20
    {
21
        $this->filename = $filename;
22
    }
23
24
    /**
25
     * @param Config $config
26
     *
27
     * @return void
28
     */
29
    public function read(Config $config)
30
    {
31
        $jsonText = file_get_contents($this->filename);
32
33
        if (false === $jsonText) {
34
            throw new \InvalidArgumentException("Cannot read configuration file '{$this->filename}'");
35
        }
36
37
        $jsonData = json_decode($jsonText, true);
38
39
        if (false === $jsonData) {
40
            throw new \InvalidArgumentException("Bad json file '{$this->filename}'");
41
        }
42
43
        if (isset($jsonData['includes'])) {
44
            $includes = $jsonData['includes'];
45
            $files = [];
46
            // with config file, includes are relative to config file
47
            foreach ($includes as $include) {
48
                $files[] = dirname($this->filename) . DIRECTORY_SEPARATOR . $include;
49
            }
50
            $config->set('files', $files);
51
            unset($jsonData['includes']);
52
        }
53
54
        if (isset($jsonData['groups'])) {
55
            $config->set('groups', $jsonData['groups']);
56
            unset($jsonData['groups']);
57
        }
58
59
        if (isset($jsonData['excludes'])) {
60
            // retro-compatibility
61
            // "exclude" is a string
62
            // excludes is an array
63
            $config->set('exclude', $jsonData['excludes']);
64
            unset($jsonData['excludes']);
65
        }
66
67
        $jsonDataImploded = $this->collapseArray($jsonData);
68
69
        foreach ($jsonDataImploded as $key => $value) {
70
            $config->set($key, $value);
71
        }
72
    }
73
74
    /**
75
     * Collapses array into a one-dimensional one by imploding nested keys with '-'
76
     *
77
     * @param array $arr
78
     *
79
     * @return array
80
     */
81
    private function collapseArray(array $arr)
82
    {
83
        $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
84
        $result = [];
85
        foreach ($iterator as $leafValue) {
86
            $keys = [];
87
            foreach (range(0, $iterator->getDepth()) as $depth) {
88
                $keys[] = $iterator->getSubIterator($depth)->key();
89
            }
90
            $result[implode('-', $keys)] = $leafValue;
91
        }
92
93
        return $result;
94
    }
95
}
96