WPML
Status
Resolved by author
Resolved in
WooCommerce Product Options 2.6.0
Related plugin/theme
WooCommerce Product Options
Topic tags
Compatibility, WCML

Overview of the issue

When using WooCommerce Product Options by Barn2 with WPML, Product option strings appear as untranslated on cart, checkout, and mini-cart, even though they are correctly translated on the product page.

Workaround

Please, make sure of having a full site backup of your site before proceeding.


  • In your theme’s functions.php file, paste the following code:
    /**
     * Translate WooCommerce Product Options texts when adding to cart
     * using the plugin's own WPML integration.
     */
     
    add_filter( 'woocommerce_add_cart_item_data', 'my_wpo_translate_cart_meta_with_wpml', 20, 4 );
     
    function my_wpo_translate_cart_meta_with_wpml( $cart_item_data, $product_id, $variation_id, $quantity ) {
     
        // If there are no WPO options in this cart item, do nothing.
        if ( empty( $cart_item_data['wpo_options'] ) ) {
            return $cart_item_data;
        }
     
        // Make sure the plugin classes exist (plugin is active and loaded).
        if (
            ! class_exists( 'Barn2PluginWC_Product_OptionsPlugin_Factory' ) ||
            ! class_exists( 'Barn2PluginWC_Product_OptionsIntegrationWPML' ) ||
            ! class_exists( 'Barn2PluginWC_Product_OptionsModelOption' )
        ) {
            return $cart_item_data;
        }
     
        // Get the plugin instance and the WPML integration helper.
        $plugin           = Barn2PluginWC_Product_OptionsPlugin_Factory::create( '', '' );
        $wpml_integration = new Barn2PluginWC_Product_OptionsIntegrationWPML( $plugin );
     
        foreach ( $cart_item_data['wpo_options'] as $option_id => &$option_data ) {
     
            // Load the option model so we can access the original data.
            $option = Barn2PluginWC_Product_OptionsModelOption::find( $option_data['option_id'] ?? 0 );
            if ( ! $option ) {
                continue;
            }
     
            // 1) Translate the option name (the "key" shown in cart/checkout).
            $translated_name     = $wpml_integration->translate_string( $option->name, $option, 'option_name' );
            $option_data['name'] = $translated_name;
     
            // 2) Translate each choice label, if any.
            if ( empty( $option_data['choice_data'] ) || empty( $option->choices ) ) {
                continue;
            }
     
            // Build a map: choice_id => index, to reproduce the same index WPML uses.
            $index_by_id = [];
            foreach ( $option->choices as $idx => $choice ) {
                if ( isset( $choice['id'] ) ) {
                    $index_by_id[ $choice['id'] ] = $idx;
                }
            }
     
            // Normalize the stored value to an array (covers both single and multi).
            $values = is_array( $option_data['value'] ) ? $option_data['value'] : [ $option_data['value'] ];
     
            foreach ( $option_data['choice_data'] as $i => &$choice_data ) {
                if ( ! isset( $choice_data['label'] ) ) {
                    continue;
                }
     
                // For free-text fields, there are usually no predefined choices to translate.
                if ( empty( $index_by_id ) ) {
                    continue;
                }
     
                $value_for_this_choice = $values[ $i ] ?? null;
                if ( ! isset( $index_by_id[ $value_for_this_choice ] ) ) {
                    continue;
                }
     
                $choice_index   = $index_by_id[ $value_for_this_choice ];
                $original_label = $option->choices[ $choice_index ]['label'];
     
                // Translate the choice label using the same context and index as when registered.
                $choice_data['label'] = $wpml_integration->translate_string(
                    $original_label,
                    $option,
                    'choice_label',
                    $choice_index
                );
            }
        }
     
        return $cart_item_data;
    }
    
       


  • Note: If you change language after having products in your cart, the labels will not be “translated”: they remain in the language that was active when the product was added (just like any other metadata that stores fixed texts). But it’s rare switching languages at that stage. A permanent fix will soon be applied by Barn2, please remove the added workaround when it is deployed

All known issues →