Exclude unsupported query parameters in posts controller#2770
Exclude unsupported query parameters in posts controller#2770rachelbaker merged 4 commits intodevelopfrom
Conversation
| $args['posts_per_page'] = $request['per_page']; | ||
| $args['name'] = $request['slug']; | ||
| $args['post_status'] = $request['status']; | ||
| $args['s'] = $request['search']; |
There was a problem hiding this comment.
We should have conditionals around these too, so a user can deregister the parameter if they don't want to support the query (or if the resource isn't meant to implement a given field like slug)
| } | ||
| if ( isset( $registered['parent_exclude'] ) ) { | ||
| $args['post_parent__not_in'] = $request['parent_exclude']; | ||
| } |
There was a problem hiding this comment.
What about possibly changing this section to something like
$parameter_mappings = array(
'offset' => 'offset',
'order' => 'order',
'orderby' => 'orderby',
'page' => 'page',
'include' => 'post__in',
'exclude' => 'post__not_in',
'slug' => 'name',
'status' => 'post_status',
'search' => 's',
'author' => 'author__in',
'author_exclude' => 'author__not_in',
'menu_order' => 'menu_order',
'parent' => 'post_parent__in',
'parent_exclude' => 'post_parent__not_in',
)
foreach ( $parameter_mappings as $query_param => $wp_query_param ) {
if ( isset( $registered[ $query_param ] ) ) {
$args[ $wp_query_param ] = $request[ $query_param ];
}
}to make it a little less repetitive?
There was a problem hiding this comment.
that would also be so much easier to read.
|
Just a note that after this PR gets merged we will need to implement in the other endpoints as well. |
| $args['post_parent__not_in'] = $request['parent_exclude']; | ||
| $args['post_status'] = $request['status']; | ||
| $args['s'] = $request['search']; | ||
| $registered = $this->get_collection_params(); |
There was a problem hiding this comment.
@rmccue Seems like this check against the registered params should happen in get_allowed_query_vars(), there is some duplicate logic there.
|
This looks to be a pretty high-priority ticket if we want to get this done prior to a merge. The approach set in this PR will need to be duplicated in all of our other controllers. |
|
Assigning myself to take a stab at refreshing this, will be coordinating with @rachelbaker to get more feedback |
rachelbaker
left a comment
There was a problem hiding this comment.
- I agree with @kadamwhite's suggestion regarding using a loop to reduce the long series of isset() conditionals.
- Because we have to do this collection parameter processing across all of our Controllers, it would be ideal to think about how we want to define the mapped parameters in the Controllers. With a protected property or method? This would be cleaner than shoving this logic into the
get_items()logic across the board. - Would it make more sense for the check against the registered collection params to happen in
prepare_items_query()orget_allowed_query_vars()? - (Very related to #3) The query parameter handling logic in the Posts Controller is already difficult to follow, is there anything we can simplify?
This tightens up the patch in #2770 to use an associative array of public api-to-internal-wp query parameters, reducing the repetition of if blocks in the code. The array only describes those properties that to not require special handling; others (like `before` or `filter`) are still checked against `$registered` individually because their values may not be set as-passed.
|
Added a commit to address (1) of @rachelbaker's feedback. Thoughts on the remainder below:
|
|
Open question:
The only params not currently being checked against registered are the "context", which I have an open question on above; and taxonomies, for which a fix would be this diff: diff --git lib/endpoints/class-wp-rest-posts-controller.php lib/endpoints/class-wp-rest-posts-controller.php
index 86ef4da..45acf9b 100755
--- lib/endpoints/class-wp-rest-posts-controller.php
+++ lib/endpoints/class-wp-rest-posts-controller.php
@@ -191,19 +191,19 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
foreach ( $taxonomies as $taxonomy ) {
- $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
- $tax_exclude = $base . '_exclude';
+ $tax_base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
+ $tax_exclude = $tax_base . '_exclude';
- if ( ! empty( $request[ $base ] ) ) {
+ if ( isset( $registered[ $tax_base ] ) && ! empty( $request[ $tax_base ] ) ) {
$query_args['tax_query'][] = array(
'taxonomy' => $taxonomy->name,
'field' => 'term_id',
- 'terms' => $request[ $base ],
+ 'terms' => $request[ $tax_base ],
'include_children' => false,
);
}
- if ( ! empty( $request[ $tax_exclude ] ) ) {
+ if ( isset( $registered[ $tax_exclude ] ) && ! empty( $request[ $tax_exclude ] ) ) {
$query_args['tax_query'][] = array(
'taxonomy' => $taxonomy->name,
'field' => 'term_id',but this depends on #2802. |
@kadamwhite Great question. Sounds like ideally we want to prevent |
…broadly Exclude unsupported params in all controllers (extends #2770)
Fixes #2767.