I started developing Magento 2.2 modules about 3 months ago. I did a very simple SMTP module by following what some open source projects did. I could use a free plugin but the real goal here is to learn Magento 2. My module is hosted on a private GitHub repository and gets updated by running composer upgrade on the magento 2 server. I can see the custom fields I created in the backend but whenever magento send a message an error is thrown. At first I thought the problem was with my module but it seems like my Transport class isn't even called. Here is my main module's files.
composer.json
{
"name": "mymodule/module-smtp",
"description": "SMTP Extension for Magento 2 to help the configuration of the SMTP (Simple Mail Transfer Protocol) server.",
"type": "magento2-module",
"version": "1.1.0",
"require": {
"php": "7.0.2|7.0.4|~7.0.6|~7.1.0",
"magento/framework": "101.0.*",
"magento/module-config": "101.0.*",
"magento/module-store": "100.2.*"
},
"license": [
"proprietary"
],
"minimum-stability": "stable",
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"MyModule\\Smtp\\": ""
}
}
}
registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'MyModule_Smtp',
__DIR__
);
etc/di.xml
<?xml version="1.0" encoding="utf-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Framework\Mail\Transport" type="MyModule\Smtp\Plugin\Magento\Framework\Mail\Transport" />
</config>
etc/module.xml
<?xml version="1.0" encoding="utf-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="MyModule_Smtp" setup_version="1.0.0">
<sequence>
<module name="Magento_Backend"/>
</sequence>
</module>
</config>
Plugin/Magento/Framework/Mail/Transport.php
<?php
namespace MyModule\Smtp\Plugin\Magento\Framework\Mail;
class Transport implements \Magento\Framework\Mail\TransportInterface
{
/**
* @var \Magento\Framework\Mail\MessageInterface
*/
protected $_message;
/**
* @var \MyModule\Smtp\Helper\Data
*/
private $_dataHelper;
/**
* @var \Magento\Framework\Encryption\EncryptorInterface
*/
private $_encryptor;
/**
* @param \Magento\Framework\Mail\MessageInterface $message
* @param \MyModule\Smtp\Helper\Data $dataHelper
* @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
*/
public function __construct(
\Magento\Framework\Mail\MessageInterface $message,
\MyModule\Smtp\Helper\Data $dataHelper,
\Magento\Framework\Encryption\EncryptorInterface $encryptor)
{
$this->_dataHelper = $dataHelper;
$this->_encryptor = $encryptor;
$this->_message = $message;
}
/**
* Send a mail using this transport
*
* @return void
*/
public function sendMessage()
{
if ($this->_dataHelper->isConfigurationEnabled()) {
$this->useSmtp();
} else {
$this->useSendMail();
}
}
/**
* Send mail using a custom SMTP server
*
* @return void
* @throws \Magento\Framework\Exception\MailException
*/
public function useSmtp()
{
$host = $this->_dataHelper->getHost();
$config = array('port' => $this->_dataHelper->getPort());
$auth = $this->_dataHelper->getAuthentication();
if ($auth === 'plain' || $auth === 'login' || $auth === 'cram-md5') {
$config['auth'] = $auth;
$config['username'] = $this->_dataHelper->getUsername();
$config['password'] = $this->_encryptor->decrypt($this->_dataHelper->getpassword());
}
$ssl = $this->_dataHelper->getProtocol();
if ($ssl === 'ssl' || $ssl === 'tls') {
$config['ssl'] = $ssl;
}
$zendMail = new \Zend_Mail_Transport_Smtp($host, $config);
try {
$zendMail->send($this->_message);
} catch (\Exception $e) {
throw new \Magento\Framework\Exception\MailException(new \Magento\Framework\Phrase($e->getMessage()), $e);
}
}
/**
* Send mail using PHP mail function
*
* @return void
* @throws \Magento\Framework\Exception\MailException
*/
public function useSendMail()
{
$zendMail = new \Zend_Mail_Transport_Sendmail();
try {
$zendMail->send($this->_message);
} catch (\Exception $e) {
throw new \Magento\Framework\Exception\MailException(new \Magento\Framework\Phrase($e->getMessage()), $e);
}
}
/**
* @inheritdoc
*/
public function getMessage()
{
return $this->_message;
}
}
The only error reported by magento is the following.
system.log
[2017-11-21 23:50:55] main.CRITICAL: Exception message: Unable to send mail.
Trace: #0 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Email\Model\Transport->sendMessage()
#1 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Email\Model\Transport\Interceptor->___callParent('sendMessage', Array)
#2 /var/www/html/vendor/magento/module-email/Model/Mail/TransportInterfacePlugin.php(48): Magento\Email\Model\Transport\Interceptor->Magento\Framework\Interception\{closure}()
#3 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(135): Magento\Email\Model\Mail\TransportInterfacePlugin->aroundSendMessage(Object(Magento\Email\Model\Transport\Interceptor), Object(Closure))
#4 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Email\Model\Transport\Interceptor->Magento\Framework\Interception\{closure}()
#5 /var/www/html/generated/code/Magento/Email/Model/Transport/Interceptor.php(26): Magento\Email\Model\Transport\Interceptor->___callPlugins('sendMessage', Array, NULL)
#6 /var/www/html/vendor/magento/module-user/Model/User.php(414): Magento\Email\Model\Transport\Interceptor->sendMessage()
#7 /var/www/html/vendor/magento/module-user/Controller/Adminhtml/Auth/Forgotpassword.php(73): Magento\User\Model\User->sendPasswordResetConfirmationEmail()
#8 /var/www/html/vendor/magento/framework/App/Action/Action.php(107): Magento\User\Controller\Adminhtml\Auth\Forgotpassword->execute()
#9 /var/www/html/vendor/magento/module-backend/App/AbstractAction.php(229): Magento\Framework\App\Action\Action->dispatch(Object(Magento\Framework\App\Request\Http))
#10 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Backend\App\AbstractAction->dispatch(Object(Magento\Framework\App\Request\Http))
#11 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(138): Magento\User\Controller\Adminhtml\Auth\Forgotpassword\Interceptor->___callParent('dispatch', Array)
#12 /var/www/html/vendor/magento/module-backend/App/Action/Plugin/Authentication.php(143): Magento\User\Controller\Adminhtml\Auth\Forgotpassword\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\$
#13 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(135): Magento\Backend\App\Action\Plugin\Authentication->aroundDispatch(Object(Magento\User\Controller\Adminhtml\Auth\Forgotpassword\Interceptor), Object(Closure), O$
#14 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(153): Magento\User\Controller\Adminhtml\Auth\Forgotpassword\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#15 /var/www/html/generated/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword/Interceptor.php(26): Magento\User\Controller\Adminhtml\Auth\Forgotpassword\Interceptor->___callPlugins('dispatch', Array, NULL)
#16 /var/www/html/vendor/magento/framework/App/FrontController.php(55): Magento\User\Controller\Adminhtml\Auth\Forgotpassword\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#17 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\App\FrontController->dispatch(Object(Magento\Framework\App\Request\Http))
#18 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\App\FrontController\Interceptor->___callParent('dispatch', Array)
#19 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#20 /var/www/html/generated/code/Magento/Framework/App/FrontController/Interceptor.php(26): Magento\Framework\App\FrontController\Interceptor->___callPlugins('dispatch', Array, Array)
#21 /var/www/html/vendor/magento/framework/App/Http.php(135): Magento\Framework\App\FrontController\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#22 /var/www/html/vendor/magento/framework/App/Bootstrap.php(256): Magento\Framework\App\Http->launch()
#23 /var/www/html/index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))
#24 {main} [] []