Passed
Push — master ( e5557f...240052 )
by Bruno
09:50
created

Options::mergeArrays()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 4
eloc 10
nc 4
nop 2
dl 0
loc 16
ccs 0
cts 0
cp 0
crap 20
rs 9.9332
c 1
b 1
f 0
1
<?php declare(strict_types=1);
2
3
namespace Modelarium;
4
5
use ArrayAccess;
6
7
use function Safe\file_get_contents;
8
use function Safe\getcwd;
9
use function Safe\json_decode;
10
use function Safe\substr;
11
12
class Options
13
{
14
    /**
15
     * @var string
16
     */
17
    public $basePath = null;
18
19
    /**
20
     *
21
     * @var array
22
     */
23
    public $options = [];
24
25
    public function __construct(string $basePath = null)
26
    {
27
        $this->basePath = $basePath;
28
        $this->options = $this->loadOptions();
29
    }
30
31
    /**
32
     * Gets a value
33
     *
34
     * @param string $section
35
     * @param string $key
36
     * @param mixed $default
37
     * @return mixed
38
     */
39
    public function getOption(string $section, string $key, $default = null)
40
    {
41
        return $this->options[$section][$key] ?? $default;
42
    }
43
44
    public function getSection(string $section): array
45
    {
46
        return $this->options[$section] ?? [];
47
    }
48
49
    public function setSectionDefaults(string $section, array $defaults): self
50
    {
51
        if (!array_key_exists($section, $this->options)) {
52
            $this->options[$section] = $defaults;
53
        } else {
54
            $this->options[$section] = array_merge_recursive($defaults, $this->options[$section]);
55
        }
56
        return $this;
57
    }
58
59
    /**
60
     * Returns the base path where we expect to find the options
61
     *
62
     * @return string
63
     */
64
    public function getBasePath(): string
65
    {
66
        if ($this->basePath) {
67
            return $this->basePath;
68
        }
69
        // assume we're in vendor/
70
        $path = __DIR__;
71
        $start = mb_strpos('/vendor/', $path);
72
        if ($start !== false) {
73
            return substr($path, $start);
74
        }
75
        return getcwd();
76
    }
77
78
    protected function loadOptions(): array
79
    {
80
        $defaultConfig = require(__DIR__ . "/Config/modelarium.php");
81
82
        // try json
83
        $config = $defaultConfig;
84
        $filename = $this->getBasePath() . '/modelarium.json';
85
        if (file_exists($filename)) {
86
            $config = self::mergeArrays($defaultConfig, json_decode(file_get_contents($filename), true));
87
        } else {
88
            // try php
89
            $filename = $this->getBasePath() . '/config/modelarium.php';
90
            if (file_exists($filename)) {
91
                $config = self::mergeArrays($defaultConfig, require($filename));
92
            }
93
        }
94
        return $config;
95
    }
96
97
    protected static function mergeArrays(array $base, array $merge)
98
    {
99
        $newarray = [];
100
        foreach ($base as $key => $val) {
101
            if (is_array($val)) {
102
                if (self::isAssoc($val)) {
103
                    $newarray[$key] = self::mergeArrays($val, $merge[$key] ?? []);
104
                } else {
105
                    $newarray[$key] = $merge[$key] ?? $val;
106
                }
107
            } else {
108
                $newarray[$key] = $merge[$key] ?? $val;
109
            }
110
        }
111
      
112
        return $newarray;
113
    }
114
115
    protected static function isAssoc(array $arr)
116
    {
117
        if (array() === $arr) {
118
            return false;
119
        }
120
        return array_keys($arr) !== range(0, count($arr) - 1);
121
    }
122
}
123