sitepress = $sitepress; $this->woocommerce_wpml = $woocommerce_wpml; $this->tp = $tp; } public function add_hooks(){ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 ); add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 ); add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 ); add_action( 'wcml_update_extra_fields', array( $this, 'bundle_update' ), 10, 4 ); add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle' ), 5, 3 ); add_filter( 'woocommerce_cart_loaded_from_session', array( $this, 'resync_bundle_clean' ), 10 ); if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WCML_VERSION' ), '3.7.2', '>' ) ) { add_filter( 'option_wpml_config_files_arr', array( $this, 'make__bundle_data_not_translatable_by_default' ), 0 ); } if( is_admin() ){ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_bundle_data_translation_package' ), 10, 2 ); add_action( 'wpml_translation_job_saved', array( $this, 'save_bundle_data_translation' ), 10, 3 ); add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) ); } } function make__bundle_data_not_translatable_by_default( $wpml_config_array ){ if( isset( $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] ) ){ $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] = str_replace( '_bundle_data', '_bundle_data', $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] ); } return $wpml_config_array; } // Sync Bundled product '_bundle_data' with translated values when the product is duplicated function sync_bundled_ids( $original_product_id, $trnsl_product_id ){ $bundle_data_array = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) ); if( $bundle_data_array ){ $lang = $this->sitepress->get_language_for_element( $trnsl_product_id, 'post_product' ); $tr_bundle_meta = maybe_unserialize( get_post_meta( $trnsl_product_id, '_bundle_data', true ) ); $i = 2; foreach( $bundle_data_array as $bundle_key => $bundle_data ){ $key_data = $this->translate_bundle_key( $bundle_key, $lang ); $tr_id = $key_data->tr_id; $tr_bundle_key = $key_data->tr_key; $tr_bundle[ $tr_bundle_key ] = $bundle_data; $tr_bundle[ $tr_bundle_key ][ 'product_id' ] = $tr_id; if( isset( $bundle_data[ 'product_title' ] ) ){ if( $bundle_data[ 'override_title' ] == 'yes' ){ $tr_bundle[ $tr_bundle_key ][ 'product_title' ] = isset( $tr_bundle_meta[ $tr_bundle_key ][ 'product_title' ] ) ? $tr_bundle_meta[ $tr_bundle_key ][ 'product_title' ] : ''; }else{ $tr_title= get_the_title( $tr_id ); $tr_bundle[ $tr_bundle_key ][ 'product_title' ] = $tr_title; } } if( isset( $bundle_data[ 'product_description' ] ) ){ if( $bundle_data[ 'override_description' ] == 'yes' ){ $tr_bundle[ $tr_bundle_key ][ 'product_description' ] = isset( $tr_bundle_meta[ $tr_bundle_key ][ 'product_description' ] ) ? $tr_bundle_meta[ $tr_bundle_key ][ 'product_description' ] : ''; }else{ $tr_prod = get_post( $tr_id ); $tr_desc = $tr_prod->post_excerpt; $tr_bundle[ $tr_bundle_key ][ 'product_description' ] = $tr_desc; } } if( isset( $bundle_data[ 'filter_variations' ] ) && $bundle_data[ 'filter_variations' ] == 'yes' ){ $allowed_var = $bundle_data[ 'allowed_variations' ]; foreach( $allowed_var as $key => $var_id ){ $tr_var_id = apply_filters( 'translate_object_id', $var_id, get_post_type( $var_id ), true, $lang ); $tr_bundle[ $tr_bundle_key ][ 'allowed_variations' ][ $key ] = $tr_var_id; } } if( isset( $bundle_data[ 'bundle_defaults' ] ) && !empty( $bundle_data[ 'bundle_defaults' ] ) ){ foreach( $bundle_data[ 'bundle_defaults' ] as $tax => $term_slug ){ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $term_slug ); if( $term_id ){ // Global Attribute $tr_def_id = apply_filters( 'translate_object_id', $term_id, $tax, true, $lang ); $tr_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_def_id, $tax ); $tr_bundle[ $tr_bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_term->slug; }else{ // Custom Attribute $args = array( 'post_type' => 'product_variation', 'meta_key' => 'attribute_'.$tax, 'meta_value' => $term_slug, 'meta_compare' => '=' ); $variationloop = new WP_Query( $args ); while ( $variationloop->have_posts() ) : $variationloop->the_post(); $tr_var_id = apply_filters( 'translate_object_id', get_the_ID(), 'product_variation', true, $lang ); $tr_meta = get_post_meta( $tr_var_id, 'attribute_'.$tax , true ); $tr_bundle[ $tr_bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_meta; endwhile; } } } } update_post_meta( $trnsl_product_id, '_bundle_data', $tr_bundle ); return $tr_bundle; } } public function translate_bundle_key( $key, $lang, $return_original_if_missing = true ) { $key_parts = explode( '_', $key ); $has_multiple_products = count( $key_parts ) > 1; $data = new stdClass; $data->id = $has_multiple_products ? $key_parts[ 0 ] : $key; $data->tr_id = apply_filters( 'translate_object_id', $data->id, get_post_type( $data->id ), $return_original_if_missing, $lang ); $data->tr_key = $data->tr_id . ( $has_multiple_products ? '_' . $key_parts[ 1 ] : '' ); return $data; } // Update Bundled products title and descritpion after saving the translation function bundle_update( $original_product_id, $tr_id, $data, $lang ){ $tr_bundle_data = array(); $tr_bundle_data = maybe_unserialize( get_post_meta($tr_id,'_bundle_data', true ) ); $bundle_data = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) ); if( empty( $bundle_data ) ){ return; } $product_bundles = array_keys( $bundle_data ); foreach ( $product_bundles as $key => $bundle_key ) { $key_data = $this->translate_bundle_key( $bundle_key, $lang ); $tr_bundle_key = $key_data->tr_key; if( isset( $tr_bundle_data[ $tr_bundle_key ] ) ){ $tr_bundle_data[ $tr_bundle_key ][ 'product_title' ] = $data[ md5( 'bundle_'.$bundle_key.'_title' ) ]; $tr_bundle_data[ $tr_bundle_key ][ 'product_description' ] = $data[ md5( 'bundle_'.$bundle_key.'_desc' ) ]; } } update_post_meta( $tr_id, '_bundle_data', $tr_bundle_data ); return $tr_bundle_data; } // Add Bundles Box to WCML Translation GUI function custom_box_html( $obj, $product_id, $data ){ $product_bundles = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) ); if( empty( $product_bundles ) || $product_bundles == false ){ return false; } $bundles_section = new WPML_Editor_UI_Field_Section( __( 'Product Bundles', 'woocommerce-multilingual' ) ); end( $product_bundles ); $last_key = key( $product_bundles ); $divider = true; $flag = false; foreach ( $product_bundles as $bundle_id => $product_bundle ) { $add_group = false; if( $bundle_id == $last_key ){ $divider = false; } $group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_id ), $divider ); if( $product_bundle[ 'override_title' ] == 'yes' ) { $bundle_field = new WPML_Editor_UI_Single_Line_Field( 'bundle_' . $bundle_id . '_title', __( 'Name', 'woocommerce-multilingual' ), $data, false ); $group->add_field( $bundle_field ); $add_group = true; } if( $product_bundle[ 'override_description' ] == 'yes' ){ $bundle_field = new WPML_Editor_UI_Single_Line_Field( 'bundle_'.$bundle_id.'_desc' , __( 'Description', 'woocommerce-multilingual' ), $data, false ); $group->add_field( $bundle_field ); $add_group = true; } if( $add_group ){ $bundles_section->add_field( $group ); $flag = true; } } if( $flag ){ $obj->add_field( $bundles_section ); } } function custom_box_html_data( $data, $product_id, $translation, $lang ){ $bundle_data = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) ); if( $translation ) { $tr_product_id = $translation->ID; $tr_bundle_data = maybe_unserialize( get_post_meta( $tr_product_id, '_bundle_data', true ) ); } if( empty( $bundle_data ) || $bundle_data == false ){ return $data; } $product_bundles = array_keys( $bundle_data ); foreach ( $product_bundles as $bundle_key ) { $key_data = $this->translate_bundle_key( $bundle_key, $lang ); $tr_bundle_key = $key_data->tr_key; if( $bundle_data[ $bundle_key ][ 'override_title' ] == 'yes' ){ $data[ 'bundle_'.$bundle_key.'_title' ] = array( 'original' => $bundle_data[ $bundle_key ][ 'product_title' ] ); if( isset( $tr_bundle_data[ $tr_bundle_key ][ 'override_title' ] ) ){ $data[ 'bundle_'.$bundle_key.'_title' ][ 'translation' ] = $tr_bundle_data[ $tr_bundle_key ][ 'product_title' ]; }else{ $data[ 'bundle_'.$bundle_key.'_title' ][ 'translation' ] = ''; } } if( $bundle_data[ $bundle_key ][ 'override_description' ] == 'yes' ){ $data[ 'bundle_'.$bundle_key.'_desc' ] = array( 'original' => $bundle_data[ $bundle_key ][ 'product_description' ] ); if( isset( $tr_bundle_data[ $tr_bundle_key ][ 'override_description' ] ) ){ $data[ 'bundle_'.$bundle_key.'_desc' ][ 'translation' ] = $tr_bundle_data[ $tr_bundle_key ][ 'product_description' ]; }else{ $data[ 'bundle_'.$bundle_key.'_desc' ][ 'translation' ] = ''; } } } return $data; } function resync_bundle( $cart_item, $session_values, $cart_item_key ) { if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) { $current_bundle_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', true ); if ( $cart_item[ 'product_id' ] != $current_bundle_id ) { $old_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data ); $cart_item[ 'data' ] = wc_get_product( $current_bundle_id ); if( is_array( $cart_item[ 'data' ]->bundle_data ) ){ $new_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data ); $remapped_bundled_item_ids = array(); foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) { $remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ]; } $cart_item[ 'remapped_bundled_item_ids' ] = $remapped_bundled_item_ids; if ( isset( $cart_item[ 'stamp' ] ) ) { $new_stamp = array(); foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) { $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data; } $cart_item[ 'stamp' ] = $new_stamp; } } } } if ( isset( $cart_item[ 'bundled_by' ] ) && isset( WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ] ) ) { $bundle_cart_item = WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ]; if ( isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ] ) && isset( $cart_item[ 'bundled_item_id' ] ) && isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ][ $cart_item[ 'bundled_item_id' ] ] ) ) { $old_id = $cart_item[ 'bundled_item_id' ]; $remapped_bundled_item_ids = $bundle_cart_item[ 'remapped_bundled_item_ids' ]; $cart_item[ 'bundled_item_id' ] = $remapped_bundled_item_ids[ $cart_item[ 'bundled_item_id' ] ]; if ( isset( $cart_item[ 'stamp' ] ) ) { $new_stamp = array(); foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) { $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data; } $cart_item[ 'stamp' ] = $new_stamp; } } } return $cart_item; } function resync_bundle_clean( $cart ) { foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) { if ( isset( $cart_item[ 'bundled_items' ] ) && $this->is_bundle_product( $cart_item[ 'product_id' ] ) ) { if ( isset( $cart_item[ 'remapped_bundled_item_ids' ] ) ) { unset( WC()->cart->cart_contents[ $cart_item_key ][ 'remapped_bundled_item_ids' ] ); } } } } function append_bundle_data_translation_package( $package, $post ){ if( $post->post_type == 'product' ) { $bundle_data = get_post_meta( $post->ID, '_bundle_data', true ); if( $bundle_data ){ $fields = array( 'title', 'description' ); foreach( $bundle_data as $bundle_key => $product ){ foreach( $fields as $field ) { if ( $product[ 'override_' . $field ] == 'yes' && !empty( $product[ 'product_' . $field ] ) ) { $package[ 'contents' ][ 'product_bundles:' . $bundle_key . ':' . $field ] = array( 'translate' => 1, 'data' => $this->tp->encode_field_data( $product[ 'product_' . $field ], 'base64' ), 'format' => 'base64' ); } } } } } return $package; } function save_bundle_data_translation( $post_id, $data, $job ){ if ( $this->is_bundle_product( $post_id ) ) { remove_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 ); $bundle_data = get_post_meta( $post_id, '_bundle_data', true ); $bundle_data_original = get_post_meta( $job->original_doc_id , '_bundle_data', true ); $translated_bundle_pieces = array(); foreach( $data as $value){ if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value[ 'field_type' ], $matches ) ){ $bundle_key = $matches[1]; $field = $matches[2]; $key_data = $this->translate_bundle_key( $bundle_key, $job->language_code ); if( !isset( $bundle_data[ $key_data->tr_key ] ) ){ $bundle_data[ $key_data->tr_key ] = array( 'product_id' => $key_data->tr_id, 'hide_thumbnail' => $bundle_data_original[ $bundle_key ][ 'hide_thumbnail' ], 'override_title' => $bundle_data_original[ $bundle_key ][ 'override_title' ], 'product_title' => '', 'override_description' => $bundle_data_original[ $bundle_key ][ 'override_description' ], 'product_description' => '', 'optional' => $bundle_data_original[ $bundle_key ][ 'optional' ], 'bundle_quantity' => $bundle_data_original[ $bundle_key ][ 'bundle_quantity' ], 'bundle_quantity_max' => $bundle_data_original[ $bundle_key ][ 'bundle_quantity_max' ], 'bundle_discount' => $bundle_data_original[ $bundle_key ][ 'bundle_discount' ], 'visibility' => $bundle_data_original[ $bundle_key ][ 'visibility' ], ); } $bundle_data[ $key_data->tr_key ][ 'product_'.$field ] = $value[ 'data' ]; } } update_post_meta( $post_id, '_bundle_data', $bundle_data ); } } function replace_tm_editor_custom_fields_with_own_sections( $fields ){ $fields[] = '_bundle_data'; return $fields; } public function is_bundle_product( $product_id ){ if ( 'bundle' === WooCommerce_Functions_Wrapper::get_product_type( $product_id ) ) { return true; } return false; } }