Email Functionality not Working in 2.3.0
-
08-02-2021 - |
Question
In my custom module, I have added email functionality. It's working in 2.1 and 2.2. I have updated to 2.3.0 and now it crashes.
Email send code is as below.
$sender = [
'name' => $this->_escaper->escapeHtml($customer_name),
'email' => $this->_escaper->escapeHtml($customer_email),
];
$to_email = $this->_helper->getSendMailTo();
$sendToInfo = [
'email' => $this->_escaper->escapeHtml($to_email),
];
$transport = $this->_transportBuilder->setTemplateIdentifier('config_email_settings_email_template')
->setTemplateOptions($templateOptions)
->setTemplateVars($templateVars)
->setFrom($sender)
->addTo($sendToInfo)
->getTransport();
$transport->sendMessage();
I am getting exception as
main.CRITICAL: Exception message: The input is not a valid email address. Use the basic format local-part@hostname
Where email address is simple john@gmail.com
[2019-01-08 07:45:19] main.CRITICAL: Exception message: The input is not a valid email address. Use the basic format local-part@hostname
Trace: #0 D:\xampp\htdocs\magento23\vendor\zendframework\zend-mail\src\AddressList.php(233): Zend\Mail\Address->__construct('email', 'john@gmail...')
#1 D:\xampp\htdocs\magento23\vendor\zendframework\zend-mail\src\AddressList.php(33): Zend\Mail\AddressList->createAddress('email', 'john@gmail...')
#2 D:\xampp\htdocs\magento23\vendor\zendframework\zend-mail\src\AddressList.php(80): Zend\Mail\AddressList->add('email', 'john@gmail...')
#3 D:\xampp\htdocs\magento23\vendor\zendframework\zend-mail\src\Message.php(518): Zend\Mail\AddressList->addMany(Array)
#4 D:\xampp\htdocs\magento23\vendor\zendframework\zend-mail\src\Message.php(169): Zend\Mail\Message->updateAddressList(Object(Zend\Mail\AddressList), Array, NULL, 'Zend\\Mail\\Messa...')
#5 D:\xampp\htdocs\magento23\vendor\magento\framework\Mail\Message.php(104): Zend\Mail\Message->addTo(Array)
#6 D:\xampp\htdocs\magento23\generated\code\Magento\Framework\Mail\Message\Interceptor.php(102): Magento\Framework\Mail\Message->addTo(Array)
#7 D:\xampp\htdocs\magento23\vendor\magento\framework\Mail\Template\TransportBuilder.php(147): Magento\Framework\Mail\Message\Interceptor->addTo(Array, '')
#8 D:\xampp\htdocs\magento23\generated\code\Magento\Framework\Mail\Template\TransportBuilder\Interceptor.php(37): Magento\Framework\Mail\Template\TransportBuilder->addTo(Array, '')
#9 D:\xampp\htdocs\magento23\app\code\Vendor\ModuleName\Controller\Order\Save.php(113): Magento\Framework\Mail\Template\TransportBuilder\Interceptor->addTo(Array)
#10 D:\xampp\htdocs\magento23\generated\code\Vendor\ModuleName\Controller\Order\Save\Interceptor.php(24): Vendor\ModuleName\Controller\Order\Save->execute()
#11 D:\xampp\htdocs\magento23\vendor\magento\framework\App\Action\Action.php(108): Vendor\ModuleName\Controller\Order\Save\Interceptor->execute()
#12 D:\xampp\htdocs\magento23\vendor\magento\framework\Interception\Interceptor.php(58): Magento\Framework\App\Action\Action->dispatch(Object(Magento\Framework\App\Request\Http))
#13 D:\xampp\htdocs\magento23\vendor\magento\framework\Interception\Interceptor.php(138): Vendor\ModuleName\Controller\Order\Save\Interceptor->___callParent('dispatch', Array)
#14 D:\xampp\htdocs\magento23\vendor\magento\framework\Interception\Interceptor.php(153): Vendor\ModuleName\Controller\Order\Save\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#15 D:\xampp\htdocs\magento23\generated\code\Vendor\ModuleName\Controller\Order\Save\Interceptor.php(39): Vendor\ModuleName\Controller\Order\Save\Interceptor->___callPlugins('dispatch', Array, Array)
#16 D:\xampp\htdocs\magento23\vendor\magento\framework\App\FrontController.php(159): Vendor\ModuleName\Controller\Order\Save\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#17 D:\xampp\htdocs\magento23\vendor\magento\framework\App\FrontController.php(99): Magento\Framework\App\FrontController->processRequest(Object(Magento\Framework\App\Request\Http), Object(Vendor\ModuleName\Controller\Order\Save\Interceptor))
#18 D:\xampp\htdocs\magento23\vendor\magento\framework\Interception\Interceptor.php(58): Magento\Framework\App\FrontController->dispatch(Object(Magento\Framework\App\Request\Http))
#19 D:\xampp\htdocs\magento23\vendor\magento\framework\Interception\Interceptor.php(138): Magento\Framework\App\FrontController\Interceptor->___callParent('dispatch', Array)
#20 D:\xampp\htdocs\magento23\vendor\magento\module-store\App\FrontController\Plugin\RequestPreprocessor.php(94): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#21 D:\xampp\htdocs\magento23\vendor\magento\framework\Interception\Interceptor.php(135): Magento\Store\App\FrontController\Plugin\RequestPreprocessor->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#22 D:\xampp\htdocs\magento23\vendor\magento\module-page-cache\Model\App\FrontController\BuiltinPlugin.php(73): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#23 D:\xampp\htdocs\magento23\vendor\magento\framework\Interception\Interceptor.php(135): Magento\PageCache\Model\App\FrontController\BuiltinPlugin->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#24 D:\xampp\htdocs\magento23\vendor\magento\framework\Interception\Interceptor.php(153): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#25 D:\xampp\htdocs\magento23\generated\code\Magento\Framework\App\FrontController\Interceptor.php(26): Magento\Framework\App\FrontController\Interceptor->___callPlugins('dispatch', Array, NULL)
#26 D:\xampp\htdocs\magento23\vendor\magento\framework\App\Http.php(135): Magento\Framework\App\FrontController\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#27 D:\xampp\htdocs\magento23\generated\code\Magento\Framework\App\Http\Interceptor.php(24): Magento\Framework\App\Http->launch()
#28 D:\xampp\htdocs\magento23\vendor\magento\framework\App\Bootstrap.php(258): Magento\Framework\App\Http\Interceptor->launch()
#29 D:\xampp\htdocs\magento23\index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http\Interceptor))
#30 {main} [] []
Solution
Finally I have Found Solution and Now it's Working
$sender = [
'email' => $this->_escaper->escapeHtml($customer_email),
'name' => $this->_escaper->escapeHtml($customer_name)
];
$to_email = $this->_helper->getSendMailTo();
$transport= $this->_transportBuilder->setTemplateIdentifier('config_email_settings_email_template')
->setTemplateOptions($templateOptions)
->setTemplateVars($templateVars)
->setFrom($sender)
->addTo($to_email, 'Name')
->getTransport();
$transport->sendMessage();
OTHER TIPS
Please replace your code with following code and check after clear your cache, also please remove "_escaper" from your code.
$transport = $this->transportBuilder
->setTemplateIdentifier('config_email_settings_email_template')
->setTemplateOptions(
[
'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
'store' => $this->storeManager->getStore()->getId()
]
)
->setTemplateVars($variables)
->setFrom($emailSender)
->addTo($emailRecipient)
->setReplyTo($replyToEmail, $replyToName)
->getTransport();
$transport->sendMessage();
Since Magento 2.3, Magento uses Zend Framework 2 for sending emails. Which probably changed the logic used for parsing array with the recipient data.
So here are few variants on how you can properly send email in Magento 2.3:
- For multiple recipients: use array where key is the recipient's email address and value - recipient's name (note, the same rules applied to sender details):
$sender = [$this->_escaper->escapeHtml($customer_email) => $this->_escaper->escapeHtml($customer_name)];
$to_email = $this->_helper->getSendMailTo();
$sendToInfo = [$this->_escaper->escapeHtml($to_email) => 'Recipient Name'];
$transport = $this->_transportBuilder->setTemplateIdentifier('config_email_settings_email_template')
->setTemplateOptions($templateOptions)
->setTemplateVars($templateVars)
->setFrom($sender)
->addTo($sendToInfo)
->getTransport();
$transport->sendMessage();
- Or you can use the code below to send an email to a single recipient. This code is backward compatible with Magento 2.2 and lower versions:
$to_email = $this->_helper->getSendMailTo();
$transport = $this->_transportBuilder->setTemplateIdentifier('config_email_settings_email_template')
->setTemplateOptions($templateOptions)
->setTemplateVars($templateVars)
->setFrom($this->_escaper->escapeHtml($customer_email))
->addTo($this->_escaper->escapeHtml($to_email))
->getTransport();
$transport->sendMessage();
Note: Contact is vendor and Us is module.Here i am posting my form data to my frontend controller Post.php
step 1: Create email_templates.xml in app/code/Contact/Us/etc
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Email/etc/email_templates.xsd">
<template id="send_email_email_template" label="Email Form" file="email_template.html" type="text" module="Contact_Us" area="frontend"/>
step 2: Create email_template.html in app/code/Contact/Us/view/frontend/email
<!--@subject xMage-support@-->
<!--@vars {
"var data.comment":"xMage-support",
"var data.email":"support@xmagestore.com",
"var data.name":"XMageStore"
} @-->
{{template config_path="design/email/header_template"}}
{{trans "Dear %name" name=$data.name}}
{{trans "we received your request regarding %queryregarding"
queryregarding=$data.requestType}}
{{template config_path="design/email/footer_template"}}
Step 3: Create Post.php controller in app/code/Contact/Us/Controller/Post
<?php
namespace Contact\Us\Controller\Index;
class Post extends \Magento\Framework\App\Action\Action
{
/**
* @var \Magento\Framework\Mail\Template\TransportBuilder
*/
protected $_transportBuilder;
/**
* @var \Magento\Framework\Translate\Inline\StateInterface
*/
protected $inlineTranslation;
/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
*/
protected $scopeConfig;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $storeManager;
/**
* @var \Magento\Framework\Escaper
*/
protected $_escaper;
/**
* @param \Magento\Framework\App\Action\Context $context
* @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
* @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
*/
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
\Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Escaper $escaper
) {
parent::__construct($context);
$this->_transportBuilder = $transportBuilder;
$this->inlineTranslation = $inlineTranslation;
$this->scopeConfig = $scopeConfig;
$this->storeManager = $storeManager;
$this->_escaper = $escaper;
}
/**
* Post user question
*
* @return void
* @throws \Exception
*/
public function execute()
{
$post = $this->getRequest()->getPostValue();
if (!$post) {
$this->_redirect('/');
return;
}
$this->inlineTranslation->suspend();
try {
$recipientMail = $this->getRequest()->getPostValue('email');
$postObject = new \Magento\Framework\DataObject();
$postObject->setData($post);
$error = false;
$sender = [
'name' => 'xMageStore',
'email' => 'support@xmagestore.com',
];
$storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
$transport = $this->_transportBuilder
->setTemplateIdentifier('send_email_email_template') // this code we have mentioned in the email_templates.xml
->setTemplateOptions(
[
'area' => \Magento\Framework\App\Area::AREA_FRONTEND, // this is using frontend area to get the template file
'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
]
)
->setTemplateVars(['data' => $postObject])
->setFrom($sender)
->addTo($recipientMail)
->getTransport();
$transport->sendMessage();
$this->inlineTranslation->resume();
$this->messageManager->addSuccess(
__('Thanks for contacting us. We\'ll respond to you very soon.')
);
$this->_redirect('/');
return;
} catch (\Exception $e) {
$this->inlineTranslation->resume();
$this->messageManager->addError(
__('We can\'t process your request right now. Sorry, that\'s all we know.' . $e->getMessage())
);
$this->_redirect('/');
return;
}
}
}