WordPress.org

Make WordPress Core

Ticket #31045: 31045.2.patch

File 31045.2.patch, 7.4 KB (added by Funkatronic, 3 years ago)

Added documentation to parse_orderby filter

  • src/wp-includes/meta.php

     
    934934        protected $table_aliases = array();
    935935
    936936        /**
     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        /**
    937945         * Constructor.
    938946         *
    939947         * @since 3.2.0
     
    13741382                // Save the alias to this clause, for future siblings to find.
    13751383                $clause['alias'] = $alias;
    13761384
     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
    13771393                // Next, build the WHERE clause.
    13781394
    13791395                // meta_key.
     
    13881404                // meta_value.
    13891405                if ( array_key_exists( 'value', $clause ) ) {
    13901406                        $meta_value = $clause['value'];
    1391                         $meta_type = $this->get_cast_for_type( isset( $clause['type'] ) ? $clause['type'] : '' );
    13921407
    13931408                        if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) {
    13941409                                if ( ! is_array( $meta_value ) ) {
     
    14501465                return $sql_chunks;
    14511466        }
    14521467
     1468        public function get_clauses() {
     1469                return $this->clauses;
     1470        }
     1471
    14531472        /**
    14541473         * Identify an existing table alias that is compatible with the current
    14551474         * query clause.
  • src/wp-includes/query.php

     
    22332233
    22342234                $primary_meta_key = '';
    22352235                $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 );
    22382239
    22392240                        if ( ! empty( $primary_meta_query['key'] ) ) {
    22402241                                $primary_meta_key = $primary_meta_query['key'];
     
    22432244
    22442245                        $allowed_keys[] = 'meta_value';
    22452246                        $allowed_keys[] = 'meta_value_num';
     2247                        $allowed_keys   = array_merge( $allowed_keys, array_keys( $meta_clauses ) );
    22462248                }
    22472249
    22482250                if ( ! in_array( $orderby, $allowed_keys ) ) {
     
    22602262                        case 'ID':
    22612263                        case 'menu_order':
    22622264                        case 'comment_count':
    2263                                 $orderby = "$wpdb->posts.{$orderby}";
     2265                                $orderby_clause = "$wpdb->posts.{$orderby}";
    22642266                                break;
    22652267                        case 'rand':
    2266                                 $orderby = 'RAND()';
     2268                                $orderby_clause = 'RAND()';
    22672269                                break;
    22682270                        case $primary_meta_key:
    22692271                        case 'meta_value':
    22702272                                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']})";
    22732274                                } else {
    2274                                         $orderby = "$wpdb->postmeta.meta_value";
     2275                                        $orderby_clause = "{$primary_meta_query['alias']}.meta_value";
    22752276                                }
    22762277                                break;
    22772278                        case 'meta_value_num':
    2278                                 $orderby = "$wpdb->postmeta.meta_value+0";
     2279                                $orderby_clause = "{$primary_meta_query['alias']}.meta_value+0";
    22792280                                break;
    22802281                        default:
    2281                                 $orderby = "$wpdb->posts.post_" . $orderby;
     2282                                if( array_key_exists( $orderby, $meta_clauses ) ){
     2283                                        $meta_clause = $meta_clauses[ $orderby ];
     2284                                        $orderby_clause = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})";
     2285                                } else {
     2286                                        $orderby_clause = "$wpdb->posts.post_" . $orderby;
     2287                                }
    22822288                                break;
    22832289                }
    2284 
    2285                 return $orderby;
     2290               
     2291                /**
     2292                 * Filter for orderby clauses.
     2293                 *
     2294                 * Description.
     2295                 *
     2296                 * @since 4.2.0
     2297                 *
     2298                 * @param type  $orderby_clause         mySQL ORDER BY.
     2299                 * @param type  $orderby                        Original orderby key.
     2300                 */
     2301                return apply_filters( 'parse_orderby', $orderby_clause, $orderby );
    22862302        }
    22872303
    22882304        /**
     
    28132829
    28142830                $where .= $search . $whichauthor . $whichmimetype;
    28152831
     2832                if ( ! empty( $this->meta_query->queries ) ) {
     2833                        $clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this );
     2834                        $join   .= $clauses['join'];
     2835                        $where  .= $clauses['where'];
     2836                }
     2837
    28162838                $rand = ( isset( $q['orderby'] ) && 'rand' === $q['orderby'] );
    28172839                if ( ! isset( $q['order'] ) ) {
    28182840                        $q['order'] = $rand ? '' : 'DESC';
     
    30303052                        $where .= ')';
    30313053                }
    30323054
    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 
    30393055                /*
    30403056                 * Apply filters on where and join prior to paging so that any
    30413057                 * manipulations to them are reflected in the paging by day queries.
  • tests/phpunit/tests/query/metaQuery.php

     
    15581558                $posts = wp_list_pluck( $posts, 'ID' );
    15591559                $this->assertEqualSets( array( $post_id, $post_id3, $post_id4, $post_id5, $post_id6 ), $posts );
    15601560        }
     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        }
    15611658}