Last active
March 1, 2023 12:27
-
-
Save jellesiderius/bc9c8ea77bfa5a58089e1224e93584a1 to your computer and use it in GitHub Desktop.
Magento 2: Replace old email variable with new ones (Files and Database) 2.4.3 to higher. https://developer.adobe.com/commerce/frontend-core/guide/templates/email-migration/. Place this file in MAGENTO_ROOT/scripts.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$time_start = microtime(true); | |
// MAGENTO START | |
require dirname(__FILE__) . '/../app/bootstrap.php'; | |
use Magento\Framework\App\Bootstrap; | |
$bootstrap = Bootstrap::create(BP, $_SERVER); | |
$objectManager = $bootstrap->getObjectManager(); | |
/** @var \Psr\Log\LoggerInterface $logger */ | |
$logger = $objectManager->get(\Psr\Log\LoggerInterface::class); | |
/** @var Magento\Email\Model\ResourceModel\Template\CollectionFactory $templateFactory */ | |
$templateFactory = $objectManager->get(\Magento\Email\Model\ResourceModel\Template\CollectionFactory::class); | |
$templateFactory = $templateFactory->create(); | |
$templateCollection = $templateFactory->load(); | |
/** | |
* OPTIONS: | |
* --dry-run: runs the script without executing this. | |
* --files: runs the script for files | |
* --database: runs the script for database files | |
**/ | |
try { | |
// CLI Options: | |
$dryRun = false; | |
$runForFiles = false; | |
$runForDatabase = false; | |
// Set options by CLI variables | |
if (count($argv) > 0) { | |
foreach ($argv as $argument) { | |
if ($argument == '--dry-run') { | |
$dryRun = true; | |
} | |
if ($argument == '--files') { | |
$runForFiles = true; | |
} | |
if ($argument == '--database') { | |
$runForDatabase = true; | |
} | |
} | |
} | |
// Key: before value, value: new value | |
$variableReplaces = [ | |
// General variable: | |
'htmlescape' => '', | |
'var=$' => 'var ', | |
// Variable openers: | |
'{{ ' => '{{', | |
' }}' => '}}', | |
// Store variables: | |
'store.getFrontendName()' => 'store.frontend_name', | |
// Order variables: | |
'order.getCreatedAt()' => 'created_at_formatted', | |
'order.getCreatedAtFormatted()' => 'created_at_formatted', | |
'order.getCreatedAtFormatted(1)' => 'created_at_formatted', | |
'order.getCreatedAtFormatted(2)' => 'created_at_formatted', | |
'order.getCreatedAtFormatted(3)' => 'created_at_formatted', | |
'order.getIncrementId()' => 'order.increment_id', | |
'order.getGrandTotal()' => 'order.grand_total', | |
'order.getOrderCurrencyCode()' => 'order.order_currency_code', | |
'order.getBillingAddress().getName()' => 'order_data.customer_name', | |
'order.getShippingAddress().getName()' => 'order_data.customer_name', | |
'order.getCustomerName()' => 'order_data.customer_name', | |
'order.getEmailCustomerNote()' => 'order_data.email_customer_note', | |
'order.getIsNotVirtual()' => 'order_data.is_not_virtual', | |
'order.getShippingDescription()' => 'order.shipping_description', | |
'order.getFrontendStatusLabel()' => 'order_data.frontend_status_label', | |
'order.getStatusLabel()' => 'order_data.frontend_status_label', | |
'order.getPayment().getMethodInstance().getTitle()' => 'payment_html|raw', | |
// Invoice variables: | |
'invoice.getCreatedAt()' => 'created_at_formatted', | |
'invoice.getCreatedAtFormatted()' => 'created_at_formatted', | |
'invoice.getCreatedAtFormatted(1)' => 'created_at_formatted', | |
'invoice.getCreatedAtFormatted(2)' => 'created_at_formatted', | |
'invoice.getCreatedAtFormatted(3)' => 'created_at_formatted', | |
'invoice.getIncrementId()' => 'order.increment_id', | |
'invoice.getGrandTotal()' => 'order.grand_total', | |
'invoice.getOrderCurrencyCode()' => 'order.order_currency_code', | |
'invoice.getBillingAddress().getName()' => 'order_data.customer_name', | |
'invoice.getShippingAddress().getName()' => 'order_data.customer_name', | |
'invoice.getCustomerName()' => 'order_data.customer_name', | |
'invoice.getEmailCustomerNote()' => 'order_data.email_customer_note', | |
'invoice.getIsNotVirtual()' => 'order_data.is_not_virtual', | |
'invoice.getShippingDescription()' => 'order.shipping_description', | |
'invoice.getFrontendStatusLabel()' => 'order_data.frontend_status_label', | |
'invoice.getStatusLabel()' => 'order_data.frontend_status_label', | |
'invoice.getPayment().getMethodInstance().getTitle()' => 'payment_html|raw', | |
'billing.getName()' => 'order_data.customer_name', | |
'billing.name' => 'order_data.customer_name', | |
// Handles: | |
'{{layout handle="sales_email_order_creditmemo_items" creditmemo=$creditmemo order=$order}}' => '{{layout handle="sales_email_order_creditmemo_items" creditmemo_id=$creditmemo_id order_id=$order_id}}', | |
'{{layout area="frontend" handle="sales_email_order_invoice_items" invoice=$invoice order=$order}}' => '{{layout area="frontend" handle="sales_email_order_invoice_items" invoice_id=$invoice_id order_id=$order_id}}', | |
'{{layout handle="sales_email_order_invoice_items" invoice=$invoice order=$order}}' => '{{layout area="frontend" handle="sales_email_order_invoice_items" invoice_id=$invoice_id order_id=$order_id}}', | |
'{{layout handle="sales_email_order_items" order=$order}}' => '{{layout handle="sales_email_order_items" order_id=$order_id area="frontend"}}', | |
'{{layout handle="sales_email_order_items" order=$order area="frontend"}}' => '{{layout handle="sales_email_order_items" order_id=$order_id area="frontend"}}', | |
'{{layout handle="sales_email_order_shipment_items" shipment=$shipment order=$order}}' => '{{layout handle="sales_email_order_shipment_items" shipment_id=$shipment_id order_id=$order_id}}', | |
'{{layout handle="sales_email_order_shipment_track" shipment=$shipment order=$order}}' => '{{layout handle="sales_email_order_shipment_track" shipment_id=$shipment_id order_id=$order_id}}', | |
'{{block class=\'Magento\\\\Framework\\\\View\\\\Element\\\\Template\' area=\'frontend\' template=\'Magento_Sales::email/shipment/track.phtml\' shipment=$shipment order=$order}}' => '{{layout | |
handle="sales_email_order_shipment_track" shipment_id=$shipment_id order_id=$order_id}}', | |
// Amasty Gift Code emails | |
'gcard_email.getGiftCode()' => 'gcard_email.gift_code', | |
'gcard_email.getExpiryDays()' => 'gcard_email.expiry_days', | |
'gcard_email.getRecipientName()' => 'gcard_email.recipient_name', | |
'gcard_email.getSenderName()' => 'gcard_email.sender_name', | |
'gcard_email.getSenderEmail()' => 'gcard_email.sender_email', | |
'gcard_email.getSenderMessage()' => 'gcard_email.sender_message', | |
'gcard_email.getBalance()' => 'gcard_email.balance', | |
'gcard_email.getExpiredDate()' => 'gcard_email.expired_date', | |
'gcard_email.getImage()' => 'gcard_email.image', | |
// Magetrend variables | |
"mtVar.getData('invoice_increment_id')" => "invoice.increment_id", | |
"mtVar.getData('invoice_increment_id')" => "invoice.increment_id", | |
"mtVar.getData( 'formatted_grand_total')" => 'mtVar.getFormattedGrandTotal()', | |
"mtVar.getData('formatted_grand_total')" => 'mtVar.getFormattedGrandTotal()' | |
]; | |
$replacedArray = []; | |
$replaceFileItems = 0; | |
$replaceDbItems = 0; | |
// Gather all emails for code + theme | |
$frontendDir = BP . '/app/design/frontend'; | |
$appCodeDir = BP . '/app/code'; | |
$frontendHtmlFiles = getDirHtmlFiles($frontendDir); | |
$appCodeDirFiles = getDirHtmlFiles($appCodeDir); | |
$mergedHtmlFilePaths = array_merge($frontendHtmlFiles, $appCodeDirFiles); | |
if ($runForFiles) { | |
// Find and replace in emails (files) | |
foreach ($mergedHtmlFilePaths as $k => $htmlFilePath) { | |
$fileContents = file_get_contents($htmlFilePath); | |
// Check if file is an email | |
if (strstr($fileContents, '@subject') === false) { | |
continue; | |
} | |
$mutatedFile = false; | |
$hasCountedFileItem = false; | |
// Find and replace in email content | |
foreach ($variableReplaces as $oldValue => $newValue) { | |
if (strstr($fileContents, $oldValue) !== false) { | |
if (!$hasCountedFileItem) { | |
$replaceFileItems++; | |
$hasCountedFileItem = true; | |
} | |
if ($dryRun) { | |
$replacedArray[$htmlFilePath][] = 'DRY RUN: Would replace file content: "' . $oldValue . '" -> "' . $newValue . '"'; | |
} else { | |
$replacedArray[$htmlFilePath][] = 'Replaced file content: "' . $oldValue . '" -> "' . $newValue . '"'; | |
$fileContents = str_replace($oldValue, $newValue, $fileContents); | |
$mutatedFile = true; | |
} | |
} | |
} | |
// Overwrite file with new content | |
if (!$dryRun && $mutatedFile) { | |
file_put_contents($htmlFilePath, $fileContents); | |
} | |
} | |
} | |
if ($runForDatabase) { | |
if (class_exists('Magetrend\Email\Model\Variable')) { | |
/** @var Magetrend\Email\Model\Variable $mtModel */ | |
$mtModel = $objectManager->get(\Magetrend\Email\Model\Variable::class); | |
$mtEmailCollection = $mtModel->getCollection(); | |
foreach ($mtEmailCollection as $mtEmailItem) { | |
$mtEmailItemVarValue = $mtEmailItem->getVarValue(); | |
$mutatedMtItem = false; | |
$dbTemplateId = "MT ITEM ID: " . $mtEmailItem->getEntityId(); | |
foreach ($variableReplaces as $oldValue => $newValue) { | |
if (strstr($mtEmailItemVarValue, $oldValue) !== false) { | |
$mtEmailItemVarValue = str_replace($oldValue, $newValue, $mtEmailItemVarValue); | |
$mtEmailItem->setVarValue($mtEmailItemVarValue); | |
$mtEmailItem->save(); | |
$replacedArray[$dbTemplateId][] = 'Replaced text: "' . $oldValue . '" -> "' . $newValue . '"'; | |
} | |
} | |
} | |
} | |
foreach ($templateCollection as $template) { | |
/** @var \Magento\Email\Model\Template $template */ | |
$templateTitle = $template->getTemplateSubject(); | |
$templateText = $template->getTemplateText(); | |
$mutatedDbItem = false; | |
$hasCountedDbItem = false; | |
$dbTemplateId = "Database ID: " . $template->getId() . " (" . $template->getTemplateCode() . ")"; | |
// Find and replace in title | |
foreach ($variableReplaces as $oldValue => $newValue) { | |
if (strstr($templateTitle, $oldValue) !== false) { | |
if (!$hasCountedDbItem) { | |
$replaceDbItems++; | |
$hasCountedDbItem = true; | |
} | |
if ($dryRun) { | |
$replacedArray[$dbTemplateId][] = 'DRY RUN: Would replace title: "' . $oldValue . '" -> "' . $newValue . '"'; | |
} else { | |
$replacedArray[$dbTemplateId][] = 'Replaced title/subject: "' . $oldValue . '" -> "' . $newValue . '"'; | |
$templateTitle = str_replace($oldValue, $newValue, $templateTitle); | |
$mutatedDbItem = true; | |
$template->setTemplateSubject($templateTitle); | |
} | |
} | |
} | |
// Find and replace in content | |
foreach ($variableReplaces as $oldValue => $newValue) { | |
if (strstr($templateText, $oldValue) !== false) { | |
if (!$hasCountedDbItem) { | |
$replaceDbItems++; | |
$hasCountedDbItem = true; | |
} | |
if ($dryRun) { | |
$replacedArray[$dbTemplateId][] = 'DRY RUN: Would replace text: "' . $oldValue . '" -> "' . $newValue . '"'; | |
} else { | |
$replacedArray[$dbTemplateId][] = 'Replaced text: "' . $oldValue . '" -> "' . $newValue . '"'; | |
$templateText = str_replace($oldValue, $newValue, $templateText); | |
$mutatedDbItem = true; | |
$template->setTemplateText($templateText); | |
} | |
} | |
} | |
if ($mutatedDbItem) { | |
$template->save(); | |
} | |
} | |
} | |
if ($runForDatabase) { | |
} | |
$replacedFileCount = $replaceFileItems + $replaceDbItems; | |
if ($replacedFileCount > 0) { | |
print_r($replacedArray); | |
echo "\n"; | |
echo "=================================================================="; | |
echo "\n"; | |
if ($dryRun) { | |
echo "DRY RUN: $replacedFileCount items would have been edited. Files: $replaceFileItems, DB items: $replaceDbItems\n"; | |
} else { | |
echo "$replacedFileCount items have been edited. Files: $replaceFileItems, DB items: $replaceDbItems \n"; | |
} | |
} else { | |
echo "Nothing has been replaced. Note: you can use '--files' and/or '--database' as variables to the file as a command.\n"; | |
} | |
} catch (Exception $exception) { | |
$logger->critical($exception); | |
} | |
$time_end = microtime(true); | |
//dividing with 60 will give the execution time in minutes other wise seconds | |
$execution_time = ($time_end - $time_start) / 60; | |
//execution time of the script | |
echo 'Total Execution Time: ' . $execution_time . ' Mins'; | |
echo "\n"; | |
echo "=================================================================="; | |
function getDirHtmlFiles($dir, &$results = []) | |
{ | |
$files = scandir($dir); | |
foreach ($files as $key => $value) { | |
$path = realpath($dir . DIRECTORY_SEPARATOR . $value); | |
if (!is_dir($path)) { | |
if (strstr($path, '.html') !== false) { | |
$results[] = $path; | |
} | |
} elseif ($value != "." && $value != "..") { | |
getDirHtmlFiles($path, $results); | |
} | |
} | |
return $results; | |
} |
Invoices don't seem to support the created_at_formatted variable, so that should probably be:
'invoice.getCreatedAt()' => 'invoice.created_at|raw',
'invoice.getCreatedAtFormatted()' => 'created_at|raw',
'invoice.getCreatedAtFormatted(1)' => 'created_at|raw',
'invoice.getCreatedAtFormatted(2)' => 'created_at|raw',
'invoice.getCreatedAtFormatted(3)' => 'created_at|raw',
If we want formatting maybe we should make a filter for that. Currently it gives you date & time, we could make a filter to strip the time.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Might be better to move
'htmlescape' => '',
above
'{{ ' => '{{',
since it's likely to cause some whitespace just after the curly braces.