You are here

public function ReverseEntityReferences::addFieldValues in Search API 8

Adds the values of properties defined by this processor to the item.

Parameters

\Drupal\search_api\Item\ItemInterface $item: The item whose field values should be added.

Overrides ProcessorPluginBase::addFieldValues

File

src/Plugin/search_api/processor/ReverseEntityReferences.php, line 272

Class

ReverseEntityReferences
Allows indexing of reverse entity references.

Namespace

Drupal\search_api\Plugin\search_api\processor

Code

public function addFieldValues(ItemInterface $item) {
  try {
    $entity = $item
      ->getOriginalObject()
      ->getValue();
  } catch (SearchApiException $e) {
    return;
  }
  if (!$entity instanceof EntityInterface) {
    return;
  }
  $entity_type_id = $entity
    ->getEntityTypeId();
  $entity_id = $entity
    ->id();
  $langcode = $entity
    ->language()
    ->getId();
  $datasource_id = $item
    ->getDatasourceId();

  /** @var \Drupal\search_api\Item\FieldInterface[][][] $to_extract */
  $to_extract = [];
  $prefix = 'search_api_reverse_entity_references_';
  $prefix_length = strlen($prefix);
  foreach ($item
    ->getFields() as $field) {
    $property_path = $field
      ->getPropertyPath();
    list($direct, $nested) = Utility::splitPropertyPath($property_path, FALSE);
    if ($field
      ->getDatasourceId() === $datasource_id && substr($direct, 0, $prefix_length) === $prefix) {
      $property_name = substr($direct, $prefix_length);
      $to_extract[$property_name][$nested][] = $field;
    }
  }
  $references = $this
    ->getEntityReferences();
  foreach ($to_extract as $property_name => $fields_to_extract) {
    if (!isset($references[$entity_type_id][$property_name])) {
      continue;
    }
    $property_info = $references[$entity_type_id][$property_name];
    try {
      $storage = $this
        ->getEntityTypeManager()
        ->getStorage($property_info['entity_type']);
    } catch (InvalidPluginDefinitionException $e) {
      continue;
    } catch (PluginNotFoundException $e) {
      continue;
    }
    $entity_ids = $storage
      ->getQuery()
      ->accessCheck(FALSE)
      ->condition($property_info['property'], $entity_id)
      ->execute();
    $entities = $storage
      ->loadMultiple($entity_ids);
    if (!$entities) {
      continue;
    }

    // This is a pretty hack-y work-around to make property extraction work for
    // Views fields, too. In general, adding entities as field values is a
    // pretty bad idea, so this might blow up in some use cases. Just do it for
    // now and hope for the best.
    if (isset($fields_to_extract[''])) {
      foreach ($fields_to_extract[''] as $field) {
        $field
          ->setValues(array_values($entities));
      }
      unset($fields_to_extract['']);
    }
    foreach ($entities as $referencing_entity) {
      $typed_data = $referencing_entity
        ->getTypedData();
      $this
        ->getFieldsHelper()
        ->extractFields($typed_data, $fields_to_extract, $langcode);
    }
  }
}