Skip to content

Commit

Permalink
use dedicated event eventArgs (doctrine-extensions#2649)
Browse files Browse the repository at this point in the history
* use dedicated eventArgs

* fix workflow fails

* fix

* move functions to appropriate class

* move functions to appropriate class

* add changelog note

* Move presoftdeletable methods

* update tests to expect dedicated eventargs instances

* Use Pre and Post event args when it is type-hinted

---------

Co-authored-by: Fran Moreno <franmomu@gmail.com>
  • Loading branch information
2 people authored and paxal committed Mar 18, 2024
1 parent 1f2ab72 commit 5a39789
Show file tree
Hide file tree
Showing 14 changed files with 337 additions and 80 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
4 changes: 0 additions & 4 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -33,7 +32,4 @@

$rectorConfig->importNames();
$rectorConfig->importShortClasses(false);
$rectorConfig->skip([
CountOnNullRector::class,
]);
};
7 changes: 7 additions & 0 deletions src/Mapping/Event/Adapter/ODM.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
}
19 changes: 15 additions & 4 deletions src/Mapping/Event/Adapter/ORM.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
2 changes: 1 addition & 1 deletion src/Mapping/Event/AdapterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions src/SoftDeleteable/Event/PostSoftDeleteEventArgs.php
Original file line number Diff line number Diff line change
@@ -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
{
}
24 changes: 24 additions & 0 deletions src/SoftDeleteable/Event/PreSoftDeleteEventArgs.php
Original file line number Diff line number Diff line change
@@ -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
{
}
61 changes: 53 additions & 8 deletions src/SoftDeleteable/SoftDeleteableListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@
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;
use Doctrine\Persistence\Event\LoadClassMetadataEventArgs;
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
Expand Down Expand Up @@ -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);

Expand All @@ -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
);
}
}
}
}
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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,
];
}
}
Original file line number Diff line number Diff line change
@@ -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,
];
}
}
Original file line number Diff line number Diff line change
@@ -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,
];
}
}
Original file line number Diff line number Diff line change
@@ -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,
];
}
}
Loading

0 comments on commit 5a39789

Please sign in to comment.