PageRenderTime 44ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/magento/module-product-alert/Model/Observer.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 414 lines | 249 code | 43 blank | 122 comment | 25 complexity | 6dd3e5279d9a2939ed6a8bed19e6761f MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\ProductAlert\Model;
  7. /**
  8. * ProductAlert observer
  9. *
  10. * @author Magento Core Team <core@magentocommerce.com>
  11. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  12. */
  13. class Observer
  14. {
  15. /**
  16. * Error email template configuration
  17. */
  18. const XML_PATH_ERROR_TEMPLATE = 'catalog/productalert_cron/error_email_template';
  19. /**
  20. * Error email identity configuration
  21. */
  22. const XML_PATH_ERROR_IDENTITY = 'catalog/productalert_cron/error_email_identity';
  23. /**
  24. * 'Send error emails to' configuration
  25. */
  26. const XML_PATH_ERROR_RECIPIENT = 'catalog/productalert_cron/error_email';
  27. /**
  28. * Allow price alert
  29. *
  30. */
  31. const XML_PATH_PRICE_ALLOW = 'catalog/productalert/allow_price';
  32. /**
  33. * Allow stock alert
  34. *
  35. */
  36. const XML_PATH_STOCK_ALLOW = 'catalog/productalert/allow_stock';
  37. /**
  38. * Website collection array
  39. *
  40. * @var array
  41. */
  42. protected $_websites;
  43. /**
  44. * Warning (exception) errors array
  45. *
  46. * @var array
  47. */
  48. protected $_errors = [];
  49. /**
  50. * Catalog data
  51. *
  52. * @var \Magento\Catalog\Helper\Data
  53. */
  54. protected $_catalogData = null;
  55. /**
  56. * Core store config
  57. *
  58. * @var \Magento\Framework\App\Config\ScopeConfigInterface
  59. */
  60. protected $_scopeConfig;
  61. /**
  62. * @var \Magento\Store\Model\StoreManagerInterface
  63. */
  64. protected $_storeManager;
  65. /**
  66. * @var \Magento\ProductAlert\Model\ResourceModel\Price\CollectionFactory
  67. */
  68. protected $_priceColFactory;
  69. /**
  70. * @var \Magento\Customer\Api\CustomerRepositoryInterface
  71. */
  72. protected $customerRepository;
  73. /**
  74. * @var \Magento\Catalog\Api\ProductRepositoryInterface
  75. */
  76. protected $productRepository;
  77. /**
  78. * @var \Magento\Framework\Stdlib\DateTime\DateTimeFactory
  79. */
  80. protected $_dateFactory;
  81. /**
  82. * @var \Magento\ProductAlert\Model\ResourceModel\Stock\CollectionFactory
  83. */
  84. protected $_stockColFactory;
  85. /**
  86. * @var \Magento\Framework\Mail\Template\TransportBuilder
  87. */
  88. protected $_transportBuilder;
  89. /**
  90. * @var \Magento\ProductAlert\Model\EmailFactory
  91. */
  92. protected $_emailFactory;
  93. /**
  94. * @var \Magento\Framework\Translate\Inline\StateInterface
  95. */
  96. protected $inlineTranslation;
  97. /**
  98. * @param \Magento\Catalog\Helper\Data $catalogData
  99. * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  100. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  101. * @param \Magento\ProductAlert\Model\ResourceModel\Price\CollectionFactory $priceColFactory
  102. * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
  103. * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
  104. * @param \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory
  105. * @param \Magento\ProductAlert\Model\ResourceModel\Stock\CollectionFactory $stockColFactory
  106. * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
  107. * @param \Magento\ProductAlert\Model\EmailFactory $emailFactory
  108. * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
  109. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  110. */
  111. public function __construct(
  112. \Magento\Catalog\Helper\Data $catalogData,
  113. \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
  114. \Magento\Store\Model\StoreManagerInterface $storeManager,
  115. \Magento\ProductAlert\Model\ResourceModel\Price\CollectionFactory $priceColFactory,
  116. \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
  117. \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
  118. \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory,
  119. \Magento\ProductAlert\Model\ResourceModel\Stock\CollectionFactory $stockColFactory,
  120. \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
  121. \Magento\ProductAlert\Model\EmailFactory $emailFactory,
  122. \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
  123. ) {
  124. $this->_catalogData = $catalogData;
  125. $this->_scopeConfig = $scopeConfig;
  126. $this->_storeManager = $storeManager;
  127. $this->_priceColFactory = $priceColFactory;
  128. $this->customerRepository = $customerRepository;
  129. $this->productRepository = $productRepository;
  130. $this->_dateFactory = $dateFactory;
  131. $this->_stockColFactory = $stockColFactory;
  132. $this->_transportBuilder = $transportBuilder;
  133. $this->_emailFactory = $emailFactory;
  134. $this->inlineTranslation = $inlineTranslation;
  135. }
  136. /**
  137. * Retrieve website collection array
  138. *
  139. * @return array
  140. */
  141. protected function _getWebsites()
  142. {
  143. if ($this->_websites === null) {
  144. try {
  145. $this->_websites = $this->_storeManager->getWebsites();
  146. } catch (\Exception $e) {
  147. $this->_errors[] = $e->getMessage();
  148. }
  149. }
  150. return $this->_websites;
  151. }
  152. /**
  153. * Process price emails
  154. *
  155. * @param \Magento\ProductAlert\Model\Email $email
  156. * @return $this
  157. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  158. * @SuppressWarnings(PHPMD.NPathComplexity)
  159. */
  160. protected function _processPrice(\Magento\ProductAlert\Model\Email $email)
  161. {
  162. $email->setType('price');
  163. foreach ($this->_getWebsites() as $website) {
  164. /* @var $website \Magento\Store\Model\Website */
  165. if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) {
  166. continue;
  167. }
  168. if (!$this->_scopeConfig->getValue(
  169. self::XML_PATH_PRICE_ALLOW,
  170. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  171. $website->getDefaultGroup()->getDefaultStore()->getId()
  172. )
  173. ) {
  174. continue;
  175. }
  176. try {
  177. $collection = $this->_priceColFactory->create()->addWebsiteFilter(
  178. $website->getId()
  179. )->setCustomerOrder();
  180. } catch (\Exception $e) {
  181. $this->_errors[] = $e->getMessage();
  182. return $this;
  183. }
  184. $previousCustomer = null;
  185. $email->setWebsite($website);
  186. foreach ($collection as $alert) {
  187. try {
  188. if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) {
  189. $customer = $this->customerRepository->getById($alert->getCustomerId());
  190. if ($previousCustomer) {
  191. $email->send();
  192. }
  193. if (!$customer) {
  194. continue;
  195. }
  196. $previousCustomer = $customer;
  197. $email->clean();
  198. $email->setCustomerData($customer);
  199. } else {
  200. $customer = $previousCustomer;
  201. }
  202. $product = $this->productRepository->getById(
  203. $alert->getProductId(),
  204. false,
  205. $website->getDefaultStore()->getId()
  206. );
  207. $product->setCustomerGroupId($customer->getGroupId());
  208. if ($alert->getPrice() > $product->getFinalPrice()) {
  209. $productPrice = $product->getFinalPrice();
  210. $product->setFinalPrice($this->_catalogData->getTaxPrice($product, $productPrice));
  211. $product->setPrice($this->_catalogData->getTaxPrice($product, $product->getPrice()));
  212. $email->addPriceProduct($product);
  213. $alert->setPrice($productPrice);
  214. $alert->setLastSendDate($this->_dateFactory->create()->gmtDate());
  215. $alert->setSendCount($alert->getSendCount() + 1);
  216. $alert->setStatus(1);
  217. $alert->save();
  218. }
  219. } catch (\Exception $e) {
  220. $this->_errors[] = $e->getMessage();
  221. }
  222. }
  223. if ($previousCustomer) {
  224. try {
  225. $email->send();
  226. } catch (\Exception $e) {
  227. $this->_errors[] = $e->getMessage();
  228. }
  229. }
  230. }
  231. return $this;
  232. }
  233. /**
  234. * Process stock emails
  235. *
  236. * @param \Magento\ProductAlert\Model\Email $email
  237. * @return $this
  238. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  239. * @SuppressWarnings(PHPMD.NPathComplexity)
  240. */
  241. protected function _processStock(\Magento\ProductAlert\Model\Email $email)
  242. {
  243. $email->setType('stock');
  244. foreach ($this->_getWebsites() as $website) {
  245. /* @var $website \Magento\Store\Model\Website */
  246. if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) {
  247. continue;
  248. }
  249. if (!$this->_scopeConfig->getValue(
  250. self::XML_PATH_STOCK_ALLOW,
  251. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  252. $website->getDefaultGroup()->getDefaultStore()->getId()
  253. )
  254. ) {
  255. continue;
  256. }
  257. try {
  258. $collection = $this->_stockColFactory->create()->addWebsiteFilter(
  259. $website->getId()
  260. )->addStatusFilter(
  261. 0
  262. )->setCustomerOrder();
  263. } catch (\Exception $e) {
  264. $this->_errors[] = $e->getMessage();
  265. return $this;
  266. }
  267. $previousCustomer = null;
  268. $email->setWebsite($website);
  269. foreach ($collection as $alert) {
  270. try {
  271. if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) {
  272. $customer = $this->customerRepository->getById($alert->getCustomerId());
  273. if ($previousCustomer) {
  274. $email->send();
  275. }
  276. if (!$customer) {
  277. continue;
  278. }
  279. $previousCustomer = $customer;
  280. $email->clean();
  281. $email->setCustomerData($customer);
  282. } else {
  283. $customer = $previousCustomer;
  284. }
  285. $product = $this->productRepository->getById(
  286. $alert->getProductId(),
  287. false,
  288. $website->getDefaultStore()->getId()
  289. );
  290. $product->setCustomerGroupId($customer->getGroupId());
  291. if ($product->isSalable()) {
  292. $email->addStockProduct($product);
  293. $alert->setSendDate($this->_dateFactory->create()->gmtDate());
  294. $alert->setSendCount($alert->getSendCount() + 1);
  295. $alert->setStatus(1);
  296. $alert->save();
  297. }
  298. } catch (\Exception $e) {
  299. $this->_errors[] = $e->getMessage();
  300. }
  301. }
  302. if ($previousCustomer) {
  303. try {
  304. $email->send();
  305. } catch (\Exception $e) {
  306. $this->_errors[] = $e->getMessage();
  307. }
  308. }
  309. }
  310. return $this;
  311. }
  312. /**
  313. * Send email to administrator if error
  314. *
  315. * @return $this
  316. */
  317. protected function _sendErrorEmail()
  318. {
  319. if (count($this->_errors)) {
  320. if (!$this->_scopeConfig->getValue(
  321. self::XML_PATH_ERROR_TEMPLATE,
  322. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  323. )
  324. ) {
  325. return $this;
  326. }
  327. $this->inlineTranslation->suspend();
  328. $transport = $this->_transportBuilder->setTemplateIdentifier(
  329. $this->_scopeConfig->getValue(
  330. self::XML_PATH_ERROR_TEMPLATE,
  331. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  332. )
  333. )->setTemplateOptions(
  334. [
  335. 'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE,
  336. 'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
  337. ]
  338. )->setTemplateVars(
  339. ['warnings' => join("\n", $this->_errors)]
  340. )->setFrom(
  341. $this->_scopeConfig->getValue(
  342. self::XML_PATH_ERROR_IDENTITY,
  343. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  344. )
  345. )->addTo(
  346. $this->_scopeConfig->getValue(
  347. self::XML_PATH_ERROR_RECIPIENT,
  348. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  349. )
  350. )->getTransport();
  351. $transport->sendMessage();
  352. $this->inlineTranslation->resume();
  353. $this->_errors[] = [];
  354. }
  355. return $this;
  356. }
  357. /**
  358. * Run process send product alerts
  359. *
  360. * @return $this
  361. */
  362. public function process()
  363. {
  364. /* @var $email \Magento\ProductAlert\Model\Email */
  365. $email = $this->_emailFactory->create();
  366. $this->_processPrice($email);
  367. $this->_processStock($email);
  368. $this->_sendErrorEmail();
  369. return $this;
  370. }
  371. }