From ecaa8dd2202260428ef3c2db7a6e997c66c34948 Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Thu, 3 Aug 2023 10:06:11 +0200 Subject: [PATCH 01/12] Update TreeNodePropertiesTrait.php Add missing ``parentNodePath`` property in TreeNodePropertiesTrait as it's used in TreeNodeMethodsTrait to fix the following deprecation (raised starting from PHP 8.2): Creation of dynamic property PTC\NoventoBundle\Entity\Menu::$parentNodePath is deprecated --- src/Model/Tree/TreeNodePropertiesTrait.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Model/Tree/TreeNodePropertiesTrait.php b/src/Model/Tree/TreeNodePropertiesTrait.php index 5a1096e0..89731fcb 100644 --- a/src/Model/Tree/TreeNodePropertiesTrait.php +++ b/src/Model/Tree/TreeNodePropertiesTrait.php @@ -23,4 +23,9 @@ trait TreeNodePropertiesTrait * @var TreeNodeInterface|null */ private $parentNode; + + /** + * @var string + */ + private $parentNodePath; } From 3bbecc25745f3d60833d60ed0f91c555e8855c07 Mon Sep 17 00:00:00 2001 From: tlallement Date: Tue, 8 Aug 2023 11:17:21 +0200 Subject: [PATCH 02/12] Fix SF63 deprecations (doctrine subscriber deprecated) --- composer.json | 2 +- src/EventSubscriber/BlameableEventSubscriber.php | 16 ++++++---------- src/EventSubscriber/LoggableEventSubscriber.php | 15 +++++---------- src/EventSubscriber/SluggableEventSubscriber.php | 15 +++++---------- .../SoftDeletableEventSubscriber.php | 13 ++++--------- .../TimestampableEventSubscriber.php | 12 +++--------- .../TranslatableEventSubscriber.php | 15 ++++++--------- src/EventSubscriber/TreeEventSubscriber.php | 13 +++---------- src/EventSubscriber/UuidableEventSubscriber.php | 14 ++++---------- 9 files changed, 37 insertions(+), 78 deletions(-) diff --git a/composer.json b/composer.json index e975e124..b80a8eb6 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "doctrine/persistence": "^2.5|^3.0", "doctrine/dbal": "^3.3", "doctrine/orm": "^2.12", - "doctrine/doctrine-bundle": "^2.6", + "doctrine/doctrine-bundle": "^2.7.2", "symfony/cache": "^5.4|^6.0", "symfony/dependency-injection": "^5.4|^6.0", "symfony/http-kernel": "^5.4|^6.0", diff --git a/src/EventSubscriber/BlameableEventSubscriber.php b/src/EventSubscriber/BlameableEventSubscriber.php index 968ea57f..edd11f2a 100644 --- a/src/EventSubscriber/BlameableEventSubscriber.php +++ b/src/EventSubscriber/BlameableEventSubscriber.php @@ -4,7 +4,7 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; -use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; +use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; @@ -14,7 +14,11 @@ use Knp\DoctrineBehaviors\Contract\Entity\BlameableInterface; use Knp\DoctrineBehaviors\Contract\Provider\UserProviderInterface; -final class BlameableEventSubscriber implements EventSubscriberInterface +#[AsDoctrineListener(event: Events::loadClassMetadata)] +#[AsDoctrineListener(event: Events::prePersist)] +#[AsDoctrineListener(event: Events::preUpdate)] +#[AsDoctrineListener(event: Events::preRemove)] +final class BlameableEventSubscriber { /** * @var string @@ -131,14 +135,6 @@ public function preRemove(LifecycleEventArgs $lifecycleEventArgs): void ->propertyChanged($entity, self::DELETED_BY, $oldDeletedBy, $user); } - /** - * @return string[] - */ - public function getSubscribedEvents(): array - { - return [Events::prePersist, Events::preUpdate, Events::preRemove, Events::loadClassMetadata]; - } - private function mapEntity(ClassMetadataInfo $classMetadataInfo): void { if ($this->blameableUserEntity !== null && class_exists($this->blameableUserEntity)) { diff --git a/src/EventSubscriber/LoggableEventSubscriber.php b/src/EventSubscriber/LoggableEventSubscriber.php index f21907e7..68fd62ab 100644 --- a/src/EventSubscriber/LoggableEventSubscriber.php +++ b/src/EventSubscriber/LoggableEventSubscriber.php @@ -4,14 +4,17 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; -use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; +use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Events; use Knp\DoctrineBehaviors\Contract\Entity\LoggableInterface; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; -final class LoggableEventSubscriber implements EventSubscriberInterface +#[AsDoctrineListener(event: Events::postPersist)] +#[AsDoctrineListener(event: Events::postUpdate)] +#[AsDoctrineListener(event: Events::preRemove)] +final class LoggableEventSubscriber { public function __construct( private LoggerInterface $logger @@ -50,14 +53,6 @@ public function preRemove(LifecycleEventArgs $lifecycleEventArgs): void } } - /** - * @return string[] - */ - public function getSubscribedEvents(): array - { - return [Events::postPersist, Events::postUpdate, Events::preRemove]; - } - /** * Logs entity changeset */ diff --git a/src/EventSubscriber/SluggableEventSubscriber.php b/src/EventSubscriber/SluggableEventSubscriber.php index 6d0b3b9b..41ffdab6 100644 --- a/src/EventSubscriber/SluggableEventSubscriber.php +++ b/src/EventSubscriber/SluggableEventSubscriber.php @@ -4,7 +4,7 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; -use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; +use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; @@ -13,7 +13,10 @@ use Knp\DoctrineBehaviors\Contract\Entity\SluggableInterface; use Knp\DoctrineBehaviors\Repository\DefaultSluggableRepository; -final class SluggableEventSubscriber implements EventSubscriberInterface +#[AsDoctrineListener(event: Events::loadClassMetadata)] +#[AsDoctrineListener(event: Events::prePersist)] +#[AsDoctrineListener(event: Events::preUpdate)] +final class SluggableEventSubscriber { /** * @var string @@ -50,14 +53,6 @@ public function preUpdate(LifecycleEventArgs $lifecycleEventArgs): void $this->processLifecycleEventArgs($lifecycleEventArgs); } - /** - * @return string[] - */ - public function getSubscribedEvents(): array - { - return [Events::loadClassMetadata, Events::prePersist, Events::preUpdate]; - } - private function shouldSkip(ClassMetadataInfo $classMetadataInfo): bool { if (! is_a($classMetadataInfo->getName(), SluggableInterface::class, true)) { diff --git a/src/EventSubscriber/SoftDeletableEventSubscriber.php b/src/EventSubscriber/SoftDeletableEventSubscriber.php index e8ba92e2..fa130930 100644 --- a/src/EventSubscriber/SoftDeletableEventSubscriber.php +++ b/src/EventSubscriber/SoftDeletableEventSubscriber.php @@ -4,13 +4,15 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; -use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; +use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Event\OnFlushEventArgs; use Doctrine\ORM\Events; use Knp\DoctrineBehaviors\Contract\Entity\SoftDeletableInterface; -final class SoftDeletableEventSubscriber implements EventSubscriberInterface +#[AsDoctrineListener(event: Events::loadClassMetadata)] +#[AsDoctrineListener(event: Events::onFlush)] +final class SoftDeletableEventSubscriber { /** * @var string @@ -62,11 +64,4 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataE ]); } - /** - * @return string[] - */ - public function getSubscribedEvents(): array - { - return [Events::onFlush, Events::loadClassMetadata]; - } } diff --git a/src/EventSubscriber/TimestampableEventSubscriber.php b/src/EventSubscriber/TimestampableEventSubscriber.php index 292e058b..51331fbb 100644 --- a/src/EventSubscriber/TimestampableEventSubscriber.php +++ b/src/EventSubscriber/TimestampableEventSubscriber.php @@ -4,12 +4,13 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; -use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; +use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Events; use Knp\DoctrineBehaviors\Contract\Entity\TimestampableInterface; -final class TimestampableEventSubscriber implements EventSubscriberInterface +#[AsDoctrineListener(event: Events::loadClassMetadata)] +final class TimestampableEventSubscriber { public function __construct( private string $timestampableDateFieldType @@ -46,11 +47,4 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataE } } - /** - * @return string[] - */ - public function getSubscribedEvents(): array - { - return [Events::loadClassMetadata]; - } } diff --git a/src/EventSubscriber/TranslatableEventSubscriber.php b/src/EventSubscriber/TranslatableEventSubscriber.php index 2df494de..b7cc3ad5 100644 --- a/src/EventSubscriber/TranslatableEventSubscriber.php +++ b/src/EventSubscriber/TranslatableEventSubscriber.php @@ -4,7 +4,7 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; -use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; +use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Events; @@ -15,7 +15,10 @@ use Knp\DoctrineBehaviors\Contract\Provider\LocaleProviderInterface; use ReflectionClass; -final class TranslatableEventSubscriber implements EventSubscriberInterface +#[AsDoctrineListener(event: Events::loadClassMetadata)] +#[AsDoctrineListener(event: Events::postLoad)] +#[AsDoctrineListener(event: Events::prePersist)] +final class TranslatableEventSubscriber { /** * @var string @@ -69,13 +72,7 @@ public function prePersist(LifecycleEventArgs $lifecycleEventArgs): void $this->setLocales($lifecycleEventArgs); } - /** - * @return string[] - */ - public function getSubscribedEvents(): array - { - return [Events::loadClassMetadata, Events::postLoad, Events::prePersist]; - } + /** * Convert string FETCH mode to required string diff --git a/src/EventSubscriber/TreeEventSubscriber.php b/src/EventSubscriber/TreeEventSubscriber.php index 15ea5595..8471eaa3 100644 --- a/src/EventSubscriber/TreeEventSubscriber.php +++ b/src/EventSubscriber/TreeEventSubscriber.php @@ -4,12 +4,13 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; -use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; +use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Events; use Knp\DoctrineBehaviors\Contract\Entity\TreeNodeInterface; -final class TreeEventSubscriber implements EventSubscriberInterface +#[AsDoctrineListener(event: Events::loadClassMetadata)] +final class TreeEventSubscriber { public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataEventArgs): void { @@ -33,12 +34,4 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataE 'length' => 255, ]); } - - /** - * @return string[] - */ - public function getSubscribedEvents(): array - { - return [Events::loadClassMetadata]; - } } diff --git a/src/EventSubscriber/UuidableEventSubscriber.php b/src/EventSubscriber/UuidableEventSubscriber.php index 525eb4dc..fe7b08a4 100644 --- a/src/EventSubscriber/UuidableEventSubscriber.php +++ b/src/EventSubscriber/UuidableEventSubscriber.php @@ -4,13 +4,15 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; -use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; +use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Events; use Knp\DoctrineBehaviors\Contract\Entity\UuidableInterface; -final class UuidableEventSubscriber implements EventSubscriberInterface +#[AsDoctrineListener(event: Events::loadClassMetadata)] +#[AsDoctrineListener(event: Events::prePersist)] +final class UuidableEventSubscriber { public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataEventArgs): void { @@ -44,12 +46,4 @@ public function prePersist(LifecycleEventArgs $lifecycleEventArgs): void $entity->generateUuid(); } - - /** - * @return string[] - */ - public function getSubscribedEvents(): array - { - return [Events::loadClassMetadata, Events::prePersist]; - } } From f98b9b55cbce2fd38fb89b4601b2d56c2e86a3f7 Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Tue, 8 Aug 2023 13:43:59 +0200 Subject: [PATCH 03/12] Update tests.yaml --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b536d238..d68c9ee5 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: shivammathur/setup-php@v1 + - uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} extensions: pdo_sqlite, pdo_mysql, pdo_pgsql From 99393acc801422be073d6d1d0d4a330deba87f5b Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Tue, 8 Aug 2023 13:48:14 +0200 Subject: [PATCH 04/12] Update linter.yaml --- .github/workflows/linter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linter.yaml b/.github/workflows/linter.yaml index f9cbe802..135730e4 100644 --- a/.github/workflows/linter.yaml +++ b/.github/workflows/linter.yaml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: shivammathur/setup-php@v1 + - uses: shivammathur/setup-php@v2 with: php-version: 8.0 extensions: pdo_sqlite, pdo_mysql, pdo_pgsql From 09bdf0102ab9203f78f2ce0976c7f8bf68f008fb Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Tue, 8 Aug 2023 13:48:32 +0200 Subject: [PATCH 05/12] Update code_checks.yaml --- .github/workflows/code_checks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code_checks.yaml b/.github/workflows/code_checks.yaml index edfab030..bcad9804 100644 --- a/.github/workflows/code_checks.yaml +++ b/.github/workflows/code_checks.yaml @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: shivammathur/setup-php@v1 + - uses: shivammathur/setup-php@v2 with: php-version: 8.0 extensions: pdo_sqlite, pdo_mysql, pdo_pgsql From 642160e2fec83a395eaef22a570f0d3113515dea Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Tue, 8 Aug 2023 14:16:39 +0200 Subject: [PATCH 06/12] Update composer.json Update rector/rector to fix error when running ``vendor/bin/rector process --dry-run --ansi`` PHP Fatal error: Uncaught _PHPStan_9a6ded56a\Nette\InvalidArgumentException: Missing parameter 'deprecationRulesInstalled'. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b80a8eb6..6ced1709 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "php-parallel-lint/php-parallel-lint": "^1.3", "phpstan/phpstan": "^1.7.10", "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.4", + "rector/rector": "^0.15.1", "symplify/easy-coding-standard": "^10.2.9", "symplify/phpstan-extensions": "^10.2.9", "phpstan/phpstan-doctrine": "^1.3", From 4cef745d0b9fff87ae8a9745212d48c92562d6ad Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Tue, 8 Aug 2023 14:28:49 +0200 Subject: [PATCH 07/12] Update rector.php Remove missing NetteSetList [ERROR] Class "Rector\Nette\Set\NetteSetList" not found --- rector.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/rector.php b/rector.php index 53b657ec..e2db68a2 100644 --- a/rector.php +++ b/rector.php @@ -5,7 +5,6 @@ use Rector\Config\RectorConfig; use Rector\Doctrine\Set\DoctrineSetList; use Rector\Naming\Rector\Class_\RenamePropertyToMatchTypeRector; -use Rector\Nette\Set\NetteSetList; use Rector\Php80\Rector\FunctionLike\UnionTypesRector; use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\SetList; @@ -31,7 +30,6 @@ SetList::DEAD_CODE, SetList::CODE_QUALITY, SetList::CODING_STYLE, - NetteSetList::NETTE_CODE_QUALITY, SetList::NAMING, LevelSetList::UP_TO_PHP_80, ]); From b971bbbac972be1377531c79ade788ad1d6373bc Mon Sep 17 00:00:00 2001 From: tlallement Date: Fri, 18 Aug 2023 11:12:39 +0200 Subject: [PATCH 08/12] Fix SF63 deprecations (security) --- composer.json | 1 + src/Provider/UserProvider.php | 5 +++-- src/Security/Security.php | 37 +++++++++++++++++++++++++++++++++++ tests/config/config_test.php | 2 +- 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 src/Security/Security.php diff --git a/composer.json b/composer.json index 6ced1709..0a558fa9 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,7 @@ "symfony/dependency-injection": "^5.4|^6.0", "symfony/http-kernel": "^5.4|^6.0", "symfony/security-core": "^5.4|^6.0", + "symfony/security-bundle": "^5.4|^6.0", "symfony/framework-bundle": "^5.4|^6.0", "symfony/string": "^5.4|^6.0", "symfony/translation-contracts": "^2.4|^3.0", diff --git a/src/Provider/UserProvider.php b/src/Provider/UserProvider.php index 5811cabd..02cc761f 100644 --- a/src/Provider/UserProvider.php +++ b/src/Provider/UserProvider.php @@ -4,8 +4,9 @@ namespace Knp\DoctrineBehaviors\Provider; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Knp\DoctrineBehaviors\Contract\Provider\UserProviderInterface; -use Symfony\Component\Security\Core\Security; +use Knp\DoctrineBehaviors\Security\Security; final class UserProvider implements UserProviderInterface { @@ -18,7 +19,7 @@ public function __construct( public function provideUser() { $token = $this->security->getToken(); - if ($token !== null) { + if ($token instanceof TokenInterface) { $user = $token->getUser(); if ($this->blameableUserEntity) { if ($user instanceof $this->blameableUserEntity) { diff --git a/src/Security/Security.php b/src/Security/Security.php new file mode 100644 index 00000000..c4d63ba2 --- /dev/null +++ b/src/Security/Security.php @@ -0,0 +1,37 @@ +security->getToken(); + } + } +} elseif (class_exists(SecurityCore::class)) { + final class Security { + public function __construct( + private SecurityCore $security, + ) { + } + + public function getToken(): ?TokenInterface + { + return $this->security->getToken(); + } + } +} else { + throw new \LogicException(sprintf('You cannot use "%s" because either the Symfony Security Bundle or Symfony Security Core is not installed. If you use Symfony 6.2+, try running "composer require symfony/security-bundle", otherwise run "composer require symfony/security-core".', __CLASS__)); +} diff --git a/tests/config/config_test.php b/tests/config/config_test.php index 7a20bf2e..f1a93ed1 100644 --- a/tests/config/config_test.php +++ b/tests/config/config_test.php @@ -8,9 +8,9 @@ use Knp\DoctrineBehaviors\Tests\DatabaseLoader; use Knp\DoctrineBehaviors\Tests\Provider\TestLocaleProvider; use Knp\DoctrineBehaviors\Tests\Provider\TestUserProvider; +use Knp\DoctrineBehaviors\Security\Security; use Psr\Log\Test\TestLogger; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -use Symfony\Component\Security\Core\Security; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; return static function (ContainerConfigurator $containerConfigurator): void { From 049a8493e9195bc4d344aa5c6b7c50596829d539 Mon Sep 17 00:00:00 2001 From: tlallement Date: Fri, 18 Aug 2023 12:27:12 +0200 Subject: [PATCH 09/12] CS Fixes --- src/Security/Security.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Security/Security.php b/src/Security/Security.php index c4d63ba2..0b82114f 100644 --- a/src/Security/Security.php +++ b/src/Security/Security.php @@ -8,8 +8,10 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Security as SecurityCore; -if (class_exists(SecurityBundle::class)) { - final class Security { +if (class_exists(SecurityBundle::class)) +{ + final class Security + { public function __construct( private SecurityBundle $security, ) { @@ -20,7 +22,8 @@ public function getToken(): ?TokenInterface return $this->security->getToken(); } } -} elseif (class_exists(SecurityCore::class)) { +} elseif (class_exists(SecurityCore::class)) +{ final class Security { public function __construct( private SecurityCore $security, @@ -33,5 +36,8 @@ public function getToken(): ?TokenInterface } } } else { - throw new \LogicException(sprintf('You cannot use "%s" because either the Symfony Security Bundle or Symfony Security Core is not installed. If you use Symfony 6.2+, try running "composer require symfony/security-bundle", otherwise run "composer require symfony/security-core".', __CLASS__)); + throw new \LogicException(sprintf( + 'You cannot use "%s" because either the Symfony Security Bundle or Symfony Security Core is not installed. If you use Symfony 6.2+, try running "composer require symfony/security-bundle", otherwise run "composer require symfony/security-core".', + __CLASS__ + )); } From d384f1572f4aad7e0086b556ab96596309868c2f Mon Sep 17 00:00:00 2001 From: tlallement Date: Fri, 18 Aug 2023 12:27:32 +0200 Subject: [PATCH 10/12] Fix tests --- tests/config/config_test.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/config/config_test.php b/tests/config/config_test.php index f1a93ed1..600d2721 100644 --- a/tests/config/config_test.php +++ b/tests/config/config_test.php @@ -2,13 +2,13 @@ declare(strict_types=1); +use Doctrine\ORM\EntityManagerInterface; use Knp\DoctrineBehaviors\Contract\Provider\LocaleProviderInterface; use Knp\DoctrineBehaviors\Contract\Provider\UserProviderInterface; use Knp\DoctrineBehaviors\EventSubscriber\LoggableEventSubscriber; use Knp\DoctrineBehaviors\Tests\DatabaseLoader; use Knp\DoctrineBehaviors\Tests\Provider\TestLocaleProvider; use Knp\DoctrineBehaviors\Tests\Provider\TestUserProvider; -use Knp\DoctrineBehaviors\Security\Security; use Psr\Log\Test\TestLogger; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; @@ -32,8 +32,14 @@ ->autowire() ->autoconfigure(); - $services->set(Security::class) - ->arg('$container', service('service_container')); + if (class_exists(Symfony\Bundle\SecurityBundle\Security::class)) { + $services->set(Symfony\Bundle\SecurityBundle\Security::class) + ->arg('$container', service('service_container')); + } + if (class_exists(Symfony\Component\Security\Core\Security::class)) { + $services->set(Symfony\Component\Security\Core\Security::class) + ->arg('$container', service('service_container')); + } $services->set(TestLogger::class); @@ -46,6 +52,7 @@ $services->set(DatabaseLoader::class); $services->set(LoggableEventSubscriber::class) + ->arg('$entityManager', service(EntityManagerInterface::class)) ->arg('$logger', service(TestLogger::class)); $containerConfigurator->extension('doctrine', [ From 87c4df69259dd1261b67176408b203ee42b62213 Mon Sep 17 00:00:00 2001 From: tlallement Date: Fri, 18 Aug 2023 12:51:06 +0200 Subject: [PATCH 11/12] Fix deprecations for Doctrine ORM 3 --- .../BlameableEventSubscriber.php | 14 +++++------ .../LoggableEventSubscriber.php | 25 ++++++++++--------- .../SluggableEventSubscriber.php | 10 ++++---- .../SoftDeletableEventSubscriber.php | 12 ++++++--- .../TimestampableEventSubscriber.php | 1 - .../TranslatableEventSubscriber.php | 10 ++++---- .../UuidableEventSubscriber.php | 6 ++--- 7 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/EventSubscriber/BlameableEventSubscriber.php b/src/EventSubscriber/BlameableEventSubscriber.php index edd11f2a..f85b6a11 100644 --- a/src/EventSubscriber/BlameableEventSubscriber.php +++ b/src/EventSubscriber/BlameableEventSubscriber.php @@ -6,11 +6,11 @@ use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Events; use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\UnitOfWork; +use Doctrine\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs; use Knp\DoctrineBehaviors\Contract\Entity\BlameableInterface; use Knp\DoctrineBehaviors\Contract\Provider\UserProviderInterface; @@ -63,9 +63,9 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataE /** * Stores the current user into createdBy and updatedBy properties */ - public function prePersist(LifecycleEventArgs $lifecycleEventArgs): void + public function prePersist(BaseLifecycleEventArgs $lifecycleEventArgs): void { - $entity = $lifecycleEventArgs->getEntity(); + $entity = $lifecycleEventArgs->getObject(); if (! $entity instanceof BlameableInterface) { return; } @@ -94,9 +94,9 @@ public function prePersist(LifecycleEventArgs $lifecycleEventArgs): void /** * Stores the current user into updatedBy property */ - public function preUpdate(LifecycleEventArgs $lifecycleEventArgs): void + public function preUpdate(BaseLifecycleEventArgs $lifecycleEventArgs): void { - $entity = $lifecycleEventArgs->getEntity(); + $entity = $lifecycleEventArgs->getObject(); if (! $entity instanceof BlameableInterface) { return; } @@ -116,9 +116,9 @@ public function preUpdate(LifecycleEventArgs $lifecycleEventArgs): void /** * Stores the current user into deletedBy property */ - public function preRemove(LifecycleEventArgs $lifecycleEventArgs): void + public function preRemove(BaseLifecycleEventArgs $lifecycleEventArgs): void { - $entity = $lifecycleEventArgs->getEntity(); + $entity = $lifecycleEventArgs->getObject(); if (! $entity instanceof BlameableInterface) { return; } diff --git a/src/EventSubscriber/LoggableEventSubscriber.php b/src/EventSubscriber/LoggableEventSubscriber.php index 68fd62ab..d29a934f 100644 --- a/src/EventSubscriber/LoggableEventSubscriber.php +++ b/src/EventSubscriber/LoggableEventSubscriber.php @@ -5,8 +5,9 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; -use Doctrine\ORM\Event\LifecycleEventArgs; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Events; +use Doctrine\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs; use Knp\DoctrineBehaviors\Contract\Entity\LoggableInterface; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; @@ -17,13 +18,14 @@ final class LoggableEventSubscriber { public function __construct( + private EntityManagerInterface $entityManager, private LoggerInterface $logger ) { } - public function postPersist(LifecycleEventArgs $lifecycleEventArgs): void + public function postPersist(BaseLifecycleEventArgs $lifecycleEventArgs): void { - $entity = $lifecycleEventArgs->getEntity(); + $entity = $lifecycleEventArgs->getObject(); if (! $entity instanceof LoggableInterface) { return; } @@ -34,9 +36,9 @@ public function postPersist(LifecycleEventArgs $lifecycleEventArgs): void $this->logChangeSet($lifecycleEventArgs); } - public function postUpdate(LifecycleEventArgs $lifecycleEventArgs): void + public function postUpdate(BaseLifecycleEventArgs $lifecycleEventArgs): void { - $entity = $lifecycleEventArgs->getEntity(); + $entity = $lifecycleEventArgs->getObject(); if (! $entity instanceof LoggableInterface) { return; } @@ -44,9 +46,9 @@ public function postUpdate(LifecycleEventArgs $lifecycleEventArgs): void $this->logChangeSet($lifecycleEventArgs); } - public function preRemove(LifecycleEventArgs $lifecycleEventArgs): void + public function preRemove(BaseLifecycleEventArgs $lifecycleEventArgs): void { - $entity = $lifecycleEventArgs->getEntity(); + $entity = $lifecycleEventArgs->getObject(); if ($entity instanceof LoggableInterface) { $this->logger->log(LogLevel::INFO, $entity->getRemoveLogMessage()); @@ -56,14 +58,13 @@ public function preRemove(LifecycleEventArgs $lifecycleEventArgs): void /** * Logs entity changeset */ - private function logChangeSet(LifecycleEventArgs $lifecycleEventArgs): void + private function logChangeSet(BaseLifecycleEventArgs $lifecycleEventArgs): void { - $entityManager = $lifecycleEventArgs->getEntityManager(); - $unitOfWork = $entityManager->getUnitOfWork(); - $entity = $lifecycleEventArgs->getEntity(); + $unitOfWork = $this->entityManager->getUnitOfWork(); + $entity = $lifecycleEventArgs->getObject(); $entityClass = $entity::class; - $classMetadata = $entityManager->getClassMetadata($entityClass); + $classMetadata = $this->entityManager->getClassMetadata($entityClass); /** @var LoggableInterface $entity */ $unitOfWork->computeChangeSet($classMetadata, $entity); diff --git a/src/EventSubscriber/SluggableEventSubscriber.php b/src/EventSubscriber/SluggableEventSubscriber.php index 41ffdab6..34de26bc 100644 --- a/src/EventSubscriber/SluggableEventSubscriber.php +++ b/src/EventSubscriber/SluggableEventSubscriber.php @@ -6,10 +6,10 @@ use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Events; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs; use Knp\DoctrineBehaviors\Contract\Entity\SluggableInterface; use Knp\DoctrineBehaviors\Repository\DefaultSluggableRepository; @@ -43,12 +43,12 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataE ]); } - public function prePersist(LifecycleEventArgs $lifecycleEventArgs): void + public function prePersist(BaseLifecycleEventArgs $lifecycleEventArgs): void { $this->processLifecycleEventArgs($lifecycleEventArgs); } - public function preUpdate(LifecycleEventArgs $lifecycleEventArgs): void + public function preUpdate(BaseLifecycleEventArgs $lifecycleEventArgs): void { $this->processLifecycleEventArgs($lifecycleEventArgs); } @@ -62,9 +62,9 @@ private function shouldSkip(ClassMetadataInfo $classMetadataInfo): bool return $classMetadataInfo->hasField(self::SLUG); } - private function processLifecycleEventArgs(LifecycleEventArgs $lifecycleEventArgs): void + private function processLifecycleEventArgs(BaseLifecycleEventArgs $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 fa130930..37b9c552 100644 --- a/src/EventSubscriber/SoftDeletableEventSubscriber.php +++ b/src/EventSubscriber/SoftDeletableEventSubscriber.php @@ -5,6 +5,7 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Event\OnFlushEventArgs; use Doctrine\ORM\Events; @@ -14,6 +15,11 @@ #[AsDoctrineListener(event: Events::onFlush)] final class SoftDeletableEventSubscriber { + public function __construct( + private EntityManagerInterface $entityManager, + ) { + } + /** * @var string */ @@ -21,8 +27,7 @@ final class SoftDeletableEventSubscriber public function onFlush(OnFlushEventArgs $onFlushEventArgs): void { - $entityManager = $onFlushEventArgs->getEntityManager(); - $unitOfWork = $entityManager->getUnitOfWork(); + $unitOfWork = $this->entityManager->getUnitOfWork(); foreach ($unitOfWork->getScheduledEntityDeletions() as $entity) { if (! $entity instanceof SoftDeletableInterface) { @@ -32,7 +37,7 @@ public function onFlush(OnFlushEventArgs $onFlushEventArgs): void $oldValue = $entity->getDeletedAt(); $entity->delete(); - $entityManager->persist($entity); + $this->entityManager->persist($entity); $unitOfWork->propertyChanged($entity, self::DELETED_AT, $oldValue, $entity->getDeletedAt()); $unitOfWork->scheduleExtraUpdate($entity, [ @@ -63,5 +68,4 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataE 'nullable' => true, ]); } - } diff --git a/src/EventSubscriber/TimestampableEventSubscriber.php b/src/EventSubscriber/TimestampableEventSubscriber.php index 51331fbb..d39bb3a7 100644 --- a/src/EventSubscriber/TimestampableEventSubscriber.php +++ b/src/EventSubscriber/TimestampableEventSubscriber.php @@ -46,5 +46,4 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataE } } } - } diff --git a/src/EventSubscriber/TranslatableEventSubscriber.php b/src/EventSubscriber/TranslatableEventSubscriber.php index b7cc3ad5..a55b68da 100644 --- a/src/EventSubscriber/TranslatableEventSubscriber.php +++ b/src/EventSubscriber/TranslatableEventSubscriber.php @@ -5,10 +5,10 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; -use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Events; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs; use Doctrine\Persistence\ObjectManager; use Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface; use Knp\DoctrineBehaviors\Contract\Entity\TranslationInterface; @@ -62,12 +62,12 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataE } } - public function postLoad(LifecycleEventArgs $lifecycleEventArgs): void + public function postLoad(BaseLifecycleEventArgs $lifecycleEventArgs): void { $this->setLocales($lifecycleEventArgs); } - public function prePersist(LifecycleEventArgs $lifecycleEventArgs): void + public function prePersist(BaseLifecycleEventArgs $lifecycleEventArgs): void { $this->setLocales($lifecycleEventArgs); } @@ -156,9 +156,9 @@ private function mapTranslation(ClassMetadataInfo $classMetadataInfo, ObjectMana } } - private function setLocales(LifecycleEventArgs $lifecycleEventArgs): void + private function setLocales(BaseLifecycleEventArgs $lifecycleEventArgs): void { - $entity = $lifecycleEventArgs->getEntity(); + $entity = $lifecycleEventArgs->getObject(); if (! $entity instanceof TranslatableInterface) { return; } diff --git a/src/EventSubscriber/UuidableEventSubscriber.php b/src/EventSubscriber/UuidableEventSubscriber.php index fe7b08a4..49f30336 100644 --- a/src/EventSubscriber/UuidableEventSubscriber.php +++ b/src/EventSubscriber/UuidableEventSubscriber.php @@ -5,9 +5,9 @@ namespace Knp\DoctrineBehaviors\EventSubscriber; use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; -use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Events; +use Doctrine\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs; use Knp\DoctrineBehaviors\Contract\Entity\UuidableInterface; #[AsDoctrineListener(event: Events::loadClassMetadata)] @@ -37,9 +37,9 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataE ]); } - public function prePersist(LifecycleEventArgs $lifecycleEventArgs): void + public function prePersist(BaseLifecycleEventArgs $lifecycleEventArgs): void { - $entity = $lifecycleEventArgs->getEntity(); + $entity = $lifecycleEventArgs->getObject(); if (! $entity instanceof UuidableInterface) { return; } From 6171a43b9e3d6b7675301cc86e91be3b5aedbb14 Mon Sep 17 00:00:00 2001 From: Hector Date: Tue, 24 Oct 2023 16:23:35 +0200 Subject: [PATCH 12/12] Fixed referencedColumnName value to be able to use values with Embedded attributes --- .../TranslatableEventSubscriber.php | 4 +- .../Entity/TranslatableEmbeddableUuid.php | 28 ++++++++++++ .../TranslatableEmbeddedIdentifierEntity.php | 38 ++++++++++++++++ ...bleEmbeddedIdentifierEntityTranslation.php | 43 +++++++++++++++++++ tests/ORM/Translatable/TranslatableTest.php | 22 ++++++++++ 5 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 tests/Fixtures/Entity/TranslatableEmbeddableUuid.php create mode 100644 tests/Fixtures/Entity/TranslatableEmbeddedIdentifierEntity.php create mode 100644 tests/Fixtures/Entity/TranslatableEmbeddedIdentifierEntityTranslation.php diff --git a/src/EventSubscriber/TranslatableEventSubscriber.php b/src/EventSubscriber/TranslatableEventSubscriber.php index a55b68da..c37fd379 100644 --- a/src/EventSubscriber/TranslatableEventSubscriber.php +++ b/src/EventSubscriber/TranslatableEventSubscriber.php @@ -123,7 +123,7 @@ private function mapTranslation(ClassMetadataInfo $classMetadataInfo, ObjectMana /** @var ClassMetadataInfo $classMetadata */ $classMetadata = $objectManager->getClassMetadata($targetEntity); - $singleIdentifierFieldName = $classMetadata->getSingleIdentifierFieldName(); + $singleIdentifierColumnName = $classMetadata->getSingleIdentifierColumnName(); $classMetadataInfo->mapManyToOne([ 'fieldName' => 'translatable', @@ -132,7 +132,7 @@ private function mapTranslation(ClassMetadataInfo $classMetadataInfo, ObjectMana 'fetch' => $this->translationFetchMode, 'joinColumns' => [[ 'name' => 'translatable_id', - 'referencedColumnName' => $singleIdentifierFieldName, + 'referencedColumnName' => $singleIdentifierColumnName, 'onDelete' => 'CASCADE', ]], 'targetEntity' => $targetEntity, diff --git a/tests/Fixtures/Entity/TranslatableEmbeddableUuid.php b/tests/Fixtures/Entity/TranslatableEmbeddableUuid.php new file mode 100644 index 00000000..a6ce131e --- /dev/null +++ b/tests/Fixtures/Entity/TranslatableEmbeddableUuid.php @@ -0,0 +1,28 @@ +value = $value; + } + + public static function random(): self + { + return new self(Uuid::uuid4()->toString()); + } +} \ No newline at end of file diff --git a/tests/Fixtures/Entity/TranslatableEmbeddedIdentifierEntity.php b/tests/Fixtures/Entity/TranslatableEmbeddedIdentifierEntity.php new file mode 100644 index 00000000..20e2324f --- /dev/null +++ b/tests/Fixtures/Entity/TranslatableEmbeddedIdentifierEntity.php @@ -0,0 +1,38 @@ +uuid = TranslatableEmbeddableUuid::random(); + } + + /** + * @param mixed[] $arguments + * @return mixed + */ + public function __call(string $method, array $arguments) + { + return $this->proxyCurrentLocaleTranslation($method, $arguments); + } + + public function getUuid(): TranslatableEmbeddableUuid + { + return $this->uuid; + } +} diff --git a/tests/Fixtures/Entity/TranslatableEmbeddedIdentifierEntityTranslation.php b/tests/Fixtures/Entity/TranslatableEmbeddedIdentifierEntityTranslation.php new file mode 100644 index 00000000..8dc69a02 --- /dev/null +++ b/tests/Fixtures/Entity/TranslatableEmbeddedIdentifierEntityTranslation.php @@ -0,0 +1,43 @@ +uuid = TranslatableEmbeddableUuid::random(); + } + + public function getUuid(): TranslatableEmbeddableUuid + { + return $this->uuid; + } + + public function getTitle(): ?string + { + return $this->title; + } + + public function setTitle(string $title): void + { + $this->title = $title; + } +} diff --git a/tests/ORM/Translatable/TranslatableTest.php b/tests/ORM/Translatable/TranslatableTest.php index 90d0b7d9..e46b574a 100644 --- a/tests/ORM/Translatable/TranslatableTest.php +++ b/tests/ORM/Translatable/TranslatableTest.php @@ -12,6 +12,7 @@ use Knp\DoctrineBehaviors\Tests\Fixtures\Contract\Translatable\TranslatableEntityWithCustomInterface; use Knp\DoctrineBehaviors\Tests\Fixtures\Entity\TranslatableCustomIdentifierEntity; use Knp\DoctrineBehaviors\Tests\Fixtures\Entity\TranslatableCustomizedEntity; +use Knp\DoctrineBehaviors\Tests\Fixtures\Entity\TranslatableEmbeddedIdentifierEntity; use Knp\DoctrineBehaviors\Tests\Fixtures\Entity\TranslatableEntity; use Knp\DoctrineBehaviors\Tests\Fixtures\Entity\TranslatableEntityTranslation; use Knp\DoctrineBehaviors\Tests\Fixtures\Entity\Translation\TranslatableCustomizedEntityTranslation; @@ -76,6 +77,27 @@ public function testShouldPersistWithCustomIdentifier(): void $this->assertSame('awesome', $translatableEntity->translate('en')->getTitle()); } + public function testShouldPersistWithEmbeddedIdentifier(): void + { + $translatableEntity = new TranslatableEmbeddedIdentifierEntity(); + $translatableEntity->translate('en') + ->setTitle('awesome'); + $translatableEntity->mergeNewTranslations(); + + $this->entityManager->persist($translatableEntity); + $this->entityManager->flush(); + + $uuid = $translatableEntity->getUuid(); + $this->entityManager->clear(); + + /** @var TranslatableEntity $translatableEntity */ + $translatableEntity = $this->entityManager->getRepository(TranslatableEmbeddedIdentifierEntity::class)->find( + $uuid + ); + + $this->assertSame('awesome', $translatableEntity->translate('en')->getTitle()); + } + public function testShouldFallbackCountryLocaleToLanguageOnlyTranslation(): void { $translatableEntity = new TranslatableEntity();