diff --git a/config/schema/facets.facetsource.schema.yml b/config/schema/facets.facetsource.schema.yml new file mode 100644 index 0000000000000000000000000000000000000000..962703ef7790b0caeceb2666a98b864afa6396b8 --- /dev/null +++ b/config/schema/facets.facetsource.schema.yml @@ -0,0 +1,16 @@ +facets.facet_source.*: + type: config_entity + label : 'Facet Source' + mapping: + uuid: + type: string + label: 'UUID' + id: + type: string + label: 'ID' + name: + type: label + label: Name' + filterKey: + type: string + label: 'Filter key' diff --git a/core_search_facets/src/Plugin/CoreSearchFacetSourceInterface.php b/core_search_facets/src/Plugin/CoreSearchFacetSourceInterface.php index fa16be56bce0f1b038396ca0094c0ec387e4d885..24486a2b04070cc9d07b679c55eca63c1325e5a0 100644 --- a/core_search_facets/src/Plugin/CoreSearchFacetSourceInterface.php +++ b/core_search_facets/src/Plugin/CoreSearchFacetSourceInterface.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\core_search_facets\Plugin\FacetSourceInterface. + * Contains \Drupal\core_search_facets\Plugin\CoreSearchFacetSourceInterface. */ namespace Drupal\core_search_facets\Plugin; @@ -14,7 +14,7 @@ use Drupal\facets\FacetInterface; * * A facet source is used to abstract the data source where facets can be added * to. A good example of this is a search api view. There are other possible - * facet data sources, these all implement the FacetSourceInterface. + * facet data sources, these all implement the FacetSourcePluginInterface. */ interface CoreSearchFacetSourceInterface { diff --git a/core_search_facets/src/Plugin/facets/facet_source/CoreNodeSearchFacetSource.php b/core_search_facets/src/Plugin/facets/facet_source/CoreNodeSearchFacetSource.php index 38b135e61ad0faa084b1a45393e43fdab44dfc94..12e63198d4d2ddf6161dd22e10c0c92a8ea654ad 100644 --- a/core_search_facets/src/Plugin/facets/facet_source/CoreNodeSearchFacetSource.php +++ b/core_search_facets/src/Plugin/facets/facet_source/CoreNodeSearchFacetSource.php @@ -12,10 +12,9 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\core_search_facets\Plugin\CoreSearchFacetSourceInterface; use Drupal\facets\FacetInterface; -use Drupal\facets\FacetSource\FacetSourceInterface; use Drupal\facets\FacetSource\FacetSourcePluginBase; +use Drupal\facets\FacetSource\FacetSourcePluginInterface; use Drupal\field\Entity\FieldConfig; -use Drupal\field\Entity\FieldStorageConfig; use Drupal\search\SearchPageInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RequestStack; @@ -178,7 +177,7 @@ class CoreNodeSearchFacetSource extends FacetSourcePluginBase implements CoreSea /** * {@inheritdoc} */ - public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourceInterface $facet_source) { + public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourcePluginInterface $facet_source) { $form['field_identifier'] = [ '#type' => 'select', diff --git a/facets.routing.yml b/facets.routing.yml index 576dd647948aac4a1cc1bcf0d2545e9d04563519..5202aa7f6b1ed5b70a88d6e5c82f3316723d68b0 100644 --- a/facets.routing.yml +++ b/facets.routing.yml @@ -41,3 +41,12 @@ entity.facets_facet.display_form: _entity_form: 'facets_facet.display' requirements: _entity_access: 'facets_facet.edit' + + +entity.facets_facetsource.edit_form: + path: '/admin/config/search/facets/facet-sources/{source_id}/edit' + defaults: + _controller: '\Drupal\facets\Controller\FacetSourceController::facetSourceConfigForm' + _title: 'Edit facet source configuration' + requirements: + _entity_create_access: 'facets_facet' diff --git a/src/Annotation/FacetsFacetSource.php b/src/Annotation/FacetsFacetSource.php index bfe425c8ce7843256a80adff6d381f93822e4075..7389e311a746468f4de0b41cd7df04fdb0c5d317 100644 --- a/src/Annotation/FacetsFacetSource.php +++ b/src/Annotation/FacetsFacetSource.php @@ -13,7 +13,7 @@ use Drupal\Component\Annotation\Plugin; * Defines a Facets facet source annotation. * * @see \Drupal\facets\FacetSource\FacetSourcePluginManager - * @see \Drupal\facets\FacetSource\FacetSourceInterface + * @see \Drupal\facets\FacetSource\FacetSourcePluginInterface * @see \Drupal\facets\FacetSource\FacetSourcePluginBase * @see plugin_api * diff --git a/src/Controller/FacetSourceController.php b/src/Controller/FacetSourceController.php new file mode 100644 index 0000000000000000000000000000000000000000..578e7c9e328dd6d2a27f807c3f2d0dc65f8f59b1 --- /dev/null +++ b/src/Controller/FacetSourceController.php @@ -0,0 +1,31 @@ +formBuilder()->getForm('\Drupal\facets\Form\FacetSourceEditForm'); + } + +} diff --git a/src/Entity/Facet.php b/src/Entity/Facet.php index 889a074773f9f8ee4c855e004486826d4bc3078a..88c71bd2c1eb51b292a09b189f33fe437cf3a4b2 100644 --- a/src/Entity/Facet.php +++ b/src/Entity/Facet.php @@ -131,7 +131,7 @@ class Facet extends ConfigEntityBase implements FacetInterface { /** * The facet source belonging to this facet. * - * @var \Drupal\facets\FacetSource\FacetSourceInterface + * @var \Drupal\facets\FacetSource\FacetSourcePluginInterface * * @see getFacetSource() */ @@ -186,6 +186,14 @@ class Facet extends ConfigEntityBase implements FacetInterface { */ protected $widget_plugin_manager; + /** + * The facet source config object. + * + * @var \Drupal\Facets\FacetSourceInterface + * The facet source config object. + */ + protected $facetSourceConfig; + /** * {@inheritdoc} */ @@ -370,6 +378,40 @@ class Facet extends ConfigEntityBase implements FacetInterface { return $this->facet_source_id; } + /** + * {@inheritdoc} + */ + public function getFacetSourceConfig() { + // Return the facet source config object, if it's already set on the facet. + if ($this->facetSourceConfig instanceof FacetSource) { + return $this->facetSourceConfig; + } + + $storage = \Drupal::entityTypeManager()->getStorage('facets_facet_source'); + $source_id = str_replace(':', '__', $this->facet_source_id); + + // Load and return the facet source config object from the storage. + $facet_source = $storage->load($source_id); + if ($facet_source instanceof FacetSource) { + $this->facetSourceConfig = $facet_source; + return $this->facetSourceConfig; + } + + // We didn't have a facet source config entity yet for this facet source + // plugin, so we create it on the fly. + $facet_source = new FacetSource( + [ + 'id' => $source_id, + 'name' => $this->facet_source_id, + ], + 'facets_facet_source' + ); + $facet_source->save(); + + $this->facetSourceConfig = $facet_source; + return $this->facetSourceConfig; + } + /** * Retrieves all processors supported by this facet. * @@ -458,7 +500,7 @@ class Facet extends ConfigEntityBase implements FacetInterface { // Create our settings for this facet source.. $config = isset($this->facetSourcePlugins[$name]) ? $this->facetSourcePlugins[$name] : []; - /* @var $facet_source \Drupal\facets\FacetSource\FacetSourceInterface */ + /* @var $facet_source \Drupal\facets\FacetSource\FacetSourcePluginInterface */ $facet_source = $facet_source_plugin_manager->createInstance($name, $config); $this->facetSourcePlugins[$name] = $facet_source; } diff --git a/src/Entity/FacetSource.php b/src/Entity/FacetSource.php new file mode 100644 index 0000000000000000000000000000000000000000..3d3f7adc7d61c72ef4cee5740bbf47e6fefe5185 --- /dev/null +++ b/src/Entity/FacetSource.php @@ -0,0 +1,98 @@ +id; + } + + /** + * {@inheritdoc} + */ + public function getName() { + return $this->name; + } + + /** + * {@inheritdoc} + */ + public function setFilterKey($filter_key) { + $this->filterKey = $filter_key; + } + + /** + * {@inheritdoc} + */ + public function getFilterKey() { + return $this->filterKey; + } + +} diff --git a/src/FacetInterface.php b/src/FacetInterface.php index 7e39f2ae90c536438bf9f70af836a6fac6d028b5..58c1cd1ce4739ba933ce0f0af5e961cc08b187b6 100644 --- a/src/FacetInterface.php +++ b/src/FacetInterface.php @@ -200,18 +200,26 @@ interface FacetInterface extends ConfigEntityInterface { /** * Returns the plugin instance of a facet source. * - * @return \Drupal\facets\FacetSource\FacetSourceInterface + * @return \Drupal\facets\FacetSource\FacetSourcePluginInterface * The plugin instance for the facet source. */ public function getFacetSource(); + /** + * Returns the facet source configuration object. + * + * @return \Drupal\facets\FacetSourceInterface + * A facet source configuration object. + */ + public function getFacetSourceConfig(); + /** * Load the facet sources for this facet. * * @param bool|TRUE $only_enabled * Only return enabled facet sources. * - * @return \Drupal\facets\FacetSource\FacetSourceInterface[] + * @return \Drupal\facets\FacetSource\FacetSourcePluginInterface[] * An array of facet sources. */ public function getFacetSources($only_enabled = TRUE); diff --git a/src/FacetListBuilder.php b/src/FacetListBuilder.php index 3469a797540e4f22d5d222953de121eedc263cb2..bb63d0499734c8446cd969bb2d81ce9f9680c305 100644 --- a/src/FacetListBuilder.php +++ b/src/FacetListBuilder.php @@ -10,6 +10,7 @@ namespace Drupal\facets; use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Config\Entity\ConfigEntityListBuilder; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Link; /** * Builds a listing of facet entities. @@ -134,7 +135,13 @@ class FacetListBuilder extends ConfigEntityListBuilder { 'status' => array( 'data' => '', ), - 'operations' => array(), + 'operations' => array( + 'data' => Link::createFromRoute( + $this->t('Configure'), + 'entity.facets_facetsource.edit_form', + ['source_id' => $facet_source['id']] + )->toRenderable(), + ), ), 'class' => array('facet-source'), ); @@ -153,7 +160,7 @@ class FacetListBuilder extends ConfigEntityListBuilder { '#markup' => $this->t( 'You currently have no facet sources defined. You should start by adding a facet source before creating facets.
An example of a facet source is a view based on Search API or a Search API page. - Other modules can also implement a facet source by providing a plugin that implements the FacetSourceInterface.' + Other modules can also implement a facet source by providing a plugin that implements the FacetSourcePluginInterface.' ), ]; } diff --git a/src/FacetManager/DefaultFacetManager.php b/src/FacetManager/DefaultFacetManager.php index 254ee04047b338a4d23d98cd7fd63ebbcb0121f9..29bd459e62bf5fe615850da2fac514a869463750 100644 --- a/src/FacetManager/DefaultFacetManager.php +++ b/src/FacetManager/DefaultFacetManager.php @@ -96,7 +96,7 @@ class DefaultFacetManager { * * @var string * - * @see \Drupal\facets\FacetSource\FacetSourceInterface + * @see \Drupal\facets\FacetSource\FacetSourcePluginInterface */ protected $facetSourceId; @@ -211,7 +211,7 @@ class DefaultFacetManager { $processor_definition = $processor->getPluginDefinition(); if (is_array($processor_definition['stages']) && array_key_exists(ProcessorInterface::STAGE_PRE_QUERY, $processor_definition['stages'])) { /** @var PreQueryProcessorInterface $pre_query_processor */ - $pre_query_processor = $this->processorPluginManager->createInstance($processor->getPluginDefinition()['id']); + $pre_query_processor = $this->processorPluginManager->createInstance($processor->getPluginDefinition()['id'], ['facet' => $facet]); if (!$pre_query_processor instanceof PreQueryProcessorInterface) { throw new InvalidProcessorException(new FormattableMarkup("The processor @processor has a pre_query definition but doesn't implement the required PreQueryProcessorInterface interface", ['@processor' => $processor_configuration['processor_id']])); } @@ -275,7 +275,7 @@ class DefaultFacetManager { $processor_definition = $this->processorPluginManager->getDefinition($processor->getPluginDefinition()['id']); if (is_array($processor_definition['stages']) && array_key_exists(ProcessorInterface::STAGE_BUILD, $processor_definition['stages'])) { /** @var BuildProcessorInterface $build_processor */ - $build_processor = $this->processorPluginManager->createInstance($processor->getPluginDefinition()['id']); + $build_processor = $this->processorPluginManager->createInstance($processor->getPluginDefinition()['id'], ['facet' => $facet]); if (!$build_processor instanceof BuildProcessorInterface) { throw new InvalidProcessorException(new FormattableMarkup("The processor @processor has a build definition but doesn't implement the required BuildProcessorInterface interface", ['@processor' => $processor['processor_id']])); } @@ -308,7 +308,7 @@ class DefaultFacetManager { */ public function updateResults() { // Get an instance of the facet source. - /** @var \drupal\facets\FacetSource\FacetSourceInterface $facet_source_plugin */ + /** @var \drupal\facets\FacetSource\FacetSourcePluginInterface $facet_source_plugin */ $facet_source_plugin = $this->facetSourcePluginManager->createInstance($this->facetSourceId); $facet_source_plugin->fillFacetsWithResults($this->facets); diff --git a/src/FacetSource/FacetSourcePluginBase.php b/src/FacetSource/FacetSourcePluginBase.php index 127b72168389d8dfdbc6c8d4aa9ecbd771be90a8..53dba895a863dee2d13c11613c9865c85d5f93e6 100644 --- a/src/FacetSource/FacetSourcePluginBase.php +++ b/src/FacetSource/FacetSourcePluginBase.php @@ -23,10 +23,10 @@ use Drupal\Facets\FacetInterface; * * @see \Drupal\facets\Annotation\FacetsFacetSource * @see \Drupal\facets\FacetSource\FacetSourcePluginManager - * @see \Drupal\facets\FacetSource\FacetSourceInterface + * @see \Drupal\facets\FacetSource\FacetSourcePluginInterface * @see plugin_api */ -abstract class FacetSourcePluginBase extends PluginBase implements FacetSourceInterface, ContainerFactoryPluginInterface { +abstract class FacetSourcePluginBase extends PluginBase implements FacetSourcePluginInterface, ContainerFactoryPluginInterface { /** * The plugin manager. diff --git a/src/FacetSource/FacetSourceInterface.php b/src/FacetSource/FacetSourcePluginInterface.php similarity index 88% rename from src/FacetSource/FacetSourceInterface.php rename to src/FacetSource/FacetSourcePluginInterface.php index aef8c7a6b32e0f7e896d6c3a0b4ee9e4a5ab46ac..93c114ec77717e1e054bc54836b3a12a3c5f3632 100644 --- a/src/FacetSource/FacetSourceInterface.php +++ b/src/FacetSource/FacetSourcePluginInterface.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\facets\FacetSource\FacetSourceInterface. + * Contains \Drupal\facets\FacetSource\FacetSourcePluginInterface. */ namespace Drupal\facets\FacetSource; @@ -15,11 +15,11 @@ use Drupal\facets\FacetInterface; * * A facet source is used to abstract the data source where facets can be added * to. A good example of this is a search api view. There are other possible - * facet data sources, these all implement the FacetSourceInterface. + * facet data sources, these all implement the FacetSourcePluginInterface. * * @see plugin_api */ -interface FacetSourceInterface { +interface FacetSourcePluginInterface { /** * Adds a configuration form for this facet source. @@ -30,10 +30,10 @@ interface FacetSourceInterface { * The current form state. * @param \Drupal\facets\FacetInterface $facet * The facet being edited. - * @param \Drupal\facets\FacetSource\FacetSourceInterface $facet_source + * @param \Drupal\facets\FacetSource\FacetSourcePluginInterface $facet_source * The facet source being edited. */ - public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourceInterface $facet_source); + public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourcePluginInterface $facet_source); /** * Fill in facet data in to the configured facets. diff --git a/src/FacetSource/FacetSourcePluginManager.php b/src/FacetSource/FacetSourcePluginManager.php index 377af69dbed363e2d663e650057d1322e18049c6..1b628746ac32798cdcb67be3b1293dcb77cda77e 100644 --- a/src/FacetSource/FacetSourcePluginManager.php +++ b/src/FacetSource/FacetSourcePluginManager.php @@ -32,7 +32,7 @@ class FacetSourcePluginManager extends DefaultPluginManager { * The module handler. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/facets/facet_source', $namespaces, $module_handler, 'Drupal\facets\FacetSource\FacetSourceInterface', 'Drupal\facets\Annotation\FacetsFacetSource'); + parent::__construct('Plugin/facets/facet_source', $namespaces, $module_handler, 'Drupal\facets\FacetSource\FacetSourcePluginInterface', 'Drupal\facets\Annotation\FacetsFacetSource'); } } diff --git a/src/FacetSourceInterface.php b/src/FacetSourceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..83957601e43cb07fcf8aafbf67914bd4b1b11740 --- /dev/null +++ b/src/FacetSourceInterface.php @@ -0,0 +1,41 @@ +getEntity()->getFacetSourceId(); if (!is_null($facet_source_id) && $facet_source_id !== '') { - /** @var \Drupal\facets\FacetSource\FacetSourceInterface $facet_source */ + /** @var \Drupal\facets\FacetSource\FacetSourcePluginInterface $facet_source */ $facet_source = $this->getFacetSourcePluginManager()->createInstance($facet_source_id); if ($config_form = $facet_source->buildConfigurationForm([], $form_state, $this->getEntity(), $facet_source)) { diff --git a/src/Form/FacetSourceEditForm.php b/src/Form/FacetSourceEditForm.php new file mode 100644 index 0000000000000000000000000000000000000000..067a39fb05cc556ad0c2795f196580e6340307a8 --- /dev/null +++ b/src/Form/FacetSourceEditForm.php @@ -0,0 +1,88 @@ +getStorage('facets_facet_source'); + + // Make sure we remove colons from the source id, those are disallowed in + // the entity id. + $source_id = $this->getRequest()->get('source_id'); + $source_id = str_replace(':', '__', $source_id); + + $facet_source = $facet_source_storage->load($source_id); + + if ($facet_source instanceof FacetSource) { + $this->setEntity($facet_source); + } + else { + + // We didn't have a facet source config entity yet for this facet source + // plugin, so we create it on the fly. + $facet_source = new FacetSource( + [ + 'id' => $source_id, + 'name' => $this->getRequest()->get('source_id'), + ], + 'facets_facet_source' + ); + $facet_source->save(); + $this->setEntity($facet_source); + } + + $this->setModuleHandler(\Drupal::moduleHandler()); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'facet_source_edit_form'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + + /** @var \Drupal\facets\FacetSourceInterface $facet_source */ + $facet_source = $this->getEntity(); + + // Filter key setting. + $form['filterKey'] = [ + '#type' => 'textfield', + '#title' => $this->t('Filter key'), + '#size' => 20, + '#maxlength' => 255, + '#default_value' => $facet_source->getFilterKey(), + '#description' => $this->t( + 'The key used in the url to identify the facet source. + When using multiple facet sources you should make sure each facet source has a different filter key.' + ), + ]; + + // The parent's form build method will add a save button. + return parent::buildForm($form, $form_state); + } + +} diff --git a/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php b/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php index b7f86d51ca71f65d1c49908d7ba0720b526359ff..74e98c8991c4015c8c7bb393ed3afca671438ab3 100644 --- a/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php +++ b/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php @@ -10,10 +10,9 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\facets\Exception\InvalidQueryTypeException; use Drupal\facets\FacetInterface; +use Drupal\facets\FacetSource\FacetSourcePluginInterface; use Drupal\search_api\Backend\BackendInterface; -use Drupal\facets\FacetSource\FacetSourceInterface; use Drupal\facets\FacetSource\FacetSourcePluginBase; -use Drupal\search_api\FacetsQueryTypeMappingInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -66,7 +65,7 @@ abstract class SearchApiBaseFacetSource extends FacetSourcePluginBase { /** * {@inheritdoc} */ - public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourceInterface $facet_source) { + public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourcePluginInterface $facet_source) { $form['field_identifier'] = [ '#type' => 'select', diff --git a/src/Processor/UrlProcessorPluginBase.php b/src/Processor/UrlProcessorPluginBase.php index ee8af0b9b3ddbd0ea993191f1bb081866bb9cfe9..99d587592ac983dcca3cadc79875af07301dd6bc 100644 --- a/src/Processor/UrlProcessorPluginBase.php +++ b/src/Processor/UrlProcessorPluginBase.php @@ -7,6 +7,7 @@ namespace Drupal\facets\Processor; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\facets\Exception\InvalidProcessorException; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -53,6 +54,18 @@ abstract class UrlProcessorPluginBase extends ProcessorPluginBase implements Url public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->request = $request; + + if (!isset($configuration['facet'])) { + throw new InvalidProcessorException(); + } + + /** @var \Drupal\facets\FacetInterface $facet */ + $facet = $configuration['facet']; + + /** @var \Drupal\facets\FacetSourceInterface $facet_source_config */ + $facet_source_config = $facet->getFacetSourceConfig(); + + $this->filterKey = $facet_source_config->getFilterKey() ?: 'f'; } /** diff --git a/src/Tests/FacetSourceTest.php b/src/Tests/FacetSourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3beef1d33fcaafeb278cf1074bb99e1d794ffd30 --- /dev/null +++ b/src/Tests/FacetSourceTest.php @@ -0,0 +1,40 @@ +drupalLogin($this->adminUser); + + // Test the overview. + $this->drupalGet('admin/config/search/facets'); + $this->assertLink($this->t('Configure')); + $this->clickLink($this->t('Configure')); + + // Test the edit page. + $this->assertField('filterKey'); + $this->drupalPostForm(NULL, array('filterKey' => 'fq'), $this->t('Save')); + + // Test that saving worked. + $this->assertField('filterKey'); + $this->assertRaw('fq'); + } + +} diff --git a/tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php b/tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php index 2315ddfef3b0595502f0ae7dd4686788f512525f..d23054b19285ec3533f54687da1796bfdc8cf9d8 100644 --- a/tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php +++ b/tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php @@ -8,6 +8,7 @@ namespace Drupal\Tests\facets\Unit\Plugin\Processor; use Drupal\facets\Entity\Facet; +use Drupal\facets\Entity\FacetSource; use Drupal\facets\Plugin\facets\processor\QueryStringUrlProcessor; use Drupal\facets\Result\Result; use Drupal\Tests\UnitTestCase; @@ -49,6 +50,8 @@ class QueryStringUrlProcessorTest extends UnitTestCase { new Result('duck', 'Duck', 15), new Result('alpaca', 'Alpaca', 25), ]; + + $this->setContainer(); } /** @@ -62,7 +65,7 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('f', ['test:badger']); - $this->processor = new QueryStringUrlProcessor([], 'query_string', [], $request); + $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); $this->processor->preQuery($facet); $this->assertEquals(['badger'], $facet->getActiveItems()); @@ -79,7 +82,7 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('f', ['test:badger', 'test:mushroom', 'donkey:kong']); - $this->processor = new QueryStringUrlProcessor([], 'query_string', [], $request); + $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); $this->processor->preQuery($facet); $this->assertEquals(['badger', 'mushroom'], $facet->getActiveItems()); @@ -95,7 +98,7 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('f', []); - $this->processor = new QueryStringUrlProcessor([], 'query_string', [], $request); + $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); $results = $this->processor->build($facet, []); $this->assertEmpty($results); } @@ -111,9 +114,7 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('f', []); - $this->setContainer(); - - $this->processor = new QueryStringUrlProcessor([], 'query_string', [], $request); + $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); $results = $this->processor->build($facet, $this->originalResults); /** @var \Drupal\facets\Result\ResultInterface $r */ @@ -137,9 +138,7 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('f', ['king:kong']); - $this->setContainer(); - - $this->processor = new QueryStringUrlProcessor([], 'query_string', [], $request); + $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); $results = $this->processor->build($facet, $original_results); /** @var \Drupal\facets\Result\ResultInterface $r */ @@ -154,6 +153,46 @@ class QueryStringUrlProcessorTest extends UnitTestCase { } } + /** + * Test that the facet source configuration filter key override works. + */ + public function testFacetSourceFilterKeyOverride() { + $facet_source = new FacetSource(['filterKey' => 'ab'], 'facets_facet_source'); + + // Override the container with the new facet source. + $storage = $this->getMock('\Drupal\Core\Entity\EntityStorageInterface'); + $storage->expects($this->once()) + ->method('load') + ->willReturn($facet_source); + $em = $this->getMockBuilder('\Drupal\Core\Entity\EntityTypeManagerInterface') + ->disableOriginalConstructor() + ->getMock(); + $em->expects($this->any()) + ->method('getStorage') + ->willReturn($storage); + + $container = \Drupal::getContainer(); + $container->set('entity_type.manager', $em); + \Drupal::setContainer($container); + + $facet = new Facet([], 'facet'); + $facet->setFieldIdentifier('test'); + $facet->setFacetSourceId('facet_source__dummy'); + + $request = new Request(); + $request->query->set('ab', []); + + $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); + $results = $this->processor->build($facet, $this->originalResults); + + /** @var \Drupal\facets\Result\ResultInterface $r */ + foreach ($results as $r) { + $this->assertInstanceOf('\Drupal\facets\Result\ResultInterface', $r); + $this->assertEquals('route:test?ab[0]=test%3A' . $r->getRawValue(), $r->getUrl()->toUriString()); + } + + } + /** * Set the container for use in unit tests. */ @@ -170,21 +209,31 @@ class QueryStringUrlProcessorTest extends UnitTestCase { ] ); - $fsi = $this->getMockBuilder('\Drupal\facets\FacetSource\FacetSourceInterface') + $fsi = $this->getMockBuilder('\Drupal\facets\FacetSource\FacetSourcePluginInterface') ->disableOriginalConstructor() ->getMock(); $fsi->method('getPath') ->willReturn('search/test'); - $manager = $this->getMockBuilder('Drupal\facets\FacetSource\FacetSourcePluginManager') + $manager = $this->getMockBuilder('\Drupal\facets\FacetSource\FacetSourcePluginManager') ->disableOriginalConstructor() ->getMock(); $manager->method('createInstance') ->willReturn($fsi); + $storage = $this->getMock('\Drupal\Core\Entity\EntityStorageInterface'); + $em = $this->getMockBuilder('\Drupal\Core\Entity\EntityTypeManagerInterface') + ->disableOriginalConstructor() + ->getMock(); + $em->expects($this->any()) + ->method('getStorage') + ->willReturn($storage); + $container = new ContainerBuilder(); $container->set('router.no_access_checks', $router); $container->set('plugin.manager.facets.facet_source', $manager); + $container->set('entity_type.manager', $em); + $container->set('entity.manager', $em); \Drupal::setContainer($container); }