Completed
Push — master ( ab5383...bdb11d )
by Neomerx
03:14
created

BundleStorage::checkNonEmptyStringOrInt()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
176
    {
177
        $isValid = true;
178
        foreach ($encodedData as $locale => $namespaceResources) {
179
            $isValid =
180
                $isValid === true && $isValid = $this->checkNonEmptyString($locale) === true &&
181
                $isValid === true && $isValid = is_array($namespaceResources) === true &&
182
                $isValid === true && $isValid = $this->checkNamespaceResources($namespaceResources);
183
        }
184
185
        return $isValid;
186
    }
187
188
    /**
189
     * @param array $namespaceResources
190
     *
191
     * @return bool
192
     */
193 View Code Duplication
    private function checkNamespaceResources(array $namespaceResources): bool
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
194
    {
195
        $isValid = true;
196
        foreach ($namespaceResources as $namespace => $resources) {
197
            $isValid =
198
                $isValid === true && $isValid = $this->checkNonEmptyString($namespace) === true &&
199
                $isValid === true && $isValid = is_array($resources) === true &&
200
                $isValid === true && $isValid = $this->checkResources($resources);
201
        }
202
203
        return $isValid;
204
    }
205
206
    /**
207
     * @param array $resources
208
     *
209
     * @return bool
210
     */
211
    private function checkResources(array $resources): bool
212
    {
213
        $isValid = true;
214
        foreach ($resources as $key => $valueAndLocale) {
215
            $isValid =
216
                $isValid === true && $isValid = $this->checkPair($key, $valueAndLocale);
217
        }
218
219
        return $isValid;
220
    }
221
222
    /**
223
     * @param string $key
224
     * @param array  $valueAndLocale
225
     *
226
     * @return bool
227
     */
228
    private function checkPair(string $key, array $valueAndLocale): bool
229
    {
230
        $result =
231
            $this->checkNonEmptyStringOrInt($key) === true && $this->checkValueWithLocale($valueAndLocale) === true;
232
233
        return $result;
234
    }
235
236
    /**
237
     * @param array $valueAndLocale
238
     *
239
     * @return bool
240
     */
241
    private function checkValueWithLocale(array $valueAndLocale): bool
242
    {
243
        $result =
244
            count($valueAndLocale) === 2 &&
245
            $this->checkNonEmptyString($valueAndLocale[static::INDEX_PAIR_VALUE]) === true &&
246
            $this->checkNonEmptyString($valueAndLocale[static::INDEX_PAIR_LOCALE]) === true;
247
248
        return $result;
249
    }
250
251
    /**
252
     * @param mixed $value
253
     *
254
     * @return bool
255
     */
256
    private function checkNonEmptyStringOrInt($value): bool
257
    {
258
        $result = $this->checkNonEmptyString($value) || is_int($value) === true;
259
260
        return $result;
261
    }
262
263
    /**
264
     * @param mixed $value
265
     *
266
     * @return bool
267
     */
268
    private function checkNonEmptyString($value): bool
269
    {
270
        $result = is_string($value) === true && (empty($value) === false || $value === '0');
271
272
        return $result;
273
    }
274
}
275