From 20f4dadc489e1724fa49b563845517e4fb9ef29a Mon Sep 17 00:00:00 2001 From: Evert Harmeling Date: Wed, 7 Feb 2024 13:44:38 +0100 Subject: [PATCH] [Autocomplete] Add support for doctrine/orm:^3.0 --- src/Autocomplete/CHANGELOG.md | 4 ++ src/Autocomplete/composer.json | 3 +- .../src/Doctrine/EntityMetadata.php | 38 ++++++++++++++-- .../src/Doctrine/EntitySearchUtil.php | 7 ++- .../Doctrine/EntityMetadataTest.php | 45 ++++++++++++++++++- 5 files changed, 87 insertions(+), 10 deletions(-) diff --git a/src/Autocomplete/CHANGELOG.md b/src/Autocomplete/CHANGELOG.md index 39032dcc02f..5b78d7ec325 100644 --- a/src/Autocomplete/CHANGELOG.md +++ b/src/Autocomplete/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## Unreleased + +- Add doctrine/orm 3 support. + ## 2.14.0 - Fixed behavior of Autocomplete when the underlying `select` or `option` diff --git a/src/Autocomplete/composer.json b/src/Autocomplete/composer.json index bedb41fbf56..95aee140a12 100644 --- a/src/Autocomplete/composer.json +++ b/src/Autocomplete/composer.json @@ -26,6 +26,7 @@ "require": { "php": ">=8.1", "symfony/dependency-injection": "^6.3|^7.0", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-foundation": "^6.3|^7.0", "symfony/http-kernel": "^6.3|^7.0", "symfony/property-access": "^6.3|^7.0", @@ -34,7 +35,7 @@ "require-dev": { "doctrine/collections": "^1.6.8|^2.0", "doctrine/doctrine-bundle": "^2.4.3", - "doctrine/orm": "^2.9.4", + "doctrine/orm": "^2.9.4|^3.0", "fakerphp/faker": "^1.22", "mtdowling/jmespath.php": "^2.6", "symfony/form": "^6.3|^7.0", diff --git a/src/Autocomplete/src/Doctrine/EntityMetadata.php b/src/Autocomplete/src/Doctrine/EntityMetadata.php index 6a5807fb5c9..7a01d0d8a0f 100644 --- a/src/Autocomplete/src/Doctrine/EntityMetadata.php +++ b/src/Autocomplete/src/Doctrine/EntityMetadata.php @@ -42,13 +42,41 @@ public function isEmbeddedClassProperty(string $propertyName): bool } public function getPropertyMetadata(string $propertyName): array + { + trigger_deprecation('symfony/ux-autocomplete', '2.15.0', 'Calling EntityMetadata::getPropertyMetadata() is deprecated. You should stop using it, as it will be removed in the future.'); + + try { + return $this->getFieldMetadata($propertyName); + } catch (\InvalidArgumentException $e) { + return $this->getAssociationMetadata($propertyName); + } + } + + /** + * @internal + * + * @return array + */ + public function getFieldMetadata(string $propertyName): array { if (\array_key_exists($propertyName, $this->metadata->fieldMappings)) { - return $this->metadata->fieldMappings[$propertyName]; + // Cast to array, because in doctrine/orm:^3.0; $metadata will be a FieldMapping object + return (array) $this->metadata->fieldMappings[$propertyName]; } + throw new \InvalidArgumentException(sprintf('The "%s" field does not exist in the "%s" entity.', $propertyName, $this->metadata->getName())); + } + + /** + * @internal + * + * @return array + */ + public function getAssociationMetadata(string $propertyName): array + { if (\array_key_exists($propertyName, $this->metadata->associationMappings)) { - return $this->metadata->associationMappings[$propertyName]; + // Cast to array, because in doctrine/orm:^3.0; $metadata will be an AssociationMapping object + return (array) $this->metadata->associationMappings[$propertyName]; } throw new \InvalidArgumentException(sprintf('The "%s" field does not exist in the "%s" entity.', $propertyName, $this->metadata->getName())); @@ -56,7 +84,11 @@ public function getPropertyMetadata(string $propertyName): array public function getPropertyDataType(string $propertyName): string { - return $this->getPropertyMetadata($propertyName)['type']; + if (\array_key_exists($propertyName, $this->metadata->fieldMappings)) { + return $this->getFieldMetadata($propertyName)['type']; + } + + return $this->getAssociationMetadata($propertyName)['type']; } public function getIdValue(object $entity): string diff --git a/src/Autocomplete/src/Doctrine/EntitySearchUtil.php b/src/Autocomplete/src/Doctrine/EntitySearchUtil.php index 44986dad70d..7cdf105764b 100644 --- a/src/Autocomplete/src/Doctrine/EntitySearchUtil.php +++ b/src/Autocomplete/src/Doctrine/EntitySearchUtil.php @@ -60,7 +60,7 @@ public function addSearchClause(QueryBuilder $queryBuilder, string $query, strin } $originalPropertyName = $associatedProperties[0]; - $originalPropertyMetadata = $entityMetadata->getPropertyMetadata($originalPropertyName); + $originalPropertyMetadata = $entityMetadata->getAssociationMetadata($originalPropertyName); $associatedEntityDto = $this->metadataFactory->create($originalPropertyMetadata['targetEntity']); for ($i = 0; $i < $numAssociatedProperties - 1; ++$i) { @@ -75,9 +75,8 @@ public function addSearchClause(QueryBuilder $queryBuilder, string $query, strin } if ($i < $numAssociatedProperties - 2) { - $propertyMetadata = $associatedEntityDto->getPropertyMetadata($associatedPropertyName); - $targetEntity = $propertyMetadata['targetEntity']; - $associatedEntityDto = $this->metadataFactory->create($targetEntity); + $propertyMetadata = $associatedEntityDto->getAssociationMetadata($associatedPropertyName); + $associatedEntityDto = $this->metadataFactory->create($propertyMetadata['targetEntity']); } } diff --git a/src/Autocomplete/tests/Integration/Doctrine/EntityMetadataTest.php b/src/Autocomplete/tests/Integration/Doctrine/EntityMetadataTest.php index 1dd30667edd..0023abe7455 100644 --- a/src/Autocomplete/tests/Integration/Doctrine/EntityMetadataTest.php +++ b/src/Autocomplete/tests/Integration/Doctrine/EntityMetadataTest.php @@ -54,7 +54,7 @@ public function testGetPropertyDataType(): void $this->assertEquals(ClassMetadataInfo::MANY_TO_ONE, $metadata->getPropertyDataType('category')); } - public function testGetPropertyMetadata(): void + public function testGetFieldMetadata(): void { $metadata = $this->getMetadata(); $this->assertSame([ @@ -66,7 +66,48 @@ public function testGetPropertyMetadata(): void 'nullable' => false, 'precision' => null, 'columnName' => 'name', - ], $metadata->getPropertyMetadata('name')); + ], $metadata->getFieldMetadata('name')); + } + + public function testGetAssociationMetadata(): void + { + $metadata = $this->getMetadata(); + $this->assertSame([ + 'fieldName' => 'category', + 'joinColumns' => [ + [ + 'name' => 'category_id', + 'unique' => false, + 'nullable' => false, + 'onDelete' => null, + 'columnDefinition' => null, + 'referencedColumnName' => 'id', + ], + ], + 'cascade' => [], + 'inversedBy' => 'products', + 'targetEntity' => 'Symfony\UX\Autocomplete\Tests\Fixtures\Entity\Category', + 'fetch' => 2, + 'type' => 2, + 'mappedBy' => null, + 'isOwningSide' => true, + 'sourceEntity' => 'Symfony\UX\Autocomplete\Tests\Fixtures\Entity\Product', + 'isCascadeRemove' => false, + 'isCascadePersist' => false, + 'isCascadeRefresh' => false, + 'isCascadeMerge' => false, + 'isCascadeDetach' => false, + 'sourceToTargetKeyColumns' => [ + 'category_id' => 'id', + ], + 'joinColumnFieldNames' => [ + 'category_id' => 'category_id', + ], + 'targetToSourceKeyColumns' => [ + 'id' => 'category_id', + ], + 'orphanRemoval' => false, + ], $metadata->getAssociationMetadata('category')); } public function testIsEmbeddedClassProperty(): void