You are here

protected function SearchApiFieldTrait::extractProcessorProperty in Search API 8

Extracts a processor-based property from an item.

Parameters

\Drupal\search_api\Processor\ProcessorPropertyInterface $property: The property definition.

\Drupal\views\ResultRow $row: The Views result row.

string|null $datasource_id: The datasource ID of the property to extract (or NULL for datasource- independent properties).

string $property_path: The property path of the property to extract.

string $combined_property_path: The combined property path of the property to set.

bool $is_required: TRUE if the property is directly required, FALSE if it should only be extracted because some child/ancestor properties are required.

1 call to SearchApiFieldTrait::extractProcessorProperty()
SearchApiFieldTrait::getValuesToExtract in src/Plugin/views/field/SearchApiFieldTrait.php
Determines and prepares the property values that need to be extracted.

File

src/Plugin/views/field/SearchApiFieldTrait.php, line 764

Class

SearchApiFieldTrait
Provides a trait to use for Search API Views field handlers.

Namespace

Drupal\search_api\Plugin\views\field

Code

protected function extractProcessorProperty(ProcessorPropertyInterface $property, ResultRow $row, $datasource_id, $property_path, $combined_property_path, $is_required) {
  $index = $this
    ->getIndex();
  $processor = $index
    ->getProcessor($property
    ->getProcessorId());
  if (!$processor) {
    return;
  }

  // We need to call the processor's addFieldValues() method in order to get
  // the field value. We do this using a clone of the search item so as to
  // preserve the original state of the item. We also use a dummy field
  // object – either a clone of a fitting indexed field (to get its
  // configuration), or a newly created one.
  $property_fields = $this
    ->getFieldsHelper()
    ->filterForPropertyPath($index
    ->getFields(), $datasource_id, $property_path);
  if ($property_fields) {
    if (!empty($this->definition['search_api field']) && !empty($property_fields[$this->definition['search_api field']])) {
      $field_id = $this->definition['search_api field'];
      $dummy_field = $property_fields[$field_id];
    }
    else {
      $dummy_field = reset($property_fields);
    }
    $dummy_field = clone $dummy_field;
  }
  else {
    $dummy_field = $this
      ->getFieldsHelper()
      ->createFieldFromProperty($index, $property, $datasource_id, $property_path, 'tmp', 'string');
  }

  /** @var \Drupal\search_api\Item\ItemInterface $dummy_item */
  $dummy_item = clone $row->_item;
  $dummy_item
    ->setFields([
    'tmp' => $dummy_field,
  ]);
  $dummy_item
    ->setFieldsExtracted(TRUE);
  $processor
    ->addFieldValues($dummy_item);
  $row->_relationship_objects[$combined_property_path] = [];
  $set_values = $is_required && !isset($row->{$combined_property_path});
  if ($set_values) {
    $row->{$combined_property_path} = [];
  }
  foreach ($dummy_field
    ->getValues() as $value) {
    if (!$this
      ->checkEntityAccess($value, $combined_property_path)) {
      continue;
    }
    if ($set_values) {
      $row->{$combined_property_path}[] = $value;
    }
    $typed_data = $this
      ->getTypedDataManager()
      ->create($property, $value);
    $row->_relationship_objects[$combined_property_path][] = $typed_data;

    // Processor-generated properties always have just a single parent: the
    // result item itself. Therefore, the parent's index is always 0.
    $row->_relationship_parent_indices[$combined_property_path][] = 0;
  }
}