93 lines
3.0 KiB
PHP
93 lines
3.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* @defgroup i18n I18N
|
|
* Implements localization concerns such as locale files, time zones, and country lists.
|
|
*/
|
|
|
|
/**
|
|
* @file classes/i18n/translation/IsoCodesTranslationDriver.php
|
|
*
|
|
* Copyright (c) 2014-2021 Simon Fraser University
|
|
* Copyright (c) 2000-2021 John Willinsky
|
|
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
|
*
|
|
* @class IsoCodesTranslationDriver
|
|
*
|
|
* @ingroup i18n
|
|
*
|
|
* @brief Translation provider for the IsoCodes package, faster and optimized to not keep items in memory
|
|
*/
|
|
|
|
namespace PKP\i18n\translation;
|
|
|
|
use APP\core\Application;
|
|
use DateInterval;
|
|
use DomainException;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use PKP\i18n\interfaces\LocaleInterface;
|
|
use Sokil\IsoCodes\TranslationDriver\TranslationDriverInterface;
|
|
|
|
class IsoCodesTranslationDriver implements TranslationDriverInterface
|
|
{
|
|
/** @var string Max lifetime for the cache, a new cache file is created whenever the translation file is modified */
|
|
protected const MAX_CACHE_LIFETIME = '1 year';
|
|
|
|
protected ?Translator $translator = null;
|
|
protected string $locale;
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public function __construct(string $locale)
|
|
{
|
|
$this->setLocale($locale);
|
|
}
|
|
|
|
/**
|
|
* Setups the translator
|
|
*/
|
|
public function configureDirectory(string $isoNumber, string $directory): void
|
|
{
|
|
if (!preg_match(LocaleInterface::LOCALE_EXPRESSION, $this->locale, $matches)) {
|
|
throw new DomainException("Invalid locale \"{$this->locale}\"");
|
|
}
|
|
$locale = (object) [
|
|
'language' => $matches['language'],
|
|
'country' => $matches['country'] ?? null,
|
|
'script' => $matches['script'] ?? null
|
|
];
|
|
$locales = [$this->locale, ...($locale->script ? [$locale->language . '@' . $locale->script] : []), $locale->language];
|
|
// Attempts to find the best locale
|
|
foreach ($locales as $locale) {
|
|
$path = "{$directory}/{$locale}/LC_MESSAGES/{$isoNumber}.mo";
|
|
if (file_exists($path)) {
|
|
// Check if it's installed before caching the ISO codes (huge dataset), just to avoid a slow installation page
|
|
$loader = fn () => Translator::createFromTranslationsArray(LocaleFile::loadArray($path, Application::isInstalled()));
|
|
$key = __METHOD__ . static::MAX_CACHE_LIFETIME . $path . filemtime($path);
|
|
$expiration = DateInterval::createFromDateString(static::MAX_CACHE_LIFETIME);
|
|
$this->translator = Application::isInstalled() ? Cache::remember($key, $expiration, $loader) : $loader();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setup the driver locale
|
|
*/
|
|
public function setLocale(string $locale): void
|
|
{
|
|
$this->locale = $locale;
|
|
}
|
|
|
|
/**
|
|
* Attempts to translate an entry
|
|
*/
|
|
public function translate(string $isoNumber, string $message): string
|
|
{
|
|
return $this->translator?->getSingular($message) ?: $message;
|
|
}
|
|
}
|