![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-product-alert/Model/Mailing/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\ProductAlert\Model\Mailing; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Helper\Data; use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; use Magento\Framework\Stdlib\DateTime; use Magento\ProductAlert\Model\Email; use Magento\ProductAlert\Model\EmailFactory; use Magento\ProductAlert\Model\Price; use Magento\ProductAlert\Model\ProductSalability; use Magento\ProductAlert\Model\ResourceModel\Stock\CollectionFactory as StockCollectionFactory; use Magento\ProductAlert\Model\ResourceModel\Price\CollectionFactory as PriceCollectionFactory; use Magento\ProductAlert\Model\Stock; use Magento\Store\Api\Data\WebsiteInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Store\Model\Website; /** * Class for mailing Product Alerts */ class AlertProcessor { public const ALERT_TYPE_STOCK = 'stock'; public const ALERT_TYPE_PRICE = 'price'; /** * @var EmailFactory */ private $emailFactory; /** * @var PriceCollectionFactory */ private $priceCollectionFactory; /** * @var StockCollectionFactory */ private $stockCollectionFactory; /** * @var CustomerRepositoryInterface */ private $customerRepository; /** * @var ProductRepositoryInterface */ private $productRepository; /** * @var Data */ private $catalogData; /** * @var ProductSalability */ private $productSalability; /** * @var StoreManagerInterface */ private $storeManager; /** * @var ErrorEmailSender */ private $errorEmailSender; /** * @param EmailFactory $emailFactory * @param PriceCollectionFactory $priceCollectionFactory * @param StockCollectionFactory $stockCollectionFactory * @param CustomerRepositoryInterface $customerRepository * @param ProductRepositoryInterface $productRepository * @param Data $catalogData * @param ProductSalability $productSalability * @param StoreManagerInterface $storeManager * @param ErrorEmailSender $errorEmailSender */ public function __construct( EmailFactory $emailFactory, PriceCollectionFactory $priceCollectionFactory, StockCollectionFactory $stockCollectionFactory, CustomerRepositoryInterface $customerRepository, ProductRepositoryInterface $productRepository, Data $catalogData, ProductSalability $productSalability, StoreManagerInterface $storeManager, ErrorEmailSender $errorEmailSender ) { $this->emailFactory = $emailFactory; $this->priceCollectionFactory = $priceCollectionFactory; $this->stockCollectionFactory = $stockCollectionFactory; $this->customerRepository = $customerRepository; $this->productRepository = $productRepository; $this->catalogData = $catalogData; $this->productSalability = $productSalability; $this->storeManager = $storeManager; $this->errorEmailSender = $errorEmailSender; } /** * Process product alerts * * @param string $alertType * @param array $customerIds * @param int $websiteId * @throws \Exception */ public function process(string $alertType, array $customerIds, int $websiteId): void { $this->validateAlertType($alertType); $errors = $this->processAlerts($alertType, $customerIds, $websiteId); if (!empty($errors)) { /** @var Website $website */ $website = $this->storeManager->getWebsite($websiteId); $defaultStoreId = $website->getDefaultStore()->getId(); $this->errorEmailSender->execute($errors, $defaultStoreId); } } /** * Process product alerts * * @param string $alertType * @param array $customerIds * @param int $websiteId * @return array * @throws \Exception */ private function processAlerts(string $alertType, array $customerIds, int $websiteId): array { /** @var Email $email */ $email = $this->emailFactory->create(); $email->setType($alertType); $email->setWebsiteId($websiteId); $errors = []; try { $collection = $this->getAlertCollection($alertType, $customerIds, $websiteId); } catch (\Exception $e) { $errors[] = $e->getMessage(); return $errors; } /** @var CustomerInterface $customer */ $customer = null; /** @var Website $website */ $website = $this->storeManager->getWebsite($websiteId); $defaultStoreId = $website->getDefaultStore()->getId(); /** @var Price|Stock $alert */ foreach ($collection as $alert) { try { if ($alert->getStoreId()) { $email->setStoreId($alert->getStoreId()); } if ($customer === null) { $customer = $this->customerRepository->getById($alert->getCustomerId()); } elseif ((int)$customer->getId() !== (int)$alert->getCustomerId()) { $this->sendEmail($customer, $email); $customer = $this->customerRepository->getById($alert->getCustomerId()); } $product = $this->productRepository->getById($alert->getProductId(), false, $defaultStoreId); switch ($alertType) { case self::ALERT_TYPE_STOCK: $this->saveStockAlert($alert, $product, $website, $email); break; case self::ALERT_TYPE_PRICE: $this->savePriceAlert($alert, $product, $customer, $email); break; } } catch (\Exception $e) { $errors[] = $e->getMessage(); } } if ($customer !== null) { try { $this->sendEmail($customer, $email); } catch (\Exception $e) { $errors[] = $e->getMessage(); } } return $errors; } /** * Validate Alert Type * * @param string $alertType * @throws \InvalidArgumentException */ private function validateAlertType(string $alertType): void { if (!in_array($alertType, [self::ALERT_TYPE_STOCK, self::ALERT_TYPE_PRICE])) { throw new \InvalidArgumentException('Invalid alert type'); } } /** * Get alert collection * * @param string $alertType * @param array $customerIds * @param int $websiteId * @return AbstractCollection * @throws \InvalidArgumentException */ private function getAlertCollection(string $alertType, array $customerIds, int $websiteId): AbstractCollection { switch ($alertType) { case self::ALERT_TYPE_STOCK: $collection = $this->stockCollectionFactory->create(); $collection->addFieldToFilter('customer_id', ['in' => $customerIds]) ->addWebsiteFilter($websiteId) ->addStatusFilter(0) ->setCustomerOrder() ->addOrder('product_id'); break; case self::ALERT_TYPE_PRICE: $collection = $this->priceCollectionFactory->create(); $collection->addFieldToFilter('customer_id', ['in' => $customerIds]) ->addWebsiteFilter($websiteId) ->setCustomerOrder() ->addOrder('product_id'); break; default: throw new \InvalidArgumentException('Invalid alert type'); } return $collection; } /** * Save Price Alert * * @param Price $alert * @param ProductInterface $product * @param CustomerInterface $customer * @param Email $email */ private function savePriceAlert( Price $alert, ProductInterface $product, CustomerInterface $customer, Email $email ): void { $product->setCustomerGroupId($customer->getGroupId()); $finalPrice = $product->getFinalPrice(); if ($alert->getPrice() <= $finalPrice) { return; } $product->setFinalPrice($this->catalogData->getTaxPrice($product, $finalPrice)); $product->setPrice($this->catalogData->getTaxPrice($product, $product->getPrice())); $alert->setPrice($finalPrice); $alert->setLastSendDate(date(DateTime::DATETIME_PHP_FORMAT)); $alert->setSendCount($alert->getSendCount() + 1); $alert->setStatus(1); $alert->save(); $email->addPriceProduct($product); } /** * Save stock alert * * @param Stock $alert * @param ProductInterface $product * @param WebsiteInterface $website * @param Email $email */ private function saveStockAlert( Stock $alert, ProductInterface $product, WebsiteInterface $website, Email $email ): void { if (!$this->productSalability->isSalable($product, $website)) { return; } $alert->setSendDate(date(DateTime::DATETIME_PHP_FORMAT)); $alert->setSendCount($alert->getSendCount() + 1); $alert->setStatus(1); $alert->save(); $email->addStockProduct($product); } /** * Send alert email * * @param CustomerInterface $customer * @param Email $email */ private function sendEmail(CustomerInterface $customer, Email $email): void { $email->setCustomerData($customer); $email->send(); $email->clean(); } }