From 3bbd79adf21fed0bfd049ed64c47ec9ac8e6e1dd Mon Sep 17 00:00:00 2001 From: Jannik Zschiesche Date: Tue, 28 Nov 2023 10:12:33 +0100 Subject: [PATCH] Add `DoctrineChangeChecker::getEntityChanges()` --- CHANGELOG.md | 6 +++ src/Doctrine/DoctrineChangeChecker.php | 44 +++++++++++++++++-- .../InvalidDoctrineChangeCheckException.php | 9 ++++ tests/Doctrine/DoctrineChangeCheckerTest.php | 15 ++++++- 4 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 src/Exception/Doctrine/InvalidDoctrineChangeCheckException.php diff --git a/CHANGELOG.md b/CHANGELOG.md index f2a8576..53c4b56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +2.5.0 +===== + +* (feature) Add `DoctrineChangeChecker::getEntityChanges()`. + + 2.4.1 ===== diff --git a/src/Doctrine/DoctrineChangeChecker.php b/src/Doctrine/DoctrineChangeChecker.php index cab9cc0..346bfed 100644 --- a/src/Doctrine/DoctrineChangeChecker.php +++ b/src/Doctrine/DoctrineChangeChecker.php @@ -3,25 +3,38 @@ namespace Torr\Rad\Doctrine; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\PersistentCollection; +use Doctrine\Persistence\ManagerRegistry; +use Torr\Rad\Exception\Doctrine\InvalidDoctrineChangeCheckException; final readonly class DoctrineChangeChecker { /** */ public function __construct ( - private EntityManagerInterface $entityManager, + private ManagerRegistry $managerRegistry, ) {} /** - * Determines whether any content in the entities (or the entities themselves) + * Determines whether any content globally in any of the entities (or the entities themselves) * has changed. Only changing "timeModified" doesn't count as content change. * * @api */ public function hasContentChanged () : bool { - $unitOfWork = $this->entityManager->getUnitOfWork(); + $defaultEntityManager = $this->managerRegistry->getManager(); + + if (!$defaultEntityManager instanceof EntityManagerInterface) + { + throw new InvalidDoctrineChangeCheckException(\sprintf( + "Default manager is no entity manager, but '%s'", + \get_debug_type($defaultEntityManager), + )); + } + + $unitOfWork = $defaultEntityManager->getUnitOfWork(); $unitOfWork->computeChangeSets(); // If any entity was added / removed, something changed, so early exit @@ -50,4 +63,29 @@ public function hasContentChanged () : bool return false; } + + + /** + * Returns the changes of the given entity + * + * @return array + */ + public function getEntityChanges (object $entity) : array + { + $entityClass = \get_class($entity); + $entityManager = $this->managerRegistry->getManagerForClass($entityClass); + + if (!$entityManager instanceof EntityManagerInterface) + { + throw new InvalidDoctrineChangeCheckException(\sprintf( + "Could not fetch entity manager for entity of type '%s'", + $entityClass, + )); + } + + $unitOfWork = $entityManager->getUnitOfWork(); + $unitOfWork->computeChangeSets(); + + return $unitOfWork->getEntityChangeSet($entity); + } } diff --git a/src/Exception/Doctrine/InvalidDoctrineChangeCheckException.php b/src/Exception/Doctrine/InvalidDoctrineChangeCheckException.php new file mode 100644 index 0000000..b5c305c --- /dev/null +++ b/src/Exception/Doctrine/InvalidDoctrineChangeCheckException.php @@ -0,0 +1,9 @@ +method("getUnitOfWork") ->willReturn($unitOfWork); - $checker = new DoctrineChangeChecker($entityManager); + $registry = $this->createMock(ManagerRegistry::class); + $registry + ->method("getManager") + ->willReturn($entityManager); + + $checker = new DoctrineChangeChecker($registry); self::assertSame($expected, $checker->hasContentChanged()); } @@ -146,7 +152,12 @@ public function testChangesets ( ->method("getUnitOfWork") ->willReturn($unitOfWork); - $checker = new DoctrineChangeChecker($entityManager); + $registry = $this->createMock(ManagerRegistry::class); + $registry + ->method("getManager") + ->willReturn($entityManager); + + $checker = new DoctrineChangeChecker($registry); self::assertSame($expected, $checker->hasContentChanged()); } }