Commit 99d6aeb02d7 for woocommerce
commit 99d6aeb02d7882365c41ab08ec2f80f103476fc6
Author: Daniel Mallory <daniel.mallory@automattic.com>
Date: Fri Sep 11 20:34:05 2026 +0100
Fix product attribute Term ID sorting (#68517)
* fix: honor product attribute term ID ordering
* docs: add attribute term ordering changelog
diff --git a/plugins/woocommerce/changelog/fix-45521-attribute-term-id-order b/plugins/woocommerce/changelog/fix-45521-attribute-term-id-order
new file mode 100644
index 00000000000..4551566b2bd
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-45521-attribute-term-id-order
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Honor the Term ID sort order for product attribute terms and variation dropdowns.
diff --git a/plugins/woocommerce/includes/wc-term-functions.php b/plugins/woocommerce/includes/wc-term-functions.php
index f74c91954ed..4c70a4c2bc9 100644
--- a/plugins/woocommerce/includes/wc-term-functions.php
+++ b/plugins/woocommerce/includes/wc-term-functions.php
@@ -37,6 +37,9 @@ function wc_change_get_terms_defaults( $defaults, $taxonomies ) {
// Change defaults. Invalid values will be changed later @see wc_change_pre_get_terms.
// These are in place so we know if a specific order was requested.
switch ( $orderby ) {
+ case 'id':
+ $defaults['orderby'] = 'term_id';
+ break;
case 'menu_order':
case 'name_num':
case 'parent':
diff --git a/plugins/woocommerce/tests/php/includes/wc-term-functions-tests.php b/plugins/woocommerce/tests/php/includes/wc-term-functions-tests.php
index 7246e21fcb9..abe374c4436 100644
--- a/plugins/woocommerce/tests/php/includes/wc-term-functions-tests.php
+++ b/plugins/woocommerce/tests/php/includes/wc-term-functions-tests.php
@@ -86,6 +86,35 @@ class WC_Term_Functions_Tests extends \WC_Unit_Test_Case {
parent::tearDown();
}
+ /**
+ * @testdox Should honor the attribute's Term ID default without overriding explicit query ordering.
+ */
+ public function test_attribute_term_id_ordering(): void {
+ global $wc_product_attributes;
+
+ $original_attributes = $wc_product_attributes;
+ $attribute = WC_Helper_Product::create_attribute( 'id_sort_test', array( 'Zebra', 'Apple', 'Mango' ) );
+ $taxonomy = $attribute['attribute_taxonomy'];
+ try {
+ wc_update_attribute( $attribute['attribute_id'], array( 'order_by' => 'id' ) );
+ $product_id = $this->products['product1']->get_id();
+ wp_set_object_terms( $product_id, $attribute['term_ids'], $taxonomy );
+
+ $args = array(
+ 'taxonomy' => $taxonomy,
+ 'hide_empty' => false,
+ 'fields' => 'names',
+ );
+ $this->assertSame( array( 'Zebra', 'Apple', 'Mango' ), get_terms( $args ), 'Default queries should honor the saved Term ID setting.' );
+ $this->assertSame( array( 'Zebra', 'Apple', 'Mango' ), wc_get_product_terms( $product_id, $taxonomy, array( 'fields' => 'names' ) ), 'Product term queries should use the same default ordering.' );
+ $this->assertSame( array( 'Apple', 'Mango', 'Zebra' ), get_terms( array_merge( $args, array( 'orderby' => 'name' ) ) ), 'An explicit ordering should override the attribute default.' );
+ $this->assertSame( array( 'Mango', 'Apple', 'Zebra' ), get_terms( array_merge( $args, array( 'order' => 'DESC' ) ) ), 'Descending order should use term IDs too.' );
+ } finally {
+ unregister_taxonomy( $taxonomy );
+ $wc_product_attributes = $original_attributes;
+ }
+ }
+
/**
* @testdox Term product counts with default settings.
*/