Commit 11a509d9 authored by Tom Verhaeghe's avatar Tom Verhaeghe Committed by borisson_

Issue #2598294 by borisson_, Tom Verhaeghe: Create Facet processors - Exclude specified items

parent 566c5a60
<?php
/**
* @file
* Contains \Drupal\facetapi\Plugin\facetapi\ExcludeSpecifiedItemsProcessor.
*/
namespace Drupal\facetapi\Plugin\facetapi\processor;
use Drupal\Core\Form\FormStateInterface;
use Drupal\facetapi\FacetInterface;
use Drupal\facetapi\Processor\BuildProcessorInterface;
use Drupal\facetapi\Processor\ProcessorPluginBase;
/**
* Provides a processor that excludes specified items.
*
* @FacetApiProcessor(
* id = "exclude_specified_items",
* label = @Translation("Exclude specified items"),
* description = @Translation("Excludes items by node id or title."),
* stages = {
* "build" = 50
* }
* )
*/
class ExcludeSpecifiedItemsProcessor extends ProcessorPluginBase implements BuildProcessorInterface {
/**
* {@inheritdoc}
*/
public function build(FacetInterface $facet, array $results) {
$processors = $facet->getProcessors();
$config = $processors[$this->getPluginId()];
/** @var \Drupal\facetapi\Result\ResultInterface $result */
$exclude_item = $config->getConfiguration()['exclude'];
foreach ($results as $id => $result) {
if ($config->getConfiguration()['regex']) {
$matcher = '/' . trim(str_replace('/', '\\/', $exclude_item)) . '/';
if (preg_match($matcher, $result->getRawValue()) || preg_match($matcher, $result->getDisplayValue())) {
unset($results[$id]);
}
}
else {
if ($result->getRawValue() == $exclude_item || $result->getDisplayValue() == $exclude_item) {
unset($results[$id]);
}
}
}
return $results;
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet) {
$processors = $facet->getProcessors();
$config = $processors[$this->getPluginId()];
$build['exclude'] = [
'#title' => $this->t('Exclude items'),
'#type' => 'textfield',
'#default_value' => isset($config) ? $config->getConfiguration()['exclude'] : $this->defaultConfiguration()['exclude'],
'#description' => $this->t("Comma separated list of titles or values that should be excluded, matching either an item's title or value."),
];
$build['regex'] = [
'#title' => $this->t('Regular expressions used'),
'#type' => 'checkbox',
'#default_value' => isset($config) ? $config->getConfiguration()['regex'] : $this->defaultConfiguration()['regex'],
'#description' => $this->t('Interpret each exclude list item as a regular expression pattern.<br /><small>(Slashes are escaped automatically, patterns using a comma can be wrapped in "double quotes", and if such a pattern uses double quotes itself, just make them double-double-quotes (""))</small>.'),
];
return $build;
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'exclude' => '',
'regex' => 0,
];
}
}
......@@ -50,11 +50,11 @@ class MinimumCountProcessor extends ProcessorPluginBase implements BuildProcesso
$config = $processors[$this->getPluginId()];
$build['minimum_items'] = array(
'#title' => 'Minimum items',
'#title' => $this->t('Minimum items'),
'#type' => 'number',
'#min' => 1,
'#default_value' => isset($config) ? $config->getConfiguration()['minimum_items'] : $this->defaultConfiguration()['minimum_items'],
'#description' => 'Hide block if the facet contains less than this number of results',
'#description' => $this->t('Hide block if the facet contains less than this number of results'),
);
return $build;
......
<?php
/**
* @file
* Contains \Drupal\Tests\facetapi\Plugin\Processor\ExcludeSpecifiedItemsProcessorTest.
*/
namespace Drupal\Tests\facetapi\Unit\Plugin\Processor;
use Drupal\facetapi\Entity\Facet;
use Drupal\facetapi\Plugin\facetapi\processor\ExcludeSpecifiedItemsProcessor;
use Drupal\facetapi\Result\Result;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @group facetapi
*/
class ExcludeSpecifiedItemsProcessorTest extends UnitTestCase {
/**
* The processor to be tested.
*
* @var \Drupal\facetapi\processor\BuildProcessorInterface
*/
protected $processor;
/**
* An array containing the results before the processor has ran.
*
* @var \Drupal\facetapi\Result\Result[]
*/
protected $original_results;
/**
* Creates a new processor object for use in the tests.
*/
protected function setUp() {
parent::setUp();
$this->original_results = [
new Result('llama', 'llama', 10),
new Result('badger', 'badger', 5),
new Result('duck', 'duck', 15),
new Result('snake', 'snake', 10),
new Result('snaake', 'snaake', 10),
new Result('snaaake', 'snaaake', 10),
new Result('snaaaake', 'snaaaake', 10),
new Result('snaaaaake', 'snaaaaake', 10),
new Result('snbke', 'snbke', 10),
];
$processor_id = 'exclude_specified_items';
$this->processor = new ExcludeSpecifiedItemsProcessor([], $processor_id, []);
$processorDefinitions = [
$processor_id => [
'id' => $processor_id,
'class' => 'Drupal\facetapi\Plugin\facetapi\processor\ExcludeSpecifiedItemsProcessor',
],
];
$manager = $this->getMockBuilder('Drupal\facetapi\Processor\ProcessorPluginManager')
->disableOriginalConstructor()
->getMock();
$manager->expects($this->once())
->method('getDefinitions')
->willReturn($processorDefinitions);
$manager->expects($this->once())
->method('createInstance')
->willReturn($this->processor);
$container_builder = new ContainerBuilder();
$container_builder->set('plugin.manager.facetapi.processor', $manager);
\Drupal::setContainer($container_builder);
}
/**
* Test no filtering happens.
*/
public function testNoFilter() {
$facet = new Facet([], 'facet');
$facet->setResults($this->original_results);
$facet->setOption('processors', [
'exclude_specified_items' => [
'settings' => [
'exclude' => 'alpaca',
'regex' => 0
],
],
]);
$this->processor->setConfiguration([
'exclude' => 'alpaca',
'regex' => 0
]);
$filtered_results = $this->processor->build($facet, $this->original_results);
$this->assertCount(count($this->original_results), $filtered_results);
}
/**
* Test filtering happens for string filter
*/
public function testStringFilter() {
$facet = new Facet([], 'facet');
$facet->setResults($this->original_results);
$facet->setOption('processors', [
'exclude_specified_items' => [
'settings' => [
'exclude' => 'llama',
'regex' => 0
],
],
]);
$this->processor->setConfiguration([
'exclude' => 'llama',
'regex' => 0
]);
$filtered_results = $this->processor->build($facet, $this->original_results);
$this->assertCount((count($this->original_results) -1), $filtered_results);
}
/**
* Test filtering happens for string filter
* @dataProvider provideRegexTests
*/
public function testRegexFilter($regex, $expectedResults) {
$facet = new Facet([], 'facet');
$facet->setResults($this->original_results);
$facet->setOption('processors', [
'exclude_specified_items' => [
'settings' => [
'exclude' => $regex,
'regex' => 1
],
],
]);
$this->processor->setConfiguration([
'exclude' => $regex,
'regex' => 1
]);
$filtered_results = $this->processor->build($facet, $this->original_results);
$this->assertCount(count($expectedResults), $filtered_results);
foreach ($filtered_results as $res) {
$this->assertTrue(in_array($res->getDisplayValue(), $expectedResults));
}
}
/**
* Provide multiple data sets for ::testRegexFilter
*/
public function provideRegexTests() {
return [
[
'test',
['llama', 'duck', 'badger', 'snake', 'snaake', 'snaaake', 'snaaaake', 'snaaaaake', 'snbke']
],
[
'llama',
['badger', 'duck', 'snake', 'snaake', 'snaaake', 'snaaaake', 'snaaaaake', 'snbke']
],
[
'duck',
['llama', 'badger', 'snake', 'snaake', 'snaaake', 'snaaaake', 'snaaaaake', 'snbke']
],
[
'sn(.*)ke',
['llama', 'duck', 'badger']
],
[
'sn(a*)ke',
['llama', 'duck', 'badger', 'snbke']
],
];
}
}
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