2
0
forked from Wavyzz/dolibarr

SwissQR: add Sprain\SwissQrBill and dependencies

This commit is contained in:
Didier 'OdyX' Raboud
2023-03-16 06:47:59 +01:00
parent 55ab3d2c56
commit f53120c915
2192 changed files with 971358 additions and 0 deletions

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

View 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)
{
$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);
}
}

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

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

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

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

View File

@@ -0,0 +1,40 @@
<?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;
/**
* 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)) {
throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s" does not exist.', $fileName));
}
return include $fileName;
}
}