mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2025-01-26 04:31:14 +01:00
RETROTEC-AG/OpenXE#17 Locale des GUI-Users ermitteln
This commit is contained in:
parent
a9f3292f8f
commit
dc58045423
90
classes/Components/I18n/Bootstrap.php
Normal file
90
classes/Components/I18n/Bootstrap.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n;
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Components\Http\Request;
|
||||
use Xentral\Components\Http\Session\Session;
|
||||
use Xentral\Core\DependencyInjection\ServiceContainer;
|
||||
|
||||
final class Bootstrap
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function registerServices(): array
|
||||
{
|
||||
return [
|
||||
'Localization' => 'onInitLocalization',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This is the factory for the Localization object.
|
||||
*
|
||||
* @param ServiceContainer $container
|
||||
*
|
||||
* @return Localization
|
||||
*/
|
||||
public static function onInitLocalization(ServiceContainer $container): Localization
|
||||
{
|
||||
/** @var Request $request */
|
||||
$request = $container->get('Request');
|
||||
/** @var Session $session */
|
||||
$session = $container->get('Session');
|
||||
/** @var \erpooSystem $app */
|
||||
$app = $container->get('LegacyApplication');
|
||||
/** @var Database $db */
|
||||
$db = $container->get('Database');
|
||||
|
||||
|
||||
// Get User
|
||||
$usersettings = [];
|
||||
if ($user = $app->User) {
|
||||
// Get User's address from user
|
||||
$userAddress = $db->fetchRow(
|
||||
$db->select()->cols(['*'])->from('adresse')->where('id=:id'),
|
||||
['id' => $user->GetAdresse()]
|
||||
);
|
||||
|
||||
|
||||
// Get language from user account and normalize to 3-letter-code and 2-letter-code
|
||||
$userSprache = strtolower($user->GetSprache());
|
||||
$userLang2 = null;
|
||||
$userLang3 = null;
|
||||
foreach ((new Iso639(new Iso639\Filter\CentralEurope())) as $key => $val) {
|
||||
if (array_filter($val, function ($str) use ($userSprache) {
|
||||
return $str && (strtolower($str) == $userSprache);
|
||||
})) {
|
||||
$userLang2 = $val[Iso639\Key::ALPHA_2];
|
||||
$userLang3 = $val[Iso639\Key::ALPHA_3];
|
||||
}
|
||||
}
|
||||
if ($userLang3) {
|
||||
$usersettings['language'] = $userLang3;
|
||||
}
|
||||
|
||||
|
||||
// Get region from user account and normalize to 2-letter-code
|
||||
$userLand = strtolower($userAddress['land'] ?? '');
|
||||
$userRegion = null;
|
||||
foreach ((new Iso3166(new Iso3166\Filter\CentralEurope())) as $key => $val) {
|
||||
if (array_filter($val, function ($str) use ($userLand) {
|
||||
return $str && (strtolower($str) == $userLand);
|
||||
})) {
|
||||
$userRegion = $val[Iso3166\Key::ALPHA_2];
|
||||
}
|
||||
}
|
||||
if ($userLang2 && $userRegion) {
|
||||
$usersettings['locale'] = "{$userLang2}_{$userRegion}";
|
||||
}
|
||||
}
|
||||
|
||||
// Create Localization object
|
||||
return new Localization($request, $session, $usersettings);
|
||||
}
|
||||
}
|
69
classes/Components/I18n/Dataaccess/ArrayAccessTrait.php
Normal file
69
classes/Components/I18n/Dataaccess/ArrayAccessTrait.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
/**
|
||||
* Provides array access functions to the data provider.
|
||||
*
|
||||
* @see \ArrayAccess
|
||||
* @see DataProvider
|
||||
* @see DataProviderInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
trait ArrayAccessTrait
|
||||
{
|
||||
/**
|
||||
* Whether an offset exists.
|
||||
*
|
||||
* @param string $offset
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset): bool
|
||||
{
|
||||
return array_key_exists($offset, $this->DataProvider_DATA);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Offset to retrieve.
|
||||
*
|
||||
* @param string $offset
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function offsetGet($offset): array
|
||||
{
|
||||
return $this->DataProvider_DATA[$offset];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Assign a value to the specified offset.
|
||||
* No function since data set is read only.
|
||||
*
|
||||
* @param string $offset
|
||||
* @param array $value
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
// $this->DataProvider_DATA[$offset]=$value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Unset an offset.
|
||||
* No function since data set is read only.
|
||||
*
|
||||
* @param string $offset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
// unset($this->DataProvider_DATA[$offset]);
|
||||
}
|
||||
}
|
26
classes/Components/I18n/Dataaccess/CountableTrait.php
Normal file
26
classes/Components/I18n/Dataaccess/CountableTrait.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
/**
|
||||
* Provides countable functions to the data provider.
|
||||
*
|
||||
* @see \Countable
|
||||
* @see DataProvider
|
||||
* @see DataProviderInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
trait CountableTrait
|
||||
{
|
||||
/**
|
||||
* Counts the number of records in the private $data array.
|
||||
*
|
||||
* @return int Number of records
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->DataProvider_DATA);
|
||||
}
|
||||
}
|
76
classes/Components/I18n/Dataaccess/DataFilter.php
Normal file
76
classes/Components/I18n/Dataaccess/DataFilter.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract filter class.
|
||||
*
|
||||
* @see DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Pointer to next filter in chain.
|
||||
*
|
||||
* @var DataFilterInterface
|
||||
*/
|
||||
private $nextFilter = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::then()
|
||||
*/
|
||||
public function then(DataFilterInterface $filter): DataFilterInterface
|
||||
{
|
||||
if (!$this->nextFilter) {
|
||||
$this->nextFilter = $filter;
|
||||
} else {
|
||||
$this->nextFilter->then($filter);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Applies the filter to the data and executes the next filter
|
||||
* if present.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::__invoke()
|
||||
*/
|
||||
public function __invoke(array $data): array
|
||||
{
|
||||
// echo get_called_class()."::__invoke(\$data)".PHP_EOL;
|
||||
|
||||
$filteredData = [];
|
||||
foreach ($data as $key => $val) {
|
||||
if ($this->selectItem($key, $val)) {
|
||||
$filteredData[$key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->nextFilter) {
|
||||
$filteredData = ($this->nextFilter)($filteredData);
|
||||
}
|
||||
return $filteredData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if the current item is to be selected for
|
||||
* the dataset.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $val
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function selectItem(&$key, &$val): bool;
|
||||
}
|
34
classes/Components/I18n/Dataaccess/DataFilterInterface.php
Normal file
34
classes/Components/I18n/Dataaccess/DataFilterInterface.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
|
||||
/**
|
||||
* Filter Interface.
|
||||
*
|
||||
* @see DataFilter
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
interface DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Add a filter to the end of the filter chain.
|
||||
*
|
||||
* @param DataFilterInterface $filter Filter to add
|
||||
*
|
||||
* @return DataFilterInterface Start of filter chain
|
||||
*/
|
||||
function then(DataFilterInterface $filter): DataFilterInterface;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Applies the filter to the data and executes the next filter
|
||||
* if present.
|
||||
*
|
||||
* @see \Ruga\I18n\Dataaccess\DataFilterInterface::__invoke()
|
||||
*/
|
||||
function __invoke(array $data): array;
|
||||
}
|
121
classes/Components/I18n/Dataaccess/DataProvider.php
Normal file
121
classes/Components/I18n/Dataaccess/DataProvider.php
Normal file
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use Iterator;
|
||||
|
||||
/**
|
||||
* Abstract implementation of a general data provider.
|
||||
*
|
||||
* @see DataProviderInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class DataProvider implements Countable, Iterator, ArrayAccess, DataProviderInterface
|
||||
{
|
||||
use CountableTrait;
|
||||
use IteratorTrait;
|
||||
use ArrayAccessTrait;
|
||||
|
||||
|
||||
/**
|
||||
* Holds filtered data.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $DataProvider_DATA = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the object and apply data filter.
|
||||
*
|
||||
* @param DataFilterInterface|null $filter
|
||||
*/
|
||||
public function __construct(DataFilterInterface $filter = null)
|
||||
{
|
||||
if ($filter) {
|
||||
$this->DataProvider_DATA = $filter($this->getOriginalData());
|
||||
} else {
|
||||
$this->DataProvider_DATA = $this->getOriginalData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the original data array).
|
||||
* Raw data before any filtering takes place.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getOriginalData(): array;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array suitable for select fields.
|
||||
* The key of the filtered data set is used as key of the
|
||||
* array and $desiredName field is used as value.
|
||||
*
|
||||
* @param string $desiredName
|
||||
*
|
||||
* @return array;
|
||||
*/
|
||||
public function getMultiOptions($desiredName = 'NAME_deu'): array
|
||||
{
|
||||
$a = [];
|
||||
foreach ($this as $key => $l) {
|
||||
$a[$key] = $l[$desiredName];
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the field $desiredName from the record $id.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param string $desiredName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getString($id, $desiredName): string
|
||||
{
|
||||
if (!isset($this[$id])) {
|
||||
throw new Exception\OutOfRangeException("Index '{$id}' not found");
|
||||
}
|
||||
$d = $this[$id];
|
||||
if ($desiredName) {
|
||||
if ($desiredName == 'POST') {
|
||||
return strtoupper($this->getString($id, 'NAME_eng'));
|
||||
}
|
||||
return $d[$desiredName];
|
||||
}
|
||||
throw new Exception\OutOfRangeException("No '{$desiredName}' data for '{$id}'");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the item at position $id.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData($id)
|
||||
{
|
||||
if (empty($id)) {
|
||||
return null;
|
||||
}
|
||||
if (!isset($this[$id])) {
|
||||
throw new Exception\OutOfRangeException("Index '{$id}' not found.");
|
||||
}
|
||||
return $this[$id];
|
||||
}
|
||||
}
|
49
classes/Components/I18n/Dataaccess/DataProviderInterface.php
Normal file
49
classes/Components/I18n/Dataaccess/DataProviderInterface.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
|
||||
/**
|
||||
* Interface to the general data provider class.
|
||||
*
|
||||
* @see DataProvider
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
interface DataProviderInterface
|
||||
{
|
||||
/**
|
||||
* Returns an array suitable for select fields.
|
||||
* The key of the filtered data set is used as key of the
|
||||
* array and $desiredName field is used as value.
|
||||
*
|
||||
* @param string $desiredName
|
||||
*
|
||||
* @return array;
|
||||
*/
|
||||
public function getMultiOptions($desiredName): array;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the field $desiredName from the record $id.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param string $desiredName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getString($id, $desiredName): string;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the item at position $id.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData($id);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess\Exception;
|
||||
|
||||
class OutOfRangeException extends \OutOfRangeException
|
||||
{
|
||||
|
||||
}
|
96
classes/Components/I18n/Dataaccess/IteratorTrait.php
Normal file
96
classes/Components/I18n/Dataaccess/IteratorTrait.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
/**
|
||||
* Provides iterator functions to the data provider.
|
||||
*
|
||||
* @see \Iterator
|
||||
* @see DataProvider
|
||||
* @see DataProviderInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
trait IteratorTrait
|
||||
{
|
||||
/**
|
||||
* Index of the current element's key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $IteratorTrait_index = null;
|
||||
|
||||
/**
|
||||
* Array of keys of the data set.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $IteratorTrait_keys = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the current element.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->valid() ? $this->DataProvider_DATA[$this->key()] : null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the key of the current element.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return static::valid() ? $this->IteratorTrait_keys[$this->IteratorTrait_index] : null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Move forward to next element.
|
||||
*
|
||||
* @return bool false if invalid
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->IteratorTrait_index++;
|
||||
if (!$this->valid()) {
|
||||
$this->IteratorTrait_index = null;
|
||||
}
|
||||
return $this->valid();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Rewind the Iterator to the first element.
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->IteratorTrait_keys = array_keys($this->DataProvider_DATA);
|
||||
sort($this->IteratorTrait_keys);
|
||||
$this->IteratorTrait_index = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks if current position is valid.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid(): bool
|
||||
{
|
||||
return ($this->IteratorTrait_index !== null)
|
||||
&& array_key_exists($this->IteratorTrait_index, $this->IteratorTrait_keys)
|
||||
&& array_key_exists($this->IteratorTrait_keys[$this->IteratorTrait_index], $this->DataProvider_DATA);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Exception;
|
||||
|
||||
class LanguageNotInitializedException extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\I18n\Exception;
|
||||
|
||||
class UnsupportedLocaleStringException extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
27
classes/Components/I18n/Iso3166.php
Normal file
27
classes/Components/I18n/Iso3166.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataProvider;
|
||||
|
||||
/**
|
||||
* Country Codes - ISO 3166.
|
||||
* Loads the data and holds the filtered (if desired) list.
|
||||
*
|
||||
* @see https://www.iso.org/iso-3166-country-codes.html
|
||||
* @see DataProvider
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class Iso3166 extends DataProvider
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataProvider::getOriginalData()
|
||||
*/
|
||||
protected function getOriginalData(): array
|
||||
{
|
||||
return include(__DIR__ . '/data/Iso3166data.php');
|
||||
}
|
||||
}
|
27
classes/Components/I18n/Iso3166/Filter/All.php
Normal file
27
classes/Components/I18n/Iso3166/Filter/All.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
|
||||
/**
|
||||
* This filter returns all records from the data set (aka dummy filter).
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class All extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
function selectItem(&$key, &$val): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
37
classes/Components/I18n/Iso3166/Filter/CentralEurope.php
Normal file
37
classes/Components/I18n/Iso3166/Filter/CentralEurope.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
use Xentral\Components\I18n\Iso3166\Key;
|
||||
|
||||
|
||||
/**
|
||||
* Applies a filter to only select central european countries.
|
||||
*
|
||||
* @see Custom
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class CentralEurope extends Custom implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Countries in Europe.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
const CentralEurope_Countries = ['CHE', 'DEU', 'AUT', 'ITA', 'FRA', 'ESP', 'PRT', 'GBR'];
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set predefined values.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(static::CentralEurope_Countries, Key::ALPHA_3);
|
||||
}
|
||||
}
|
51
classes/Components/I18n/Iso3166/Filter/ChangeKey.php
Normal file
51
classes/Components/I18n/Iso3166/Filter/ChangeKey.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
|
||||
|
||||
/**
|
||||
* This filter can be used to change the main key
|
||||
* of the data set.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class ChangeKey extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* New key to use for the data set.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $ChangeKey_key = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize filter and set the new key.
|
||||
*
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function __construct($key)
|
||||
{
|
||||
$this->ChangeKey_key = $key;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
protected function selectItem(&$key, &$val): bool
|
||||
{
|
||||
$key = $val[$this->ChangeKey_key];
|
||||
return true;
|
||||
}
|
||||
}
|
59
classes/Components/I18n/Iso3166/Filter/Custom.php
Normal file
59
classes/Components/I18n/Iso3166/Filter/Custom.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Apply a custom filter to the data set.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class Custom extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Array of wanted values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $Custom_values = null;
|
||||
|
||||
/**
|
||||
* Key to check for the values in $this->Custom_values.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $Custom_key = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set values for filter.
|
||||
*
|
||||
* @param array $values
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function __construct(array $values, $key)
|
||||
{
|
||||
$this->Custom_values = $values;
|
||||
$this->Custom_key = $key;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
protected function selectItem(&$key, &$val): bool
|
||||
{
|
||||
$needle = $val[$this->Custom_key];
|
||||
return in_array($needle, $this->Custom_values);
|
||||
}
|
||||
}
|
28
classes/Components/I18n/Iso3166/Filter/Europe.php
Normal file
28
classes/Components/I18n/Iso3166/Filter/Europe.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
use Xentral\Components\I18n\Iso3166\Key;
|
||||
|
||||
|
||||
/**
|
||||
* Applies a filter to only select european countries.
|
||||
*
|
||||
* @see Custom
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class Europe extends Custom implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Set predefined values.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(['150'], Key::REGION_CODE);
|
||||
}
|
||||
}
|
71
classes/Components/I18n/Iso3166/Key.php
Normal file
71
classes/Components/I18n/Iso3166/Key.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166;
|
||||
|
||||
|
||||
/**
|
||||
* Keys for the iso3166 list.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Iso3166
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class Key/* extends Ruga_Enum*/
|
||||
{
|
||||
/** Key: Alpha-2 code */
|
||||
const ALPHA_2 = 'A2';
|
||||
|
||||
/** Key: Alpha-3 code */
|
||||
const ALPHA_3 = 'A3';
|
||||
|
||||
/** Key: Numeric code */
|
||||
const NUMERIC = 'NUM';
|
||||
|
||||
/** Key: Top Level Domain */
|
||||
const TLD = 'TLD';
|
||||
|
||||
/** Key: Currency Code */
|
||||
const CURRENCY_CODE = 'CURRENCY_CODE';
|
||||
const TELEPHONE_CODE = 'TEL_CODE';
|
||||
const REGION = 'REGION';
|
||||
const REGION_CODE = 'REGION_CODE';
|
||||
const SUBREGION = 'SUBREGION';
|
||||
const SUBREGION_CODE = 'SUBREGION_CODE';
|
||||
const INTERMEDIATEREGION = 'INTERMEDIATEREGION';
|
||||
const INTERMEDIATEREGION_CODE = 'INTERMEDIATEREGION_CODE';
|
||||
const NAME_eng = 'NAME_eng';
|
||||
const NAME_fra = 'NAME_fra';
|
||||
const NAME_deu = 'NAME_deu';
|
||||
|
||||
|
||||
/** Key: Postal country name */
|
||||
const POST = 'POST';
|
||||
|
||||
|
||||
const DEFAULT = self::ALPHA_3;
|
||||
|
||||
|
||||
protected static $fullnameMap = [
|
||||
self::ALPHA_2 => 'ISO 3166 Alpha-2',
|
||||
self::ALPHA_3 => 'ISO 3166 Alpha-3',
|
||||
self::NUMERIC => 'ISO 3166 Numerisch',
|
||||
self::TLD => 'Top Level Domain',
|
||||
self::CURRENCY_CODE => 'Währung',
|
||||
self::TELEPHONE_CODE => 'Landesvorwahl',
|
||||
self::REGION => 'Region',
|
||||
self::REGION_CODE => 'Region Code',
|
||||
self::SUBREGION => 'Unter-Region',
|
||||
self::SUBREGION_CODE => 'Unter-Region Code',
|
||||
self::INTERMEDIATEREGION => 'Intermediate-Region',
|
||||
self::INTERMEDIATEREGION_CODE => 'Intermediate-Region Code',
|
||||
self::NAME_eng => 'Englische Bezeichnung',
|
||||
self::NAME_fra => 'Französische Bezeichnung',
|
||||
self::NAME_deu => 'Deutsche Bezeichnung',
|
||||
|
||||
self::POST => 'Landesbezeichung Postadresse',
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
|
28
classes/Components/I18n/Iso3166/Name.php
Normal file
28
classes/Components/I18n/Iso3166/Name.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166;
|
||||
|
||||
/**
|
||||
* Names for the iso3166 list.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Iso3166
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class Name/* extends Ruga_Enum */
|
||||
{
|
||||
/** Englisch */
|
||||
const ENG = 'NAME_eng';
|
||||
/** Französisch */
|
||||
const FRA = 'NAME_fra';
|
||||
/** Deutsch */
|
||||
const DEU = 'NAME_deu';
|
||||
|
||||
|
||||
protected static $fullnameMap = [
|
||||
self::ENG => 'Englische Bezeichnung',
|
||||
self::FRA => 'Französische Bezeichnung',
|
||||
self::DEU => 'Deutsche Bezeichnung',
|
||||
];
|
||||
}
|
69
classes/Components/I18n/Iso639.php
Normal file
69
classes/Components/I18n/Iso639.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataProvider;
|
||||
use Xentral\Components\I18n\Dataaccess\Exception\OutOfRangeException;
|
||||
|
||||
/**
|
||||
* Codes for the Representation of Names of Languages - ISO 639.
|
||||
* Loads the data and holds the filtered (if desired) list.
|
||||
*
|
||||
* @see https://www.iso.org/iso-639-language-codes.html
|
||||
* @see DataProvider
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class Iso639 extends DataProvider
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataProvider::getOriginalData()
|
||||
*/
|
||||
protected function getOriginalData(): array
|
||||
{
|
||||
return include(__DIR__ . '/data/Iso639data.php');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the field $desiredName from the record $id.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param string $desiredName
|
||||
* @param null $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function find($id, $desiredName, $default = null): string
|
||||
{
|
||||
$id = strtolower($id);
|
||||
try {
|
||||
return $this->getString($id, $desiredName);
|
||||
} catch (OutOfRangeException $e) {
|
||||
try {
|
||||
return (new \Xentral\Components\I18n\Iso639(
|
||||
(new \Xentral\Components\I18n\Iso639\Filter\All())
|
||||
->then(new \Xentral\Components\I18n\Iso639\Filter\ChangeKey(\Xentral\Components\I18n\Iso639\Key::ALPHA_2))
|
||||
))->getString($id, $desiredName);
|
||||
} catch (OutOfRangeException $e) {
|
||||
try {
|
||||
$id = strtoupper($id);
|
||||
return (new \Xentral\Components\I18n\Iso639(
|
||||
(new \Xentral\Components\I18n\Iso639\Filter\All())
|
||||
->then(new \Xentral\Components\I18n\Iso639\Filter\ChangeKey(\Xentral\Components\I18n\Iso639\Key::ONELETTER))
|
||||
))->getString($id, $desiredName);
|
||||
} catch (OutOfRangeException $e) {
|
||||
if ($default === null) {
|
||||
throw $e;
|
||||
} else {
|
||||
return $this->getString($default, $desiredName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
28
classes/Components/I18n/Iso639/Filter/All.php
Normal file
28
classes/Components/I18n/Iso639/Filter/All.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
|
||||
|
||||
/**
|
||||
* This filter returns all records from the data set (aka dummy filter).
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class All extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
function selectItem(&$key, &$val): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
37
classes/Components/I18n/Iso639/Filter/CentralEurope.php
Normal file
37
classes/Components/I18n/Iso639/Filter/CentralEurope.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
use Xentral\Components\I18n\Iso639\Key;
|
||||
|
||||
|
||||
/**
|
||||
* Applies a filter to only select central european countries.
|
||||
*
|
||||
* @see Custom
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class CentralEurope extends Custom implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Countries in Europe.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
const CentralEurope_Languages = ['deu', 'fra', 'ita', 'roh', 'spa', 'por', 'eng'];
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set predefined values.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(static::CentralEurope_Languages, Key::ALPHA_3);
|
||||
}
|
||||
}
|
51
classes/Components/I18n/Iso639/Filter/ChangeKey.php
Normal file
51
classes/Components/I18n/Iso639/Filter/ChangeKey.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
|
||||
|
||||
/**
|
||||
* This filter can be used to change the main key
|
||||
* of the data set.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class ChangeKey extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* New key to use for the data set.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $ChangeKey_key = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize filter and set the new key.
|
||||
*
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function __construct($key)
|
||||
{
|
||||
$this->ChangeKey_key = $key;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
protected function selectItem(&$key, &$val): bool
|
||||
{
|
||||
$key = $val[$this->ChangeKey_key] ?? null;
|
||||
return true;
|
||||
}
|
||||
}
|
59
classes/Components/I18n/Iso639/Filter/Custom.php
Normal file
59
classes/Components/I18n/Iso639/Filter/Custom.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Apply a custom filter to the data set.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class Custom extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Array of wanted values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $Custom_values = null;
|
||||
|
||||
/**
|
||||
* Key to check for the values in $this->Custom_values.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $Custom_key = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set values for filter.
|
||||
*
|
||||
* @param array $values
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function __construct(array $values, $key)
|
||||
{
|
||||
$this->Custom_values = $values;
|
||||
$this->Custom_key = $key;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
protected function selectItem(&$key, &$val): bool
|
||||
{
|
||||
$needle = $val[$this->Custom_key];
|
||||
return in_array($needle, $this->Custom_values);
|
||||
}
|
||||
}
|
47
classes/Components/I18n/Iso639/Key.php
Normal file
47
classes/Components/I18n/Iso639/Key.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639;
|
||||
|
||||
|
||||
/**
|
||||
* Keys for the iso639 list.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Iso639
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class Key/* extends Ruga_Enum*/
|
||||
{
|
||||
/** Key: Alpha-2 code */
|
||||
const ALPHA_2 = '639-1';
|
||||
const ISO639_1 = '639-1';
|
||||
|
||||
/** Key: Alpha-3 code */
|
||||
const ALPHA_3 = '639-2';
|
||||
const ISO639_2 = '639-2';
|
||||
|
||||
/** Key: Top Level Domain */
|
||||
const ONELETTER = '1L';
|
||||
|
||||
/** Key: Name */
|
||||
const NAME_eng = 'NAME_eng';
|
||||
const NAME_fra = 'NAME_fra';
|
||||
const NAME_deu = 'NAME_deu';
|
||||
|
||||
|
||||
const DEFAULT = self::ALPHA_3;
|
||||
|
||||
|
||||
protected static $fullnameMap = [
|
||||
self::ALPHA_2 => 'ISO 639 Alpha-2',
|
||||
self::ALPHA_3 => 'ISO 639 Alpha-3',
|
||||
self::ONELETTER => 'ISO 639 Alpha-1',
|
||||
self::NAME_eng => 'Englische Bezeichnung',
|
||||
self::NAME_fra => 'Französische Bezeichnung',
|
||||
self::NAME_deu => 'Deutsche Bezeichnung',
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
|
29
classes/Components/I18n/Iso639/Name.php
Normal file
29
classes/Components/I18n/Iso639/Name.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639;
|
||||
|
||||
|
||||
/**
|
||||
* Names for the iso639 list.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Iso639
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class Name/* extends Ruga_Enum */
|
||||
{
|
||||
/** Englisch */
|
||||
const ENG = 'NAME_eng';
|
||||
/** Französisch */
|
||||
const FRA = 'NAME_fra';
|
||||
/** Deutsch */
|
||||
const DEU = 'NAME_deu';
|
||||
|
||||
|
||||
protected static $fullnameMap = [
|
||||
self::ENG => 'Englische Bezeichnung',
|
||||
self::FRA => 'Französische Bezeichnung',
|
||||
self::DEU => 'Deutsche Bezeichnung',
|
||||
];
|
||||
}
|
206
classes/Components/I18n/Localization.php
Normal file
206
classes/Components/I18n/Localization.php
Normal file
@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n;
|
||||
|
||||
use Locale;
|
||||
use Xentral\Components\Http\Request;
|
||||
use Xentral\Components\Http\Session\Session;
|
||||
use Xentral\Components\I18n\Exception\LanguageNotInitializedException;
|
||||
use Xentral\Components\I18n\Exception\UnsupportedLocaleStringException;
|
||||
|
||||
final class Localization implements LocalizationInterface
|
||||
{
|
||||
private array $config;
|
||||
|
||||
private ?Request $request;
|
||||
|
||||
private ?Session $session;
|
||||
|
||||
private array $usersettings = [];
|
||||
|
||||
private array $language = [];
|
||||
|
||||
private array $locale = [];
|
||||
|
||||
|
||||
|
||||
public function __construct(?Request $request, ?Session $session, array $usersettings = [])
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->session = $session;
|
||||
$this->usersettings = $usersettings;
|
||||
$this->config = [];
|
||||
$this->process();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function process()
|
||||
{
|
||||
// Hardcoded defaults if config is not available
|
||||
$localeDefault = $this->config[Localization::LOCALE_DEFAULT] ?? 'de_DE';
|
||||
$localeAttrName = $this->config[Localization::LOCALE_ATTRIBUTE_NAME] ?? 'locale';
|
||||
$langDefault = $this->config[Localization::LANGUAGE_DEFAULT] ?? 'deu';
|
||||
$langAttrName = $this->config[Localization::LANGUAGE_ATTRIBUTE_NAME] ?? 'language';
|
||||
|
||||
$segmentName = 'i18n';
|
||||
// $session = $this->session;
|
||||
// $request = $this->request;
|
||||
|
||||
// Get the locale from the session, if available
|
||||
if ($this->session && ($locale = $this->session->getValue($segmentName, $localeAttrName))) {
|
||||
} else {
|
||||
// Get locale from request, fallback to the user's browser preference
|
||||
if ($this->request) {
|
||||
$locale = $this->request->attributes->get(
|
||||
$localeAttrName,
|
||||
Locale::acceptFromHttp(
|
||||
$this->request->getHeader('Accept-Language', $localeDefault)
|
||||
) ?? $localeDefault
|
||||
);
|
||||
} else {
|
||||
$locale = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? $localeDefault);
|
||||
}
|
||||
}
|
||||
// Get locale from user
|
||||
// This overrides all previous attempts to find a locale
|
||||
if (array_key_exists('locale', $this->usersettings)) {
|
||||
$locale = $this->usersettings['locale'];
|
||||
}
|
||||
// Get locale from query string
|
||||
// This overrides all previous attempts to find a locale
|
||||
if ($this->request) {
|
||||
$locale = $this->request->getParam($localeAttrName, $locale ?? $localeDefault);
|
||||
} else {
|
||||
$locale = $_GET[$localeAttrName] ?? $locale ?? $localeDefault;
|
||||
}
|
||||
|
||||
|
||||
// Get the language from the session, if available
|
||||
if ($this->session && ($language = $this->session->getValue($segmentName, $langAttrName))) {
|
||||
} else {
|
||||
// Get language from request, fallback to the current locale
|
||||
if ($this->request) {
|
||||
$language = $this->request->attributes->get($langAttrName, Locale::getPrimaryLanguage($locale));
|
||||
} else {
|
||||
$language = Locale::getPrimaryLanguage($locale);
|
||||
}
|
||||
}
|
||||
// Get language from user
|
||||
// This overrides all previous attempts to find a language
|
||||
if (array_key_exists('language', $this->usersettings)) {
|
||||
$language = $this->usersettings['language'];
|
||||
}
|
||||
// Get language from query string
|
||||
// This overrides all previous attempts to find a language
|
||||
if ($this->request) {
|
||||
$language = $this->request->getParam($langAttrName, $language ?? $langDefault);
|
||||
} else {
|
||||
$language = $language ?? $langDefault;
|
||||
}
|
||||
|
||||
// Check language against the data from Iso639 (and normalize to 3-letter-code)
|
||||
$language = (new Iso639())->find($language, Iso639\Key::DEFAULT, $langDefault);
|
||||
|
||||
|
||||
// Store the locale and language to the LocalizationInterface
|
||||
$this->setLanguage($language);
|
||||
$this->setLocale($locale);
|
||||
|
||||
// Store the locale and language to the session
|
||||
if ($this->session) {
|
||||
$this->session->setValue($segmentName, $localeAttrName, $locale);
|
||||
$this->session->setValue($segmentName, $langAttrName, $language);
|
||||
}
|
||||
|
||||
// Store the locale and language as a request attribute
|
||||
if ($this->request) {
|
||||
$this->request->attributes->set($localeAttrName, $locale);
|
||||
$this->request->attributes->set($langAttrName, $language);
|
||||
}
|
||||
|
||||
// Set the default locale
|
||||
Locale::setDefault($locale);
|
||||
|
||||
// error_log(self::class . ": {$locale}");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the language.
|
||||
*
|
||||
* @param string $language
|
||||
*/
|
||||
public function setLanguage(string $language)
|
||||
{
|
||||
$this->language[Iso639\Key::DEFAULT] = (new \Xentral\Components\I18n\Iso639())->find(
|
||||
$language,
|
||||
Iso639\Key::DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the language string as defined by $key.
|
||||
*
|
||||
* @param string|null $key A constant from Iso639\Key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage(string $key = null): string
|
||||
{
|
||||
if (!$key) {
|
||||
$key = Iso639\Key::DEFAULT;
|
||||
}
|
||||
if (!($this->language[$key] ?? null)) {
|
||||
if (!($this->language[Iso639\Key::DEFAULT] ?? null)) {
|
||||
throw new LanguageNotInitializedException("Language is not set for key '" . Iso639\Key::DEFAULT . "'");
|
||||
}
|
||||
$this->language[$key] = (new \Xentral\Components\I18n\Iso639())->find(
|
||||
$this->language[Iso639\Key::DEFAULT],
|
||||
$key
|
||||
);
|
||||
}
|
||||
return $this->language[$key];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the locale.
|
||||
*
|
||||
* @param string $locale
|
||||
*/
|
||||
public function setLocale(string $locale)
|
||||
{
|
||||
$parsedLocale = Locale::parseLocale($locale);
|
||||
$locale = Locale::composeLocale([
|
||||
'language' => $parsedLocale['language'],
|
||||
'region' => $parsedLocale['region'],
|
||||
]);
|
||||
|
||||
if(!$locale) throw new UnsupportedLocaleStringException("The given locale string '{$locale}' is not supported");
|
||||
|
||||
$this->locale[Iso3166\Key::DEFAULT] = $locale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the locale string as defined by $key.
|
||||
*
|
||||
* @param string|null $key A constant from Iso3166\Key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocale(string $key = null): string
|
||||
{
|
||||
return $this->locale[Iso3166\Key::DEFAULT];
|
||||
}
|
||||
|
||||
|
||||
}
|
58
classes/Components/I18n/LocalizationInterface.php
Normal file
58
classes/Components/I18n/LocalizationInterface.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n;
|
||||
|
||||
/**
|
||||
* Interface LocalizationInterface
|
||||
*
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
interface LocalizationInterface
|
||||
{
|
||||
const LOCALE_DEFAULT = 'locale_default';
|
||||
const LOCALE_ATTRIBUTE_NAME = 'locale_attr_name';
|
||||
const LANGUAGE_DEFAULT = 'language_default';
|
||||
const LANGUAGE_ATTRIBUTE_NAME = 'language_attr_name';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the language.
|
||||
*
|
||||
* @param string $language
|
||||
*/
|
||||
public function setLanguage(string $language);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the language string as defined by $key.
|
||||
*
|
||||
* @param string|null $key A constant from Iso639\Key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage(string $key = null): string;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the locale.
|
||||
*
|
||||
* @param string $locale
|
||||
*/
|
||||
public function setLocale(string $locale);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the locale string as defined by $key.
|
||||
*
|
||||
* @param string|null $key A constant from Iso3166\Key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocale(string $key = null): string;
|
||||
}
|
5256
classes/Components/I18n/data/Iso3166data.php
Normal file
5256
classes/Components/I18n/data/Iso3166data.php
Normal file
File diff suppressed because it is too large
Load Diff
155
classes/Components/I18n/data/Iso639data.php
Normal file
155
classes/Components/I18n/data/Iso639data.php
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
// ISO639 list
|
||||
// 2020-02-26T16:05:00+01:00
|
||||
return [
|
||||
|
||||
'aar' => [
|
||||
'639-2' => 'aar',
|
||||
'639-1' => 'aa',
|
||||
'NAME_eng' => 'Afar',
|
||||
'NAME_fra' => 'afar',
|
||||
'NAME_deu' => 'Danakil-Sprache',
|
||||
],
|
||||
'abk' => [
|
||||
'639-2' => 'abk',
|
||||
'639-1' => 'ab',
|
||||
'NAME_eng' => 'Abkhazian',
|
||||
'NAME_fra' => 'abkhaze',
|
||||
'NAME_deu' => 'Abchasisch',
|
||||
],
|
||||
'ace' => [
|
||||
'639-2' => 'ace',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Achinese',
|
||||
'NAME_fra' => 'aceh',
|
||||
'NAME_deu' => 'Aceh-Sprache',
|
||||
],
|
||||
'ach' => [
|
||||
'639-2' => 'ach',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Acoli',
|
||||
'NAME_fra' => 'acoli',
|
||||
'NAME_deu' => 'Acholi-Sprache',
|
||||
],
|
||||
'ada' => [
|
||||
'639-2' => 'ada',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Adangme',
|
||||
'NAME_fra' => 'adangme',
|
||||
'NAME_deu' => 'Adangme-Sprache',
|
||||
],
|
||||
'ady' => [
|
||||
'639-2' => 'ady',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Adyghe',
|
||||
'NAME_fra' => 'adyghé',
|
||||
'NAME_deu' => 'Adygisch',
|
||||
],
|
||||
'afa' => [
|
||||
'639-2' => 'afa',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Afro-Asiatic languages',
|
||||
'NAME_fra' => 'afro-asiatiques, langues',
|
||||
'NAME_deu' => 'Hamitosemitische Sprachen (Andere)',
|
||||
],
|
||||
'afh' => [
|
||||
'639-2' => 'afh',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Afrihili',
|
||||
'NAME_fra' => 'afrihili',
|
||||
'NAME_deu' => 'Afrihili',
|
||||
],
|
||||
'afr' => [
|
||||
'639-2' => 'afr',
|
||||
'639-1' => 'af',
|
||||
'NAME_eng' => 'Afrikaans',
|
||||
'NAME_fra' => 'afrikaans',
|
||||
'NAME_deu' => 'Afrikaans',
|
||||
],
|
||||
'ain' => [
|
||||
'639-2' => 'ain',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Ainu',
|
||||
'NAME_fra' => 'aïnou',
|
||||
'NAME_deu' => 'Ainu-Sprache',
|
||||
],
|
||||
'aka' => [
|
||||
'639-2' => 'aka',
|
||||
'639-1' => 'ak',
|
||||
'NAME_eng' => 'Akan',
|
||||
'NAME_fra' => 'akan',
|
||||
'NAME_deu' => 'Akan-Sprache',
|
||||
],
|
||||
'akk' => [
|
||||
'639-2' => 'akk',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Akkadian',
|
||||
'NAME_fra' => 'akkadien',
|
||||
'NAME_deu' => 'Akkadisch',
|
||||
],
|
||||
'sqi' => [
|
||||
'639-2' => 'sqi',
|
||||
'639-1' => 'sq',
|
||||
'NAME_eng' => 'Albanian',
|
||||
'NAME_fra' => 'albanais',
|
||||
'NAME_deu' => 'Albanisch',
|
||||
'639-2-B' => 'alb',
|
||||
],
|
||||
|
||||
'deu' => [
|
||||
'639-2' => 'deu',
|
||||
'639-1' => 'de',
|
||||
'NAME_eng' => 'German',
|
||||
'NAME_fra' => 'allemand',
|
||||
'NAME_deu' => 'Deutsch',
|
||||
'639-2-B' => 'ger',
|
||||
'1L' => 'D',
|
||||
],
|
||||
'eng' => [
|
||||
'639-2' => 'eng',
|
||||
'639-1' => 'en',
|
||||
'NAME_eng' => 'English',
|
||||
'NAME_fra' => 'anglais',
|
||||
'NAME_deu' => 'Englisch',
|
||||
'1L' => 'E',
|
||||
],
|
||||
'fra' => [
|
||||
'639-2' => 'fra',
|
||||
'639-1' => 'fr',
|
||||
'NAME_eng' => 'French',
|
||||
'NAME_fra' => 'français',
|
||||
'NAME_deu' => 'Französisch',
|
||||
'639-2-B' => 'fre',
|
||||
'1L' => 'F',
|
||||
],
|
||||
'ita' => [
|
||||
'639-2' => 'ita',
|
||||
'639-1' => 'it',
|
||||
'NAME_eng' => 'Italian',
|
||||
'NAME_fra' => 'italien',
|
||||
'NAME_deu' => 'Italienisch',
|
||||
'1L' => 'I',
|
||||
],
|
||||
'spa' => [
|
||||
'639-2' => 'spa',
|
||||
'639-1' => 'es',
|
||||
'NAME_eng' => 'Spanish',
|
||||
'NAME_fra' => 'espagnol',
|
||||
'NAME_deu' => 'Spanisch',
|
||||
],
|
||||
'por' => [
|
||||
'639-2' => 'por',
|
||||
'639-1' => 'pt',
|
||||
'NAME_eng' => 'Portuguese',
|
||||
'NAME_fra' => 'portugais',
|
||||
'NAME_deu' => 'Portugiesisch',
|
||||
],
|
||||
'roh' => [
|
||||
'639-2' => 'roh',
|
||||
'639-1' => 'rm',
|
||||
'NAME_eng' => 'Romansh',
|
||||
'NAME_fra' => 'romanche',
|
||||
'NAME_deu' => 'Rätoromanisch',
|
||||
],
|
||||
|
||||
];
|
Loading…
x
Reference in New Issue
Block a user