limoncello-php-dist /
l10n
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 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
|
|||
| 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 |
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..