WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#35692 closed enhancement (fixed)

Allow seed value to be passed to WP_Query when using random ordering

Reported by: hlashbrooke Owned by: boonebgorges
Milestone: 4.5 Priority: normal
Severity: normal Version: 2.5
Component: Query Keywords: has-patch
Focuses: Cc:
PR Number:

Description

When we build the MySQL query from the WP_Query class and rand is specified as the orderby argument in the query args, we parse the ORDER BY clause like this: RAND(). The parentheses there imply that a seed value could be passed to the RAND function, which would allow for consistent random ordering. This is a relatively common need when posts are ordered randomly, but need to retain persistent pagination.

This can be worked around by using the posts_orderby filter of course, but it would be useful if we could simply specify a seed value in the query args that would be validated as an integer and then added to the RAND() function if it has been supplied.

This would obviously be an entirely optional new argument, but it would make WP_Query just that much more powerful.

Here are the docs on the usage of a seed value for the RAND() function.

Attachments (3)

35692.diff (2.7 KB) - added by hlashbrooke 4 years ago.
Adding new seed argument to WP_Query args
35692.1.diff (2.8 KB) - added by hlashbrooke 4 years ago.
Adding new parse_orderby parameter to function comments
35692.2.diff (2.1 KB) - added by boonebgorges 4 years ago.

Download all attachments as: .zip

Change History (13)

@hlashbrooke
4 years ago

Adding new seed argument to WP_Query args

@hlashbrooke
4 years ago

Adding new parse_orderby parameter to function comments

This ticket was mentioned in Slack in #core by chriscct7. View the logs.


4 years ago

#2 @chriscct7
4 years ago

  • Keywords has-patch needs-unit-tests added

#3 follow-up: @boonebgorges
4 years ago

  • Keywords 2nd-opinion added

There's something about this syntax that feels wrong to me. $seed is not a very transparent parameter name. And passing around a $seed parameter when invoking parse_orderby() seems somehow too ad hoc.

Here's an idea: allow orderby to accept RAND(3) in addition to RAND. We would need some validation to make sure it's a integer. But it keeps the syntax much simpler and, IMO, intuitive for devs.

#4 in reply to: ↑ 3 @hlashbrooke
4 years ago

Replying to boonebgorges:

There's something about this syntax that feels wrong to me. $seed is not a very transparent parameter name. And passing around a $seed parameter when invoking parse_orderby() seems somehow too ad hoc.

Here's an idea: allow orderby to accept RAND(3) in addition to RAND. We would need some validation to make sure it's a integer. But it keeps the syntax much simpler and, IMO, intuitive for devs.

That's a fair point - the validation there would be an issue, but not a huge one. The part that would be a bit more complex is that the orderby parameter is validated against a list of allowed options and if we allowed that to have a value of rand(3) then it would mean that the validation there would need to be modified quite heavily.

I do tend to agree that having the $seed parameter passed around like this does seem a little too ad hoc, but it was the best implementation that I could think of on a first pass - I'll put some more thought into it though and see what I can come up with.

Do you perhaps have a better parameter name than seed if we were to continue to use that as a separate parameter?

@boonebgorges
4 years ago

#5 @boonebgorges
4 years ago

The part that would be a bit more complex is that the orderby parameter is validated against a list of allowed options and if we allowed that to have a value of rand(3) then it would mean that the validation there would need to be modified quite heavily.

Yeah, it would require some modification. See 35692.2.diff for an idea. It's not very elegant, but it gets the job done. Personally, while I think the internal logic here is not beautiful, I think 'orderby' => 'RAND(5)' is a pretty good syntax for devs.

Do you perhaps have a better parameter name than seed if we were to continue to use that as a separate parameter?

At the very least, the name should make it clear that it's connected to RAND. Maybe orderby_rand_seed?

#6 @hlashbrooke
4 years ago

I think that's actually a really good implementation to be honest - much more dev friendly I think. Works well for me and I think it's the kind of thing that isn't ever going to be super elegant.

#7 @boonebgorges
4 years ago

  • Keywords needs-unit-tests 2nd-opinion removed
  • Milestone changed from Awaiting Review to 4.5

Let's do it.

#8 @hlashbrooke
4 years ago

Awesome :)

#9 @boonebgorges
4 years ago

  • Owner set to boonebgorges
  • Resolution set to fixed
  • Status changed from new to closed

In 36632:

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.

#10 @johnbillion
4 years ago

  • Version changed from trunk to 2.5
Note: See TracTickets for help on using tickets.