protected function SearchApiFieldTrait::extractPropertyValues in Search API 8
Places extracted property values and objects into the result row.
Parameters
\Drupal\views\ResultRow[] $values: The Views result rows from which property values should be extracted.
string $combined_property_path: The combined property path of the property to extract.
\Drupal\Core\TypedData\TypedDataInterface[][] $property_values: The values of the property for each result row, keyed by result row index.
string[] $dependents: The actually required properties (as combined property paths) that depend on this property.
1 call to SearchApiFieldTrait::extractPropertyValues()
- SearchApiFieldTrait::preRender in src/
Plugin/ views/ field/ SearchApiFieldTrait.php - Runs before any fields are rendered.
File
- src/
Plugin/ views/ field/ SearchApiFieldTrait.php, line 837
Class
- SearchApiFieldTrait
- Provides a trait to use for Search API Views field handlers.
Namespace
Drupal\search_api\Plugin\views\fieldCode
protected function extractPropertyValues(array $values, $combined_property_path, array $property_values, array $dependents) {
// Now go through the rows a second time and actually add all objects
// and (if necessary) properties.
foreach ($values as $i => $row) {
if (!empty($property_values[$i])) {
// Add the typed data for the property to our relationship objects
// for this property path.
$row->_relationship_objects[$combined_property_path] = [];
foreach ($property_values[$i] as $j => $typed_data) {
// If the typed data is an entity, check whether the current
// user can access it (and switch to the right translation, if
// available).
$value = $typed_data
->getValue();
if ($value instanceof EntityInterface) {
if (!$this
->checkEntityAccess($value, $combined_property_path)) {
continue;
}
if ($value instanceof TranslatableInterface && $value
->hasTranslation($row->search_api_language)) {
// PhpStorm isn't able to keep both interfaces in mind at the same
// time, so we need to use a third interface here that combines
// both.
/** @var \Drupal\Core\Entity\ContentEntityInterface $value */
$typed_data = $value
->getTranslation($row->search_api_language)
->getTypedData();
}
}
// To treat list properties correctly regarding possible child
// properties, add all the list items individually.
if ($typed_data instanceof ListInterface) {
foreach ($typed_data as $item) {
$row->_relationship_objects[$combined_property_path][] = $item;
$row->_relationship_parent_indices[$combined_property_path][] = $j;
}
}
else {
$row->_relationship_objects[$combined_property_path][] = $typed_data;
$row->_relationship_parent_indices[$combined_property_path][] = $j;
}
}
}
// Determine whether we want to set field values for this property on this
// row. This is the case if the property is one of the explicitly
// retrieved properties and not yet set on the result row object. Also, if
// we have no objects for this property, we needn't bother anyways, of
// course.
if (!in_array($combined_property_path, $dependents) || isset($row->{$combined_property_path}) || empty($row->_relationship_objects[$combined_property_path])) {
continue;
}
$row->{$combined_property_path} = [];
// Iterate over the typed data objects, extract their values and set
// the relationship objects for the next iteration of the outer loop
// over properties.
foreach ($row->_relationship_objects[$combined_property_path] as $typed_data) {
$row->{$combined_property_path}[] = $this
->getFieldsHelper()
->extractFieldValues($typed_data);
}
// If we just set any field values on the result row, clean them up
// by merging them together (currently it's an array of arrays, but
// it should be just a flat array).
if ($row->{$combined_property_path}) {
$row->{$combined_property_path} = call_user_func_array('array_merge', $row->{$combined_property_path});
}
}
}