mirror of
https://github.com/bdnugget/magento2.git
synced 2026-11-07 17:27:36 +00:00
459 lines
11 KiB
PHP
459 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
namespace Magento\ProductAlert\Model;
|
|
|
|
use Magento\Catalog\Model\Product;
|
|
use Magento\Customer\Api\CustomerRepositoryInterface;
|
|
use Magento\Customer\Api\Data\CustomerInterface;
|
|
use Magento\Customer\Helper\View;
|
|
use Magento\Framework\App\Area;
|
|
use Magento\Framework\App\Config\ScopeConfigInterface;
|
|
use Magento\Framework\Data\Collection\AbstractDb;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use Magento\Framework\Exception\MailException;
|
|
use Magento\Framework\Exception\NoSuchEntityException;
|
|
use Magento\Framework\Mail\Template\TransportBuilder;
|
|
use Magento\Framework\Model\AbstractModel;
|
|
use Magento\Framework\Model\Context;
|
|
use Magento\Framework\Model\ResourceModel\AbstractResource;
|
|
use Magento\Framework\Registry;
|
|
use Magento\ProductAlert\Block\Email\AbstractEmail;
|
|
use Magento\ProductAlert\Block\Email\Price;
|
|
use Magento\ProductAlert\Block\Email\Stock;
|
|
use Magento\ProductAlert\Helper\Data;
|
|
use Magento\Store\Api\Data\StoreInterface;
|
|
use Magento\Store\Model\App\Emulation;
|
|
use Magento\Store\Model\ScopeInterface;
|
|
use Magento\Store\Model\StoreManagerInterface;
|
|
use Magento\Store\Model\Website;
|
|
|
|
/**
|
|
* ProductAlert Email processor
|
|
*
|
|
* @author Magento Core Team <core@magentocommerce.com>
|
|
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
|
*
|
|
* @api
|
|
* @since 100.0.2
|
|
* @method int getStoreId()
|
|
* @method $this setStoreId(int $storeId)
|
|
*/
|
|
class Email extends AbstractModel
|
|
{
|
|
const XML_PATH_EMAIL_PRICE_TEMPLATE = 'catalog/productalert/email_price_template';
|
|
|
|
const XML_PATH_EMAIL_STOCK_TEMPLATE = 'catalog/productalert/email_stock_template';
|
|
|
|
const XML_PATH_EMAIL_IDENTITY = 'catalog/productalert/email_identity';
|
|
|
|
/**
|
|
* Type
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $_type = 'price';
|
|
|
|
/**
|
|
* Website Model
|
|
*
|
|
* @var Website
|
|
*/
|
|
protected $_website;
|
|
|
|
/**
|
|
* Customer model
|
|
*
|
|
* @var CustomerInterface
|
|
*/
|
|
protected $_customer;
|
|
|
|
/**
|
|
* Products collection where changed price
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $_priceProducts = [];
|
|
|
|
/**
|
|
* Product collection which of back in stock
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $_stockProducts = [];
|
|
|
|
/**
|
|
* Price block
|
|
*
|
|
* @var Price
|
|
*/
|
|
protected $_priceBlock;
|
|
|
|
/**
|
|
* Stock block
|
|
*
|
|
* @var Stock
|
|
*/
|
|
protected $_stockBlock;
|
|
|
|
/**
|
|
* Product alert data
|
|
*
|
|
* @var Data
|
|
*/
|
|
protected $_productAlertData = null;
|
|
|
|
/**
|
|
* Core store config
|
|
*
|
|
* @var ScopeConfigInterface
|
|
*/
|
|
protected $_scopeConfig;
|
|
|
|
/**
|
|
* @var StoreManagerInterface
|
|
*/
|
|
protected $_storeManager;
|
|
|
|
/**
|
|
* @var CustomerRepositoryInterface
|
|
*/
|
|
protected $customerRepository;
|
|
|
|
/**
|
|
* @var Emulation
|
|
*/
|
|
protected $_appEmulation;
|
|
|
|
/**
|
|
* @var TransportBuilder
|
|
*/
|
|
protected $_transportBuilder;
|
|
|
|
/**
|
|
* @var View
|
|
*/
|
|
protected $_customerHelper;
|
|
|
|
/**
|
|
* @param Context $context
|
|
* @param Registry $registry
|
|
* @param Data $productAlertData
|
|
* @param ScopeConfigInterface $scopeConfig
|
|
* @param StoreManagerInterface $storeManager
|
|
* @param CustomerRepositoryInterface $customerRepository
|
|
* @param View $customerHelper
|
|
* @param Emulation $appEmulation
|
|
* @param TransportBuilder $transportBuilder
|
|
* @param AbstractResource $resource
|
|
* @param AbstractDb $resourceCollection
|
|
* @param array $data
|
|
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
|
|
*/
|
|
public function __construct(
|
|
Context $context,
|
|
Registry $registry,
|
|
Data $productAlertData,
|
|
ScopeConfigInterface $scopeConfig,
|
|
StoreManagerInterface $storeManager,
|
|
CustomerRepositoryInterface $customerRepository,
|
|
View $customerHelper,
|
|
Emulation $appEmulation,
|
|
TransportBuilder $transportBuilder,
|
|
AbstractResource $resource = null,
|
|
AbstractDb $resourceCollection = null,
|
|
array $data = []
|
|
) {
|
|
$this->_productAlertData = $productAlertData;
|
|
$this->_scopeConfig = $scopeConfig;
|
|
$this->_storeManager = $storeManager;
|
|
$this->customerRepository = $customerRepository;
|
|
$this->_appEmulation = $appEmulation;
|
|
$this->_transportBuilder = $transportBuilder;
|
|
$this->_customerHelper = $customerHelper;
|
|
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
|
|
}
|
|
|
|
/**
|
|
* Set model type
|
|
*
|
|
* @param string $type
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setType($type)
|
|
{
|
|
$this->_type = $type;
|
|
}
|
|
|
|
/**
|
|
* Retrieve model type
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getType()
|
|
{
|
|
return $this->_type;
|
|
}
|
|
|
|
/**
|
|
* Set website model
|
|
*
|
|
* @param Website $website
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function setWebsite(Website $website)
|
|
{
|
|
$this->_website = $website;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set website id
|
|
*
|
|
* @param int $websiteId
|
|
*
|
|
* @return $this
|
|
* @throws LocalizedException
|
|
*/
|
|
public function setWebsiteId($websiteId)
|
|
{
|
|
$this->_website = $this->_storeManager->getWebsite($websiteId);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set customer by id
|
|
*
|
|
* @param int $customerId
|
|
*
|
|
* @return $this
|
|
* @throws LocalizedException
|
|
* @throws NoSuchEntityException
|
|
*/
|
|
public function setCustomerId($customerId)
|
|
{
|
|
$this->_customer = $this->customerRepository->getById($customerId);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set customer model
|
|
*
|
|
* @param CustomerInterface $customer
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function setCustomerData($customer)
|
|
{
|
|
$this->_customer = $customer;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Clean data
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function clean()
|
|
{
|
|
$this->_customer = null;
|
|
$this->_priceProducts = [];
|
|
$this->_stockProducts = [];
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Add product (price change) to collection
|
|
*
|
|
* @param Product $product
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function addPriceProduct(Product $product)
|
|
{
|
|
$this->_priceProducts[$product->getId()] = $product;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Add product (back in stock) to collection
|
|
*
|
|
* @param Product $product
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function addStockProduct(Product $product)
|
|
{
|
|
$this->_stockProducts[$product->getId()] = $product;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Retrieve price block
|
|
*
|
|
* @return Price
|
|
* @throws LocalizedException
|
|
*/
|
|
protected function _getPriceBlock()
|
|
{
|
|
if ($this->_priceBlock === null) {
|
|
$this->_priceBlock = $this->_productAlertData->createBlock(Price::class);
|
|
}
|
|
return $this->_priceBlock;
|
|
}
|
|
|
|
/**
|
|
* Retrieve stock block
|
|
*
|
|
* @return Stock
|
|
* @throws LocalizedException
|
|
*/
|
|
protected function _getStockBlock()
|
|
{
|
|
if ($this->_stockBlock === null) {
|
|
$this->_stockBlock = $this->_productAlertData->createBlock(Stock::class);
|
|
}
|
|
return $this->_stockBlock;
|
|
}
|
|
|
|
/**
|
|
* Send customer email
|
|
*
|
|
* @return bool
|
|
* @throws MailException
|
|
* @throws NoSuchEntityException
|
|
* @throws LocalizedException
|
|
*/
|
|
public function send()
|
|
{
|
|
if ($this->_website === null || $this->_customer === null || !$this->isExistDefaultStore()) {
|
|
return false;
|
|
}
|
|
|
|
$products = $this->getProducts();
|
|
$templateConfigPath = $this->getTemplateConfigPath();
|
|
if (!in_array($this->_type, ['price', 'stock']) || count($products) === 0 || !$templateConfigPath) {
|
|
return false;
|
|
}
|
|
|
|
$storeId = (int) $this->getStoreId() ?: (int) $this->_customer->getStoreId();
|
|
$store = $this->getStore($storeId);
|
|
|
|
$this->_appEmulation->startEnvironmentEmulation($storeId);
|
|
|
|
$block = $this->getBlock();
|
|
$block->setStore($store)->reset();
|
|
|
|
// Add products to the block
|
|
foreach ($products as $product) {
|
|
$product->setCustomerGroupId($this->_customer->getGroupId());
|
|
$block->addProduct($product);
|
|
}
|
|
|
|
$templateId = $this->_scopeConfig->getValue(
|
|
$templateConfigPath,
|
|
ScopeInterface::SCOPE_STORE,
|
|
$storeId
|
|
);
|
|
|
|
$alertGrid = $this->_appState->emulateAreaCode(
|
|
Area::AREA_FRONTEND,
|
|
[$block, 'toHtml']
|
|
);
|
|
$this->_appEmulation->stopEnvironmentEmulation();
|
|
|
|
$customerName = $this->_customerHelper->getCustomerName($this->_customer);
|
|
$this->_transportBuilder->setTemplateIdentifier(
|
|
$templateId
|
|
)->setTemplateOptions(
|
|
['area' => Area::AREA_FRONTEND, 'store' => $storeId]
|
|
)->setTemplateVars(
|
|
[
|
|
'customerName' => $customerName,
|
|
'alertGrid' => $alertGrid,
|
|
]
|
|
)->setFromByScope(
|
|
$this->_scopeConfig->getValue(
|
|
self::XML_PATH_EMAIL_IDENTITY,
|
|
ScopeInterface::SCOPE_STORE,
|
|
$storeId
|
|
),
|
|
$storeId
|
|
)->addTo(
|
|
$this->_customer->getEmail(),
|
|
$customerName
|
|
)->getTransport()->sendMessage();
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the store for the email
|
|
*
|
|
* @param int $storeId
|
|
* @return StoreInterface
|
|
* @throws NoSuchEntityException
|
|
*/
|
|
private function getStore(int $storeId): StoreInterface
|
|
{
|
|
return $this->_storeManager->getStore($storeId);
|
|
}
|
|
|
|
/**
|
|
* Retrieve the block for the email based on type
|
|
*
|
|
* @return Price|Stock
|
|
* @throws LocalizedException
|
|
*/
|
|
private function getBlock(): AbstractEmail
|
|
{
|
|
return $this->_type === 'price'
|
|
? $this->_getPriceBlock()
|
|
: $this->_getStockBlock();
|
|
}
|
|
|
|
/**
|
|
* Retrieve the products for the email based on type
|
|
*
|
|
* @return array
|
|
*/
|
|
private function getProducts(): array
|
|
{
|
|
return $this->_type === 'price'
|
|
? $this->_priceProducts
|
|
: $this->_stockProducts;
|
|
}
|
|
|
|
/**
|
|
* Retrieve template config path based on type
|
|
*
|
|
* @return string
|
|
*/
|
|
private function getTemplateConfigPath(): string
|
|
{
|
|
return $this->_type === 'price'
|
|
? self::XML_PATH_EMAIL_PRICE_TEMPLATE
|
|
: self::XML_PATH_EMAIL_STOCK_TEMPLATE;
|
|
}
|
|
|
|
/**
|
|
* Check if exists default store.
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function isExistDefaultStore(): bool
|
|
{
|
|
if (!$this->_website->getDefaultGroup() || !$this->_website->getDefaultGroup()->getDefaultStore()) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|