diff --git a/docs/reference/filter_field_definition.rst b/docs/reference/filter_field_definition.rst index 73bd4186b..6f3071485 100644 --- a/docs/reference/filter_field_definition.rst +++ b/docs/reference/filter_field_definition.rst @@ -192,6 +192,8 @@ Empty } } +This filter has an additional option ``inverse`` in order to be used as a ``NotEmptyFilter``. + Advanced usage -------------- diff --git a/src/Filter/EmptyFilter.php b/src/Filter/EmptyFilter.php index 3627e1306..09043fd05 100644 --- a/src/Filter/EmptyFilter.php +++ b/src/Filter/EmptyFilter.php @@ -31,19 +31,18 @@ public function filter(ProxyQueryInterface $queryBuilder, $alias, $field, $value return; } - if (BooleanType::TYPE_YES === (int) $value['value']) { + $isYes = BooleanType::TYPE_YES === (int) $value['value']; + $isNo = BooleanType::TYPE_NO === (int) $value['value']; + + if (!$this->getOption('inverse') && $isYes || $this->getOption('inverse') && $isNo) { $this->applyWhere( $queryBuilder, - $queryBuilder - ->expr() - ->isNull(sprintf('%s.%s', $alias, $field)) + $queryBuilder->expr()->isNull(sprintf('%s.%s', $alias, $field)) ); - } elseif (BooleanType::TYPE_NO === (int) $value['value']) { + } elseif (!$this->getOption('inverse') && $isNo || $this->getOption('inverse') && $isYes) { $this->applyWhere( $queryBuilder, - $queryBuilder - ->expr() - ->isNotNull(sprintf('%s.%s', $alias, $field)) + $queryBuilder->expr()->isNotNull(sprintf('%s.%s', $alias, $field)) ); } } @@ -54,6 +53,7 @@ public function getDefaultOptions() 'field_type' => BooleanType::class, 'operator_type' => HiddenType::class, 'operator_options' => [], + 'inverse' => false, ]; } diff --git a/tests/Filter/EmptyFilterTest.php b/tests/Filter/EmptyFilterTest.php index 4c3003ac8..bd881a1ff 100644 --- a/tests/Filter/EmptyFilterTest.php +++ b/tests/Filter/EmptyFilterTest.php @@ -38,11 +38,12 @@ public function testEmpty(): void /** * @dataProvider valueDataProvider */ - public function testValue(int $value, string $expectedQuery): void + public function testValue(bool $inverse, int $value, string $expectedQuery): void { $filter = new EmptyFilter(); $filter->initialize('field_name', [ 'field_options' => ['class' => 'FooBar'], + 'inverse' => $inverse, ]); $builder = new ProxyQuery(new QueryBuilder()); @@ -68,8 +69,10 @@ public function testRenderSettings(): void public function valueDataProvider(): array { return [ - [BooleanType::TYPE_YES, 'alias.field IS NULL'], - [BooleanType::TYPE_NO, 'alias.field IS NOT NULL'], + [false, BooleanType::TYPE_YES, 'alias.field IS NULL'], + [false, BooleanType::TYPE_NO, 'alias.field IS NOT NULL'], + [true, BooleanType::TYPE_YES, 'alias.field IS NOT NULL'], + [true, BooleanType::TYPE_NO, 'alias.field IS NULL'], ]; } }