Passed
Branch 2.0 (72e182)
by Philippe
02:18
created

Config::validate()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 11
nc 6
nop 1
dl 0
loc 22
ccs 12
cts 12
cp 1
crap 7
rs 6.9811
c 0
b 0
f 0
1
<?php
2
3
namespace Thinktomorrow\Locale\Values;
4
5
use Thinktomorrow\Locale\Exceptions\InvalidConfig;
6
7
class Config implements \ArrayAccess
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
8
{
9
    /**
10
     * @var array
11
     */
12
    private $config;
13
14 109
    private function __construct(array $config)
15
    {
16 109
        $this->validate($config);
17
18 98
        $this->config = $this->sanitize($config);
19 98
    }
20
21 109
    public static function from(array $config)
22
    {
23 109
        return new static($config);
24
    }
25
26 89
    public function get($key)
27
    {
28 89
        if(!isset($this->config[$key])) throw new \InvalidArgumentException('No config value found by key ['.$key.']');
29
30 88
        return $this->config[$key];
31
    }
32
33 1
    public function all(): array
34
    {
35 1
        return $this->config;
36
    }
37
38 98
    private function sanitize(array $config): array
39
    {
40 98
        $locales = $config['locales'];
41 98
        $locales = $this->convertSingleEntryToDefault($locales);
42 98
        $locales = $this->removeSlashes($locales);
43
44 98
        $config['locales'] = $locales;
45
46 98
        return $config;
47
    }
48
49
    /**
50
     * @param array $locales
51
     * @return array
52
     */
53 98
    private function removeSlashes(array $locales): array
54
    {
55 98
        foreach($locales as $group => $segments)
56
        {
57 98
            foreach ($segments as $segment => $locale) {
58
                // remove slashes if any
59 98
                if ($segment != '/' && false !== strpos($segment, '/')) {
60 14
                    $_segment = str_replace('/', '', $segment);
61
62 14
                    unset($locales[$group][$segment]);
63 98
                    $locales[$group][$_segment] = $locale;
64
                }
65
            }
66
        }
67
68 98
        return $locales;
69
    }
70
71
    /**
72
     * @param array $locales
73
     * @return array
74
     */
75 98
    private function convertSingleEntryToDefault(array $locales): array
76
    {
77 98
        foreach ($locales as $group => $segments) {
78
            // If single locale is passed, it's considered the default for this group
79 98
            if (!is_array($segments)) {
80 98
                $locales[$group] = $segments = ['/' => $segments];
81
            }
82
        }
83
84 98
        return $locales;
85
    }
86
87
    /**
88
     * @param array $config
89
     */
90 109
    private function validate(array $config)
91
    {
92 109
        if (!isset($config['locales'])) {
93 2
            throw new InvalidConfig('Value [Locales] is missing for config structure.');
94
        }
95
96 107
        $locales = $config['locales'];
97
98 107
        if (!isset($locales['*'])) {
99 8
            throw new InvalidConfig('Group [default] is missing for locales structure. At least add the default "*" scope.');
100
        }
101
102 99
        if (is_array($locales['*']) && !isset($locales['*']['/'])) {
103 1
            throw new InvalidConfig('Group [default] is missing the default locale. e.g. ["/" => "en"]');
104
        }
105
106 98
        foreach ($locales as $group => $segments) {
107 98
            if (!is_string($group)) {
108 98
                throw new InvalidConfig('Invalid config structure for locales group [' . $group . ']');
109
            }
110
        }
111 98
    }
112
113 88
    public function offsetExists($offset)
114
    {
115 88
        if(!is_string($offset) && !is_int($offset)) return false;
116 88
        return array_key_exists($offset, $this->config);
117
    }
118 86
    public function offsetGet($offset)
119
    {
120 86
        return $this->config[$offset];
121
    }
122 1
    public function offsetSet($offset, $value)
123
    {
124 1
        if(is_null($offset)) $this->config[] = $value;
125 1
        else $this->config[$offset] = $value;
126 1
    }
127 1
    public function offsetUnset($offset)
128
    {
129 1
        unset($this->config[$offset]);
130 1
    }
131
132 1
    public function toArray(): array
133
    {
134 1
        return $this->config;
135
    }
136
}