src/EventSubscriber/JobOnWaySubscriber.php line 44

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use ApiPlatform\Symfony\EventListener\EventPriorities;
  4. use App\Entity\Job;
  5. use App\Entity\Schedule;
  6. use App\Entity\User;
  7. use App\Service\Message;
  8. use Doctrine\Persistence\ManagerRegistry;
  9. use JetBrains\PhpStorm\ArrayShape;
  10. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpKernel\Event\ViewEvent;
  13. use Symfony\Component\HttpKernel\KernelEvents;
  14. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  15. use function array_multisort;
  16. use function current;
  17. use function floor;
  18. use function in_array;
  19. final class JobOnWaySubscriber implements EventSubscriberInterface
  20. {
  21.     /** @var string The relative path inside templates/messages without any extensions */
  22.     private const TEMPLATE 'job/on-way';
  23.     public function __construct(
  24.         private readonly TokenStorageInterface $tokenStorage,
  25.         private readonly ManagerRegistry $managerRegistry,
  26.         private readonly Message $messageService,
  27.     )
  28.     {
  29.     }
  30.     #[ArrayShape([KernelEvents::VIEW => "array"])]
  31.     public static function getSubscribedEvents(): array
  32.     {
  33.         return [
  34.             KernelEvents::VIEW => ['sendMessage'EventPriorities::POST_WRITE],
  35.         ];
  36.     }
  37.     public function sendMessage(ViewEvent $event): void
  38.     {
  39.         $job $event->getControllerResult();
  40.         $method $event->getRequest()->getMethod();
  41.         # PUT and PATCH methods are used to update instances, and we are only interested in updated jobs
  42.         if (!$job instanceof Job || !in_array($method, [Request::METHOD_PUTRequest::METHOD_PATCH])) {
  43.             return;
  44.         }
  45.         $previousData $event->getRequest()->get('previous_data');
  46.         # If the status hasn't changed, we're not interested
  47.         if ($previousData->getStatus() === $job->getStatus()) {
  48.             return;
  49.         }
  50.         # If the status hasn't changed to "on way", we're not interested
  51.         if ($job->getStatus() !== Job::JOB_STATUS_ON_WAY) {
  52.             return;
  53.         }
  54.         $customer $job->getPond()->getCustomer();
  55.         $schedule $this->getLatestSchedule($job);
  56.         $message $this->messageService
  57.             ->withRecipient($customer)
  58.             ->withSubject('We are on our way')
  59.             ->withTemplate(self::TEMPLATE)
  60.             ->withTemplateData([
  61.                 'addressLine1' => $job->getPond()->getAddress1(),
  62.                 'firstName' => $customer->getFirstName() === 'ANNETTE' null $customer->getFirstName(),
  63.                 'fullAddress' => $job->getPond()->getAddress(),
  64.                 'travelTime' => $this->formatTime($schedule->getEstimatedTravelTime()),
  65.             ]);
  66.         $currentUser $this->tokenStorage->getToken()->getUser();
  67.         if ($currentUser instanceof User) {
  68.             $message $message->withCurrentUser($currentUser);
  69.         }
  70.         $message->send();
  71.     }
  72.     private function getLatestSchedule(Job $job): Schedule
  73.     {
  74.         /** @var iterable<int, Schedule> $schedules */
  75.         $schedules $this->managerRegistry->getRepository(Schedule::class)
  76.             ->findBy(['job' => $job]);
  77.         $sort = [];
  78.         foreach ($schedules as $schedule) {
  79.             $sort[] = $schedule->getDate()->getTimestamp();
  80.         }
  81.         array_multisort($schedulesSORT_DESC$sort);
  82.         return current($schedules);
  83.     }
  84.     private function formatTime(int $time): string
  85.     {
  86.         $parts = [];
  87.         $days floor($time / (60 60 24));
  88.         if ($days 0) {
  89.             $parts[] = sprintf('%d day%s'$days$days 's' '');
  90.             $time -= $days * (60 60 24);
  91.         }
  92.         $hours floor($time / (60 60));
  93.         if ($hours 0) {
  94.             $parts[] = sprintf('%d hour%s'$hours$hours 's' '');
  95.             $time -= $hours * (60 60);
  96.         }
  97.         $minutes floor($time 60);
  98.         if ($minutes 0) {
  99.             $parts[] = sprintf('%d minute%s'$minutes$minutes 's' '');
  100.         }
  101.         if (count($parts) === 0) {
  102.             return '1 minute';
  103.         }
  104.         return implode(', '$parts);
  105.     }
  106. }