/** * {@inheritdoc} */ public function readEntry($path, $locale, array $indices, $fallback = true) { $data = $this->reader->read($path, $locale); $entry = RecursiveArrayAccess::get($data, $indices); $multivalued = is_array($entry) || $entry instanceof \Traversable; if (!($fallback && (null === $entry || $multivalued))) { return $entry; } if (null !== ($fallbackLocale = $this->getFallbackLocale($locale))) { $parentEntry = $this->readEntry($path, $fallbackLocale, $indices, true); if ($entry || $parentEntry) { $multivalued = $multivalued || is_array($parentEntry) || $parentEntry instanceof \Traversable; if ($multivalued) { if ($entry instanceof \Traversable) { $entry = iterator_to_array($entry); } if ($parentEntry instanceof \Traversable) { $parentEntry = iterator_to_array($parentEntry); } $entry = array_merge($parentEntry ?: array(), $entry ?: array()); } else { $entry = null === $entry ? $parentEntry : $entry; } } } return $entry; }
/** * {@inheritdoc} */ public function read($path, $locale) { $hash = $path . '//' . $locale; if (!isset($this->buffer[$hash])) { $this->buffer[$hash] = $this->reader->read($path, $locale); } return $this->buffer[$hash]; }
/** * {@inheritdoc} */ public function readEntry($path, $locale, array $indices, $fallback = true) { $entry = null; $isMultiValued = false; $readSucceeded = false; $exception = null; $currentLocale = $locale; $testedLocales = array(); 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 . '.res'; // 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] from "%s/%s.res".', implode('][', $indices), $path, $locale); // Append fallback locales, if any if (count($testedLocales) > 1) { // Remove original locale array_shift($testedLocales); $errorMessage .= sprintf(' The indices also couldn\'t be found in the fallback locale(s) "%s".', implode('", "', $testedLocales)); } throw new MissingResourceException($errorMessage, 0, $exception); }