From 061fe13c9f0f597fc08d160047dfb7ed7dfb3d22 Mon Sep 17 00:00:00 2001 From: Konstantin Kovshenin Date: Wed, 8 Oct 2014 15:11:14 +0000 Subject: [PATCH] Use the primary `meta_query` clause when parsing `orderby` in `WP_Query`. When using legacy `meta_key`, `meta_value`, etc. arguments in `WP_Query`, they're converted into the first clause of a `meta_query`. By using that clause instead of the original arguments, we make sure that behavior is consistent between the two available formats. props boonebgorges. fixes #16814. git-svn-id: https://develop.svn.wordpress.org/trunk@29855 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/query.php | 22 ++++++++++------- tests/phpunit/tests/meta.php | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/query.php b/src/wp-includes/query.php index a832e6d515..a31bf8791e 100644 --- a/src/wp-includes/query.php +++ b/src/wp-includes/query.php @@ -2223,9 +2223,16 @@ class WP_Query { 'parent', 'type', 'ID', 'menu_order', 'comment_count', 'rand', ); - $meta_key = $this->get( 'meta_key' ); - if ( ! empty( $meta_key ) ) { - $allowed_keys[] = $meta_key; + $primary_meta_key = ''; + $primary_meta_query = false; + if ( ! empty( $this->meta_query->queries ) ) { + $primary_meta_query = reset( $this->meta_query->queries ); + + if ( ! empty( $primary_meta_query['key'] ) ) { + $primary_meta_key = $primary_meta_query['key']; + $allowed_keys[] = $primary_meta_key; + } + $allowed_keys[] = 'meta_value'; $allowed_keys[] = 'meta_value_num'; } @@ -2250,12 +2257,11 @@ class WP_Query { case 'rand': $orderby = 'RAND()'; break; - case $meta_key: + case $primary_meta_key: case 'meta_value': - $type = $this->get( 'meta_type' ); - if ( ! empty( $type ) ) { - $meta_type = $this->meta_query->get_cast_for_type( $type ); - $orderby = "CAST($wpdb->postmeta.meta_value AS {$meta_type})"; + if ( ! empty( $primary_meta_query['type'] ) ) { + $sql_type = $this->meta_query->get_cast_for_type( $primary_meta_query['type'] ); + $orderby = "CAST($wpdb->postmeta.meta_value AS {$sql_type})"; } else { $orderby = "$wpdb->postmeta.meta_value"; } diff --git a/tests/phpunit/tests/meta.php b/tests/phpunit/tests/meta.php index 8da40de5c1..abf3ba527b 100644 --- a/tests/phpunit/tests/meta.php +++ b/tests/phpunit/tests/meta.php @@ -162,11 +162,16 @@ class Tests_Meta extends WP_UnitTestCase { $this->assertEquals( $expected2, get_metadata( 'user', $this->author->ID, $key, true ) ); } + /** + * @ticket 16814 + */ function test_meta_type_cast() { $post_id1 = $this->factory->post->create(); add_post_meta( $post_id1, 'num_as_longtext', 123 ); + add_post_meta( $post_id1, 'num_as_longtext_desc', 10 ); $post_id2 = $this->factory->post->create(); add_post_meta( $post_id2, 'num_as_longtext', 99 ); + add_post_meta( $post_id2, 'num_as_longtext_desc', 100 ); $posts = new WP_Query( array( 'fields' => 'ids', @@ -181,6 +186,47 @@ class Tests_Meta extends WP_UnitTestCase { $this->assertEquals( array( $post_id2, $post_id1 ), $posts->posts ); $this->assertEquals( 2, substr_count( $posts->request, 'CAST(' ) ); + + // Make sure the newer meta_query syntax behaves in a consistent way + $posts = new WP_Query( array( + 'fields' => 'ids', + 'post_type' => 'any', + 'meta_query' => array( + array( + 'key' => 'num_as_longtext', + 'value' => '0', + 'compare' => '>', + 'type' => 'UNSIGNED', + ), + ), + 'orderby' => 'meta_value', + 'order' => 'ASC' + ) ); + + $this->assertEquals( array( $post_id2, $post_id1 ), $posts->posts ); + $this->assertEquals( 2, substr_count( $posts->request, 'CAST(' ) ); + + // The legacy `meta_key` value should take precedence. + $posts = new WP_Query( array( + 'fields' => 'ids', + 'post_type' => 'any', + 'meta_key' => 'num_as_longtext', + 'meta_compare' => '>', + 'meta_type' => 'UNSIGNED', + 'meta_query' => array( + array( + 'key' => 'num_as_longtext_desc', + 'value' => '0', + 'compare' => '>', + 'type' => 'UNSIGNED', + ), + ), + 'orderby' => 'meta_value', + 'order' => 'ASC' + ) ); + + $this->assertEquals( array( $post_id2, $post_id1 ), $posts->posts ); + $this->assertEquals( 2, substr_count( $posts->request, 'CAST(' ) ); } function test_meta_cache_order_asc() {