From ec2ccd516f76152ffd9bcf5e36f5bc2a802b4ae2 Mon Sep 17 00:00:00 2001 From: Dennis de Best Date: Thu, 26 Dec 2024 12:11:45 +0100 Subject: [PATCH] Update DoctrineBehaviors for Symfony 7 and Doctrine ORM 3 compatibility This commit upgrades dependencies and adjusts classes to align with Symfony 7 and Doctrine ORM 3 requirements. Key changes include modifying type hints, updating deprecated `ClassMetadataInfo` usage to `ClassMetadata`, and refining mapping logics. This ensures compatibility with the latest frameworks and improves maintainability. --- composer.json | 20 ++++---- .../BlameableEventSubscriber.php | 36 ++++++------- .../SluggableEventSubscriber.php | 10 ++-- .../SoftDeletableEventSubscriber.php | 2 +- .../TranslatableEventSubscriber.php | 50 +++++++++---------- .../Translatable/TranslatableMethodsTrait.php | 5 +- .../TranslationPropertiesTrait.php | 2 +- 7 files changed, 63 insertions(+), 62 deletions(-) diff --git a/composer.json b/composer.json index 3e0f054f..0d3712cc 100644 --- a/composer.json +++ b/composer.json @@ -13,18 +13,18 @@ "require": { "php": ">=8.1", "doctrine/common": "^3.3", - "doctrine/persistence": "^2.5|^3.0", + "doctrine/persistence": "^3.0", "doctrine/dbal": "^3.3", - "doctrine/orm": "^2.12", + "doctrine/orm": "^3.3", "doctrine/doctrine-bundle": "^2.7.2", - "symfony/cache": "^6.1|^7.0", - "symfony/dependency-injection": "^6.1|^7.0", - "symfony/http-kernel": "^6.1|^7.0", - "symfony/security-bundle": "^6.1|^7.0", - "symfony/framework-bundle": "^6.1|^7.0", - "symfony/string": "^6.1|^7.0", - "symfony/translation-contracts": "^2.4|^3.0", - "nette/utils": "^3.2", + "symfony/cache": "^7.0", + "symfony/dependency-injection": "^7.0", + "symfony/http-kernel": "^7.0", + "symfony/security-bundle": "^7.0", + "symfony/framework-bundle": "^7.0", + "symfony/string": "^7.0", + "symfony/translation-contracts": "^3.0", + "nette/utils": "^4.0", "ramsey/uuid": "^4.2" }, "require-dev": { diff --git a/src/EventSubscriber/BlameableEventSubscriber.php b/src/EventSubscriber/BlameableEventSubscriber.php index f86637d9..887b90c9 100644 --- a/src/EventSubscriber/BlameableEventSubscriber.php +++ b/src/EventSubscriber/BlameableEventSubscriber.php @@ -11,7 +11,7 @@ use Doctrine\ORM\Event\PreRemoveEventArgs; use Doctrine\ORM\Event\PreUpdateEventArgs; use Doctrine\ORM\Events; -use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\UnitOfWork; use Knp\DoctrineBehaviors\Contract\Entity\BlameableInterface; use Knp\DoctrineBehaviors\Contract\Provider\UserProviderInterface; @@ -137,12 +137,12 @@ public function preRemove(PreRemoveEventArgs $preRemoveEventArgs): void ->propertyChanged($object, self::DELETED_BY, $oldDeletedBy, $user); } - private function mapEntity(ClassMetadataInfo $classMetadataInfo): void + private function mapEntity(ClassMetadata $classMetadata): void { if ($this->blameableUserEntity !== null && class_exists($this->blameableUserEntity)) { - $this->mapManyToOneUser($classMetadataInfo); + $this->mapManyToOneUser($classMetadata); } else { - $this->mapStringUser($classMetadataInfo); + $this->mapStringUser($classMetadata); } } @@ -151,27 +151,27 @@ private function getUnitOfWork(): UnitOfWork return $this->entityManager->getUnitOfWork(); } - private function mapManyToOneUser(ClassMetadataInfo $classMetadataInfo): void + private function mapManyToOneUser(ClassMetadata $classMetadata): void { - $this->mapManyToOneWithTargetEntity($classMetadataInfo, self::CREATED_BY); - $this->mapManyToOneWithTargetEntity($classMetadataInfo, self::UPDATED_BY); - $this->mapManyToOneWithTargetEntity($classMetadataInfo, self::DELETED_BY); + $this->mapManyToOneWithTargetEntity($classMetadata, self::CREATED_BY); + $this->mapManyToOneWithTargetEntity($classMetadata, self::UPDATED_BY); + $this->mapManyToOneWithTargetEntity($classMetadata, self::DELETED_BY); } - private function mapStringUser(ClassMetadataInfo $classMetadataInfo): void + private function mapStringUser(ClassMetadata $classMetadata): void { - $this->mapStringNullableField($classMetadataInfo, self::CREATED_BY); - $this->mapStringNullableField($classMetadataInfo, self::UPDATED_BY); - $this->mapStringNullableField($classMetadataInfo, self::DELETED_BY); + $this->mapStringNullableField($classMetadata, self::CREATED_BY); + $this->mapStringNullableField($classMetadata, self::UPDATED_BY); + $this->mapStringNullableField($classMetadata, self::DELETED_BY); } - private function mapManyToOneWithTargetEntity(ClassMetadataInfo $classMetadataInfo, string $fieldName): void + private function mapManyToOneWithTargetEntity(ClassMetadata $classMetadata, string $fieldName): void { - if ($classMetadataInfo->hasAssociation($fieldName)) { + if ($classMetadata->hasAssociation($fieldName)) { return; } - $classMetadataInfo->mapManyToOne([ + $classMetadata->mapManyToOne([ 'fieldName' => $fieldName, 'targetEntity' => $this->blameableUserEntity, 'joinColumns' => [ @@ -182,13 +182,13 @@ private function mapManyToOneWithTargetEntity(ClassMetadataInfo $classMetadataIn ]); } - private function mapStringNullableField(ClassMetadataInfo $classMetadataInfo, string $fieldName): void + private function mapStringNullableField(ClassMetadata $classMetadata, string $fieldName): void { - if ($classMetadataInfo->hasField($fieldName)) { + if ($classMetadata->hasField($fieldName)) { return; } - $classMetadataInfo->mapField([ + $classMetadata->mapField([ 'fieldName' => $fieldName, 'type' => 'string', 'nullable' => true, diff --git a/src/EventSubscriber/SluggableEventSubscriber.php b/src/EventSubscriber/SluggableEventSubscriber.php index c082d7a4..0d9b6f2d 100644 --- a/src/EventSubscriber/SluggableEventSubscriber.php +++ b/src/EventSubscriber/SluggableEventSubscriber.php @@ -10,7 +10,7 @@ use Doctrine\ORM\Event\PrePersistEventArgs; use Doctrine\ORM\Event\PreUpdateEventArgs; use Doctrine\ORM\Events; -use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\Mapping\ClassMetadata; use Knp\DoctrineBehaviors\Contract\Entity\SluggableInterface; use Knp\DoctrineBehaviors\Repository\DefaultSluggableRepository; @@ -54,18 +54,18 @@ public function preUpdate(PreUpdateEventArgs $preUpdateEventArgs): void $this->processLifecycleEventArgs($preUpdateEventArgs); } - private function shouldSkip(ClassMetadataInfo $classMetadataInfo): bool + private function shouldSkip(ClassMetadata $classMetadata): bool { - if (! is_a($classMetadataInfo->getName(), SluggableInterface::class, true)) { + if (! is_a($classMetadata->getName(), SluggableInterface::class, true)) { return true; } - return $classMetadataInfo->hasField(self::SLUG); + return $classMetadata->hasField(self::SLUG); } private function processLifecycleEventArgs(PrePersistEventArgs|PreUpdateEventArgs $lifecycleEventArgs): void { - $entity = $lifecycleEventArgs->getEntity(); + $entity = $lifecycleEventArgs->getObject(); if (! $entity instanceof SluggableInterface) { return; } diff --git a/src/EventSubscriber/SoftDeletableEventSubscriber.php b/src/EventSubscriber/SoftDeletableEventSubscriber.php index 9009a8d4..fac35168 100644 --- a/src/EventSubscriber/SoftDeletableEventSubscriber.php +++ b/src/EventSubscriber/SoftDeletableEventSubscriber.php @@ -21,7 +21,7 @@ final class SoftDeletableEventSubscriber public function onFlush(OnFlushEventArgs $onFlushEventArgs): void { - $entityManager = $onFlushEventArgs->getEntityManager(); + $entityManager = $onFlushEventArgs->getObjectManager(); $unitOfWork = $entityManager->getUnitOfWork(); foreach ($unitOfWork->getScheduledEntityDeletions() as $entity) { diff --git a/src/EventSubscriber/TranslatableEventSubscriber.php b/src/EventSubscriber/TranslatableEventSubscriber.php index 8cff5c0c..51e898e8 100644 --- a/src/EventSubscriber/TranslatableEventSubscriber.php +++ b/src/EventSubscriber/TranslatableEventSubscriber.php @@ -9,7 +9,7 @@ use Doctrine\ORM\Event\PostLoadEventArgs; use Doctrine\ORM\Event\PrePersistEventArgs; use Doctrine\ORM\Events; -use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\Persistence\ObjectManager; use Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface; use Knp\DoctrineBehaviors\Contract\Entity\TranslationInterface; @@ -83,51 +83,51 @@ private function convertFetchString(string|int $fetchMode): int } if ($fetchMode === 'EAGER') { - return ClassMetadataInfo::FETCH_EAGER; + return ClassMetadata::FETCH_EAGER; } if ($fetchMode === 'EXTRA_LAZY') { - return ClassMetadataInfo::FETCH_EXTRA_LAZY; + return ClassMetadata::FETCH_EXTRA_LAZY; } - return ClassMetadataInfo::FETCH_LAZY; + return ClassMetadata::FETCH_LAZY; } - private function mapTranslatable(ClassMetadataInfo $classMetadataInfo): void + private function mapTranslatable(ClassMetadata $classMetadata): void { - if ($classMetadataInfo->hasAssociation('translations')) { + if ($classMetadata->hasAssociation('translations')) { return; } - $classMetadataInfo->mapOneToMany([ + $classMetadata->mapOneToMany([ 'fieldName' => 'translations', 'mappedBy' => 'translatable', 'indexBy' => self::LOCALE, - 'cascade' => ['persist', 'merge', 'remove'], + 'cascade' => ['persist', 'remove'], 'fetch' => $this->translatableFetchMode, - 'targetEntity' => $classMetadataInfo->getReflectionClass() + 'targetEntity' => $classMetadata->getReflectionClass() ->getMethod('getTranslationEntityClass') ->invoke(null), 'orphanRemoval' => true, ]); } - private function mapTranslation(ClassMetadataInfo $classMetadataInfo, ObjectManager $objectManager): void + private function mapTranslation(ClassMetadata $classMetadata, ObjectManager $objectManager): void { - if (! $classMetadataInfo->hasAssociation('translatable')) { - $targetEntity = $classMetadataInfo->getReflectionClass() + if (! $classMetadata->hasAssociation('translatable')) { + $targetEntity = $classMetadata->getReflectionClass() ->getMethod('getTranslatableEntityClass') ->invoke(null); - /** @var ClassMetadataInfo $classMetadata */ - $classMetadata = $objectManager->getClassMetadata($targetEntity); + /** @var ClassMetadata $classPersistenceMetadata */ + $classPersistenceMetadata = $objectManager->getClassMetadata($targetEntity); - $singleIdentifierFieldName = $classMetadata->getSingleIdentifierFieldName(); + $singleIdentifierFieldName = $classPersistenceMetadata->getSingleIdentifierFieldName(); - $classMetadataInfo->mapManyToOne([ + $classMetadata->mapManyToOne([ 'fieldName' => 'translatable', 'inversedBy' => 'translations', - 'cascade' => ['persist', 'merge'], + 'cascade' => ['persist'], 'fetch' => $this->translationFetchMode, 'joinColumns' => [[ 'name' => 'translatable_id', @@ -138,16 +138,16 @@ private function mapTranslation(ClassMetadataInfo $classMetadataInfo, ObjectMana ]); } - $name = $classMetadataInfo->getTableName() . '_unique_translation'; - if (! $this->hasUniqueTranslationConstraint($classMetadataInfo, $name) && - $classMetadataInfo->getName() === $classMetadataInfo->rootEntityName) { - $classMetadataInfo->table['uniqueConstraints'][$name] = [ + $name = $classMetadata->getTableName() . '_unique_translation'; + if (! $this->hasUniqueTranslationConstraint($classMetadata, $name) && + $classMetadata->getName() === $classMetadata->rootEntityName) { + $classMetadata->table['uniqueConstraints'][$name] = [ 'columns' => ['translatable_id', self::LOCALE], ]; } - if (! $classMetadataInfo->hasField(self::LOCALE) && ! $classMetadataInfo->hasAssociation(self::LOCALE)) { - $classMetadataInfo->mapField([ + if (! $classMetadata->hasField(self::LOCALE) && ! $classMetadata->hasAssociation(self::LOCALE)) { + $classMetadata->mapField([ 'fieldName' => self::LOCALE, 'type' => 'string', 'length' => 5, @@ -173,8 +173,8 @@ private function setLocales(PostLoadEventArgs|PrePersistEventArgs $lifecycleEven } } - private function hasUniqueTranslationConstraint(ClassMetadataInfo $classMetadataInfo, string $name): bool + private function hasUniqueTranslationConstraint(ClassMetadata $classMetadata, string $name): bool { - return isset($classMetadataInfo->table['uniqueConstraints'][$name]); + return isset($classMetadata->table['uniqueConstraints'][$name]); } } diff --git a/src/Model/Translatable/TranslatableMethodsTrait.php b/src/Model/Translatable/TranslatableMethodsTrait.php index a1374b20..be2464dc 100644 --- a/src/Model/Translatable/TranslatableMethodsTrait.php +++ b/src/Model/Translatable/TranslatableMethodsTrait.php @@ -12,9 +12,9 @@ trait TranslatableMethodsTrait { /** - * @return Collection + * @return ArrayCollection|Collection */ - public function getTranslations() + public function getTranslations(): ArrayCollection|Collection { // initialize collection, usually in ctor if ($this->translations === null) { @@ -27,6 +27,7 @@ public function getTranslations() /** * @param Collection $translations * @phpstan-param iterable $translations + * @throws TranslatableException */ public function setTranslations(iterable $translations): void { diff --git a/src/Model/Translatable/TranslationPropertiesTrait.php b/src/Model/Translatable/TranslationPropertiesTrait.php index c3773e27..124c0be6 100644 --- a/src/Model/Translatable/TranslationPropertiesTrait.php +++ b/src/Model/Translatable/TranslationPropertiesTrait.php @@ -14,7 +14,7 @@ trait TranslationPropertiesTrait protected $locale; /** - * Will be mapped to translatable entity by TranslatableSubscriber + * Will be mapped to translatable entity by TranslatableEventSubscriber * * @var TranslatableInterface */