public function DataFetcher::fetchDataBySubPaths in Typed Data API enhancements 8
Fetches data based upon the given sub-paths.
Parameters
\Drupal\Core\TypedData\TypedDataInterface $typed_data: The data from which to select a value.
string[] $sub_paths: A list of sub paths; i.e., a property path separated into its parts.
\Drupal\Core\Render\BubbleableMetadata|null $bubbleable_metadata: (optional) An object to which required bubbleable metadata will be added.
string $langcode: (optional) The language code used to get the argument value if the argument value should be translated. Defaults to NULL.
Return value
\Drupal\Core\TypedData\TypedDataInterface The variable wrapped as typed data.
Throws
\Drupal\Core\TypedData\Exception\MissingDataException Thrown if the data cannot be fetched due to missing data; e.g., unset properties or list items.
\Drupal\typed_data\Exception\InvalidArgumentException Thrown if the given path is not valid for the given data; e.g., a not existing property is referenced.
Overrides DataFetcherInterface::fetchDataBySubPaths
1 call to DataFetcher::fetchDataBySubPaths()
- DataFetcher::fetchDataByPropertyPath in src/
DataFetcher.php - Fetches data based upon the given property path.
File
- src/
DataFetcher.php, line 38
Class
- DataFetcher
- Implementation of the data fetcher service.
Namespace
Drupal\typed_dataCode
public function fetchDataBySubPaths(TypedDataInterface $typed_data, array $sub_paths, BubbleableMetadata $bubbleable_metadata = NULL, $langcode = NULL) {
$current_selector = [];
$bubbleable_metadata = $bubbleable_metadata ?: new BubbleableMetadata();
try {
foreach ($sub_paths as $name) {
$current_selector[] = $name;
// If the current data is just a reference then directly dereference the
// target.
if ($typed_data instanceof DataReferenceInterface) {
$this
->addBubbleableMetadata($typed_data, $bubbleable_metadata);
$typed_data = $typed_data
->getTarget();
if ($typed_data === NULL) {
throw new MissingDataException("The specified reference is NULL.");
}
}
// Make sure we are using the right language.
if (isset($langcode) && $typed_data instanceof TranslatableInterface) {
if ($typed_data
->hasTranslation($langcode)) {
$typed_data = $typed_data
->getTranslation($langcode);
}
// @todo What if the requested translation does not exist? Currently
// we just ignore that and continue with the current object.
}
// If this is a list but the selector is not an integer, we forward the
// selection to the first element in the list.
if ($typed_data instanceof ListInterface && !ctype_digit($name)) {
$this
->addBubbleableMetadata($typed_data, $bubbleable_metadata);
$typed_data = $typed_data
->get(0);
}
// Drill down to the next step in the data selector.
if ($typed_data instanceof ListInterface || $typed_data instanceof ComplexDataInterface) {
$this
->addBubbleableMetadata($typed_data, $bubbleable_metadata);
$typed_data = $typed_data
->get($name);
}
else {
$current_selector_string = implode('.', $current_selector);
throw new InvalidArgumentException("The parent property is not a list or a complex structure at '{$current_selector_string}'.");
}
// If an accessed list item does not exist, $typed_data will be NULL.
if (!isset($typed_data)) {
$selector_string = implode('.', $sub_paths);
$current_selector_string = implode('.', $current_selector);
throw new MissingDataException("Unable to apply data selector '{$selector_string}' at '{$current_selector_string}'");
}
}
$this
->addBubbleableMetadata($typed_data, $bubbleable_metadata);
return $typed_data;
} catch (MissingDataException $e) {
$selector = implode('.', $sub_paths);
$current_selector = implode('.', $current_selector);
throw new MissingDataException("Unable to apply data selector '{$selector}' at '{$current_selector}': " . $e
->getMessage());
} catch (\InvalidArgumentException $e) {
$selector = implode('.', $sub_paths);
$current_selector = implode('.', $current_selector);
throw new InvalidArgumentException("Unable to apply data selector '{$selector}' at '{$current_selector}': " . $e
->getMessage());
}
}