Skip to content

Commit

Permalink
#6328 Fixes and small improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasraoni committed Nov 30, 2021
1 parent 8e8e56d commit df02b8b
Show file tree
Hide file tree
Showing 28 changed files with 184 additions and 134 deletions.
3 changes: 1 addition & 2 deletions classes/category/DAO.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
namespace PKP\category;

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\LazyCollection;
use PKP\core\EntityDAO;
Expand Down Expand Up @@ -48,7 +47,7 @@ class DAO extends EntityDAO
*/
public function newDataObject(): Category
{
return App::make(Category::class);
return app(Category::class);
}

/**
Expand Down
3 changes: 1 addition & 2 deletions classes/category/Repository.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use APP\core\Request;
use APP\i18n\AppLocale;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\LazyCollection;
use PKP\plugins\HookRegistry;
use PKP\services\PKPSchemaService;
Expand Down Expand Up @@ -81,7 +80,7 @@ public function getMany(Collector $query): LazyCollection
/** @copydoc DAO::getCollector() */
public function getCollector(): Collector
{
return App::make(Collector::class);
return app(Collector::class);
}

/**
Expand Down
1 change: 0 additions & 1 deletion classes/cliTool/InstallTool.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ public function readParams()
$this->printTitle('installer.localeSettings');
$this->readParamOptions('locale', 'locale.primary', $installForm->supportedLocales, 'en_US');
$this->readParamOptions('additionalLocales', 'installer.additionalLocales', $installForm->supportedLocales, '', true);
$this->readParamOptions('connectionCharset', 'installer.connectionCharset', $installForm->supportedConnectionCharsets, '');

// File Settings
$this->printTitle('installer.fileSettings');
Expand Down
6 changes: 0 additions & 6 deletions classes/core/PKPContainer.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@
use Illuminate\Log\LogServiceProvider;
use Illuminate\Support\Facades\Facade;
use PKP\config\Config;
use PKP\facades\Locale;
use PKP\i18n\LocaleServiceProvider;
use PKP\i18n\translation\IsoCodesTranslationDriver;
use Sokil\IsoCodes\IsoCodesFactory;
use Throwable;

class PKPContainer extends Container
Expand Down Expand Up @@ -81,9 +78,6 @@ public function renderForConsole($output, Throwable $e)
};
});

// This singleton is necessary to keep user selected language across the application
$this->singleton(IsoCodesFactory::class, fn (self $container, array $params): IsoCodesFactory => new IsoCodesFactory(null, new IsoCodesTranslationDriver($params['locale'] ?? Locale::getLocale())));

Facade::setFacadeApplication($this);
}

Expand Down
2 changes: 1 addition & 1 deletion classes/core/PKPRequest.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ public function redirect($context = null, $page = null, $op = null, $path = null
*
* @see PKPPageRouter::getContext()
*/
public function &getContext(): Context
public function &getContext(): ?Context
{
return $this->_delegateToRouter('getContext');
}
Expand Down
2 changes: 1 addition & 1 deletion classes/emailTemplate/DAO.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ public function installEmailTemplateLocaleData(
->delete();

$previous = Locale::getMissingKeyHandler();
Locale::setMissingKeyHandler(fn (string $key): string => error_log("Missing locale key used by email: \"${key}\""));
Locale::setMissingKeyHandler(fn (string $key): string => '');
$translatedSubject = __($subject, [], $locale);
$translatedBody = __($body, [], $locale);
Locale::setMissingKeyHandler($previous);
Expand Down
3 changes: 2 additions & 1 deletion classes/facades/Locale.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@
* @method static \PKP\i18n\LocaleMetadata[] getLocales()
* @method static void installLocale(string $locale)
* @method static void uninstallLocale(string $locale)
* @method static bool isSupported(string $locale)
* @method static array getSupportedFormLocales()
* @method static array getSupportedLocales()
* @method static void setMissingKeyHandler(callable $handler)
* @method static callable getMissingKeyHandler()
* @method static \PKP\i18n\translation\LocaleBundle getBundle(?string $locale = null, bool $cacheInMemory = true)
* @method static \PKP\i18n\translation\LocaleBundle getBundle(?string $locale = null, bool $useCache = true)
* @method static string getDefaultLocale()
* @method static \Sokil\IsoCodes\Database\Countries getCountries(?string $locale = null)
* @method static \Sokil\IsoCodes\Database\Currencies getCurrencies(?string $locale = null)
Expand Down
2 changes: 1 addition & 1 deletion classes/facades/Repo.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ public static function emailTemplate(): \PKP\emailTemplate\Repository

public static function category(): \PKP\category\Repository
{
return App::make(\PKP\category\Repository::class);
return app(\PKP\category\Repository::class);
}
}
112 changes: 61 additions & 51 deletions classes/i18n/Locale.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@
use Closure;
use DateInterval;
use DirectoryIterator;
use Exception;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use PKP\config\Config;
use PKP\core\Core;
use PKP\core\PKPRequest;
use PKP\facades\Repo;
use PKP\i18n\interfaces\LocaleInterface;
Expand Down Expand Up @@ -62,9 +60,6 @@ class Locale implements LocaleInterface
/** Current locale cache */
protected ?string $locale = null;

/** @var LocaleBundle[] Locale bundles cache */
protected ?array $localeBundles = null;

/** @var int[] Folders where locales can be found, where key = path and value = loading priority */
protected array $paths = [];

Expand All @@ -86,12 +81,14 @@ class Locale implements LocaleInterface
/** @var string[]|null Supported locales cache, where key = locale and value = name */
protected ?array $supportedLocales = null;

/**
* @var array[]|null Discovered locale files by path and locale.
* First dimension = key represents a path and the value the second dimension
* Second dimension = key represents a locale and the value a list of paths for the locale files
*/
protected ?array $localeFiles = null;
/** @var LocaleBundle[] Keeps a cache for the locale bundles */
protected array $localeBundles = [];

/** @var string[][][]|null Discovered locale files, keyed first by base path and then by locale */
protected array $localeFiles = [];

/** Keeps cached data related only to the current locale */
protected array $cache = [];

/**
* @copy \Illuminate\Contracts\Translation\Translator::get()
Expand Down Expand Up @@ -123,7 +120,7 @@ public function getLocale(): string
$locale = $request->getUserVar('setLocale')
?: (SessionManager::hasSession() ? SessionManager::getManager()->getUserSession()->getSessionVar('currentLocale') : null)
?: $request->getCookieVar('currentLocale');
$this->setLocale(in_array($locale, array_keys($this->getSupportedLocales())) ? $locale : $this->getPrimaryLocale());
$this->setLocale($locale);
return $this->locale;
})();
}
Expand All @@ -133,8 +130,10 @@ public function getLocale(): string
*/
public function setLocale($locale): void
{
if (!$this->isLocaleValid($locale) || !in_array($locale, array_keys($this->getSupportedLocales()))) {
throw new InvalidArgumentException("Invalid locale \"${locale}\", default locale restored");
if (!$this->isLocaleValid($locale) || !$this->isSupported($locale)) {
if ($locale) {
error_log((string) new InvalidArgumentException("Invalid/unsupported locale \"${locale}\", default locale restored"));
}
$locale = $this->getPrimaryLocale();
}

Expand Down Expand Up @@ -174,7 +173,7 @@ public function registerPath(string $path, int $priority = 0): void
$realPath = $path->getRealPath();
if (($this->paths[$realPath] ?? null) !== $priority) {
$this->paths[$realPath] = $priority;
$this->localeBundles = null;
$this->localeBundles = [];
$this->locales = null;
}
}
Expand All @@ -187,7 +186,7 @@ public function registerLoader(callable $fileLoader, int $priority = 0): void
// Invalidate the loaded bundles cache
if (array_search($fileLoader, $this->loaders[$priority] ?? [], true) === false) {
$this->loaders[$priority][] = $fileLoader;
$this->localeBundles = null;
$this->localeBundles = [];
ksort($this->loaders, SORT_NUMERIC);
}
}
Expand All @@ -197,7 +196,7 @@ public function registerLoader(callable $fileLoader, int $priority = 0): void
*/
public function isLocaleValid(?string $locale): bool
{
return !empty($locale) && preg_match(LocaleInterface::LOCALE_EXPRESSION, $locale) && file_exists(Core::getBaseDir() . "/locale/${locale}");
return !empty($locale) && preg_match(LocaleInterface::LOCALE_EXPRESSION, $locale);
}

/**
Expand Down Expand Up @@ -225,6 +224,7 @@ function () {
}
}
}
ksort($locales);
return $locales;
}
);
Expand Down Expand Up @@ -255,36 +255,38 @@ public function uninstallLocale(string $locale): void
Repo::emailTemplate()->dao->deleteDefaultEmailTemplatesByLocale($locale);
}

/**
* Retrieves whether the given locale is supported
*/
public function isSupported(string $locale): bool
{
static $locales;
$locales ??= SessionManager::isDisabled()
? array_keys($this->getLocales())
: (($context = $this->_getRequest()->getContext()) ? $context->getSupportedLocales() : $this->_getRequest()->getSite()->getSupportedLocales());
return in_array($locale, $locales);
}

/**
* @copy LocaleInterface::getSupportedFormLocales()
*/
public function getSupportedFormLocales(): array
{
return $this->supportedFormLocales ??= array_map(
fn (LocaleMetadata $locale) => $locale->getDisplayName(),
SessionManager::isDisabled() ? $this->getLocales() : array_combine(
$locales = ($context = $this->_getRequest()->getContext())
? $context->getSupportedFormLocales()
: $this->_getRequest()->getSite()->getSupportedLocales(),
$locales
)
);
return $this->supportedFormLocales ??= (fn(): array => SessionManager::isDisabled()
? array_map(fn(LocaleMetadata $locale) => $locale->locale, $this->getLocales())
: (($context = $this->_getRequest()->getContext()) ? $context->getSupportedFormLocaleNames() : $this->_getRequest()->getSite()->getSupportedLocaleNames())
)();
}

/**
* @copy LocaleInterface::getSupportedLocales()
*/
public function getSupportedLocales(): array
{
return $this->supportedLocales ??= array_map(
fn (LocaleMetadata $locale) => $locale->getDisplayName(),
SessionManager::isDisabled() ? $this->getLocales() : array_combine(
$locales = ($context = $this->_getRequest()->getContext())
? $context->getSupportedLocales()
: $this->_getRequest()->getSite()->getSupportedLocales(),
$locales
)
);
return $this->supportedLocales ??= (fn(): array => SessionManager::isDisabled()
? array_map(fn(LocaleMetadata $locale) => $locale->locale, $this->getLocales())
: ($this->_getRequest()->getContext() ?? $this->_getRequest()->getSite())->getSupportedLocaleNames()
)();
}

/**
Expand All @@ -306,25 +308,20 @@ public function getMissingKeyHandler(): ?callable
/**
* @copy LocaleInterface::getBundle()
*/
public function getBundle(?string $locale = null, bool $cacheInMemory = true): LocaleBundle
public function getBundle(?string $locale = null, bool $useCache = true): LocaleBundle
{
$locale ??= $this->getLocale();
if (!isset($this->localeBundles[$locale])) {
$getter = function () use ($locale): LocaleBundle {
$bundle = [];
foreach ($this->paths as $folder => $priority) {
$bundle += $this->_getLocaleFiles($folder, $locale, $priority);
}
foreach ($this->loaders as $loader) {
$loader($locale, $bundle);
}
$localeBundle = new LocaleBundle($locale, $bundle);
if (!$cacheInMemory) {
return $localeBundle;
}
$this->localeBundles[$locale] = $localeBundle;
}

return $this->localeBundles[$locale];
return new LocaleBundle($locale, $bundle);
};
return $useCache ? $this->localeBundles[$locale] ??= $getter() : $getter();
}

/**
Expand All @@ -340,34 +337,33 @@ public function getDefaultLocale(): string
*/
public function getCountries(?string $locale = null): Countries
{
return $this->_getIsoCodes($locale)->getCountries();
return $this->_getLocaleCache(__METHOD__, $locale, fn () => $this->_getIsoCodes($locale)->getCountries());
}

/**
* @copy LocaleInterface::getCurrencies()
*/
public function getCurrencies(?string $locale = null): Currencies
{
return $this->_getIsoCodes($locale)->getCurrencies();
return $this->_getLocaleCache(__METHOD__, $locale, fn () => $this->_getIsoCodes($locale)->getCurrencies());
}

/**
* @copy LocaleInterface::getLanguages()
*/
public function getLanguages(?string $locale = null): LanguagesInterface
{
return $this->_getIsoCodes($locale)->getLanguages();
return $this->_getLocaleCache(__METHOD__, $locale, fn () => $this->_getIsoCodes($locale)->getLanguages());
}

/**
* @copy LocaleInterface::getScripts()
*/
public function getScripts(?string $locale = null): Scripts
{
return $this->_getIsoCodes($locale)->getScripts();
return $this->_getLocaleCache(__METHOD__, $locale, fn () => $this->_getIsoCodes($locale)->getScripts());
}


/**
* Translates the texts
*/
Expand All @@ -384,10 +380,24 @@ protected function translate(string $key, ?int $number, array $params, ?string $
return $value;
}

error_log((string) (new Exception("Missing locale key \"${key}\" for the locale \"${locale}\"")));
error_log("Missing locale key \"${key}\" for the locale \"${locale}\"");
return is_callable($this->missingKeyHandler) ? ($this->missingKeyHandler)($key) : '##' . htmlentities($key) . '##';
}

/**
* Retrieves a cached item only if it belongs to the current locale. If it doesn't exist, the getter will be called
*/
private function _getLocaleCache(string $key, ?string $locale, callable $getter)
{
if (($locale ??= $this->getLocale()) !== $this->getLocale()) {
return $getter();
}
if (!isset($this->cache[$key][$locale])) {
// Ensures the previous cache is cleared
$this->cache[$key] = [$locale => $getter()];
}
return $this->cache[$key][$locale];
}

/**
* Given a locale folder, retrieves all locale files (.po)
Expand Down
7 changes: 5 additions & 2 deletions classes/i18n/LocaleMetadata.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
namespace PKP\i18n;

use DomainException;
use Gettext\Translation;
use PKP\core\ExportableTrait;
use PKP\core\PKPString;
use PKP\facades\Locale;
use PKP\i18n\interfaces\LocaleInterface;
use PKP\i18n\translation\LocaleBundle;
use PKP\i18n\translation\LocaleFile;
use Sokil\IsoCodes\Database\Languages\Language;

class LocaleMetadata
Expand Down Expand Up @@ -115,9 +118,9 @@ public function getCompletenessRatio(string $referenceLocale = null): float
/**
* Retrieves whether the locale can be considered complete respecting a threshold level of completeness
*/
public function isComplete(float $minimumThreshold = 0.9): bool
public function isComplete(float $minimumThreshold = 0.9, ?string $referenceLocale = null): bool
{
return $this->getCompletenessRatio() >= $minimumThreshold;
return $this->getCompletenessRatio($referenceLocale) >= $minimumThreshold;
}

/**
Expand Down
Loading

0 comments on commit df02b8b

Please sign in to comment.