diff --git a/src/Bundle/Doctrine/DBAL/ExpressionBuilder.php b/src/Bundle/Doctrine/DBAL/ExpressionBuilder.php index 80bf24ae..b904f3e0 100644 --- a/src/Bundle/Doctrine/DBAL/ExpressionBuilder.php +++ b/src/Bundle/Doctrine/DBAL/ExpressionBuilder.php @@ -15,6 +15,7 @@ use Doctrine\DBAL\Query\QueryBuilder; use Sylius\Component\Grid\Data\ExpressionBuilderInterface; +use Sylius\Component\Resource\Exception\UnsupportedMethodException; final class ExpressionBuilder implements ExpressionBuilderInterface { @@ -82,6 +83,14 @@ public function greaterThanOrEqual(string $field, $value) return $this->queryBuilder->expr()->gte($field, ':' . $field); } + /** + * Method not supported by Doctrine\DBAL\Query\Expression\ExpressionBuilder + */ + public function memberOf($value, string $field) + { + throw new UnsupportedMethodException('memberOf'); + } + public function in(string $field, array $values) { return $this->queryBuilder->expr()->in($field, $values); diff --git a/src/Bundle/Doctrine/ORM/ExpressionBuilder.php b/src/Bundle/Doctrine/ORM/ExpressionBuilder.php index 2188637a..fd634994 100644 --- a/src/Bundle/Doctrine/ORM/ExpressionBuilder.php +++ b/src/Bundle/Doctrine/ORM/ExpressionBuilder.php @@ -97,6 +97,13 @@ public function greaterThanOrEqual(string $field, $value) return $this->queryBuilder->expr()->gte($this->resolveFieldByAddingJoins($field), ':' . $parameterName); } + public function memberOf($value, string $field) + { + $field = $this->adjustField($field); + + return $this->queryBuilder->expr()->isMemberOf($value, $this->resolveFieldByAddingJoins($field)); + } + public function in(string $field, array $values) { $field = $this->adjustField($field); diff --git a/src/Bundle/Doctrine/PHPCRODM/ExpressionBuilder.php b/src/Bundle/Doctrine/PHPCRODM/ExpressionBuilder.php index bdf0181d..db7b931b 100644 --- a/src/Bundle/Doctrine/PHPCRODM/ExpressionBuilder.php +++ b/src/Bundle/Doctrine/PHPCRODM/ExpressionBuilder.php @@ -79,6 +79,11 @@ public function greaterThanOrEqual(string $field, $value) return $this->expressionBuilder->gte($field, $value); } + public function memberOf($value, string $field) + { + return $this->expressionBuilder->memberOf($value, $field); + } + public function in(string $field, array $values) { return $this->expressionBuilder->in($field, $values); diff --git a/src/Component/Data/ExpressionBuilderInterface.php b/src/Component/Data/ExpressionBuilderInterface.php index ef8bc1e3..92d1faac 100644 --- a/src/Component/Data/ExpressionBuilderInterface.php +++ b/src/Component/Data/ExpressionBuilderInterface.php @@ -78,6 +78,13 @@ public function greaterThan(string $field, $value); */ public function greaterThanOrEqual(string $field, $value); + /** + * @param mixed $value + * + * @return mixed + */ + public function memberOf($value, string $field); + /** * @return mixed */ diff --git a/src/Component/Filter/StringFilter.php b/src/Component/Filter/StringFilter.php index aa94aa15..c54cd055 100644 --- a/src/Component/Filter/StringFilter.php +++ b/src/Component/Filter/StringFilter.php @@ -37,6 +37,8 @@ final class StringFilter implements FilterInterface public const TYPE_ENDS_WITH = 'ends_with'; + public const TYPE_MEMBER_OF = 'member_of'; + public const TYPE_IN = 'in'; public const TYPE_NOT_IN = 'not_in'; @@ -107,6 +109,8 @@ private function getExpression( return $expressionBuilder->in($field, array_map('trim', explode(',', $value))); case self::TYPE_NOT_IN: return $expressionBuilder->notIn($field, array_map('trim', explode(',', $value))); + case self::TYPE_MEMBER_OF: + return $expressionBuilder->memberOf($value, $field); default: throw new \InvalidArgumentException(sprintf('Could not get an expression for type "%s"!', $type)); } diff --git a/src/Component/spec/Filter/StringFilterSpec.php b/src/Component/spec/Filter/StringFilterSpec.php index 8d679f97..0eaa85d8 100644 --- a/src/Component/spec/Filter/StringFilterSpec.php +++ b/src/Component/spec/Filter/StringFilterSpec.php @@ -146,6 +146,18 @@ function it_filters_data_containing_one_of_strings( $this->apply($dataSource, 'firstName', ['type' => StringFilter::TYPE_IN, 'value' => 'John, Paul,Rick'], []); } + function it_filters_data_containing_value_being_member_of_field( + DataSourceInterface $dataSource, + ExpressionBuilderInterface $expressionBuilder, + ): void { + $dataSource->getExpressionBuilder()->willReturn($expressionBuilder); + + $expressionBuilder->memberOf('Rick', 'firstName')->willReturn('EXPR'); + $dataSource->restrict('EXPR')->shouldBeCalled(); + + $this->apply($dataSource, 'firstName', ['type' => StringFilter::TYPE_MEMBER_OF, 'value' => 'Rick'], []); + } + function it_filters_data_containing_none_of_strings( DataSourceInterface $dataSource, ExpressionBuilderInterface $expressionBuilder,