src/EventSubscriber/OrderEventSubscriber.php line 49

Open in your IDE?
  1. <?php
  2.     namespace App\EventSubscriber;
  3.     use App\Event\CreditEvent;
  4.     use App\Event\OrderEvent;
  5.     use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  6.     use Symfony\Component\Mailer\MailerInterface;
  7.     use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  8.     use App\Entity\ShopOrder;
  9.     use App\Entity\UserEleveCredit;
  10.     
  11.     use Doctrine\ORM\EntityManagerInterface;
  12.     use Symfony\Component\Lock\LockFactory;
  13.     class OrderEventSubscriber implements EventSubscriberInterface
  14.     {
  15.         private $logger;
  16.         private $dispatcher;
  17.         private array $cachers = array();
  18.         public function __construct(
  19.             private LockFactory $locker
  20.             \Psr\Log\LoggerInterface $lifecycleLogger
  21.             private EntityManagerInterface $entityManager
  22.             private MailerInterface $mailer
  23.             \App\Cacher\PreSetCacher $cacher
  24.             UserEventSubscriber $UserEventSubscriber
  25.         )
  26.         {
  27.             $this->dispatcher = new  \Symfony\Component\EventDispatcher\EventDispatcher();
  28.             $this->dispatcher->addSubscriber($UserEventSubscriber);
  29.             $this->logger $lifecycleLogger;
  30.             $cacher->setItemName('commande');
  31.             $this->cachers['order'] = clone $cacher;
  32.             $cacher->setItemName('eleve');
  33.             $this->cachers['eleve'] = clone $cacher;
  34.             $cacher->setItemName('lifecycle');
  35.             $this->cachers['lifecycle'] = clone $cacher;
  36.         }
  37.         public static function getSubscribedEvents() : array
  38.         {
  39.             return [
  40.                 OrderEvent::CONFIRMED => 'onOrderConfirmed',
  41.             ];
  42.         }
  43.         public function onOrderConfirmed(OrderEvent $event)
  44.         {
  45.             #à bug aléatoire, solution aléatoire
  46.             sleep(rand(0,3));
  47.             $shopOrder $event->getShopOrder();
  48.             // Log the event
  49.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  50.                 'shopOrder'=>['id'=>$shopOrder->getId(), 'reference'=>$shopOrder->getReference(), 'total'=>$shopOrder->getTotal()],
  51.             ]);
  52.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  53.                 'lock'=>'acquiring',
  54.             ]);
  55.             $lock $this->locker->createLock('order:'.$shopOrder->getReference());
  56.             $locked $lock->acquire(true);
  57.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  58.                 'lock'=>'acquired',
  59.                 'locked'=>$locked,
  60.             ]);
  61.             // $e = new \Exception;
  62.             $trace '';
  63.             // $trace = print_r($e->getTraceAsString(),true);
  64.             $trace .= '#locked '.print_r($locked,true);
  65.             $trace .= '#_GET '.print_r($_GET,true);
  66.             $trace .= '#_POST '.print_r($_POST,true);
  67.             $trace .= '#_SERVER '.print_r($_SERVER,true);
  68.             // $trace .= '#Request '.print_r(Request::createFromGlobals()->getContent(),true);
  69.             // $trace .= '#lock '.print_r($lock,true);
  70.             $this->mailer->send((new TemplatedEmail())
  71.                 ->to('gabriel@pyreweb.com')
  72.                 ->subject('Locker')
  73.                 ->textTemplate('maildebug.txt.twig')
  74.                 ->context([
  75.                     'texte'=>$shopOrder->getReference().' has a locker?'.PHP_EOL.$trace,
  76.                 ])
  77.             );
  78.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  79.                 'status shopOrder'=>$shopOrder->getStatus()->getCode(),
  80.             ]);
  81.             if ($shopOrder->getStatus()->getCode() == 'success') {
  82.                 // $this->mailAdminAboutError($shopOrder, 'La commande n°'.$shopOrder->getReference().' a déjà été payée.');
  83.                 throw new \Error('La commande n°'.$shopOrder->getReference().' a déjà été payée.');
  84.             }
  85.             $user $event->getUser();
  86.             // Delete the cache entries
  87.             $this->cachers['lifecycle']->empty();
  88.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  89.                 'cache emptied'=>'lifecycle',
  90.             ]);
  91.             $this->cachers['eleve']->delete($user);
  92.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  93.                 'cache emptied'=>'eleve',
  94.                 'index'=>['id'=>$user->getId(), 'email'=>$user->getEmail()],
  95.             ]);
  96.             $this->cachers['order']->delete($shopOrder);
  97.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  98.                 'cache emptied'=>'order',
  99.                 'index'=>['id'=>$shopOrder->getId(), 'reference'=>$shopOrder->getReference()],
  100.             ]);
  101.             $this->cachers['order']->delete('count');
  102.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  103.                 'cache emptied'=>'order',
  104.                 'index'=>'count',
  105.             ]);
  106.             $entityManager $this->entityManager;
  107.             $ShopOrderStatus $entityManager->getRepository(\App\Entity\ShopOrderStatus::class)->findOneBy(['code'=>'success']);
  108.             $shopOrder->setStatus($ShopOrderStatus);
  109.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  110.                 'status'=>$ShopOrderStatus->getCode(),
  111.             ]);
  112.             //liste des crédits utilisateurs non flushés
  113.             $UserEleveCredits = new \Doctrine\Common\Collections\ArrayCollection();
  114.     
  115.             // Traitement des éléments de la commande
  116.             /** @var \App\Entity\ShopOrderProduct */
  117.             foreach($shopOrder->getshopOrderProducts() as $shopOrderProduct) {
  118.                 $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  119.                     'shopOrderProduct'=>[
  120.                         'id'=>$shopOrderProduct->getId(),
  121.                         'intitule'=>$shopOrderProduct->getIntitule(),
  122.                         'categorie'=>$shopOrderProduct->getCategorie()->getIntitule(),
  123.                         'points'=>$shopOrderProduct->getPoints(),
  124.                         'quantite'=>$shopOrderProduct->getQuantite(),
  125.                     ]
  126.                 ]);
  127.     
  128.                 //Mise à jour des crédits utilisateur
  129.                 // La catégorie des crédits utilisateur concernée existe-elle ?
  130.                 $cat =  $entityManager->getRepository(UserEleveCredit::class);
  131.                 $UserEleveCredit $cat->findOneWithShopOrderProduct($shopOrderProduct);
  132.                 if($UserEleveCredit == null) {
  133.                     // On vérifie s'il y a une catégorie pas encore flushée pour le user
  134.                     $UserEleveCredit $UserEleveCredits->filter(function($UserEleveCredit) use ($shopOrderProduct) {
  135.                         return $UserEleveCredit->getCategorie() == $shopOrderProduct->getCategorie();
  136.                     })->first();
  137.                     if(!$UserEleveCredit) {
  138.                         $UserEleveCredit null;
  139.                     }
  140.                 }
  141.                 // Elle n'existe pas pour ce User, on la crée
  142.                 if($UserEleveCredit == null) {
  143.                     $UserEleveCredit = new UserEleveCredit();
  144.                     $UserEleveCredit->setUser($user);
  145.                     $UserEleveCredit->setCategorie($shopOrderProduct->getCategorie());
  146.                 }
  147.                 // On ajoute les points
  148.                 $UserEleveCredit->addPoints($shopOrderProduct->getTotalPoints());
  149.                 $entityManager->persist($UserEleveCredit);
  150.                 $UserEleveCredits->add($UserEleveCredit);
  151.                 $event = new CreditEvent($UserEleveCredit);
  152.                 $event->setMovedPoints($shopOrderProduct->getTotalPoints());
  153.                 $this->dispatcher->dispatch($eventCreditEvent::ADDED);
  154.             }
  155.             $entityManager->persist($shopOrder);
  156.     
  157.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  158.                 'flushed'=>'pending',
  159.             ]);
  160.             $entityManager->flush();
  161.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  162.                 'flushed'=>'done',
  163.             ]);
  164.             $lock->release();
  165.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  166.                 'lock'=>'released',
  167.             ]);
  168.             $this->mailAdminAboutConfirmation($shopOrder);
  169.             $this->mailUserAboutConfirmation($shopOrder);
  170.         }
  171.         protected function mailAdminAboutError(ShopOrder $shopOrderstring $erreur){
  172.             $this->mailer->send((new TemplatedEmail())
  173.                 ->subject('Erreur sur une Commande')
  174.                 ->htmlTemplate('admin/mail/order_error.html.twig')
  175.                 ->context([
  176.                     'commande'=>$shopOrder,
  177.                     'erreur'=>$erreur
  178.                 ])
  179.             );
  180.         }
  181.         protected function mailAdminAboutConfirmation(ShopOrder $shopOrder){
  182.             $this->mailer->send((new TemplatedEmail())
  183.                 ->subject('Commande confirmée')
  184.                 ->htmlTemplate('admin/mail/order_confirmed.html.twig')
  185.                 ->context([
  186.                     'commande'=>$shopOrder,
  187.                 ])
  188.             );
  189.         }
  190.         protected function mailUserAboutConfirmation(ShopOrder $shopOrder){
  191.             $this->mailer->send((new TemplatedEmail())
  192.                 ->to($shopOrder->getUser()->getEmail())
  193.                 ->subject('Commande confirmée')
  194.                 ->htmlTemplate('eleve/mail/order_confirmed.html.twig')
  195.                 ->context([
  196.                     'commande'=>$shopOrder,
  197.                 ])
  198.             );
  199.         }
  200.     }