From 1b97786a593898d33c677d33e12a9dc72c8ca098 Mon Sep 17 00:00:00 2001 From: Sebastiaan Stok Date: Tue, 17 Mar 2026 16:32:35 +0100 Subject: [PATCH] [Doctrine] Check order-field multi-mapping This was already checked during the query generating process but it's better to handle this during the mapping building --- lib/Doctrine/Dbal/FieldConfigurationSet.php | 18 ++++++++++++------ lib/Doctrine/Orm/FieldConfigBuilder.php | 7 ++++++- .../Orm/Tests/FieldConfigBuilderTest.php | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/lib/Doctrine/Dbal/FieldConfigurationSet.php b/lib/Doctrine/Dbal/FieldConfigurationSet.php index 586ba986..9f674f3b 100644 --- a/lib/Doctrine/Dbal/FieldConfigurationSet.php +++ b/lib/Doctrine/Dbal/FieldConfigurationSet.php @@ -14,6 +14,7 @@ namespace Rollerworks\Component\Search\Doctrine\Dbal; use Rollerworks\Component\Search\Doctrine\Dbal\Query\QueryField; +use Rollerworks\Component\Search\Field\OrderField; use Rollerworks\Component\Search\FieldSet; /** @@ -29,19 +30,24 @@ public function __construct( ) { } - public function setField(string $fieldName, string $column, ?string $alias = null, string $type = 'string'): void + public function setField(string $mappingName, string $column, ?string $alias = null, string $type = 'string'): void { - $mappingIdx = null; + $mappingIdx = ''; + $fieldName = $mappingName; - if (mb_strpos($fieldName, '#') !== false) { - [$fieldName, $mappingIdx] = explode('#', $fieldName, 2); + if (str_contains($mappingName, '#')) { + [$fieldName, $mappingIdx] = explode('#', $mappingName, 2); unset($this->fields[$fieldName]['']); } else { - $this->fields[$fieldName] = []; + $this->fields[$mappingName] = []; + } + + if (OrderField::isOrder($fieldName) && str_contains($mappingName, '#')) { + throw new \RuntimeException(\sprintf('Ordering field "%s" cannot be registered with multiple mapping.', $fieldName)); } $this->fields[$fieldName][$mappingIdx] = new QueryField( - $fieldName . ($mappingIdx !== null ? "#{$mappingIdx}" : ''), + $mappingName, $this->fieldSet->get($fieldName), $type, $column, diff --git a/lib/Doctrine/Orm/FieldConfigBuilder.php b/lib/Doctrine/Orm/FieldConfigBuilder.php index a0ba1f6e..4b75505f 100644 --- a/lib/Doctrine/Orm/FieldConfigBuilder.php +++ b/lib/Doctrine/Orm/FieldConfigBuilder.php @@ -14,6 +14,7 @@ namespace Rollerworks\Component\Search\Doctrine\Orm; use Doctrine\ORM\EntityManagerInterface; +use Rollerworks\Component\Search\Field\OrderField; use Rollerworks\Component\Search\FieldSet; /** @@ -48,13 +49,17 @@ public function setField(string $mappingName, string $property, ?string $alias = throw new \RuntimeException('No default entity is set, either provide the entity or set a default entity first.'); } - if (mb_strpos($mappingName, '#') !== false) { + if (str_contains($mappingName, '#')) { [$fieldName, $mappingIdx] = explode('#', $mappingName, 2); unset($this->fields[$fieldName]['']); } else { $this->fields[$fieldName] = []; } + if (OrderField::isOrder($fieldName) && str_contains($mappingName, '#')) { + throw new \RuntimeException(\sprintf('Ordering field "%s" cannot be registered with multiple mapping.', $fieldName)); + } + [$entity, $property] = $this->getEntityAndProperty( $mappingName, $entity ?? $this->defaultEntity, diff --git a/lib/Doctrine/Orm/Tests/FieldConfigBuilderTest.php b/lib/Doctrine/Orm/Tests/FieldConfigBuilderTest.php index 3f57a723..3f443088 100644 --- a/lib/Doctrine/Orm/Tests/FieldConfigBuilderTest.php +++ b/lib/Doctrine/Orm/Tests/FieldConfigBuilderTest.php @@ -22,6 +22,7 @@ use Rollerworks\Component\Search\Doctrine\Orm\OrmQueryField as QueryField; use Rollerworks\Component\Search\Extension\Core\Type\IntegerType; use Rollerworks\Component\Search\Extension\Core\Type\TextType; +use Rollerworks\Component\Search\Field\OrderFieldType; use Rollerworks\Component\Search\Searches; use Rollerworks\Component\Search\SearchFactory; use Rollerworks\Component\Search\Tests\Doctrine\Orm\Fixtures\Entity\ECommerceCustomer; @@ -212,6 +213,23 @@ public function fails_when_no_entity_is_provided(): void $fieldConfigBuilder->setField('id', 'id'); } + /** + * @test + */ + public function fails_when_ordering_with_multi_mapping(): void + { + $this->getFieldSet(false) + ->add('@id', OrderFieldType::class) + ->getFieldSet('invoice'); + + $fieldConfigBuilder = new FieldConfigBuilder($this->em->reveal(), $this->getFieldSet()); + + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Ordering field "@id" cannot be registered with multiple mapping.'); + + $fieldConfigBuilder->setField('@id#1', 'id', 'I', 'Invoice'); + } + /** * @test */