diff --git a/src/Plugin/search_api/processor/Property/TypedRelationFilteredProperty.php b/src/Plugin/search_api/processor/Property/TypedRelationFilteredProperty.php new file mode 100644 index 0000000..0d5938f --- /dev/null +++ b/src/Plugin/search_api/processor/Property/TypedRelationFilteredProperty.php @@ -0,0 +1,55 @@ + [], + 'bundle' => '', + 'base_field' => '', + ]; + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(FieldInterface $field, array $form, FormStateInterface $form_state) { + $configuration = $field->getConfiguration(); + $form['rel_types'] = [ + '#type' => 'select', + '#title' => $this->t('Relations to include'), + '#options' => $field->getDataDefinition()->getSetting('options'), + '#multiple' => TRUE, + '#default_value' => $configuration['rel_types'], + '#required' => TRUE, + '#size' => 16, + ]; + $form['bundle'] = [ + '#type' => 'hidden', + '#value' => $field->getDataDefinition()->getSetting('bundle'), + ]; + $form['base_field'] = [ + '#type' => 'hidden', + '#value' => $field->getDataDefinition()->getSetting('base_field'), + ]; + return $form; + } + +} diff --git a/src/Plugin/search_api/processor/TypedRelationFiltered.php b/src/Plugin/search_api/processor/TypedRelationFiltered.php new file mode 100644 index 0000000..b28dbc1 --- /dev/null +++ b/src/Plugin/search_api/processor/TypedRelationFiltered.php @@ -0,0 +1,169 @@ +entityTypeManager = $entityTypeManager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity_type.manager'), + ); + } + + /** + * {@inheritdoc} + */ + public function getPropertyDefinitions(DatasourceInterface $datasource = NULL): array { + $properties = []; + + if (!$datasource || !$datasource->getEntityTypeId()) { + return $properties; + } + + $entity_type = $datasource->getEntityTypeId(); + + // Get all configured typed relation fields. + $fields = $this->entityTypeManager->getStorage('field_config')->loadByProperties([ + 'entity_type' => $entity_type, + 'field_type' => 'typed_relation', + ]); + + foreach ($fields as $field) { + // Create a "filtered" option. + $definition = [ + 'label' => $this->t('@label (filtered by type) [@bundle]', [ + '@label' => $field->label(), + '@bundle' => $field->getTargetBundle(), + ]), + 'description' => $this->t('Typed relation field, filtered by type'), + 'type' => 'string', + 'processor_id' => $this->getPluginId(), + 'is_list' => TRUE, + 'settings' => [ + 'options' => $field->getSetting('rel_types'), + 'bundle' => $field->getTargetBundle(), + 'base_field' => $field->getName(), + ], + ]; + $fieldname = 'typed_relation_filter__' . str_replace('.', '__', $field->id()); + $property = new TypedRelationFilteredProperty($definition); + $property->setSetting('options', $field->getSetting('rel_types')); + $properties[$fieldname] = $property; + } + return $properties; + } + + /** + * {@inheritdoc} + */ + public function addFieldValues(ItemInterface $item) { + // Skip if no Typed Relation Filtered search_api_fields are configured. + $relevant_search_api_fields = []; + $search_api_fields = $item->getFields(FALSE); + foreach ($search_api_fields as $search_api_field) { + if (substr($search_api_field->getPropertyPath(), 0, 23) == 'typed_relation_filter__') { + $relevant_search_api_fields[] = $search_api_field; + } + } + if (empty($search_api_fields)) { + return; + } + // Cycle over any typed relation fields on the original item. + $content_entity = $item->getOriginalObject()->getValue(); + + foreach ($relevant_search_api_fields as $search_api_field) { + $field_config = $search_api_field->getConfiguration(); + + // Exit if we're on the wrong bundle or the field isn't set. + if (($content_entity->bundle() != $field_config['bundle']) + || !$content_entity->hasField($field_config['base_field'])) { + return; + } + + $vals = $content_entity->get($field_config['base_field'])->getValue(); + foreach ($vals as $element) { + $rel_type = $element['rel_type']; + if (in_array($rel_type, $field_config['rel_types'])) { + $tid = $element['target_id']; + $taxo_term = $this->entityTypeManager + ->getStorage('taxonomy_term') + ->load($tid); + if ($taxo_term) { + $taxo_name = $taxo_term->name->value; + $search_api_field->addValue($taxo_name); + } + } + } + } + } + + /** + * {@inheritdoc} + */ + public function requiresReindexing(array $old_settings = NULL, array $new_settings = NULL) { + if ($new_settings != $old_settings) { + return TRUE; + } + return FALSE; + } + +}