Ticket #31045: 31045.diff
File 31045.diff, 7.3 KB (added by , 10 years ago) |
---|
-
src/wp-includes/meta.php
diff --git src/wp-includes/meta.php src/wp-includes/meta.php index 8953aaa..b03a40b 100644
class WP_Meta_Query { 934 934 protected $table_aliases = array(); 935 935 936 936 /** 937 * A flat list of clauses, keyed by table aliases. 938 * 939 * @since 4.2.0 940 * @var array 941 */ 942 protected $clauses = array(); 943 944 /** 937 945 * Constructor. 938 946 * 939 947 * @since 3.2.0 … … class WP_Meta_Query { 1374 1382 // Save the alias to this clause, for future siblings to find. 1375 1383 $clause['alias'] = $alias; 1376 1384 1385 // Determine the data type. 1386 $meta_type = $this->get_cast_for_type( isset( $clause['type'] ) ? $clause['type'] : '' ); 1387 $clause['cast'] = $meta_type; 1388 1389 // Store the clause in our flat array. 1390 $clause_name = isset( $clause['name'] ) ? $clause['name'] : $clause['alias']; 1391 $this->clauses[ $clause_name ] =& $clause; 1392 1377 1393 // Next, build the WHERE clause. 1378 1394 1379 1395 // meta_key. … … class WP_Meta_Query { 1388 1404 // meta_value. 1389 1405 if ( array_key_exists( 'value', $clause ) ) { 1390 1406 $meta_value = $clause['value']; 1391 $meta_type = $this->get_cast_for_type( isset( $clause['type'] ) ? $clause['type'] : '' );1392 1407 1393 1408 if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) { 1394 1409 if ( ! is_array( $meta_value ) ) { … … class WP_Meta_Query { 1450 1465 return $sql_chunks; 1451 1466 } 1452 1467 1468 public function get_clauses() { 1469 return $this->clauses; 1470 } 1471 1453 1472 /** 1454 1473 * Identify an existing table alias that is compatible with the current 1455 1474 * query clause. -
src/wp-includes/query.php
diff --git src/wp-includes/query.php src/wp-includes/query.php index 5a6774e..1725d2c 100644
class WP_Query { 2233 2233 2234 2234 $primary_meta_key = ''; 2235 2235 $primary_meta_query = false; 2236 if ( ! empty( $this->meta_query->queries ) ) { 2237 $primary_meta_query = reset( $this->meta_query->queries ); 2236 $meta_clauses = $this->meta_query->get_clauses(); 2237 if ( ! empty( $meta_clauses ) ) { 2238 $primary_meta_query = reset( $meta_clauses ); 2238 2239 2239 2240 if ( ! empty( $primary_meta_query['key'] ) ) { 2240 2241 $primary_meta_key = $primary_meta_query['key']; … … class WP_Query { 2243 2244 2244 2245 $allowed_keys[] = 'meta_value'; 2245 2246 $allowed_keys[] = 'meta_value_num'; 2247 $allowed_keys = array_merge( $allowed_keys, array_keys( $meta_clauses ) ); 2246 2248 } 2247 2249 2248 2250 if ( ! in_array( $orderby, $allowed_keys ) ) { … … class WP_Query { 2260 2262 case 'ID': 2261 2263 case 'menu_order': 2262 2264 case 'comment_count': 2263 $orderby = "$wpdb->posts.{$orderby}";2265 $orderby_clause = "$wpdb->posts.{$orderby}"; 2264 2266 break; 2265 2267 case 'rand': 2266 $orderby = 'RAND()';2268 $orderby_clause = 'RAND()'; 2267 2269 break; 2268 2270 case $primary_meta_key: 2269 2271 case 'meta_value': 2270 2272 if ( ! empty( $primary_meta_query['type'] ) ) { 2271 $sql_type = $this->meta_query->get_cast_for_type( $primary_meta_query['type'] ); 2272 $orderby = "CAST($wpdb->postmeta.meta_value AS {$sql_type})"; 2273 $orderby_clause = "CAST({$primary_meta_query['alias']}.meta_value AS {$primary_meta_query['cast']})"; 2273 2274 } else { 2274 $orderby = "$wpdb->postmeta.meta_value";2275 $orderby_clause = "{$primary_meta_query['alias']}.meta_value"; 2275 2276 } 2276 2277 break; 2277 2278 case 'meta_value_num': 2278 $orderby = "$wpdb->postmeta.meta_value+0"; 2279 $orderby_clause = "{$primary_meta_query['alias']}.meta_value+0"; 2280 break; 2281 case array_key_exists( $orderby, $meta_clauses ): 2282 $meta_clause = $meta_clauses[ $orderby ]; 2283 $orderby_clause = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})"; 2279 2284 break; 2280 2285 default: 2281 $orderby = "$wpdb->posts.post_" . $orderby;2286 $orderby_clause = "$wpdb->posts.post_" . $orderby; 2282 2287 break; 2283 2288 } 2284 2289 2285 return $orderby;2290 return apply_filters( 'parse_orderby', $orderby_clause, $orderby ); 2286 2291 } 2287 2292 2288 2293 /** … … class WP_Query { 2813 2818 2814 2819 $where .= $search . $whichauthor . $whichmimetype; 2815 2820 2821 if ( ! empty( $this->meta_query->queries ) ) { 2822 $clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this ); 2823 $join .= $clauses['join']; 2824 $where .= $clauses['where']; 2825 } 2826 2816 2827 $rand = ( isset( $q['orderby'] ) && 'rand' === $q['orderby'] ); 2817 2828 if ( ! isset( $q['order'] ) ) { 2818 2829 $q['order'] = $rand ? '' : 'DESC'; … … class WP_Query { 3030 3041 $where .= ')'; 3031 3042 } 3032 3043 3033 if ( !empty( $this->meta_query->queries ) ) {3034 $clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this );3035 $join .= $clauses['join'];3036 $where .= $clauses['where'];3037 }3038 3039 3044 /* 3040 3045 * Apply filters on where and join prior to paging so that any 3041 3046 * manipulations to them are reflected in the paging by day queries. -
tests/phpunit/tests/query/metaQuery.php
diff --git tests/phpunit/tests/query/metaQuery.php tests/phpunit/tests/query/metaQuery.php index 8f9b212..2eff8eb 100644
class Tests_Query_MetaQuery extends WP_UnitTestCase { 1558 1558 $posts = wp_list_pluck( $posts, 'ID' ); 1559 1559 $this->assertEqualSets( array( $post_id, $post_id3, $post_id4, $post_id5, $post_id6 ), $posts ); 1560 1560 } 1561 1562 /** 1563 * @ticket 31045 1564 */ 1565 public function test_orderby_name() { 1566 $posts = $this->factory->post->create_many( 3 ); 1567 add_post_meta( $posts[0], 'foo', 'aaa' ); 1568 add_post_meta( $posts[1], 'foo', 'zzz' ); 1569 add_post_meta( $posts[2], 'foo', 'jjj' ); 1570 1571 $q = new WP_Query( array( 1572 'fields' => 'ids', 1573 'meta_query' => array( 1574 array( 1575 'name' => 'foo_name', 1576 'key' => 'foo', 1577 'compare' => 'EXISTS', 1578 ), 1579 ), 1580 'orderby' => 'foo_name', 1581 'order' => 'DESC', 1582 ) ); 1583 1584 $this->assertEquals( array( $posts[1], $posts[2], $posts[0] ), $q->posts ); 1585 } 1586 1587 /** 1588 * @ticket 31045 1589 */ 1590 public function test_orderby_name_as_secondary_sort() { 1591 $p1 = $this->factory->post->create( array( 1592 'post_date' => '2015-01-28 03:00:00', 1593 ) ); 1594 $p2 = $this->factory->post->create( array( 1595 'post_date' => '2015-01-28 05:00:00', 1596 ) ); 1597 $p3 = $this->factory->post->create( array( 1598 'post_date' => '2015-01-28 03:00:00', 1599 ) ); 1600 1601 add_post_meta( $p1, 'foo', 'jjj' ); 1602 add_post_meta( $p2, 'foo', 'zzz' ); 1603 add_post_meta( $p3, 'foo', 'aaa' ); 1604 1605 $q = new WP_Query( array( 1606 'fields' => 'ids', 1607 'meta_query' => array( 1608 array( 1609 'name' => 'foo_name', 1610 'key' => 'foo', 1611 'compare' => 'EXISTS', 1612 ), 1613 ), 1614 'orderby' => array( 1615 'post_date' => 'asc', 1616 'foo_name' => 'asc', 1617 ), 1618 ) ); 1619 1620 $this->assertEquals( array( $p3, $p1, $p2 ), $q->posts ); 1621 } 1622 1623 /** 1624 * @ticket 31045 1625 */ 1626 public function test_orderby_more_than_one_name() { 1627 $posts = $this->factory->post->create_many( 3 ); 1628 1629 add_post_meta( $posts[0], 'foo', 'jjj' ); 1630 add_post_meta( $posts[1], 'foo', 'zzz' ); 1631 add_post_meta( $posts[2], 'foo', 'jjj' ); 1632 add_post_meta( $posts[0], 'bar', 'aaa' ); 1633 add_post_meta( $posts[1], 'bar', 'ccc' ); 1634 add_post_meta( $posts[2], 'bar', 'bbb' ); 1635 1636 $q = new WP_Query( array( 1637 'fields' => 'ids', 1638 'meta_query' => array( 1639 array( 1640 'name' => 'foo_name', 1641 'key' => 'foo', 1642 'compare' => 'EXISTS', 1643 ), 1644 array( 1645 'name' => 'bar_name', 1646 'key' => 'bar', 1647 'compare' => 'EXISTS', 1648 ), 1649 ), 1650 'orderby' => array( 1651 'foo_name' => 'asc', 1652 'bar_name' => 'desc', 1653 ), 1654 ) ); 1655 1656 $this->assertEquals( array( $posts[2], $posts[0], $posts[1] ), $q->posts ); 1657 } 1561 1658 }