Files
OSJ/lib/pkp/classes/i18n/translation/IsoCodesTranslationDriver.php
CHIEFSOFT\ameye df3a033196 first commit
2024-06-08 17:09:23 -04:00

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;
}
}