woocommerce_wpml = $woocommerce_wpml; $this->sitepress = $sitepress; add_action( 'init', [ $this, 'init' ] ); // Checkout page. add_action( 'wp_ajax_woocommerce_checkout', [ $this, 'switch_to_current' ], 9 ); add_action( 'wp_ajax_nopriv_woocommerce_checkout', [ $this, 'switch_to_current' ], 9 ); add_action( 'wp_ajax_wcml_order_delete_items', [ $this, 'order_delete_items' ] ); } public function init() { add_action( 'woocommerce_checkout_update_order_meta', [ $this, 'set_order_language' ] ); add_filter( 'icl_lang_sel_copy_parameters', [ $this, 'append_query_parameters' ] ); add_filter( 'the_comments', [ $this, 'get_filtered_comments' ] ); add_filter( 'woocommerce_order_get_items', [ $this, 'woocommerce_order_get_items' ], 10, 2 ); add_action( 'woocommerce_process_shop_order_meta', [ $this, 'set_order_language_backend' ], 10, 2 ); add_action( 'woocommerce_order_actions_start', [ $this, 'order_language_dropdown' ], 11 ); // After order currency drop-down. add_action( 'woocommerce_before_order_itemmeta', [ $this, 'backend_before_order_itemmeta' ], 100, 3 ); add_action( 'woocommerce_after_order_itemmeta', [ $this, 'backend_after_order_itemmeta' ], 100, 3 ); add_filter( 'woocommerce_get_item_downloads', [ $this, 'filter_downloadable_product_items' ], 10, 3 ); add_filter( 'woocommerce_customer_get_downloadable_products', [ $this, 'filter_customer_get_downloadable_products' ], 10, 3 ); if ( is_admin() ) { $this->maybe_set_dashboard_cookie(); } } /** * This method will try to convert the comments in the current language * if the user is identified (i.e. he has an ID). * * Note: I was not able to find the place where the strings are * registered and maybe this code is not used anymore. This should * be investigated in the future. * * @param \WP_Comment[] $comments * * @return \WP_Comment[] */ public function get_filtered_comments( $comments ) { // $ifIdentifiedUser :: void -> bool $ifIdentifiedUser = function () { return (bool) get_current_user_id(); }; // $translateInWoocommerce :: string -> string $translateInWoocommerce = \WPML\FP\partialRight( 'translate', 'woocommerce' ); // $translateComment :: WP_Comment -> WP_Comment $translateComment = Obj::over( Obj::lensProp( 'comment_content' ), $translateInWoocommerce ); return Maybe::of( $comments ) ->filter( $ifIdentifiedUser ) ->map( Fns::map( $translateComment ) ) ->getOrElse( $comments ); } /** * @param WC_Order_Item[] $items * @param WC_Order $order * * @return WC_Order_Item[] */ public function woocommerce_order_get_items( $items, $order ) { $translate_order_items = is_admin() || is_view_order_page() || is_order_received_page() || \WCML\Rest\Functions::isRestApiRequest(); /** * This filter hook allows to override if we need to translate order items. * * @since 4.11.0 * * @param bool True if we should to translate order items. * @param $items WC_Order_Item[] Order items. * @param $order WC_Order WC Order. */ $translate_order_items = apply_filters( 'wcml_should_translate_order_items', $translate_order_items, $items, $order ); if ( $items && $translate_order_items ) { $language_to_filter = $this->get_order_items_language_to_filter( $order ); $this->adjust_order_item_in_language( $items, $language_to_filter ); } return $items; } /** * @param array $items * @param string|bool $language_to_filter */ public function adjust_order_item_in_language( $items, $language_to_filter = false ) { if ( ! $language_to_filter ) { $language_to_filter = $this->sitepress->get_current_language(); } foreach ( $items as $index => $item ) { /** * This filter hook allows to override if we need to save adjusted order item. * * @since 4.11.0 * * @param bool True if we should save adjusted order item. * @param $item WC_Order_Item * @param $language_to_filter string Language to filter. */ $save_adjusted_item = apply_filters( 'wcml_should_save_adjusted_order_item_in_language', true, $item, $language_to_filter ); if ( $item instanceof WC_Order_Item_Product ) { if ( 'line_item' === $item->get_type() ) { $this->adjust_product_item_if_translated( $item, $language_to_filter ); $this->adjust_variation_item_if_translated( $item, $language_to_filter ); if ( $save_adjusted_item ) { $item->save(); } } } elseif ( $item instanceof WC_Order_Item_Shipping ) { $shipping_id = $item->get_method_id(); if ( $shipping_id ) { if ( method_exists( $item, 'get_instance_id' ) ) { $shipping_id .= $item->get_instance_id(); } $item->set_method_title( $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item->get_method_title(), $shipping_id, $language_to_filter ) ); if ( $save_adjusted_item ) { $item->save(); } } } } } /** * @param WC_Order_Item_Product $item * @param string $language_to_filter */ private function adjust_product_item_if_translated( $item, $language_to_filter ) { $translated_product_id = apply_filters( 'translate_object_id', $this->get_item_product_id( $item ), 'product', false, $language_to_filter ); if ( ! is_null( $translated_product_id ) ) { $item->set_product_id( $translated_product_id ); $item->set_name( get_post( $translated_product_id )->post_title ); } } /** * @param WC_Order_Item_Product $item * * @return false|int */ private function get_item_product_id( $item ) { $item_product_id = $item->get_product_id(); if ( 'product_variation' === get_post_type( $item_product_id ) ) { $item_product_id = wp_get_post_parent_id( $item_product_id ); } return $item_product_id; } /** * @param WC_Order_Item_Product $item * @param string $language_to_filter */ private function adjust_variation_item_if_translated( $item, $language_to_filter ) { $translated_variation_id = apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $language_to_filter ); if ( ! is_null( $translated_variation_id ) ) { $item->set_variation_id( $translated_variation_id ); $item->set_name( wc_get_product( $translated_variation_id )->get_name() ); $this->update_attribute_item_meta_value( $item, $translated_variation_id ); } } /** * @param WC_Order $order * * @return string */ private function get_order_items_language_to_filter( $order ) { if ( $this->is_on_order_edit_page() ) { $language = $this->sitepress->get_user_admin_language( get_current_user_id(), true ); } elseif ( $this->is_order_action_triggered_for_customer() ) { $order_language = get_post_meta( $order->get_id(), 'wpml_language', true ); $language = $order_language ? $order_language : $this->sitepress->get_default_language(); } else { $language = $this->sitepress->get_current_language(); } /** * This filter hook allows to override item language to filter. * * @since 4.11.0 * * @param $language string Order item language to filter. * @param $order WC_Order */ return apply_filters( 'wcml_get_order_items_language', $language, $order ); } /** * @return bool */ private function is_on_order_edit_page() { return isset( $_GET['post'] ) && 'shop_order' === get_post_type( $_GET['post'] ); } /** * @return bool */ private function is_order_action_triggered_for_customer() { return isset( $_GET['action'] ) && wpml_collect( [ 'woocommerce_mark_order_complete', 'woocommerce_mark_order_status', 'mark_processing' ] )->contains( $_GET['action'] ); } /** * @param WC_Order_Item_Product $item * @param int $variation_id */ private function update_attribute_item_meta_value( $item, $variation_id ) { foreach ( $item->get_meta_data() as $meta_data ) { $data = $meta_data->get_data(); $attribute_value = get_post_meta( $variation_id, 'attribute_' . $data['key'], true ); if ( $attribute_value ) { $item->update_meta_data( $data['key'], $attribute_value, isset( $data['id'] ) ? $data['id'] : 0 ); } } } public function backend_before_order_itemmeta( $item_id, $item, $product ) { global $sitepress; if ( $this->get_order_language_by_item_id( $item_id ) != $sitepress->get_user_admin_language( get_current_user_id(), true ) ) { foreach ( $item['item_meta'] as $key => $item_meta ) { if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) === 'pa_' ) { $item_meta = (array) $item_meta; foreach ( $item_meta as $value ) { $this->force_update_itemmeta( $item_id, $key, $value, $sitepress->get_user_admin_language( get_current_user_id(), true ) ); } } } } } public function backend_after_order_itemmeta( $item_id, $item, $product ) { global $sitepress; $order_languge = $this->get_order_language_by_item_id( $item_id ); if ( $order_languge != $sitepress->get_user_admin_language( get_current_user_id(), true ) ) { foreach ( $item['item_meta'] as $key => $item_meta ) { if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) === 'pa_' ) { $item_meta = (array) $item_meta; foreach ( $item_meta as $value ) { $this->force_update_itemmeta( $item_id, $key, $value, $order_languge ); } } } } } public function get_order_language_by_item_id( $item_id ) { global $wpdb; $order_id = $wpdb->get_var( $wpdb->prepare( "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $item_id ) ); return get_post_meta( $order_id, 'wpml_language', true ); } // force update to display attribute in correct language on edit order page. public function force_update_itemmeta( $item_id, $key, $value, $languge ) { global $wpdb, $woocommerce_wpml; $taxonomy = substr( $key, 0, 3 ) !== 'pa_' ? wc_attribute_taxonomy_name( $key ) : $key; $term_id = $woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $value ); $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge ); if ( $translated_term ) { $value = $translated_term->slug; $wpdb->update( $wpdb->prefix . 'woocommerce_order_itemmeta', [ 'meta_value' => $value ], [ 'order_item_id' => $item_id, 'meta_key' => $key, ] ); } } /** * Adds language to order post type. * * @param type $order_id */ public function set_order_language( $order_id ) { if ( ! get_post_meta( $order_id, 'wpml_language' ) ) { update_post_meta( $order_id, 'wpml_language', ICL_LANGUAGE_CODE ); } } public function append_query_parameters( $parameters ) { if ( is_order_received_page() || is_checkout() ) { if ( ! in_array( 'order', $parameters ) ) { $parameters[] = 'order'; } if ( ! in_array( 'key', $parameters ) ) { $parameters[] = 'key'; } } return $parameters; } public function switch_to_current() { $this->woocommerce_wpml->emails->change_email_language( $this->sitepress->get_current_language() ); } public function order_language_dropdown( $order_id ) { if ( ! get_post_meta( $order_id, '_order_currency' ) ) { $languages = apply_filters( 'wpml_active_languages', [], [ 'skip_missing' => 0, 'orderby' => 'code', ] ); $selected_lang = isset( $_COOKIE [ self::DASHBOARD_COOKIE_NAME ] ) ? $_COOKIE [ self::DASHBOARD_COOKIE_NAME ] : $this->sitepress->get_default_language(); ?>