eav_field-2.x-dev/src/Plugin/search_api/processor/EavFieldSearchApiProcessor.php
src/Plugin/search_api/processor/EavFieldSearchApiProcessor.php
<?php
namespace Drupal\eav_field\Plugin\search_api\processor;
use Drupal\Core\Database\StatementInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\eav_field\Plugin\Field\FieldType\EavItemInterface;
use Drupal\eav_field\Plugin\Field\FieldType\EavItemListInterface;
use Drupal\eav_field\Plugin\search_api\processor\Property\EavFieldProcessorProperty;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
/**
* @SearchApiProcessor(
* id = "eav_field_processor",
* label = @Translation("EAV field processor"),
* description = @Translation("Index EAV field values as separate fields."),
* stages = {
* "add_properties" = 0,
* "pre_index_save" = 0,
* },
* locked = false,
* hidden = false,
* )
*/
class EavFieldSearchApiProcessor extends ProcessorPluginBase {
/**
* {@inheritdoc}
*/
public function getPropertyDefinitions(DatasourceInterface $datasource = NULL): array {
$properties = [];
if (!$datasource) {
$attributes = $this->getEavAttributes();
foreach ($attributes as $attribute) {
$value_field_storage_config = unserialize($attribute->value_storage_config, ['allowed_classes' => FALSE]);
$value_field_cardinality = $value_field_storage_config['cardinality'] ?? 1;
$definition_type = match ($attribute->value_type) {
'string', 'string_long', 'list_string' => 'string',
'integer', 'entity_reference', 'list_integer' => 'integer',
'decimal' => 'decimal',
'boolean' => 'boolean',
};
$properties['eav_field_' . $this->clearMachineName($attribute->machine_name)] = new EavFieldProcessorProperty([
'label' => $this->t('EAV Field') . ' ' . $attribute->label,
'description' => $this->t('EAV Field values.'),
'type' => $definition_type,
'processor_id' => $this->getPluginId(),
'is_list' => ($value_field_cardinality > 1 || $value_field_cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED),
'hidden' => TRUE,
]);
}
}
return $properties;
}
/**
* {@inheritdoc}
*/
public function preIndexSave() {
$attributes = $this->getEavAttributes();
foreach ($attributes as $attribute) {
$this->ensureField(NULL, 'eav_field_' . $this->clearMachineName($attribute->machine_name))->setHidden();
}
}
/**
* {@inheritdoc}
*/
public function addFieldValues(ItemInterface $item) {
$entity = $item->getOriginalObject();
if ($eav_field_items = $this->getEntityEavFieldItems($entity)) {
$search_api_fields_helper = $this->getFieldsHelper();
/** @var EavItemInterface $eav_field_item */
foreach ($eav_field_items as $eav_field_item) {
$eav_value_entity = $eav_field_item->getValueEntity();
$eav_value_entity_values = $eav_value_entity?->getValueFieldMainValues();
$eav_attribute_entity = $eav_value_entity?->getAttributeEntity();
if ($eav_value_entity_values && $eav_attribute_entity) {
$attribute_machine_name = $this->clearMachineName($eav_attribute_entity->getMachineName());
$item_fields = $search_api_fields_helper->filterForPropertyPath($item->getFields(), NULL, 'eav_field_' . $attribute_machine_name);
foreach ($item_fields as $item_field) {
$item_field->setValues($eav_value_entity_values);
}
}
}
}
}
/**
* Return all EAV attributes.
*/
protected function getEavAttributes(): StatementInterface {
return \Drupal::database()
->select('eav_attribute_field_data', 'a')
->fields('a', ['aid', 'machine_name', 'label', 'value_type', 'value_storage_config'])
->condition('a.status', 1)
->orderBy('a.weight')
->execute();
}
/**
* Return entity eav field items.
*/
protected function getEntityEavFieldItems($entity): ?EavItemListInterface {
foreach ($entity->getProperties() as $property) {
if ($property instanceof EavItemListInterface) {
return $property;
}
}
return NULL;
}
/**
* Clear machine name.
*/
protected function clearMachineName(string $string): string {
$string = strtr($string, [
'-' => '_',
' ' => '_',
]);
$string = preg_replace('/[^a-z0-9_]/', '', $string);
return $string;
}
}
