diff --git a/features/doctrine/search_filter.feature b/features/doctrine/search_filter.feature index 119a64a8b61..50718f81963 100644 --- a/features/doctrine/search_filter.feature +++ b/features/doctrine/search_filter.feature @@ -76,7 +76,7 @@ Feature: Search filter on collections }, "hydra:search": { "@type": "hydra:IriTemplate", - "hydra:template": "/dummy_cars{?availableAt[before],availableAt[strictly_before],availableAt[after],availableAt[strictly_after],canSell,foobar[],foobargroups[],foobargroups_override[],colors.prop,colors,colors[],secondColors,secondColors[],thirdColors,thirdColors[],uuid,uuid[],name}", + "hydra:template": "/dummy_cars{?availableAt[before],availableAt[strictly_before],availableAt[after],availableAt[strictly_after],canSell,foobar[],foobargroups[],foobargroups_override[],colors.prop,colors,colors[],secondColors,secondColors[],thirdColors,thirdColors[],uuid,uuid[],name,brand,brand[]}", "hydra:variableRepresentation": "BasicRepresentation", "hydra:mapping": [ { @@ -186,6 +186,18 @@ Feature: Search filter on collections "variable": "name", "property": "name", "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "brand", + "property": "brand", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "brand[]", + "property": "brand", + "required": false } ] } diff --git a/src/Doctrine/Common/Filter/SearchFilterInterface.php b/src/Doctrine/Common/Filter/SearchFilterInterface.php index a96042cabc7..198129dc4f5 100644 --- a/src/Doctrine/Common/Filter/SearchFilterInterface.php +++ b/src/Doctrine/Common/Filter/SearchFilterInterface.php @@ -26,23 +26,48 @@ interface SearchFilterInterface */ public const STRATEGY_EXACT = 'exact'; + /** + * @var string Exact matching case-insensitive + */ + public const STRATEGY_IEXACT = 'iexact'; + /** * @var string The value must be contained in the field */ public const STRATEGY_PARTIAL = 'partial'; + /** + * @var string The value must be contained in the field case-insensitive + */ + public const STRATEGY_IPARTIAL = 'partial'; + /** * @var string Finds fields that are starting with the value */ public const STRATEGY_START = 'start'; + /** + * @var string Finds fields that are starting with the value case-insensitive + */ + public const STRATEGY_ISTART = 'start'; + /** * @var string Finds fields that are ending with the value */ public const STRATEGY_END = 'end'; + /** + * @var string Finds fields that are ending with the value case-insensitive + */ + public const STRATEGY_IEND = 'end'; + /** * @var string Finds fields that are starting with the word */ public const STRATEGY_WORD_START = 'word_start'; + + /** + * @var string Finds fields that are starting with the word case-insensitive + */ + public const STRATEGY_IWORD_START = 'word_start'; } diff --git a/src/Doctrine/Common/Filter/SearchFilterTrait.php b/src/Doctrine/Common/Filter/SearchFilterTrait.php index e07a201046c..d004add8e63 100644 --- a/src/Doctrine/Common/Filter/SearchFilterTrait.php +++ b/src/Doctrine/Common/Filter/SearchFilterTrait.php @@ -66,7 +66,7 @@ public function getDescription(string $resourceClass): array $strategy = $this->getProperties()[$property] ?? self::STRATEGY_EXACT; $filterParameterNames = [$propertyName]; - if (self::STRATEGY_EXACT === $strategy) { + if (\in_array($strategy, [self::STRATEGY_EXACT, self::STRATEGY_IEXACT], true)) { $filterParameterNames[] = $propertyName.'[]'; } diff --git a/tests/Fixtures/TestBundle/Document/DummyCar.php b/tests/Fixtures/TestBundle/Document/DummyCar.php index 16d482326c2..db3fe080125 100644 --- a/tests/Fixtures/TestBundle/Document/DummyCar.php +++ b/tests/Fixtures/TestBundle/Document/DummyCar.php @@ -65,6 +65,7 @@ class DummyCar private ?bool $canSell = null; #[ODM\Field(type: 'date')] private ?\DateTime $availableAt = null; + #[ApiFilter(SearchFilter::class, strategy: SearchFilter::STRATEGY_IEXACT)] #[Serializer\Groups(['colors'])] #[Serializer\SerializedName('carBrand')] #[ODM\Field] diff --git a/tests/Fixtures/TestBundle/Entity/DummyCar.php b/tests/Fixtures/TestBundle/Entity/DummyCar.php index 080abef640e..3991a1da6a8 100644 --- a/tests/Fixtures/TestBundle/Entity/DummyCar.php +++ b/tests/Fixtures/TestBundle/Entity/DummyCar.php @@ -73,6 +73,7 @@ class DummyCar private bool $canSell; #[ORM\Column(type: 'datetime')] private \DateTime $availableAt; + #[ApiFilter(SearchFilter::class, strategy: SearchFilter::STRATEGY_IEXACT)] #[Serializer\Groups(['colors'])] #[Serializer\SerializedName('carBrand')] #[ORM\Column]