diff --git a/search_api_field_map_domain/search_api_field_map_domain.info.yml b/search_api_field_map_domain/search_api_field_map_domain.info.yml new file mode 100644 index 0000000..89879ae --- /dev/null +++ b/search_api_field_map_domain/search_api_field_map_domain.info.yml @@ -0,0 +1,9 @@ +name: Search API Field Map Domain +type: module +description: Allows indexing multiple Drupal sites into a single search index by Domain. +core: 8.x +package: Search +dependencies: + - search_api_solr + - field + - domain diff --git a/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomain.php b/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomain.php new file mode 100644 index 0000000..299298b --- /dev/null +++ b/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomain.php @@ -0,0 +1,126 @@ +get('domain.negotiator'); + $domain_storage = $container->get('entity_type.manager')->getStorage('domain'); + + return new static ( + $configuration, + $plugin_id, + $plugin_definition, + $domain_negotiator, + $domain_storage + ); + } + + /** + * MappedDomain constructor. + * + * @param array $configuration + * @param $plugin_id + * @param $plugin_definition + * @param DomainNegotiator $domain_negotiator + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, DomainNegotiator $domain_negotiator, DomainStorage $domain_storage) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + + $this->domainNegotiator = $domain_negotiator; + $this->domainStorage = $domain_storage; + } + + /** + * {@inheritdoc} + */ + public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) { + $properties = []; + + if (!$datasource) { + $definition = [ + 'label' => $this->t('Mapped domain'), + 'description' => $this->t('Create a field that maps domains to provided values.'), + 'type' => 'string', + 'processor_id' => $this->getPluginId(), + ]; + $properties['mapped_domain'] = new MappedDomainProperty($definition, $this->domainStorage); + } + + return $properties; + } + + /** + * {@inheritdoc} + */ + public function addFieldValues(ItemInterface $item) { + // Get all of the mapped fields on our item. + $mapped_fields = $this->getFieldsHelper() + ->filterForPropertyPath($item->getFields(), NULL, 'mapped_domain'); + + // Get the entity object, bail if there's somehow not one. + $entity = $item->getOriginalObject()->getValue(); + if (!$entity) { + // Apparently we were active for a wrong item. + return; + } + + foreach ($mapped_fields as $mapped_field) { + + // Get configuration for the field. + $configuration = $mapped_field->getConfiguration(); + + // Get the current domain. + $domain = $this->domainNegotiator->getActiveId(); + + // If there's a config item for the entity and bundle type we're in, set the value for the field. + if(!empty($configuration['field_data'][$domain])) { + // If the token replacement produces a value, add to this item. + $value = $configuration['field_data'][$domain]; + + // Do not use setValues(), since that doesn't preprocess the values according to their data type. + $mapped_field->addValue($value); + } + } + } +} diff --git a/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainProperty.php b/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainProperty.php new file mode 100644 index 0000000..a8521af --- /dev/null +++ b/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainProperty.php @@ -0,0 +1,83 @@ +domainStorage = $domain_storage; + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + 'type' => 'union', + 'fields' => [], + ]; + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(FieldInterface $field, array $form, FormStateInterface $form_state) { + $index = $field->getIndex(); + $configuration = $field->getConfiguration(); + + $form['#attached']['library'][] = 'search_api/drupal.search_api.admin_css'; + $form['#tree'] = TRUE; + + $form['field_data'] = [ + '#type' => 'item', + '#title' => $this->t('Mapped data'), + '#description' => $this->t('Set the data to be sent to the index for each domain.'), + ]; + + $domains = $this->domainStorage->loadMultipleSorted(NULL, TRUE); + + foreach ($domains as $domain) { + $form['field_data'][$domain->get('id')] = [ + '#type' => 'textfield', + '#title' => $this->t('Field data for %domain', ['%domain' => $domain->get('name')]), + ]; + + // Set the default value if something already exists in our config. + if (isset($configuration['field_data'][$domain->get('id')])) { + $form['field_data'][$domain->get('id')]['#default_value'] = $configuration['field_data'][$domain->get('id')]; + } + } + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(FieldInterface $field, array &$form, FormStateInterface $form_state) { + $values = [ + 'field_data' => array_filter($form_state->getValue('field_data')), + ]; + + $field->setConfiguration($values); + } + +}