|
29 | 29 | use Illuminate\Support\Facades\Cache;
|
30 | 30 | use InvalidArgumentException;
|
31 | 31 | use PKP\config\Config;
|
| 32 | +use PKP\core\Core; |
32 | 33 | use PKP\core\PKPRequest;
|
33 | 34 | use PKP\facades\Repo;
|
34 | 35 | use PKP\i18n\interfaces\LocaleInterface;
|
@@ -95,6 +96,9 @@ class Locale implements LocaleInterface
|
95 | 96 | /** Keeps cached data related only to the current locale */
|
96 | 97 | protected array $cache = [];
|
97 | 98 |
|
| 99 | + /** @var string[]|null Available submission locales cache, where key = locale and value = name */ |
| 100 | + protected ?array $submissionLocaleNames = null; |
| 101 | + |
98 | 102 | /**
|
99 | 103 | * @copy \Illuminate\Contracts\Translation\Translator::get()
|
100 | 104 | *
|
@@ -204,6 +208,14 @@ public function isLocaleValid(?string $locale): bool
|
204 | 208 | return !empty($locale) && preg_match(LocaleInterface::LOCALE_EXPRESSION, $locale);
|
205 | 209 | }
|
206 | 210 |
|
| 211 | + /** |
| 212 | + * @copy LocaleInterface::isSubmissionLocaleValid() |
| 213 | + */ |
| 214 | + public function isSubmissionLocaleValid(?string $locale): bool |
| 215 | + { |
| 216 | + return !empty($locale) && preg_match(LocaleInterface::LOCALE_EXPRESSION_SUBMISSION, $locale); |
| 217 | + } |
| 218 | + |
207 | 219 | /**
|
208 | 220 | * @copy LocaleInterface::getMetadata()
|
209 | 221 | */
|
@@ -405,6 +417,38 @@ public function getUiTranslator(): UITranslator
|
405 | 417 | return new UITranslator($locale, $this->paths, $localeBundleCacheKey);
|
406 | 418 | }
|
407 | 419 |
|
| 420 | + /** |
| 421 | + * Get appropriately localized display names for submission locales to array |
| 422 | + * If $filterByLocales empty, return all languages. |
| 423 | + * Add '*' (= in English) to display name if no translation available |
| 424 | + * |
| 425 | + * @param array $filterByLocales Optional list of locale codes/code-name-pairs to filter |
| 426 | + * @param ?string $displayLocale Optional display locale |
| 427 | + * |
| 428 | + * @return array The list of locales with formatted display name |
| 429 | + */ |
| 430 | + public function getSubmissionLocaleDisplayNames(array $filterByLocales = [], ?string $displayLocale = null): array |
| 431 | + { |
| 432 | + $convDispLocale = $this->convertSubmissionLocaleCode($displayLocale ?: $this->getLocale()); |
| 433 | + return collect($this->_getSubmissionLocaleNames()) |
| 434 | + ->when(!empty(count($filterByLocales)), |
| 435 | + fn ($sln) => $sln->intersectByKeys(array_is_list($filterByLocales) ? array_flip(array_filter($filterByLocales)) : $filterByLocales)) |
| 436 | + ->when($convDispLocale !== 'en', fn ($sln) => $sln->map(function ($nameEn, $l) use ($convDispLocale) { |
| 437 | + $cl = $this->convertSubmissionLocaleCode($l); |
| 438 | + $dn = locale_get_display_name($cl, $convDispLocale); |
| 439 | + return ($dn && $dn !== $cl) ? $dn : "*$nameEn"; |
| 440 | + })) |
| 441 | + ->toArray(); |
| 442 | + } |
| 443 | + |
| 444 | + /** |
| 445 | + * Convert submission locale code |
| 446 | + */ |
| 447 | + public function convertSubmissionLocaleCode(string $locale): string |
| 448 | + { |
| 449 | + return str_replace(['@cyrillic', '@latin'], ['_Cyrl', '_Latn'], $locale); |
| 450 | + } |
| 451 | + |
408 | 452 | /**
|
409 | 453 | * Get the filtered locales by locale codes
|
410 | 454 | *
|
@@ -513,4 +557,29 @@ private function _getSupportedLocales(): array
|
513 | 557 | ?? array_map(fn (LocaleMetadata $locale) => $locale->locale, $this->getLocales());
|
514 | 558 | return $this->supportedLocales = array_combine($locales, $locales);
|
515 | 559 | }
|
| 560 | + |
| 561 | + /** |
| 562 | + * Get Weblate submission languages to array |
| 563 | + * Combine app's language names with weblate's in English. |
| 564 | + * Weblate's names override app's if same locale key |
| 565 | + * |
| 566 | + * @return string[] |
| 567 | + */ |
| 568 | + private function _getSubmissionLocaleNames(): array |
| 569 | + { |
| 570 | + return $this->submissionLocaleNames ??= (function (): array { |
| 571 | + $file = Core::getBaseDir() . '/' . PKP_LIB_PATH . '/lib/weblateLanguages/languages.json'; |
| 572 | + $key = __METHOD__ . self::MAX_CACHE_LIFETIME . sha1($file); |
| 573 | + $expiration = DateInterval::createFromDateString(static::MAX_CACHE_LIFETIME); |
| 574 | + return Cache::remember($key, $expiration, fn (): array => collect($this->getLocales()) |
| 575 | + ->map(function (LocaleMetadata $lm, string $l): string { |
| 576 | + $cl = $this->convertSubmissionLocaleCode($l); |
| 577 | + $n = locale_get_display_name($cl, 'en'); |
| 578 | + return ($n && $n !== $cl) ? $n : $lm->getDisplayName('en', true); |
| 579 | + }) |
| 580 | + ->merge(json_decode(file_get_contents($file), true) ?: []) |
| 581 | + ->sortKeys() |
| 582 | + ->toArray()); |
| 583 | + })(); |
| 584 | + } |
516 | 585 | }
|
0 commit comments