[wp-trac] [WordPress Trac] #63890: Add multiple order conditions to WP_Term_Query

WordPress Trac noreply at wordpress.org
Tue Jan 27 16:36:52 UTC 2026


#63890: Add multiple order conditions to WP_Term_Query
-------------------------+------------------------------
 Reporter:  oglekler     |       Owner:  (none)
     Type:  enhancement  |      Status:  new
 Priority:  normal       |   Milestone:  Awaiting Review
Component:  Taxonomy     |     Version:
 Severity:  normal       |  Resolution:
 Keywords:  has-patch    |     Focuses:
-------------------------+------------------------------
Changes (by sajib1223):

 * keywords:  has-patch needs-testing => has-patch


Comment:

 == Patch Testing Report

 Patch tested: https://github.com/WordPress/wordpress-develop/pull/9658

 === Environment
 - WordPress: 7.0-alpha-61215-src
 - PHP: 8.2.29
 - Server: nginx/1.27.5
 - Database: mysqli (Server: 8.4.7 / Client: mysqlnd 8.2.29)
 - Browser: Firefox 147.0
 - OS: Windows 10/11
 - Theme: Twenty Twenty-Five 1.4
 - MU Plugins: None activated
 - Plugins:
   * Test Reports 1.2.1
   * Test Ticket 63890 - Array Orderby 1.0.0

 === Steps taken
 1. Applied patch using `git checkout -b test/10445-auto-update` & `gh pr
 diff 9658 | git apply`
 2. Added following code to a custom plugin and visit.
 {{{#!php
 <?php
 /**
  * Plugin Name: Test Ticket 63890 - Array Orderby
  * Description: Tests array orderby support in WP_Term_Query
  * Version: 1.0.0
  */

 if ( ! defined( 'ABSPATH' ) ) {
         die();
 }

 class Test_Ticket_63890 {

         private $taxonomy = 'wptests_tax_63890';
         private $result = null;

         public function __construct() {
                 add_action( 'admin_menu', array( $this, 'add_admin_menu' )
 );
                 add_action( 'admin_init', array( $this, 'maybe_run_test' )
 );
         }

         public function add_admin_menu() {
                 add_menu_page(
                         'Test 63890',
                         'Test 63890',
                         'manage_options',
                         'test-ticket-63890',
                         array( $this, 'render_page' ),
                         'dashicons-yes-alt'
                 );
         }

         public function maybe_run_test() {
                 if ( isset( $_GET['page'] ) && $_GET['page'] === 'test-
 ticket-63890' ) {
                         $this->setup();
                         $this->cleanup();
                         $this->result =
 $this->test_orderby_array_multiple_fields();
                 }
         }

         private function setup() {
                 // Register taxonomy if not already registered
                 if ( ! taxonomy_exists( $this->taxonomy ) ) {
                         register_taxonomy( $this->taxonomy, 'post', array(
 'public' => false ) );
                 }
         }

         private function cleanup() {
                 // Only delete terms, keep taxonomy registered
                 if ( taxonomy_exists( $this->taxonomy ) ) {
                         $terms = get_terms( array(
                                 'taxonomy'   => $this->taxonomy,
                                 'hide_empty' => false,
                                 'fields'     => 'ids'
                         ) );

                         if ( ! is_wp_error( $terms ) && ! empty( $terms )
 ) {
                                 foreach ( $terms as $term_id ) {
                                         wp_delete_term( $term_id,
 $this->taxonomy );
                                 }
                         }
                 }
         }

         private function test_orderby_array_multiple_fields() {
                 // Create 4 terms with unique names
                 $timestamp = time();
                 $terms = array();
                 for ( $i = 0; $i < 4; $i++ ) {
                         $term = wp_insert_term( 'Term ' . ( $i + 1 ) . ' '
 . $timestamp, $this->taxonomy );
                         if ( ! is_wp_error( $term ) ) {
                                 $terms[] = $term['term_id'];
                         }
                 }

                 // Check if we have all 4 terms
                 if ( count( $terms ) !== 4 ) {
                         return array(
                                 'passed'   => false,
                                 'expected' => array(),
                                 'actual'   => array(),
                                 'terms'    => array(),
                                 'sql'      => 'Error: Could not create all
 4 test terms',
                         );
                 }

                 // Add priority meta
                 add_term_meta( $terms[0], 'priority', 2 );
                 add_term_meta( $terms[1], 'priority', 1 );
                 add_term_meta( $terms[2], 'priority', 2 );
                 add_term_meta( $terms[3], 'priority', 1 );

                 // Run query with array orderby
                 $q = new WP_Term_Query(
                         array(
                                 'taxonomy'   => $this->taxonomy,
                                 'orderby'    => array(
                                         'meta_value_num' => 'DESC',
                                         'term_id'        => 'ASC',
                                 ),
                                 'meta_key'   => 'priority',
                                 'hide_empty' => false,
                                 'fields'     => 'ids',
                         )
                 );

                 // Expected order: priority 2 first (DESC), then by
 term_id (ASC)
                 $expected = array( $terms[0], $terms[2], $terms[1],
 $terms[3] );
                 $actual   = $q->terms;

                 $term_details = array();
                 foreach ( $terms as $term_id ) {
                         $term = get_term( $term_id, $this->taxonomy );
                         if ( ! is_wp_error( $term ) && $term ) {
                                 $term_details[] = array(
                                         'id'       => $term_id,
                                         'name'     => $term->name,
                                         'priority' => get_term_meta(
 $term_id, 'priority', true ),
                                 );
                         }
                 }

                 return array(
                         'passed'   => $expected === $actual,
                         'expected' => $expected,
                         'actual'   => $actual,
                         'terms'    => $term_details,
                         'sql'      => $q->request,
                 );
         }

         public function render_page() {
                 $result = $this->result;

                 if ( ! $result || ! isset( $result['passed'] ) ) {
                         echo '<div class="wrap"><h1>Test
 63890</h1><p>Error running test. Please try again.</p></div>';
                         return;
                 }

                 $status = $result['passed'] ? 'PASS' : 'FAIL';
                 $color  = $result['passed'] ? '#46b450' : '#dc3232';
                 ?>
                 <div class="wrap">
                         <h1>Test Ticket #63890</h1>
                         <p>Testing: Array orderby with multiple fields
 (meta_value_num DESC + term_id ASC)</p>

                         <style>
                                 .test-box {
                                         background: #fff;
                                         border-left: 4px solid <?php echo
 esc_attr( $color ); ?>;
                                         padding: 20px;
                                         margin: 20px 0;
                                         box-shadow: 0 1px 3px
 rgba(0,0,0,0.1);
                                 }
                                 .status {
                                         display: inline-block;
                                         background: <?php echo esc_attr(
 $color ); ?>;
                                         color: #fff;
                                         padding: 5px 15px;
                                         border-radius: 3px;
                                         font-weight: bold;
                                 }
                                 table {
                                         width: 100%;
                                         border-collapse: collapse;
                                         margin: 15px 0;
                                 }
                                 th, td {
                                         padding: 10px;
                                         text-align: left;
                                         border: 1px solid #ddd;
                                 }
                                 th {
                                         background: #f5f5f5;
                                         font-weight: bold;
                                 }
                                 pre {
                                         background: #f5f5f5;
                                         padding: 10px;
                                         border-radius: 3px;
                                         overflow-x: auto;
                                 }
                         </style>

                         <div class="test-box">
                                 <h2>Result: <span class="status"><?php
 echo esc_html( $status ); ?></span></h2>

                                 <h3>Expected vs Actual</h3>
                                 <table>
                                         <tr>
                                                 <th>Expected</th>
                                                 <td><?php echo esc_html(
 implode( ', ', $result['expected'] ) ); ?></td>
                                         </tr>
                                         <tr>
                                                 <th>Actual</th>
                                                 <td><?php echo esc_html(
 implode( ', ', $result['actual'] ) ); ?></td>
                                         </tr>
                                         <tr>
                                                 <th>Match</th>
                                                 <td><?php echo
 $result['passed'] ? '✓ YES' : '✗ NO'; ?></td>
                                         </tr>
                                 </table>

                                 <h3>Term Details</h3>
                                 <?php if ( ! empty( $result['terms'] ) ) :
 ?>
                                 <table>
                                         <thead>
                                                 <tr>
                                                         <th>Term ID</th>
                                                         <th>Name</th>
                                                         <th>Priority
 (Meta)</th>
                                                 </tr>
                                         </thead>
                                         <tbody>
                                                 <?php foreach (
 $result['terms'] as $term ) : ?>
                                                         <tr>
                                                                 <td><?php
 echo esc_html( $term['id'] ); ?></td>
                                                                 <td><?php
 echo esc_html( $term['name'] ); ?></td>
                                                                 <td><?php
 echo esc_html( $term['priority'] ); ?></td>
                                                         </tr>
                                                 <?php endforeach; ?>
                                         </tbody>
                                 </table>
                                 <?php else : ?>
                                         <p>No term details available.</p>
                                 <?php endif; ?>

                                 <h3>Generated SQL</h3>
                                 <pre><?php echo esc_html( $result['sql']
 ); ?></pre>
                         </div>

                         <p>
                                 <a href="<?php echo esc_url( admin_url(
 'admin.php?page=test-ticket-63890' ) ); ?>" class="button button-primary">
                                         Re-run Test
                                 </a>
                         </p>
                 </div>
                 <?php
         }
 }

 new Test_Ticket_63890();


 }}}

 3. Went to the "Test 63890" Menu.
 4. It showed "Result: PASS" & some metadata.
 5. ✅ Patch enables multiple order condition for terms.

 === Alternative Steps taken
 1. Applied patch using `git checkout -b test/10445-auto-update` & `gh pr
 diff 9658 | git apply`.
 2. Run `npm run test:php -- --filter test_orderby_array_multiple_fields`.
 3. It produced "OK (1 test, 1 assertion)"
 4. ✅ Patch enables multiple order condition for terms.

 === Expected result

 Patch enables multiple order condition for terms.

 === Screenshots with results

 Test results page:

 [[Image(https://files.catbox.moe/wcfq6r.png)]]

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/63890#comment:4>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list