diff --git a/src/Form/DropdownWidgetForm.php b/src/Form/DropdownWidgetForm.php new file mode 100644 index 0000000..cd739e1 --- /dev/null +++ b/src/Form/DropdownWidgetForm.php @@ -0,0 +1,112 @@ +facet = $facet; + } + + /** + * {@inheritdoc} + */ + public function getBaseFormId() { + return 'facets_dropdown_widget'; + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return $this->getBaseFormId() . '__' . $this->facet->id(); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $results = $this->facet->getResults(); + + $configuration = $this->facet->getWidgetConfigs(); + $form[$this->facet->getFieldAlias()] = [ + '#type' => 'select', + '#title' => $this->facet->getName(), + '#default_value' => '_none', + ]; + + $options = []; + $active_result_url = '_none'; + foreach ($results as $result) { + $result_url = $result->getUrl()->setAbsolute()->toString(); + + $text = $result->getDisplayValue(); + if (!empty($configuration['show_numbers'])) { + $text .= ' (' . $result->getCount() . ')'; + } + + if ($result->isActive()) { + $options['_none'] = $text; + $active_result_url = $result_url; + } + else { + $options[$result_url] = $text; + } + } + + $options = [$active_result_url => $this->t('- All -')] + $options; + + $form[$this->facet->getFieldAlias()]['#options'] = $options; + + $form[$this->facet->getFieldAlias() . '_submit'] = [ + '#type' => 'submit', + '#value' => 'submit', + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $field_alias = $this->facet->getFieldAlias(); + $form_value = $form_state->getValue($field_alias); + $form_state->setResponse(new RedirectResponse($form_value)); + } + +} diff --git a/src/Plugin/facets/widget/DropdownWidget.php b/src/Plugin/facets/widget/DropdownWidget.php new file mode 100644 index 0000000..12a8650 --- /dev/null +++ b/src/Plugin/facets/widget/DropdownWidget.php @@ -0,0 +1,65 @@ +get('form_builder'); + $form_object = new DropdownWidgetForm($facet); + return $form_builder->getForm($form_object); + } + + /** + * {@inheritdoc} + */ + public function getQueryType($query_types) { + return $query_types['string']; + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state, $config) { + + $form['show_numbers'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Show the amount of results'), + ]; + + if (!is_null($config)) { + $widget_configs = $config->get('widget_configs'); + if (isset($widget_configs['show_numbers'])) { + $form['show_numbers']['#default_value'] = $widget_configs['show_numbers']; + } + } + + return $form; + } + +} diff --git a/src/Tests/WidgetIntegrationTest.php b/src/Tests/WidgetIntegrationTest.php index b0a4058..e83fd60 100644 --- a/src/Tests/WidgetIntegrationTest.php +++ b/src/Tests/WidgetIntegrationTest.php @@ -7,6 +7,7 @@ namespace Drupal\facets\Tests; +use Drupal\Core\Url; use \Drupal\facets\Tests\WebTestBase as FacetWebTestBase; /** @@ -193,6 +194,49 @@ class WidgetIntegrationTest extends FacetWebTestBase { } /** + * Tests select widget's basic functionality. + */ + public function testSelectWidget() { + $id = 'select_widget'; + $name = 'Select'; + $facet_add_page = 'admin/config/search/facets/add-facet'; + + $this->drupalGet($facet_add_page); + + $form_values = [ + 'id' => $id, + 'status' => 1, + 'url_alias' => $id, + 'name' => $name, + 'facet_source_id' => 'search_api_views:search_api_test_view:page_1', + 'facet_source_configs[search_api_views:search_api_test_view:page_1][field_identifier]' => 'type', + ]; + $this->drupalPostForm(NULL, ['facet_source_id' => 'search_api_views:search_api_test_view:page_1'], $this->t('Configure facet source')); + $this->drupalPostForm(NULL, $form_values, $this->t('Save')); + $this->drupalPostForm(NULL, ['widget' => 'select'], $this->t('Save')); + + $block_values = [ + 'plugin_id' => 'facet_block:' . $id, + 'settings' => [ + 'region' => 'footer', + 'id' => str_replace('_', '-', $id), + ], + ]; + $this->drupalPlaceBlock($block_values['plugin_id'], $block_values['settings']); + + $this->drupalGet('search-api-test-fulltext'); + $this->assertField('edit-type', 'Dropdown is visible.'); + $this->assertText('Displaying 5 search results'); + + $url = Url::fromUserInput('/search-api-test-fulltext', ['query' => ['f[0]' => 'select_widget:item']]); + $url->setAbsolute(); + + $this->drupalPostForm(NULL, ['type' => $url->toString()], $this->t('submit')); + $this->assertResponse(200); + $this->assertText('Displaying 3 search results'); + } + + /** * Tests the functionality of a widget to hide/show the item-count. */ public function testLinksShowHideCount() { diff --git a/tests/src/Unit/Form/SelectWidgetFormTest.php b/tests/src/Unit/Form/SelectWidgetFormTest.php new file mode 100644 index 0000000..9510fcc --- /dev/null +++ b/tests/src/Unit/Form/SelectWidgetFormTest.php @@ -0,0 +1,162 @@ +setUrl(new Url('llama')); + $result2 = new Result('badger', 'Badger', 20); + $result2->setUrl(new Url('badger')); + $result3 = new Result('duck', 'Duck', 15); + $result3->setUrl(new Url('duck')); + $result4 = new Result('alpaca', 'Alpaca', 9); + $result4->setUrl(new Url('alpaca')); + + $this->originalResults = [ + $result, + $result2, + $result3, + $result4, + ]; + + $url_generator = $this->getMock(UrlGeneratorInterface::class); + $url_generator->expects($this->any()) + ->method('generateFromRoute') + ->willReturnCallback(function ($param) { return 'http://test/' . $param; }); + $string_translation = $this->getMockBuilder(TranslationManager::class) + ->disableOriginalConstructor() + ->getMock(); + + $container_builder = new ContainerBuilder(); + $container_builder->set('url_generator', $url_generator); + $container_builder->set('string_translation', $string_translation); + \Drupal::setContainer($container_builder); + } + + /** + * Tests widget form with default settings. + */ + public function testDefaultSettings() { + $facet = new Facet(['id' => 'zoo_animal'], 'facet'); + $facet->setResults($this->originalResults); + $facet->setFieldIdentifier('zoo_animal'); + + $form_state = new FormState(); + $form_state->addBuildInfo('args', [$facet]); + $form = []; + + $widget_form = new DropdownWidgetForm($facet); + $built_form = $widget_form->buildForm($form, $form_state); + + $this->assertInternalType('array', $built_form); + $this->assertCount(5, $built_form['zoo_animal']['#options']); + $this->assertEquals('select', $built_form['zoo_animal']['#type']); + + $expected_links = [ + 'http://test/llama' => 'Llama', + 'http://test/badger' => 'Badger', + 'http://test/duck' => 'Duck', + 'http://test/alpaca' => 'Alpaca', + ]; + foreach ($expected_links as $index => $value) { + $this->assertEquals($value, $built_form['zoo_animal']['#options'][$index]); + } + $this->assertEquals(array('zoo_animal', 'zoo_animal_submit'), array_keys($built_form)); + } + + /** + * Tests widget form, make sure hiding and showing numbers works. + */ + public function testHideNumbers() { + $facet = new Facet([], 'facet'); + $facet->setResults($this->originalResults); + $facet->setFieldIdentifier('zoo__animal'); + $facet->setWidgetConfigs(['show_numbers' => 0]); + + $form_state = new FormState(); + $form_state->addBuildInfo('args', [$facet]); + $form = []; + + $widget_form = new DropdownWidgetForm($facet); + $built_form = $widget_form->buildForm($form, $form_state); + + $this->assertInternalType('array', $built_form); + $this->assertCount(5, $built_form['zoo__animal']['#options']); + $expected_links = [ + 'http://test/llama' => 'Llama', + 'http://test/badger' => 'Badger', + 'http://test/duck' => 'Duck', + 'http://test/alpaca' => 'Alpaca', + ]; + foreach ($expected_links as $index => $value) { + $this->assertEquals($value, $built_form['zoo__animal']['#options'][$index]); + } + + // Enable the 'show_numbers' setting again to make sure that the switch + // between those settings works. + $facet->setWidgetConfigs(['show_numbers' => 1]); + + $built_form = $widget_form->buildForm($form, $form_state); + $this->assertInternalType('array', $built_form); + $this->assertCount(5, $built_form['zoo__animal']['#options']); + + $expected_links = [ + 'http://test/llama' => 'Llama (10)', + 'http://test/badger' => 'Badger (20)', + 'http://test/duck' => 'Duck (15)', + 'http://test/alpaca' => 'Alpaca (9)', + ]; + foreach ($expected_links as $index => $value) { + $this->assertEquals($value, $built_form['zoo__animal']['#options'][$index]); + } + } + + /** + * Tests form default methods. + */ + public function testForm() { + $facet = new Facet(['id' => 'donkey'], 'facet'); + $facet->setResults($this->originalResults); + $facet->setFieldIdentifier('donkey'); + + $form = new DropdownWidgetForm($facet); + + $this->assertEquals('facets_dropdown_widget', $form->getBaseFormId()); + $this->assertEquals('facets_dropdown_widget__donkey', $form->getFormId()); + } + +} diff --git a/tests/src/Unit/Plugin/widget/SelectWidgetTest.php b/tests/src/Unit/Plugin/widget/SelectWidgetTest.php new file mode 100644 index 0000000..ecc902a --- /dev/null +++ b/tests/src/Unit/Plugin/widget/SelectWidgetTest.php @@ -0,0 +1,88 @@ +setUrl(new Url('test')); + } + $this->originalResults = $original_results; + + $form_builder = $this->getMockBuilder('\Drupal\Core\Form\FormBuilder') + ->disableOriginalConstructor() + ->getMock(); + $form_builder->expects($this->once()) + ->method('getForm') + ->willReturn('build'); + + $string_translation = $this->getMockBuilder('\Drupal\Core\StringTranslation\TranslationManager') + ->disableOriginalConstructor() + ->getMock(); + + $container_builder = new ContainerBuilder(); + $container_builder->set('form_builder', $form_builder); + $container_builder->set('string_translation', $string_translation); + \Drupal::setContainer($container_builder); + + $this->widget = new DropdownWidget(); + } + + /** + * Tests widget with default settings. + */ + public function testDefaultSettings() { + $facet = new Facet([], 'facet'); + $facet->setResults($this->originalResults); + $facet->setFieldIdentifier('test_field'); + + $built_form = $this->widget->build($facet); + $this->assertEquals('build', $built_form); + } + +}