Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a multi-language store running WooCommerce and qTranslate, and am trying to setup multi-language customer emails. The problem is, the "order complete" email gets sent from the admin backend, and it is sent in the language the backend is used in, not in the language that the order was initially made in.

What I've got working so far is storing the order locale as a custom field, and plugging my code into WooCommerce's email sending mechanism. What I need to do now is to dynamically switch the current locale to the one saved in the order data, dispatch the email, and switch it back.

Currently, I'm trying to force locale in a multitude of places, but none of them work. Here's the current code:

// get order language and its locale from qTranslate config
$order_custom_data = get_post_custom($order_id);
$new_locale = $order_custom_data['Customer Locale'][0];

// save current locale
$old_locale = get_locale();

// set the current locale and send email with it active
setlocale(LC_ALL, $new_locale);
global $q_config, $locale;
$locale = $new_locale;
$q_config['language'] = substr($new_locale, 0, 2);
// dispatch email
global $wc_cle_wc_email;
$wc_cle_wc_email->customer_processing_order($order_id);

// set the old locale back
$q_config['language'] = substr($old_locale, 0, 2);
$locale = $old_locale;
setlocale(LC_ALL, $old_locale);

Debug output shows the current and order locales being read correctly, and a get_locale() call parallel to customer_processing_order() outputs the order locale instead of the current one. But the email generated by the customer_processing_order() call is built with the current language strings instead of those in the order language. Any ideas how to work around this?

share|improve this question

2 Answers 2

Ok, here is a slightly more complete answer for those who stumble upon this later.

add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
function custom_override_checkout_fields( $fields ) {
         $fields['order']['language']['placeholder'] = '';
         $fields['order']['language']['type'] = 'text';
         $fields['order']['language']['label'] = 'language';
         $fields['order']['language']['class'] = array('hidden'); 
         $fields['order']['language']['default'] = qtrans_getLanguage();
     return $fields;
}

And then... you need to save that field on checkout, which is simple:

/**
 * Save the language to the order (despite what woocommerce doc says this is required)
 */
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['language'] ) ) {
        update_post_meta( $order_id, 'language', sanitize_text_field( $_POST['language'] ) );
    }
}

And then... (this part is a bit hacky, but i hook into the beginning of the email creation (the subject) and then change the language to the order's language). I don't think you really need to worry about changing it back since once the thread dies it will switch back to default. And it should just die right after sending this email because this only happens on a callback.

add_filter('woocommerce_email_subject_customer_completed_order', 'waspdigital_order_complete_language_fix', 1, 2);
function waspdigital_order_complete_language_fix( $subject, $order ){
    global $woocommerce;
    $new_locale = get_post_meta( $order->id, 'language', true);
    // set the current locale and send email with it active
    unload_textdomain('woocommerce');
    setlocale(LC_ALL, $new_locale);
    global $q_config, $locale, $woocommerce;
    $locale = $new_locale;
    $q_config['language'] = substr($new_locale, 0, 2);
    $woocommerce->load_plugin_textdomain();

/*
    // set the old locale back
    unload_textdomain('woocommerce');
    $q_config['language'] = substr($old_locale, 0, 2);
    $locale = $old_locale;
    setlocale(LC_ALL, $old_locale);
    $woocommerce->load_plugin_textdomain();
*/

    return $subject;
}
share|improve this answer

And I got it. What was missing was re-loading the text domain for WooCommerce, that was loaded with the current locale at initialization:

// set the current locale and send email with it active
unload_textdomain('woocommerce');
setlocale(LC_ALL, $new_locale);
global $q_config, $locale, $woocommerce;
$locale = $new_locale;
$q_config['language'] = substr($new_locale, 0, 2);
$woocommerce->load_plugin_textdomain();

global $wc_cle_wc_email;
$wc_cle_wc_email->customer_completed_order($order_id);

// set the old locale back
unload_textdomain('woocommerce');
$q_config['language'] = substr($old_locale, 0, 2);
$locale = $old_locale;
setlocale(LC_ALL, $old_locale);
$woocommerce->load_plugin_textdomain();

Some of the calls setting the locale variables are probably redundant and/or simply unnecessary, but this works.

share|improve this answer
    
where did you put this code? is this inside a hook? I'm stuck on the exact same thing! –  deweydb Jul 11 at 22:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.