0

Is their any way we can override Magento\Sales\Model\Order\Email\Sender.php model in magento 2 module ?

I have created below files

di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Sales\Model\Order\Email\Sender" type="Mod\Sales\Model\Order\Email\Sender" />
</config>


app/code/Mod/Sales/Model/Order/Email/Sender.php

I have added log in

protected function prepareTemplate(Order $order)
    {
        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/prepareTemplate.log');
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        $logger->info('$templateId');

but log did not generated.

Any thoughts ?

2
  • Any corrections ? – devhs Feb 24 at 5:25
  • Do you still need any help? – ZealousWeb Mar 4 at 7:18
1

Update

Updated the Observer Class


If you want to override the model Magento\Sales\Model\Order\Email\Sender\OrderSender just to extend the method prepareTemplate in order to add or modify email order template variables or change the template id, then its not the recommended approach.

Better observe the event email_order_set_template_vars_before and in your observer method add or modify the order email template variables as per your requirement.

Sample code added below

app/code/Vendor/Module/etc/events.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="email_order_set_template_vars_before">
        <observer name="email_order_set_template_vars_observer" instance="Vendor\Module\Observer\OrderEmailSetTemplateVars" />
    </event>
</config>

Observer class - app/code/Vendor/Module/Observer/OrderEmailSetTemplateVars.php

<?php

namespace Vendor\Module\Observer;

use Magento\Framework\Event\ObserverInterface;
use Psr\Log\LoggerInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Payment\Helper\Data as PaymentHelper;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Email\Container\OrderIdentity;
use Magento\Sales\Model\Order\Email\Container\Template;
use Magento\Sales\Model\ResourceModel\Order as OrderResource;
use Magento\Sales\Model\Order\Address\Renderer;
use Magento\Framework\DataObject;

class OrderEmailSetTemplateVars extends \Magento\Sales\Model\Order\Email\Sender implements ObserverInterface 
{
    /**
     * @var LoggerInterface
     */
    protected $logger;
    
    /**
     * @var Template
     */
    protected $templateContainer;

    
    /**
     * @var PaymentHelper
     */
    protected $paymentHelper;

    /**
     * @var OrderResource
     */
    protected $orderResource;

    /**
     * Global configuration storage.
     *
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $globalConfig;

    /**
     * @var Renderer
     */
    protected $addressRenderer;

    /**
     * Application Event Dispatcher
     *
     * @var ManagerInterface
     */
    protected $eventManager;

    /**
     * @param Template $templateContainer
     * @param OrderIdentity $identityContainer
     * @param Order\Email\SenderBuilderFactory $senderBuilderFactory
     * @param \Psr\Log\LoggerInterface $logger
     * @param Renderer $addressRenderer
     * @param PaymentHelper $paymentHelper
     * @param OrderResource $orderResource
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
     * @param ManagerInterface $eventManager
     */
    public function __construct(
        Template $templateContainer,
        OrderIdentity $identityContainer,
        \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory,
        \Psr\Log\LoggerInterface $logger,
        Renderer $addressRenderer,
        PaymentHelper $paymentHelper,
        OrderResource $orderResource,
        \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
    ) {
        parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger, $addressRenderer);
        $this->paymentHelper = $paymentHelper;
        $this->orderResource = $orderResource;
        $this->globalConfig = $globalConfig;
        $this->addressRenderer = $addressRenderer;
        $this->identityContainer = $identityContainer;
        $this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
        $this->templateContainer = $templateContainer;
    }
    

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $this->logger->debug('Observer '.__CLASS__.' called.');
        $transportObject = $observer->getEvent()->getTransport();
        
//        $transportObject = $observer->getEvent()->getTransportObject();
        $order = $transportObject->getOrder(); 
        $this->logger->debug('Order Id: ' . $order->getId());
        
        // you can use get this var in your order email template
        $transportObject->setData('test_var','Test Value'); // or $transportObject->getTestVar('Test Value');
        
        // get order's shipping method and set the email template based on that
        $shippingMethod = $order->getShippingMethod();
        $this->logger->debug('Order Shipping Method  ' . $shippingMethod);
        
        if ($this->templateContainer) {
            
            $this->templateContainer->setTemplateOptions($this->getTemplateOptions());

            if ($order->getCustomerIsGuest()) {
                $templateId = $this->identityContainer->getGuestTemplateId();
                $customerName = $order->getBillingAddress()->getName();
            } else {
                $templateId = $this->identityContainer->getTemplateId();
                $customerName = $order->getCustomerName();
            }
            
            if ($shippingMethod == 'freeshipping_freeshipping') {
                $templateId = 10; // set your template id here based on the shipping method
            }
            
            $this->templateContainer->setTemplateId($templateId);
            
            $orderEmailTemplateId = $this->templateContainer->getTemplateId();
            
            $this->logger->debug('set order email template id based on shipping method : ' . $orderEmailTemplateId);
        }
        
        
    }
}
12
  • Hi, thanks for the answer but i need to implement a functionality that checks for shipping method & based on that shipping method i need to use different email template as order confirmation. Any thoughts on that ? Thanks – devhs Feb 24 at 6:34
  • My requirement is to send custom email template based on order shipping method – devhs Feb 24 at 6:37
  • @devhs updated the code. it checks the order shipping method and sets the order confirmation email template accordingly. – Haijerome Feb 24 at 6:43
  • Great Thanks, let me check & update. – devhs Feb 24 at 6:46
  • I can see a method prepareTemplate() which sets the template id for the order, Magento2/vendor/magento/module-sales/Model/Order/Email/Sender.php also same method available in Magento2/vendor/magento/module-sales/Model/Order/Email/Sender/OrderSender.php Can you please tell me what's the difference between these two methods & which runs at the end or before event dispatch? Thanks – devhs Feb 24 at 6:56
0

We can't rewrite the method of an abstract class, in this case, it is \Magento\Sales\Model\Order\Email\Sender

Instead of that, we need to find the actual class that is being used, likely it is Magento\Sales\Model\Order\Email\Sender\OrderSender

2
  • Yes, is their any way i can implement according to requirement which is to send custom email template based on order shipping method. – devhs Feb 24 at 6:37
  • let me check... – Rk Rathod Feb 24 at 8:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.