search_api-8.x-1.15/src/Plugin/search_api/processor/AggregatedFields.php
src/Plugin/search_api/processor/AggregatedFields.php
<?php namespace Drupal\search_api\Plugin\search_api\processor; use Drupal\search_api\Datasource\DatasourceInterface; use Drupal\search_api\Item\ItemInterface; use Drupal\search_api\Plugin\search_api\processor\Property\AggregatedFieldProperty; use Drupal\search_api\Processor\ProcessorPluginBase; use Drupal\search_api\Utility\Utility; /** * Adds customized aggregations of existing fields to the index. * * @see \Drupal\search_api\Plugin\search_api\processor\Property\AggregatedFieldProperty * * @SearchApiProcessor( * id = "aggregated_field", * label = @Translation("Aggregated fields"), * description = @Translation("Add customized aggregations of existing fields to the index."), * stages = { * "add_properties" = 20, * }, * locked = true, * hidden = true, * ) */ class AggregatedFields extends ProcessorPluginBase { /** * {@inheritdoc} */ public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) { $properties = []; if (!$datasource) { $definition = [ 'label' => $this->t('Aggregated field'), 'description' => $this->t('An aggregation of multiple other fields.'), 'type' => 'string', 'processor_id' => $this->getPluginId(), // Most aggregation types are single-valued, but "Union" isn't, and we // can't know which will be picked, so err on the side of caution here. 'is_list' => TRUE, ]; $properties['aggregated_field'] = new AggregatedFieldProperty($definition); } return $properties; } /** * {@inheritdoc} */ public function addFieldValues(ItemInterface $item) { $fields = $this->index->getFields(); $aggregated_fields = $this->getFieldsHelper() ->filterForPropertyPath($fields, NULL, 'aggregated_field'); $required_properties_by_datasource = [ NULL => [], $item->getDatasourceId() => [], ]; foreach ($aggregated_fields as $field) { foreach ($field->getConfiguration()['fields'] as $combined_id) { list($datasource_id, $property_path) = Utility::splitCombinedId($combined_id); $required_properties_by_datasource[$datasource_id][$property_path] = $combined_id; } } $property_values = $this->getFieldsHelper() ->extractItemValues([$item], $required_properties_by_datasource)[0]; $aggregated_fields = $this->getFieldsHelper() ->filterForPropertyPath($item->getFields(), NULL, 'aggregated_field'); foreach ($aggregated_fields as $aggregated_field) { $values = []; $configuration = $aggregated_field->getConfiguration(); foreach ($configuration['fields'] as $combined_id) { if (!empty($property_values[$combined_id])) { $values = array_merge($values, $property_values[$combined_id]); } } switch ($configuration['type']) { case 'concat': $values = [implode("\n\n", $values)]; break; case 'sum': $values = [array_sum($values)]; break; case 'count': $values = [count($values)]; break; case 'max': if ($values) { $values = [max($values)]; } break; case 'min': if ($values) { $values = [min($values)]; } break; case 'first': if ($values) { $values = [reset($values)]; } break; case 'last': if ($values) { $values = [end($values)]; } break; } // Do not use setValues(), since that doesn't preprocess the values // according to their data type. foreach ($values as $value) { $aggregated_field->addValue($value); } } } }