Commit e2d47678 authored by Leksat's avatar Leksat Committed by borisson_
Browse files

Issue #2636328 by borisson_, Leksat: Widget dropdown - select

parent 1f7db29a
<?php
/**
* @file
* Contains \Drupal\facets\Form\DropdownWidgetForm.
*/
namespace Drupal\facets\Form;
use Drupal\Core\Form\BaseFormIdInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\facets\FacetInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* The dropdown widget form.
*/
class DropdownWidgetForm implements BaseFormIdInterface {
use StringTranslationTrait;
/**
* The facet to build the form for.
*
* @var FacetInterface $facet
*/
protected $facet;
/**
* Class constructor.
*
* @param \Drupal\facets\FacetInterface $facet
* The facet to build the form for.
*/
public function __construct(FacetInterface $facet) {
$this->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);
if ($form_value != '_none') {
$form_state->setResponse(new RedirectResponse($form_value));
}
}
}
<?php
/**
* @file
* Contains \Drupal\facets\Plugin\facets\widget\DropdownWidget.
*/
namespace Drupal\facets\Plugin\facets\widget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\facets\FacetInterface;
use Drupal\facets\Form\DropdownWidgetForm;
use Drupal\facets\Widget\WidgetInterface;
/**
* The dropdown widget.
*
* @FacetsWidget(
* id = "select",
* label = @Translation("Dropdown"),
* description = @Translation("A configurable widget that shows a dropdown."),
* )
*/
class DropdownWidget implements WidgetInterface {
use StringTranslationTrait;
/**
* {@inheritdoc}
*/
public function build(FacetInterface $facet) {
$form_builder = \Drupal::getContainer()->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;
}
}
......@@ -7,6 +7,7 @@
namespace Drupal\facets\Tests;
use Drupal\Core\Url;
use \Drupal\facets\Tests\WebTestBase as FacetWebTestBase;
/**
......@@ -192,6 +193,49 @@ class WidgetIntegrationTest extends FacetWebTestBase {
$this->assertLink('(-) item');
}
/**
* 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.
*/
......
<?php
/**
* @file
* Contains \Drupal\Tests\facets\Unit\Form\SelectWidgetFormTest.
*/
namespace Drupal\Tests\facets\Unit\Form;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Form\FormState;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\StringTranslation\TranslationManager;
use Drupal\Core\Url;
use Drupal\facets\Entity\Facet;
use Drupal\facets\Form\DropdownWidgetForm;
use Drupal\facets\Result\Result;
use Drupal\Tests\UnitTestCase;
/**
* Unit test for the select widget form.
*
* @group facets
*/
class SelectWidgetFormTest extends UnitTestCase {
/**
* An array containing the results before the processor has ran.
*
* @var \Drupal\facets\Result\Result[]
*/
protected $originalResults;
/**
* Creates a new processor object for use in the tests.
*/
protected function setUp() {
parent::setUp();
$result = new Result('llama', 'Llama', 10);
$result->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());
}
}
<?php
/**
* @file
* Contains \Drupal\Tests\facets\Plugin\widget\SelectWidgetTest.
*/
namespace Drupal\Tests\facets\Unit\Plugin\widget;
use Drupal\Core\Url;
use Drupal\facets\Entity\Facet;
use Drupal\facets\Plugin\facets\widget\DropdownWidget;
use Drupal\facets\Result\Result;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* Unit test for widget.
*
* @group facets
*/
class SelectWidgetTest extends UnitTestCase {
/**
* The processor to be tested.
*
* @var \Drupal\facets\Plugin\facets\widget\DropdownWidget
*/
protected $widget;
/**
* An array containing the results before the processor has ran.
*
* @var \Drupal\facets\Result\Result[]
*/
protected $originalResults;
/**
* Creates a new processor object for use in the tests.
*/
protected function setUp() {
parent::setUp();
/** @var \Drupal\facets\Result\Result[] $original_results */
$original_results = [
new Result('llama', 'Llama', 10),
new Result('badger', 'Badger', 20),
new Result('duck', 'Duck', 15),
new Result('alpaca', 'Alpaca', 9),
];
foreach ($original_results as $original_result) {
$original_result->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);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment