From 245604dfa81547b955c6652b57ef0874c0939833 Mon Sep 17 00:00:00 2001 From: Daniel Montgomery Date: Thu, 3 Jan 2019 17:51:50 -0600 Subject: [PATCH 1/4] PL-47: Submodule proof of concept for domain support. This is mostly copy and pasted from the base module code. TODO: Convert static calls to dependency injection. --- .../search_api_field_map_domain.info.yml | 9 ++ .../processor/MappedDomainSiteName.php | 82 +++++++++++++++++++ .../Property/MappedDomainSiteNameProperty.php | 74 +++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 search_api_field_map_domain/search_api_field_map_domain.info.yml create mode 100644 search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php create mode 100644 search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainSiteNameProperty.php 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..0046585 --- /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 Solr 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/MappedDomainSiteName.php b/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php new file mode 100644 index 0000000..44f357a --- /dev/null +++ b/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php @@ -0,0 +1,82 @@ + $this->t('Mapped Domain Site Name Field'), + 'description' => $this->t('Create a field that maps domains to site names.'), + 'type' => 'string', + 'processor_id' => $this->getPluginId(), + ]; + $properties['mapped_domain_site_name_field'] = new MappedDomainSiteNameProperty($definition); + } + + 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_site_name_field'); + + // 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; + } + + // Process and set values for each mapped field on the item. + foreach ($mapped_fields as $mapped_field) { + + // Get configuration for the field. + $configuration = $mapped_field->getConfiguration(); + + // TODO: Dependency injection. + // Get the current domain. + $domain = \Drupal::getContainer()->get('domain.negotiator')->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/MappedDomainSiteNameProperty.php b/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainSiteNameProperty.php new file mode 100644 index 0000000..e99b5ec --- /dev/null +++ b/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainSiteNameProperty.php @@ -0,0 +1,74 @@ + '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 in the data sources set in your index configuration.'), + ]; + + // TODO: Dependency injection. + $domains = \Drupal::entityTypeManager()->getStorage('domain')->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); + } + +} From 28fa7e2af1d596d29d183ab35ed35edf3c8e3be2 Mon Sep 17 00:00:00 2001 From: Daniel Montgomery Date: Thu, 3 Jan 2019 18:16:39 -0600 Subject: [PATCH 2/4] PL-47: Dependency injection for the mapped Domain Site Name plugin. --- .../processor/MappedDomainSiteName.php | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php b/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php index 44f357a..9c96724 100644 --- a/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php +++ b/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php @@ -2,10 +2,12 @@ namespace Drupal\search_api_field_map_domain\Plugin\search_api\processor; +use Drupal\domain\DomainNegotiator; use Drupal\search_api\Datasource\DatasourceInterface; use Drupal\search_api\Item\ItemInterface; use Drupal\search_api_field_map_domain\Plugin\search_api\processor\Property\MappedDomainSiteNameProperty; use Drupal\search_api\Processor\ProcessorPluginBase; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Create a field that maps domains to site names. @@ -24,6 +26,43 @@ * ) */ class MappedDomainSiteName extends ProcessorPluginBase { + // @var $domainNegotiator DomainNegotiator. + private $domainNegotiator; + + /** + * @param ContainerInterface $container + * + * @param array $configuration + * @param $plugin_id + * @param $plugin_definition + * + * @return MappedDomainSiteName + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + + $domain_negotiator = $container->get('domain.negotiator'); + + return new static ( + $configuration, + $plugin_id, + $plugin_definition, + $domain_negotiator + ); + } + + /** + * MappedDomainSiteName 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) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + + $this->domainNegotiator = $domain_negotiator; + } /** * {@inheritdoc} @@ -65,9 +104,8 @@ public function addFieldValues(ItemInterface $item) { // Get configuration for the field. $configuration = $mapped_field->getConfiguration(); - // TODO: Dependency injection. // Get the current domain. - $domain = \Drupal::getContainer()->get('domain.negotiator')->getActiveId();; + $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])) { From cc6f20e1650e072a43d1c8b283b97a920e9c03cd Mon Sep 17 00:00:00 2001 From: Daniel Montgomery Date: Thu, 3 Jan 2019 18:29:29 -0600 Subject: [PATCH 3/4] PL-47: Added dependency injection to the processor. --- .../search_api/processor/MappedDomainSiteName.php | 13 ++++++++++--- .../Property/MappedDomainSiteNameProperty.php | 13 +++++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php b/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php index 9c96724..39112e2 100644 --- a/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php +++ b/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php @@ -3,6 +3,7 @@ namespace Drupal\search_api_field_map_domain\Plugin\search_api\processor; use Drupal\domain\DomainNegotiator; +use Drupal\domain\DomainStorage; use Drupal\search_api\Datasource\DatasourceInterface; use Drupal\search_api\Item\ItemInterface; use Drupal\search_api_field_map_domain\Plugin\search_api\processor\Property\MappedDomainSiteNameProperty; @@ -29,6 +30,9 @@ class MappedDomainSiteName extends ProcessorPluginBase { // @var $domainNegotiator DomainNegotiator. private $domainNegotiator; + // @var $domainStorage DomainStorage. + private $domainStorage; + /** * @param ContainerInterface $container * @@ -41,12 +45,14 @@ class MappedDomainSiteName extends ProcessorPluginBase { public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { $domain_negotiator = $container->get('domain.negotiator'); + $domain_storage = $container->get('entity_type.manager')->getStorage('domain'); return new static ( $configuration, $plugin_id, $plugin_definition, - $domain_negotiator + $domain_negotiator, + $domain_storage ); } @@ -58,10 +64,11 @@ public static function create(ContainerInterface $container, array $configuratio * @param $plugin_definition * @param DomainNegotiator $domain_negotiator */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, 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; } /** @@ -77,7 +84,7 @@ public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) { 'type' => 'string', 'processor_id' => $this->getPluginId(), ]; - $properties['mapped_domain_site_name_field'] = new MappedDomainSiteNameProperty($definition); + $properties['mapped_domain_site_name_field'] = new MappedDomainSiteNameProperty($definition, $this->domainStorage); } return $properties; diff --git a/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainSiteNameProperty.php b/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainSiteNameProperty.php index e99b5ec..3c1f2eb 100644 --- a/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainSiteNameProperty.php +++ b/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainSiteNameProperty.php @@ -2,6 +2,7 @@ namespace Drupal\search_api_field_map_domain\Plugin\search_api\processor\Property; +use Drupal\domain\DomainStorage; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\search_api\Item\FieldInterface; @@ -16,6 +17,15 @@ class MappedDomainSiteNameProperty extends ConfigurablePropertyBase { use StringTranslationTrait; + // @var $domainStorage DomainStorage. + private $domainStorage; + + public function __construct($definition, DomainStorage $domain_storage) { + parent::__construct($definition); + + $this->domainStorage = $domain_storage; + } + /** * {@inheritdoc} */ @@ -42,8 +52,7 @@ public function buildConfigurationForm(FieldInterface $field, array $form, FormS '#description' => $this->t('Set the data to be sent to the index for each domain in the data sources set in your index configuration.'), ]; - // TODO: Dependency injection. - $domains = \Drupal::entityTypeManager()->getStorage('domain')->loadMultipleSorted(NULL, TRUE); + $domains = $this->domainStorage->loadMultipleSorted(NULL, TRUE); foreach ($domains as $domain) { $form['field_data'][$domain->get('id')] = [ From 35ce47e2f09111e723fad4cea008101678fa73ae Mon Sep 17 00:00:00 2001 From: Daniel Montgomery Date: Fri, 4 Jan 2019 09:58:52 -0600 Subject: [PATCH 4/4] PL-47: Refactor the class / plugin names. Multiple fields can be created, so using `site name` as part of the plugin doesn't make sense. --- .../search_api_field_map_domain.info.yml | 2 +- ...pedDomainSiteName.php => MappedDomain.php} | 25 +++++++++---------- ...eProperty.php => MappedDomainProperty.php} | 8 +++--- 3 files changed, 17 insertions(+), 18 deletions(-) rename search_api_field_map_domain/src/Plugin/search_api/processor/{MappedDomainSiteName.php => MappedDomain.php} (84%) rename search_api_field_map_domain/src/Plugin/search_api/processor/Property/{MappedDomainSiteNameProperty.php => MappedDomainProperty.php} (90%) 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 index 0046585..89879ae 100644 --- 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 @@ -1,6 +1,6 @@ name: Search API Field Map Domain type: module -description: Allows indexing multiple Drupal sites into a single Solr search index by Domain. +description: Allows indexing multiple Drupal sites into a single search index by Domain. core: 8.x package: Search dependencies: diff --git a/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php b/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomain.php similarity index 84% rename from search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php rename to search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomain.php index 39112e2..299298b 100644 --- a/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomainSiteName.php +++ b/search_api_field_map_domain/src/Plugin/search_api/processor/MappedDomain.php @@ -6,19 +6,19 @@ use Drupal\domain\DomainStorage; use Drupal\search_api\Datasource\DatasourceInterface; use Drupal\search_api\Item\ItemInterface; -use Drupal\search_api_field_map_domain\Plugin\search_api\processor\Property\MappedDomainSiteNameProperty; +use Drupal\search_api_field_map_domain\Plugin\search_api\processor\Property\MappedDomainProperty; use Drupal\search_api\Processor\ProcessorPluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Create a field that maps domains to site names. * - * @see \Drupal\search_api_field_map_domain\Plugin\search_api\processor\Property\MappedDomainSiteNameProperty + * @see \Drupal\search_api_field_map_domain\Plugin\search_api\processor\Property\MappedDomainProperty * * @SearchApiProcessor( - * id = "mapped_domain_site_name", - * label = @Translation("Mapped Domain Site Name"), - * description = @Translation("Create a field that maps domains to site names."), + * id = "mapped_domain", + * label = @Translation("Mapped domain"), + * description = @Translation("Create a field that maps domains to provided values."), * stages = { * "add_properties" = 20, * }, @@ -26,7 +26,7 @@ * hidden = true, * ) */ -class MappedDomainSiteName extends ProcessorPluginBase { +class MappedDomain extends ProcessorPluginBase { // @var $domainNegotiator DomainNegotiator. private $domainNegotiator; @@ -40,7 +40,7 @@ class MappedDomainSiteName extends ProcessorPluginBase { * @param $plugin_id * @param $plugin_definition * - * @return MappedDomainSiteName + * @return MappedDomain */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { @@ -57,7 +57,7 @@ public static function create(ContainerInterface $container, array $configuratio } /** - * MappedDomainSiteName constructor. + * MappedDomain constructor. * * @param array $configuration * @param $plugin_id @@ -79,12 +79,12 @@ public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) { if (!$datasource) { $definition = [ - 'label' => $this->t('Mapped Domain Site Name Field'), - 'description' => $this->t('Create a field that maps domains to site names.'), + '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_site_name_field'] = new MappedDomainSiteNameProperty($definition, $this->domainStorage); + $properties['mapped_domain'] = new MappedDomainProperty($definition, $this->domainStorage); } return $properties; @@ -96,7 +96,7 @@ public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) { public function addFieldValues(ItemInterface $item) { // Get all of the mapped fields on our item. $mapped_fields = $this->getFieldsHelper() - ->filterForPropertyPath($item->getFields(), NULL, 'mapped_domain_site_name_field'); + ->filterForPropertyPath($item->getFields(), NULL, 'mapped_domain'); // Get the entity object, bail if there's somehow not one. $entity = $item->getOriginalObject()->getValue(); @@ -105,7 +105,6 @@ public function addFieldValues(ItemInterface $item) { return; } - // Process and set values for each mapped field on the item. foreach ($mapped_fields as $mapped_field) { // Get configuration for the field. diff --git a/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainSiteNameProperty.php b/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainProperty.php similarity index 90% rename from search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainSiteNameProperty.php rename to search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainProperty.php index 3c1f2eb..a8521af 100644 --- a/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainSiteNameProperty.php +++ b/search_api_field_map_domain/src/Plugin/search_api/processor/Property/MappedDomainProperty.php @@ -9,11 +9,11 @@ use Drupal\search_api\Processor\ConfigurablePropertyBase; /** - * Defines an "mapped domain site name field" property. + * Defines an "mapped domain" property. * - * @see \Drupal\search_api_field_map_domain\Plugin\search_api\processor\MappedDomainSiteName + * @see \Drupal\search_api_field_map_domain\Plugin\search_api\processor\MappedDomain */ -class MappedDomainSiteNameProperty extends ConfigurablePropertyBase { +class MappedDomainProperty extends ConfigurablePropertyBase { use StringTranslationTrait; @@ -49,7 +49,7 @@ public function buildConfigurationForm(FieldInterface $field, array $form, FormS $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 in the data sources set in your index configuration.'), + '#description' => $this->t('Set the data to be sent to the index for each domain.'), ]; $domains = $this->domainStorage->loadMultipleSorted(NULL, TRUE);