• Hello,

    First of all, I love your plugin and it works great!

    I would like to propose a new setting / option to make the order sync when WPML is active.
    I looked into the plugin and made some changes to Database.php wich works perfectly

    When WPML is active, and the store owner changes the order in the default language, the same order should be applied to the translated products in all secondary languages. This saves a lot of time.

    Ideally as a plugin option:

    “Sync ordering across WPML translations”

    1) Add a new private method in Database.php

    This should be one-way sync:
    default language → translations
    (so secondary language ordering never overwrites the default language ordering)

    Add this inside the ReWooProducts\Database class:

    /**
    * WPML sync: copy ordering written in DEFAULT language to translated products/categories.
    * One-way sync (default -> translations).
    *
    * @param array $sort_orders Array of sort_order => product_id mappings
    * @param int $category_id Category ID (0 for global)
    *
    * @return void
    */
    private static function sync_orders_to_wpml_translations( $sort_orders, $category_id = 0 ) {
    // Only if WPML is active
    if ( ! function_exists( 'apply_filters' ) || ! has_filter( 'wpml_default_language' ) ) {
    return;
    }

    $default_lang = apply_filters( 'wpml_default_language', null );
    $current_lang = apply_filters( 'wpml_current_language', null );

    if ( empty( $default_lang ) ) {
    return;
    }

    // Only sync when saving from default language (one-way)
    if ( ! empty( $current_lang ) && $current_lang !== $default_lang ) {
    return;
    }

    $languages = apply_filters( 'wpml_active_languages', null, [ 'skip_missing' => 1 ] );
    if ( empty( $languages ) || ! is_array( $languages ) ) {
    return;
    }

    global $wpdb;
    $table_name = self::get_table_name();
    $category_id = absint( $category_id );

    foreach ( $languages as $lang_code => $lang_info ) {
    if ( $lang_code === $default_lang ) {
    continue;
    }

    // Translate category term id for this language (unless global category_id=0)
    $translated_category_id = 0;
    if ( $category_id > 0 ) {
    $translated_category_id = (int) apply_filters( 'wpml_object_id', $category_id, 'product_cat', false, $lang_code );
    // If category not translated in this language, skip syncing for it
    if ( $translated_category_id <= 0 ) {
    continue;
    }
    }

    $placeholders = [];
    $args = [];

    foreach ( $sort_orders as $sort_order => $product_id ) {
    $product_id = absint( $product_id );
    $sort_order = absint( $sort_order );

    if ( $product_id <= 0 ) {
    continue;
    }

    // ALSO sync WooCommerce native menu_order for shop overview sorting
    $wpdb->update(
    $wpdb->posts,
    [ 'menu_order' => $sort_order ],
    [ 'ID' => $translated_product_id ],
    [ '%d' ],
    [ '%d' ]
    );

    // Translate product ID
    $translated_product_id = (int) apply_filters( 'wpml_object_id', $product_id, 'product', false, $lang_code );
    if ( $translated_product_id <= 0 ) {
    // Product not translated in this language
    continue;
    }

    $placeholders[] = "(%d, %d, %d, NOW(), NOW())";
    $args[] = $translated_product_id;
    $args[] = $translated_category_id;
    $args[] = $sort_order;
    }

    if ( empty( $placeholders ) ) {
    continue;
    }

    $sql = "
    INSERT INTO {$table_name} (product_id, category_id, sort_order, created_at, updated_at)
    VALUES " . implode( ',', $placeholders ) . "
    ON DUPLICATE KEY UPDATE sort_order = VALUES(sort_order), updated_at = NOW()
    ";

    $wpdb->query( $wpdb->prepare( $sql, $args ) );
    }
    }

    2) Call the sync method after saving order changes A) In Database::bulk_update_orders()

    After the successful insert/update (right before return true;) add:

    self::sync_orders_to_wpml_translations( $sort_orders, $category_id );

    B) In Database::set_sort_order()

    After saving successfully, add:

    self::sync_orders_to_wpml_translations( [ $sort_order => $product_id ], $category_id );
    • This topic was modified 3 weeks, 6 days ago by ridle. Reason: fix for shop overview page
Viewing 1 replies (of 1 total)
  • Plugin Author Aslam Doctor

    (@aslamdoctor)

    Hi @ridle ,

    Thank you so much for the kind words. I’m really glad to hear the plugin is working well for you!

    I also appreciate you taking the time to dig into the code and share such a detailed implementation. Syncing product ordering across WPML translations is a great idea and definitely a valuable workflow improvement for multilingual stores.

    If you are interested, I would like you to help me test the updates for WPML support before I release them in next version. Please connect with me through here.

    Kind regards,

    Aslam

Viewing 1 replies (of 1 total)

You must be logged in to reply to this topic.