Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Observer.php
Go to the documentation of this file.
1 <?php
7 
14 class Observer
15 {
19  const XML_PATH_ERROR_TEMPLATE = 'catalog/productalert_cron/error_email_template';
20 
24  const XML_PATH_ERROR_IDENTITY = 'catalog/productalert_cron/error_email_identity';
25 
29  const XML_PATH_ERROR_RECIPIENT = 'catalog/productalert_cron/error_email';
30 
35  const XML_PATH_PRICE_ALLOW = 'catalog/productalert/allow_price';
36 
41  const XML_PATH_STOCK_ALLOW = 'catalog/productalert/allow_stock';
42 
48  protected $_websites;
49 
55  protected $_errors = [];
56 
62  protected $_catalogData = null;
63 
69  protected $_scopeConfig;
70 
74  protected $_storeManager;
75 
79  protected $_priceColFactory;
80 
85 
89  protected $productRepository;
90 
94  protected $_dateFactory;
95 
99  protected $_stockColFactory;
100 
105 
109  protected $_emailFactory;
110 
115 
120 
136  public function __construct(
137  \Magento\Catalog\Helper\Data $catalogData,
138  \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
140  \Magento\ProductAlert\Model\ResourceModel\Price\CollectionFactory $priceColFactory,
143  \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory,
144  \Magento\ProductAlert\Model\ResourceModel\Stock\CollectionFactory $stockColFactory,
145  \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
146  \Magento\ProductAlert\Model\EmailFactory $emailFactory,
147  \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
149  ) {
150  $this->_catalogData = $catalogData;
151  $this->_scopeConfig = $scopeConfig;
152  $this->_storeManager = $storeManager;
153  $this->_priceColFactory = $priceColFactory;
154  $this->customerRepository = $customerRepository;
155  $this->productRepository = $productRepository;
156  $this->_dateFactory = $dateFactory;
157  $this->_stockColFactory = $stockColFactory;
158  $this->_transportBuilder = $transportBuilder;
159  $this->_emailFactory = $emailFactory;
160  $this->inlineTranslation = $inlineTranslation;
162  $this->productSalability = $productSalability ?: $objectManager->get(ProductSalability::class);
163  }
164 
171  protected function _getWebsites()
172  {
173  if ($this->_websites === null) {
174  try {
175  $this->_websites = $this->_storeManager->getWebsites();
176  } catch (\Exception $e) {
177  $this->_errors[] = $e->getMessage();
178  throw $e;
179  }
180  }
181  return $this->_websites;
182  }
183 
193  protected function _processPrice(\Magento\ProductAlert\Model\Email $email)
194  {
195  $email->setType('price');
196  foreach ($this->_getWebsites() as $website) {
197  /* @var $website \Magento\Store\Model\Website */
198  if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) {
199  continue;
200  }
201  if (!$this->_scopeConfig->getValue(
202  self::XML_PATH_PRICE_ALLOW,
204  $website->getDefaultGroup()->getDefaultStore()->getId()
205  )
206  ) {
207  continue;
208  }
209  try {
210  $collection = $this->_priceColFactory->create()->addWebsiteFilter(
211  $website->getId()
212  )->setCustomerOrder();
213  } catch (\Exception $e) {
214  $this->_errors[] = $e->getMessage();
215  throw $e;
216  }
217 
218  $previousCustomer = null;
219  $email->setWebsite($website);
220  foreach ($collection as $alert) {
221  try {
222  if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) {
223  $customer = $this->customerRepository->getById($alert->getCustomerId());
224  if ($previousCustomer) {
225  $email->send();
226  }
227  if (!$customer) {
228  continue;
229  }
230  $previousCustomer = $customer;
231  $email->clean();
232  $email->setCustomerData($customer);
233  } else {
234  $customer = $previousCustomer;
235  }
236 
237  $product = $this->productRepository->getById(
238  $alert->getProductId(),
239  false,
240  $website->getDefaultStore()->getId()
241  );
242 
243  $product->setCustomerGroupId($customer->getGroupId());
244  if ($alert->getPrice() > $product->getFinalPrice()) {
245  $productPrice = $product->getFinalPrice();
246  $product->setFinalPrice($this->_catalogData->getTaxPrice($product, $productPrice));
247  $product->setPrice($this->_catalogData->getTaxPrice($product, $product->getPrice()));
248  $email->addPriceProduct($product);
249 
250  $alert->setPrice($productPrice);
251  $alert->setLastSendDate($this->_dateFactory->create()->gmtDate());
252  $alert->setSendCount($alert->getSendCount() + 1);
253  $alert->setStatus(1);
254  $alert->save();
255  }
256  } catch (\Exception $e) {
257  $this->_errors[] = $e->getMessage();
258  throw $e;
259  }
260  }
261  if ($previousCustomer) {
262  try {
263  $email->send();
264  } catch (\Exception $e) {
265  $this->_errors[] = $e->getMessage();
266  throw $e;
267  }
268  }
269  }
270  return $this;
271  }
272 
282  protected function _processStock(\Magento\ProductAlert\Model\Email $email)
283  {
284  $email->setType('stock');
285 
286  foreach ($this->_getWebsites() as $website) {
287  /* @var $website \Magento\Store\Model\Website */
288 
289  if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) {
290  continue;
291  }
292  if (!$this->_scopeConfig->getValue(
293  self::XML_PATH_STOCK_ALLOW,
295  $website->getDefaultGroup()->getDefaultStore()->getId()
296  )
297  ) {
298  continue;
299  }
300  try {
301  $collection = $this->_stockColFactory->create()->addWebsiteFilter(
302  $website->getId()
303  )->addStatusFilter(
304  0
305  )->setCustomerOrder();
306  } catch (\Exception $e) {
307  $this->_errors[] = $e->getMessage();
308  throw $e;
309  }
310 
311  $previousCustomer = null;
312  $email->setWebsite($website);
313  foreach ($collection as $alert) {
314  try {
315  if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) {
316  $customer = $this->customerRepository->getById($alert->getCustomerId());
317  if ($previousCustomer) {
318  $email->send();
319  }
320  if (!$customer) {
321  continue;
322  }
323  $previousCustomer = $customer;
324  $email->clean();
325  $email->setCustomerData($customer);
326  } else {
327  $customer = $previousCustomer;
328  }
329 
330  $product = $this->productRepository->getById(
331  $alert->getProductId(),
332  false,
333  $website->getDefaultStore()->getId()
334  );
335 
336  $product->setCustomerGroupId($customer->getGroupId());
337 
338  if ($this->productSalability->isSalable($product, $website)) {
339  $email->addStockProduct($product);
340 
341  $alert->setSendDate($this->_dateFactory->create()->gmtDate());
342  $alert->setSendCount($alert->getSendCount() + 1);
343  $alert->setStatus(1);
344  $alert->save();
345  }
346  } catch (\Exception $e) {
347  $this->_errors[] = $e->getMessage();
348  throw $e;
349  }
350  }
351 
352  if ($previousCustomer) {
353  try {
354  $email->send();
355  } catch (\Exception $e) {
356  $this->_errors[] = $e->getMessage();
357  throw $e;
358  }
359  }
360  }
361 
362  return $this;
363  }
364 
370  protected function _sendErrorEmail()
371  {
372  if (count($this->_errors)) {
373  if (!$this->_scopeConfig->getValue(
374  self::XML_PATH_ERROR_TEMPLATE,
376  )
377  ) {
378  return $this;
379  }
380 
381  $this->inlineTranslation->suspend();
382 
383  $transport = $this->_transportBuilder->setTemplateIdentifier(
384  $this->_scopeConfig->getValue(
385  self::XML_PATH_ERROR_TEMPLATE,
387  )
388  )->setTemplateOptions(
389  [
390  'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE,
391  'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
392  ]
393  )->setTemplateVars(
394  ['warnings' => join("\n", $this->_errors)]
395  )->setFrom(
396  $this->_scopeConfig->getValue(
397  self::XML_PATH_ERROR_IDENTITY,
399  )
400  )->addTo(
401  $this->_scopeConfig->getValue(
402  self::XML_PATH_ERROR_RECIPIENT,
404  )
405  )->getTransport();
406 
407  $transport->sendMessage();
408 
409  $this->inlineTranslation->resume();
410  $this->_errors[] = [];
411  }
412  return $this;
413  }
414 
420  public function process()
421  {
422  /* @var $email \Magento\ProductAlert\Model\Email */
423  $email = $this->_emailFactory->create();
424  $this->_processPrice($email);
425  $this->_processStock($email);
426  $this->_sendErrorEmail();
427 
428  return $this;
429  }
430 }
$objectManager
Definition: bootstrap.php:17
$customer
Definition: customers.php:11
$email
Definition: details.phtml:13
$storeManager
_processPrice(\Magento\ProductAlert\Model\Email $email)
Definition: Observer.php:193
_processStock(\Magento\ProductAlert\Model\Email $email)
Definition: Observer.php:282
__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)
Definition: Observer.php:136