diff --git a/src/Bundle/EventListener/ORMTranslatableListener.php b/src/Bundle/EventListener/ORMTranslatableListener.php index 5b95d861b..33b505041 100644 --- a/src/Bundle/EventListener/ORMTranslatableListener.php +++ b/src/Bundle/EventListener/ORMTranslatableListener.php @@ -183,7 +183,9 @@ private function hasUniqueConstraint(ClassMetadata $metadata, array $columns): b } foreach ($metadata->table['uniqueConstraints'] as $constraint) { - if (!array_diff($constraint['columns'], $columns)) { + $constraintColumns = $constraint['columns'] ?? $constraint['fields'] ?? []; + + if (!array_diff($constraintColumns, $columns)) { return true; } } diff --git a/tests/Bundle/EventListener/ORMTranslatableListenerTest.php b/tests/Bundle/EventListener/ORMTranslatableListenerTest.php index ec42880e0..f1ef7dc47 100644 --- a/tests/Bundle/EventListener/ORMTranslatableListenerTest.php +++ b/tests/Bundle/EventListener/ORMTranslatableListenerTest.php @@ -13,9 +13,15 @@ namespace Bundle\EventListener; +use App\Entity\BookTranslation; use App\Entity\BookTranslationInterface; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\Event\LoadClassMetadataEventArgs; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\DefaultNamingStrategy; +use Doctrine\Persistence\Mapping\RuntimeReflectionService; +use Sylius\Bundle\ResourceBundle\EventListener\ORMTranslatableListener; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; final class ORMTranslatableListenerTest extends KernelTestCase @@ -30,8 +36,72 @@ public function testGettingTranslationRepositoryByItsInterface(): void ); } + public function testItAddsTheTranslatableUniqueConstraintWhenAnotherOneUsesTheFieldsFormat(): void + { + self::bootKernel(); + + $metadata = $this->createTranslationClassMetadata([ + 'uniq_book_translation_title' => ['fields' => ['title']], + ]); + + $this->createListener()->loadClassMetadata( + new LoadClassMetadataEventArgs($metadata, $this->getEntityManager()), + ); + + $uniqueConstraints = $metadata->table['uniqueConstraints']; + + $this->assertArrayHasKey('uniq_book_translation_title', $uniqueConstraints); + $this->assertArrayHasKey('app_book_translation_uniq_trans', $uniqueConstraints); + $this->assertSame( + ['translatable_id', 'locale'], + $uniqueConstraints['app_book_translation_uniq_trans']['columns'], + ); + } + + public function testItAddsTheTranslatableUniqueConstraintWhenAnotherOneUsesTheLegacyColumnsFormat(): void + { + self::bootKernel(); + + $metadata = $this->createTranslationClassMetadata([ + 'uniq_book_translation_title' => ['columns' => ['title']], + ]); + + $this->createListener()->loadClassMetadata( + new LoadClassMetadataEventArgs($metadata, $this->getEntityManager()), + ); + + $uniqueConstraints = $metadata->table['uniqueConstraints']; + + $this->assertArrayHasKey('uniq_book_translation_title', $uniqueConstraints); + $this->assertArrayHasKey('app_book_translation_uniq_trans', $uniqueConstraints); + $this->assertSame( + ['translatable_id', 'locale'], + $uniqueConstraints['app_book_translation_uniq_trans']['columns'], + ); + } + + /** + * @param array, fields?: array}> $uniqueConstraints + */ + private function createTranslationClassMetadata(array $uniqueConstraints): ClassMetadata + { + $metadata = new ClassMetadata(BookTranslation::class, new DefaultNamingStrategy()); + $metadata->wakeupReflection(new RuntimeReflectionService()); + $metadata->setPrimaryTable([ + 'name' => 'app_book_translation', + 'uniqueConstraints' => $uniqueConstraints, + ]); + + return $metadata; + } + + private function createListener(): ORMTranslatableListener + { + return self::getContainer()->get(ORMTranslatableListener::class); + } + private function getEntityManager(): EntityManagerInterface { - return $this->getContainer()->get(EntityManagerInterface::class); + return self::getContainer()->get(EntityManagerInterface::class); } }