diff --git a/config/schema/facets.facetsource.schema.yml b/config/schema/facets.facetsource.schema.yml index 962703e..8cf0e35 100644 --- a/config/schema/facets.facetsource.schema.yml +++ b/config/schema/facets.facetsource.schema.yml @@ -14,3 +14,6 @@ facets.facet_source.*: filterKey: type: string label: 'Filter key' + url_processor: + type: string + label: 'Url processor' diff --git a/facets.plugin_type.yml b/facets.plugin_type.yml index 1fd9cbf..8db8901 100644 --- a/facets.plugin_type.yml +++ b/facets.plugin_type.yml @@ -3,6 +3,11 @@ facets_processor: plugin_manager_service_id: plugin.manager.facets.processor plugin_definition_decorator_class: \Drupal\plugin\PluginDefinition\ArrayPluginDefinitionDecorator +facets_url_processor: + label: Facets URL processor + plugin_manager_service_id: plugin.manager.facets.url_processor + plugin_definition_decorator_class: \Drupal\plugin\PluginDefinition\ArrayPluginDefinitionDecorator + facets_facet_source: label: Facets source plugin_manager_service_id: plugin.manager.facets.facet_source diff --git a/facets.services.yml b/facets.services.yml index c33a611..01d4ee8 100644 --- a/facets.services.yml +++ b/facets.services.yml @@ -11,6 +11,9 @@ services: plugin.manager.facets.processor: class: Drupal\facets\Processor\ProcessorPluginManager arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@string_translation'] + plugin.manager.facets.url_processor: + class: Drupal\facets\UrlProcessor\UrlProcessorPluginManager + parent: default_plugin_manager facets.manager: class: Drupal\facets\FacetManager\DefaultFacetManager arguments: diff --git a/src/Annotation/FacetsUrlProcessor.php b/src/Annotation/FacetsUrlProcessor.php new file mode 100644 index 0000000..8547812 --- /dev/null +++ b/src/Annotation/FacetsUrlProcessor.php @@ -0,0 +1,48 @@ +filterKey; } + /** + * {@inheritdoc} + */ + public function setUrlProcessor($processor_name) { + $this->urlProcessor = $processor_name; + } + + /** + * {@inheritdoc} + */ + public function getUrlProcessorName() { + return $this->urlProcessor; + } + } diff --git a/src/FacetSourceInterface.php b/src/FacetSourceInterface.php index 8395760..8c6e909 100644 --- a/src/FacetSourceInterface.php +++ b/src/FacetSourceInterface.php @@ -38,4 +38,20 @@ interface FacetSourceInterface extends ConfigEntityInterface { */ public function setFilterKey($filter_key); + /** + * Set the processor name to be used. + * + * @param string $processor_name + * Plugin name of the url processor. + */ + public function setUrlProcessor($processor_name); + + /** + * Returns a string version of the url processor. + * + * @return string + * The url processor to be used as a string. + */ + public function getUrlProcessorName(); + } diff --git a/src/Form/FacetDisplayForm.php b/src/Form/FacetDisplayForm.php index d55dfe1..e096de0 100644 --- a/src/Form/FacetDisplayForm.php +++ b/src/Form/FacetDisplayForm.php @@ -14,6 +14,7 @@ use Drupal\Core\Entity\EntityTypeManager; use Drupal\Core\Form\FormStateInterface; use Drupal\facets\Processor\ProcessorInterface; use Drupal\facets\Processor\ProcessorPluginManager; +use Drupal\facets\UrlProcessor\UrlProcessorInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\facets\Widget\WidgetPluginManager; use Drupal\facets\Processor\WidgetOrderProcessorInterface; @@ -219,7 +220,7 @@ class FacetDisplayForm extends EntityForm { ), ); foreach ($all_processors as $processor_id => $processor) { - if (!($processor instanceof WidgetOrderProcessorInterface)) { + if (!($processor instanceof WidgetOrderProcessorInterface) && !($processor instanceof UrlProcessorInterface)) { $clean_css_id = Html::cleanCssIdentifier($processor_id); $form['facet_settings'][$processor_id]['status'] = array( '#type' => 'checkbox', diff --git a/src/Form/FacetSourceEditForm.php b/src/Form/FacetSourceEditForm.php index 067a39f..bdc7779 100644 --- a/src/Form/FacetSourceEditForm.php +++ b/src/Form/FacetSourceEditForm.php @@ -8,8 +8,11 @@ namespace Drupal\facets\Form; use Drupal\Core\Entity\EntityForm; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\facets\Entity\FacetSource; +use Drupal\facets\UrlProcessor\UrlProcessorPluginManager; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides a form for editing facet sources. @@ -20,10 +23,32 @@ use Drupal\facets\Entity\FacetSource; class FacetSourceEditForm extends EntityForm { /** + * The plugin manager for URL Processors. + * + * @var \Drupal\facets\UrlProcessor\UrlProcessorPluginManager + */ + protected $urlProcessorPluginManager; + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */ + $entity_type_manager = $container->get('entity_type.manager'); + + /** @var \Drupal\facets\UrlProcessor\UrlProcessorPluginManager $url_processor_plugin_manager */ + $url_processor_plugin_manager = $container->get('plugin.manager.facets.url_processor'); + + return new static($entity_type_manager, $url_processor_plugin_manager); + } + + /** * Constructs a FacetSourceEditForm. */ - public function __construct() { - $facet_source_storage = \Drupal::entityTypeManager()->getStorage('facets_facet_source'); + public function __construct(EntityTypeManagerInterface $entity_type_manager, UrlProcessorPluginManager $url_processor_plugin_manager) { + $facet_source_storage = $entity_type_manager->getStorage('facets_facet_source'); + + $this->urlProcessorPluginManager = $url_processor_plugin_manager; // Make sure we remove colons from the source id, those are disallowed in // the entity id. @@ -81,6 +106,17 @@ class FacetSourceEditForm extends EntityForm { ), ]; + $url_processors = array(); + foreach ($this->urlProcessorPluginManager->getDefinitions() as $definition) { + $url_processors[$definition['id']] = $definition['label']; + } + $form['urlProcessor'] = [ + '#type' => 'select', + '#title' => $this->t('URL Processor'), + '#options' => $url_processors, + '#default_value' => $facet_source->getUrlProcessorName(), + ]; + // The parent's form build method will add a save button. return parent::buildForm($form, $form_state); } diff --git a/src/Plugin/facets/processor/UrlProcessorHandler.php b/src/Plugin/facets/processor/UrlProcessorHandler.php new file mode 100644 index 0000000..3ec3819 --- /dev/null +++ b/src/Plugin/facets/processor/UrlProcessorHandler.php @@ -0,0 +1,75 @@ +getFacetSourceConfig(); + + $url_processor_name = $fs->getUrlProcessorName(); + + $manager = \Drupal::getContainer()->get('plugin.manager.facets.url_processor'); + $this->processor= $manager->createInstance($url_processor_name, ['facet' => $facet]); + } + + /** + * {@inheritdoc} + */ + public function build(FacetInterface $facet, array $results) { + return $this->processor->buildUrls($facet, $results); + } + + /** + * {@inheritdoc} + */ + public function preQuery(FacetInterface $facet) { + $this->processor->setActiveItems($facet); + } + +} diff --git a/src/Plugin/facets/processor/QueryStringUrlProcessor.php b/src/Plugin/facets/url_processor/QueryString.php similarity index 85% rename from src/Plugin/facets/processor/QueryStringUrlProcessor.php rename to src/Plugin/facets/url_processor/QueryString.php index 3c53a32..78812b5 100644 --- a/src/Plugin/facets/processor/QueryStringUrlProcessor.php +++ b/src/Plugin/facets/url_processor/QueryString.php @@ -2,31 +2,26 @@ /** * @file - * Contains Drupal\facets\Plugin\facets\url_processor\UrlProcessorQueryString. + * Contains Drupal\facets\Plugin\facets\url_processor\QueryString. */ -namespace Drupal\facets\Plugin\facets\processor; +namespace Drupal\facets\Plugin\facets\url_processor; use Drupal\Core\Url; use Drupal\facets\FacetInterface; -use Drupal\facets\Processor\UrlProcessorPluginBase; +use Drupal\facets\UrlProcessor\UrlProcessorPluginBase; use Symfony\Component\HttpFoundation\Request; /** - * The basic url processor, uses query strings. + * Query string URL processor. * - * @FacetsProcessor( + * @FacetsUrlProcessor( * id = "query_string", * label = @Translation("Query string url processor"), - * description = @Translation("Most simple url processor which uses the query sting."), - * stages = { - * "pre_query" = 50, - * "build" = 15, - * }, - * locked = true + * description = @Translation("Most simple url processor which uses the query sting.") * ) */ -class QueryStringUrlProcessor extends UrlProcessorPluginBase { +class QueryString extends UrlProcessorPluginBase { /** * A string that separates the filters in the query string. @@ -59,7 +54,7 @@ class QueryStringUrlProcessor extends UrlProcessorPluginBase { /** * {@inheritdoc} */ - public function build(FacetInterface $facet, array $results) { + public function buildUrls(FacetInterface $facet, array $results) { // Create links for all the values. // First get the current list of get parameters. $get_params = $this->request->query; @@ -74,7 +69,7 @@ class QueryStringUrlProcessor extends UrlProcessorPluginBase { /** @var \Drupal\facets\Result\ResultInterface $result */ foreach ($results as &$result) { - $filter_string = $this->url_alias . ':' . $result->getRawValue(); + $filter_string = $this->url_alias . self::SEPARATOR . $result->getRawValue(); $result_get_params = clone $get_params; $filter_params = $result_get_params->get($this->filterKey, [], TRUE); @@ -108,7 +103,7 @@ class QueryStringUrlProcessor extends UrlProcessorPluginBase { /** * {@inheritdoc} */ - public function preQuery(FacetInterface $facet) { + public function setActiveItems(FacetInterface $facet) { // Set the url alias from the the facet object. $this->url_alias = $facet->getUrlAlias(); diff --git a/src/Processor/UrlProcessorInterface.php b/src/Processor/UrlProcessorInterface.php deleted file mode 100644 index 31aeb9c..0000000 --- a/src/Processor/UrlProcessorInterface.php +++ /dev/null @@ -1,31 +0,0 @@ -clickLink($this->t('Configure')); // Test the edit page. + $edit = array( + 'filterKey' => 'fq', + 'urlProcessor' => 'query_string', + ); $this->assertField('filterKey'); - $this->drupalPostForm(NULL, array('filterKey' => 'fq'), $this->t('Save')); + $this->assertField('urlProcessor'); + $this->drupalPostForm(NULL, $edit, $this->t('Save')); // Test that saving worked. $this->assertField('filterKey'); + $this->assertField('urlProcessor'); $this->assertRaw('fq'); } diff --git a/src/Tests/UrlIntegrationTest.php b/src/Tests/UrlIntegrationTest.php new file mode 100644 index 0000000..565392e --- /dev/null +++ b/src/Tests/UrlIntegrationTest.php @@ -0,0 +1,101 @@ +drupalLogin($this->adminUser); + + $this->insertExampleContent(); + $this->assertEqual($this->indexItems($this->indexId), 5, '5 items were indexed.'); + } + + /** + * Tests various url integration things. + */ + public function testUrlIntegration() { + $id = 'facet'; + $name = '&^Facet@#1'; + $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_views_fulltext:page_1', + 'facet_source_configs[search_api_views:search_api_test_views_fulltext:page_1][field_identifier]' => 'entity:entity_test/type', + ]; + $this->drupalPostForm(NULL, ['facet_source_id' => 'search_api_views:search_api_test_views_fulltext:page_1'], $this->t('Configure facet source')); + $this->drupalPostForm(NULL, $form_values, $this->t('Save')); + + // Go to the only enabled facet source's config. + $this->drupalGet('admin/config/search/facets'); + $this->clickLink($this->t('Configure')); + + $edit = [ + 'filterKey' => 'y', + 'urlProcessor' => 'dummy_query', + ]; + $this->drupalPostForm(NULL, $edit, $this->t('Save')); + + /** @var \Drupal\facets\FacetInterface $facet */ + $facet = \Drupal::service('entity_type.manager')->getStorage('facets_facet')->load($id); + $block_values = [ + 'region' => 'footer', + 'id' => str_replace('_', '-', $id), + 'context_mapping' => [ + 'facet' => '@facets.facet_context:' . $facet->uuid(), + ], + ]; + $this->drupalPlaceBlock('facet_block', $block_values); + + $this->drupalGet('search-api-test-fulltext'); + $this->assertResponse(200); + $this->assertLink('item'); + $this->assertLink('article'); + + $this->clickLink('item'); + + $this->assertResponse(200); + $this->assertLink('(-) item'); + $this->assertNoLink('article'); + $this->assertUrl('search-api-test-fulltext?y[0]=facet||item'); + } + +} diff --git a/src/UrlProcessor/UrlProcessorInterface.php b/src/UrlProcessor/UrlProcessorInterface.php new file mode 100644 index 0000000..3bc51a1 --- /dev/null +++ b/src/UrlProcessor/UrlProcessorInterface.php @@ -0,0 +1,56 @@ +request = $request; if (!isset($configuration['facet'])) { - throw new InvalidProcessorException(); + throw new InvalidProcessorException("The url processor doesn't have the required 'facet' in the configuration array."); } /** @var \Drupal\facets\FacetInterface $facet */ diff --git a/src/UrlProcessor/UrlProcessorPluginManager.php b/src/UrlProcessor/UrlProcessorPluginManager.php new file mode 100644 index 0000000..84008fd --- /dev/null +++ b/src/UrlProcessor/UrlProcessorPluginManager.php @@ -0,0 +1,35 @@ +setCacheBackend($cache_backend, 'facets_url_processors'); + } + +} diff --git a/tests/facets_query_processor/facets_query_processor.info.yml b/tests/facets_query_processor/facets_query_processor.info.yml new file mode 100644 index 0000000..8347423 --- /dev/null +++ b/tests/facets_query_processor/facets_query_processor.info.yml @@ -0,0 +1,6 @@ +name: 'Facets query processor' +type: module +description: 'Facets query processor' +package: 'Search' +core: 8.x +hidden: true diff --git a/tests/facets_query_processor/src/Plugin/facets/url_processor/DummyQuery.php b/tests/facets_query_processor/src/Plugin/facets/url_processor/DummyQuery.php new file mode 100644 index 0000000..764e67c --- /dev/null +++ b/tests/facets_query_processor/src/Plugin/facets/url_processor/DummyQuery.php @@ -0,0 +1,143 @@ +initializeActiveFilters(); + } + + /** + * {@inheritdoc} + */ + public function buildUrls(FacetInterface $facet, array $results) { + // Create links for all the values. + // First get the current list of get parameters. + $get_params = $this->request->query; + + // Set the url alias from the the facet object. + $this->url_alias = $facet->getUrlAlias(); + + // No results are found for this facet, so don't try to create urls. + if (empty($results)) { + return []; + } + + /** @var \Drupal\facets\Result\ResultInterface $result */ + foreach ($results as &$result) { + $filter_string = $this->url_alias . self::SEPARATOR . $result->getRawValue(); + $result_get_params = clone $get_params; + + $filter_params = $result_get_params->get($this->filterKey, [], TRUE); + // If the value is active, remove the filter string from the parameters. + if ($result->isActive()) { + foreach ($filter_params as $key => $filter_param) { + if ($filter_param == $filter_string) { + unset($filter_params[$key]); + } + } + } + // If the value is not active, add the filter string. + else { + $filter_params[] = $filter_string; + } + + $result_get_params->set($this->filterKey, $filter_params); + $request = $this->request; + if ($facet->getFacetSource()->getPath()) { + $request = Request::create('/' . $facet->getFacetSource()->getPath()); + } + $url = Url::createFromRequest($request); + $url->setOption('query', $result_get_params->all()); + + $result->setUrl($url); + } + + return $results; + } + + /** + * {@inheritdoc} + */ + public function setActiveItems(FacetInterface $facet) { + // Set the url alias from the the facet object. + $this->url_alias = $facet->getUrlAlias(); + + // Get the filter key of the facet. + if (isset($this->activeFilters[$this->url_alias])) { + foreach ($this->activeFilters[$this->url_alias] as $value) { + $facet->setActiveItem(trim($value, '"')); + } + } + } + + /** + * Initialize the active filters. + * + * Get all the filters that are active. This method only get's all the + * filters but doesn't assign them to facets. In the processFacet method the + * active values for a specific facet are added to the facet. + */ + protected function initializeActiveFilters() { + $url_parameters = $this->request->query; + + // Get the active facet parameters. + $active_params = $url_parameters->get($this->filterKey, array(), TRUE); + + // Explode the active params on the separator. + foreach ($active_params as $param) { + list($key, $value) = explode(self::SEPARATOR, $param); + if (!isset($this->activeFilters[$key])) { + $this->activeFilters[$key] = [$value]; + } + else { + $this->activeFilters[$key][] = $value; + } + } + } + +} diff --git a/tests/src/Unit/Plugin/processor/UrlProcessorHandlerTest.php b/tests/src/Unit/Plugin/processor/UrlProcessorHandlerTest.php new file mode 100644 index 0000000..c411be8 --- /dev/null +++ b/tests/src/Unit/Plugin/processor/UrlProcessorHandlerTest.php @@ -0,0 +1,80 @@ +setExpectedException('\Drupal\facets\Exception\InvalidProcessorException', "The UrlProcessorHandler doesn't have the required 'facet' in the configuration array."); + new UrlProcessorHandler([], 'test', []); + } + + /** + * Tests that the processor correctly throws an exception. + */ + public function testInvalidProcessorConfiguration() { + $this->setExpectedException('\Drupal\facets\Exception\InvalidProcessorException', "The UrlProcessorHandler doesn't have the required 'facet' in the configuration array."); + new UrlProcessorHandler(['facet' => new \stdClass()], 'test', []); + } + + /** + * Test that the build method is correctly called. + */ + public function testBuild() { + $facet = new Facet(['id' => '_test'], 'facets_facet'); + $this->createContainer(); + + $processor = new UrlProcessorHandler(['facet' => $facet], 'url_processor_handler', []); + // The actual results of this should be tested in the actual processor. + $processor->build($facet, []); + } + + /** + * Helper function to create a correct container. + */ + protected function createContainer() { + $url_processor = $this->getMockBuilder('\Drupal\facets\UrlProcessor\UrlProcessorInterface') + ->disableOriginalConstructor() + ->getMock(); + + $manager = $this->getMockBuilder('\Drupal\facets\FacetSource\FacetSourcePluginManager') + ->disableOriginalConstructor() + ->getMock(); + $manager->expects($this->exactly(1)) + ->method('createInstance') + ->willReturn($url_processor); + + $storage = $this->getMock('\Drupal\Core\Entity\EntityStorageInterface'); + $em = $this->getMockBuilder('\Drupal\Core\Entity\EntityTypeManagerInterface') + ->disableOriginalConstructor() + ->getMock(); + $em->expects($this->exactly(2)) + ->method('getStorage') + ->willReturn($storage); + + $container = new ContainerBuilder(); + $container->set('entity.manager', $em); + $container->set('entity_type.manager', $em); + $container->set('plugin.manager.facets.url_processor', $manager); + \Drupal::setContainer($container); + } + +} diff --git a/tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php b/tests/src/Unit/Plugin/url_processor/QueryStringTest.php similarity index 80% rename from tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php rename to tests/src/Unit/Plugin/url_processor/QueryStringTest.php index 1b4c58f..df418fb 100644 --- a/tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php +++ b/tests/src/Unit/Plugin/url_processor/QueryStringTest.php @@ -2,14 +2,14 @@ /** * @file - * Contains \Drupal\Tests\facets\Plugin\Processor\QueryStringUrlProcessorTest. + * Contains \Drupal\Tests\facets\Plugin\url_processor\QueryStringTest. */ -namespace Drupal\Tests\facets\Unit\Plugin\Processor; +namespace Drupal\Tests\facets\Unit\Plugin\url_processor; use Drupal\facets\Entity\Facet; use Drupal\facets\Entity\FacetSource; -use Drupal\facets\Plugin\facets\processor\QueryStringUrlProcessor; +use Drupal\facets\Plugin\facets\url_processor\QueryString; use Drupal\facets\Result\Result; use Drupal\Tests\UnitTestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -21,12 +21,12 @@ use Symfony\Component\HttpFoundation\Request; * * @group facets */ -class QueryStringUrlProcessorTest extends UnitTestCase { +class QueryStringTest extends UnitTestCase { /** * The processor to be tested. * - * @var \Drupal\facets\Plugin\facets\processor\QueryStringUrlProcessor + * @var \Drupal\facets\Plugin\facets\url_processor\QueryString */ protected $processor; @@ -55,6 +55,14 @@ class QueryStringUrlProcessorTest extends UnitTestCase { } /** + * Tests that the processor correctly throws an exception. + */ + public function testEmptyProcessorConfiguration() { + $this->setExpectedException('\Drupal\facets\Exception\InvalidProcessorException', "The url processor doesn't have the required 'facet' in the configuration array."); + new QueryString([], 'test', [], new Request()); + } + + /** * Basic test with one active item. */ public function testSetSingleActiveItem() { @@ -66,8 +74,8 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('f', ['test:badger']); - $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); - $this->processor->preQuery($facet); + $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request); + $this->processor->setActiveItems($facet); $this->assertEquals(['badger'], $facet->getActiveItems()); } @@ -84,8 +92,8 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('f', ['test:badger', 'test:mushroom', 'donkey:kong']); - $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); - $this->processor->preQuery($facet); + $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request); + $this->processor->setActiveItems($facet); $this->assertEquals(['badger', 'mushroom'], $facet->getActiveItems()); } @@ -101,8 +109,8 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('f', []); - $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); - $results = $this->processor->build($facet, []); + $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request); + $results = $this->processor->buildUrls($facet, []); $this->assertEmpty($results); } @@ -118,8 +126,8 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('f', []); - $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); - $results = $this->processor->build($facet, $this->originalResults); + $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request); + $results = $this->processor->buildUrls($facet, $this->originalResults); /** @var \Drupal\facets\Result\ResultInterface $r */ foreach ($results as $r) { @@ -143,8 +151,8 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('f', ['king:kong']); - $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); - $results = $this->processor->build($facet, $original_results); + $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request); + $results = $this->processor->buildUrls($facet, $original_results); /** @var \Drupal\facets\Result\ResultInterface $r */ foreach ($results as $k => $r) { @@ -188,8 +196,8 @@ class QueryStringUrlProcessorTest extends UnitTestCase { $request = new Request(); $request->query->set('ab', []); - $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request); - $results = $this->processor->build($facet, $this->originalResults); + $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request); + $results = $this->processor->buildUrls($facet, $this->originalResults); /** @var \Drupal\facets\Result\ResultInterface $r */ foreach ($results as $r) {