Email Templates After Patch 2.3.4¶
This patch brought in some changes to the way Magento 2 handles email templates. There are now two modes for templates, legacy and not legacy. In version 2.3.4 until 2.4.0 any custom templates that clients create will be broken because of this change.
Legacy Templates¶
These are traditional email templates and include any templates created before the site was patched to 2.3.4 or up and any Magento templates.
They can continue to use the standard variables that Magento offers in email templates.
Non Legacy¶
These are templates not set to legacy and can only contain variables which are scalar types or arrays.
What Does This Mean?!?¶
Basically any new template will be unable to access object variables, think $order in order emails.
The functionality for this can be seen here: StrictResolver.php
What Do I Do Then?¶
You will need to pass variables as strict scalar types or as arrays. Instead of passing the Magento order object you will pass an array of items from that order.
In order to visualize this take a look at this code:
$order = $this->getData('order');
if ($order !== null) {
return $order;
}
$orderId = (int)$this->getData('order_id');
if ($orderId) {
$order = $this->orderRepository->get($orderId);
$this->setData('order', $order);
}
How do I make these changes¶
The best way is to overwrite the way that objects such as order are being passed to templates, which is what magento are doing in patch 2.4.0.
So the options are to either update the site to patch 2.4.0 or to create a custom module that adds the updated changes from 2.4.0 to the required classes.
Can I just overwrite template saving to always be Legacy?¶
Yes!! It's a bit trashy, but it works fine:
<?php
declare(strict_types=1);
namespace EdmondsCommerce\EmailTemplateLegacy\Plugin;
class EmailTemplate
{
public function beforeBeforeSave(\Magento\Email\Model\Template $subject)
{
$subject->setData('is_legacy', 1);
return [];
}
}
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Email\Model\Template">
<plugin disabled="false" name="EdmondsCommerce_EmailTemplateLegacy_Plugin_Magento_Email_Model_Template" sortOrder="10" type="EdmondsCommerce\EmailTemplateLegacy\Plugin\EmailTemplate"/>
</type>
</config>
<?php
declare(strict_types=1);
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
class LegacyColumnChange implements DataPatchInterface
{
protected $setup;
/**
* LegacyColumnChange constructor.
* @param \ModuleDataSetupInterface $setup
*/
public function __construct(
ModuleDataSetupInterface $setup
) {
$this->setup = $setup;
}
/**
* @inheritDoc
*/
public static function getDependencies()
{
return [];
}
/**
* @inheritDoc
*/
public function getAliases()
{
return [];
}
/**
* @inheritDoc
*/
public function apply()
{
try {
$connection = $this->setup->getConnection();
$emailTemplateTable = $connection->getTableName('email_template');
$connection->query("UPDATE `$emailTemplateTable` SET `is_legacy` = '1';");
} catch (\Exception $e) {
// ignore
}
}
}
This plugin will get called on every template save and make the template legacy. The patch is just for existing templates.