Skip to content

Commit

Permalink
#10616 Add ThemePlugin function to get localized theme opt… (#10654)
Browse files Browse the repository at this point in the history
* #10616 Add ThemePlugin function to get localized theme option value

* #10616 Improve method description in LocalizedData trait
  • Loading branch information
NateWr authored Dec 5, 2024
1 parent b2b3d71 commit d2fad34
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 63 deletions.
70 changes: 7 additions & 63 deletions classes/core/DataObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

use APP\core\Application;
use Exception;
use PKP\core\traits\LocalizedData;
use PKP\db\DAO;
use PKP\db\DAORegistry;
use PKP\facades\Locale;
Expand All @@ -33,6 +34,8 @@
*/
class DataObject
{
use LocalizedData;

/** @var array Array of object data */
public array $_data = [];

Expand All @@ -51,19 +54,6 @@ class DataObject
/** @var mixed Whether injection adapters have already been loaded from the database */
public mixed $_injectionAdaptersLoaded = false;

/** @var Conversion table for locales */
public array $_localesTable = [
'be@cyrillic' => 'be',
'bs' => 'bs_Latn',
'fr_FR' => 'fr',
'nb' => 'nb_NO',
'sr@cyrillic' => 'sr_Cyrl',
'sr@latin' => 'sr_Latn',
'uz@cyrillic' => 'uz',
'uz@latin' => 'uz_Latn',
'zh_CN' => 'zh_Hans',
];

/**
* Constructor
*/
Expand All @@ -80,57 +70,11 @@ public function __construct()
*/
public function getLocalizedData(string $key, ?string $preferredLocale = null, ?string &$selectedLocale = null): mixed
{
foreach ($this->getLocalePrecedence($preferredLocale) as $locale) {
$value = & $this->getData($key, $locale);
if (!empty($value)) {
$selectedLocale = $locale;
return $value;
}
unset($value);
$value = $this->getData($key);
if (!is_array($value)) {

This comment has been minimized.

Copy link
@bozana

bozana Dec 6, 2024

Collaborator

@NateWr, is there a case when we have localized data that is not an array?

return $value;
}

// Fallback: Get the first available piece of data.
$data = $this->getData($key, null);
foreach ((array) $data as $locale => $dataValue) {
if (!empty($dataValue)) {
$selectedLocale = $locale;
return $dataValue;
}
}

return null;
}

/**
* Get the locale precedence order for object in the following order
*
* 1. Preferred Locale if provided
* 2. User's current local
* 3. Object's default locale if set
* 4. Context's primary locale if context available
* 5. Site's primary locale
*/
public function getLocalePrecedence(?string $preferredLocale = null): array
{
$request = Application::get()->getRequest();

return array_unique(
array_filter([
$preferredLocale ?? Locale::getLocale(),
$this->_localesTable[$preferredLocale ?? Locale::getLocale()] ?? null,
$this->getDefaultLocale(),
$request->getContext()?->getPrimaryLocale(),
$request->getSite()->getPrimaryLocale(),
])
);
}

/**
* Get the default locale for object
*/
public function getDefaultLocale(): ?string
{
return null;
return $this->getBestLocalizedData((array) $this->getData($key), $preferredLocale, $selectedLocale);
}

/**
Expand Down
98 changes: 98 additions & 0 deletions classes/core/traits/LocalizedData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

/**
* @file classes/core/traits/LocalizedData.php
*
* Copyright (c) 2014-2024 Simon Fraser University
* Copyright (c) 2000-2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class LocalizedData
*
* @ingroup core_traits
*
* @brief A trait for getting localized data from assoc arrays
*
*/

namespace PKP\core\traits;

use APP\core\Application;
use PKP\facades\Locale;

trait LocalizedData
{
/** @var Conversion table for locales */
public array $_localesTable = [
'be@cyrillic' => 'be',
'bs' => 'bs_Latn',
'fr_FR' => 'fr',
'nb' => 'nb_NO',
'sr@cyrillic' => 'sr_Cyrl',
'sr@latin' => 'sr_Latn',
'uz@cyrillic' => 'uz',
'uz@latin' => 'uz_Latn',
'zh_CN' => 'zh_Hans',
];

/**
* Get a localized value from a multilingual data array
*
* @param array $data An assoc array with localized data, where each
* key is the localeKey. Example: ['en' => 'Journal', 'de' => 'Zeitschrift']
*/
protected function getBestLocalizedData(array $data, ?string $preferredLocale = null, ?string &$selectedLocale = null): mixed
{
foreach ($this->getLocalePrecedence($preferredLocale) as $locale) {
if (!empty($data[$locale])) {
$selectedLocale = $locale;
return $data[$locale];
}
}

// Fallback: Get the first available piece of data.
foreach ($data as $locale => $dataValue) {
if (!empty($dataValue)) {
$selectedLocale = $locale;
return $dataValue;
}
}

return null;
}

/**
* Get the locale precedence order for object data in the following order
*
* 1. Preferred Locale if provided
* 2. User's current local
* 3. Object's default locale if set
* 4. Context's primary locale if context available
* 5. Site's primary locale
*/
public function getLocalePrecedence(?string $preferredLocale = null): array
{
$request = Application::get()->getRequest();

return array_unique(
array_filter([
$preferredLocale ?? Locale::getLocale(),
$this->_localesTable[$preferredLocale ?? Locale::getLocale()] ?? null,
$this->getDefaultLocale(),
$request->getContext()?->getPrimaryLocale(),
$request->getSite()->getPrimaryLocale(),
])
);
}

/**
* Get the default locale
*
* Override this method in the object which uses this trait, if the object
* has a default locale. Most objects don't have a default locale.
*/
public function getDefaultLocale(): ?string
{
return null;
}
}
11 changes: 11 additions & 0 deletions classes/plugins/ThemePlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@
use PKP\core\Core;
use PKP\core\PKPApplication;
use PKP\core\PKPSessionGuard;
use PKP\core\traits\LocalizedData;
use PKP\db\DAORegistry;

define('LESS_FILENAME_SUFFIX', '.less');
define('THEME_OPTION_PREFIX', 'themeOption_');

abstract class ThemePlugin extends LazyLoadPlugin
{
use LocalizedData;

/**
* Collection of styles
*
Expand Down Expand Up @@ -490,6 +493,14 @@ public function getOption($name)
return $option->default ?? null;
}

/**
* Get the localized value of an option
*/
public function getLocalizedOption(string $name, string $preferredLocale = null, string &$selectedLocale = null): mixed
{
return $this->getBestLocalizedData($this->getOption($name), $preferredLocale, $selectedLocale);
}

/**
* Get an option's configuration settings
*
Expand Down

0 comments on commit d2fad34

Please sign in to comment.