StructuredBundleReader.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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\ResourceBundle\Reader;
  11. use Symfony\Component\Intl\ResourceBundle\Util\RecursiveArrayAccess;
  12. /**
  13. * A structured reader wrapping an existing resource bundle reader.
  14. *
  15. * @author Bernhard Schussek <bschussek@gmail.com>
  16. *
  17. * @see StructuredResourceBundleBundleReaderInterface
  18. */
  19. class StructuredBundleReader implements StructuredBundleReaderInterface
  20. {
  21. /**
  22. * @var BundleReaderInterface
  23. */
  24. private $reader;
  25. /**
  26. * Creates an entry reader based on the given resource bundle reader.
  27. *
  28. * @param BundleReaderInterface $reader A resource bundle reader to use.
  29. */
  30. public function __construct(BundleReaderInterface $reader)
  31. {
  32. $this->reader = $reader;
  33. }
  34. /**
  35. * {@inheritdoc}
  36. */
  37. public function read($path, $locale)
  38. {
  39. return $this->reader->read($path, $locale);
  40. }
  41. /**
  42. * {@inheritdoc}
  43. */
  44. public function getLocales($path)
  45. {
  46. return $this->reader->getLocales($path);
  47. }
  48. /**
  49. * {@inheritdoc}
  50. */
  51. public function readEntry($path, $locale, array $indices, $fallback = true)
  52. {
  53. $data = $this->reader->read($path, $locale);
  54. $entry = RecursiveArrayAccess::get($data, $indices);
  55. $multivalued = is_array($entry) || $entry instanceof \Traversable;
  56. if (!($fallback && (null === $entry || $multivalued))) {
  57. return $entry;
  58. }
  59. if (null !== ($fallbackLocale = $this->getFallbackLocale($locale))) {
  60. $parentEntry = $this->readEntry($path, $fallbackLocale, $indices, true);
  61. if ($entry || $parentEntry) {
  62. $multivalued = $multivalued || is_array($parentEntry) || $parentEntry instanceof \Traversable;
  63. if ($multivalued) {
  64. if ($entry instanceof \Traversable) {
  65. $entry = iterator_to_array($entry);
  66. }
  67. if ($parentEntry instanceof \Traversable) {
  68. $parentEntry = iterator_to_array($parentEntry);
  69. }
  70. $entry = array_merge(
  71. $parentEntry ?: array(),
  72. $entry ?: array()
  73. );
  74. } else {
  75. $entry = null === $entry ? $parentEntry : $entry;
  76. }
  77. }
  78. }
  79. return $entry;
  80. }
  81. /**
  82. * Returns the fallback locale for a given locale, if any
  83. *
  84. * @param string $locale The locale to find the fallback for.
  85. *
  86. * @return string|null The fallback locale, or null if no parent exists
  87. */
  88. private function getFallbackLocale($locale)
  89. {
  90. if (false === $pos = strrpos($locale, '_')) {
  91. return null;
  92. }
  93. return substr($locale, 0, $pos);
  94. }
  95. }