1 | <?php |
||||
2 | /** |
||||
3 | * File containing the {@link Localization} class. |
||||
4 | * @package Localization |
||||
5 | * @subpackage Core |
||||
6 | * @see Localization |
||||
7 | */ |
||||
8 | |||||
9 | declare(strict_types=1); |
||||
10 | |||||
11 | namespace AppLocalize; |
||||
12 | |||||
13 | use AppLocalize\Localization\Countries\BaseCountry; |
||||
14 | use AppLocalize\Localization\Countries\CountryCollection; |
||||
15 | use AppLocalize\Localization\Currencies\CurrencyCollection; |
||||
16 | use AppLocalize\Localization\Currencies\CurrencyInterface; |
||||
17 | use AppLocalize\Localization\Event\LocaleChanged; |
||||
18 | use AppUtils\ClassHelper; |
||||
19 | use AppUtils\FileHelper; |
||||
20 | use AppUtils\FileHelper\FileInfo; |
||||
21 | use AppUtils\FileHelper_Exception; |
||||
22 | use HTML_QuickForm2_Container; |
||||
23 | use HTML_QuickForm2_Element_Select; |
||||
24 | use Mistralys\ChangelogParser\ChangelogParser; |
||||
25 | use Throwable; |
||||
26 | |||||
27 | /** |
||||
28 | * Localization handling collection for both the |
||||
29 | * application itself and its user contents. |
||||
30 | * |
||||
31 | * @package Localization |
||||
32 | * @subpackage Core |
||||
33 | * @author Sebastian Mordziol <[email protected]> |
||||
34 | */ |
||||
35 | class Localization |
||||
36 | { |
||||
37 | const ERROR_UNKNOWN_CONTENT_LOCALE = 39001; |
||||
38 | const ERROR_UNKNOWN_APPLICATION_LOCALE = 39002; |
||||
39 | const ERROR_NO_STORAGE_FILE_SET = 39003; |
||||
40 | const ERROR_CONFIGURE_NOT_CALLED = 39004; |
||||
41 | const ERROR_NO_SOURCES_ADDED = 39005; |
||||
42 | const ERROR_NO_LOCALE_SELECTED_IN_NS = 39006; |
||||
43 | const ERROR_NO_LOCALES_IN_NAMESPACE = 39007; |
||||
44 | const ERROR_UNKNOWN_NAMESPACE = 39008; |
||||
45 | const ERROR_UNKNOWN_LOCALE_IN_NS = 39009; |
||||
46 | const ERROR_UNKNOWN_EVENT_NAME = 39010; |
||||
47 | const ERROR_LOCALE_NOT_FOUND = 39011; |
||||
48 | const ERROR_COUNTRY_NOT_FOUND = 39012; |
||||
49 | |||||
50 | /** |
||||
51 | * The name of the default application locale, i.e. the |
||||
52 | * locale in which application textual content is written. |
||||
53 | * |
||||
54 | * @var string |
||||
55 | */ |
||||
56 | const BUILTIN_LOCALE_NAME = 'en_UK'; |
||||
57 | |||||
58 | const NAMESPACE_APPLICATION = '__application'; |
||||
59 | const NAMESPACE_CONTENT = '__content'; |
||||
60 | |||||
61 | public const EVENT_LOCALE_CHANGED = 'LocaleChanged'; |
||||
62 | public const EVENT_CLIENT_FOLDER_CHANGED = 'ClientFolderChanged'; |
||||
63 | public const EVENT_CACHE_KEY_CHANGED = 'CacheKeyChanged'; |
||||
64 | |||||
65 | /** |
||||
66 | * Collection of all locales by namespace (application, content, custom...). |
||||
67 | * |
||||
68 | * @var array<string,array<string,Localization_Locale>> |
||||
69 | * @see Localization::addLocale() |
||||
70 | */ |
||||
71 | protected static $locales = array(); |
||||
72 | |||||
73 | /** |
||||
74 | * @var boolean |
||||
75 | * @see Localization::init() |
||||
76 | */ |
||||
77 | private static $initDone = false; |
||||
78 | |||||
79 | /** |
||||
80 | * Path to the file in which the scanner results are stored. |
||||
81 | * @var string |
||||
82 | * @see Localization::configure() |
||||
83 | */ |
||||
84 | protected static $storageFile = ''; |
||||
85 | |||||
86 | /** |
||||
87 | * Path to the folder into which the client libraries are written. |
||||
88 | * @var string |
||||
89 | * @see Localization::setClientLibrariesFolder() |
||||
90 | */ |
||||
91 | protected static $clientFolder = ''; |
||||
92 | |||||
93 | /** |
||||
94 | * If this key changes, client libraries are refreshed. |
||||
95 | * @var string |
||||
96 | * @see Localization::setClientLibrariesCacheKey() |
||||
97 | */ |
||||
98 | protected static $clientCacheKey = ''; |
||||
99 | |||||
100 | /** |
||||
101 | * Whether the configuration has been made. |
||||
102 | * @var bool |
||||
103 | * @see Localization::configure() |
||||
104 | */ |
||||
105 | protected static $configured = false; |
||||
106 | |||||
107 | /** |
||||
108 | * Stores event listener instances. |
||||
109 | * @var array |
||||
110 | */ |
||||
111 | protected static array $listeners = array(); |
||||
112 | |||||
113 | /** |
||||
114 | * @var integer |
||||
115 | * @see Localization::addEventListener() |
||||
116 | */ |
||||
117 | protected static $listenersCounter = 0; |
||||
118 | |||||
119 | /** |
||||
120 | * @var Localization_Translator|NULL |
||||
121 | */ |
||||
122 | protected static $translator; |
||||
123 | |||||
124 | /** |
||||
125 | * Initializes the localization layer. This is done |
||||
126 | * automatically, and only once per request. |
||||
127 | * |
||||
128 | * (Called at the end of this file) |
||||
129 | */ |
||||
130 | public static function init() : void |
||||
131 | { |
||||
132 | if(self::$initDone) { |
||||
133 | return; |
||||
134 | } |
||||
135 | |||||
136 | self::reset(); |
||||
137 | |||||
138 | $installFolder = realpath(__DIR__.'/../'); |
||||
139 | |||||
140 | // add the localization package's own sources, |
||||
141 | // so the bundled localized strings can |
||||
142 | // always be translated. |
||||
143 | Localization::addSourceFolder( |
||||
144 | 'application-localization', |
||||
145 | 'Application Localization Package', |
||||
146 | 'Composer packages', |
||||
147 | $installFolder.'/localization', |
||||
148 | $installFolder.'/src' |
||||
149 | ) |
||||
150 | ->excludeFiles(array('jtokenizer')) |
||||
151 | ->excludeFolder('css'); |
||||
152 | |||||
153 | self::$initDone = true; |
||||
154 | } |
||||
155 | |||||
156 | /** |
||||
157 | * Retrieves all available application locales, as an indexed |
||||
158 | * array with locale objects sorted by locale label. |
||||
159 | * |
||||
160 | * @return Localization_Locale[] |
||||
161 | * @see getAppLocale() |
||||
162 | */ |
||||
163 | public static function getAppLocales() |
||||
164 | { |
||||
165 | return self::getLocalesByNS(self::NAMESPACE_APPLICATION); |
||||
166 | } |
||||
167 | |||||
168 | /** |
||||
169 | * Retrieves all locales in the specified namespace. |
||||
170 | * |
||||
171 | * @param string $namespace |
||||
172 | * @return Localization_Locale[] |
||||
173 | */ |
||||
174 | public static function getLocalesByNS(string $namespace) |
||||
175 | { |
||||
176 | if(isset(self::$locales[$namespace])) { |
||||
177 | return array_values(self::$locales[$namespace]); |
||||
178 | } |
||||
179 | |||||
180 | throw new Localization_Exception( |
||||
181 | 'No locales available in namespace', |
||||
182 | sprintf( |
||||
183 | 'The namespace [%s] does not exist.', |
||||
184 | $namespace |
||||
185 | ), |
||||
186 | self::ERROR_NO_LOCALES_IN_NAMESPACE |
||||
187 | ); |
||||
188 | } |
||||
189 | |||||
190 | /** |
||||
191 | * Adds an application locale to use in the application. |
||||
192 | * |
||||
193 | * @param string $localeName |
||||
194 | * @return Localization_Locale |
||||
195 | */ |
||||
196 | public static function addAppLocale(string $localeName) : Localization_Locale |
||||
197 | { |
||||
198 | return self::addLocaleByNS($localeName, self::NAMESPACE_APPLICATION); |
||||
199 | } |
||||
200 | |||||
201 | /** |
||||
202 | * Adds a content locale to use for content in the application. |
||||
203 | * |
||||
204 | * @param string $localeName |
||||
205 | * @return Localization_Locale |
||||
206 | */ |
||||
207 | public static function addContentLocale(string $localeName) : Localization_Locale |
||||
208 | { |
||||
209 | return self::addLocaleByNS($localeName, self::NAMESPACE_CONTENT); |
||||
210 | } |
||||
211 | |||||
212 | /** |
||||
213 | * Adds a locale to the specified namespace. |
||||
214 | * |
||||
215 | * @param string $localeName |
||||
216 | * @param string $namespace |
||||
217 | * @return Localization_Locale |
||||
218 | */ |
||||
219 | public static function addLocaleByNS(string $localeName, string $namespace) : Localization_Locale |
||||
220 | { |
||||
221 | if(!isset(self::$locales[$namespace])) { |
||||
222 | self::$locales[$namespace] = array(); |
||||
223 | } |
||||
224 | |||||
225 | if(!isset(self::$locales[$namespace][$localeName])) |
||||
226 | { |
||||
227 | self::$locales[$namespace][$localeName] = self::createLocale($localeName); |
||||
228 | |||||
229 | // sort the locales on add: less resource intensive |
||||
230 | // than doing it on getting locales. |
||||
231 | uasort(self::$locales[$namespace], function(Localization_Locale $a, Localization_Locale $b) { |
||||
232 | return strnatcasecmp($a->getLabel(), $b->getLabel()); |
||||
233 | }); |
||||
234 | } |
||||
235 | |||||
236 | return self::$locales[$namespace][$localeName]; |
||||
237 | } |
||||
238 | |||||
239 | /** |
||||
240 | * @param string $localeName |
||||
241 | * @return Localization_Locale |
||||
242 | * |
||||
243 | * @throws Localization_Exception |
||||
244 | * @see Localization::ERROR_LOCALE_NOT_FOUND |
||||
245 | */ |
||||
246 | protected static function createLocale(string $localeName) : Localization_Locale |
||||
247 | { |
||||
248 | $class = '\AppLocalize\Locale\\'.$localeName; |
||||
249 | |||||
250 | try |
||||
251 | { |
||||
252 | $locale = new $class(); |
||||
253 | |||||
254 | if ($locale instanceof Localization_Locale) |
||||
255 | { |
||||
256 | return $locale; |
||||
257 | } |
||||
258 | } |
||||
259 | catch (Throwable $e) |
||||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
![]() |
|||||
260 | { |
||||
261 | |||||
262 | } |
||||
263 | |||||
264 | throw new Localization_Exception( |
||||
265 | 'Locale not supported.', |
||||
266 | sprintf( |
||||
267 | 'The locale class [%s] does not exist.', |
||||
268 | $localeName |
||||
269 | ), |
||||
270 | self::ERROR_LOCALE_NOT_FOUND |
||||
271 | ); |
||||
272 | } |
||||
273 | |||||
274 | private static ?CountryCollection $countries = null; |
||||
275 | |||||
276 | /** |
||||
277 | * Retrieves the country collection instance to |
||||
278 | * access all available countries. |
||||
279 | * |
||||
280 | * @return CountryCollection |
||||
281 | */ |
||||
282 | public static function createCountries() : CountryCollection |
||||
283 | { |
||||
284 | if(!isset(self::$countries)) { |
||||
285 | self::$countries = CountryCollection::getInstance(); |
||||
286 | } |
||||
287 | |||||
288 | return self::$countries; |
||||
0 ignored issues
–
show
|
|||||
289 | } |
||||
290 | |||||
291 | private static ?CurrencyCollection $currencies = null; |
||||
292 | |||||
293 | /** |
||||
294 | * Retrieves the currency collection instance to |
||||
295 | * access all available currencies. |
||||
296 | * |
||||
297 | * @return CurrencyCollection |
||||
298 | */ |
||||
299 | public static function createCurrencies() : CurrencyCollection |
||||
300 | { |
||||
301 | if(!isset(self::$currencies)) { |
||||
302 | self::$currencies = CurrencyCollection::getInstance(); |
||||
303 | } |
||||
304 | |||||
305 | return self::$currencies; |
||||
0 ignored issues
–
show
|
|||||
306 | } |
||||
307 | |||||
308 | /** |
||||
309 | * Creates a new country object for the specified country, e.g. "uk". |
||||
310 | * |
||||
311 | * @param string $id |
||||
312 | * @return BaseCountry |
||||
313 | * |
||||
314 | * @deprecated Use the collection instead: {@see self::createCountries()} |
||||
315 | */ |
||||
316 | public static function createCountry(string $id) : BaseCountry |
||||
317 | { |
||||
318 | return self::createCountries()->getByID($id); |
||||
319 | } |
||||
320 | |||||
321 | /** |
||||
322 | * Retrieves the currency of the selected app locale. |
||||
323 | * |
||||
324 | * @return CurrencyInterface |
||||
325 | * |
||||
326 | * @throws Localization_Exception |
||||
327 | * @see Localization::ERROR_NO_LOCALE_SELECTED_IN_NS |
||||
328 | */ |
||||
329 | public static function getAppCurrency() : CurrencyInterface |
||||
330 | { |
||||
331 | return self::getCurrencyNS(self::NAMESPACE_APPLICATION); |
||||
332 | } |
||||
333 | |||||
334 | /** |
||||
335 | * Retrieves the currency of the selected content locale. |
||||
336 | * |
||||
337 | * @return CurrencyInterface |
||||
338 | * |
||||
339 | * @throws Localization_Exception |
||||
340 | * @see Localization::ERROR_NO_LOCALE_SELECTED_IN_NS |
||||
341 | */ |
||||
342 | public static function getContentCurrency() : CurrencyInterface |
||||
343 | { |
||||
344 | return self::getCurrencyNS(self::NAMESPACE_CONTENT); |
||||
345 | } |
||||
346 | |||||
347 | /** |
||||
348 | * Retrieves the currency of the selected locale in the specified namespace. |
||||
349 | * |
||||
350 | * @param string $namespace |
||||
351 | * @return CurrencyInterface |
||||
352 | * |
||||
353 | * @throws Localization_Exception |
||||
354 | * @see Localization::ERROR_NO_LOCALE_SELECTED_IN_NS |
||||
355 | */ |
||||
356 | public static function getCurrencyNS(string $namespace) : CurrencyInterface |
||||
357 | { |
||||
358 | return self::getSelectedLocaleByNS($namespace)->getCurrency(); |
||||
359 | } |
||||
360 | |||||
361 | /** |
||||
362 | * Retrieves the selected application locale instance. |
||||
363 | * |
||||
364 | * @return Localization_Locale |
||||
365 | */ |
||||
366 | public static function getAppLocale() : Localization_Locale |
||||
367 | { |
||||
368 | return self::getSelectedLocaleByNS(self::NAMESPACE_APPLICATION); |
||||
369 | } |
||||
370 | |||||
371 | /** |
||||
372 | * Retrieves the name of the selected application locale. |
||||
373 | * |
||||
374 | * @return string |
||||
375 | */ |
||||
376 | public static function getAppLocaleName() : string |
||||
377 | { |
||||
378 | return self::getLocaleNameByNS(self::NAMESPACE_APPLICATION); |
||||
379 | } |
||||
380 | |||||
381 | /** |
||||
382 | * Retrieves the names of the available application locales. |
||||
383 | * @return string[] |
||||
384 | */ |
||||
385 | public static function getAppLocaleNames() : array |
||||
386 | { |
||||
387 | return self::getLocaleNamesByNS(self::NAMESPACE_APPLICATION); |
||||
388 | } |
||||
389 | |||||
390 | /** |
||||
391 | * Retrieves the selected locale name in the specified namespace. |
||||
392 | * |
||||
393 | * @param string $namespace |
||||
394 | * @throws Localization_Exception |
||||
395 | * @return string |
||||
396 | */ |
||||
397 | public static function getLocaleNameByNS(string $namespace) : string |
||||
398 | { |
||||
399 | return self::getSelectedLocaleByNS($namespace)->getName(); |
||||
400 | } |
||||
401 | |||||
402 | /** |
||||
403 | * Retrieves the selected locale instance for the specified namespace. |
||||
404 | * |
||||
405 | * @param string $namespace |
||||
406 | * @return Localization_Locale |
||||
407 | * @throws Localization_Exception |
||||
408 | * @see Localization::ERROR_NO_LOCALE_SELECTED_IN_NS |
||||
409 | */ |
||||
410 | public static function getSelectedLocaleByNS(string $namespace) : Localization_Locale |
||||
411 | { |
||||
412 | self::requireNamespace($namespace); |
||||
413 | |||||
414 | if(isset(self::$selected[$namespace])) { |
||||
415 | return self::$selected[$namespace]; |
||||
416 | } |
||||
417 | |||||
418 | throw new Localization_Exception( |
||||
419 | 'No selected locale in namespace.', |
||||
420 | sprintf( |
||||
421 | 'Cannot retrieve selected locale: no locale has been selected in the namespace [%s].', |
||||
422 | $namespace |
||||
423 | ), |
||||
424 | self::ERROR_NO_LOCALE_SELECTED_IN_NS |
||||
425 | ); |
||||
426 | } |
||||
427 | |||||
428 | /** |
||||
429 | * Stores the selected locale names by namespace. |
||||
430 | * @var array<string,Localization_Locale> |
||||
431 | */ |
||||
432 | protected static $selected = array(); |
||||
433 | |||||
434 | /** |
||||
435 | * Selects the active locale for the specified namespace. |
||||
436 | * |
||||
437 | * NOTE: Triggers the "LocaleChanged" event. |
||||
438 | * |
||||
439 | * @param string $localeName |
||||
440 | * @param string $namespace |
||||
441 | * @return Localization_Locale |
||||
442 | * @throws Localization_Exception |
||||
443 | * |
||||
444 | * @see LocaleChanged |
||||
445 | */ |
||||
446 | public static function selectLocaleByNS(string $localeName, string $namespace) : Localization_Locale |
||||
447 | { |
||||
448 | self::requireNamespace($namespace); |
||||
449 | |||||
450 | $locale = self::addLocaleByNS($localeName, $namespace); |
||||
451 | $previous = null; |
||||
452 | |||||
453 | if(isset(self::$selected[$namespace])) |
||||
454 | { |
||||
455 | if(self::$selected[$namespace]->getName() === $localeName) { |
||||
456 | return $locale; |
||||
457 | } |
||||
458 | |||||
459 | $previous = self::$selected[$namespace]; |
||||
460 | } |
||||
461 | |||||
462 | self::$translator = null; |
||||
463 | |||||
464 | self::$selected[$namespace] = $locale; |
||||
465 | |||||
466 | self::triggerEvent( |
||||
467 | self::EVENT_LOCALE_CHANGED, |
||||
468 | array( |
||||
469 | $namespace, |
||||
470 | $previous, |
||||
471 | self::$selected[$namespace] |
||||
472 | ) |
||||
473 | ); |
||||
474 | |||||
475 | return $locale; |
||||
476 | } |
||||
477 | |||||
478 | /** |
||||
479 | * Triggers the specified event, with the provided arguments. |
||||
480 | * |
||||
481 | * @param string $name The event name. |
||||
482 | * @param array $argsList |
||||
483 | * @return Localization_Event |
||||
484 | * @see Localization_Event |
||||
485 | */ |
||||
486 | protected static function triggerEvent(string $name, array $argsList) : Localization_Event |
||||
487 | { |
||||
488 | $class = self::resolveEventClass($name); |
||||
489 | |||||
490 | $event = ClassHelper::requireObjectInstanceOf( |
||||
491 | Localization_Event::class, |
||||
492 | new $class($argsList) |
||||
493 | ); |
||||
494 | |||||
495 | if(!isset(self::$listeners[$name])) { |
||||
496 | return $event; |
||||
497 | } |
||||
498 | |||||
499 | foreach(self::$listeners[$name] as $listener) |
||||
500 | { |
||||
501 | $callArgs = $listener['args']; |
||||
502 | array_unshift($callArgs, $event); |
||||
503 | |||||
504 | call_user_func_array($listener['callback'], $callArgs); |
||||
505 | } |
||||
506 | |||||
507 | return $event; |
||||
508 | } |
||||
509 | |||||
510 | /** |
||||
511 | * Adds a listener to the specified event name. |
||||
512 | * |
||||
513 | * @param string $eventName |
||||
514 | * @param callable $callback |
||||
515 | * @param array $args Additional arguments to add to the event |
||||
516 | * @return int The listener number. |
||||
517 | * |
||||
518 | * @throws Localization_Exception |
||||
519 | * @see Localization::ERROR_UNKNOWN_EVENT_NAME |
||||
520 | */ |
||||
521 | public static function addEventListener(string $eventName, $callback, array $args=array()) : int |
||||
522 | { |
||||
523 | if(!isset(self::$listeners[$eventName])) { |
||||
524 | self::$listeners[$eventName] = array(); |
||||
525 | } |
||||
526 | |||||
527 | self::$listenersCounter++; |
||||
528 | |||||
529 | self::$listeners[$eventName][] = array( |
||||
530 | 'class' => self::resolveEventClass($eventName), |
||||
531 | 'callback' => $callback, |
||||
532 | 'args' => $args, |
||||
533 | 'id' => self::$listenersCounter |
||||
534 | ); |
||||
535 | |||||
536 | return self::$listenersCounter; |
||||
537 | } |
||||
538 | |||||
539 | private static function resolveEventClass(string $eventName) : string |
||||
540 | { |
||||
541 | $className = ClassHelper::resolveClassName( |
||||
542 | Localization_Event::class.'_'.$eventName, |
||||
543 | 'AppLocalize' |
||||
544 | ); |
||||
545 | |||||
546 | if(class_exists($className)) { |
||||
0 ignored issues
–
show
It seems like
$className can also be of type null ; however, parameter $class of class_exists() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
547 | return $className; |
||||
0 ignored issues
–
show
|
|||||
548 | } |
||||
549 | |||||
550 | throw new Localization_Exception( |
||||
551 | sprintf('Unknown localization event [%s].', $eventName), |
||||
552 | sprintf('The required event class [%s] is not present.', $className), |
||||
553 | self::ERROR_UNKNOWN_EVENT_NAME |
||||
554 | ); |
||||
555 | } |
||||
556 | |||||
557 | /** |
||||
558 | * Adds an event listener for the <code>LocaleChanged</code> event, |
||||
559 | * which is triggered every time a locale is changed in any of the |
||||
560 | * available namespaces. |
||||
561 | * |
||||
562 | * The first parameter of the callback is always the event instance. |
||||
563 | * |
||||
564 | * @param callable $callback The listener function to call. |
||||
565 | * @param array $args Optional indexed array with additional arguments to pass on to the callback function. |
||||
566 | * @return int |
||||
567 | * @throws Localization_Exception |
||||
568 | * @see LocaleChanged |
||||
569 | */ |
||||
570 | public static function onLocaleChanged($callback, array $args=array()) : int |
||||
571 | { |
||||
572 | return self::addEventListener(self::EVENT_LOCALE_CHANGED, $callback, $args); |
||||
573 | } |
||||
574 | |||||
575 | public static function onClientFolderChanged(callable $callback, array $args=array()) : int |
||||
576 | { |
||||
577 | return self::addEventListener(self::EVENT_CLIENT_FOLDER_CHANGED, $callback, $args); |
||||
578 | } |
||||
579 | |||||
580 | public static function onCacheKeyChanged(callable $callback, array $args=array()) : int |
||||
581 | { |
||||
582 | return self::addEventListener(self::EVENT_CACHE_KEY_CHANGED, $callback, $args); |
||||
583 | } |
||||
584 | |||||
585 | /** |
||||
586 | * Selects the application locale to use. |
||||
587 | * |
||||
588 | * @param string $localeName |
||||
589 | * @return Localization_Locale |
||||
590 | * @throws Localization_Exception |
||||
591 | */ |
||||
592 | public static function selectAppLocale(string $localeName) : Localization_Locale |
||||
593 | { |
||||
594 | return self::selectLocaleByNS($localeName, self::NAMESPACE_APPLICATION); |
||||
595 | } |
||||
596 | |||||
597 | /** |
||||
598 | * Retrieves an application locale by its name. |
||||
599 | * Note that the locale must have been added first. |
||||
600 | * |
||||
601 | * @param string $localeName |
||||
602 | * @throws Localization_Exception |
||||
603 | * @return Localization_Locale |
||||
604 | * @see Localization::appLocaleExists() |
||||
605 | */ |
||||
606 | public static function getAppLocaleByName(string $localeName) : Localization_Locale |
||||
607 | { |
||||
608 | return self::getLocaleByNameNS($localeName, self::NAMESPACE_APPLICATION); |
||||
609 | } |
||||
610 | |||||
611 | /** |
||||
612 | * Checks by the locale name if the specified locale is |
||||
613 | * available as a locale for the application. |
||||
614 | * |
||||
615 | * @param string $localeName |
||||
616 | * @return boolean |
||||
617 | */ |
||||
618 | public static function appLocaleExists(string $localeName) : bool |
||||
619 | { |
||||
620 | return self::localeExistsInNS($localeName, self::NAMESPACE_APPLICATION); |
||||
621 | } |
||||
622 | |||||
623 | public static function localeExistsInNS(string $localeName, string $namespace) : bool |
||||
624 | { |
||||
625 | return isset(self::$locales[$namespace]) && isset(self::$locales[$namespace][$localeName]); |
||||
626 | } |
||||
627 | |||||
628 | /** |
||||
629 | * Retrieves an indexed array with all available content locales, |
||||
630 | * sorted by locale label. |
||||
631 | * |
||||
632 | * @return Localization_Locale[]; |
||||
633 | * @throws Localization_Exception |
||||
634 | */ |
||||
635 | public static function getContentLocales() |
||||
636 | { |
||||
637 | return self::getLocalesByNS(self::NAMESPACE_CONTENT); |
||||
638 | } |
||||
639 | |||||
640 | /** |
||||
641 | * Retrieves the names of all content locales that have been added. |
||||
642 | * @return string[] |
||||
643 | */ |
||||
644 | public static function getContentLocaleNames() |
||||
645 | { |
||||
646 | return self::getLocaleNamesByNS(self::NAMESPACE_CONTENT); |
||||
647 | } |
||||
648 | |||||
649 | /** |
||||
650 | * Retrieves all locale names available in the specified namespace. |
||||
651 | * The names are sorted alphabetically. |
||||
652 | * |
||||
653 | * @param string $namespace |
||||
654 | * @return string[] |
||||
655 | * @throws Localization_Exception |
||||
656 | */ |
||||
657 | public static function getLocaleNamesByNS(string $namespace) : array |
||||
658 | { |
||||
659 | self::requireNamespace($namespace); |
||||
660 | |||||
661 | $names = array_keys(self::$locales[$namespace]); |
||||
662 | |||||
663 | sort($names); |
||||
664 | |||||
665 | return $names; |
||||
666 | } |
||||
667 | |||||
668 | /** |
||||
669 | * Checks by the locale name if the specified locale is |
||||
670 | * available as a locale for the user data. |
||||
671 | * |
||||
672 | * @param string $localeName |
||||
673 | * @return boolean |
||||
674 | */ |
||||
675 | public static function contentLocaleExists(string $localeName) : bool |
||||
676 | { |
||||
677 | return self::localeExistsInNS($localeName, self::NAMESPACE_CONTENT); |
||||
678 | } |
||||
679 | |||||
680 | /** |
||||
681 | * Retrieves a specific content locale object by the locale name. |
||||
682 | * Note that you should check if it exists first to avoid triggering |
||||
683 | * an Exception if it does not. |
||||
684 | * |
||||
685 | * @param string $localeName |
||||
686 | * @throws Localization_Exception |
||||
687 | * @return Localization_Locale |
||||
688 | * @see Localization::contentLocaleExists() |
||||
689 | */ |
||||
690 | public static function getContentLocaleByName($localeName) : Localization_Locale |
||||
691 | { |
||||
692 | return self::getLocaleByNameNS($localeName, self::NAMESPACE_CONTENT); |
||||
693 | } |
||||
694 | |||||
695 | /** |
||||
696 | * Retrieves a locale by its name in the specified namespace. |
||||
697 | * |
||||
698 | * @param string $localeName |
||||
699 | * @param string $namespace |
||||
700 | * @throws Localization_Exception |
||||
701 | * @return Localization_Locale |
||||
702 | */ |
||||
703 | public static function getLocaleByNameNS(string $localeName, string $namespace) : Localization_Locale |
||||
704 | { |
||||
705 | self::requireNamespace($namespace); |
||||
706 | |||||
707 | if(isset(self::$locales[$namespace]) && isset(self::$locales[$namespace][$localeName])) { |
||||
708 | return self::$locales[$namespace][$localeName]; |
||||
709 | } |
||||
710 | |||||
711 | throw new Localization_Exception( |
||||
712 | 'Unknown locale in namespace', |
||||
713 | sprintf( |
||||
714 | 'The locale [%s] has not been added to the namespace [%s].', |
||||
715 | $localeName, |
||||
716 | $namespace |
||||
717 | ), |
||||
718 | self::ERROR_UNKNOWN_LOCALE_IN_NS |
||||
719 | ); |
||||
720 | } |
||||
721 | |||||
722 | /** |
||||
723 | * Retrieves the currently selected content locale. |
||||
724 | * |
||||
725 | * @return Localization_Locale |
||||
726 | * @throws Localization_Exception |
||||
727 | */ |
||||
728 | public static function getContentLocale() : Localization_Locale |
||||
729 | { |
||||
730 | return self::getSelectedLocaleByNS(self::NAMESPACE_CONTENT); |
||||
731 | } |
||||
732 | |||||
733 | /** |
||||
734 | * @return string |
||||
735 | * @throws Localization_Exception |
||||
736 | */ |
||||
737 | public static function getContentLocaleName() : string |
||||
738 | { |
||||
739 | return self::getSelectedLocaleByNS(self::NAMESPACE_CONTENT)->getName(); |
||||
740 | } |
||||
741 | |||||
742 | /** |
||||
743 | * @param Localization_Locale $locale |
||||
744 | * @return bool |
||||
745 | */ |
||||
746 | public static function isActiveAppLocale(Localization_Locale $locale) : bool |
||||
747 | { |
||||
748 | return $locale->getName() === self::getAppLocaleName(); |
||||
749 | } |
||||
750 | |||||
751 | /** |
||||
752 | * Checks whether the specified locale is the current content locale. |
||||
753 | * @param Localization_Locale $locale |
||||
754 | * @return boolean |
||||
755 | * @throws Localization_Exception |
||||
756 | */ |
||||
757 | public static function isActiveContentLocale(Localization_Locale $locale) : bool |
||||
758 | { |
||||
759 | return $locale->getName() === self::getContentLocaleName(); |
||||
760 | } |
||||
761 | |||||
762 | /** |
||||
763 | * Selects a specific content locale |
||||
764 | * @param string $localeName |
||||
765 | * @return Localization_Locale |
||||
766 | * @throws Localization_Exception |
||||
767 | */ |
||||
768 | public static function selectContentLocale(string $localeName) : Localization_Locale |
||||
769 | { |
||||
770 | return self::selectLocaleByNS($localeName, self::NAMESPACE_CONTENT); |
||||
771 | } |
||||
772 | |||||
773 | /** |
||||
774 | * Checks whether the localization has been configured entirely. |
||||
775 | * @return bool |
||||
776 | */ |
||||
777 | public static function isConfigured() : bool |
||||
778 | { |
||||
779 | return self::$configured; |
||||
780 | } |
||||
781 | |||||
782 | /** |
||||
783 | * @param Localization_Locale|null $locale |
||||
784 | * @return Localization_Translator |
||||
785 | */ |
||||
786 | public static function getTranslator(?Localization_Locale $locale=null) : Localization_Translator |
||||
787 | { |
||||
788 | if($locale !== null) |
||||
789 | { |
||||
790 | $obj = new Localization_Translator(); |
||||
791 | $obj->addSources(self::getSources()); |
||||
792 | $obj->setTargetLocale($locale); |
||||
793 | return $obj; |
||||
794 | } |
||||
795 | |||||
796 | if(!isset(self::$translator)) |
||||
797 | { |
||||
798 | $obj = new Localization_Translator(); |
||||
799 | $obj->addSources(self::getSources()); |
||||
800 | $obj->setTargetLocale(self::getAppLocale()); |
||||
801 | self::$translator = $obj; |
||||
802 | } |
||||
803 | |||||
804 | return self::$translator; |
||||
805 | } |
||||
806 | |||||
807 | public static function countContentLocales() : int |
||||
808 | { |
||||
809 | return self::countLocalesByNS(self::NAMESPACE_CONTENT); |
||||
810 | } |
||||
811 | |||||
812 | public static function countAppLocales() : int |
||||
813 | { |
||||
814 | return self::countLocalesByNS(self::NAMESPACE_APPLICATION); |
||||
815 | } |
||||
816 | |||||
817 | public static function countLocalesByNS(string $namespace) : int |
||||
818 | { |
||||
819 | self::requireNamespace($namespace); |
||||
820 | |||||
821 | if(isset(self::$locales[$namespace])) { |
||||
822 | return count(self::$locales[$namespace]); |
||||
823 | } |
||||
824 | |||||
825 | return 0; |
||||
826 | } |
||||
827 | |||||
828 | /** |
||||
829 | * @param string $namespace |
||||
830 | * @throws Localization_Exception |
||||
831 | */ |
||||
832 | protected static function requireNamespace(string $namespace) : void |
||||
833 | { |
||||
834 | if(isset(self::$locales[$namespace])) { |
||||
835 | return; |
||||
836 | } |
||||
837 | |||||
838 | throw new Localization_Exception( |
||||
839 | 'Cannot count locales in unknown namespace', |
||||
840 | sprintf( |
||||
841 | 'The namespace [%s] does not exist.', |
||||
842 | $namespace |
||||
843 | ), |
||||
844 | self::ERROR_UNKNOWN_NAMESPACE |
||||
845 | ); |
||||
846 | } |
||||
847 | |||||
848 | /** |
||||
849 | * Injects a content locales selector element into the specified |
||||
850 | * HTML QuickForm2 container. |
||||
851 | * |
||||
852 | * @param string $elementName |
||||
853 | * @param HTML_QuickForm2_Container $container |
||||
854 | * @param string $label |
||||
855 | * @return HTML_QuickForm2_Element_Select |
||||
856 | */ |
||||
857 | public static function injectContentLocalesSelector(string $elementName, HTML_QuickForm2_Container $container, string $label='') : HTML_QuickForm2_Element_Select |
||||
858 | { |
||||
859 | return self::injectLocalesSelectorNS($elementName, self::NAMESPACE_CONTENT, $container, $label); |
||||
860 | } |
||||
861 | |||||
862 | /** |
||||
863 | * Injects an app locales selector element into the specified |
||||
864 | * HTML QuickForm2 container. |
||||
865 | * |
||||
866 | * @param string $elementName |
||||
867 | * @param HTML_QuickForm2_Container $container |
||||
868 | * @param string $label |
||||
869 | * @return HTML_QuickForm2_Element_Select |
||||
870 | */ |
||||
871 | public static function injectAppLocalesSelector(string $elementName, HTML_QuickForm2_Container $container, string $label='') : HTML_QuickForm2_Element_Select |
||||
872 | { |
||||
873 | return self::injectLocalesSelectorNS($elementName, self::NAMESPACE_APPLICATION, $container, $label); |
||||
874 | } |
||||
875 | |||||
876 | /** |
||||
877 | * Injects a locales selector element into the specified |
||||
878 | * HTML QuickForm2 container, for the specified locales |
||||
879 | * namespace. |
||||
880 | * |
||||
881 | * @param string $elementName |
||||
882 | * @param string $namespace |
||||
883 | * @param HTML_QuickForm2_Container $container |
||||
884 | * @param string $label |
||||
885 | * @return HTML_QuickForm2_Element_Select |
||||
886 | * @throws Localization_Exception |
||||
887 | */ |
||||
888 | public static function injectLocalesSelectorNS(string $elementName, string $namespace, HTML_QuickForm2_Container $container, string $label='') : HTML_QuickForm2_Element_Select |
||||
889 | { |
||||
890 | if(empty($label)) { |
||||
891 | $label = t('Language'); |
||||
892 | } |
||||
893 | |||||
894 | $select = $container->addSelect($elementName); |
||||
895 | $select->setLabel($label); |
||||
896 | |||||
897 | $locales = self::getLocalesByNS($namespace); |
||||
898 | |||||
899 | foreach($locales as $locale) { |
||||
900 | $select->addOption($locale->getLabel(), $locale->getName()); |
||||
901 | } |
||||
902 | |||||
903 | return $select; |
||||
904 | } |
||||
905 | |||||
906 | /** |
||||
907 | * @var Localization_Source[] |
||||
908 | */ |
||||
909 | protected static $sources = array(); |
||||
910 | |||||
911 | /** |
||||
912 | * @var string[] |
||||
913 | */ |
||||
914 | protected static $excludeFolders = array(); |
||||
915 | |||||
916 | /** |
||||
917 | * @var string[] |
||||
918 | */ |
||||
919 | protected static $excludeFiles = array(); |
||||
920 | |||||
921 | /** |
||||
922 | * Retrieves all currently available sources. |
||||
923 | * |
||||
924 | * @return Localization_Source[] |
||||
925 | */ |
||||
926 | public static function getSources() : array |
||||
927 | { |
||||
928 | return self::$sources; |
||||
929 | } |
||||
930 | |||||
931 | public static function addExcludeFolder(string $folderName) : void |
||||
932 | { |
||||
933 | if(!in_array($folderName, self::$excludeFolders)) { |
||||
934 | self::$excludeFolders[] = $folderName; |
||||
935 | } |
||||
936 | } |
||||
937 | |||||
938 | public static function addExcludeFile(string $fileName) : void |
||||
939 | { |
||||
940 | if(!in_array($fileName, self::$excludeFiles)) { |
||||
941 | self::$excludeFiles[] = $fileName; |
||||
942 | } |
||||
943 | } |
||||
944 | |||||
945 | public static function addSourceFolder(string $alias, string $label, string $group, string $storageFolder, string $path) : Localization_Source_Folder |
||||
946 | { |
||||
947 | $source = new Localization_Source_Folder($alias, $label, $group, $storageFolder, $path); |
||||
948 | self::$sources[] = $source; |
||||
949 | |||||
950 | usort(self::$sources, function(Localization_Source $a, Localization_Source $b) { |
||||
951 | return strnatcasecmp($a->getLabel(), $b->getLabel()); |
||||
952 | }); |
||||
953 | |||||
954 | return $source; |
||||
955 | } |
||||
956 | |||||
957 | /** |
||||
958 | * Retrieves all sources grouped by their group name. |
||||
959 | * @return array |
||||
960 | */ |
||||
961 | public static function getSourcesGrouped() |
||||
962 | { |
||||
963 | $sources = self::getSources(); |
||||
964 | |||||
965 | $grouped = array(); |
||||
966 | |||||
967 | foreach($sources as $source) |
||||
968 | { |
||||
969 | $group = $source->getGroup(); |
||||
970 | |||||
971 | if(!isset($grouped[$group])) { |
||||
972 | $grouped[$group] = array(); |
||||
973 | } |
||||
974 | |||||
975 | $grouped[$group][] = $source; |
||||
976 | } |
||||
977 | |||||
978 | return $grouped; |
||||
979 | } |
||||
980 | |||||
981 | /** |
||||
982 | * Checks whether a specific source exists by its ID. |
||||
983 | * @param string $sourceID |
||||
984 | * @return boolean |
||||
985 | */ |
||||
986 | public static function sourceExists(string $sourceID) : bool |
||||
987 | { |
||||
988 | $sources = self::getSources(); |
||||
989 | foreach($sources as $source) { |
||||
990 | if($source->getID() == $sourceID) { |
||||
991 | return true; |
||||
992 | } |
||||
993 | } |
||||
994 | |||||
995 | return false; |
||||
996 | } |
||||
997 | |||||
998 | /** |
||||
999 | * Checks whether a specific source exists by its alias. |
||||
1000 | * @param string $sourceAlias |
||||
1001 | * @return boolean |
||||
1002 | */ |
||||
1003 | public static function sourceAliasExists(string $sourceAlias) : bool |
||||
1004 | { |
||||
1005 | $sources = self::getSources(); |
||||
1006 | foreach($sources as $source) { |
||||
1007 | if($source->getAlias() == $sourceAlias) { |
||||
1008 | return true; |
||||
1009 | } |
||||
1010 | } |
||||
1011 | |||||
1012 | return false; |
||||
1013 | } |
||||
1014 | |||||
1015 | /** |
||||
1016 | * Retrieves a localization source by its ID. |
||||
1017 | * |
||||
1018 | * @param string $sourceID |
||||
1019 | * @throws Localization_Exception |
||||
1020 | * @return Localization_Source |
||||
1021 | */ |
||||
1022 | public static function getSourceByID(string $sourceID) : Localization_Source |
||||
1023 | { |
||||
1024 | $sources = self::getSources(); |
||||
1025 | foreach($sources as $source) { |
||||
1026 | if($source->getID() == $sourceID) { |
||||
1027 | return $source; |
||||
1028 | } |
||||
1029 | } |
||||
1030 | |||||
1031 | throw new Localization_Exception( |
||||
1032 | 'Unknown localization source', |
||||
1033 | sprintf( |
||||
1034 | 'The source [%s] has not been added. Available soources are: [%s].', |
||||
1035 | $sourceID, |
||||
1036 | implode(', ', self::getSourceIDs()) |
||||
1037 | ) |
||||
1038 | ); |
||||
1039 | } |
||||
1040 | |||||
1041 | /** |
||||
1042 | * Retrieves a localization source by its ID. |
||||
1043 | * |
||||
1044 | * @param string $sourceAlias |
||||
1045 | * @throws Localization_Exception |
||||
1046 | * @return Localization_Source |
||||
1047 | */ |
||||
1048 | public static function getSourceByAlias(string $sourceAlias) : Localization_Source |
||||
1049 | { |
||||
1050 | $sources = self::getSources(); |
||||
1051 | foreach($sources as $source) { |
||||
1052 | if($source->getAlias() == $sourceAlias) { |
||||
1053 | return $source; |
||||
1054 | } |
||||
1055 | } |
||||
1056 | |||||
1057 | throw new Localization_Exception( |
||||
1058 | 'Unknown localization source', |
||||
1059 | sprintf( |
||||
1060 | 'The source [%s] has not been added. Available soources are: [%s].', |
||||
1061 | $sourceAlias, |
||||
1062 | implode(', ', self::getSourceAliases()) |
||||
1063 | ) |
||||
1064 | ); |
||||
1065 | } |
||||
1066 | |||||
1067 | /** |
||||
1068 | * Creates the scanner instance that is used to find |
||||
1069 | * all translatable strings in the application. |
||||
1070 | * |
||||
1071 | * @return Localization_Scanner |
||||
1072 | * @throws Localization_Exception |
||||
1073 | */ |
||||
1074 | public static function createScanner() : Localization_Scanner |
||||
1075 | { |
||||
1076 | self::requireConfiguration(); |
||||
1077 | |||||
1078 | return new Localization_Scanner(self::$storageFile); |
||||
1079 | } |
||||
1080 | |||||
1081 | public static function log(string $message) : void |
||||
0 ignored issues
–
show
The parameter
$message is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
1082 | { |
||||
1083 | // FIXME: TODO: Add this |
||||
1084 | } |
||||
1085 | |||||
1086 | /** |
||||
1087 | * Configures the localization for the application: |
||||
1088 | * sets the location of the required files and folders. |
||||
1089 | * Also updated the client library files as needed. |
||||
1090 | * |
||||
1091 | * @param string $storageFile Where to store the file analysis storage file. |
||||
1092 | * @param string $clientLibrariesFolder Where to put the client libraries and translation files. Will be created if it does not exist. Optional: if not set, client libraries will not be created. |
||||
1093 | * @throws FileHelper_Exception |
||||
1094 | * @throws Localization_Exception |
||||
1095 | */ |
||||
1096 | public static function configure(string $storageFile, string $clientLibrariesFolder='') : void |
||||
1097 | { |
||||
1098 | self::$configured = true; |
||||
1099 | |||||
1100 | self::$storageFile = $storageFile; |
||||
1101 | self::$clientFolder = $clientLibrariesFolder; |
||||
1102 | |||||
1103 | // only write the client libraries to disk if the folder |
||||
1104 | // has been specified. |
||||
1105 | if(!empty($clientLibrariesFolder)) |
||||
1106 | { |
||||
1107 | self::writeClientFiles(); |
||||
1108 | } |
||||
1109 | } |
||||
1110 | |||||
1111 | /** |
||||
1112 | * Sets a key that is used to verify whether the client |
||||
1113 | * libraries have to be refreshed. A common use is to set |
||||
1114 | * this to the application's version number to guarantee |
||||
1115 | * new texts are automatically used with each release. |
||||
1116 | * |
||||
1117 | * NOTE: Otherwise files are refreshed only when saving |
||||
1118 | * them in the editor UI. |
||||
1119 | * |
||||
1120 | * @param string $key |
||||
1121 | */ |
||||
1122 | public static function setClientLibrariesCacheKey(string $key) : void |
||||
1123 | { |
||||
1124 | if($key !== self::$clientCacheKey) { |
||||
1125 | self::$clientCacheKey = $key; |
||||
1126 | self::triggerEvent(self::EVENT_CACHE_KEY_CHANGED, array($key)); |
||||
1127 | } |
||||
1128 | } |
||||
1129 | |||||
1130 | public static function getClientLibrariesCacheKey() : string |
||||
1131 | { |
||||
1132 | return self::$clientCacheKey; |
||||
1133 | } |
||||
1134 | |||||
1135 | /** |
||||
1136 | * Sets the folder where client libraries are to be stored. |
||||
1137 | * @param string $folder |
||||
1138 | */ |
||||
1139 | public static function setClientLibrariesFolder(string $folder) : void |
||||
1140 | { |
||||
1141 | if($folder !== self::$clientFolder) { |
||||
1142 | self::$clientFolder = $folder; |
||||
1143 | self::triggerEvent(self::EVENT_CLIENT_FOLDER_CHANGED, array($folder)); |
||||
1144 | } |
||||
1145 | } |
||||
1146 | |||||
1147 | /** |
||||
1148 | * Retrieves the path to the folder in which the client |
||||
1149 | * libraries should be stored. |
||||
1150 | * |
||||
1151 | * NOTE: Can return an empty string, when this is disabled. |
||||
1152 | * |
||||
1153 | * @return string |
||||
1154 | */ |
||||
1155 | public static function getClientLibrariesFolder() : string |
||||
1156 | { |
||||
1157 | return self::$clientFolder; |
||||
1158 | } |
||||
1159 | |||||
1160 | /** |
||||
1161 | * Writes / updates the client library files on disk, |
||||
1162 | * at the location specified in the {@link Localization::configure()} |
||||
1163 | * method. |
||||
1164 | * |
||||
1165 | * @param bool $force Whether to refresh the files, even if they exist. |
||||
1166 | * @throws Localization_Exception|FileHelper_Exception |
||||
1167 | * @see Localization_ClientGenerator |
||||
1168 | */ |
||||
1169 | public static function writeClientFiles(bool $force=false) : void |
||||
0 ignored issues
–
show
The parameter
$force is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
1170 | { |
||||
1171 | self::createGenerator()->writeFiles(); |
||||
1172 | } |
||||
1173 | |||||
1174 | private static ?Localization_ClientGenerator $generator = null; |
||||
1175 | |||||
1176 | /** |
||||
1177 | * Creates a new instance of the client generator class |
||||
1178 | * that is used to write the localization files into the |
||||
1179 | * target folder on disk. |
||||
1180 | * |
||||
1181 | * @return Localization_ClientGenerator |
||||
1182 | */ |
||||
1183 | public static function createGenerator() : Localization_ClientGenerator |
||||
1184 | { |
||||
1185 | if(!isset(self::$generator)) { |
||||
1186 | self::$generator = new Localization_ClientGenerator(); |
||||
1187 | } |
||||
1188 | |||||
1189 | return self::$generator; |
||||
0 ignored issues
–
show
|
|||||
1190 | } |
||||
1191 | |||||
1192 | /** |
||||
1193 | * @return string |
||||
1194 | * @throws Localization_Exception |
||||
1195 | */ |
||||
1196 | public static function getClientFolder() : string |
||||
1197 | { |
||||
1198 | self::requireConfiguration(); |
||||
1199 | |||||
1200 | return self::$clientFolder; |
||||
1201 | } |
||||
1202 | |||||
1203 | /** |
||||
1204 | * @throws Localization_Exception |
||||
1205 | */ |
||||
1206 | protected static function requireConfiguration() : void |
||||
1207 | { |
||||
1208 | if(!self::$configured) |
||||
1209 | { |
||||
1210 | throw new Localization_Exception( |
||||
1211 | 'The localization configuration is incomplete.', |
||||
1212 | 'The configure method has not been called.', |
||||
1213 | self::ERROR_CONFIGURE_NOT_CALLED |
||||
1214 | ); |
||||
1215 | } |
||||
1216 | |||||
1217 | if(empty(self::$storageFile)) |
||||
1218 | { |
||||
1219 | throw new Localization_Exception( |
||||
1220 | 'No localization storage file set', |
||||
1221 | 'To use the scanner, the storage file has to be set using the setStorageFile method.', |
||||
1222 | self::ERROR_NO_STORAGE_FILE_SET |
||||
1223 | ); |
||||
1224 | } |
||||
1225 | |||||
1226 | if(empty(self::$sources)) |
||||
1227 | { |
||||
1228 | throw new Localization_Exception( |
||||
1229 | 'No source folders have been defined.', |
||||
1230 | 'At least one source folder has to be configured using the addSourceFolder method.', |
||||
1231 | self::ERROR_NO_SOURCES_ADDED |
||||
1232 | ); |
||||
1233 | } |
||||
1234 | } |
||||
1235 | |||||
1236 | /** |
||||
1237 | * Creates the editor instance that can be used to |
||||
1238 | * display the localization UI to edit translatable |
||||
1239 | * strings in the browser. |
||||
1240 | * |
||||
1241 | * @return Localization_Editor |
||||
1242 | * @throws Localization_Exception |
||||
1243 | */ |
||||
1244 | public static function createEditor() : Localization_Editor |
||||
1245 | { |
||||
1246 | self::requireConfiguration(); |
||||
1247 | |||||
1248 | return new Localization_Editor(); |
||||
1249 | } |
||||
1250 | |||||
1251 | /** |
||||
1252 | * Retrieves a list of all available source IDs. |
||||
1253 | * @return string[] |
||||
1254 | */ |
||||
1255 | public static function getSourceIDs() : array |
||||
1256 | { |
||||
1257 | $ids = array(); |
||||
1258 | |||||
1259 | foreach(self::$sources as $source) { |
||||
1260 | $ids[] = $source->getID(); |
||||
1261 | } |
||||
1262 | |||||
1263 | return $ids; |
||||
1264 | } |
||||
1265 | |||||
1266 | /** |
||||
1267 | * Retrieves a list of all available source aliases. |
||||
1268 | * @return string[] |
||||
1269 | */ |
||||
1270 | public static function getSourceAliases() : array |
||||
1271 | { |
||||
1272 | $aliases = array(); |
||||
1273 | |||||
1274 | foreach(self::$sources as $source) { |
||||
1275 | $aliases[] = $source->getAlias(); |
||||
1276 | } |
||||
1277 | |||||
1278 | return $aliases; |
||||
1279 | } |
||||
1280 | |||||
1281 | /** |
||||
1282 | * Resets all locales to the built-in locale. |
||||
1283 | */ |
||||
1284 | public static function reset() : void |
||||
1285 | { |
||||
1286 | self::$locales = array(); |
||||
1287 | self::$selected = array(); |
||||
1288 | |||||
1289 | self::addAppLocale(self::BUILTIN_LOCALE_NAME); |
||||
1290 | self::addContentLocale(self::BUILTIN_LOCALE_NAME); |
||||
1291 | |||||
1292 | self::selectAppLocale(self::BUILTIN_LOCALE_NAME); |
||||
1293 | self::selectContentLocale(self::BUILTIN_LOCALE_NAME); |
||||
1294 | } |
||||
1295 | |||||
1296 | /** |
||||
1297 | * Indexed array with locale names supported by the application |
||||
1298 | * @var string[] |
||||
1299 | */ |
||||
1300 | protected static $supportedLocales = array(); |
||||
1301 | |||||
1302 | /** |
||||
1303 | * Retrieves a list of all supported locales. |
||||
1304 | * |
||||
1305 | * @return string[] |
||||
1306 | * @throws FileHelper_Exception |
||||
1307 | */ |
||||
1308 | public static function getSupportedLocaleNames() : array |
||||
1309 | { |
||||
1310 | if(empty(self::$supportedLocales)) |
||||
1311 | { |
||||
1312 | self::$supportedLocales = FileHelper::createFileFinder(__DIR__.'/Localization/Locale') |
||||
0 ignored issues
–
show
The function
AppUtils\FileHelper\FileFinder::getPHPClassNames() has been deprecated: Use {@see self::getFiles()} > {@see FileCollector::PHPClassNames()} instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||
1313 | ->getPHPClassNames(); |
||||
1314 | } |
||||
1315 | |||||
1316 | return self::$supportedLocales; |
||||
1317 | } |
||||
1318 | |||||
1319 | /** |
||||
1320 | * Checks whether the specified locale is supported. |
||||
1321 | * |
||||
1322 | * @param string $localeName |
||||
1323 | * @return bool |
||||
1324 | */ |
||||
1325 | public static function isLocaleSupported(string $localeName) : bool |
||||
1326 | { |
||||
1327 | return file_exists(__DIR__.'/Localization/Locale/'.$localeName.'.php'); |
||||
1328 | } |
||||
1329 | |||||
1330 | private static ?string $version = null; |
||||
1331 | |||||
1332 | public static function getVersion() : string |
||||
1333 | { |
||||
1334 | if(isset(self::$version)) { |
||||
1335 | return self::$version; |
||||
1336 | } |
||||
1337 | |||||
1338 | $versionFile = FileInfo::factory(__DIR__.'/../version.txt'); |
||||
1339 | |||||
1340 | if($versionFile->exists()) { |
||||
1341 | self::$version = $versionFile->getContents(); |
||||
1342 | return self::$version; |
||||
0 ignored issues
–
show
|
|||||
1343 | } |
||||
1344 | |||||
1345 | self::$version = ChangelogParser::parseMarkdownFile(__DIR__.'/../changelog.md') |
||||
1346 | ->requireLatestVersion() |
||||
1347 | ->getVersionInfo() |
||||
1348 | ->getTagVersion(); |
||||
1349 | |||||
1350 | $versionFile->putContents(self::$version); |
||||
0 ignored issues
–
show
self::version of type null is incompatible with the type string expected by parameter $content of AppUtils\FileHelper\FileInfo::putContents() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
1351 | |||||
1352 | return self::$version; |
||||
0 ignored issues
–
show
|
|||||
1353 | } |
||||
1354 | } |
||||
1355 | |||||
1356 | Localization::init(); |
||||
1357 |