123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\ProductAlert\Model;
- /**
- * ProductAlert observer
- *
- * @author Magento Core Team <core@magentocommerce.com>
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class Observer
- {
- /**
- * Error email template configuration
- */
- const XML_PATH_ERROR_TEMPLATE = 'catalog/productalert_cron/error_email_template';
- /**
- * Error email identity configuration
- */
- const XML_PATH_ERROR_IDENTITY = 'catalog/productalert_cron/error_email_identity';
- /**
- * 'Send error emails to' configuration
- */
- const XML_PATH_ERROR_RECIPIENT = 'catalog/productalert_cron/error_email';
- /**
- * Allow price alert
- *
- */
- const XML_PATH_PRICE_ALLOW = 'catalog/productalert/allow_price';
- /**
- * Allow stock alert
- *
- */
- const XML_PATH_STOCK_ALLOW = 'catalog/productalert/allow_stock';
- /**
- * Website collection array
- *
- * @var array
- */
- protected $_websites;
- /**
- * Warning (exception) errors array
- *
- * @var array
- */
- protected $_errors = [];
- /**
- * Catalog data
- *
- * @var \Magento\Catalog\Helper\Data
- */
- protected $_catalogData = null;
- /**
- * Core store config
- *
- * @var \Magento\Framework\App\Config\ScopeConfigInterface
- */
- protected $_scopeConfig;
- /**
- * @var \Magento\Store\Model\StoreManagerInterface
- */
- protected $_storeManager;
- /**
- * @var \Magento\ProductAlert\Model\ResourceModel\Price\CollectionFactory
- */
- protected $_priceColFactory;
- /**
- * @var \Magento\Customer\Api\CustomerRepositoryInterface
- */
- protected $customerRepository;
- /**
- * @var \Magento\Catalog\Api\ProductRepositoryInterface
- */
- protected $productRepository;
- /**
- * @var \Magento\Framework\Stdlib\DateTime\DateTimeFactory
- */
- protected $_dateFactory;
- /**
- * @var \Magento\ProductAlert\Model\ResourceModel\Stock\CollectionFactory
- */
- protected $_stockColFactory;
- /**
- * @var \Magento\Framework\Mail\Template\TransportBuilder
- */
- protected $_transportBuilder;
- /**
- * @var \Magento\ProductAlert\Model\EmailFactory
- */
- protected $_emailFactory;
- /**
- * @var \Magento\Framework\Translate\Inline\StateInterface
- */
- protected $inlineTranslation;
- /**
- * @var ProductSalability
- */
- protected $productSalability;
- /**
- * @param \Magento\Catalog\Helper\Data $catalogData
- * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
- * @param \Magento\Store\Model\StoreManagerInterface $storeManager
- * @param \Magento\ProductAlert\Model\ResourceModel\Price\CollectionFactory $priceColFactory
- * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
- * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
- * @param \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory
- * @param \Magento\ProductAlert\Model\ResourceModel\Stock\CollectionFactory $stockColFactory
- * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
- * @param \Magento\ProductAlert\Model\EmailFactory $emailFactory
- * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
- * @param ProductSalability|null $productSalability
- * @SuppressWarnings(PHPMD.ExcessiveParameterList)
- */
- public function __construct(
- \Magento\Catalog\Helper\Data $catalogData,
- \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
- \Magento\Store\Model\StoreManagerInterface $storeManager,
- \Magento\ProductAlert\Model\ResourceModel\Price\CollectionFactory $priceColFactory,
- \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
- \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
- \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory,
- \Magento\ProductAlert\Model\ResourceModel\Stock\CollectionFactory $stockColFactory,
- \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
- \Magento\ProductAlert\Model\EmailFactory $emailFactory,
- \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
- ProductSalability $productSalability = null
- ) {
- $this->_catalogData = $catalogData;
- $this->_scopeConfig = $scopeConfig;
- $this->_storeManager = $storeManager;
- $this->_priceColFactory = $priceColFactory;
- $this->customerRepository = $customerRepository;
- $this->productRepository = $productRepository;
- $this->_dateFactory = $dateFactory;
- $this->_stockColFactory = $stockColFactory;
- $this->_transportBuilder = $transportBuilder;
- $this->_emailFactory = $emailFactory;
- $this->inlineTranslation = $inlineTranslation;
- $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
- $this->productSalability = $productSalability ?: $objectManager->get(ProductSalability::class);
- }
- /**
- * Retrieve website collection array
- *
- * @return array
- * @throws \Exception
- */
- protected function _getWebsites()
- {
- if ($this->_websites === null) {
- try {
- $this->_websites = $this->_storeManager->getWebsites();
- } catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
- throw $e;
- }
- }
- return $this->_websites;
- }
- /**
- * Process price emails
- *
- * @param \Magento\ProductAlert\Model\Email $email
- * @return $this
- * @throws \Exception
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- protected function _processPrice(\Magento\ProductAlert\Model\Email $email)
- {
- $email->setType('price');
- foreach ($this->_getWebsites() as $website) {
- /* @var $website \Magento\Store\Model\Website */
- if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) {
- continue;
- }
- if (!$this->_scopeConfig->getValue(
- self::XML_PATH_PRICE_ALLOW,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
- $website->getDefaultGroup()->getDefaultStore()->getId()
- )
- ) {
- continue;
- }
- try {
- $collection = $this->_priceColFactory->create()->addWebsiteFilter(
- $website->getId()
- )->setCustomerOrder();
- } catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
- throw $e;
- }
- $previousCustomer = null;
- $email->setWebsite($website);
- foreach ($collection as $alert) {
- $this->setAlertStoreId($alert, $email);
- try {
- if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) {
- $customer = $this->customerRepository->getById($alert->getCustomerId());
- if ($previousCustomer) {
- $email->send();
- }
- if (!$customer) {
- continue;
- }
- $previousCustomer = $customer;
- $email->clean();
- $email->setCustomerData($customer);
- } else {
- $customer = $previousCustomer;
- }
- $product = $this->productRepository->getById(
- $alert->getProductId(),
- false,
- $website->getDefaultStore()->getId()
- );
- $product->setCustomerGroupId($customer->getGroupId());
- if ($alert->getPrice() > $product->getFinalPrice()) {
- $productPrice = $product->getFinalPrice();
- $product->setFinalPrice($this->_catalogData->getTaxPrice($product, $productPrice));
- $product->setPrice($this->_catalogData->getTaxPrice($product, $product->getPrice()));
- $email->addPriceProduct($product);
- $alert->setPrice($productPrice);
- $alert->setLastSendDate($this->_dateFactory->create()->gmtDate());
- $alert->setSendCount($alert->getSendCount() + 1);
- $alert->setStatus(1);
- $alert->save();
- }
- } catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
- throw $e;
- }
- }
- if ($previousCustomer) {
- try {
- $email->send();
- } catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
- throw $e;
- }
- }
- }
- return $this;
- }
- /**
- * Process stock emails
- *
- * @param \Magento\ProductAlert\Model\Email $email
- * @return $this
- * @throws \Exception
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- protected function _processStock(\Magento\ProductAlert\Model\Email $email)
- {
- $email->setType('stock');
- foreach ($this->_getWebsites() as $website) {
- /* @var $website \Magento\Store\Model\Website */
- if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) {
- continue;
- }
- if (!$this->_scopeConfig->getValue(
- self::XML_PATH_STOCK_ALLOW,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
- $website->getDefaultGroup()->getDefaultStore()->getId()
- )
- ) {
- continue;
- }
- try {
- $collection = $this->_stockColFactory->create()->addWebsiteFilter(
- $website->getId()
- )->addStatusFilter(
- 0
- )->setCustomerOrder();
- } catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
- throw $e;
- }
- $previousCustomer = null;
- $email->setWebsite($website);
- foreach ($collection as $alert) {
- $this->setAlertStoreId($alert, $email);
- try {
- if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) {
- $customer = $this->customerRepository->getById($alert->getCustomerId());
- if ($previousCustomer) {
- $email->send();
- }
- if (!$customer) {
- continue;
- }
- $previousCustomer = $customer;
- $email->clean();
- $email->setCustomerData($customer);
- } else {
- $customer = $previousCustomer;
- }
- $product = $this->productRepository->getById(
- $alert->getProductId(),
- false,
- $website->getDefaultStore()->getId()
- );
- $product->setCustomerGroupId($customer->getGroupId());
- if ($this->productSalability->isSalable($product, $website)) {
- $email->addStockProduct($product);
- $alert->setSendDate($this->_dateFactory->create()->gmtDate());
- $alert->setSendCount($alert->getSendCount() + 1);
- $alert->setStatus(1);
- $alert->save();
- }
- } catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
- throw $e;
- }
- }
- if ($previousCustomer) {
- try {
- $email->send();
- } catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
- throw $e;
- }
- }
- }
- return $this;
- }
- /**
- * Send email to administrator if error
- *
- * @return $this
- */
- protected function _sendErrorEmail()
- {
- if (count($this->_errors)) {
- if (!$this->_scopeConfig->getValue(
- self::XML_PATH_ERROR_TEMPLATE,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE
- )
- ) {
- return $this;
- }
- $this->inlineTranslation->suspend();
- $transport = $this->_transportBuilder->setTemplateIdentifier(
- $this->_scopeConfig->getValue(
- self::XML_PATH_ERROR_TEMPLATE,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE
- )
- )->setTemplateOptions(
- [
- 'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE,
- 'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
- ]
- )->setTemplateVars(
- ['warnings' => join("\n", $this->_errors)]
- )->setFrom(
- $this->_scopeConfig->getValue(
- self::XML_PATH_ERROR_IDENTITY,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE
- )
- )->addTo(
- $this->_scopeConfig->getValue(
- self::XML_PATH_ERROR_RECIPIENT,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE
- )
- )->getTransport();
- $transport->sendMessage();
- $this->inlineTranslation->resume();
- $this->_errors[] = [];
- }
- return $this;
- }
- /**
- * Run process send product alerts
- *
- * @return $this
- */
- public function process()
- {
- /* @var $email \Magento\ProductAlert\Model\Email */
- $email = $this->_emailFactory->create();
- $this->_processPrice($email);
- $this->_processStock($email);
- $this->_sendErrorEmail();
- return $this;
- }
- /**
- * Set alert store id.
- *
- * @param \Magento\ProductAlert\Model\Price|\Magento\ProductAlert\Model\Stock $alert
- * @param Email $email
- * @return Observer
- */
- private function setAlertStoreId($alert, \Magento\ProductAlert\Model\Email $email) : Observer
- {
- $alertStoreId = $alert->getStoreId();
- if ($alertStoreId) {
- $email->setStoreId((int)$alertStoreId);
- }
- return $this;
- }
- }
|