first commit
This commit is contained in:
30
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Compiler/BundleCompilerInterface.php
vendored
Normal file
30
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Compiler/BundleCompilerInterface.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Compiler;
|
||||
|
||||
/**
|
||||
* Compiles a resource bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface BundleCompilerInterface
|
||||
{
|
||||
/**
|
||||
* Compiles a resource bundle at the given source to the given target
|
||||
* directory.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compile(string $sourcePath, string $targetDir);
|
||||
}
|
58
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Compiler/GenrbCompiler.php
vendored
Normal file
58
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Compiler/GenrbCompiler.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Compiler;
|
||||
|
||||
use Symfony\Component\Intl\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Compiles .txt resource bundles to binary .res files.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class GenrbCompiler implements BundleCompilerInterface
|
||||
{
|
||||
private string $genrb;
|
||||
|
||||
/**
|
||||
* Creates a new compiler based on the "genrb" executable.
|
||||
*
|
||||
* @param string $genrb Optional. The path to the "genrb" executable
|
||||
* @param string $envVars Optional. Environment variables to be loaded when running "genrb".
|
||||
*
|
||||
* @throws RuntimeException if the "genrb" cannot be found
|
||||
*/
|
||||
public function __construct(string $genrb = 'genrb', string $envVars = '')
|
||||
{
|
||||
exec('which '.$genrb, $output, $status);
|
||||
|
||||
if (0 !== $status) {
|
||||
throw new RuntimeException(sprintf('The command "%s" is not installed.', $genrb));
|
||||
}
|
||||
|
||||
$this->genrb = ($envVars ? $envVars.' ' : '').$genrb;
|
||||
}
|
||||
|
||||
public function compile(string $sourcePath, string $targetDir): void
|
||||
{
|
||||
if (is_dir($sourcePath)) {
|
||||
$sourcePath .= '/*.txt';
|
||||
}
|
||||
|
||||
exec($this->genrb.' --quiet -e UTF-8 -d '.$targetDir.' '.$sourcePath, $output, $status);
|
||||
|
||||
if (0 !== $status) {
|
||||
throw new RuntimeException(sprintf('genrb failed with status %d while compiling "%s" to "%s".', $status, $sourcePath, $targetDir));
|
||||
}
|
||||
}
|
||||
}
|
43
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/BufferedBundleReader.php
vendored
Normal file
43
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/BufferedBundleReader.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Data\Util\RingBuffer;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BufferedBundleReader implements BundleReaderInterface
|
||||
{
|
||||
private BundleReaderInterface $reader;
|
||||
/** @var RingBuffer<string, mixed> */
|
||||
private RingBuffer $buffer;
|
||||
|
||||
public function __construct(BundleReaderInterface $reader, int $bufferSize)
|
||||
{
|
||||
$this->reader = $reader;
|
||||
$this->buffer = new RingBuffer($bufferSize);
|
||||
}
|
||||
|
||||
public function read(string $path, string $locale): mixed
|
||||
{
|
||||
$hash = $path.'//'.$locale;
|
||||
|
||||
if (!isset($this->buffer[$hash])) {
|
||||
$this->buffer[$hash] = $this->reader->read($path, $locale);
|
||||
}
|
||||
|
||||
return $this->buffer[$hash];
|
||||
}
|
||||
}
|
171
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/BundleEntryReader.php
vendored
Normal file
171
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/BundleEntryReader.php
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Data\Util\RecursiveArrayAccess;
|
||||
use Symfony\Component\Intl\Exception\MissingResourceException;
|
||||
use Symfony\Component\Intl\Exception\OutOfBoundsException;
|
||||
use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException;
|
||||
use Symfony\Component\Intl\Locale;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link BundleEntryReaderInterface}.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @see BundleEntryReaderInterface
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BundleEntryReader implements BundleEntryReaderInterface
|
||||
{
|
||||
private BundleReaderInterface $reader;
|
||||
|
||||
/**
|
||||
* A mapping of locale aliases to locales.
|
||||
*/
|
||||
private array $localeAliases = [];
|
||||
|
||||
/**
|
||||
* Creates an entry reader based on the given resource bundle reader.
|
||||
*/
|
||||
public function __construct(BundleReaderInterface $reader)
|
||||
{
|
||||
$this->reader = $reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a mapping of locale aliases to locales.
|
||||
*
|
||||
* This mapping is used when reading entries and merging them with their
|
||||
* fallback locales. If an entry is read for a locale alias (e.g. "mo")
|
||||
* that points to a locale with a fallback locale ("ro_MD"), the reader
|
||||
* can continue at the correct fallback locale ("ro").
|
||||
*
|
||||
* @param array $localeAliases A mapping of locale aliases to locales
|
||||
*/
|
||||
public function setLocaleAliases(array $localeAliases): void
|
||||
{
|
||||
$this->localeAliases = $localeAliases;
|
||||
}
|
||||
|
||||
public function read(string $path, string $locale): mixed
|
||||
{
|
||||
return $this->reader->read($path, $locale);
|
||||
}
|
||||
|
||||
public function readEntry(string $path, string $locale, array $indices, bool $fallback = true): mixed
|
||||
{
|
||||
$entry = null;
|
||||
$isMultiValued = false;
|
||||
$readSucceeded = false;
|
||||
$exception = null;
|
||||
$currentLocale = $locale;
|
||||
$testedLocales = [];
|
||||
|
||||
while (null !== $currentLocale) {
|
||||
// Resolve any aliases to their target locales
|
||||
if (isset($this->localeAliases[$currentLocale])) {
|
||||
$currentLocale = $this->localeAliases[$currentLocale];
|
||||
}
|
||||
|
||||
try {
|
||||
$data = $this->reader->read($path, $currentLocale);
|
||||
$currentEntry = RecursiveArrayAccess::get($data, $indices);
|
||||
$readSucceeded = true;
|
||||
|
||||
$isCurrentTraversable = $currentEntry instanceof \Traversable;
|
||||
$isCurrentMultiValued = $isCurrentTraversable || \is_array($currentEntry);
|
||||
|
||||
// Return immediately if fallback is disabled or we are dealing
|
||||
// with a scalar non-null entry
|
||||
if (!$fallback || (!$isCurrentMultiValued && null !== $currentEntry)) {
|
||||
return $currentEntry;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Fallback is enabled, entry is either multi-valued or NULL
|
||||
// =========================================================
|
||||
|
||||
// If entry is multi-valued, convert to array
|
||||
if ($isCurrentTraversable) {
|
||||
$currentEntry = iterator_to_array($currentEntry);
|
||||
}
|
||||
|
||||
// If previously read entry was multi-valued too, merge them
|
||||
if ($isCurrentMultiValued && $isMultiValued) {
|
||||
$currentEntry = array_merge($currentEntry, $entry);
|
||||
}
|
||||
|
||||
// Keep the previous entry if the current entry is NULL
|
||||
if (null !== $currentEntry) {
|
||||
$entry = $currentEntry;
|
||||
}
|
||||
|
||||
// If this or the previous entry was multi-valued, we are dealing
|
||||
// with a merged, multi-valued entry now
|
||||
$isMultiValued = $isMultiValued || $isCurrentMultiValued;
|
||||
} catch (ResourceBundleNotFoundException $e) {
|
||||
// Continue if there is a fallback locale for the current
|
||||
// locale
|
||||
$exception = $e;
|
||||
} catch (OutOfBoundsException $e) {
|
||||
// Remember exception and rethrow if we cannot find anything in
|
||||
// the fallback locales either
|
||||
$exception = $e;
|
||||
}
|
||||
|
||||
// Remember which locales we tried
|
||||
$testedLocales[] = $currentLocale;
|
||||
|
||||
// Check whether fallback is allowed
|
||||
if (!$fallback) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Then determine fallback locale
|
||||
$currentLocale = Locale::getFallback($currentLocale);
|
||||
}
|
||||
|
||||
// Multi-valued entry was merged
|
||||
if ($isMultiValued) {
|
||||
return $entry;
|
||||
}
|
||||
|
||||
// Entry is still NULL, but no read error occurred
|
||||
if ($readSucceeded) {
|
||||
return $entry;
|
||||
}
|
||||
|
||||
// Entry is still NULL, read error occurred. Throw an exception
|
||||
// containing the detailed path and locale
|
||||
$errorMessage = sprintf(
|
||||
'Couldn\'t read the indices [%s] for the locale "%s" in "%s".',
|
||||
implode('][', $indices),
|
||||
$locale,
|
||||
$path
|
||||
);
|
||||
|
||||
// Append fallback locales, if any
|
||||
if (\count($testedLocales) > 1) {
|
||||
// Remove original locale
|
||||
array_shift($testedLocales);
|
||||
|
||||
$errorMessage .= sprintf(
|
||||
' The indices also couldn\'t be found for the fallback locale(s) "%s".',
|
||||
implode('", "', $testedLocales)
|
||||
);
|
||||
}
|
||||
|
||||
throw new MissingResourceException($errorMessage, 0, $exception);
|
||||
}
|
||||
}
|
54
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/BundleEntryReaderInterface.php
vendored
Normal file
54
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/BundleEntryReaderInterface.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Exception\MissingResourceException;
|
||||
|
||||
/**
|
||||
* Reads individual entries of a resource file.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface BundleEntryReaderInterface extends BundleReaderInterface
|
||||
{
|
||||
/**
|
||||
* Reads an entry from a resource bundle.
|
||||
*
|
||||
* An entry can be selected from the resource bundle by passing the path
|
||||
* to that entry in the bundle. For example, if the bundle is structured
|
||||
* like this:
|
||||
*
|
||||
* TopLevel
|
||||
* NestedLevel
|
||||
* Entry: Value
|
||||
*
|
||||
* Then the value can be read by calling:
|
||||
*
|
||||
* $reader->readEntry('...', 'en', ['TopLevel', 'NestedLevel', 'Entry']);
|
||||
*
|
||||
* @param string $path The path to the resource bundle
|
||||
* @param string[] $indices The indices to read from the bundle
|
||||
* @param bool $fallback Whether to merge the value with the value from
|
||||
* the fallback locale (e.g. "en" for "en_GB").
|
||||
* Only applicable if the result is multivalued
|
||||
* (i.e. array or \ArrayAccess) or cannot be found
|
||||
* in the requested locale.
|
||||
*
|
||||
* @return mixed returns an array or {@link \ArrayAccess} instance for
|
||||
* complex data and a scalar value for simple data
|
||||
*
|
||||
* @throws MissingResourceException If the indices cannot be accessed
|
||||
*/
|
||||
public function readEntry(string $path, string $locale, array $indices, bool $fallback = true): mixed;
|
||||
}
|
28
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/BundleReaderInterface.php
vendored
Normal file
28
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/BundleReaderInterface.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Reader;
|
||||
|
||||
/**
|
||||
* Reads resource bundle files.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface BundleReaderInterface
|
||||
{
|
||||
/**
|
||||
* @return mixed returns an array or {@link \ArrayAccess} instance for
|
||||
* complex data, a scalar value otherwise
|
||||
*/
|
||||
public function read(string $path, string $locale): mixed;
|
||||
}
|
47
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/IntlBundleReader.php
vendored
Normal file
47
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/IntlBundleReader.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Data\Util\ArrayAccessibleResourceBundle;
|
||||
use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException;
|
||||
|
||||
/**
|
||||
* Reads binary .res resource bundles.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class IntlBundleReader implements BundleReaderInterface
|
||||
{
|
||||
public function read(string $path, string $locale): mixed
|
||||
{
|
||||
// Point for future extension: Modify this class so that it works also
|
||||
// if the \ResourceBundle class is not available.
|
||||
try {
|
||||
// Never enable fallback. We want to know if a bundle cannot be found
|
||||
$bundle = new \ResourceBundle($locale, $path, false);
|
||||
} catch (\Exception) {
|
||||
$bundle = null;
|
||||
}
|
||||
|
||||
// The bundle is NULL if the path does not look like a resource bundle
|
||||
// (i.e. contain a bunch of *.res files)
|
||||
if (null === $bundle) {
|
||||
throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s/%s.res" could not be found.', $path, $locale));
|
||||
}
|
||||
|
||||
// Other possible errors are U_USING_FALLBACK_WARNING and U_ZERO_ERROR,
|
||||
// which are OK for us.
|
||||
return new ArrayAccessibleResourceBundle($bundle);
|
||||
}
|
||||
}
|
47
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/JsonBundleReader.php
vendored
Normal file
47
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/JsonBundleReader.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException;
|
||||
use Symfony\Component\Intl\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Reads .json resource bundles.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class JsonBundleReader implements BundleReaderInterface
|
||||
{
|
||||
public function read(string $path, string $locale): mixed
|
||||
{
|
||||
$fileName = $path.'/'.$locale.'.json';
|
||||
|
||||
// prevent directory traversal attacks
|
||||
if (\dirname($fileName) !== $path) {
|
||||
throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s" does not exist.', $fileName));
|
||||
}
|
||||
|
||||
if (!is_file($fileName)) {
|
||||
throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s" does not exist.', $fileName));
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents($fileName), true);
|
||||
|
||||
if (null === $data) {
|
||||
throw new RuntimeException(sprintf('The resource bundle "%s" contains invalid JSON: ', $fileName).json_last_error_msg());
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
45
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/PhpBundleReader.php
vendored
Normal file
45
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Reader/PhpBundleReader.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException;
|
||||
use Symfony\Component\Intl\Util\GzipStreamWrapper;
|
||||
|
||||
/**
|
||||
* Reads .php resource bundles.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class PhpBundleReader implements BundleReaderInterface
|
||||
{
|
||||
public function read(string $path, string $locale): mixed
|
||||
{
|
||||
$fileName = $path.'/'.$locale.'.php';
|
||||
|
||||
// prevent directory traversal attacks
|
||||
if (\dirname($fileName) !== $path) {
|
||||
throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s" does not exist.', $fileName));
|
||||
}
|
||||
|
||||
if (is_file($fileName.'.gz')) {
|
||||
return GzipStreamWrapper::require($fileName.'.gz');
|
||||
}
|
||||
|
||||
if (!is_file($fileName)) {
|
||||
throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s" does not exist.', $fileName));
|
||||
}
|
||||
|
||||
return include $fileName;
|
||||
}
|
||||
}
|
27
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Writer/BundleWriterInterface.php
vendored
Normal file
27
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Writer/BundleWriterInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Writer;
|
||||
|
||||
/**
|
||||
* Writes resource bundle files.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface BundleWriterInterface
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function write(string $path, string $locale, mixed $data);
|
||||
}
|
39
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Writer/JsonBundleWriter.php
vendored
Normal file
39
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Writer/JsonBundleWriter.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Writer;
|
||||
|
||||
/**
|
||||
* Writes .json resource bundles.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class JsonBundleWriter implements BundleWriterInterface
|
||||
{
|
||||
public function write(string $path, string $locale, mixed $data): void
|
||||
{
|
||||
if ($data instanceof \Traversable) {
|
||||
$data = iterator_to_array($data);
|
||||
}
|
||||
|
||||
array_walk_recursive($data, function (&$value) {
|
||||
if ($value instanceof \Traversable) {
|
||||
$value = iterator_to_array($value);
|
||||
}
|
||||
});
|
||||
|
||||
$contents = json_encode($data, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_UNICODE)."\n";
|
||||
|
||||
file_put_contents($path.'/'.$locale.'.json', $contents);
|
||||
}
|
||||
}
|
46
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Writer/PhpBundleWriter.php
vendored
Normal file
46
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Writer/PhpBundleWriter.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Writer;
|
||||
|
||||
use Symfony\Component\VarExporter\VarExporter;
|
||||
|
||||
/**
|
||||
* Writes .php resource bundles.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class PhpBundleWriter implements BundleWriterInterface
|
||||
{
|
||||
public function write(string $path, string $locale, mixed $data): void
|
||||
{
|
||||
$template = <<<'TEMPLATE'
|
||||
<?php
|
||||
|
||||
return %s;
|
||||
|
||||
TEMPLATE;
|
||||
|
||||
if ($data instanceof \Traversable) {
|
||||
$data = iterator_to_array($data);
|
||||
}
|
||||
|
||||
array_walk_recursive($data, function (&$value) {
|
||||
if ($value instanceof \Traversable) {
|
||||
$value = iterator_to_array($value);
|
||||
}
|
||||
});
|
||||
|
||||
file_put_contents($path.'/'.$locale.'.php', sprintf($template, VarExporter::export($data)));
|
||||
}
|
||||
}
|
205
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Writer/TextBundleWriter.php
vendored
Normal file
205
plugins/simplesaml/lib/vendor/symfony/intl/Data/Bundle/Writer/TextBundleWriter.php
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Bundle\Writer;
|
||||
|
||||
/**
|
||||
* Writes .txt resource bundles.
|
||||
*
|
||||
* The resulting files can be converted to binary .res files using a
|
||||
* {@link \Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompilerInterface}
|
||||
* implementation.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TextBundleWriter implements BundleWriterInterface
|
||||
{
|
||||
public function write(string $path, string $locale, mixed $data, bool $fallback = true): void
|
||||
{
|
||||
$file = fopen($path.'/'.$locale.'.txt', 'w');
|
||||
|
||||
$this->writeResourceBundle($file, $locale, $data, $fallback);
|
||||
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a "resourceBundle" node.
|
||||
*
|
||||
* @param resource $file The file handle to write to
|
||||
* @param mixed $value The value of the node
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt
|
||||
*/
|
||||
private function writeResourceBundle($file, string $bundleName, mixed $value, bool $fallback): void
|
||||
{
|
||||
fwrite($file, $bundleName);
|
||||
|
||||
$this->writeTable($file, $value, 0, $fallback);
|
||||
|
||||
fwrite($file, "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a "resource" node.
|
||||
*
|
||||
* @param resource $file The file handle to write to
|
||||
* @param mixed $value The value of the node
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt
|
||||
*/
|
||||
private function writeResource($file, mixed $value, int $indentation, bool $requireBraces = true): void
|
||||
{
|
||||
if (\is_int($value)) {
|
||||
$this->writeInteger($file, $value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($value instanceof \Traversable) {
|
||||
$value = iterator_to_array($value);
|
||||
}
|
||||
|
||||
if (\is_array($value)) {
|
||||
$intValues = \count($value) === \count(array_filter($value, 'is_int'));
|
||||
|
||||
// check that the keys are 0-indexed and ascending
|
||||
$intKeys = array_is_list($value);
|
||||
|
||||
if ($intValues && $intKeys) {
|
||||
$this->writeIntVector($file, $value, $indentation);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($intKeys) {
|
||||
$this->writeArray($file, $value, $indentation);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->writeTable($file, $value, $indentation);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (\is_bool($value)) {
|
||||
$value = $value ? 'true' : 'false';
|
||||
}
|
||||
|
||||
$this->writeString($file, (string) $value, $requireBraces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an "integer" node.
|
||||
*
|
||||
* @param resource $file The file handle to write to
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt
|
||||
*/
|
||||
private function writeInteger($file, int $value): void
|
||||
{
|
||||
fprintf($file, ':int{%d}', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an "intvector" node.
|
||||
*
|
||||
* @param resource $file The file handle to write to
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt
|
||||
*/
|
||||
private function writeIntVector($file, array $value, int $indentation): void
|
||||
{
|
||||
fwrite($file, ":intvector{\n");
|
||||
|
||||
foreach ($value as $int) {
|
||||
fprintf($file, "%s%d,\n", str_repeat(' ', $indentation + 1), $int);
|
||||
}
|
||||
|
||||
fprintf($file, '%s}', str_repeat(' ', $indentation));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a "string" node.
|
||||
*
|
||||
* @param resource $file The file handle to write to
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt
|
||||
*/
|
||||
private function writeString($file, string $value, bool $requireBraces = true): void
|
||||
{
|
||||
if ($requireBraces) {
|
||||
fprintf($file, '{"%s"}', $value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf($file, '"%s"', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an "array" node.
|
||||
*
|
||||
* @param resource $file The file handle to write to
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt
|
||||
*/
|
||||
private function writeArray($file, array $value, int $indentation): void
|
||||
{
|
||||
fwrite($file, "{\n");
|
||||
|
||||
foreach ($value as $entry) {
|
||||
fwrite($file, str_repeat(' ', $indentation + 1));
|
||||
|
||||
$this->writeResource($file, $entry, $indentation + 1, false);
|
||||
|
||||
fwrite($file, ",\n");
|
||||
}
|
||||
|
||||
fprintf($file, '%s}', str_repeat(' ', $indentation));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a "table" node.
|
||||
*
|
||||
* @param resource $file The file handle to write to
|
||||
*/
|
||||
private function writeTable($file, iterable $value, int $indentation, bool $fallback = true): void
|
||||
{
|
||||
if (!$fallback) {
|
||||
fwrite($file, ':table(nofallback)');
|
||||
}
|
||||
|
||||
fwrite($file, "{\n");
|
||||
|
||||
foreach ($value as $key => $entry) {
|
||||
fwrite($file, str_repeat(' ', $indentation + 1));
|
||||
|
||||
// escape colons, otherwise they are interpreted as resource types
|
||||
if (str_contains($key, ':') || str_contains($key, ' ')) {
|
||||
$key = '"'.$key.'"';
|
||||
}
|
||||
|
||||
fwrite($file, $key);
|
||||
|
||||
$this->writeResource($file, $entry, $indentation + 1);
|
||||
|
||||
fwrite($file, "\n");
|
||||
}
|
||||
|
||||
fprintf($file, '%s}', str_repeat(' ', $indentation));
|
||||
}
|
||||
}
|
107
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/AbstractDataGenerator.php
vendored
Normal file
107
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/AbstractDataGenerator.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Generator;
|
||||
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface;
|
||||
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReader;
|
||||
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
|
||||
use Symfony\Component\Intl\Data\Bundle\Reader\IntlBundleReader;
|
||||
use Symfony\Component\Intl\Data\Util\LocaleScanner;
|
||||
|
||||
/**
|
||||
* The rule for compiling the currency bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract class AbstractDataGenerator
|
||||
{
|
||||
private BundleCompilerInterface $compiler;
|
||||
private string $dirName;
|
||||
|
||||
public function __construct(BundleCompilerInterface $compiler, string $dirName)
|
||||
{
|
||||
$this->compiler = $compiler;
|
||||
$this->dirName = $dirName;
|
||||
}
|
||||
|
||||
public function generateData(GeneratorConfig $config): void
|
||||
{
|
||||
$filesystem = new Filesystem();
|
||||
$localeScanner = new LocaleScanner();
|
||||
$reader = new BundleEntryReader(new IntlBundleReader());
|
||||
|
||||
$writers = $config->getBundleWriters();
|
||||
$tempDir = sys_get_temp_dir().'/icu-data-'.$this->dirName;
|
||||
|
||||
// Prepare filesystem directories
|
||||
foreach ($writers as $targetDir => $writer) {
|
||||
$filesystem->remove($targetDir.'/'.$this->dirName);
|
||||
$filesystem->mkdir($targetDir.'/'.$this->dirName);
|
||||
}
|
||||
|
||||
$filesystem->remove($tempDir);
|
||||
$filesystem->mkdir($tempDir);
|
||||
|
||||
$locales = $this->scanLocales($localeScanner, $config->getSourceDir());
|
||||
|
||||
$this->compileTemporaryBundles($this->compiler, $config->getSourceDir(), $tempDir);
|
||||
|
||||
$this->preGenerate();
|
||||
|
||||
foreach ($locales as $locale) {
|
||||
$localeData = $this->generateDataForLocale($reader, $tempDir, $locale);
|
||||
|
||||
if (null !== $localeData) {
|
||||
foreach ($writers as $targetDir => $writer) {
|
||||
$writer->write($targetDir.'/'.$this->dirName, $locale, $localeData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rootData = $this->generateDataForRoot($reader, $tempDir);
|
||||
|
||||
if (null !== $rootData) {
|
||||
foreach ($writers as $targetDir => $writer) {
|
||||
$writer->write($targetDir.'/'.$this->dirName, 'root', $rootData);
|
||||
}
|
||||
}
|
||||
|
||||
$metaData = $this->generateDataForMeta($reader, $tempDir);
|
||||
|
||||
if (null !== $metaData) {
|
||||
foreach ($writers as $targetDir => $writer) {
|
||||
$writer->write($targetDir.'/'.$this->dirName, 'meta', $metaData);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up
|
||||
$filesystem->remove($tempDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
abstract protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array;
|
||||
|
||||
abstract protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir): void;
|
||||
|
||||
abstract protected function preGenerate(): void;
|
||||
|
||||
abstract protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array;
|
||||
|
||||
abstract protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array;
|
||||
|
||||
abstract protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array;
|
||||
}
|
159
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/CurrencyDataGenerator.php
vendored
Normal file
159
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/CurrencyDataGenerator.php
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Generator;
|
||||
|
||||
use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface;
|
||||
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
|
||||
use Symfony\Component\Intl\Data\Util\ArrayAccessibleResourceBundle;
|
||||
use Symfony\Component\Intl\Data\Util\LocaleScanner;
|
||||
|
||||
/**
|
||||
* The rule for compiling the currency bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class CurrencyDataGenerator extends AbstractDataGenerator
|
||||
{
|
||||
private const DENYLIST = [
|
||||
'XBA' => true, // European Composite Unit
|
||||
'XBB' => true, // European Monetary Unit
|
||||
'XBC' => true, // European Unit of Account (XBC)
|
||||
'XBD' => true, // European Unit of Account (XBD)
|
||||
'XUA' => true, // ADB Unit of Account
|
||||
'XAU' => true, // Gold
|
||||
'XAG' => true, // Silver
|
||||
'XPT' => true, // Platinum
|
||||
'XPD' => true, // Palladium
|
||||
'XSU' => true, // Sucre
|
||||
'XDR' => true, // Special Drawing Rights
|
||||
'XTS' => true, // Testing Currency Code
|
||||
'XXX' => true, // Unknown Currency
|
||||
];
|
||||
|
||||
/**
|
||||
* Collects all available currency codes.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private array $currencyCodes = [];
|
||||
|
||||
protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array
|
||||
{
|
||||
return $scanner->scanLocales($sourceDir.'/curr');
|
||||
}
|
||||
|
||||
protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir): void
|
||||
{
|
||||
$compiler->compile($sourceDir.'/curr', $tempDir);
|
||||
$compiler->compile($sourceDir.'/misc/currencyNumericCodes.txt', $tempDir);
|
||||
}
|
||||
|
||||
protected function preGenerate(): void
|
||||
{
|
||||
$this->currencyCodes = [];
|
||||
}
|
||||
|
||||
protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array
|
||||
{
|
||||
$localeBundle = $reader->read($tempDir, $displayLocale);
|
||||
|
||||
if (isset($localeBundle['Currencies']) && null !== $localeBundle['Currencies']) {
|
||||
$data = [
|
||||
'Names' => $this->generateSymbolNamePairs($localeBundle),
|
||||
];
|
||||
|
||||
$this->currencyCodes = array_merge($this->currencyCodes, array_keys($data['Names']));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
$rootBundle = $reader->read($tempDir, 'root');
|
||||
|
||||
return [
|
||||
'Names' => $this->generateSymbolNamePairs($rootBundle),
|
||||
];
|
||||
}
|
||||
|
||||
protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
$supplementalDataBundle = $reader->read($tempDir, 'supplementalData');
|
||||
$numericCodesBundle = $reader->read($tempDir, 'currencyNumericCodes');
|
||||
|
||||
$this->currencyCodes = array_unique($this->currencyCodes);
|
||||
|
||||
sort($this->currencyCodes);
|
||||
|
||||
$data = [
|
||||
'Currencies' => $this->currencyCodes,
|
||||
'Meta' => $this->generateCurrencyMeta($supplementalDataBundle),
|
||||
'Alpha3ToNumeric' => $this->generateAlpha3ToNumericMapping($numericCodesBundle, $this->currencyCodes),
|
||||
];
|
||||
|
||||
$data['NumericToAlpha3'] = $this->generateNumericToAlpha3Mapping($data['Alpha3ToNumeric']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function generateSymbolNamePairs(ArrayAccessibleResourceBundle $rootBundle): array
|
||||
{
|
||||
$symbolNamePairs = array_map(fn ($pair) => \array_slice(iterator_to_array($pair), 0, 2), iterator_to_array($rootBundle['Currencies']));
|
||||
|
||||
// Remove unwanted currencies
|
||||
$symbolNamePairs = array_diff_key($symbolNamePairs, self::DENYLIST);
|
||||
|
||||
return $symbolNamePairs;
|
||||
}
|
||||
|
||||
private function generateCurrencyMeta(ArrayAccessibleResourceBundle $supplementalDataBundle): array
|
||||
{
|
||||
// The metadata is already de-duplicated. It contains one key "DEFAULT"
|
||||
// which is used for currencies that don't have dedicated entries.
|
||||
return iterator_to_array($supplementalDataBundle['CurrencyMeta']);
|
||||
}
|
||||
|
||||
private function generateAlpha3ToNumericMapping(ArrayAccessibleResourceBundle $numericCodesBundle, array $currencyCodes): array
|
||||
{
|
||||
$alpha3ToNumericMapping = iterator_to_array($numericCodesBundle['codeMap']);
|
||||
|
||||
asort($alpha3ToNumericMapping);
|
||||
|
||||
// Filter unknown currencies (e.g. "AYM")
|
||||
$alpha3ToNumericMapping = array_intersect_key($alpha3ToNumericMapping, array_flip($currencyCodes));
|
||||
|
||||
return $alpha3ToNumericMapping;
|
||||
}
|
||||
|
||||
private function generateNumericToAlpha3Mapping(array $alpha3ToNumericMapping): array
|
||||
{
|
||||
$numericToAlpha3Mapping = [];
|
||||
|
||||
foreach ($alpha3ToNumericMapping as $alpha3 => $numeric) {
|
||||
// Make sure that the mapping is stored as table and not as array
|
||||
$numeric = (string) $numeric;
|
||||
|
||||
if (!isset($numericToAlpha3Mapping[$numeric])) {
|
||||
$numericToAlpha3Mapping[$numeric] = [];
|
||||
}
|
||||
|
||||
$numericToAlpha3Mapping[$numeric][] = $alpha3;
|
||||
}
|
||||
|
||||
return $numericToAlpha3Mapping;
|
||||
}
|
||||
}
|
58
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/FallbackTrait.php
vendored
Normal file
58
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/FallbackTrait.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Generator;
|
||||
|
||||
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
|
||||
use Symfony\Component\Intl\Locale;
|
||||
|
||||
/**
|
||||
* @author Roland Franssen <franssen.roland@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait FallbackTrait
|
||||
{
|
||||
private array $fallbackCache = [];
|
||||
private bool $generatingFallback = false;
|
||||
|
||||
/**
|
||||
* @see AbstractDataGenerator::generateDataForLocale()
|
||||
*/
|
||||
abstract protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array;
|
||||
|
||||
/**
|
||||
* @see AbstractDataGenerator::generateDataForRoot()
|
||||
*/
|
||||
abstract protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array;
|
||||
|
||||
private function generateFallbackData(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): array
|
||||
{
|
||||
if (null === $fallback = Locale::getFallback($displayLocale)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (isset($this->fallbackCache[$fallback])) {
|
||||
return $this->fallbackCache[$fallback];
|
||||
}
|
||||
|
||||
$prevGeneratingFallback = $this->generatingFallback;
|
||||
$this->generatingFallback = true;
|
||||
|
||||
try {
|
||||
$data = 'root' === $fallback ? $this->generateDataForRoot($reader, $tempDir) : $this->generateDataForLocale($reader, $tempDir, $fallback);
|
||||
} finally {
|
||||
$this->generatingFallback = $prevGeneratingFallback;
|
||||
}
|
||||
|
||||
return $this->fallbackCache[$fallback] = $data ?: [];
|
||||
}
|
||||
}
|
73
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/GeneratorConfig.php
vendored
Normal file
73
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/GeneratorConfig.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Generator;
|
||||
|
||||
use Symfony\Component\Intl\Data\Bundle\Writer\BundleWriterInterface;
|
||||
|
||||
/**
|
||||
* Stores contextual information for resource bundle generation.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class GeneratorConfig
|
||||
{
|
||||
private string $sourceDir;
|
||||
private string $icuVersion;
|
||||
|
||||
/**
|
||||
* @var BundleWriterInterface[]
|
||||
*/
|
||||
private array $bundleWriters = [];
|
||||
|
||||
public function __construct(string $sourceDir, string $icuVersion)
|
||||
{
|
||||
$this->sourceDir = $sourceDir;
|
||||
$this->icuVersion = $icuVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a writer to be used during the data conversion.
|
||||
*/
|
||||
public function addBundleWriter(string $targetDir, BundleWriterInterface $writer): void
|
||||
{
|
||||
$this->bundleWriters[$targetDir] = $writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the writers indexed by their output directories.
|
||||
*
|
||||
* @return BundleWriterInterface[]
|
||||
*/
|
||||
public function getBundleWriters(): array
|
||||
{
|
||||
return $this->bundleWriters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory where the source versions of the resource bundles
|
||||
* are stored.
|
||||
*/
|
||||
public function getSourceDir(): string
|
||||
{
|
||||
return $this->sourceDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ICU version of the bundles being converted.
|
||||
*/
|
||||
public function getIcuVersion(): string
|
||||
{
|
||||
return $this->icuVersion;
|
||||
}
|
||||
}
|
234
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/LanguageDataGenerator.php
vendored
Normal file
234
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/LanguageDataGenerator.php
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Generator;
|
||||
|
||||
use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface;
|
||||
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
|
||||
use Symfony\Component\Intl\Data\Util\ArrayAccessibleResourceBundle;
|
||||
use Symfony\Component\Intl\Data\Util\LocaleScanner;
|
||||
use Symfony\Component\Intl\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* The rule for compiling the language bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LanguageDataGenerator extends AbstractDataGenerator
|
||||
{
|
||||
/**
|
||||
* Source: https://iso639-3.sil.org/code_tables/639/data.
|
||||
*/
|
||||
private const PREFERRED_ALPHA2_TO_ALPHA3_MAPPING = [
|
||||
'ak' => 'aka',
|
||||
'ar' => 'ara',
|
||||
'ay' => 'aym',
|
||||
'az' => 'aze',
|
||||
'bo' => 'bod',
|
||||
'cr' => 'cre',
|
||||
'cs' => 'ces',
|
||||
'cy' => 'cym',
|
||||
'de' => 'deu',
|
||||
'dz' => 'dzo',
|
||||
'el' => 'ell',
|
||||
'et' => 'est',
|
||||
'eu' => 'eus',
|
||||
'fa' => 'fas',
|
||||
'ff' => 'ful',
|
||||
'fr' => 'fra',
|
||||
'gn' => 'grn',
|
||||
'hy' => 'hye',
|
||||
'hr' => 'hrv',
|
||||
'ik' => 'ipk',
|
||||
'is' => 'isl',
|
||||
'iu' => 'iku',
|
||||
'ka' => 'kat',
|
||||
'kr' => 'kau',
|
||||
'kg' => 'kon',
|
||||
'kv' => 'kom',
|
||||
'ku' => 'kur',
|
||||
'lv' => 'lav',
|
||||
'mg' => 'mlg',
|
||||
'mi' => 'mri',
|
||||
'mk' => 'mkd',
|
||||
'mn' => 'mon',
|
||||
'ms' => 'msa',
|
||||
'my' => 'mya',
|
||||
'nb' => 'nob',
|
||||
'ne' => 'nep',
|
||||
'nl' => 'nld',
|
||||
'oj' => 'oji',
|
||||
'om' => 'orm',
|
||||
'or' => 'ori',
|
||||
'ps' => 'pus',
|
||||
'qu' => 'que',
|
||||
'ro' => 'ron',
|
||||
'sc' => 'srd',
|
||||
'sk' => 'slk',
|
||||
'sq' => 'sqi',
|
||||
'sr' => 'srp',
|
||||
'sw' => 'swa',
|
||||
'uz' => 'uzb',
|
||||
'yi' => 'yid',
|
||||
'za' => 'zha',
|
||||
'zh' => 'zho',
|
||||
];
|
||||
private const DENYLIST = [
|
||||
'root' => true, // Absolute root language
|
||||
'mul' => true, // Multiple languages
|
||||
'mis' => true, // Uncoded language
|
||||
'und' => true, // Unknown language
|
||||
'zxx' => true, // No linguistic content
|
||||
];
|
||||
|
||||
/**
|
||||
* Collects all available language codes.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private array $languageCodes = [];
|
||||
|
||||
protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array
|
||||
{
|
||||
return $scanner->scanLocales($sourceDir.'/lang');
|
||||
}
|
||||
|
||||
protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir): void
|
||||
{
|
||||
$compiler->compile($sourceDir.'/lang', $tempDir);
|
||||
$compiler->compile($sourceDir.'/misc/metadata.txt', $tempDir);
|
||||
}
|
||||
|
||||
protected function preGenerate(): void
|
||||
{
|
||||
$this->languageCodes = [];
|
||||
}
|
||||
|
||||
protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array
|
||||
{
|
||||
$localeBundle = $reader->read($tempDir, $displayLocale);
|
||||
|
||||
// isset() on \ResourceBundle returns true even if the value is null
|
||||
if (isset($localeBundle['Languages']) && null !== $localeBundle['Languages']) {
|
||||
$names = [];
|
||||
$localizedNames = [];
|
||||
foreach (self::generateLanguageNames($localeBundle) as $language => $name) {
|
||||
if (!str_contains($language, '_')) {
|
||||
$this->languageCodes[] = $language;
|
||||
$names[$language] = $name;
|
||||
} else {
|
||||
$localizedNames[$language] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'Names' => $names,
|
||||
'LocalizedNames' => $localizedNames,
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
$metadataBundle = $reader->read($tempDir, 'metadata');
|
||||
|
||||
$this->languageCodes = array_unique($this->languageCodes);
|
||||
|
||||
sort($this->languageCodes);
|
||||
|
||||
return [
|
||||
'Languages' => $this->languageCodes,
|
||||
'Alpha3Languages' => $this->generateAlpha3Codes($this->languageCodes, $metadataBundle),
|
||||
'Alpha2ToAlpha3' => $this->generateAlpha2ToAlpha3Mapping($metadataBundle),
|
||||
'Alpha3ToAlpha2' => $this->generateAlpha3ToAlpha2Mapping($metadataBundle),
|
||||
];
|
||||
}
|
||||
|
||||
private static function generateLanguageNames(ArrayAccessibleResourceBundle $localeBundle): array
|
||||
{
|
||||
return array_diff_key(iterator_to_array($localeBundle['Languages']), self::DENYLIST);
|
||||
}
|
||||
|
||||
private function generateAlpha3Codes(array $languageCodes, ArrayAccessibleResourceBundle $metadataBundle): array
|
||||
{
|
||||
$alpha3Codes = array_flip(array_filter($languageCodes, static fn (string $language): bool => 3 === \strlen($language)));
|
||||
|
||||
foreach ($metadataBundle['alias']['language'] as $alias => $data) {
|
||||
if (3 === \strlen($alias) && 'overlong' === $data['reason']) {
|
||||
$alpha3Codes[$alias] = true;
|
||||
}
|
||||
}
|
||||
|
||||
ksort($alpha3Codes);
|
||||
|
||||
return array_keys($alpha3Codes);
|
||||
}
|
||||
|
||||
private function generateAlpha2ToAlpha3Mapping(ArrayAccessibleResourceBundle $metadataBundle): array
|
||||
{
|
||||
$aliases = iterator_to_array($metadataBundle['alias']['language']);
|
||||
$alpha2ToAlpha3 = [];
|
||||
|
||||
foreach ($aliases as $alias => $data) {
|
||||
$language = $data['replacement'];
|
||||
if (2 === \strlen($language) && 3 === \strlen($alias) && 'overlong' === $data['reason']) {
|
||||
if (isset(self::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING[$language])) {
|
||||
// Validate to prevent typos
|
||||
if (!isset($aliases[self::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING[$language]])) {
|
||||
throw new RuntimeException('The statically set three-letter mapping '.self::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING[$language].' for the language code '.$language.' seems to be invalid. Typo?');
|
||||
}
|
||||
|
||||
$alpha3 = self::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING[$language];
|
||||
$alpha2 = $aliases[$alpha3]['replacement'];
|
||||
|
||||
if ($language !== $alpha2) {
|
||||
throw new RuntimeException('The statically set three-letter mapping '.$alpha3.' for the language code '.$language.' seems to be an alias for '.$alpha2.'. Wrong mapping?');
|
||||
}
|
||||
|
||||
$alpha2ToAlpha3[$language] = $alpha3;
|
||||
} elseif (isset($alpha2ToAlpha3[$language])) {
|
||||
throw new RuntimeException('Multiple three-letter mappings exist for the language code '.$language.'. Please add one of them to the const PREFERRED_ALPHA2_TO_ALPHA3_MAPPING.');
|
||||
} else {
|
||||
$alpha2ToAlpha3[$language] = $alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asort($alpha2ToAlpha3);
|
||||
|
||||
return $alpha2ToAlpha3;
|
||||
}
|
||||
|
||||
private function generateAlpha3ToAlpha2Mapping(ArrayAccessibleResourceBundle $metadataBundle): array
|
||||
{
|
||||
$alpha3ToAlpha2 = [];
|
||||
|
||||
foreach ($metadataBundle['alias']['language'] as $alias => $data) {
|
||||
$language = $data['replacement'];
|
||||
if (2 === \strlen($language) && 3 === \strlen($alias) && \in_array($data['reason'], ['overlong', 'bibliographic'], true)) {
|
||||
$alpha3ToAlpha2[$alias] = $language;
|
||||
}
|
||||
}
|
||||
|
||||
asort($alpha3ToAlpha2);
|
||||
|
||||
return $alpha3ToAlpha2;
|
||||
}
|
||||
}
|
167
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/LocaleDataGenerator.php
vendored
Normal file
167
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/LocaleDataGenerator.php
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Generator;
|
||||
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface;
|
||||
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
|
||||
use Symfony\Component\Intl\Data\Util\LocaleScanner;
|
||||
use Symfony\Component\Intl\Exception\MissingResourceException;
|
||||
|
||||
/**
|
||||
* The rule for compiling the locale bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
* @author Roland Franssen <franssen.roland@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LocaleDataGenerator extends AbstractDataGenerator
|
||||
{
|
||||
use FallbackTrait;
|
||||
|
||||
private array $locales = [];
|
||||
private array $localeAliases = [];
|
||||
private array $localeParents = [];
|
||||
|
||||
protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array
|
||||
{
|
||||
$this->locales = $scanner->scanLocales($sourceDir.'/locales');
|
||||
$this->localeAliases = $scanner->scanAliases($sourceDir.'/locales');
|
||||
$this->localeParents = $scanner->scanParents($sourceDir.'/locales');
|
||||
|
||||
return $this->locales;
|
||||
}
|
||||
|
||||
protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir): void
|
||||
{
|
||||
$filesystem = new Filesystem();
|
||||
$filesystem->mkdir([
|
||||
$tempDir.'/lang',
|
||||
$tempDir.'/region',
|
||||
]);
|
||||
$compiler->compile($sourceDir.'/lang', $tempDir.'/lang');
|
||||
$compiler->compile($sourceDir.'/region', $tempDir.'/region');
|
||||
}
|
||||
|
||||
protected function preGenerate(): void
|
||||
{
|
||||
// Write parents locale file for the Translation component
|
||||
file_put_contents(
|
||||
__DIR__.'/../../../Translation/Resources/data/parents.json',
|
||||
json_encode($this->localeParents, \JSON_PRETTY_PRINT).\PHP_EOL
|
||||
);
|
||||
}
|
||||
|
||||
protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array
|
||||
{
|
||||
// Don't generate aliases, as they are resolved during runtime
|
||||
// Unless an alias is needed as fallback for de-duplication purposes
|
||||
if (isset($this->localeAliases[$displayLocale]) && !$this->generatingFallback) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Generate locale names for all locales that have translations in
|
||||
// at least the language or the region bundle
|
||||
$displayFormat = $reader->readEntry($tempDir.'/lang', $displayLocale, ['localeDisplayPattern']);
|
||||
$pattern = $displayFormat['pattern'] ?? '{0} ({1})';
|
||||
$separator = $displayFormat['separator'] ?? '{0}, {1}';
|
||||
$localeNames = [];
|
||||
foreach ($this->locales as $locale) {
|
||||
// Ensure a normalized list of pure locales
|
||||
if (\Locale::getAllVariants($locale)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// Generate a locale name in the language of each display locale
|
||||
// Each locale name has the form: "Language (Script, Region, Variant1, ...)
|
||||
// Script, Region and Variants are optional. If none of them is
|
||||
// available, the braces are not printed.
|
||||
$localeNames[$locale] = $this->generateLocaleName($reader, $tempDir, $locale, $displayLocale, $pattern, $separator);
|
||||
} catch (MissingResourceException) {
|
||||
// Silently ignore incomplete locale names
|
||||
// In this case one should configure at least one fallback locale that is complete (e.g. English) during
|
||||
// runtime. Alternatively a translation for the missing resource can be proposed upstream.
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'Names' => $localeNames,
|
||||
];
|
||||
|
||||
// Don't de-duplicate a fallback locale
|
||||
// Ensures the display locale can be de-duplicated on itself
|
||||
if ($this->generatingFallback) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
// Process again to de-duplicate locale and its fallback locales
|
||||
// Only keep the differences
|
||||
$fallbackData = $this->generateFallbackData($reader, $tempDir, $displayLocale);
|
||||
if (isset($fallbackData['Names'])) {
|
||||
$data['Names'] = array_diff($data['Names'], $fallbackData['Names']);
|
||||
}
|
||||
if (!$data['Names']) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
return [
|
||||
'Locales' => $this->locales,
|
||||
'Aliases' => $this->localeAliases,
|
||||
];
|
||||
}
|
||||
|
||||
private function generateLocaleName(BundleEntryReaderInterface $reader, string $tempDir, string $locale, string $displayLocale, string $pattern, string $separator): string
|
||||
{
|
||||
// Apply generic notation using square brackets as described per http://cldr.unicode.org/translation/language-names
|
||||
$name = str_replace(['(', ')'], ['[', ']'], $reader->readEntry($tempDir.'/lang', $displayLocale, ['Languages', \Locale::getPrimaryLanguage($locale)]));
|
||||
$extras = [];
|
||||
|
||||
// Discover the name of the script part of the locale
|
||||
// i.e. in zh_Hans_MO, "Hans" is the script
|
||||
if ($script = \Locale::getScript($locale)) {
|
||||
$extras[] = str_replace(['(', ')'], ['[', ']'], $reader->readEntry($tempDir.'/lang', $displayLocale, ['Scripts', $script]));
|
||||
}
|
||||
|
||||
// Discover the name of the region part of the locale
|
||||
// i.e. in de_AT, "AT" is the region
|
||||
if ($region = \Locale::getRegion($locale)) {
|
||||
if (ctype_alpha($region) && !RegionDataGenerator::isValidCountryCode($region)) {
|
||||
throw new MissingResourceException(sprintf('Skipping "%s" due an invalid country.', $locale));
|
||||
}
|
||||
|
||||
$extras[] = str_replace(['(', ')'], ['[', ']'], $reader->readEntry($tempDir.'/region', $displayLocale, ['Countries', $region]));
|
||||
}
|
||||
|
||||
if ($extras) {
|
||||
$extra = array_shift($extras);
|
||||
foreach ($extras as $part) {
|
||||
$extra = str_replace(['{0}', '{1}'], [$extra, $part], $separator);
|
||||
}
|
||||
|
||||
$name = str_replace(['{0}', '{1}'], [$name, $extra], $pattern);
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
}
|
264
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/RegionDataGenerator.php
vendored
Normal file
264
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/RegionDataGenerator.php
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Generator;
|
||||
|
||||
use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface;
|
||||
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
|
||||
use Symfony\Component\Intl\Data\Util\ArrayAccessibleResourceBundle;
|
||||
use Symfony\Component\Intl\Data\Util\LocaleScanner;
|
||||
use Symfony\Component\Intl\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* The rule for compiling the region bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icu4j/trunk/main/classes/core/src/com/ibm/icu/util/Region.java
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class RegionDataGenerator extends AbstractDataGenerator
|
||||
{
|
||||
/**
|
||||
* Source: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes.
|
||||
*/
|
||||
private const PREFERRED_ALPHA2_TO_ALPHA3_MAPPING = [
|
||||
'CD' => 'COD',
|
||||
'DE' => 'DEU',
|
||||
'FR' => 'FRA',
|
||||
'MM' => 'MMR',
|
||||
'TL' => 'TLS',
|
||||
'YE' => 'YEM',
|
||||
];
|
||||
|
||||
private const DENYLIST = [
|
||||
// Exceptional reservations
|
||||
'AC' => true, // Ascension Island
|
||||
'CP' => true, // Clipperton Island
|
||||
'CQ' => true, // Island of Sark
|
||||
'DG' => true, // Diego Garcia
|
||||
'EA' => true, // Ceuta & Melilla
|
||||
'EU' => true, // European Union
|
||||
'EZ' => true, // Eurozone
|
||||
'IC' => true, // Canary Islands
|
||||
'TA' => true, // Tristan da Cunha
|
||||
'UN' => true, // United Nations
|
||||
// User-assigned
|
||||
'QO' => true, // Outlying Oceania
|
||||
'XA' => true, // Pseudo-Accents
|
||||
'XB' => true, // Pseudo-Bidi
|
||||
'XK' => true, // Kosovo
|
||||
// Misc
|
||||
'ZZ' => true, // Unknown Region
|
||||
];
|
||||
|
||||
// @see https://en.wikipedia.org/wiki/ISO_3166-1_numeric#Withdrawn_codes
|
||||
private const WITHDRAWN_CODES = [
|
||||
128, // Canton and Enderbury Islands
|
||||
200, // Czechoslovakia
|
||||
216, // Dronning Maud Land
|
||||
230, // Ethiopia
|
||||
249, // France, Metropolitan
|
||||
278, // German Democratic Republic
|
||||
280, // Germany, Federal Republic of
|
||||
396, // Johnston Island
|
||||
488, // Midway Islands
|
||||
530, // Netherlands Antilles
|
||||
532, // Netherlands Antilles
|
||||
536, // Neutral Zone
|
||||
582, // Pacific Islands (Trust Territory)
|
||||
590, // Panama
|
||||
658, // Saint Kitts-Nevis-Anguilla
|
||||
720, // Yemen, Democratic
|
||||
736, // Sudan
|
||||
810, // USSR
|
||||
849, // United States Miscellaneous Pacific Islands
|
||||
872, // Wake Island
|
||||
886, // Yemen Arab Republic
|
||||
890, // Yugoslavia, Socialist Federal Republic of
|
||||
891, // Serbia and Montenegro
|
||||
];
|
||||
|
||||
/**
|
||||
* Collects all available language codes.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private array $regionCodes = [];
|
||||
|
||||
public static function isValidCountryCode(int|string|null $region): bool
|
||||
{
|
||||
if (isset(self::DENYLIST[$region])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// WORLD/CONTINENT/SUBCONTINENT/GROUPING
|
||||
if (\is_int($region) || ctype_digit($region)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array
|
||||
{
|
||||
return $scanner->scanLocales($sourceDir.'/region');
|
||||
}
|
||||
|
||||
protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir): void
|
||||
{
|
||||
$compiler->compile($sourceDir.'/region', $tempDir);
|
||||
$compiler->compile($sourceDir.'/misc/metadata.txt', $tempDir);
|
||||
}
|
||||
|
||||
protected function preGenerate(): void
|
||||
{
|
||||
$this->regionCodes = [];
|
||||
}
|
||||
|
||||
protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array
|
||||
{
|
||||
$localeBundle = $reader->read($tempDir, $displayLocale);
|
||||
|
||||
// isset() on \ResourceBundle returns true even if the value is null
|
||||
if (isset($localeBundle['Countries']) && null !== $localeBundle['Countries']) {
|
||||
$data = [
|
||||
'Names' => $this->generateRegionNames($localeBundle),
|
||||
];
|
||||
|
||||
$this->regionCodes = array_merge($this->regionCodes, array_keys($data['Names']));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
$metadataBundle = $reader->read($tempDir, 'metadata');
|
||||
|
||||
$this->regionCodes = array_unique($this->regionCodes);
|
||||
|
||||
sort($this->regionCodes);
|
||||
|
||||
$alpha2ToAlpha3 = $this->generateAlpha2ToAlpha3Mapping(array_flip($this->regionCodes), $metadataBundle);
|
||||
$alpha3ToAlpha2 = array_flip($alpha2ToAlpha3);
|
||||
asort($alpha3ToAlpha2);
|
||||
|
||||
$alpha2ToNumeric = $this->generateAlpha2ToNumericMapping($metadataBundle);
|
||||
$numericToAlpha2 = [];
|
||||
foreach ($alpha2ToNumeric as $alpha2 => $numeric) {
|
||||
// Add underscore prefix to force keys with leading zeros to remain as string keys.
|
||||
$numericToAlpha2['_'.$numeric] = $alpha2;
|
||||
}
|
||||
|
||||
asort($numericToAlpha2);
|
||||
|
||||
return [
|
||||
'Regions' => $this->regionCodes,
|
||||
'Alpha2ToAlpha3' => $alpha2ToAlpha3,
|
||||
'Alpha3ToAlpha2' => $alpha3ToAlpha2,
|
||||
'Alpha2ToNumeric' => $alpha2ToNumeric,
|
||||
'NumericToAlpha2' => $numericToAlpha2,
|
||||
];
|
||||
}
|
||||
|
||||
protected function generateRegionNames(ArrayAccessibleResourceBundle $localeBundle): array
|
||||
{
|
||||
$unfilteredRegionNames = iterator_to_array($localeBundle['Countries']);
|
||||
$regionNames = [];
|
||||
|
||||
foreach ($unfilteredRegionNames as $region => $regionName) {
|
||||
if (!self::isValidCountryCode($region)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$regionNames[$region] = $regionName;
|
||||
}
|
||||
|
||||
return $regionNames;
|
||||
}
|
||||
|
||||
private function generateAlpha2ToAlpha3Mapping(array $countries, ArrayAccessibleResourceBundle $metadataBundle): array
|
||||
{
|
||||
$aliases = iterator_to_array($metadataBundle['alias']['territory']);
|
||||
|
||||
$alpha2ToAlpha3 = [];
|
||||
|
||||
foreach ($aliases as $alias => $data) {
|
||||
$country = $data['replacement'];
|
||||
|
||||
if (2 === \strlen($country) && 3 === \strlen($alias) && 'overlong' === $data['reason']) {
|
||||
if (isset(self::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING[$country])) {
|
||||
// Validate to prevent typos
|
||||
if (!isset($aliases[self::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING[$country]])) {
|
||||
throw new RuntimeException('The statically set three-letter mapping '.self::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING[$country].' for the country code '.$country.' seems to be invalid. Typo?');
|
||||
}
|
||||
|
||||
$alpha3 = self::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING[$country];
|
||||
$alpha2 = $aliases[$alpha3]['replacement'];
|
||||
|
||||
if ($country !== $alpha2) {
|
||||
throw new RuntimeException('The statically set three-letter mapping '.$alpha3.' for the country code '.$country.' seems to be an alias for '.$alpha2.'. Wrong mapping?');
|
||||
}
|
||||
|
||||
$alpha2ToAlpha3[$country] = $alpha3;
|
||||
} elseif (isset($alpha2ToAlpha3[$country])) {
|
||||
throw new RuntimeException('Multiple three-letter mappings exist for the country code '.$country.'. Please add one of them to the const PREFERRED_ALPHA2_TO_ALPHA3_MAPPING.');
|
||||
} elseif (isset($countries[$country]) && self::isValidCountryCode($alias)) {
|
||||
$alpha2ToAlpha3[$country] = $alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asort($alpha2ToAlpha3);
|
||||
|
||||
return $alpha2ToAlpha3;
|
||||
}
|
||||
|
||||
private function generateAlpha2ToNumericMapping(ArrayAccessibleResourceBundle $metadataBundle): array
|
||||
{
|
||||
$aliases = iterator_to_array($metadataBundle['alias']['territory']);
|
||||
|
||||
$alpha2ToNumeric = [];
|
||||
|
||||
foreach ($aliases as $alias => $data) {
|
||||
if (!is_numeric($alias)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (\in_array($alias, self::WITHDRAWN_CODES)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset(self::DENYLIST[$data['replacement']])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('deprecated' === $data['reason']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$alpha2ToNumeric[$data['replacement']] = (string) $alias;
|
||||
}
|
||||
|
||||
ksort($alpha2ToNumeric);
|
||||
|
||||
return $alpha2ToNumeric;
|
||||
}
|
||||
}
|
86
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/ScriptDataGenerator.php
vendored
Normal file
86
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/ScriptDataGenerator.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Generator;
|
||||
|
||||
use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface;
|
||||
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
|
||||
use Symfony\Component\Intl\Data\Util\LocaleScanner;
|
||||
|
||||
/**
|
||||
* The rule for compiling the script bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ScriptDataGenerator extends AbstractDataGenerator
|
||||
{
|
||||
private const DENYLIST = [
|
||||
'Zzzz' => true, // Unknown Script
|
||||
];
|
||||
|
||||
/**
|
||||
* Collects all available language codes.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private array $scriptCodes = [];
|
||||
|
||||
protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array
|
||||
{
|
||||
return $scanner->scanLocales($sourceDir.'/lang');
|
||||
}
|
||||
|
||||
protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir): void
|
||||
{
|
||||
$compiler->compile($sourceDir.'/lang', $tempDir);
|
||||
}
|
||||
|
||||
protected function preGenerate(): void
|
||||
{
|
||||
$this->scriptCodes = [];
|
||||
}
|
||||
|
||||
protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array
|
||||
{
|
||||
$localeBundle = $reader->read($tempDir, $displayLocale);
|
||||
|
||||
// isset() on \ResourceBundle returns true even if the value is null
|
||||
if (isset($localeBundle['Scripts']) && null !== $localeBundle['Scripts']) {
|
||||
$data = [
|
||||
'Names' => array_diff_key(iterator_to_array($localeBundle['Scripts']), self::DENYLIST),
|
||||
];
|
||||
|
||||
$this->scriptCodes = array_merge($this->scriptCodes, array_keys($data['Names']));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
$this->scriptCodes = array_unique($this->scriptCodes);
|
||||
|
||||
sort($this->scriptCodes);
|
||||
|
||||
return [
|
||||
'Scripts' => $this->scriptCodes,
|
||||
];
|
||||
}
|
||||
}
|
274
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/TimezoneDataGenerator.php
vendored
Normal file
274
plugins/simplesaml/lib/vendor/symfony/intl/Data/Generator/TimezoneDataGenerator.php
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Generator;
|
||||
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface;
|
||||
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
|
||||
use Symfony\Component\Intl\Data\Util\ArrayAccessibleResourceBundle;
|
||||
use Symfony\Component\Intl\Data\Util\LocaleScanner;
|
||||
use Symfony\Component\Intl\Exception\MissingResourceException;
|
||||
use Symfony\Component\Intl\Locale;
|
||||
|
||||
/**
|
||||
* The rule for compiling the zone bundle.
|
||||
*
|
||||
* @author Roland Franssen <franssen.roland@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TimezoneDataGenerator extends AbstractDataGenerator
|
||||
{
|
||||
use FallbackTrait;
|
||||
|
||||
/**
|
||||
* Collects all available zone IDs.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private array $zoneIds = [];
|
||||
private array $zoneToCountryMapping = [];
|
||||
private array $localeAliases = [];
|
||||
|
||||
protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array
|
||||
{
|
||||
$this->localeAliases = $scanner->scanAliases($sourceDir.'/locales');
|
||||
|
||||
return $scanner->scanLocales($sourceDir.'/zone');
|
||||
}
|
||||
|
||||
protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir): void
|
||||
{
|
||||
$filesystem = new Filesystem();
|
||||
$filesystem->mkdir($tempDir.'/region');
|
||||
$compiler->compile($sourceDir.'/region', $tempDir.'/region');
|
||||
$compiler->compile($sourceDir.'/zone', $tempDir);
|
||||
$compiler->compile($sourceDir.'/misc/timezoneTypes.txt', $tempDir);
|
||||
$compiler->compile($sourceDir.'/misc/metaZones.txt', $tempDir);
|
||||
$compiler->compile($sourceDir.'/misc/windowsZones.txt', $tempDir);
|
||||
}
|
||||
|
||||
protected function preGenerate(): void
|
||||
{
|
||||
$this->zoneIds = [];
|
||||
$this->zoneToCountryMapping = [];
|
||||
}
|
||||
|
||||
protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array
|
||||
{
|
||||
if (!$this->zoneToCountryMapping) {
|
||||
$this->zoneToCountryMapping = self::generateZoneToCountryMapping($reader->read($tempDir, 'windowsZones'));
|
||||
}
|
||||
|
||||
// Don't generate aliases, as they are resolved during runtime
|
||||
// Unless an alias is needed as fallback for de-duplication purposes
|
||||
if (isset($this->localeAliases[$displayLocale]) && !$this->generatingFallback) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$localeBundle = $reader->read($tempDir, $displayLocale);
|
||||
|
||||
if (!isset($localeBundle['zoneStrings']) || null === $localeBundle['zoneStrings']) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'Names' => $this->generateZones($reader, $tempDir, $displayLocale),
|
||||
'Meta' => self::generateZoneMetadata($localeBundle),
|
||||
];
|
||||
|
||||
// Don't de-duplicate a fallback locale
|
||||
// Ensures the display locale can be de-duplicated on itself
|
||||
if ($this->generatingFallback) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
// Process again to de-duplicate locales and their fallback locales
|
||||
// Only keep the differences
|
||||
$fallback = $this->generateFallbackData($reader, $tempDir, $displayLocale);
|
||||
if (isset($fallback['Names'])) {
|
||||
$data['Names'] = array_diff($data['Names'], $fallback['Names']);
|
||||
}
|
||||
if (isset($fallback['Meta'])) {
|
||||
$data['Meta'] = array_diff($data['Meta'], $fallback['Meta']);
|
||||
}
|
||||
if (!$data['Names'] && !$data['Meta']) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->zoneIds = array_merge($this->zoneIds, array_keys($data['Names']));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
$rootBundle = $reader->read($tempDir, 'root');
|
||||
|
||||
return [
|
||||
'Meta' => self::generateZoneMetadata($rootBundle),
|
||||
];
|
||||
}
|
||||
|
||||
protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array
|
||||
{
|
||||
$rootBundle = $reader->read($tempDir, 'root');
|
||||
|
||||
$this->zoneIds = array_unique($this->zoneIds);
|
||||
|
||||
sort($this->zoneIds);
|
||||
ksort($this->zoneToCountryMapping);
|
||||
|
||||
$data = [
|
||||
'Zones' => $this->zoneIds,
|
||||
'ZoneToCountry' => $this->zoneToCountryMapping,
|
||||
'CountryToZone' => self::generateCountryToZoneMapping($this->zoneToCountryMapping),
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function generateZones(BundleEntryReaderInterface $reader, string $tempDir, string $locale): array
|
||||
{
|
||||
$typeBundle = $reader->read($tempDir, 'timezoneTypes');
|
||||
$available = [];
|
||||
foreach ($typeBundle['typeMap']['timezone'] as $zone => $_) {
|
||||
if ('Etc:Unknown' === $zone || preg_match('~^Etc:GMT[-+]\d+$~', $zone)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$available[$zone] = true;
|
||||
}
|
||||
|
||||
$metaBundle = $reader->read($tempDir, 'metaZones');
|
||||
$metazones = [];
|
||||
foreach ($metaBundle['metazoneInfo'] as $zone => $info) {
|
||||
foreach ($info as $metazone) {
|
||||
$metazones[$zone] = $metazone->get(0);
|
||||
}
|
||||
}
|
||||
|
||||
$regionFormat = $reader->readEntry($tempDir, $locale, ['zoneStrings', 'regionFormat']);
|
||||
$fallbackFormat = $reader->readEntry($tempDir, $locale, ['zoneStrings', 'fallbackFormat']);
|
||||
$resolveName = function (string $id, ?string $city = null) use ($reader, $tempDir, $locale, $regionFormat, $fallbackFormat): ?string {
|
||||
// Resolve default name as described per http://cldr.unicode.org/translation/timezones
|
||||
if (isset($this->zoneToCountryMapping[$id])) {
|
||||
try {
|
||||
$country = $reader->readEntry($tempDir.'/region', $locale, ['Countries', $this->zoneToCountryMapping[$id]]);
|
||||
} catch (MissingResourceException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$name = str_replace('{0}', $country, $regionFormat);
|
||||
|
||||
return null === $city ? $name : str_replace(['{0}', '{1}'], [$city, $name], $fallbackFormat);
|
||||
}
|
||||
if (null !== $city) {
|
||||
return str_replace('{0}', $city, $regionFormat);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
$accessor = static function (array $indices, array ...$fallbackIndices) use ($locale, $reader, $tempDir) {
|
||||
foreach (\func_get_args() as $indices) {
|
||||
try {
|
||||
return $reader->readEntry($tempDir, $locale, $indices);
|
||||
} catch (MissingResourceException) {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
$zones = [];
|
||||
foreach (array_keys($available) as $zone) {
|
||||
// lg: long generic, e.g. "Central European Time"
|
||||
// ls: long specific (not DST), e.g. "Central European Standard Time"
|
||||
// ld: long DST, e.g. "Central European Summer Time"
|
||||
// ec: example city, e.g. "Amsterdam"
|
||||
$name = $accessor(['zoneStrings', $zone, 'lg'], ['zoneStrings', $zone, 'ls']);
|
||||
$city = $accessor(['zoneStrings', $zone, 'ec']);
|
||||
$id = str_replace(':', '/', $zone);
|
||||
|
||||
if (null === $name && isset($metazones[$zone])) {
|
||||
$meta = 'meta:'.$metazones[$zone];
|
||||
$name = $accessor(['zoneStrings', $meta, 'lg'], ['zoneStrings', $meta, 'ls']);
|
||||
}
|
||||
|
||||
// Infer a default English named city for all locales
|
||||
// Ensures each timezone ID has a distinctive name
|
||||
if (null === $city && 0 !== strrpos($zone, 'Etc:') && false !== $i = strrpos($zone, ':')) {
|
||||
$city = str_replace('_', ' ', substr($zone, $i + 1));
|
||||
}
|
||||
if (null === $name) {
|
||||
$name = $resolveName($id, $city);
|
||||
$city = null;
|
||||
}
|
||||
if (null === $name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ensure no duplicated content is generated
|
||||
if (null !== $city && false === mb_stripos(str_replace('-', ' ', $name), str_replace('-', ' ', $city))) {
|
||||
$name = str_replace(['{0}', '{1}'], [$city, $name], $fallbackFormat);
|
||||
}
|
||||
|
||||
$zones[$id] = $name;
|
||||
}
|
||||
|
||||
return $zones;
|
||||
}
|
||||
|
||||
private static function generateZoneMetadata(ArrayAccessibleResourceBundle $localeBundle): array
|
||||
{
|
||||
$metadata = [];
|
||||
if (isset($localeBundle['zoneStrings']['gmtFormat'])) {
|
||||
$metadata['GmtFormat'] = str_replace('{0}', '%s', $localeBundle['zoneStrings']['gmtFormat']);
|
||||
}
|
||||
if (isset($localeBundle['zoneStrings']['hourFormat'])) {
|
||||
$hourFormat = explode(';', str_replace(['HH', 'mm', 'H', 'm'], ['%02d', '%02d', '%d', '%d'], $localeBundle['zoneStrings']['hourFormat']), 2);
|
||||
$metadata['HourFormatPos'] = $hourFormat[0];
|
||||
$metadata['HourFormatNeg'] = $hourFormat[1];
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
private static function generateZoneToCountryMapping(ArrayAccessibleResourceBundle $windowsZoneBundle): array
|
||||
{
|
||||
$mapping = [];
|
||||
|
||||
foreach ($windowsZoneBundle['mapTimezones'] as $zoneInfo) {
|
||||
foreach ($zoneInfo as $region => $zones) {
|
||||
if (RegionDataGenerator::isValidCountryCode($region)) {
|
||||
$mapping += array_fill_keys(explode(' ', $zones), $region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksort($mapping);
|
||||
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
private static function generateCountryToZoneMapping(array $zoneToCountryMapping): array
|
||||
{
|
||||
$mapping = [];
|
||||
|
||||
foreach ($zoneToCountryMapping as $zone => $country) {
|
||||
$mapping[$country][] = $zone;
|
||||
}
|
||||
|
||||
ksort($mapping);
|
||||
|
||||
return $mapping;
|
||||
}
|
||||
}
|
81
plugins/simplesaml/lib/vendor/symfony/intl/Data/Util/ArrayAccessibleResourceBundle.php
vendored
Normal file
81
plugins/simplesaml/lib/vendor/symfony/intl/Data/Util/ArrayAccessibleResourceBundle.php
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Util;
|
||||
|
||||
use Symfony\Component\Intl\Exception\BadMethodCallException;
|
||||
|
||||
/**
|
||||
* Work-around for a bug in PHP's \ResourceBundle implementation.
|
||||
*
|
||||
* More information can be found on https://bugs.php.net/64356.
|
||||
* This class can be removed once that bug is fixed.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ArrayAccessibleResourceBundle implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
{
|
||||
private \ResourceBundle $bundleImpl;
|
||||
|
||||
public function __construct(\ResourceBundle $bundleImpl)
|
||||
{
|
||||
$this->bundleImpl = $bundleImpl;
|
||||
}
|
||||
|
||||
public function get(int|string $offset): mixed
|
||||
{
|
||||
$value = $this->bundleImpl->get($offset);
|
||||
|
||||
return $value instanceof \ResourceBundle ? new static($value) : $value;
|
||||
}
|
||||
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
return null !== $this->bundleImpl->get($offset);
|
||||
}
|
||||
|
||||
public function offsetGet(mixed $offset): mixed
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
throw new BadMethodCallException('Resource bundles cannot be modified.');
|
||||
}
|
||||
|
||||
public function offsetUnset(mixed $offset): void
|
||||
{
|
||||
throw new BadMethodCallException('Resource bundles cannot be modified.');
|
||||
}
|
||||
|
||||
public function getIterator(): \Traversable
|
||||
{
|
||||
return $this->bundleImpl;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return $this->bundleImpl->count();
|
||||
}
|
||||
|
||||
public function getErrorCode(): int
|
||||
{
|
||||
return $this->bundleImpl->getErrorCode();
|
||||
}
|
||||
|
||||
public function getErrorMessage(): string
|
||||
{
|
||||
return $this->bundleImpl->getErrorMessage();
|
||||
}
|
||||
}
|
99
plugins/simplesaml/lib/vendor/symfony/intl/Data/Util/LocaleScanner.php
vendored
Normal file
99
plugins/simplesaml/lib/vendor/symfony/intl/Data/Util/LocaleScanner.php
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Util;
|
||||
|
||||
/**
|
||||
* Scans a directory with data files for locales.
|
||||
*
|
||||
* The name of each file with the extension ".txt" is considered, if it "looks"
|
||||
* like a locale:
|
||||
*
|
||||
* - the name must start with two letters;
|
||||
* - the two letters may optionally be followed by an underscore and any
|
||||
* sequence of other symbols.
|
||||
*
|
||||
* For example, "de" and "de_DE" are considered to be locales. "root" and "meta"
|
||||
* are not.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LocaleScanner
|
||||
{
|
||||
/**
|
||||
* Returns all locales found in the given directory.
|
||||
*
|
||||
* @return array An array of locales. The result also contains locales that
|
||||
* are in fact just aliases for other locales. Use
|
||||
* {@link scanAliases()} to determine which of the locales
|
||||
* are aliases
|
||||
*/
|
||||
public function scanLocales(string $sourceDir): array
|
||||
{
|
||||
$locales = glob($sourceDir.'/*.txt', \GLOB_NOSORT);
|
||||
|
||||
// Remove file extension and sort
|
||||
array_walk($locales, function (&$locale) { $locale = basename($locale, '.txt'); });
|
||||
|
||||
// Remove non-locales
|
||||
$locales = array_filter($locales, fn ($locale) => preg_match('/^[a-z]{2}(_.+)?$/', $locale));
|
||||
|
||||
sort($locales);
|
||||
|
||||
return $locales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all locale aliases found in the given directory.
|
||||
*
|
||||
* @return array An array with the locale aliases as keys and the aliased
|
||||
* locales as values
|
||||
*/
|
||||
public function scanAliases(string $sourceDir): array
|
||||
{
|
||||
$locales = $this->scanLocales($sourceDir);
|
||||
$aliases = [];
|
||||
|
||||
// Delete locales that are no aliases
|
||||
foreach ($locales as $locale) {
|
||||
$content = file_get_contents($sourceDir.'/'.$locale.'.txt');
|
||||
|
||||
// Aliases contain the text "%%ALIAS" followed by the aliased locale
|
||||
if (preg_match('/"%%ALIAS"\{"([^"]+)"\}/', $content, $matches)) {
|
||||
$aliases[$locale] = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all locale parents found in the given directory.
|
||||
*/
|
||||
public function scanParents(string $sourceDir): array
|
||||
{
|
||||
$locales = $this->scanLocales($sourceDir);
|
||||
$fallbacks = [];
|
||||
|
||||
foreach ($locales as $locale) {
|
||||
$content = file_get_contents($sourceDir.'/'.$locale.'.txt');
|
||||
|
||||
// Aliases contain the text "%%PARENT" followed by the aliased locale
|
||||
if (preg_match('/%%Parent{"([^"]+)"}/', $content, $matches)) {
|
||||
$fallbacks[$locale] = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $fallbacks;
|
||||
}
|
||||
}
|
48
plugins/simplesaml/lib/vendor/symfony/intl/Data/Util/RecursiveArrayAccess.php
vendored
Normal file
48
plugins/simplesaml/lib/vendor/symfony/intl/Data/Util/RecursiveArrayAccess.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Util;
|
||||
|
||||
use Symfony\Component\Intl\Exception\OutOfBoundsException;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class RecursiveArrayAccess
|
||||
{
|
||||
public static function get(mixed $array, array $indices): mixed
|
||||
{
|
||||
foreach ($indices as $index) {
|
||||
// Use array_key_exists() for arrays, isset() otherwise
|
||||
if (\is_array($array)) {
|
||||
if (\array_key_exists($index, $array)) {
|
||||
$array = $array[$index];
|
||||
continue;
|
||||
}
|
||||
} elseif ($array instanceof \ArrayAccess) {
|
||||
if (isset($array[$index])) {
|
||||
$array = $array[$index];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
throw new OutOfBoundsException(sprintf('The index "%s" does not exist.', $index));
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
}
|
79
plugins/simplesaml/lib/vendor/symfony/intl/Data/Util/RingBuffer.php
vendored
Normal file
79
plugins/simplesaml/lib/vendor/symfony/intl/Data/Util/RingBuffer.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Data\Util;
|
||||
|
||||
use Symfony\Component\Intl\Exception\OutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Implements a ring buffer.
|
||||
*
|
||||
* A ring buffer is an array-like structure with a fixed size. If the buffer
|
||||
* is full, the next written element overwrites the first bucket in the buffer,
|
||||
* then the second and so on.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @template TKey of array-key
|
||||
* @template TValue
|
||||
*
|
||||
* @implements \ArrayAccess<TKey, TValue>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class RingBuffer implements \ArrayAccess
|
||||
{
|
||||
/** @var array<int, TValue> */
|
||||
private array $values = [];
|
||||
/** @var array<TKey, int> */
|
||||
private array $indices = [];
|
||||
private int $cursor = 0;
|
||||
private int $size;
|
||||
|
||||
public function __construct(int $size)
|
||||
{
|
||||
$this->size = $size;
|
||||
}
|
||||
|
||||
public function offsetExists(mixed $key): bool
|
||||
{
|
||||
return isset($this->indices[$key]);
|
||||
}
|
||||
|
||||
public function offsetGet(mixed $key): mixed
|
||||
{
|
||||
if (!isset($this->indices[$key])) {
|
||||
throw new OutOfBoundsException(sprintf('The index "%s" does not exist.', $key));
|
||||
}
|
||||
|
||||
return $this->values[$this->indices[$key]];
|
||||
}
|
||||
|
||||
public function offsetSet(mixed $key, mixed $value): void
|
||||
{
|
||||
if (false !== ($keyToRemove = array_search($this->cursor, $this->indices))) {
|
||||
unset($this->indices[$keyToRemove]);
|
||||
}
|
||||
|
||||
$this->values[$this->cursor] = $value;
|
||||
$this->indices[$key] = $this->cursor;
|
||||
|
||||
$this->cursor = ($this->cursor + 1) % $this->size;
|
||||
}
|
||||
|
||||
public function offsetUnset(mixed $key): void
|
||||
{
|
||||
if (isset($this->indices[$key])) {
|
||||
$this->values[$this->indices[$key]] = null;
|
||||
unset($this->indices[$key]);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user