You are here

public function DataFetcher::fetchDefinitionBySubPaths in Typed Data API enhancements 8

Fetches a data definition based upon the given sub-paths.

Parameters

\Drupal\Core\TypedData\DataDefinitionInterface $data_definition: The data definition from which to retrieve a nested definition.

string[] $sub_paths: A list of sub paths; i.e., a property path separated into its parts.

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\DataDefinitionInterface The data definition of the target.

Throws

\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::fetchDefinitionBySubPaths

1 call to DataFetcher::fetchDefinitionBySubPaths()
DataFetcher::fetchDefinitionByPropertyPath in src/DataFetcher.php
Fetches a data definition based upon the given property path.

File

src/DataFetcher.php, line 115

Class

DataFetcher
Implementation of the data fetcher service.

Namespace

Drupal\typed_data

Code

public function fetchDefinitionBySubPaths(DataDefinitionInterface $data_definition, array $sub_paths, $langcode = NULL) {
  $current_selector = [];
  foreach ($sub_paths as $name) {
    $current_selector[] = $name;

    // If the current data is just a reference then directly dereference the
    // target.
    if ($data_definition instanceof DataReferenceDefinitionInterface) {
      $data_definition = $data_definition
        ->getTargetDefinition();
    }

    // If this is a list but the selector is not an integer, we forward the
    // selection to the first element in the list.
    if ($data_definition instanceof ListDataDefinitionInterface && !ctype_digit($name)) {
      $data_definition = $data_definition
        ->getItemDefinition();
    }

    // Drill down to the next step in the data selector.
    if ($data_definition instanceof ComplexDataDefinitionInterface) {
      $data_definition = $data_definition
        ->getPropertyDefinition($name);
    }
    elseif ($data_definition instanceof ListDataDefinitionInterface) {
      $data_definition = $data_definition
        ->getItemDefinition();
    }
    else {
      $current_selector_string = implode('.', $current_selector);
      if (count($current_selector) > 1) {
        $parent_property = $current_selector[count($current_selector) - 2];
        throw new InvalidArgumentException("The data selector '{$current_selector_string}' cannot be applied because the parent property '{$parent_property}' is not a list or a complex structure");
      }
      else {
        $type = $data_definition
          ->getDataType();
        throw new InvalidArgumentException("The data selector '{$current_selector_string}' cannot be applied because the definition of type '{$type}' is not a list or a complex structure");
      }
    }

    // If an accessed property is not existing, $data_definition will be
    // NULL.
    if (!isset($data_definition)) {
      $selector_string = implode('.', $sub_paths);
      $current_selector_string = implode('.', $current_selector);
      throw new InvalidArgumentException("Unable to apply data selector '{$selector_string}' at '{$current_selector_string}'");
    }
  }
  return $data_definition;
}