vendor/symfony/intl/Data/Bundle/Reader/BundleEntryReader.php line 72

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Intl\Data\Bundle\Reader;
  11. use Symfony\Component\Intl\Data\Util\RecursiveArrayAccess;
  12. use Symfony\Component\Intl\Exception\MissingResourceException;
  13. use Symfony\Component\Intl\Exception\OutOfBoundsException;
  14. use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException;
  15. use Symfony\Component\Intl\Locale;
  16. /**
  17.  * Default implementation of {@link BundleEntryReaderInterface}.
  18.  *
  19.  * @author Bernhard Schussek <bschussek@gmail.com>
  20.  *
  21.  * @see BundleEntryReaderInterface
  22.  *
  23.  * @internal
  24.  */
  25. class BundleEntryReader implements BundleEntryReaderInterface
  26. {
  27.     private $reader;
  28.     /**
  29.      * A mapping of locale aliases to locales.
  30.      */
  31.     private $localeAliases = [];
  32.     /**
  33.      * Creates an entry reader based on the given resource bundle reader.
  34.      */
  35.     public function __construct(BundleReaderInterface $reader)
  36.     {
  37.         $this->reader $reader;
  38.     }
  39.     /**
  40.      * Stores a mapping of locale aliases to locales.
  41.      *
  42.      * This mapping is used when reading entries and merging them with their
  43.      * fallback locales. If an entry is read for a locale alias (e.g. "mo")
  44.      * that points to a locale with a fallback locale ("ro_MD"), the reader
  45.      * can continue at the correct fallback locale ("ro").
  46.      *
  47.      * @param array $localeAliases A mapping of locale aliases to locales
  48.      */
  49.     public function setLocaleAliases(array $localeAliases)
  50.     {
  51.         $this->localeAliases $localeAliases;
  52.     }
  53.     /**
  54.      * {@inheritdoc}
  55.      */
  56.     public function read(string $pathstring $locale)
  57.     {
  58.         return $this->reader->read($path$locale);
  59.     }
  60.     /**
  61.      * {@inheritdoc}
  62.      */
  63.     public function readEntry(string $pathstring $locale, array $indicesbool $fallback true)
  64.     {
  65.         $entry null;
  66.         $isMultiValued false;
  67.         $readSucceeded false;
  68.         $exception null;
  69.         $currentLocale $locale;
  70.         $testedLocales = [];
  71.         while (null !== $currentLocale) {
  72.             // Resolve any aliases to their target locales
  73.             if (isset($this->localeAliases[$currentLocale])) {
  74.                 $currentLocale $this->localeAliases[$currentLocale];
  75.             }
  76.             try {
  77.                 $data $this->reader->read($path$currentLocale);
  78.                 $currentEntry RecursiveArrayAccess::get($data$indices);
  79.                 $readSucceeded true;
  80.                 $isCurrentTraversable $currentEntry instanceof \Traversable;
  81.                 $isCurrentMultiValued $isCurrentTraversable || \is_array($currentEntry);
  82.                 // Return immediately if fallback is disabled or we are dealing
  83.                 // with a scalar non-null entry
  84.                 if (!$fallback || (!$isCurrentMultiValued && null !== $currentEntry)) {
  85.                     return $currentEntry;
  86.                 }
  87.                 // =========================================================
  88.                 // Fallback is enabled, entry is either multi-valued or NULL
  89.                 // =========================================================
  90.                 // If entry is multi-valued, convert to array
  91.                 if ($isCurrentTraversable) {
  92.                     $currentEntry iterator_to_array($currentEntry);
  93.                 }
  94.                 // If previously read entry was multi-valued too, merge them
  95.                 if ($isCurrentMultiValued && $isMultiValued) {
  96.                     $currentEntry array_merge($currentEntry$entry);
  97.                 }
  98.                 // Keep the previous entry if the current entry is NULL
  99.                 if (null !== $currentEntry) {
  100.                     $entry $currentEntry;
  101.                 }
  102.                 // If this or the previous entry was multi-valued, we are dealing
  103.                 // with a merged, multi-valued entry now
  104.                 $isMultiValued $isMultiValued || $isCurrentMultiValued;
  105.             } catch (ResourceBundleNotFoundException $e) {
  106.                 // Continue if there is a fallback locale for the current
  107.                 // locale
  108.                 $exception $e;
  109.             } catch (OutOfBoundsException $e) {
  110.                 // Remember exception and rethrow if we cannot find anything in
  111.                 // the fallback locales either
  112.                 $exception $e;
  113.             }
  114.             // Remember which locales we tried
  115.             $testedLocales[] = $currentLocale;
  116.             // Check whether fallback is allowed
  117.             if (!$fallback) {
  118.                 break;
  119.             }
  120.             // Then determine fallback locale
  121.             $currentLocale Locale::getFallback($currentLocale);
  122.         }
  123.         // Multi-valued entry was merged
  124.         if ($isMultiValued) {
  125.             return $entry;
  126.         }
  127.         // Entry is still NULL, but no read error occurred
  128.         if ($readSucceeded) {
  129.             return $entry;
  130.         }
  131.         // Entry is still NULL, read error occurred. Throw an exception
  132.         // containing the detailed path and locale
  133.         $errorMessage sprintf(
  134.             'Couldn\'t read the indices [%s] for the locale "%s" in "%s".',
  135.             implode(']['$indices),
  136.             $locale,
  137.             $path
  138.         );
  139.         // Append fallback locales, if any
  140.         if (\count($testedLocales) > 1) {
  141.             // Remove original locale
  142.             array_shift($testedLocales);
  143.             $errorMessage .= sprintf(
  144.                 ' The indices also couldn\'t be found for the fallback locale(s) "%s".',
  145.                 implode('", "'$testedLocales)
  146.             );
  147.         }
  148.         throw new MissingResourceException($errorMessage0$exception);
  149.     }
  150. }