local/modules/StockAlert/EventListeners/StockAlertManager.php line 124

  1. <?php
  2. /*************************************************************************************/
  3. /*      This file is part of the Thelia package.                                     */
  4. /*                                                                                   */
  5. /*      Copyright (c) OpenStudio                                                     */
  6. /*      email : dev@thelia.net                                                       */
  7. /*      web : http://www.thelia.net                                                  */
  8. /*                                                                                   */
  9. /*      For the full copyright and license information, please view the LICENSE.txt  */
  10. /*      file that was distributed with this source code.                             */
  11. /*************************************************************************************/
  12. namespace StockAlert\EventListeners;
  13. use Propel\Runtime\ActiveQuery\Criteria;
  14. use StockAlert\Event\ProductSaleElementAvailabilityEvent;
  15. use StockAlert\Event\StockAlertEvent;
  16. use StockAlert\Event\StockAlertEvents;
  17. use StockAlert\Model\RestockingAlert;
  18. use StockAlert\Model\RestockingAlertQuery;
  19. use StockAlert\StockAlert;
  20. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  22. use Thelia\Core\Event\Newsletter\NewsletterEvent;
  23. use Thelia\Core\Event\Order\OrderEvent;
  24. use Thelia\Core\Event\ProductSaleElement\ProductSaleElementUpdateEvent;
  25. use Thelia\Core\Event\TheliaEvents;
  26. use Thelia\Core\Translation\Translator;
  27. use Thelia\Log\Tlog;
  28. use Thelia\Mailer\MailerFactory;
  29. use Thelia\Model\ConfigQuery;
  30. use Thelia\Model\Lang;
  31. use Thelia\Model\NewsletterQuery;
  32. use Thelia\Model\ProductQuery;
  33. use Thelia\Model\ProductSaleElementsQuery;
  34. /**
  35.  * Class StockAlertManager
  36.  * @package StockAlert\EventListeners
  37.  * @author Baixas Alban <abaixas@openstudio.fr>
  38.  * @author Julien Chanséaume <julien@thelia.net>
  39.  */
  40. class StockAlertManager implements EventSubscriberInterface
  41. {
  42.     protected $mailer;
  43.     protected $dispatcher;
  44.     public function __construct(MailerFactory $mailerEventDispatcherInterface $dispatcher)
  45.     {
  46.         $this->mailer $mailer;
  47.         $this->dispatcher $dispatcher;
  48.     }
  49.     /**
  50.      * Returns an array of event names this subscriber wants to listen to.
  51.      * @return array The event names to listen to
  52.      *
  53.      * @api
  54.      */
  55.     public static function getSubscribedEvents()
  56.     {
  57.         return [
  58.             StockAlertEvents::STOCK_ALERT_SUBSCRIBE => ['subscribe'128],
  59.             TheliaEvents::PRODUCT_UPDATE_PRODUCT_SALE_ELEMENT => ['checkStock'120],
  60.             TheliaEvents::ORDER_UPDATE_STATUS => ['checkStockForAdmin'128],
  61.         ];
  62.     }
  63.     public function subscribe(StockAlertEvent $event)
  64.     {
  65.         $productSaleElementsId $event->getProductSaleElementsId();
  66.         $email $event->getEmail();
  67.         $subscribeToNewsLetter $event->getSubscribeToNewsLetter();
  68.         if (!isset($productSaleElementsId)) {
  69.             throw new \Exception("missing param");
  70.         }
  71.         if (!isset($email)) {
  72.             throw new \Exception("missing param");
  73.         }
  74.         $productSaleList $this->getProductSaleElementsArray($productSaleElementsId);
  75.         foreach($productSaleList as $productSale){
  76.              // test if it already exists
  77.             $subscribe RestockingAlertQuery::create()
  78.             ->filterByEmail($email)
  79.             ->filterByProductSaleElementsId($productSaleElementsId)
  80.             ->findOne();
  81.         if (null === $subscribe) {
  82.             $subscribe = new RestockingAlert();
  83.             $subscribe
  84.                 ->setProductSaleElementsId($productSale->getId())
  85.                 ->setEmail($email)
  86.                 ->setLocale($event->getLocale())
  87.                 ->save();
  88.         }
  89.         if ($subscribeToNewsLetter) {
  90.             $this->subscribeNewsletter($email,$event);
  91.         }
  92.         $event->setRestockingAlert($subscribe);
  93.             }
  94.        
  95.     }
  96.     protected function subscribeNewsletter($emailStockAlertEvent $event)
  97.     {
  98.         $customer NewsletterQuery::create()->findOneByEmail($email);
  99.         if (!$customer) {
  100.             $newsletter = new NewsletterEvent($email,"fr_FR");
  101.             $this->dispatcher->dispatch($newsletterTheliaEvents::NEWSLETTER_SUBSCRIBE);
  102.         }
  103.     }
  104.     public function checkStock(ProductSaleElementUpdateEvent $productSaleElementUpdateEvent)
  105.     {
  106.         if ($productSaleElementUpdateEvent->getQuantity() > 0) {
  107.             // add extra checking
  108.             $pse ProductSaleElementsQuery::create()->findPk(
  109.                 $productSaleElementUpdateEvent->getProductSaleElementId()
  110.             );
  111.             $availabilityEvent = new ProductSaleElementAvailabilityEvent(
  112.                 $pse
  113.             );
  114.             $this->dispatcher->dispatch(
  115.                 $availabilityEvent,
  116.                 StockAlertEvents::STOCK_ALERT_CHECK_AVAILABILITY
  117.             );
  118.             if ($availabilityEvent->isAvailable()) {
  119.                 $subscribers RestockingAlertQuery::create()
  120.                     ->filterByProductSaleElementsId($productSaleElementUpdateEvent->getProductSaleElementId())
  121.                     ->find();
  122.                 if (null !== $subscribers) {
  123.                     foreach ($subscribers as $subscriber) {
  124.                         try {
  125.                             $this->sendEmail($subscriber);
  126.                             $subscriber->delete();
  127.                         } catch (\Exception $ex) {
  128.                             ;
  129.                         }
  130.                     }
  131.                 }
  132.             }
  133.         }
  134.     }
  135.     /**FCA */
  136.     /**
  137.      * @param int $pseId
  138.      */
  139.     protected function getProductSaleElementsArray(int $pseId){
  140.         $pse ProductSaleElementsQuery::create()->findPk$pseId);
  141.         $productId $pse->getProductId();
  142.         $productSales ProductSaleElementsQuery::create()
  143.         ->filterByProductId($productId)
  144.         ->find();
  145.         return $productSales;
  146.     }
  147.     /**FCA */
  148.     /**
  149.      * @param RestockingAlert $subscriber
  150.      * @throws \Propel\Runtime\Exception\PropelException
  151.      */
  152.     public function sendEmail(RestockingAlert $subscriber)
  153.     {
  154.         $contactEmail ConfigQuery::read('store_email');
  155.         if ($contactEmail) {
  156.             $pse ProductSaleElementsQuery::create()->findPk($subscriber->getProductSaleElementsId());
  157.             $this->mailer->sendEmailMessage(
  158.                 'stockalert_customer',
  159.                 [ $contactEmail => ConfigQuery::read('store_name') ],
  160.                 [ $subscriber->getEmail() => ConfigQuery::read('store_name') ],
  161.                 [
  162.                     'locale' => $subscriber->getLocale(),
  163.                     'pse_id' => $pse->getId(),
  164.                     'product_id' => $pse->getProductId(),
  165.                     'product_title' => $pse->getProduct()->setLocale($subscriber->getLocale())->getTitle()
  166.                 ],
  167.                 $subscriber->getLocale()
  168.             );
  169.             Tlog::getInstance()->debug("Restocking Alert sent to customer " $subscriber->getEmail());
  170.         } else {
  171.             Tlog::getInstance()->debug(
  172.                 "Restocking Alert: no contact email is defined !"
  173.             );
  174.         }
  175.     }
  176.     public function checkStockForAdmin(OrderEvent $event)
  177.     {
  178.         $order $event->getOrder();
  179.         $config StockAlert::getConfig();
  180.         $pseIds = [];
  181.         foreach ($order->getOrderProducts() as $orderProduct) {
  182.             $pseIds[] = $orderProduct->getProductSaleElementsId();
  183.         }
  184.         if ($config['enabled']) {
  185.             $threshold $config['threshold'];
  186.             $productIds ProductQuery::create()
  187.                 ->useProductSaleElementsQuery()
  188.                 ->filterById($pseIdsCriteria::IN)
  189.                 ->filterByQuantity($thresholdCriteria::LESS_EQUAL)
  190.                 // exclude virtual product with weight at 0
  191.                 ->filterByWeight(0Criteria::NOT_EQUAL)
  192.                 ->endUse()
  193.                 ->select('Id')
  194.                 ->find()
  195.                 ->toArray();
  196.             if (!empty($productIds)) {
  197.                 $this->sendEmailForAdmin($config['emails'], $productIds);
  198.             }
  199.         }
  200.     }
  201.     public function sendEmailForAdmin($emails$productIds): void
  202.     {
  203.         $config StockAlert::getConfig();
  204.         if ($config['notify']) {
  205.             $locale Lang::getDefaultLanguage()->getLocale();
  206.             $contactEmail ConfigQuery::read('store_email');
  207.             if ($contactEmail) {
  208.                 $storeName ConfigQuery::read('store_name');
  209.                 $to = [];
  210.                 foreach ($emails as $recipient) {
  211.                     $to[$recipient] = $storeName;
  212.                 }
  213.                 $this->mailer->sendEmailMessage(
  214.                     'stockalert_administrator',
  215.                     [ $contactEmail => $storeName ],
  216.                     $to,
  217.                     [
  218.                         'locale' => $locale,
  219.                         'products_id' => $productIds
  220.                     ],
  221.                     $locale
  222.                 );
  223.                 Tlog::getInstance()->debug("Stock Alert sent to administrator " implode(', '$emails));
  224.             } else {
  225.                 Tlog::getInstance()->debug("Restocking Alert: no contact email is defined !");
  226.             }
  227.         }
  228.     }
  229. }