diff --git a/modules/facets_range_widget/src/Plugin/facets/widget/RangeSliderWidget.php b/modules/facets_range_widget/src/Plugin/facets/widget/RangeSliderWidget.php index 890ff7e..277ec9a 100644 --- a/modules/facets_range_widget/src/Plugin/facets/widget/RangeSliderWidget.php +++ b/modules/facets_range_widget/src/Plugin/facets/widget/RangeSliderWidget.php @@ -54,8 +54,8 @@ public function isPropertyRequired($name, $type) { /** * {@inheritdoc} */ - public function getQueryType(array $query_types) { - return $query_types['range']; + public function getQueryType() { + return 'range'; } } diff --git a/modules/facets_range_widget/src/Plugin/facets/widget/SliderWidget.php b/modules/facets_range_widget/src/Plugin/facets/widget/SliderWidget.php index 8620a7e..fe15671 100644 --- a/modules/facets_range_widget/src/Plugin/facets/widget/SliderWidget.php +++ b/modules/facets_range_widget/src/Plugin/facets/widget/SliderWidget.php @@ -155,13 +155,6 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta return $form; } - /** - * {@inheritdoc} - */ - public function getQueryType(array $query_types) { - return $query_types['string']; - } - /** * {@inheritdoc} */ diff --git a/src/Entity/Facet.php b/src/Entity/Facet.php index 45e4468..5fc7d87 100644 --- a/src/Entity/Facet.php +++ b/src/Entity/Facet.php @@ -6,6 +6,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\facets\Exception\Exception; use Drupal\facets\Exception\InvalidProcessorException; +use Drupal\facets\Exception\InvalidQueryTypeException; use Drupal\facets\FacetInterface; /** @@ -456,9 +457,59 @@ public function getQueryType() { $widget = $this->getWidgetInstance(); // Give the widget the chance to select a preferred query type. This is - // useful for widget that have different query type. See the date widget, - // that needs to select the date query type. - return $widget->getQueryType($query_types); + // needed for widget that have different query type. For example the need + // for a range query. + $widgetQueryType = $widget->getQueryType(); + + // Allow widgets to also specify a query type. + $processorQueryTypes = []; + foreach ($this->getProcessors() as $processor) { + $pqt = $processor->getQueryType(); + if ($pqt !== NULL) { + $processorQueryTypes[] = $pqt; + } + } + $processorQueryTypes = array_flip($processorQueryTypes); + + // The widget has made no decision and neither have the processors. + if ($widgetQueryType === NULL && count($processorQueryTypes) === 0) { + return $this->pickQueryType($query_types, 'string'); + } + // The widget has made a decision and processors have specific needs. + if ($widgetQueryType !== NULL && count($processorQueryTypes) === 0) { + return $this->pickQueryType($query_types, $widgetQueryType); + } + // The widget has made no decision but the processors have made 1 decision. + if ($widgetQueryType === NULL && count($processorQueryTypes) === 1) { + return $this->pickQueryType($query_types, key($processorQueryTypes)); + } + // The widget has made a decision, and so have the processors, but it's + // the same. + if ($widgetQueryType !== NULL && count($processorQueryTypes) === 1 && key($processorQueryTypes) === $widgetQueryType) { + return $this->pickQueryType($query_types, $widgetQueryType); + } + + // Invalid choice. + throw new InvalidQueryTypeException("Invalid query type combination in widget / processors"); + } + + /** + * Choose the query type. + * + * @param array $allTypes + * An array of query type definitions. + * @param string $type + * The chose query type. + * + * @return string + * The class name of the chose query type. + * @throws \Drupal\facets\Exception\InvalidQueryTypeException + */ + protected function pickQueryType(array $allTypes, $type) { + if (!isset($allTypes[$type])) { + throw new InvalidQueryTypeException("Query type {$type} doesn't exist."); + } + return $allTypes[$type]; } /** diff --git a/src/Plugin/facets/processor/DateItemProcessor.php b/src/Plugin/facets/processor/DateItemProcessor.php index eb3b4da..974890b 100644 --- a/src/Plugin/facets/processor/DateItemProcessor.php +++ b/src/Plugin/facets/processor/DateItemProcessor.php @@ -52,13 +52,12 @@ private function granularityOptions() { * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet) { - $processors = $facet->getProcessors(); - $config = isset($processors[$this->getPluginId()]) ? $processors[$this->getPluginId()] : NULL; + $this->getConfiguration(); $build['display_relative'] = [ '#type' => 'radios', '#title' => $this->t('Date display'), - '#default_value' => !is_null($config) ? $config->getConfiguration()['display_relative'] : $this->defaultConfiguration()['display_relative'], + '#default_value' => $this->getConfiguration()['display_relative'], '#options' => [ FALSE => $this->t('Actual date with granularity'), TRUE => $this->t('Relative date'), @@ -68,13 +67,13 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $build['granularity'] = [ '#type' => 'radios', '#title' => $this->t('Granularity'), - '#default_value' => !is_null($config) ? $config->getConfiguration()['granularity'] : $this->defaultConfiguration()['granularity'], + '#default_value' => $this->getConfiguration()['granularity'], '#options' => $this->granularityOptions(), ]; $build['date_display'] = [ '#type' => 'textfield', '#title' => $this->t('Date format'), - '#default_value' => !is_null($config) ? $config->getConfiguration()['date_display'] : $this->defaultConfiguration()['date_display'], + '#default_value' => $this->getConfiguration()['date_display'], '#description' => $this->t('Override default date format used for the displayed filter format. See the PHP manual for available options.'), '#states' => [ 'visible' => [':input[name="facet_settings[date_item][settings][display_relative]"]' => ['value' => 0]], @@ -84,6 +83,13 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta return $build; } + /** + * {@inheritdoc} + */ + public function getQueryType() { + return 'date'; + } + /** * {@inheritdoc} */ diff --git a/src/Plugin/facets/widget/DateArrayWidget.php b/src/Plugin/facets/widget/DateArrayWidget.php deleted file mode 100644 index 1beab1d..0000000 --- a/src/Plugin/facets/widget/DateArrayWidget.php +++ /dev/null @@ -1,94 +0,0 @@ - $this->t('Year'), - SearchApiDate::FACETAPI_DATE_MONTH => $this->t('Month'), - SearchApiDate::FACETAPI_DATE_DAY => $this->t('Day'), - SearchApiDate::FACETAPI_DATE_HOUR => $this->t('Hour'), - SearchApiDate::FACETAPI_DATE_MINUTE => $this->t('Minute'), - SearchApiDate::FACETAPI_DATE_SECOND => $this->t('Second'), - ]; - } - - /** - * {@inheritdoc} - */ - public function defaultConfiguration() { - return [ - 'display_relative' => FALSE, - 'granularity' => SearchApiDate::FACETAPI_DATE_MONTH, - 'date_display' => '', - 'relative_granularity' => 1, - 'relative_text' => TRUE, - ] + parent::defaultConfiguration(); - } - - /** - * {@inheritdoc} - */ - public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet) { - $configuration = $this->getConfiguration(); - - $form += parent::buildConfigurationForm($form, $form_state, $facet); - - $form['display_relative'] = [ - '#type' => 'radios', - '#title' => $this->t('Date display'), - '#default_value' => $configuration['display_relative'], - '#options' => [ - FALSE => $this->t('Actual date with granularity'), - TRUE => $this->t('Relative date'), - ], - ]; - - $form['granularity'] = [ - '#type' => 'radios', - '#title' => $this->t('Granularity'), - '#default_value' => $configuration['granularity'], - '#options' => $this->granularityOptions(), - ]; - $form['date_display'] = [ - '#type' => 'textfield', - '#title' => $this->t('Date format'), - '#default_value' => $configuration['date_display'], - '#description' => $this->t('Override default date format used for the displayed filter format. See the PHP manual for available options.'), - '#states' => [ - 'visible' => [':input[name="widget_config[display_relative]"]' => ['value' => 0]], - ], - ]; - - return $form; - } - - /** - * {@inheritdoc} - */ - public function getQueryType(array $query_types) { - return $query_types['date']; - } - -} diff --git a/src/Plugin/facets/widget/DateBasicWidget.php b/src/Plugin/facets/widget/DateBasicWidget.php deleted file mode 100644 index 1915d53..0000000 --- a/src/Plugin/facets/widget/DateBasicWidget.php +++ /dev/null @@ -1,124 +0,0 @@ - $this->t('Year'), - SearchApiDate::FACETAPI_DATE_MONTH => $this->t('Month'), - SearchApiDate::FACETAPI_DATE_DAY => $this->t('Day'), - SearchApiDate::FACETAPI_DATE_HOUR => $this->t('Hour'), - SearchApiDate::FACETAPI_DATE_MINUTE => $this->t('Minute'), - SearchApiDate::FACETAPI_DATE_SECOND => $this->t('Second'), - ]; - } - - /** - * {@inheritdoc} - */ - public function defaultConfiguration() { - return [ - 'display_relative' => FALSE, - 'granularity' => SearchApiDate::FACETAPI_DATE_MONTH, - 'date_display' => '', - 'relative_granularity' => 1, - 'relative_text' => TRUE, - ] + parent::defaultConfiguration(); - } - - /** - * {@inheritdoc} - */ - public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet) { - $configuration = $this->getConfiguration(); - - $form += parent::buildConfigurationForm($form, $form_state, $facet); - - $form['display_relative'] = [ - '#type' => 'radios', - '#title' => $this->t('Date display'), - '#default_value' => $configuration['display_relative'], - '#options' => [ - FALSE => $this->t('Actual date with granularity'), - TRUE => $this->t('Relative date'), - ], - ]; - - $form['granularity'] = [ - '#type' => 'radios', - '#title' => $this->t('Granularity'), - '#default_value' => $configuration['granularity'], - '#options' => $this->granularityOptions(), - ]; - $form['date_display'] = [ - '#type' => 'textfield', - '#title' => $this->t('Date format'), - '#default_value' => $configuration['date_display'], - '#description' => $this->t('Override default date format used for the displayed filter format. See the PHP manual for available options.'), - '#states' => [ - 'visible' => [':input[name="widget_config[display_relative]"]' => ['value' => 0]], - ], - ]; - - return $form; - } - - /** - * {@inheritdoc} - */ - public function getQueryType(array $query_types) { - return $query_types['date']; - } - - /** - * {@inheritdoc} - */ - public function build(FacetInterface $facet) { - $this->facet = $facet; - - $items = array_map(function (Result $result) use ($facet) { - if (empty($result->getUrl())) { - return ['#markup' => $this->extractText($result)]; - } - else { - return $this->buildListItems($facet, $result); - } - }, $facet->getResults()); - - return [ - '#theme' => $this->getFacetItemListThemeHook($facet), - '#items' => $items, - '#attributes' => ['data-drupal-facet-id' => $facet->id()], - '#cache' => [ - 'contexts' => [ - 'url.path', - 'url.query_args', - ], - ], - ]; - } - -} diff --git a/src/Plugin/facets/widget/LinksWidget.php b/src/Plugin/facets/widget/LinksWidget.php index e1ef00b..1ff8d7b 100644 --- a/src/Plugin/facets/widget/LinksWidget.php +++ b/src/Plugin/facets/widget/LinksWidget.php @@ -57,11 +57,4 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta return $form; } - /** - * {@inheritdoc} - */ - public function getQueryType(array $query_types) { - return $query_types['string']; - } - } diff --git a/src/Plugin/facets/widget/NumericGranularWidget.php b/src/Plugin/facets/widget/NumericGranularWidget.php index 0faa22f..9490a73 100644 --- a/src/Plugin/facets/widget/NumericGranularWidget.php +++ b/src/Plugin/facets/widget/NumericGranularWidget.php @@ -46,8 +46,8 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta /** * {@inheritdoc} */ - public function getQueryType(array $query_types) { - return $query_types['numeric']; + public function getQueryType() { + return 'numeric'; } } diff --git a/src/Processor/ProcessorInterface.php b/src/Processor/ProcessorInterface.php index 778fb80..0617aed 100644 --- a/src/Processor/ProcessorInterface.php +++ b/src/Processor/ProcessorInterface.php @@ -111,4 +111,13 @@ public function isHidden(); */ public function getDescription(); + /** + * Picks the preferred query type for this widget. + * + * @return string|NULL + * The query type machine name to load or NULL to load the default query + * type. + */ + public function getQueryType(); + } diff --git a/src/Processor/ProcessorPluginBase.php b/src/Processor/ProcessorPluginBase.php index 7f832c3..ac109d3 100644 --- a/src/Processor/ProcessorPluginBase.php +++ b/src/Processor/ProcessorPluginBase.php @@ -107,4 +107,11 @@ public function calculateDependencies() { return $this->dependencies; } + /** + * {@inheritdoc} + */ + public function getQueryType() { + return NULL; + } + } diff --git a/src/Widget/WidgetPluginBase.php b/src/Widget/WidgetPluginBase.php index 8959ce2..fd1393f 100644 --- a/src/Widget/WidgetPluginBase.php +++ b/src/Widget/WidgetPluginBase.php @@ -122,8 +122,8 @@ public function getConfiguration() { /** * {@inheritdoc} */ - public function getQueryType(array $query_types) { - return $query_types['string']; + public function getQueryType() { + return 'string'; } /** diff --git a/src/Widget/WidgetPluginInterface.php b/src/Widget/WidgetPluginInterface.php index 68dd9a1..2a819c7 100644 --- a/src/Widget/WidgetPluginInterface.php +++ b/src/Widget/WidgetPluginInterface.php @@ -25,13 +25,11 @@ public function build(FacetInterface $facet); /** * Picks the preferred query type for this widget. * - * @param string[] $query_types - * An array keyed with query type name and it's plugin class to load. - * - * @return string - * The query type plugin class to load. + * @return string|NULL + * The query type machine name to load or NULL to load the default query + * type. */ - public function getQueryType(array $query_types); + public function getQueryType(); /** * Checks is a specific property is required for this widget. diff --git a/tests/facets_custom_widget/src/Plugin/facets/processor/InvalidQT.php b/tests/facets_custom_widget/src/Plugin/facets/processor/InvalidQT.php new file mode 100644 index 0000000..66f7636 --- /dev/null +++ b/tests/facets_custom_widget/src/Plugin/facets/processor/InvalidQT.php @@ -0,0 +1,31 @@ +setFacetSourceId('search_api:views_page__search_api_test_view__page_1'); $entity->setFieldIdentifier('name'); - $aa = $entity->getQueryType(); - $this->assertEquals('search_api_string', $aa); + $selectedQueryType = $entity->getQueryType(); + $this->assertEquals('search_api_string', $selectedQueryType); + } + + /** + * Tests the selection of a query type. + * + * @covers ::getQueryType + * @covers ::pickQueryType + */ + public function testQueryTypeJugglingInvalidWidget() { + $entity = new Facet([], 'facets_facet'); + $entity->setWidget('widget_invalid_qt'); + $entity->setFacetSourceId('search_api:views_page__search_api_test_view__page_1'); + $entity->setFieldIdentifier('name'); + + $this->setExpectedException(InvalidQueryTypeException::class); + $entity->getQueryType(); + } + + /** + * Tests the selection of a query type. + * + * @covers ::getQueryType + * @covers ::pickQueryType + */ + public function testQueryTypeJugglingInvalidProcessor() { + $entity = new Facet([], 'facets_facet'); + $entity->setWidget('links'); + $entity->setFacetSourceId('search_api:views_page__search_api_test_view__page_1'); + $entity->setFieldIdentifier('name'); + $entity->addProcessor(['processor_id' => 'invalid_qt', 'weights' => [], 'settings' => []]); + + $this->setExpectedException(InvalidQueryTypeException::class); + $entity->getQueryType(); + } + + /** + * Tests the selection of a query type. + * + * @covers ::getQueryType + * @covers ::pickQueryType + */ + public function testQueryTypeJugglingInvalidCombo() { + $entity = new Facet([], 'facets_facet'); + $entity->setWidget('numericgranular'); + $entity->setFacetSourceId('search_api:views_page__search_api_test_view__page_1'); + $entity->setFieldIdentifier('name'); + $entity->addProcessor(['processor_id' => 'test_pre_query', 'weights' => [], 'settings' => []]); + + $this->setExpectedException(InvalidQueryTypeException::class); + $entity->getQueryType(); } } diff --git a/tests/src/Unit/Plugin/widget/DateArrayWidgetTest.php b/tests/src/Unit/Plugin/widget/DateArrayWidgetTest.php deleted file mode 100644 index d228a31..0000000 --- a/tests/src/Unit/Plugin/widget/DateArrayWidgetTest.php +++ /dev/null @@ -1,74 +0,0 @@ -widget = new DateArrayWidget(['show_numbers' => 1]); - } - - /** - * Tests widget without filters. - */ - public function testNoFilterResults() { - $facet = new Facet([], 'facets_facet'); - $facet->setResults($this->originalResults); - $facet->setFieldIdentifier('tag'); - - $output = $this->widget->build($facet); - - $this->assertInternalType('array', $output); - $this->assertCount(4, $output['tag']); - - $expected_links = [ - ['url' => NULL, 'values' => ['value' => 'Llama', 'count' => 10]], - ['url' => NULL, 'values' => ['value' => 'Badger', 'count' => 20]], - ['url' => NULL, 'values' => ['value' => 'Duck', 'count' => 15]], - ['url' => NULL, 'values' => ['value' => 'Alpaca', 'count' => 9]], - ]; - foreach ($expected_links as $index => $value) { - $this->assertInternalType('array', $output['tag'][$index]); - $this->assertEquals($value['values']['value'], $output['tag'][$index]['values']['value']); - $this->assertEquals($value['values']['count'], $output['tag'][$index]['values']['count']); - } - } - - /** - * Tests get query type. - */ - public function testGetQueryType() { - $result = $this->widget->getQueryType($this->queryTypes); - $this->assertEquals('date', $result); - } - - /** - * {@inheritdoc} - */ - public function testDefaultConfiguration() { - $default_config = $this->widget->defaultConfiguration(); - $expected = [ - 'show_numbers' => FALSE, - 'display_relative' => FALSE, - 'granularity' => 5, - 'date_display' => '', - 'relative_granularity' => 1, - 'relative_text' => TRUE, - ]; - $this->assertEquals($expected, $default_config); - } - -}