From 1fe97077600d3cf2dfbc362591734b0d9bcd6505 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Fri, 24 Oct 2014 19:50:53 +0000 Subject: [PATCH] Accept 'orderby=include' in `WP_User_Query`. This lets the results of a user query be sorted manually by the value of the 'include' param. Props jipmoors. Fixes #30064. git-svn-id: https://develop.svn.wordpress.org/trunk@30016 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/user.php | 16 ++++++++-- tests/phpunit/tests/user/query.php | 51 ++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index 968baeba6d..71b32fc089 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -598,6 +598,13 @@ class WP_User_Query { $this->query_from = "FROM $wpdb->users"; $this->query_where = "WHERE 1=1"; + // Parse and sanitize 'include', for use by 'orderby' as well as 'include' below. + if ( ! empty( $qv['include'] ) ) { + $include = wp_parse_id_list( $qv['include'] ); + } else { + $include = false; + } + // sorting if ( isset( $qv['orderby'] ) ) { if ( in_array( $qv['orderby'], array('nicename', 'email', 'url', 'registered') ) ) { @@ -621,6 +628,10 @@ class WP_User_Query { $orderby = 'ID'; } elseif ( 'meta_value' == $qv['orderby'] ) { $orderby = "$wpdb->usermeta.meta_value"; + } else if ( 'include' === $qv['orderby'] && ! empty( $include ) ) { + // Sanitized earlier. + $include_sql = implode( ',', $include ); + $orderby = "FIELD( $wpdb->users.ID, $include_sql )"; } else { $orderby = 'user_login'; } @@ -734,8 +745,9 @@ class WP_User_Query { $this->query_fields = 'DISTINCT ' . $this->query_fields; } - if ( ! empty( $qv['include'] ) ) { - $ids = implode( ',', wp_parse_id_list( $qv['include'] ) ); + if ( ! empty( $include ) ) { + // Sanitized earlier. + $ids = implode( ',', $include ); $this->query_where .= " AND $wpdb->users.ID IN ($ids)"; } elseif ( ! empty( $qv['exclude'] ) ) { $ids = implode( ',', wp_parse_id_list( $qv['exclude'] ) ); diff --git a/tests/phpunit/tests/user/query.php b/tests/phpunit/tests/user/query.php index 8f955d7dfa..05ae9f56e5 100644 --- a/tests/phpunit/tests/user/query.php +++ b/tests/phpunit/tests/user/query.php @@ -134,6 +134,57 @@ class Tests_User_Query extends WP_UnitTestCase { $this->assertEquals( $names, $values ); } + /** + * @ticket 30064 + */ + public function test_orderby_include_with_empty_include() { + $q = new WP_User_Query( array( + 'orderby' => 'include', + ) ); + + $this->assertContains( 'ORDER BY user_login', $q->query_orderby ); + } + + /** + * @ticket 30064 + */ + public function test_orderby_include() { + global $wpdb; + + $users = $this->factory->user->create_many( 4 ); + $q = new WP_User_Query( array( + 'orderby' => 'include', + 'include' => array( $users[1], $users[0], $users[3] ), + 'fields' => '', + ) ); + + $expected_orderby = 'ORDER BY FIELD( ' . $wpdb->users . '.ID, ' . $users[1] . ',' . $users[0] . ',' . $users[3] . ' )'; + $this->assertContains( $expected_orderby, $q->query_orderby ); + + // assertEquals() respects order but ignores type (get_results() returns numeric strings). + $this->assertEquals( array( $users[1], $users[0], $users[3] ), $q->get_results() ); + } + + /** + * @ticket 30064 + */ + public function test_orderby_include_duplicate_values() { + global $wpdb; + + $users = $this->factory->user->create_many( 4 ); + $q = new WP_User_Query( array( + 'orderby' => 'include', + 'include' => array( $users[1], $users[0], $users[1], $users[3] ), + 'fields' => '', + ) ); + + $expected_orderby = 'ORDER BY FIELD( ' . $wpdb->users . '.ID, ' . $users[1] . ',' . $users[0] . ',' . $users[3] . ' )'; + $this->assertContains( $expected_orderby, $q->query_orderby ); + + // assertEquals() respects order but ignores type (get_results() returns numeric strings). + $this->assertEquals( array( $users[1], $users[0], $users[3] ), $q->get_results() ); + } + /** * @ticket 21119 */