Upgrading Magento to 2.2.8 While Using Mageplaza Smtp Extension 1.2.9: Fixing Errors

Upgrading Magento to 2.2.8 While Using Mageplaza Smtp Extension 1.2.9: Fixing Errors

5 min read

Send to you:

The Magento 2 era began on November 17, 2015, when Magento released the first version of its 2.0 line. Since then, Magento has been launching updates one after another, while sometimes supporting several branches at the same time. Magento 2.0 is no longer supported, but subsequent versions (2.1, 2.2, 2.3) still are. Magento supports several branches simultaneously because different systems have different requirements. For example, Magento 2.1 still supports PHP 5.6, whereas the minimum version of PHP for Magento 2.2 is 7.0.13 and for Magento 2.3 it’s 7.1.3.

It’s not always feasible for store owners to update to new versions. Moreover, stores usually contain third-party modules which, broadly speaking, shouldn’t conflict with new versions of Magento, although in reality they sometimes do. So even though Magento 2.3 was released on November 28, 2018, many store owners are still using version 2.2 and will be for quite a while.

On March 26, 2019, Magento released the three latest versions in each branch: 2.1.7, 2.2.8, and 2.3.1. We would like to discuss working with the extension for version 2.2.8.

Background on the Mageplaza Smtp Extension

Third-party extensions are often used for sending emails. One of these extensions is the module Mageplaza Smtp. This extension is free, which is why it’s popular. That being said, after upgrading the core to version 2.2.8 and the Mageplaza module to version 1.2.9, the site stopped sending emails. We will investigate why this happened.

Let’s analyze the Mageplaza Smtp module. It is embedded in Magento for sending emails, using the following plugin:

<type name="Magento\Framework\Mail\TransportInterface">
    <plugin name="mageplaza_mail_transport" type="Mageplaza\Smtp\Mail\Transport" sortOrder="1" disabled="false"/>
</type>

We are interested in the constructor and only one method of this plugin:

public function __construct(
    Mail $resourceMail,
    LogFactory $logFactory,
    Registry $registry,
    Data $helper,
    LoggerInterface $logger
)
{
    $this->resourceMail = $resourceMail;
    $this->logFactory = $logFactory;
    $this->registry = $registry;
    $this->helper = $helper;
    $this->logger = $logger;
}
/**
 * @param TransportInterface $subject
 * @param \Closure $proceed
 * @throws MailException
 * @throws \Zend_Exception
 */
public function aroundSendMessage(
    TransportInterface $subject,
    \Closure $proceed
)
{
    $this->_storeId = $this->registry->registry('mp_smtp_store_id');
    $message = $this->getMessage($subject);
    if ($this->resourceMail->isModuleEnable($this->_storeId) && $message) {
        if ($this->helper->versionCompare('2.3.0')) {
            $message = \Zend\Mail\Message::fromString($message->getRawMessage());
        }
        $message = $this->resourceMail->processMessage($message, $this->_storeId);
        $transport = $this->resourceMail->getTransport($this->_storeId);
        try {
            if (!$this->resourceMail->isDeveloperMode($this->_storeId)) {
                $transport->send($message);
            }
            $this->emailLog($message);
        } catch (\Exception $e) {
            $this->emailLog($message, false);
            throw new MailException(new Phrase($e->getMessage()), $e);
        }
    } else {
        $proceed();
    }
}

As we can see, it checks the Magento version and executes additional code if the version is greater than or equal to 2.3.0.Why does this happen? Magento’s main library is Zend Framework. However, for historical reasons, Magento 2 contains both Zend Framework 1 classes and Zend Framework 2 classes. For a long time, Magento used Zend Framework 1 classes to send emails, but there was a transition to Zend Framework 2 classes in version 2.3.0. The use of Zend Framework 2 libraries were then added to version 2.2.8 as well.

It’s likely that the Mageplaza developer team didn’t know this when they released this version, so they created a check for version 2.3.0, which made the Mageplaza Smtp 1.2.9 extension incompatible with Magento 2.2.8. That being said, this conflict can be resolved.

Solution for Compatibility Between Version 1.2.9 of the Mageplaza Smtp Module and Magento 2.2.8

Let’s look at which other classes are checked for the version. These classes are Mageplaza\Smtp\Mail\Rse\Mail and Mageplaza\Smtp\Model\Log. In these classes, there is a check for version 2.3.0. Let’s rework the comparison to check for 2.2.8. The actual solution to this problem looks as follows:

di.xml

<type name="Magentice\All\Model\Mail\Transport">
    <arguments>
        <argument name="resourceMail" xsi:type="object">Web4pro\All\Model\Mail</argument>
    </arguments>
</type>
<type name="Mageplaza\Smtp\Plugin\Message">
    <arguments>
        <argument name="resourceMail" xsi:type="object">Web4pro\All\Model\Mail</argument>
    </arguments>
</type>
<preference for="Mageplaza\Smtp\Mail\Transport" type="Web4pro\All\Model\Mail\Transport"/>
<type name="Mageplaza\Smtp\Model\Log">
    <plugin name="fix-mageplaz-228-incompability" type="Web4pro\All\Model\Plugin" sortOrder="20"/>
</type>

The classes will look as follows:

Web4pro\All\Model\Mail\Transport

class Transport extends \Mageplaza\Smtp\Mail\Transport
{
    public function aroundSendMessage(
        TransportInterface $subject,
        \Closure $proceed
    )
    {
        $this->_storeId = $this->registry->registry('mp_smtp_store_id');
        $message = $this->getMessage($subject);
        if ($this->resourceMail->isModuleEnable($this->_storeId) && $message) {
            if ($this->helper->versionCompare('2.2.8')) {
                $message = \Zend\Mail\Message::fromString($message->getRawMessage());
            }
            $message = $this->resourceMail->processMessage($message, $this->_storeId);
            $transport = $this->resourceMail->getTransport($this->_storeId);
            try {
                if (!$this->resourceMail->isDeveloperMode($this->_storeId)) {
                    $transport->send($message);
                }
                $this->emailLog($message);
            } catch (\Exception $e) {
                $this->emailLog($message, false);
                throw new MailException(new Phrase($e->getMessage()), $e);
            }
        } else {
            $proceed();
        }
    }
}

This class redefines the around plugin from Mageplaza_Smtp.

Web4pro\All\Model\Mail

class Mail extends \Mageplaza\Smtp\Mail\Rse\Mail
{
    public function processMessage($message, $storeId)
    {
        if (!isset($this->_returnPath[$storeId])) {
            $this->_returnPath[$storeId] = $this->smtpHelper->getSmtpConfig('return_path_email', $storeId);
        }
        if ($this->_returnPath[$storeId]) {
            if ($this->smtpHelper->versionCompare('2.3.0')) {
                $message->getHeaders()->addHeaders(["Return-Path" => $this->_returnPath[$storeId]]);
            } else if (method_exists($message, 'setReturnPath')) {
                $message->setReturnPath($this->_returnPath[$storeId]);
            }
        }
        if (!empty($this->_fromByStore) &&
            (($message instanceof \Zend\Mail\Message && !$message->getFrom()->count()))
        ) {
            $message->setFrom($this->_fromByStore['email'], $this->_fromByStore['name']);
        }
        return $message;
    }
    public function getTransport($storeId)
    {
        if (null === $this->_transport) {
            if (!isset($this->_smtpOptions[$storeId])) {
                $configData = $this->smtpHelper->getSmtpConfig('', $storeId);
                $options = [
                    'host' => isset($configData['host']) ? $configData['host'] : '',
                    'port' => isset($configData['port']) ? $configData['port'] : ''
                ];
                if (isset($configData['authentication']) && $configData['authentication'] !== "") {
                    $options  = [
                        'auth' => $configData['authentication'],
                        'username' => isset($configData['username']) ? $configData['username'] : '',
                        'password' => $this->smtpHelper->getPassword($storeId)
                    ];
                }
                if (isset($configData['protocol']) && $configData['protocol'] !== "") {
                    $options['ssl'] = $configData['protocol'];
                }
                $this->_smtpOptions[$storeId] = $options;
            }
            if (!isset($this->_smtpOptions[$storeId]['host']) || !$this->_smtpOptions[$storeId]['host']) {
                throw new \Zend_Exception('A host is necessary for smtp transport, but none was given');
            }
            if ($this->smtpHelper->versionCompare('2.2.8')) {
                $options = $this->_smtpOptions[$storeId];
                if (isset($options['auth'])) {
                    $options['connection_class'] = $options['auth'];
                    $options['connection_config'] = [
                        'username' => $options['username'],
                        'password' => $options['password']
                    ];
                    unset($options['auth']);
                    unset($options['username']);
                    unset($options['password']);
                }
                if (isset($options['ssl'])) {
                    $options['connection_config']['ssl'] = $options['ssl'];
                    unset($options['ssl']);
                }
                unset($options['type']);
                $options = new \Zend\Mail\Transport\SmtpOptions($options);
                $this->_transport = new \Zend\Mail\Transport\Smtp($options);
            } else {
                $this->_transport = new \Zend_Mail_Transport_Smtp($this->_smtpOptions[$storeId]['host'], $this->_smtpOptions[$storeId]);
            }
        }
        return $this->_transport;
    }

Web4pro\All\Model\Plugin

class Plugin
{
    protected $productMetaData;
    public function __construct(\Magento\Framework\App\ProductMetadata $productMetaData)
    {
        $this->productMetaData = $productMetaData;
    }
public function aroundSaveLog($subject,$proceed,$message,$status){
    if(version_compare($this->productMetaData->getVersion(),'2.2.8','<')){
        $proceed($message,$status);
    }else{
        if ($message->getSubject()) {
            $subject->setSubject($message->getSubject());
        }
        $from = $message->getFrom();
        if (count($from)) {
            $from->rewind();
            $subject->setSender($from->current()->getEmail());
        }
        $toArr = [];
        foreach($message->getTo() as $toAddr){
            $toArr[] = $toAddr->getEmail();
        }
        $subject->setRecipient(implode(',', $toArr));
        $ccArr = [];
        foreach($message->getCc() as $ccAddr){
            $ccArr[] = $ccAddr->getEmail();
        }
        $subject->setCc(implode(',', $ccArr));
        $bccArr = [];
        foreach($message->getBcc() as $bccAddr){
            $bccArr[] = $bccAddr->getEmail();
        }
        $subject->setBcc(implode(',', $bccArr));
        $content = htmlspecialchars($message->getBodyText());
        $subject->setEmailContent($content)
            ->setStatus($status)
            ->save();
    }
}

SUM MARY

By doing this, we were able to fix the conflict between Mageplaza_Smtp 1.2.9 and Magento 2.2.8. This issue may be fixed in future versions of the Mageplaza module. At any rate, an experienced developer can always detect problems and create replacement comparisons for compatibility, as is the case with the Mageplaza extension.

Posted on: June 20, 2019

5.0/5.0

Article rating (11 Reviews)

Do you find this article useful? Please, let us know your opinion and rate the post!

  • Not bad
  • Good
  • Very Good
  • Great
  • Awesome