Make WordPress Core

Changeset 36632


Ignore:
Timestamp:
02/23/2016 04:39:50 PM (9 years ago)
Author:
boonebgorges
Message:

Query: Allow a seed value to be passed when using 'rand' $orderby.

WP_Query allows random ordering; 'orderby' => 'rand' translates to
ORDER BY RAND(). This syntax results in random ordering that is not
consistent from request to request. MySQL supports the passing of a seed value
to random sorts, such as ORDER BY RAND(3), which will return the same
random value each time it's called. WP_Query now supports this syntax, by
passing RAND(3) (or whatever integer seed value you'd like) as the value
of 'orderby'.

Props hlashbrooke.
Fixes #35692.

Location:
trunk
Files:
2 edited

Legend:

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

    r36625 r36632  
    14681468     * @since 4.5.0 Removed the `$comments_popup` parameter.
    14691469     *              Introduced the `$comment_status` and `$ping_status` parameters.
     1470     *              Introduced `RAND(x)` syntax for `$orderby`, which allows an integer seed value to random sorts.
    14701471     * @access public
    14711472     *
     
    15211522     *                                                 Default 'date'. Accepts 'none', 'name', 'author', 'date',
    15221523     *                                                 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand',
     1524     *                                                 'RAND(x)' (where 'x' is an integer seed value),
    15231525     *                                                 'comment_count', 'meta_value', 'meta_value_num', 'post__in',
    15241526     *                                                 and the array keys of `$meta_query`.
     
    23332335        }
    23342336
     2337        // If RAND() contains a seed value, sanitize and add to allowed keys.
     2338        $rand_with_seed = false;
     2339        if ( preg_match( '/RAND\(([0-9]+)\)/i', $orderby, $matches ) ) {
     2340            $orderby = sprintf( 'RAND(%s)', intval( $matches[1] ) );
     2341            $allowed_keys[] = $orderby;
     2342            $rand_with_seed = true;
     2343        }
     2344
    23352345        if ( ! in_array( $orderby, $allowed_keys, true ) ) {
    23362346            return false;
     
    23692379                    $meta_clause = $meta_clauses[ $orderby ];
    23702380                    $orderby_clause = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})";
     2381                } elseif ( $rand_with_seed ) {
     2382                    $orderby_clause = $orderby;
    23712383                } else {
    23722384                    // Default: order by post field.
  • trunk/tests/phpunit/tests/post/query.php

    r35242 r36632  
    305305
    306306    /**
     307     * @ticket 35692
     308     */
     309    public function test_orderby_rand_with_seed() {
     310        $q = new WP_Query( array(
     311            'orderby' => 'RAND(5)',
     312        ) );
     313
     314        $this->assertContains( 'ORDER BY RAND(5)', $q->request );
     315    }
     316
     317    /**
     318     * @ticket 35692
     319     */
     320    public function test_orderby_rand_should_ignore_invalid_seed() {
     321        $q = new WP_Query( array(
     322            'orderby' => 'RAND(foo)',
     323        ) );
     324
     325        $this->assertNotContains( 'ORDER BY RAND', $q->request );
     326    }
     327
     328    /**
     329     * @ticket 35692
     330     */
     331    public function test_orderby_rand_with_seed_should_be_case_insensitive() {
     332        $q = new WP_Query( array(
     333            'orderby' => 'rand(5)',
     334        ) );
     335
     336        $this->assertContains( 'ORDER BY RAND(5)', $q->request );
     337    }
     338
     339    /**
    307340     * Tests the post_name__in attribute of WP_Query.
    308341     *
Note: See TracChangeset for help on using the changeset viewer.