Repository: doctrine-extensions/DoctrineExtensions (PHP)

Issue:
SoftDeleteable dedicated events eventargs

Hello,

in doctrine 3, the class **Doctrine\ORM\Event\LifecycleEventArgs** will be removed, and so dedicated classes of events should be used instead (_PrePersistEventArgs, PostPersistEventArgs, PostUpdateEventArgs, ..._),

which means the function **createLifecycleEventArgsInstance** in the **Gedmo\Mapping\Event\Adapter\ORM** will be invalid to use which create an instance of the **class Doctrine\ORM\Event\LifecycleEventArgs**

i think there should be dedicated events eventargs for the _PRE_SOFT_DELETE_ and _POST_SOFT_DELETE_ events for both ORM and ODM

i implemented those points in my [fork](https://github.com/yassinefikri/DoctrineExtensions/commit/0fad774cf71df23f742c2da7d982b1d9fb9ae92a)
and would like to open a pull request, and of course, open to suggestions

currenty on doctrine 2, the ORM dedicated eventargs i added extends the **Doctrine\ORM\Event\LifecycleEventArgs**, in doctrine 3 they should extend the **Doctrine\Persistence\Event\LifecycleEventArgs** instead



Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 334d691212..2a9702e5ba 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,15 @@ a release.
 ---
 
 ## [Unreleased]
+### Added
+- SoftDeleteable: `Gedmo\SoftDeleteable\Event\PreSoftDeleteEventArgs` and
+  `Gedmo\SoftDeleteable\Event\PostSoftDeleteEventArgs` classes.
+
+### Deprecated
+- Do not add type-hinted parameters `Gedmo\SoftDeleteable\Event\PreSoftDeleteEventArgs` and
+  `Gedmo\SoftDeleteable\Event\PostSoftDeleteEventArgs` classes to `preSoftDelete` and `postSoftDelete` events.
+- The `createLifecycleEventArgsInstance()` method on `Gedmo\Mapping\Event\AdapterInterface`
+  implementations is deprecated, use your own subclass of `Doctrine\Persistence\Event\LifecycleEventArgs` as needed.
 
 ## [3.14.0]
 ### Added
@@ -31,7 +40,7 @@ a release.
 
 ### Deprecated
 - Calling `Gedmo\Mapping\Event\Adapter\ORM::getObjectManager()` and `getObject()` on EventArgs that do not implement `getObjectManager()` and `getObject()` (such as old EventArgs implementing `getEntityManager()` and `getEntity()`) 
-- Calling `Gedmo\Uploadable\Event\UploadableBaseEventArgs::getEntityManager()` and `getEntity()`. Call `getObjectManager()` and `getObject()` instead. 
+- Calling `Gedmo\Uploadable\Event\UploadableBaseEventArgs::getEntityManager()` and `getEntity()`. Call `getObjectManager()` and `getObject()` instead.
 
 ## [3.13.0] - 2023-09-06
 ### Fixed
diff --git a/rector.php b/rector.php
index aad132431a..2803e9f705 100644
--- a/rector.php
+++ b/rector.php
@@ -10,7 +10,6 @@
  */
 
 use Rector\Config\RectorConfig;
-use Rector\Php71\Rector\FuncCall\CountOnNullRector;
 use Rector\Set\ValueObject\LevelSetList;
 use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector;
 
@@ -33,7 +32,4 @@
 
     $rectorConfig->importNames();
     $rectorConfig->importShortClasses(false);
-    $rectorConfig->skip([
-        CountOnNullRector::class,
-    ]);
 };
diff --git a/src/Mapping/Event/Adapter/ODM.php b/src/Mapping/Event/Adapter/ODM.php
index f90ee5417b..b333b6f06f 100644
--- a/src/Mapping/Event/Adapter/ODM.php
+++ b/src/Mapping/Event/Adapter/ODM.php
@@ -150,6 +150,8 @@ public function clearObjectChangeSet($uow, $object)
     }
 
     /**
+     * @deprecated to be removed in 4.0, use custom lifecycle event classes instead.
+     *
      * Creates a ODM specific LifecycleEventArgs.
      *
      * @param object          $document
@@ -159,6 +161,11 @@ public function clearObjectChangeSet($uow, $object)
      */
     public function createLifecycleEventArgsInstance($document, $documentManager)
     {
+        @trigger_error(sprintf(
+            'Using "%s()" method is deprecated since gedmo/doctrine-extensions 3.15 and will be removed in version 4.0.',
+            __METHOD__
+        ), E_USER_DEPRECATED);
+
         return new LifecycleEventArgs($document, $documentManager);
     }
 }
diff --git a/src/Mapping/Event/Adapter/ORM.php b/src/Mapping/Event/Adapter/ORM.php
index 55c834167a..1c1ddadd02 100644
--- a/src/Mapping/Event/Adapter/ORM.php
+++ b/src/Mapping/Event/Adapter/ORM.php
@@ -180,15 +180,26 @@ public function clearObjectChangeSet($uow, $object)
     }
 
     /**
-     * Creates a ORM specific LifecycleEventArgs.
+     * @deprecated use custom lifecycle event classes instead
      *
-     * @param object                 $document
+     * Creates an ORM specific LifecycleEventArgs
+     *
+     * @param object                 $object
      * @param EntityManagerInterface $entityManager
      *
      * @return LifecycleEventArgs
      */
-    public function createLifecycleEventArgsInstance($document, $entityManager)
+    public function createLifecycleEventArgsInstance($object, $entityManager)
     {
-        return new LifecycleEventArgs($document, $entityManager);
+        @trigger_error(sprintf(
+            'Using "%s()" method is deprecated since gedmo/doctrine-extensions 3.15 and will be removed in version 4.0.',
+            __METHOD__
+        ), E_USER_DEPRECATED);
+
+        if (!class_exists(LifecycleEventArgs::class)) {
+            throw new \RuntimeException(sprintf('Cannot call %s() when using doctrine/orm >=3.0, use a custom lifecycle event class instead.', __METHOD__));
+        }
+
+        return new LifecycleEventArgs($object, $entityManager);
     }
 }
diff --git a/src/Mapping/Event/AdapterInterface.php b/src/Mapping/Event/AdapterInterface.php
index 0fc8bc6fa3..339a54f3ea 100644
--- a/src/Mapping/Event/AdapterInterface.php
+++ b/src/Mapping/Event/AdapterInterface.php
@@ -21,7 +21,7 @@
  *
  * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  *
- * @method LifecycleEventArgs createLifecycleEventArgsInstance(object $object, ObjectManager $manager)
+ * @method LifecycleEventArgs createLifecycleEventArgsInstance(object $object, ObjectManager $manager) @deprecated
  * @method object             getObject()
  */
 interface AdapterInterface
diff --git a/src/SoftDeleteable/Event/PostSoftDeleteEventArgs.php b/src/SoftDeleteable/Event/PostSoftDeleteEventArgs.php
new file mode 100644
index 0000000000..f8a41338b2
--- /dev/null
+++ b/src/SoftDeleteable/Event/PostSoftDeleteEventArgs.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the Doctrine Behavioral Extensions package.
+ * (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Gedmo\SoftDeleteable\Event;
+
+use Doctrine\Persistence\Event\LifecycleEventArgs;
+use Doctrine\Persistence\ObjectManager;
+
+/**
+ * @template TObjectManager of ObjectManager
+ *
+ * @template-extends LifecycleEventArgs<TObjectManager>
+ */
+final class PostSoftDeleteEventArgs extends LifecycleEventArgs
+{
+}
diff --git a/src/SoftDeleteable/Event/PreSoftDeleteEventArgs.php b/src/SoftDeleteable/Event/PreSoftDeleteEventArgs.php
new file mode 100644
index 0000000000..e01cd73d86
--- /dev/null
+++ b/src/SoftDeleteable/Event/PreSoftDeleteEventArgs.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the Doctrine Behavioral Extensions package.
+ * (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Gedmo\SoftDeleteable\Event;
+
+use Doctrine\Persistence\Event\LifecycleEventArgs;
+use Doctrine\Persistence\ObjectManager;
+
+/**
+ * @template TObjectManager of ObjectManager
+ *
+ * @template-extends LifecycleEventArgs<TObjectManager>
+ */
+final class PreSoftDeleteEventArgs extends LifecycleEventArgs
+{
+}
diff --git a/src/SoftDeleteable/SoftDeleteableListener.php b/src/SoftDeleteable/SoftDeleteableListener.php
index 6bf17e9ccb..eae0260eb9 100644
--- a/src/SoftDeleteable/SoftDeleteableListener.php
+++ b/src/SoftDeleteable/SoftDeleteableListener.php
@@ -10,6 +10,7 @@
 namespace Gedmo\SoftDeleteable;
 
 use Doctrine\Common\EventArgs;
+use Doctrine\Common\EventManager;
 use Doctrine\ODM\MongoDB\DocumentManager;
 use Doctrine\ODM\MongoDB\UnitOfWork as MongoDBUnitOfWork;
 use Doctrine\ORM\EntityManagerInterface;
@@ -17,6 +18,8 @@
 use Doctrine\Persistence\Mapping\ClassMetadata;
 use Doctrine\Persistence\ObjectManager;
 use Gedmo\Mapping\MappedEventSubscriber;
+use Gedmo\SoftDeleteable\Event\PostSoftDeleteEventArgs;
+use Gedmo\SoftDeleteable\Event\PreSoftDeleteEventArgs;
 
 /**
  * SoftDeleteable listener
@@ -81,10 +84,17 @@ public function onFlush(EventArgs $args)
                     continue; // want to hard delete
                 }
 
-                $evm->dispatchEvent(
-                    self::PRE_SOFT_DELETE,
-                    $ea->createLifecycleEventArgsInstance($object, $om)
-                );
+                if ($evm->hasListeners(self::PRE_SOFT_DELETE)) {
+                    // @todo: in the next major remove check and only instantiate the event
+                    $preSoftDeleteEventArgs = $this->hasToDispatchNewEvent($evm, self::PRE_SOFT_DELETE, PreSoftDeleteEventArgs::class)
+                        ? new PreSoftDeleteEventArgs($object, $om)
+                        : $ea->createLifecycleEventArgsInstance($object, $om);
+
+                    $evm->dispatchEvent(
+                        self::PRE_SOFT_DELETE,
+                        $preSoftDeleteEventArgs
+                    );
+                }
 
                 $reflProp->setValue($object, $date);
 
@@ -98,10 +108,17 @@ public function onFlush(EventArgs $args)
                     ]);
                 }
 
-                $evm->dispatchEvent(
-                    self::POST_SOFT_DELETE,
-                    $ea->createLifecycleEventArgsInstance($object, $om)
-                );
+                if ($evm->hasListeners(self::POST_SOFT_DELETE)) {
+                    // @todo: in the next major remove check and only instantiate the event
+                    $postSoftDeleteEventArgs = $this->hasToDispatchNewEvent($evm, self::POST_SOFT_DELETE, PostSoftDeleteEventArgs::class)
+                        ? new PostSoftDeleteEventArgs($object, $om)
+                        : $ea->createLifecycleEventArgsInstance($object, $om);
+
+                    $evm->dispatchEvent(
+                        self::POST_SOFT_DELETE,
+                        $postSoftDeleteEventArgs
+                    );
+                }
             }
         }
     }
@@ -124,4 +141,32 @@ protected function getNamespace()
     {
         return __NAMESPACE__;
     }
+
+    /** @param class-string $eventClass */
+    private function hasToDispatchNewEvent(EventManager $eventManager, string $eventName, string $eventClass): bool
+    {
+        foreach ($eventManager->getListeners($eventName) as $listener) {
+            $reflMethod = new \ReflectionMethod($listener, $eventName);
+
+            $parameters = $reflMethod->getParameters();
+
+            if (
+                1 !== count($parameters)
+                || !$parameters[0]->hasType()
+                || !$parameters[0]->getType() instanceof \ReflectionNamedType
+                || $eventClass !== $parameters[0]->getType()->getName()
+            ) {
+                @trigger_error(sprintf(
+                    'Type-hinting to something different than "%s" in "%s::%s()" is deprecated.',
+                    $eventClass,
+                    get_class($listener),
+                    $reflMethod->getName()
+                ), E_USER_DEPRECATED);
+
+                return false;
+            }
+        }
+
+        return true;
+    }
 }


Test patch:
diff --git a/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithLifecycleEventArgsFromODMTypeListener.php b/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithLifecycleEventArgsFromODMTypeListener.php
new file mode 100644
index 0000000000..fdc592d810
--- /dev/null
+++ b/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithLifecycleEventArgsFromODMTypeListener.php
@@ -0,0 +1,35 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the Doctrine Behavioral Extensions package.
+ * (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Gedmo\Tests\SoftDeleteable\Fixture\Listener;
+
+use Doctrine\Common\EventSubscriber;
+use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs;
+use Gedmo\SoftDeleteable\SoftDeleteableListener;
+
+final class WithLifecycleEventArgsFromODMTypeListener implements EventSubscriber
+{
+    public function preSoftDelete(LifecycleEventArgs $args): void
+    {
+    }
+
+    public function postSoftDelete(LifecycleEventArgs $args): void
+    {
+    }
+
+    public function getSubscribedEvents(): array
+    {
+        return [
+            SoftDeleteableListener::PRE_SOFT_DELETE,
+            SoftDeleteableListener::POST_SOFT_DELETE,
+        ];
+    }
+}
diff --git a/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithLifecycleEventArgsFromORMTypeListener.php b/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithLifecycleEventArgsFromORMTypeListener.php
new file mode 100644
index 0000000000..5d936b7d5f
--- /dev/null
+++ b/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithLifecycleEventArgsFromORMTypeListener.php
@@ -0,0 +1,35 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the Doctrine Behavioral Extensions package.
+ * (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Gedmo\Tests\SoftDeleteable\Fixture\Listener;
+
+use Doctrine\Common\EventSubscriber;
+use Doctrine\ORM\Event\LifecycleEventArgs;
+use Gedmo\SoftDeleteable\SoftDeleteableListener;
+
+final class WithLifecycleEventArgsFromORMTypeListener implements EventSubscriber
+{
+    public function preSoftDelete(LifecycleEventArgs $args): void
+    {
+    }
+
+    public function postSoftDelete(LifecycleEventArgs $args): void
+    {
+    }
+
+    public function getSubscribedEvents(): array
+    {
+        return [
+            SoftDeleteableListener::PRE_SOFT_DELETE,
+            SoftDeleteableListener::POST_SOFT_DELETE,
+        ];
+    }
+}
diff --git a/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithPreAndPostSoftDeleteEventArgsTypeListener.php b/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithPreAndPostSoftDeleteEventArgsTypeListener.php
new file mode 100644
index 0000000000..b24c51f6d7
--- /dev/null
+++ b/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithPreAndPostSoftDeleteEventArgsTypeListener.php
@@ -0,0 +1,39 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the Doctrine Behavioral Extensions package.
+ * (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Gedmo\Tests\SoftDeleteable\Fixture\Listener;
+
+use Doctrine\Common\EventSubscriber;
+use Doctrine\Persistence\ObjectManager;
+use Gedmo\SoftDeleteable\Event\PostSoftDeleteEventArgs;
+use Gedmo\SoftDeleteable\Event\PreSoftDeleteEventArgs;
+use Gedmo\SoftDeleteable\SoftDeleteableListener;
+
+final class WithPreAndPostSoftDeleteEventArgsTypeListener implements EventSubscriber
+{
+    /** @param PreSoftDeleteEventArgs<ObjectManager> $args */
+    public function preSoftDelete(PreSoftDeleteEventArgs $args): void
+    {
+    }
+
+    /** @param PostSoftDeleteEventArgs<ObjectManager> $args */
+    public function postSoftDelete(PostSoftDeleteEventArgs $args): void
+    {
+    }
+
+    public function getSubscribedEvents(): array
+    {
+        return [
+            SoftDeleteableListener::PRE_SOFT_DELETE,
+            SoftDeleteableListener::POST_SOFT_DELETE,
+        ];
+    }
+}
diff --git a/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithoutTypeListener.php b/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithoutTypeListener.php
new file mode 100644
index 0000000000..9ab5cf3a8e
--- /dev/null
+++ b/tests/Gedmo/SoftDeleteable/Fixture/Listener/WithoutTypeListener.php
@@ -0,0 +1,39 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the Doctrine Behavioral Extensions package.
+ * (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Gedmo\Tests\SoftDeleteable\Fixture\Listener;
+
+use Doctrine\Common\EventSubscriber;
+use Doctrine\Persistence\ObjectManager;
+use Gedmo\SoftDeleteable\Event\PostSoftDeleteEventArgs;
+use Gedmo\SoftDeleteable\Event\PreSoftDeleteEventArgs;
+use Gedmo\SoftDeleteable\SoftDeleteableListener;
+
+final class WithoutTypeListener implements EventSubscriber
+{
+    /** @param PreSoftDeleteEventArgs<ObjectManager> $args */
+    public function preSoftDelete($args): void
+    {
+    }
+
+    /** @param PostSoftDeleteEventArgs<ObjectManager> $args */
+    public function postSoftDelete($args): void
+    {
+    }
+
+    public function getSubscribedEvents(): array
+    {
+        return [
+            SoftDeleteableListener::PRE_SOFT_DELETE,
+            SoftDeleteableListener::POST_SOFT_DELETE,
+        ];
+    }
+}
diff --git a/tests/Gedmo/SoftDeleteable/SoftDeleteableDocumentTest.php b/tests/Gedmo/SoftDeleteable/SoftDeleteableDocumentTest.php
index 34dfbb1129..fcf8261f96 100644
--- a/tests/Gedmo/SoftDeleteable/SoftDeleteableDocumentTest.php
+++ b/tests/Gedmo/SoftDeleteable/SoftDeleteableDocumentTest.php
@@ -12,11 +12,13 @@
 namespace Gedmo\Tests\SoftDeleteable;
 
 use Doctrine\Common\EventManager;
-use Doctrine\Common\EventSubscriber;
 use Gedmo\SoftDeleteable\Filter\ODM\SoftDeleteableFilter;
 use Gedmo\SoftDeleteable\SoftDeleteableListener;
 use Gedmo\Tests\SoftDeleteable\Fixture\Document\User;
 use Gedmo\Tests\SoftDeleteable\Fixture\Document\UserTimeAware;
+use Gedmo\Tests\SoftDeleteable\Fixture\Listener\WithLifecycleEventArgsFromODMTypeListener;
+use Gedmo\Tests\SoftDeleteable\Fixture\Listener\WithoutTypeListener;
+use Gedmo\Tests\SoftDeleteable\Fixture\Listener\WithPreAndPostSoftDeleteEventArgsTypeListener;
 use Gedmo\Tests\Tool\BaseTestCaseMongoODM;
 
 /**
@@ -150,28 +152,22 @@ public function shouldSupportSoftDeleteableFilterTimeAware(): void
 
     public function testPostSoftDeleteEventIsDispatched(): void
     {
-        $subscriber = $this->getMockBuilder(EventSubscriber::class)
-            ->setMethods([
-                'getSubscribedEvents',
-                'preSoftDelete',
-                'postSoftDelete',
-            ])
-            ->getMock();
+        $this->dm->getEventManager()->addEventSubscriber(new WithPreAndPostSoftDeleteEventArgsTypeListener());
 
-        $subscriber->expects(static::once())
-            ->method('getSubscribedEvents')
-            ->willReturn([SoftDeleteableListener::PRE_SOFT_DELETE, SoftDeleteableListener::POST_SOFT_DELETE]);
-
-        $subscriber->expects(static::once())
-            ->method('preSoftDelete')
-            ->with(static::anything());
+        $this->doTestPostSoftDeleteEventIsDispatched();
+    }
 
-        $subscriber->expects(static::once())
-            ->method('postSoftDelete')
-            ->with(static::anything());
+    /** @group legacy */
+    public function testPostSoftDeleteEventIsDispatchedWithDeprecatedListeners(): void
+    {
+        $this->dm->getEventManager()->addEventSubscriber(new WithoutTypeListener());
+        $this->dm->getEventManager()->addEventSubscriber(new WithLifecycleEventArgsFromODMTypeListener());
 
-        $this->dm->getEventManager()->addEventSubscriber($subscriber);
+        $this->doTestPostSoftDeleteEventIsDispatched();
+    }
 
+    private function doTestPostSoftDeleteEventIsDispatched(): void
+    {
         $repo = $this->dm->getRepository(self::USER_CLASS);
 
         $newUser = new User();
diff --git a/tests/Gedmo/SoftDeleteable/SoftDeleteableEntityTest.php b/tests/Gedmo/SoftDeleteable/SoftDeleteableEntityTest.php
index 19067a7ef1..fcff3c745b 100644
--- a/tests/Gedmo/SoftDeleteable/SoftDeleteableEntityTest.php
+++ b/tests/Gedmo/SoftDeleteable/SoftDeleteableEntityTest.php
@@ -12,7 +12,7 @@
 namespace Gedmo\Tests\SoftDeleteable;
 
 use Doctrine\Common\EventManager;
-use Doctrine\Common\EventSubscriber;
+use Doctrine\ORM\Event\LifecycleEventArgs;
 use Doctrine\ORM\Query;
 use Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter;
 use Gedmo\SoftDeleteable\Query\TreeWalker\SoftDeleteableWalker;
@@ -27,6 +27,9 @@
 use Gedmo\Tests\SoftDeleteable\Fixture\Entity\Page;
 use Gedmo\Tests\SoftDeleteable\Fixture\Entity\User;
 use Gedmo\Tests\SoftDeleteable\Fixture\Entity\UserNoHardDelete;
+use Gedmo\Tests\SoftDeleteable\Fixture\Listener\WithLifecycleEventArgsFromORMTypeListener;
+use Gedmo\Tests\SoftDeleteable\Fixture\Listener\WithoutTypeListener;
+use Gedmo\Tests\SoftDeleteable\Fixture\Listener\WithPreAndPostSoftDeleteEventArgsTypeListener;
 use Gedmo\Tests\Tool\BaseTestCaseORM;
 use Symfony\Component\Cache\Adapter\ArrayAdapter;
 
@@ -529,52 +532,21 @@ public function testShouldFilterBeQueryCachedCorrectlyWhenToggledForEntity(): vo
 
     public function testPostSoftDeleteEventIsDispatched(): void
     {
-        $subscriber = $this->getMockBuilder(EventSubscriber::class)
-            ->setMethods([
-                'getSubscribedEvents',
-                'preSoftDelete',
-                'postSoftDelete',
-            ])
-            ->getMock();
-
-        $subscriber->expects(static::once())
-                   ->method('getSubscribedEvents')
-                   ->willReturn([
-                       SoftDeleteableListener::PRE_SOFT_DELETE,
-                       SoftDeleteableListener::POST_SOFT_DELETE,
-                   ]);
-
-        $subscriber->expects(static::exactly(2))
-                   ->method('preSoftDelete')
-                   ->with(static::anything());
-
-        $subscriber->expects(static::exactly(2))
-                   ->method('postSoftDelete')
-                   ->with(static::anything());
-
-        $this->em->getEventManager()->addEventSubscriber($subscriber);
+        $this->em->getEventManager()->addEventSubscriber(new WithPreAndPostSoftDeleteEventArgsTypeListener());
 
-        $repo = $this->em->getRepository(self::ARTICLE_CLASS);
-
-        $comment = new Comment();
-        $commentValue = 'Comment 1';
-        $comment->setComment($commentValue);
-        $art0 = new Article();
-        $field = 'title';
-        $value = 'Title 1';
-        $art0->setTitle($value);
-        $art0->addComment($comment);
-
-        $this->em->persist($art0);
-        $this->em->flush();
+        $this->doTestPostSoftDeleteEventIsDispatched();
+    }
 
-        $art = $repo->findOneBy([$field => $value]);
+    /** @group legacy */
+    public function testPostSoftDeleteEventIsDispatchedWithDeprecatedListeners(): void
+    {
+        $this->em->getEventManager()->addEventSubscriber(new WithoutTypeListener());
 
-        static::assertNull($art->getDeletedAt());
-        static::assertNull($comment->getDeletedAt());
+        if (class_exists(LifecycleEventArgs::class)) {
+            $this->em->getEventManager()->addEventSubscriber(new WithLifecycleEventArgsFromORMTypeListener());
+        }
 
-        $this->em->remove($art);
-        $this->em->flush();
+        $this->doTestPostSoftDeleteEventIsDispatched();
     }
 
     public function testShouldNotDeleteIfColumnNameDifferFromPropertyName(): void
@@ -625,4 +597,29 @@ protected function getUsedEntityFixtures(): array
             self::USER_NO_HARD_DELETE_CLASS,
         ];
     }
+
+    private function doTestPostSoftDeleteEventIsDispatched(): void
+    {
+        $repo = $this->em->getRepository(self::ARTICLE_CLASS);
+
+        $comment = new Comment();
+        $commentValue = 'Comment 1';
+        $comment->setComment($commentValue);
+        $art0 = new Article();
+        $field = 'title';
+        $value = 'Title 1';
+        $art0->setTitle($value);
+        $art0->addComment($comment);
+
+        $this->em->persist($art0);
+        $this->em->flush();
+
+        $art = $repo->findOneBy([$field => $value]);
+
+        static::assertNull($art->getDeletedAt());
+        static::assertNull($comment->getDeletedAt());
+
+        $this->em->remove($art);
+        $this->em->flush();
+    }
 }