如何处理 Magento 2 中覆盖 Magento\Sales\Model\Order\Email\Sender\OrderSender 的冲突
How to handle conflict in overriding Magento\Sales\Model\Order\Email\Sender\OrderSender in Magento 2
由于创建自定义支付模块,我在覆盖 Magento 2 中的 OrderSender 模型时遇到了一段时间的问题。
首先,我无法阻止在下订单后发送电子邮件(无论成功与否),这是一个问题,所以我决定创建一个流程来覆盖 OrderSender 使用通过在模块中指定首选项文件来建议进程,即
class OrderSender extends \Magento\Sales\Model\Order\Email\Sender\OrderSender{
/**
* Sends order email to the customer.
*
* Email will be sent immediately in two cases:
*
* - if asynchronous email sending is disabled in global settings
* - if $forceSyncMode parameter is set to TRUE
*
* Otherwise, email will be sent later during running of
* corresponding cron job.
*
* @param Order $order
* @param bool $forceSyncMode
* @return bool
*/
public function send(Order $order, $forceSyncMode = false)
{
$payment = $order->getPayment()->getMethodInstance()->getCode();
//allow other module or payment to proceed should in case it is not my payment module is calling for order sender.
if($payment == 'afronijapay' && !$forceSyncMode){
return false;
}
$order->setSendEmail(true);
if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) {
if ($this->checkAndSend($order)) {
$order->setEmailSent(true);
$this->orderResource->saveAttribute($order, ['send_email', 'email_sent']);
return true;
}
}
$this->orderResource->saveAttribute($order, 'send_email');
return false;
}}
如上所示,因此一切正常,我是在完成我的流程后发送电子邮件,然后在付款成功时调用以下命令。
//send new order email
$this->_checkout_session->setForceOrderMailSentOnSuccess(true);
$this->_orderSender->send($order, true);
再次,我发现这是来自多个来源的一些建议解决方案,包括 Whosebug/stackexchange 和所有来源。
然而,尽管如此,我想到了另一个问题,即如果有人已经从另一个模块覆盖了这个 class 并且 Magento 2 使用了覆盖 class 而没有我的问题怎么办可能会再次发生。
我使用不同的命名空间和供应商名称构建了另一个支付模块(只是原件的副本),我的恐惧暴露了,因为 Magento 2 忽略了一个 classes 覆盖 OrderSender class 并使用另一个,从而使问题重新开始出现。
对于如何解决此问题的任何建议,我将不胜感激。谢谢
经过多次尝试,我终于想出了这个方案
在您的
中创建一个活动
<Vendor>/<ModuleName>/etc.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_order_place_after">
<observer name="<vendor>_<modulename>_event_email_stopper" instance="<Vendor>\<ModuleName>\Event\EmailStopper\Order\Email" />
</event>
</config>
然后在目录下创建一个名为Email.php的class
\\Event\EmailStopper\Order\ 内容如下
namespace <Vendor>\<ModuleName>\Event\EmailStopper\Order;
class Email implements \Magento\Framework\Event\ObserverInterface
{
public function execute(\Magento\Framework\Event\Observer $observer)
{
$this->objectManager = \Magento\Framework\App\ObjectManager::getInstance();
try{
$order = $observer->getEvent()->getOrder();
$this->_current_order = $order;
$payment = $order->getPayment()->getMethodInstance()->getCode();
if($payment == 'chukplcspredirect' || $payment == 'chukplcspdirect'){
$this->stopNewOrderEmail($order);
}
}
catch (\ErrorException $ee){
}
catch (\Exception $ex)
{
}
catch (\Error $error){
}
}
public function stopNewOrderEmail(\Magento\Sales\Model\Order $order){
$order->setCanSendNewEmailFlag(false);
$order->setSendEmail(false);
try{
$order->save();
}
catch (\ErrorException $ee){
}
catch (\Exception $ex)
{
}
catch (\Error $error){
}
}
}
完成后,您可以使用以下代码轻松发送订单电子邮件
$order->setCanSendNewEmailFlag(true);
$order->save();
$this->_checkout_session->setForceOrderMailSentOnSuccess(true);
$this->_orderSender->send($order, true);
由于创建自定义支付模块,我在覆盖 Magento 2 中的 OrderSender 模型时遇到了一段时间的问题。
首先,我无法阻止在下订单后发送电子邮件(无论成功与否),这是一个问题,所以我决定创建一个流程来覆盖 OrderSender 使用通过在模块中指定首选项文件来建议进程,即
class OrderSender extends \Magento\Sales\Model\Order\Email\Sender\OrderSender{
/**
* Sends order email to the customer.
*
* Email will be sent immediately in two cases:
*
* - if asynchronous email sending is disabled in global settings
* - if $forceSyncMode parameter is set to TRUE
*
* Otherwise, email will be sent later during running of
* corresponding cron job.
*
* @param Order $order
* @param bool $forceSyncMode
* @return bool
*/
public function send(Order $order, $forceSyncMode = false)
{
$payment = $order->getPayment()->getMethodInstance()->getCode();
//allow other module or payment to proceed should in case it is not my payment module is calling for order sender.
if($payment == 'afronijapay' && !$forceSyncMode){
return false;
}
$order->setSendEmail(true);
if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) {
if ($this->checkAndSend($order)) {
$order->setEmailSent(true);
$this->orderResource->saveAttribute($order, ['send_email', 'email_sent']);
return true;
}
}
$this->orderResource->saveAttribute($order, 'send_email');
return false;
}}
如上所示,因此一切正常,我是在完成我的流程后发送电子邮件,然后在付款成功时调用以下命令。
//send new order email
$this->_checkout_session->setForceOrderMailSentOnSuccess(true);
$this->_orderSender->send($order, true);
再次,我发现这是来自多个来源的一些建议解决方案,包括 Whosebug/stackexchange 和所有来源。
然而,尽管如此,我想到了另一个问题,即如果有人已经从另一个模块覆盖了这个 class 并且 Magento 2 使用了覆盖 class 而没有我的问题怎么办可能会再次发生。
我使用不同的命名空间和供应商名称构建了另一个支付模块(只是原件的副本),我的恐惧暴露了,因为 Magento 2 忽略了一个 classes 覆盖 OrderSender class 并使用另一个,从而使问题重新开始出现。
对于如何解决此问题的任何建议,我将不胜感激。谢谢
经过多次尝试,我终于想出了这个方案
在您的
中创建一个活动<Vendor>/<ModuleName>/etc.xml
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="sales_order_place_after"> <observer name="<vendor>_<modulename>_event_email_stopper" instance="<Vendor>\<ModuleName>\Event\EmailStopper\Order\Email" /> </event> </config>
然后在目录下创建一个名为Email.php的class \\Event\EmailStopper\Order\ 内容如下
namespace <Vendor>\<ModuleName>\Event\EmailStopper\Order;
class Email implements \Magento\Framework\Event\ObserverInterface
{
public function execute(\Magento\Framework\Event\Observer $observer)
{
$this->objectManager = \Magento\Framework\App\ObjectManager::getInstance();
try{
$order = $observer->getEvent()->getOrder();
$this->_current_order = $order;
$payment = $order->getPayment()->getMethodInstance()->getCode();
if($payment == 'chukplcspredirect' || $payment == 'chukplcspdirect'){
$this->stopNewOrderEmail($order);
}
}
catch (\ErrorException $ee){
}
catch (\Exception $ex)
{
}
catch (\Error $error){
}
}
public function stopNewOrderEmail(\Magento\Sales\Model\Order $order){
$order->setCanSendNewEmailFlag(false);
$order->setSendEmail(false);
try{
$order->save();
}
catch (\ErrorException $ee){
}
catch (\Exception $ex)
{
}
catch (\Error $error){
}
}
}
完成后,您可以使用以下代码轻松发送订单电子邮件
$order->setCanSendNewEmailFlag(true);
$order->save();
$this->_checkout_session->setForceOrderMailSentOnSuccess(true);
$this->_orderSender->send($order, true);