Email Notifications in Different Languages
-
Hi,
First of all many thanks for this great plugin (I have the Pro version).
I am facing the following problem: I have a buyer that made a purchase in German (I am using Polylang):This buyer got the “Order Confirmation” email notification in German, the “Order shipped” email notification in English and the “Invoice (PDF)” in English.
Given that this order purchase was realized in German, I would like to have all email notifications in German.
How to solve this?
Worth mentioning that I am using the latest versions of Germanized and Germanized Pro.
Thanks!
-
As I said: The details are tricky. The invoice title/wording comes from a custom registered document type. That happens on init hook and you’d need to manually reset that global variable before sending the email to make sure it is reloaded within the current requests’ language. The data is stored within $sab_document_types and registered via
sab_register_document_type()
(similar to WP core post types). If you really want to make the whole thing 100 % compatible with PolyLang you’ll need to dig deep into the code. I’m sorry, but we do not have the resources to guide you through the code..Best,
DennisHi Dennis,
Thank you for your answer. I tried to reset the global variable$sab_document_types
, but it got even worse, the whole email is sent in English (instead of the language ordered by the customer).<?php
// WooCommerce - Order email notifications language set based on order using Polylang
// Last update: 2024-09-24
if (class_exists('WooCommerce') && WC() && class_exists('Polylang')) {
class WC_Email_Locale_Handler
{
public function __construct()
{
// Hook into the email header to switch locale before email content
add_action($hook_name = 'woocommerce_email_header', $callback = [$this, 'set_email_locale_based_on_order'], $priority = 10, $accepted_args = 2);
add_action($hook_name = 'woocommerce_email_before_order_table', $callback = [$this, 'set_email_locale_based_on_order'], $priority = 10, $accepted_args = 2);
// Hook into the email footer to restore the original locale after email content
add_action($hook_name = 'woocommerce_email_footer', $callback = [$this, 'restore_email_locale'], $priority = 10, $accepted_args = 1);
// Hook into resending emails to handle locale switching
add_action($hook_name = 'woocommerce_before_resend_order_emails', $callback = [$this, 'set_locale_on_woocommerce_before_resend_order_emails'], $priority = 10, $accepted_args = 1);
// Hook into email recipient filter to switch locale before generating the subject
add_filter($hook_name = 'woocommerce_email_recipient_new_order', $callback = [$this, 'set_locale_on_woocommerce_email_recipient_new_order'], $priority = 10, $accepted_args = 2);
}
public function set_email_locale_based_on_order($email_heading, $email)
{
if (isset($email->object)) {
// Get the language locale of the order
$order_locale = $this->get_locale_from_object($email->object);
if ($order_locale) {
// Switch to the order's locale
switch_to_locale($order_locale);
// Reset the global document types
if (function_exists('sab_register_document_type')) {
$this->reset_sab_document_types();
}
}
}
}
public function restore_email_locale()
{
restore_previous_locale();
}
public function set_locale_on_woocommerce_before_resend_order_emails($order)
{
if ($order) {
// Get the language locale of the order
$order_locale = $this->get_locale_from_object($order);
if ($order_locale) {
// Switch to the order's locale
switch_to_locale($order_locale);
// Reset the global document types
if (function_exists('sab_register_document_type')) {
$this->reset_sab_document_types();
}
}
}
}
public function set_locale_on_woocommerce_email_recipient_new_order($to, $order)
{
// Get the order locale
$order_locale = $this->get_locale_from_object($order);
if ($order_locale) {
// Switch to the order's locale before generating the subject
switch_to_locale($order_locale);
}
return $to;
}
private function map_language_to_locale($language_slug)
{
// Define a mapping of language slugs to locale codes
$mapping = array(
'de' => 'de_DE',
'en' => 'en_US',
'pt' => 'pt_BR',
);
return isset($mapping[$language_slug]) ? $mapping[$language_slug] : false;
}
private function get_locale_from_object($object)
{
$order = null;
// Check if the object is a WC_Order or if the object is a Shipment/Invoice from "Germanized for WooCommerce" plugin
if (is_a($object, 'WC_Order')) {
$order = $object;
} elseif (is_a($object, 'Vendidero\Germanized\Shipments\Shipment') || is_a($object, 'Vendidero\StoreaBill\Invoice\Invoice')) {
$order = $object->get_order();
}
if ($order && function_exists('pll_get_post_language')) {
// Get the language slug of the order
$order_language = pll_get_post_language($order->get_id(), 'slug');
// Map the language slug to a locale code
return $this->map_language_to_locale($order_language);
}
return null;
}
private function reset_sab_document_types()
{
global $sab_document_types; // Import the global variable
// Reset the global document types to force reloading in the current language
if (isset($sab_document_types)) {
$sab_document_types = array(); // Clear the existing types
Package::register_document_types(); // Re-register document types
}
}
}
// Initialize the handler class
new WC_Email_Locale_Handler();
}I think I will give up. It would be nice to have official support to Polylang in the future. Perhaps a simple edit in the
get_order_language( $order )
function stored in thewoocommerce-germanized-pro/packages/storeabill/src/Compatibility/WPML.php
file would solve this problem, like:protected static function get_order_language( $order ) {
$order = is_numeric( $order ) ? wc_get_order( $order ) : $order;
$lang = '';
if ( $order ) {
if ( function_exists('icl_object_id') ) {
$lang = $order->get_meta( 'wpml_language' ); // WPML
} else if ( function_exists('pll_get_post_language') ) {
$lang = pll_get_post_language($order->get_id(), 'slug'); // Polylang
$lang = map_language_to_locale($lang);
}
}
return $lang;
}Kind regards
- You must be logged in to reply to this topic.