Magento 2.3.2 Email Sending Code Not Working in Magento 2.3.3

magento2.3.2magento2.3.3send mail

I have created one extension which is send mail on particular event. This extension working fine in Magento 2.3.2 and also send email but this extension not working in Magento 2.3.3. I have read Magento 2.3.3 release note and I found that Email class is changed in Magento 2.3.3. Read here Email Library

Can anyone help me how can I make send mail code compatible for both version. here is my code.

<?php

namespace Vendor\Modulename\Observer;

use Magento\Framework\Event\ObserverInterface;
use \Magento\Store\Model\StoreManagerInterface;
use \Magento\Framework\Mail\Template\TransportBuilder;
use \Magento\Framework\Translate\Inline\StateInterface;
use Psr\Log\LoggerInterface;

class SendMail implements ObserverInterface
{
    protected $scopeConfig;

    const XML_PATH_TEMPLATE_SUBJECT = 'mycustomdemo/general/template_subject';
    const XML_PATH_SENDER_NAME = 'mycustomdemo/general/sender_name';
    const XML_PATH_SENDER_EMAIL = 'mycustomdemo/general/sender_email';
    const XML_PATH_SENDER_MESSAGE = 'mycustomdemo/general/sender_message';

    public function __construct(
        StoreManagerInterface $storeManager,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        TransportBuilder $transportBuilder,
        LoggerInterface $logLoggerInterface,
        StateInterface $inlineTranslation,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
    ) {
        $this->storeManager = $storeManager;
        $this->messageManager = $messageManager;
        $this->transportBuilder = $transportBuilder;
        $this->inlineTranslation = $inlineTranslation;
        $this->logLoggerInterface = $logLoggerInterface;
        $this->scopeConfig = $scopeConfig;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        try {
                $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
                $templateSubject = $this->scopeConfig->getValue(self::XML_PATH_TEMPLATE_SUBJECT, $storeScope);
                $senderName = $this->scopeConfig->getValue(self::XML_PATH_SENDER_NAME, $storeScope);
                $senderEmail = $this->scopeConfig->getValue(self::XML_PATH_SENDER_EMAIL, $storeScope);
                $senderMessage = $this->scopeConfig->getValue(self::XML_PATH_SENDER_MESSAGE, $storeScope);
                $order = $observer->getEvent()->getOrder();
                $custFirstname = $order->getCustomerEmail();
                $custFirstname = $order->getCustomerFirstname();
                $custEmail = $order->getCustomerEmail();
                $template_sub = $templateSubject; # Set email subject
                $sender_name = $senderName; # Set sender name
                $sender_email = $senderEmail; # Set sender email
                $template_content = $senderMessage; # Set email content
                $templateId = 'cancel_order_template'; #This is my custom template ID
                $this->inlineTranslation->suspend();
                $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
                $sendFrom = $sender_email;
                $senderName = $sender_name;
                $sendTo = $custEmail;
                $transport = $this->transportBuilder
                ->setTemplateIdentifier($templateId)
                ->setTemplateOptions(
                    [
                        'area' => 'frontend',
                        'store' => $this->storeManager->getStore()->getId(),
                    ]
                )
                ->setTemplateVars([
                    'template_subject' => $template_sub,
                    'email_content' => $template_content,
                    'order'=> $order
                ])
                ->setFrom(['email' => $sendFrom, 'name' => $senderName])
                ->addTo([$sendTo])
                ->getTransport();
                $transport->sendMessage();
                $this->inlineTranslation->resume();
        } catch (\Exception $e) {
            $this->logLoggerInterface->debug($e->getMessage());
        }
    }
}

I am facing this error in debug.logMagento 2.3.3

[2019-11-23 08:45:32] main.CRITICAL: Type Error occurred when creating object: Magento\Framework\Mail\EmailMessage, Argument 2 passed to Magento\Framework\Mail\EmailMessage::__construct() must be of the type array, null given, called in /opt/lampp72/htdocs/magento2/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 116 [] []
[2019-11-23 08:45:32] main.DEBUG: Type Error occurred when creating object: Magento\Framework\Mail\EmailMessage [] []

Any help would be appreciated.

Thanks in advance..!

Best Answer

You can remove array from addTo([$sendTo]) function. If you'll remove that and add only single email address there then it will work.

<?php

namespace Vendor\Modulename\Observer;

use Magento\Framework\Event\ObserverInterface;
use \Magento\Store\Model\StoreManagerInterface;
use \Magento\Framework\Mail\Template\TransportBuilder;
use \Magento\Framework\Translate\Inline\StateInterface;
use Psr\Log\LoggerInterface;

class SendMail implements ObserverInterface
{
    protected $scopeConfig;

    const XML_PATH_TEMPLATE_SUBJECT = 'mycustomdemo/general/template_subject';
    const XML_PATH_SENDER_NAME = 'mycustomdemo/general/sender_name';
    const XML_PATH_SENDER_EMAIL = 'mycustomdemo/general/sender_email';
    const XML_PATH_SENDER_MESSAGE = 'mycustomdemo/general/sender_message';

    public function __construct(
        StoreManagerInterface $storeManager,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        TransportBuilder $transportBuilder,
        LoggerInterface $logLoggerInterface,
        StateInterface $inlineTranslation,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
    ) {
        $this->storeManager = $storeManager;
        $this->messageManager = $messageManager;
        $this->transportBuilder = $transportBuilder;
        $this->inlineTranslation = $inlineTranslation;
        $this->logLoggerInterface = $logLoggerInterface;
        $this->scopeConfig = $scopeConfig;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        try {
                $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
                $templateSubject = $this->scopeConfig->getValue(self::XML_PATH_TEMPLATE_SUBJECT, $storeScope);
                $senderName = $this->scopeConfig->getValue(self::XML_PATH_SENDER_NAME, $storeScope);
                $senderEmail = $this->scopeConfig->getValue(self::XML_PATH_SENDER_EMAIL, $storeScope);
                $senderMessage = $this->scopeConfig->getValue(self::XML_PATH_SENDER_MESSAGE, $storeScope);
                $order = $observer->getEvent()->getOrder();
                $custFirstname = $order->getCustomerEmail();
                $custFirstname = $order->getCustomerFirstname();
                $custEmail = $order->getCustomerEmail();
                $template_sub = $templateSubject; # Set email subject
                $sender_name = $senderName; # Set sender name
                $sender_email = $senderEmail; # Set sender email
                $template_content = $senderMessage; # Set email content
                $templateId = 'cancel_order_template'; #This is my custom template ID
                $this->inlineTranslation->suspend();
                $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
                $sendFrom = $sender_email;
                $senderName = $sender_name;
                $sendTo = $custEmail;
                $transport = $this->transportBuilder
                ->setTemplateIdentifier($templateId)
                ->setTemplateOptions(
                    [
                        'area' => 'frontend',
                        'store' => $this->storeManager->getStore()->getId(),
                    ]
                )
                ->setTemplateVars([
                    'template_subject' => $template_sub,
                    'email_content' => $template_content,
                    'order'=> $order
                ])
                ->setFrom(['email' => $sendFrom, 'name' => $senderName])
                ->addTo($sendTo) //I make change here and it's working now.
                ->getTransport();
                $transport->sendMessage();
                $this->inlineTranslation->resume();
        } catch (\Exception $e) {
            $this->logLoggerInterface->debug($e->getMessage());
        }
    }
}

Because there is one if condition where isset function is used and whenever we will use addTo() function with string type of argument at that time that is working because first condition become true there. But when we will add array as an argument in that function at that time when we check $this->messageData there is not any index with to addressType. So I just initialize that index at starting of this function and assign blank array as an argument. So now whenever we will use array as an argument second argument become true in that case and we can send multiple emails.

Hope this will help you!

Related Topic