From 6a62a53f854ec93947d1c4a5a32007df09e55d06 Mon Sep 17 00:00:00 2001 From: Corentin FACKEURE Date: Mon, 25 Sep 2023 14:18:39 +0200 Subject: [PATCH 1/3] fix(hydra): add xxx[] hydra:search iexact --- src/Doctrine/Common/Filter/SearchFilterInterface.php | 5 +++++ src/Doctrine/Common/Filter/SearchFilterTrait.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Doctrine/Common/Filter/SearchFilterInterface.php b/src/Doctrine/Common/Filter/SearchFilterInterface.php index a96042cabc7..2979c8fd872 100644 --- a/src/Doctrine/Common/Filter/SearchFilterInterface.php +++ b/src/Doctrine/Common/Filter/SearchFilterInterface.php @@ -26,6 +26,11 @@ 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 */ diff --git a/src/Doctrine/Common/Filter/SearchFilterTrait.php b/src/Doctrine/Common/Filter/SearchFilterTrait.php index e07a201046c..9bb610d4478 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 (self::STRATEGY_EXACT === $strategy || self::STRATEGY_IEXACT === $strategy) { $filterParameterNames[] = $propertyName.'[]'; } From 1fccb8413a902a1011f049d0f8ddcd8d5456d335 Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Thu, 28 Sep 2023 16:10:11 +0200 Subject: [PATCH 2/3] feat(doctrine): add SearchFilter case-insensitive strategies constants --- .../Common/Filter/SearchFilterInterface.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Doctrine/Common/Filter/SearchFilterInterface.php b/src/Doctrine/Common/Filter/SearchFilterInterface.php index 2979c8fd872..198129dc4f5 100644 --- a/src/Doctrine/Common/Filter/SearchFilterInterface.php +++ b/src/Doctrine/Common/Filter/SearchFilterInterface.php @@ -36,18 +36,38 @@ interface SearchFilterInterface */ 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'; } From e8adb08b89d2ca2d340ace19bab4e97562c8dda6 Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Thu, 28 Sep 2023 16:26:30 +0200 Subject: [PATCH 3/3] test(doctrine): add xxx[] hydra:search iexact field non-regression tests --- features/doctrine/search_filter.feature | 14 +++++++++++++- src/Doctrine/Common/Filter/SearchFilterTrait.php | 2 +- tests/Fixtures/TestBundle/Document/DummyCar.php | 1 + tests/Fixtures/TestBundle/Entity/DummyCar.php | 1 + 4 files changed, 16 insertions(+), 2 deletions(-) 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/SearchFilterTrait.php b/src/Doctrine/Common/Filter/SearchFilterTrait.php index 9bb610d4478..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 || self::STRATEGY_IEXACT === $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]