Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multiple orderby support to REST Posts Controller #1186

Closed
wants to merge 1 commit into from

Conversation

gwwar
Copy link

@gwwar gwwar commented Apr 9, 2021

Fixes https://core.trac.wordpress.org/ticket/39037 This PR adds multiple orderby support to the REST posts controller.

As an experiment, I also added a secondary ID sort to stabilize the order. This would help address pagination issues, without forcing the caller to set a second sort. Another way of fixing that would be doing so in WP_Query versus the REST posts controller, but that change would have a much larger surface area. Reading through other issues, I think folks were preferring this be done at the WP_Query level.

Related: https://core.trac.wordpress.org/ticket/46294 https://core.trac.wordpress.org/ticket/44349

Problem

We can currently only sort by a single dimension using the REST API. In some cases, we need a second sort to help provide a stable order. For example imagine if we sort by menu_order, if other items don't have this value set, what order should they be sorted by? id? title?

What happens currently is that internal implementation details affect this ordering, sometimes in surprising ways. One example is simply changing a limit from 499 to 500 when using menu_order. This is because at a limit of <500, WP_Query internally splits a post query into two queries: issue, changeset.

Proposed changes here allow us to sort with multiple orderby values, to provide more consistent ordering in results.

TODO

  • Audit affected filters
  • Smoke test other affected rest endpoints

Testing Instructions

  • Verify that tests pass and make sense
  • Manually test with a few requests in the following format:
/wp/v2/pages?per_page=100&orderby=menu_order&order=asc
/wp/v2/pages?per_page=100&orderby=menu_order,title&order=asc
/wp/v2/pages?per_page=100&orderby[]=menu_order&orderby[]=title&order=asc
/wp/v2/pages?per_page=100&orderby[menu_order]=asc&orderby[title]=desc

If folks don't have an rest client handy, we can open the console when visiting the post editor:

wp.apiFetch( { path: '/wp/v2/pages?per_page=100&orderby[menu_order]=asc&orderby[title]=desc' } ).then( ( data ) => { 
    console.log( data );
} );

@@ -1012,6 +1049,8 @@ protected function prepare_items_query( $prepared_args = array(), $request = nul
*
* @param string $value The query_var value.
*/
// TODO: Do not merge without auditing filters
// BREAKING CHANGE! Other filters too? orderby was a string but is now a PHP array (either a REST array or a REST object).
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Highlighting that we still need to 🤔 audit existing filters

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the rest_query_var-orderby filter I do think it's clearest to simply pass through value, which might be a string or array.

If we'd really like to preserve backwards compatibility, we could do something like pass through the first argument as a string (maybe the first value or some comma or space delimited string), and have the second argument be the original value. I feel like it'd avoid potential errors on upgrade, but would be confusing for future usage.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking another look, it looks like the default implementation returns $value so passing through a string as a first arg won't work.

@gwwar
Copy link
Author

gwwar commented Apr 12, 2021

@mdawaffe was kind enough to propose a patch, which I added in 073fffc along with some basic tests.

@gwwar gwwar force-pushed the add/multiple-orderby branch from 93da3b9 to fe70bae Compare April 13, 2021 18:25
@gwwar gwwar force-pushed the add/multiple-orderby branch from 035addd to cbe69f3 Compare April 13, 2021 20:06
@gwwar
Copy link
Author

gwwar commented Apr 14, 2021

Reading through https://core.trac.wordpress.org/ticket/47642#comment:13 it looks like folks do prefer this at the WP_Query level. I’ll back out the other commits from this PR

@gwwar gwwar force-pushed the add/multiple-orderby branch from 8c26557 to 04b0929 Compare May 12, 2021 20:33
@gwwar
Copy link
Author

gwwar commented May 13, 2021

I circled back to this one and it's ready for another look 👀 In terms of feedback I have two main areas that would be helpful:

Affected Filters

There are two filters that now have breaking changes. What do folks think might be the best way to resolve this?

Any missing test coverage?

Are there any areas that I should add tests / verify changes for?

cc @TimothyBJacobs @mdawaffe or whomever may be interested

@gwwar gwwar force-pushed the add/multiple-orderby branch from c51989f to 1ddfce5 Compare October 14, 2021 16:28
@gwwar
Copy link
Author

gwwar commented Oct 14, 2021

I think test failures here mean that fixtures need to be regenerated for tests/qunit/fixtures/wp-api-generated.js Do folks know what command should be run here?

@TimothyBJacobs
Copy link
Member

I think test failures here mean that fixtures need to be regenerated for tests/qunit/fixtures/wp-api-generated.js Do folks know what command should be run here?

Running the rest api phpunit test suite should regenerate those files. --group restapi

@gwwar gwwar closed this Jul 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants