You are here

public function FieldsHelper::extractFields in Search API 8

Extracts specific field values from a complex data object.

The values will be set directly on the given field objects, nothing is returned.

Parameters

\Drupal\Core\TypedData\ComplexDataInterface $item: The item from which fields should be extracted.

\Drupal\search_api\Item\FieldInterface[][] $fields: An associative array, keyed by property paths, mapped to field objects with that property path.

string|null $langcode: (optional) The code of the language the retrieved values should have.

Overrides FieldsHelperInterface::extractFields

1 call to FieldsHelper::extractFields()
FieldsHelper::extractItemValues in src/Utility/FieldsHelper.php
Extracts property values from items.

File

src/Utility/FieldsHelper.php, line 105

Class

FieldsHelper
Provides helper methods for dealing with Search API fields and properties.

Namespace

Drupal\search_api\Utility

Code

public function extractFields(ComplexDataInterface $item, array $fields, $langcode = NULL) {

  // If a language code was given, get the correct translation (if possible).
  if ($langcode) {
    if ($item instanceof TranslatableInterface) {
      if ($item
        ->hasTranslation($langcode)) {
        $item = $item
          ->getTranslation($langcode);
      }
    }
    else {
      $value = $item
        ->getValue();
      if ($value instanceof ContentEntityInterface) {
        if ($value
          ->hasTranslation($langcode)) {
          $item = $value
            ->getTranslation($langcode)
            ->getTypedData();
        }
      }
    }
  }

  // Figure out which fields are directly on the item and which need to be
  // extracted from nested items.
  $directFields = [];
  $nestedFields = [];
  foreach (array_keys($fields) as $key) {
    if (strpos($key, ':') !== FALSE) {
      list($direct, $nested) = explode(':', $key, 2);
      $nestedFields[$direct][$nested] = $fields[$key];
    }
    else {
      $directFields[] = $key;
    }
  }

  // Extract the direct fields.
  $properties = $item
    ->getProperties(TRUE);
  foreach ($directFields as $key) {
    if (empty($properties[$key])) {
      continue;
    }
    $data = $item
      ->get($key);
    foreach ($fields[$key] as $field) {
      $this
        ->extractField($data, $field);
    }
  }

  // Recurse for all nested fields.
  foreach ($nestedFields as $direct => $fieldsNested) {
    if (empty($properties[$direct])) {
      continue;
    }
    $itemNested = $item
      ->get($direct);
    if ($itemNested instanceof DataReferenceInterface) {
      $itemNested = $itemNested
        ->getTarget();
    }
    if ($itemNested instanceof EntityInterface) {
      $itemNested = $itemNested
        ->getTypedData();
    }
    if ($itemNested instanceof ComplexDataInterface && !$itemNested
      ->isEmpty()) {
      $this
        ->extractFields($itemNested, $fieldsNested, $langcode);
    }
    elseif ($itemNested instanceof ListInterface && !$itemNested
      ->isEmpty()) {
      foreach ($itemNested as $listItem) {
        if ($listItem instanceof ComplexDataInterface && !$listItem
          ->isEmpty()) {
          $this
            ->extractFields($listItem, $fieldsNested, $langcode);
        }
      }
    }
  }
}