<?php
namespace App\EventSubscriber;
/*
bin/stripe listen --forward-to localhost:4242/cultureroute/public/stripe/webhook
*/
use App\Event\OrderPaymentEvent;
use App\Event\OrderEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Psr\Log\LoggerInterface;
use App\Entity\ShopPanier;
use App\Entity\ShopOrder;
use App\Entity\ShopOrderProduct;
use Doctrine\ORM\EntityManagerInterface;
class OrderPaymentEventSubscriber implements EventSubscriberInterface
{
private $dispatcher;
public function __construct(
private LoggerInterface $lifecycleLogger,
private EntityManagerInterface $entityManager,
OrderEventSubscriber $orderEventSubscriber
)
{
$this->entityManager = $entityManager;
$this->dispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
$this->dispatcher->addSubscriber($orderEventSubscriber);
}
public static function getSubscribedEvents() : array
{
return [
OrderPaymentEvent::SUCCESS => 'onPaymentSuccess',
OrderPaymentEvent::CREATED => 'onPaymentCreated',
];
}
public function onPaymentCreated(OrderPaymentEvent $event)
{
$reference = $event->getOrderReference();
// Log the event
$this->lifecycleLogger->info(OrderPaymentEvent::CREATED.' '.$reference, [
'reference'=>$reference,
]);
$panier = $this->entityManager->getRepository(ShopPanier::class)->findBy(['reference'=>$reference]);
if (!$panier) {
throw new \Error('Pas de panier avec la référence "'.$reference.'"');
return;
}
/** @var \App\Entity\ShopPanier */
$ShopPanier = $panier[0];
$this->lifecycleLogger->info(OrderPaymentEvent::CREATED.' '.$reference, [
'panier'=>['id'=>$ShopPanier->getId(), 'reference'=>$ShopPanier->getReference(), 'produit'=>$ShopPanier->getProduit()->getIntitule()],
]);
$user = $ShopPanier->getUser();
$entityManager = $this->entityManager;
/** @var \App\Entity\ShopOrderStatus */
$ShopOrderStatus = $entityManager->getRepository(\App\Entity\ShopOrderStatus::class)->findOneBy(['code'=>'created']);
$this->lifecycleLogger->info(OrderPaymentEvent::CREATED.' '.$reference, [
'ShopOrderStatus'=>$ShopOrderStatus->getIntitule(),
]);
// Nouvelle commande
$order = new ShopOrder();
$order->setUser($user);
$order->setStatus($ShopOrderStatus);
$order->setReference($reference);
$order->setAdress($ShopPanier->getAdress());
$order->setTotal(0);
$entityManager->persist($order);
$this->lifecycleLogger->info(OrderPaymentEvent::CREATED.' '.$reference, [
'order'=>['id'=>NULL, 'reference'=>$order->getReference(), 'total'=>$order->getTotal()],
]);
// Traitement des éléments de la commande
foreach($panier as $panierElt) {
// Nouveau produit de la commande
$shopOrderProduct = new ShopOrderProduct();
$shopOrderProduct->setShopOrder($order);
$shopOrderProduct->setProduct($panierElt->getProduit());
$shopOrderProduct->setQuantite($panierElt->getUnit());
$shopOrderProduct->setPrice($panierElt->getProduit()->getPrice());
$shopOrderProduct->setIntitule($panierElt->getProduit()->getIntitule());
$shopOrderProduct->setDescriptif($panierElt->getProduit()->getDescriptif());
$shopOrderProduct->setCategorie($panierElt->getProduit()->getCategorie());
$shopOrderProduct->setPoints($panierElt->getProduit()->getPoints());
$entityManager->persist($shopOrderProduct);
$order->setTotal($order->getTotal() + $shopOrderProduct->getTotal());
//On supprime les éléments du panier en cours
$panierEltToDelete = $entityManager->getRepository(ShopPanier::class)->find($panierElt->getId());
$entityManager->remove($panierEltToDelete);
}
$this->lifecycleLogger->info(OrderPaymentEvent::CREATED.' '.$reference, [
'persist'=>['id'=>$order->getId(), 'reference'=>$order->getReference(), 'total'=>$order->getTotal()],
]);
$entityManager->persist($order);
$entityManager->flush();
$this->lifecycleLogger->info(OrderPaymentEvent::CREATED.' '.$reference, [
'flush'=>'done',
]);
}
public function onPaymentSuccess(OrderPaymentEvent $event)
{
$reference = $event->getOrderReference();
// Log the event
$this->lifecycleLogger->info(OrderPaymentEvent::SUCCESS.' '.$reference, [
'reference'=>$reference,
]);
/** @var \App\Entity\ShopOrder */
$shopOrder = $this->entityManager->getRepository(ShopOrder::class)->findOneBy(['reference'=>$reference]);
if (!$shopOrder) {
throw new \Error('Pas de commande avec la référence "'.$reference.'"');
return;
}
$this->lifecycleLogger->info(OrderPaymentEvent::SUCCESS.' '.$reference, [
'shopOrder'=>['id'=>$shopOrder->getId(), 'reference'=>$shopOrder->getReference(), 'total'=>$shopOrder->getTotal()],
]);
$OrderEvent = new OrderEvent($shopOrder);
$this->dispatcher->dispatch($OrderEvent, OrderEvent::CONFIRMED);
}
}