Hallo everyone,
since the release of Magento 2.2 the old override Zend_Mail_Transport_Sendmail does not work anymore.
before, an rewrite in etc/di.xml and model/Transport.php worked.
<preference for="MagentoFrameworkMailTransport" type="MyModulMyPluginModelTransport"/>
and
namespace MyModulMyPluginModel;
class Transport extends Zend_Mail_Transport_Sendmail implements MagentoFrameworkMailTransportInterface
{
protected $_message;
/**
* @param MagentoFrameworkMailMessageInterface $message
* @throws Zend_Mail_Exception
*/
public function __construct(
MagentoFrameworkMailMessageInterface $message
)
{
if (!$message instanceof Zend_Mail) {
throw new InvalidArgumentException('The message should be an instance of Zend_Mail');
}
parent::__construct('-f ' . '[email protected]');
$this->_message = $message;
}
/**
* Send a mail using this transport
*
* @return void
* @throws MagentoFrameworkExceptionMailException
*/
public function sendMessage()
{
try {
parent::send($this->_message);
} catch (Exception $e) {
throw new MagentoFrameworkExceptionMailException(new MagentoFrameworkPhrase($e->getMessage()), $e);
}
}
/**
* @inheritdoc
*/
public function getMessage()
{
return $this->_message;
}
/**
* Send mail using PHP native mail()
*
* @access public
* @return void
* @throws Zend_Mail_Transport_Exception if parameters is set
* but not a string
* @throws Zend_Mail_Transport_Exception on mail() failure
*/
public function _sendMail()
{
/**
* revert changes from update to 2.1.7
*
* mailing was not working with Envelope >= 2.1.7
*/
if ($this->parameters === null) {
set_error_handler(array($this, '_handleMailErrors'));
$result = mail(
$this->recipients,
$this->_mail->getSubject(),
$this->body,
$this->header);
restore_error_handler();
} else {
if(!is_string($this->parameters)) {
/**
* @see Zend_Mail_Transport_Exception
*
* Exception is thrown here because
* $parameters is a public property
*/
#require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception(
'Parameters were set but are not a string'
);
}
set_error_handler(array($this, '_handleMailErrors'));
$result = mail(
$this->recipients,
$this->_mail->getSubject(),
$this->body,
$this->header,
$this->parameters);
restore_error_handler();
}
if ($this->_errstr !== null || !$result) {
/**
* @see Zend_Mail_Transport_Exception
*/
#require_once 'Zend/Mail/Transport/Exception.php';
throw new Zend_Mail_Transport_Exception('Unable to send mail. ' . $this->_errstr);
}
}
}
But now i am kind of lost
I tryed creating a plugin, which seem to be the ways it is supposed to be done now.
<type name="MagentoFrameworkMailTransport">
<plugin sortOrder="50" name="SendMailPlugin" type="MyModulMyPluginPluginSendMailPlugin"/>
</type>
I also read about overriding “TransportInterface”, but i am not getting it to work. I only need it to call the constructor on my plugin.
best regards and thanks in advance
UPDATE:
It is working again now. The Problem was really just the TransportInterface. I thought i tryed that already or maybe it had something to do with “generation” cache …
<preference for="MagentoFrameworkMailTransportInterface" type="MyModulMyPluginModelTransport" />
So when override a class the preference needs to point to the interface.
I did not get the plugin version to work yet. In my first attempts i was not even sure how to call the methode in the plugin “after__construct” or “afterConstruct”. Also it is calling the parent::contruct.
If i get it to work in the end i will post it.
Thanks you all for your help.
UPDATE 2:
A Plugin solution ist not possible in this case, since contruct methodes can not be set for a plugin.
https://www.mageplaza.com/magento-2-module-development/magento-2-plugin-interceptor.html
3
Answers
Ok, first of all you misunderstand the role of plugins in Magento 2. You try to use it as a class which overrides another class but this is a wrong approach. With plugins you are able to wrap public methods in a class either by changing input, output or both. You can read more about plugins in documentation
What you are looking for is an override in M2 fashion so you need to get familiar with dependency injection and preferences
Your initial approach is correct. Do you have properly configured sequence in your module to make sure that your module is loaded after Magento_Email? Verify the sequence in etc/config.php
Another thing you can try is to set preference for TransportInterface rather than on transport model especially if your override is global.
You need to use plugin for model
app/code/Magento/Email/Model/Transport.php
Create yours
di.xml
in the folder of your moduleAnd your plugin file should be looke like
Or if you want, you can override this file by creation own and set sequence
die.xml in your module
and
module.xml
Then it will override it.
So two ways – override class or one method via “after”, “before” “around” plugin
solution worked in single shot. Thank you.