Completed
Pull Request — master (#428)
by personal
02:44 queued 01:01
created

ConfigFileReaderJson   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 87
rs 10
c 0
b 0
f 0
wmc 12
lcom 1
cbo 1

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B read() 0 44 8
A collapseArray() 0 14 3
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