BundleStorage   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 220
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 35
lcom 1
cbo 0
dl 0
loc 220
ccs 64
cts 64
cp 1
rs 9.6
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A has() 0 8 3
A get() 0 11 3
A hasResources() 0 8 2
A getResources() 0 10 1
A getDefaultLocale() 0 4 1
A getEncodedStorage() 0 4 1
A lookupLocale() 0 5 2
A getLocales() 0 4 1
A setEncodedStorage() 0 16 2
A checkEncodedData() 0 11 5
A checkNamespaceResources() 0 11 5
A checkResources() 0 9 3
A checkPair() 0 6 2
A checkValueWithLocale() 0 9 3
1
<?php declare (strict_types = 1);
2
3
namespace Limoncello\l10n\Messages;
4
5
/**
6
 * Copyright 2015-2019 [email protected]
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
use Limoncello\l10n\Contracts\Messages\BundleStorageInterface;
22
use function array_keys;
23
use function assert;
24
use function count;
25
use function is_array;
26
use function locale_lookup;
27
use function strlen;
28
29
/**
30
 * @package Limoncello\l10n
31
 */
32
class BundleStorage implements BundleStorageInterface
33
{
34
    /** Encode index */
35
    const INDEX_DEFAULT_LOCALE = 0;
36
37
    /** Encode index */
38
    const INDEX_DATA = self::INDEX_DEFAULT_LOCALE + 1;
39
40
    /**
41
     * @var array
42
     */
43
    private $encodedStorage;
44
45
    /**
46
     * @var string[]
47
     */
48
    private $locales;
49
50
    /**
51
     * @var string
52
     */
53
    private $defaultLocale;
54
55
    /**
56
     * @param array $encodedStorage
57
     */
58 7
    public function __construct(array $encodedStorage)
59
    {
60 7
        $this->setEncodedStorage($encodedStorage);
61
    }
62
63
    /**
64
     * @inheritdoc
65
     */
66 7
    public function has(string $locale, string $namespace, string $key): bool
67
    {
68 7
        assert(empty($locale) === false && empty($namespace) === false && strlen($key) > 0);
69
70 7
        $has = isset($this->getEncodedStorage()[$locale][$namespace][$key]);
71
72 7
        return $has;
73
    }
74
75
    /**
76
     * @inheritdoc
77
     */
78 7
    public function get(string $locale, string $namespace, string $key): ?array
79
    {
80 7
        $locale = $this->lookupLocale($this->getLocales(), $locale, $this->getDefaultLocale());
81
82 7
        $result = $this->has($locale, $namespace, $key) === true ?
83 7
            $this->getEncodedStorage()[$locale][$namespace][$key] : null;
84
85 7
        assert($result === null || $this->checkValueWithLocale($result) === true);
86
87 7
        return $result;
88
    }
89
90
    /**
91
     * @inheritdoc
92
     */
93 1
    public function hasResources(string $locale, string $namespace): bool
94
    {
95 1
        assert(empty($locale) === false && empty($namespace) === false);
96
97 1
        $has = isset($this->getEncodedStorage()[$locale][$namespace]);
98
99 1
        return $has;
100
    }
101
102
    /**
103
     * @inheritdoc
104
     */
105 1
    public function getResources(string $locale, string $namespace): array
106
    {
107 1
        $locale = $this->lookupLocale($this->getLocales(), $locale, $this->getDefaultLocale());
108
109 1
        assert($this->hasResources($locale, $namespace) === true);
110
111 1
        $result = $this->getEncodedStorage()[$locale][$namespace];
112
113 1
        return $result;
114
    }
115
116
    /**
117
     * @inheritdoc
118
     */
119 7
    public function getDefaultLocale(): string
120
    {
121 7
        return $this->defaultLocale;
122
    }
123
124
    /**
125
     * @return array
126
     */
127 7
    protected function getEncodedStorage(): array
128
    {
129 7
        return $this->encodedStorage;
130
    }
131
132
    /**
133
     * @param string[] $locales
134
     * @param string   $locale
135
     * @param string   $defaultLocale
136
     *
137
     * @return string
138
     */
139 7
    protected function lookupLocale(array $locales, string $locale, string $defaultLocale): string
140
    {
141
        // for some odd reason locale_lookup returns empty string but not default locale if input locales are empty
142 7
        return empty($locales) === true ? $defaultLocale : locale_lookup($locales, $locale, false, $defaultLocale);
143
    }
144
145
    /**
146
     * @return string[]
147
     */
148 7
    protected function getLocales(): array
149
    {
150 7
        return $this->locales;
151
    }
152
153
    /**
154
     * @param array $encodedStorage
155
     *
156
     * @return self
157
     */
158 7
    protected function setEncodedStorage(array $encodedStorage): self
159
    {
160 7
        assert(count($encodedStorage) === 2);
161
162 7
        $encodedData = $encodedStorage[static::INDEX_DATA];
163
164
        // check storage has 3 levels locale -> namespace -> key & value + culture pairs and
165
        // keys, values and cultures are non-empty strings
166 7
        assert(is_array($encodedData) === true && $this->checkEncodedData($encodedData) === true);
167
168 7
        $this->defaultLocale  = $encodedStorage[static::INDEX_DEFAULT_LOCALE];
169 7
        $this->encodedStorage = $encodedData;
170 7
        $this->locales        = array_keys($encodedData);
0 ignored issues
show
Documentation Bug introduced by
It seems like \array_keys($encodedData) of type array<integer,integer|string> is incompatible with the declared type array<integer,string> of property $locales.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
171
172 7
        return $this;
173
    }
174
175
    /**
176
     * @param array $encodedData
177
     *
178
     * @return bool
179
     */
180 7
    private function checkEncodedData(array $encodedData): bool
181
    {
182 7
        $isValid = true;
183 7
        foreach ($encodedData as $locale => $namespaceResources) {
184 7
            $isValid = $isValid === true &&
185 7
                empty($locale) === false &&
186 7
                is_array($namespaceResources) === true && $this->checkNamespaceResources($namespaceResources);
187
        }
188
189 7
        return $isValid;
190
    }
191
192
    /**
193
     * @param array $namespaceResources
194
     *
195
     * @return bool
196
     */
197 7
    private function checkNamespaceResources(array $namespaceResources): bool
198
    {
199 7
        $isValid = true;
200 7
        foreach ($namespaceResources as $namespace => $resources) {
201 7
            $isValid = $isValid === true &&
202 7
                empty($namespace) === false &&
203 7
                is_array($resources) === true && $this->checkResources($resources);
204
        }
205
206 7
        return $isValid;
207
    }
208
209
    /**
210
     * @param array $resources
211
     *
212
     * @return bool
213
     */
214 7
    private function checkResources(array $resources): bool
215
    {
216 7
        $isValid = true;
217 7
        foreach ($resources as $key => $valueAndLocale) {
218 7
            $isValid = $isValid === true && $this->checkPair((string)$key, $valueAndLocale);
219
        }
220
221 7
        return $isValid;
222
    }
223
224
    /**
225
     * @param string $key
226
     * @param array  $valueAndLocale
227
     *
228
     * @return bool
229
     */
230 7
    private function checkPair(string $key, array $valueAndLocale): bool
231
    {
232 7
        $result = strlen($key) > 0 && $this->checkValueWithLocale($valueAndLocale) === true;
233
234 7
        return $result;
235
    }
236
237
    /**
238
     * @param array $valueAndLocale
239
     *
240
     * @return bool
241
     */
242 7
    private function checkValueWithLocale(array $valueAndLocale): bool
243
    {
244
        $result =
245 7
            count($valueAndLocale) === 2 &&
246 7
            empty($valueAndLocale[static::INDEX_PAIR_VALUE]) === false &&
247 7
            empty($valueAndLocale[static::INDEX_PAIR_LOCALE]) === false;
248
249 7
        return $result;
250
    }
251
}
252