web-dev-qa-db-ja.com

Wordpressに一時的にロケールの切り替えを強制するにはどうすればよいですか(qTranslateを使用)。

私はWooCommerceとqTranslateを実行している多言語ストアを持っていて、多言語の顧客メールを設定しようとしています。問題は、「注文完了」のEメールがadminバックエンドから送信され、注文が最初に行われた言語ではなく、バックエンドが使用されている言語で送信されることです。

これまで作業してきたのは、注文ロケールをカスタムフィールドとして保存し、自分のコードをWooCommerceの電子メール送信メカニズムにプラグインすることです。今しなければならないのは、現在のロケールを注文データに保存されているロケールに動的に切り替え、電子メールを送信して元に戻すことです。

現在、私は多数の場所でロケールを強制しようとしていますが、どれも機能しません。これが現在のコードです:

// 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);

デバッグ出力には、現在のロケールとorderロケールが正しく読み込まれていることが示され、get_locale()と並列のcustomer_processing_order()呼び出しは、現在のロケールではなくorderロケールを出力します。しかし、customer_processing_order()呼び出しによって生成された電子メールは、注文言語の文字列ではなく現在の言語文字列で作成されています。これを回避するためのアイデアはありますか。

5
olex

そして私はそれを手に入れました。欠けていたのは、初期化時に現在のロケールでロードされたWooCommerceのテキストドメインを再ロードすることでした。

// 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();

ロケール変数を設定するいくつかの呼び出しは、おそらく冗長であるか、または単に不要です。しかし、これはうまくいきます。

5
olex

わかりました、これは後でこれにつまずく人のためのもう少し完全な答えです。

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;
}

そして...チェックアウト時にそのフィールドを保存する必要があります。これは簡単です。

/**
 * 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'] ) );
    }
}

そして... ...(この部分は少し厄介ですが、私はEメール作成の最初の部分(件名)にフックしてから、言語をオーダーの言語に変更します)。スレッドが死んだらデフォルトに戻るので、あなたが本当にそれを元に戻すことを心配する必要はないと思います。これはコールバックでのみ発生するため、このEメールを送信した直後に終了するはずです。

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;
}
3
deweydb