WordPress.org

Make WordPress Core

Changeset 31340


Ignore:
Timestamp:
02/05/15 19:37:47 (2 years ago)
Author:
boonebgorges
Message:

Modify `meta_query orderby syntax to use array keys as clause "handles".

The implementation of meta_query orderby introduced in [31312] put clause
identifiers into a 'name' parameter of the clause. For greater clarity, this
changeset updates the syntax to use the associative array key used when
defining meta_query parameters, instead of the 'name' parameter.

Props Funkatronic, DrewAPicture.
Fixes #31045.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/meta.php

    r31312 r31340  
    946946     * 
    947947     * @since 3.2.0 
    948      * @since 4.2.0 Introduced the `$name` parameter, for improved `$orderby` support in the parent query. 
     948     * @since 4.2.0 Introduced support for naming query clauses by associative array keys. 
    949949     * 
    950950     * @access public 
    951951     * 
    952952     * @param array $meta_query { 
    953      *     Array of meta query clauses. 
     953     *     Array of meta query clauses. When first-order clauses use strings as their array keys, they may be 
     954     *     referenced in the 'orderby' parameter of the parent query. 
    954955     * 
    955956     *     @type string $relation Optional. The MySQL keyword used to join 
     
    968969     *                               'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', or 'UNSIGNED'. 
    969970     *                               Default is 'CHAR'. 
    970      *         @type string $name    Optional. A unique identifier for the clause. If provided, `$name` can be 
    971      *                               referenced in the `$orderby` parameter of the parent query. 
    972971     *     } 
    973972     * } 
     
    10171016                } 
    10181017 
    1019                 $clean_queries[] = $query; 
     1018                $clean_queries[ $key ] = $query; 
    10201019 
    10211020            // Otherwise, it's a nested query, so we recurse. 
     
    10241023 
    10251024                if ( ! empty( $cleaned_query ) ) { 
    1026                     $clean_queries[] = $cleaned_query; 
     1025                    $clean_queries[ $key ] = $cleaned_query; 
    10271026                } 
    10281027            } 
     
    12711270                // This is a first-order clause. 
    12721271                if ( $this->is_first_order_clause( $clause ) ) { 
    1273                     $clause_sql = $this->get_sql_for_clause( $clause, $query ); 
     1272                    $clause_sql = $this->get_sql_for_clause( $clause, $query, $key ); 
    12741273 
    12751274                    $where_count = count( $clause_sql['where'] ); 
     
    13221321     * @access public 
    13231322     * 
    1324      * @param array $clause       Query clause, passed by reference. 
    1325      * @param array $parent_query Parent query array. 
     1323     * @param array  $clause       Query clause, passed by reference. 
     1324     * @param array  $parent_query Parent query array. 
     1325     * @param string $clause_key   Optional. The array key used to name the clause in the original `$meta_query` 
     1326     *                             parameters. If not provided, a key will be generated automatically. 
    13261327     * @return array { 
    13271328     *     Array containing JOIN and WHERE SQL clauses to append to a first-order query. 
     
    13311332     * } 
    13321333     */ 
    1333     public function get_sql_for_clause( &$clause, $parent_query ) { 
     1334    public function get_sql_for_clause( &$clause, $parent_query, $clause_key = '' ) { 
    13341335        global $wpdb; 
    13351336 
     
    13921393        $clause['cast'] = $meta_type; 
    13931394 
     1395        // Fallback for clause keys is the table alias. 
     1396        if ( ! $clause_key ) { 
     1397            $clause_key = $clause['alias']; 
     1398        } 
     1399 
     1400        // Ensure unique clause keys, so none are overwritten. 
     1401        $iterator = 1; 
     1402        $clause_key_base = $clause_key; 
     1403        while ( isset( $this->clauses[ $clause_key ] ) ) { 
     1404            $clause_key = $clause_key_base . '-' . $iterator; 
     1405            $iterator++; 
     1406        } 
     1407 
    13941408        // Store the clause in our flat array. 
    1395         $clause_name = isset( $clause['name'] ) ? $clause['name'] : $clause['alias']; 
    1396         $this->clauses[ $clause_name ] =& $clause; 
     1409        $this->clauses[ $clause_key ] =& $clause; 
    13971410 
    13981411        // Next, build the WHERE clause. 
     
    14721485 
    14731486    /** 
    1474      * Get a flattened list of sanitized meta clauses, indexed by clause 'name'. 
     1487     * Get a flattened list of sanitized meta clauses. 
    14751488     * 
    14761489     * This array should be used for clause lookup, as when the table alias and CAST type must be determined for 
  • trunk/src/wp-includes/query.php

    r31324 r31340  
    14511451     * 
    14521452     * @since 1.5.0 
     1453     * @since 4.2.0 Introduced the ability to order by specific clauses of a `$meta_query`, by passing the clause's 
     1454     *              array key to `$orderby`. 
    14531455     * @access public 
    14541456     * 
     
    14981500     *     @type string       $order                   Designates ascending or descending order of posts. Default 'DESC'. 
    14991501     *                                                 Accepts 'ASC', 'DESC'. 
    1500      *     @type string       $orderby                 Sort retrieved posts by parameter. One or more options can be 
     1502     *     @type string|array $orderby                 Sort retrieved posts by parameter. One or more options may be 
    15011503     *                                                 passed. To use 'meta_value', or 'meta_value_num', 
    1502      *                                                 'meta_key=keyname' must be also be defined. Default 'date'. 
    1503      *                                                 Accepts 'none', 'name', 'author', 'date', 'title', 'modified', 
    1504      *                                                 'menu_order', 'parent', 'ID', 'rand', 'comment_count'. 
     1504     *                                                 'meta_key=keyname' must be also be defined. To sort by a 
     1505     *                                                 specific `$meta_query` clause, use that clause's array key. 
     1506     *                                                 Default 'date'. Accepts 'none', 'name', 'author', 'date', 
     1507     *                                                 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 
     1508     *                                                 'comment_count', 'meta_value', 'meta_value_num', and the 
     1509     *                                                 array keys of `$meta_query`. 
    15051510     *     @type int          $p                       Post ID. 
    15061511     *     @type int          $page                    Show the number of posts that would show up on page X of a 
  • trunk/tests/phpunit/tests/query/metaQuery.php

    r31312 r31340  
    15631563     * @ticket 31045 
    15641564     */ 
    1565     public function test_orderby_name() { 
     1565    public function test_orderby_clause_key() { 
    15661566        $posts = $this->factory->post->create_many( 3 ); 
    15671567        add_post_meta( $posts[0], 'foo', 'aaa' ); 
     
    15721572            'fields' => 'ids', 
    15731573            'meta_query' => array( 
    1574                 array( 
    1575                     'name' => 'foo_name', 
     1574                'foo_key' => array( 
    15761575                    'key' => 'foo', 
    15771576                    'compare' => 'EXISTS', 
    15781577                ), 
    15791578            ), 
    1580             'orderby' => 'foo_name', 
     1579            'orderby' => 'foo_key', 
    15811580            'order' => 'DESC', 
    15821581        ) ); 
     
    15881587     * @ticket 31045 
    15891588     */ 
    1590     public function test_orderby_name_as_secondary_sort() { 
     1589    public function test_orderby_clause_key_as_secondary_sort() { 
    15911590        $p1 = $this->factory->post->create( array( 
    15921591            'post_date' => '2015-01-28 03:00:00', 
     
    16061605            'fields' => 'ids', 
    16071606            'meta_query' => array( 
    1608                 array( 
    1609                     'name' => 'foo_name', 
     1607                'foo_key' => array( 
    16101608                    'key' => 'foo', 
    16111609                    'compare' => 'EXISTS', 
     
    16141612            'orderby' => array( 
    16151613                'post_date' => 'asc', 
    1616                 'foo_name' => 'asc', 
     1614                'foo_key' => 'asc', 
    16171615            ), 
    16181616        ) ); 
     
    16241622     * @ticket 31045 
    16251623     */ 
    1626     public function test_orderby_more_than_one_name() { 
     1624    public function test_orderby_more_than_one_clause_key() { 
    16271625        $posts = $this->factory->post->create_many( 3 ); 
    16281626 
     
    16371635            'fields' => 'ids', 
    16381636            'meta_query' => array( 
    1639                 array( 
    1640                     'name' => 'foo_name', 
     1637                'foo_key' => array( 
    16411638                    'key' => 'foo', 
    16421639                    'compare' => 'EXISTS', 
    16431640                ), 
    1644                 array( 
    1645                     'name' => 'bar_name', 
     1641                'bar_key' => array( 
    16461642                    'key' => 'bar', 
    16471643                    'compare' => 'EXISTS', 
     
    16491645            ), 
    16501646            'orderby' => array( 
    1651                 'foo_name' => 'asc', 
    1652                 'bar_name' => 'desc', 
     1647                'foo_key' => 'asc', 
     1648                'bar_key' => 'desc', 
    16531649            ), 
    16541650        ) ); 
     
    16561652        $this->assertEquals( array( $posts[2], $posts[0], $posts[1] ), $q->posts ); 
    16571653    } 
     1654 
     1655    /** 
     1656     * @ticket 31045 
     1657     */ 
     1658    public function test_duplicate_clause_keys_should_be_made_unique() { 
     1659        $q = new WP_Query( array( 
     1660            'fields' => 'ids', 
     1661            'meta_query' => array( 
     1662                'foo_key' => array( 
     1663                    'key' => 'foo', 
     1664                    'compare' => 'EXISTS', 
     1665                ), 
     1666                array( 
     1667                    'foo_key' => array( 
     1668                        'key' => 'bar', 
     1669                        'compare' => 'EXISTS', 
     1670                    ), 
     1671                ), 
     1672                array( 
     1673                    'foo_key' => array( 
     1674                        'key' => 'baz', 
     1675                        'compare' => 'EXISTS', 
     1676                    ), 
     1677                ), 
     1678            ), 
     1679        ) ); 
     1680 
     1681        $this->assertEqualSets( array( 'foo_key', 'foo_key-1', 'foo_key-2' ), array_keys( $q->meta_query->get_clauses() ) ); 
     1682    } 
    16581683} 
Note: See TracChangeset for help on using the changeset viewer.