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.             $entityManager $this->entityManager;
  87.             $ShopOrderStatus $entityManager->getRepository(\App\Entity\ShopOrderStatus::class)->findOneBy(['code'=>'success']);
  88.             $shopOrder->setStatus($ShopOrderStatus);
  89.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  90.                 'status'=>$ShopOrderStatus->getCode(),
  91.             ]);
  92.             //liste des crédits utilisateurs non flushés
  93.             $UserEleveCredits = new \Doctrine\Common\Collections\ArrayCollection();
  94.     
  95.             // Traitement des éléments de la commande
  96.             /** @var \App\Entity\ShopOrderProduct */
  97.             foreach($shopOrder->getshopOrderProducts() as $shopOrderProduct) {
  98.                 $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  99.                     'shopOrderProduct'=>[
  100.                         'id'=>$shopOrderProduct->getId(),
  101.                         'intitule'=>$shopOrderProduct->getIntitule(),
  102.                         'categorie'=>$shopOrderProduct->getCategorie()->getIntitule(),
  103.                         'points'=>$shopOrderProduct->getPoints(),
  104.                         'quantite'=>$shopOrderProduct->getQuantite(),
  105.                     ]
  106.                 ]);
  107.     
  108.                 //Mise à jour des crédits utilisateur
  109.                 // La catégorie des crédits utilisateur concernée existe-elle ?
  110.                 $cat =  $entityManager->getRepository(UserEleveCredit::class);
  111.                 $UserEleveCredit $cat->findOneWithShopOrderProduct($shopOrderProduct);
  112.                 if($UserEleveCredit == null) {
  113.                     // On vérifie s'il y a une catégorie pas encore flushée pour le user
  114.                     $UserEleveCredit $UserEleveCredits->filter(function($UserEleveCredit) use ($shopOrderProduct) {
  115.                         return $UserEleveCredit->getCategorie() == $shopOrderProduct->getCategorie();
  116.                     })->first();
  117.                     if(!$UserEleveCredit) {
  118.                         $UserEleveCredit null;
  119.                     }
  120.                 }
  121.                 // Elle n'existe pas pour ce User, on la crée
  122.                 if($UserEleveCredit == null) {
  123.                     $UserEleveCredit = new UserEleveCredit();
  124.                     $UserEleveCredit->setUser($user);
  125.                     $UserEleveCredit->setCategorie($shopOrderProduct->getCategorie());
  126.                 }
  127.                 // On ajoute les points
  128.                 $UserEleveCredit->addPoints($shopOrderProduct->getTotalPoints());
  129.                 $entityManager->persist($UserEleveCredit);
  130.                 $UserEleveCredits->add($UserEleveCredit);
  131.                 $event = new CreditEvent($UserEleveCredit);
  132.                 $event->setMovedPoints($shopOrderProduct->getTotalPoints());
  133.                 $this->dispatcher->dispatch($eventCreditEvent::ADDED);
  134.             }
  135.             $entityManager->persist($shopOrder);
  136.     
  137.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  138.                 'flushed'=>'pending',
  139.             ]);
  140.             $entityManager->flush();
  141.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  142.                 'flushed'=>'done',
  143.             ]);
  144.             $lock->release();
  145.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  146.                 'lock'=>'released',
  147.             ]);
  148.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  149.                 'cache emptying'=>'lifecycle',
  150.             ]);
  151.             // Delete the cache entries
  152.             $this->cachers['lifecycle']->empty();
  153.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  154.                 'cache emptied'=>'lifecycle',
  155.             ]);
  156.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  157.                 'cache emptying'=>'eleve',
  158.                 'index'=>['id'=>$user->getId(), 'email'=>$user->getEmail()],
  159.             ]);
  160.             $this->cachers['eleve']->delete($user);
  161.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  162.                 'cache emptied'=>'eleve',
  163.                 'index'=>['id'=>$user->getId(), 'email'=>$user->getEmail()],
  164.             ]);
  165.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  166.                 'cache emptying'=>'order',
  167.                 'index'=>['id'=>$shopOrder->getId(), 'reference'=>$shopOrder->getReference()],
  168.             ]);
  169.             $this->cachers['order']->delete($shopOrder);
  170.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  171.                 'cache emptied'=>'order',
  172.                 'index'=>['id'=>$shopOrder->getId(), 'reference'=>$shopOrder->getReference()],
  173.             ]);
  174.             $this->cachers['order']->delete('count');
  175.             $this->logger->info(OrderEvent::CONFIRMED.' '.$shopOrder->getReference(), [
  176.                 'cache emptied'=>'order',
  177.                 'index'=>'count',
  178.             ]);
  179.             $this->mailAdminAboutConfirmation($shopOrder);
  180.             $this->mailUserAboutConfirmation($shopOrder);
  181.         }
  182.         protected function mailAdminAboutError(ShopOrder $shopOrderstring $erreur){
  183.             $this->mailer->send((new TemplatedEmail())
  184.                 ->subject('Erreur sur une Commande')
  185.                 ->htmlTemplate('admin/mail/order_error.html.twig')
  186.                 ->context([
  187.                     'commande'=>$shopOrder,
  188.                     'erreur'=>$erreur
  189.                 ])
  190.             );
  191.         }
  192.         protected function mailAdminAboutConfirmation(ShopOrder $shopOrder){
  193.             $this->mailer->send((new TemplatedEmail())
  194.                 ->subject('Commande confirmée')
  195.                 ->htmlTemplate('admin/mail/order_confirmed.html.twig')
  196.                 ->context([
  197.                     'commande'=>$shopOrder,
  198.                 ])
  199.             );
  200.         }
  201.         protected function mailUserAboutConfirmation(ShopOrder $shopOrder){
  202.             $this->mailer->send((new TemplatedEmail())
  203.                 ->to($shopOrder->getUser()->getEmail())
  204.                 ->subject('Commande confirmée')
  205.                 ->htmlTemplate('eleve/mail/order_confirmed.html.twig')
  206.                 ->context([
  207.                     'commande'=>$shopOrder,
  208.                 ])
  209.             );
  210.         }
  211.     }