WPML sync order
-
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 perfectlyWhen 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.phpThis should be one-way sync:
default language → translations
(so secondary language ordering never overwrites the default language ordering)Add this inside the
ReWooProducts\Databaseclass:/**
* 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 );
You must be logged in to reply to this topic.