PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.1.0
Defender Security – Malware Scanner, Login Security & Firewall v3.1.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / vendor / gettext / languages / src / CldrData.php

CldrData.php in Defender Security – Malware Scanner, Login Security & Firewall 3.1.0, at vendor/gettext/languages/src/CldrData.php

343 lines 13.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Gettext\Languages;
4
5 use Exception;
6
7 /**
8 * Holds the CLDR data.
9 */
10 class CldrData
11 {
12 /**
13 * Super-special plural category: this should always be present for any language.
14 *
15 * @var string
16 */
17 const OTHER_CATEGORY = 'other';
18
19 /**
20 * The list of the plural categories, sorted from 'zero' to 'other'.
21 *
22 * @var string[]
23 */
24 public static $categories = array('zero', 'one', 'two', 'few', 'many', self::OTHER_CATEGORY);
25
26 /**
27 * The loaded CLDR data.
28 *
29 * @var array
30 */
31 private static $data;
32
33 /**
34 * @var array
35 */
36 private static $plurals;
37
38 /**
39 * Returns a dictionary containing the language names.
40 * The keys are the language identifiers.
41 * The values are the language names in US English.
42 *
43 * @return string[]
44 */
45 public static function getLanguageNames()
46 {
47 return self::getData('languages');
48 }
49
50 /**
51 * Return a dictionary containing the territory names (in US English).
52 * The keys are the territory identifiers.
53 * The values are the territory names in US English.
54 *
55 * @return string[]
56 */
57 public static function getTerritoryNames()
58 {
59 return self::getData('territories');
60 }
61
62 /**
63 * Return a dictionary containing the script names (in US English).
64 * The keys are the script identifiers.
65 * The values are the script names in US English.
66 *
67 * @param bool $standAlone set to true to retrieve the stand-alone script names, false otherwise
68 *
69 * @return string[]
70 */
71 public static function getScriptNames($standAlone)
72 {
73 return self::getData($standAlone ? 'standAloneScripts' : 'scripts');
74 }
75
76 /**
77 * A dictionary containing the plural rules.
78 * The keys are the language identifiers.
79 * The values are arrays whose keys are the CLDR category names and the values are the CLDR category definition.
80 *
81 * @example The English key-value pair is somethink like this:
82 * <code><pre>
83 * "en": {
84 * "pluralRule-count-one": "i = 1 and v = 0 @integer 1",
85 * "pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
86 * }
87 * </pre></code>
88 *
89 * @return array
90 */
91 public static function getPlurals()
92 {
93 return self::getData('plurals');
94 }
95
96 /**
97 * Return a list of superseded language codes.
98 *
99 * @return array keys are the former language codes, values are the new language/locale codes
100 */
101 public static function getSupersededLanguages()
102 {
103 return self::getData('supersededLanguages');
104 }
105
106 /**
107 * Retrieve the name of a language, as well as if a language code is deprecated in favor of another language code.
108 *
109 * @param string $id the language identifier
110 *
111 * @return array|null Returns an array with the keys 'id' (normalized), 'name', 'supersededBy' (optional), 'territory' (optional), 'script' (optional), 'baseLanguage' (optional), 'categories'. If $id is not valid returns null.
112 */
113 public static function getLanguageInfo($id)
114 {
115 $result = null;
116 $matches = array();
117 if (preg_match('/^([a-z]{2,3})(?:[_\-]([a-z]{4}))?(?:[_\-]([a-z]{2}|[0-9]{3}))?(?:$|-)/i', $id, $matches)) {
118 $languageId = strtolower($matches[1]);
119 $scriptId = (isset($matches[2]) && ($matches[2] !== '')) ? ucfirst(strtolower($matches[2])) : null;
120 $territoryId = (isset($matches[3]) && ($matches[3] !== '')) ? strtoupper($matches[3]) : null;
121 $normalizedId = $languageId;
122 if (isset($scriptId)) {
123 $normalizedId .= '_' . $scriptId;
124 }
125 if (isset($territoryId)) {
126 $normalizedId .= '_' . $territoryId;
127 }
128 // Structure precedence: see Likely Subtags - http://www.unicode.org/reports/tr35/tr35-31/tr35.html#Likely_Subtags
129 $variants = array();
130 $variantsWithScript = array();
131 $variantsWithTerritory = array();
132 if (isset($scriptId) && isset($territoryId)) {
133 $variantsWithTerritory[] = $variantsWithScript[] = $variants[] = "{$languageId}_{$scriptId}_{$territoryId}";
134 }
135 if (isset($scriptId)) {
136 $variantsWithScript[] = $variants[] = "{$languageId}_{$scriptId}";
137 }
138 if (isset($territoryId)) {
139 $variantsWithTerritory[] = $variants[] = "{$languageId}_{$territoryId}";
140 }
141 $variants[] = $languageId;
142 $allGood = true;
143 $scriptName = null;
144 $scriptStandAloneName = null;
145 if (isset($scriptId)) {
146 $scriptNames = self::getScriptNames(false);
147 if (isset($scriptNames[$scriptId])) {
148 $scriptName = $scriptNames[$scriptId];
149 $scriptStandAloneNames = self::getScriptNames(true);
150 $scriptStandAloneName = $scriptStandAloneNames[$scriptId];
151 } else {
152 $allGood = false;
153 }
154 }
155 $territoryName = null;
156 if (isset($territoryId)) {
157 $territoryNames = self::getTerritoryNames();
158 if (isset($territoryNames[$territoryId])) {
159 if ($territoryId !== '001') {
160 $territoryName = $territoryNames[$territoryId];
161 }
162 } else {
163 $allGood = false;
164 }
165 }
166 $languageName = null;
167 $languageNames = self::getLanguageNames();
168 foreach ($variants as $variant) {
169 if (isset($languageNames[$variant])) {
170 $languageName = $languageNames[$variant];
171 if (isset($scriptName) && (!in_array($variant, $variantsWithScript))) {
172 $languageName = $scriptName . ' ' . $languageName;
173 }
174 if (isset($territoryName) && (!in_array($variant, $variantsWithTerritory))) {
175 $languageName .= ' (' . $territoryNames[$territoryId] . ')';
176 }
177 break;
178 }
179 }
180 if (!isset($languageName)) {
181 $allGood = false;
182 }
183 $baseLanguage = null;
184 if (isset($scriptId) || isset($territoryId)) {
185 if (isset($languageNames[$languageId]) && ($languageNames[$languageId] !== $languageName)) {
186 $baseLanguage = $languageNames[$languageId];
187 }
188 }
189 $plural = null;
190 $plurals = self::getPlurals();
191 foreach ($variants as $variant) {
192 if (isset($plurals[$variant])) {
193 $plural = $plurals[$variant];
194 break;
195 }
196 }
197 if (!isset($plural)) {
198 $allGood = false;
199 }
200 $supersededBy = null;
201 $supersededBys = self::getSupersededLanguages();
202 foreach ($variants as $variant) {
203 if (isset($supersededBys[$variant])) {
204 $supersededBy = $supersededBys[$variant];
205 break;
206 }
207 }
208 if ($allGood) {
209 $result = array();
210 $result['id'] = $normalizedId;
211 $result['name'] = $languageName;
212 if (isset($supersededBy)) {
213 $result['supersededBy'] = $supersededBy;
214 }
215 if (isset($scriptStandAloneName)) {
216 $result['script'] = $scriptStandAloneName;
217 }
218 if (isset($territoryName)) {
219 $result['territory'] = $territoryName;
220 }
221 if (isset($baseLanguage)) {
222 $result['baseLanguage'] = $baseLanguage;
223 }
224 $result['categories'] = $plural;
225 }
226 }
227
228 return $result;
229 }
230
231 /**
232 * Returns the loaded CLDR data.
233 *
234 * @param string $key Can be 'languages', 'territories', 'plurals', 'supersededLanguages', 'scripts', 'standAloneScripts'
235 *
236 * @return array
237 */
238 private static function getData($key)
239 {
240 if (!isset(self::$data)) {
241 $fixKeys = function ($list, &$standAlone = null) {
242 $result = array();
243 $standAlone = array();
244 $match = null;
245 foreach ($list as $key => $value) {
246 $variant = '';
247 if (preg_match('/^(.+)-alt-(short|variant|stand-alone|long|menu)$/', $key, $match)) {
248 $key = $match[1];
249 $variant = $match[2];
250 }
251 $key = str_replace('-', '_', $key);
252 switch ($key) {
253 case 'root': // Language: Root
254 case 'und': // Language: Unknown Language
255 case 'zxx': // Language: No linguistic content
256 case 'ZZ': // Territory: Unknown Region
257 case 'Zinh': // Script: Inherited
258 case 'Zmth': // Script: Mathematical Notation
259 case 'Zsym': // Script: Symbols
260 case 'Zxxx': // Script: Unwritten
261 case 'Zyyy': // Script: Common
262 case 'Zzzz': // Script: Unknown Script
263 break;
264 default:
265 switch ($variant) {
266 case 'stand-alone':
267 $standAlone[$key] = $value;
268 break;
269 case '':
270 $result[$key] = $value;
271 break;
272 }
273 break;
274 }
275 }
276
277 return $result;
278 };
279 $data = array();
280 $json = json_decode(file_get_contents(__DIR__ . '/cldr-data/main/en-US/languages.json'), true);
281 $data['languages'] = $fixKeys($json['main']['en-US']['localeDisplayNames']['languages']);
282 $json = json_decode(file_get_contents(__DIR__ . '/cldr-data/main/en-US/territories.json'), true);
283 $data['territories'] = $fixKeys($json['main']['en-US']['localeDisplayNames']['territories']);
284 $json = json_decode(file_get_contents(__DIR__ . '/cldr-data/supplemental/plurals.json'), true);
285 $data['plurals'] = $fixKeys($json['supplemental']['plurals-type-cardinal']);
286 $json = json_decode(file_get_contents(__DIR__ . '/cldr-data/main/en-US/scripts.json'), true);
287 $data['scripts'] = $fixKeys($json['main']['en-US']['localeDisplayNames']['scripts'], $data['standAloneScripts']);
288 $data['standAloneScripts'] = array_merge($data['scripts'], $data['standAloneScripts']);
289 $data['scripts'] = array_merge($data['standAloneScripts'], $data['scripts']);
290 $data['supersededLanguages'] = array();
291 // Remove the languages for which we don't have plurals
292 $m = null;
293 foreach (array_keys(array_diff_key($data['languages'], $data['plurals'])) as $missingPlural) {
294 if (preg_match('/^([a-z]{2,3})_/', $missingPlural, $m)) {
295 if (!isset($data['plurals'][$m[1]])) {
296 unset($data['languages'][$missingPlural]);
297 }
298 } else {
299 unset($data['languages'][$missingPlural]);
300 }
301 }
302 // Fix the languages for which we have plurals
303 $formerCodes = array(
304 'in' => 'id', // former Indonesian
305 'iw' => 'he', // former Hebrew
306 'ji' => 'yi', // former Yiddish
307 'jw' => 'jv', // former Javanese
308 'mo' => 'ro_MD', // former Moldavian
309 );
310 $knownMissingLanguages = array(
311 'guw' => 'Gun',
312 'hnj' => 'Mong Njua',
313 'nah' => 'Nahuatl',
314 'smi' => 'Sami',
315 );
316 foreach (array_keys(array_diff_key($data['plurals'], $data['languages'])) as $missingLanguage) {
317 if (isset($formerCodes[$missingLanguage]) && isset($data['languages'][$formerCodes[$missingLanguage]])) {
318 $data['languages'][$missingLanguage] = $data['languages'][$formerCodes[$missingLanguage]];
319 $data['supersededLanguages'][$missingLanguage] = $formerCodes[$missingLanguage];
320 } else {
321 if (isset($knownMissingLanguages[$missingLanguage])) {
322 $data['languages'][$missingLanguage] = $knownMissingLanguages[$missingLanguage];
323 } else {
324 throw new Exception("We have the plural rule for the language '{$missingLanguage}' but we don't have its language name");
325 }
326 }
327 }
328 ksort($data['languages'], SORT_STRING);
329 ksort($data['territories'], SORT_STRING);
330 ksort($data['plurals'], SORT_STRING);
331 ksort($data['scripts'], SORT_STRING);
332 ksort($data['standAloneScripts'], SORT_STRING);
333 ksort($data['supersededLanguages'], SORT_STRING);
334 self::$data = $data;
335 }
336 if (!isset(self::$data[$key])) {
337 throw new Exception("Invalid CLDR data key: '{$key}'");
338 }
339
340 return self::$data[$key];
341 }
342 }
343