3

I want to override one of the function in Magento core model which is located in

vendor\magento\module-sales\Model\Order\Email\Sender\OrderSender.php

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\Sales\Model\Order\Email\Sender;

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\Order\Email\Sender;
use Magento\Sales\Model\ResourceModel\Order as OrderResource;
use Magento\Sales\Model\Order\Address\Renderer;
use Magento\Framework\Event\ManagerInterface;

/**
 * Class OrderSender
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class OrderSender extends Sender
{
  protected function prepareTemplate(Order $order)
    {
        $transport = [
            'order' => $order, 
            'billing' => $order->getBillingAddress(),
            'payment_html' => $this->getPaymentHtml($order),
            'store' => $order->getStore(),
            'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
            'formattedBillingAddress' => $this->getFormattedBillingAddress($order),
        ];

        $transport = new \Magento\Framework\DataObject($transport);

        $this->eventManager->dispatch(
            'email_order_set_template_vars_before',
            ['sender' => $this, 'transport' => $transport]
        );

        $this->templateContainer->setTemplateVars($transport->getData());

        parent::prepareTemplate($order);
    }
}

I just want to add additional data to $transport array variable from my custom extension, but it seems not working because when I call the additional data it didn't print anything, here's what i've done:

etc/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\OrderSender" type="Namespace\Module\Model\Order\Email\Sender\OrderSender"/>
</config>

Namespace\Module\Model\Order\Email\Sender\OrderSender.php

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Namespace\Module\Model\Order\Email\Sender;

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\Order\Email\Sender;
use Magento\Sales\Model\ResourceModel\Order as OrderResource;
use Magento\Sales\Model\Order\Address\Renderer;
use Magento\Framework\Event\ManagerInterface;

/**
 * Class OrderSender
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class OrderSender extends \Magento\Sales\Model\Order\Email\Sender\OrderSender
{


    public function prepareTemplate(Order $order)
    {

        $transport = [
            'order' => $order,
            'billing' => $order->getBillingAddress(),
            'payment_html' => $this->getPaymentHtml($order),
            'test' => '<p> Yoo Yeezy </p>',
            'store' => $order->getStore(),
            'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
            'formattedBillingAddress' => $this->getFormattedBillingAddress($order),
        ];
        $transport = new \Magento\Framework\DataObject($transport);

        $this->eventManager->dispatch(
            'email_order_set_template_vars_before',
            ['sender' => $this, 'transport' => $transport]
        );

        $this->templateContainer->setTemplateVars($transport->getData());

        parent::prepareTemplate($order);
    }


}
9
  • have u put echo exit in ur override model function? seems ok webkul.com/blog/overriding-rewriting-classes-magento2
    – Jackson
    Commented Feb 10, 2017 at 7:47
  • @AnkitShah i already did that, but it didnt echo anything, it goes straight to the core funtion
    – simple guy
    Commented Feb 10, 2017 at 7:50
  • module.xml code <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Namespace_Module" setup_version="1.0.0"> <sequence> <module name="Magento_Sales"/> </sequence> </module> </config> & then run php bin/magento setup:upgrade, php bin/magento setup:di:compile, php bin/magento setup:static-content:deploy, php bin/magento indexer:reindex, php bin/magento cache:flush
    – Jackson
    Commented Feb 10, 2017 at 7:53
  • @AnkitShah when running setup:upgrade [InvalidArgumentException] There are no commands defined in the "setup" namespace.
    – simple guy
    Commented Feb 10, 2017 at 7:59
  • Something wrong with ur module. Check log for error magento.stackexchange.com/questions/103774/…
    – Jackson
    Commented Feb 10, 2017 at 8:00

3 Answers 3

9

Depending on what kind of data you want to add, you might want to use an observer instead of rewriting the model:

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="add_extra_data_to_transport" instance="Vendor\Module\Observer\AddExtraDataToTransport" />
    </event>
</config>

Then create Observer\AddExtraDataToTransport.php

<?php

namespace Vendor\Module\Observer;

use Magento\Framework\Event\ObserverInterface;

class AddExtraDataToTransport implements ObserverInterface
{  
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $transport = $observer->getEvent()->getTransport();
        $transport['test'] = '<p> Yoo Yeezy </p>';
        if ($transport['payment_html'] == 'transfer') {
            $transport['payment_html'] = 'test';
        }
    }
}
10
  • what if i want change the data?
    – simple guy
    Commented Feb 10, 2017 at 8:18
  • @simpleguy like change one of the original data in the $transport variable ? Commented Feb 10, 2017 at 8:22
  • yes, for example if($transport['payment_html'] == 'transfer') $transport['payment_html'] = 'test';
    – simple guy
    Commented Feb 10, 2017 at 8:26
  • @simpleguy see my updated answer Commented Feb 10, 2017 at 8:28
  • when is use the $order variable , i got an error undefined variable
    – simple guy
    Commented Feb 13, 2017 at 8:28
1

Use an observer instead of rewriting the model:

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="add_extra_data_to_transport" instance="Vendor\Module\Observer\AddExtraDataToTransport" />
    </event>
</config>

Then create Observer\AddExtraDataToTransport.php and change data

<?php
namespace Vendor\Module\Observer;

use Magento\Framework\Event\ObserverInterface;

class AddExtraDataToTransport implements ObserverInterface
{  
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $transport = $observer->getTransport();
        if ($transport->getPaymentHtml == 'transfer') {
            $transport->setPaymentHtml('test');
        }
    }
}

Checked at Magento 2.2.2

1
  • not working in Magento 2.2.2 Commented Jul 5, 2018 at 7:17
0

Depending on what kind of data you want to add, you might want to use an observer instead of rewriting the model:

Method to use custom variables in transactional Email in Magento 2:

1 - Create registration.php file in app\code\[Vendor]\[Namespace]\

<?php
 \Magento\Framework\Component\ComponentRegistrar::register(
     \Magento\Framework\Component\ComponentRegistrar::MODULE,
        '[Vendor]_[Namespace]',
          __DIR__
  );

2 - create module.xml file in app\code\[Vendor]\[Namespace]\etc

<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="[Vendor]_[Namespace]" setup_version="1.0.0"/>
    </config>

3 - Create events.xml file in app\code\[Vendor]\[Namespace]\etc

<?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="add_extra_data_to_transport" instance="[Vendor]\[Namespace]\Observer\ObserverforAddCustomVariable" />
        </event>
    </config>

4 - Create ObserverforAddCustomVariable.php file in app\code\[Vendor]\[Namespace]\Observer

<?php

    namespace [Vendor]\[Namespace]\Observer;

    use Magento\Customer\Api\CustomerRepositoryInterface;

    class ObserverforAddCustomVariable implements ObserverInterface
    {
        protected $customerRepository;
        public function __construct(
            CustomerRepositoryInterface $customerRepository
        ) {
            $this->customerRepository = $customerRepository;
        }
        public function execute(\Magento\Framework\Event\Observer $observer)
        {
            /** @var \Magento\Framework\App\Action\Action $controller */
            $transport = $observer->getEvent()->getTransport();
            if($transport->getOrder() != null)
            {
                $customer = $this->customerRepository->getById($transport->getOrder()->getCustomerId());
                if ($customer->getCustomAttribute('username')) {
                    $transport['username'] = $customer->getCustomAttribute('username')->getValue();
                }

            }
        }
    }

You can use custom Email variable in email template like{var username}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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