Make WordPress Core

Changeset 36632


Ignore:
Timestamp:
02/23/2016 04:39:50 PM (11 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.