diff --git a/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetPersonsCommandHandler.php b/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetPersonsCommandHandler.php index e0a7cfbd0..cab723e7f 100644 --- a/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetPersonsCommandHandler.php +++ b/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetPersonsCommandHandler.php @@ -15,9 +15,12 @@ use Chill\MainBundle\Entity\User; use Chill\TicketBundle\Action\Ticket\SetPersonsCommand; use Chill\TicketBundle\Entity\PersonHistory; use Chill\TicketBundle\Entity\Ticket; +use Chill\TicketBundle\Event\PersonsUpdateEvent; +use Chill\TicketBundle\Event\TicketUpdateEvent; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Clock\ClockInterface; use Symfony\Component\Security\Core\Security; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; final readonly class SetPersonsCommandHandler { @@ -25,10 +28,13 @@ final readonly class SetPersonsCommandHandler private ClockInterface $clock, private EntityManagerInterface $entityManager, private Security $security, + private EventDispatcherInterface $eventDispatcher, ) {} public function handle(Ticket $ticket, SetPersonsCommand $command): void { + $event = new PersonsUpdateEvent($ticket); + // remove existing addresses which are not in the new addresses foreach ($ticket->getPersonHistories() as $personHistory) { if (null !== $personHistory->getEndDate()) { @@ -40,6 +46,7 @@ final readonly class SetPersonsCommandHandler if (($user = $this->security->getUser()) instanceof User) { $personHistory->setRemovedBy($user); } + $event->personsRemoved[] = $personHistory->getPerson(); } } @@ -51,6 +58,11 @@ final readonly class SetPersonsCommandHandler $history = new PersonHistory($person, $ticket, $this->clock->now()); $this->entityManager->persist($history); + $event->personsAdded[] = $person; + } + + if ($event->hasChanges()) { + $this->eventDispatcher->dispatch($event, TicketUpdateEvent::class); } } } diff --git a/src/Bundle/ChillTicketBundle/src/Event/PersonsUpdateEvent.php b/src/Bundle/ChillTicketBundle/src/Event/PersonsUpdateEvent.php new file mode 100644 index 000000000..6d1672dc3 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/Event/PersonsUpdateEvent.php @@ -0,0 +1,38 @@ + + */ + public $personsAdded = []; + + /** + * @var list + */ + public $personsRemoved = []; + + public function hasChanges(): bool + { + return count($this->personsAdded) > 0 || count($this->personsRemoved) > 0; + } +} diff --git a/src/Bundle/ChillTicketBundle/src/Event/TicketUpdateEvent.php b/src/Bundle/ChillTicketBundle/src/Event/TicketUpdateEvent.php new file mode 100644 index 000000000..e3b1ac175 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/Event/TicketUpdateEvent.php @@ -0,0 +1,22 @@ +persist(Argument::that(fn ($arg) => $arg instanceof PersonHistory && $arg->getPerson() === $person1))->shouldBeCalledOnce(); $entityManager->persist(Argument::that(fn ($arg) => $arg instanceof PersonHistory && $arg->getPerson() === $group1))->shouldBeCalledOnce(); - $handler = $this->buildHandler($entityManager->reveal()); + $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); + $eventDispatcher->dispatch( + Argument::that(fn ($arg) => $arg instanceof PersonsUpdateEvent + && in_array($person1, $arg->personsAdded, true) + && in_array($group1, $arg->personsAdded, true) + && [] === $arg->personsRemoved), + TicketUpdateEvent::class + )->shouldBeCalled(); + + $handler = $this->buildHandler($entityManager->reveal(), $eventDispatcher->reveal()); $handler->handle($ticket, $command); @@ -59,7 +71,15 @@ final class SetPersonsCommandHandlerTest extends TestCase $entityManager = $this->prophesize(EntityManagerInterface::class); $entityManager->persist(Argument::that(fn ($arg) => $arg instanceof PersonHistory && $arg->getPerson() === $person))->shouldNotBeCalled(); - $handler = $this->buildHandler($entityManager->reveal()); + $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); + $eventDispatcher->dispatch( + Argument::that( + fn ($arg) => $arg instanceof PersonsUpdateEvent + ), + TicketUpdateEvent::class + )->shouldNotBeCalled(); + + $handler = $this->buildHandler($entityManager->reveal(), $eventDispatcher->reveal()); $handler->handle($ticket, $command); @@ -78,7 +98,17 @@ final class SetPersonsCommandHandlerTest extends TestCase $entityManager = $this->prophesize(EntityManagerInterface::class); $entityManager->persist(Argument::that(fn ($arg) => $arg instanceof PersonHistory && $arg->getPerson() === $person2))->shouldBeCalled(); - $handler = $this->buildHandler($entityManager->reveal()); + $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); + $eventDispatcher->dispatch( + Argument::that( + fn ($arg) => $arg instanceof PersonsUpdateEvent + && in_array($person, $arg->personsRemoved, true) && 1 === count($arg->personsRemoved) + && in_array($person2, $arg->personsAdded, true) && 1 === count($arg->personsAdded) + ), + TicketUpdateEvent::class + )->shouldBeCalled(); + + $handler = $this->buildHandler($entityManager->reveal(), $eventDispatcher->reveal()); $handler->handle($ticket, $command); @@ -95,18 +125,28 @@ final class SetPersonsCommandHandlerTest extends TestCase $entityManager = $this->prophesize(EntityManagerInterface::class); $entityManager->persist(Argument::that(fn ($arg) => $arg instanceof PersonHistory && $arg->getPerson() === $person))->shouldBeCalledOnce(); - $handler = $this->buildHandler($entityManager->reveal()); + $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); + $eventDispatcher->dispatch( + Argument::that( + fn ($arg) => $arg instanceof PersonsUpdateEvent + && in_array($person, $arg->personsAdded, true) && 1 === count($arg->personsAdded) + && [] === $arg->personsRemoved + ), + TicketUpdateEvent::class + )->shouldBeCalled(); + + $handler = $this->buildHandler($entityManager->reveal(), $eventDispatcher->reveal()); $handler->handle($ticket, $command); self::assertCount(1, $ticket->getPersons()); } - private function buildHandler(EntityManagerInterface $entityManager): SetPersonsCommandHandler + private function buildHandler(EntityManagerInterface $entityManager, EventDispatcherInterface $eventDispatcher): SetPersonsCommandHandler { $security = $this->prophesize(Security::class); $security->getUser()->willReturn(new User()); - return new SetPersonsCommandHandler(new MockClock(), $entityManager, $security->reveal()); + return new SetPersonsCommandHandler(new MockClock(), $entityManager, $security->reveal(), $eventDispatcher); } }