Fixes the warning if null is given to prepare_items_query()#7625
Fixes the warning if null is given to prepare_items_query()#7625apermo wants to merge 7 commits intoWordPress:trunkfrom
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
dmsnell
left a comment
There was a problem hiding this comment.
I’ve checked the menu-items and attachment REST controllers and they call the posts controller, so it looks like this is comprehensive.
The purpose of the existing default value appears to be to make the code flow smoothly when no $prepared_args are sent, but this only triggers when the function is called without the argument, not when the argument itself is NULL.
To that end I could see two different ways of approaching this, both of which are rather subjective options and roughly equivalent to what you’ve proposed:
- Combine all of the nullable/optional assignments inside the function.
function prepare_items_query( $prepared_args = null, $request = null ) {
$prepared_args = $prepared_args ?? array();
...- Provide a second check inside the
foreach
foreach ( $prepared_args ?? array() ...The second option was my initial preference, but I don’t like that it splits the method’s understanding of the argument. Your if approach leaves that understanding in tact, but the first option, of combining the optional/nullable values, harmonizes what I suspect was the original intention behind this function.
Granted, as the existing type is written, the problem identified here is in the call sites of prepare_items_query(). Since these are protected methods, the other option for this PR would be to fix the bug where it appears, e.g.
$args = apply_filters( "rest_{$this->post_type}_query", $args, $request );
$query_args = $this->prepare_items_query( $args ?? array(), $request );This current fix removes the code which triggers the warning, but it leaves the type error in the codebase, the error being outside of this method and in the places that call it.
Use null coalescing to default to an empty array instead of wrapping the loop in an is_array() check in WP_REST_Posts_Controller and WP_REST_Revisions_Controller.
dmsnell
left a comment
There was a problem hiding this comment.
@westonruter what are your thoughts on this? I don’t love seeing us guard against type errors where the parameter types assert that those errors cannot happen, but this is getting filter output and people end up sending the wrong values anyway (a challenge with all this typing business)
we could change the $prepared_args type to ?array which accounts for probably all reasonable expectations here, but I tossed in 36530f0 to update the call sites and avoid passing any invalid data types (make sure that Core itself doesn’t propagate type errors deeper).
if we change the arg type it seems dishonest because the intent was always an array, but then if we were to do that we would end up with only a single type-check inside the function and callers need not worry about it. that would be a bit cleaner in my opinion.
protected function prepare_items_query( $prepared_args, $request = null ) {
$prepared_args = is_array( $prepared_args ) ? $prepared_args : array();otherwise we can merge this code. it’s protecting against an existing actual bug. either of the commits resolves the known cases. the first commit guards plugin code which might call this method directly, the second guards against plugin code which might return the wrong data type from the filter.
|
In order to see the tests pass I have merged |
|
@dmsnell I'm glad to see this. I think your addition is the key one (which I iterated on a bit more in e54f258). The return value of With that in place, I'd ideally want to add the type hints to the methods and eliminate the default values, since the params are “always” provided: diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
index 720f122aed..83467201ba 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
@@ -1208,15 +1208,12 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
*
* @since 4.7.0
*
- * @param array $prepared_args Optional. Prepared WP_Query arguments. Default empty array.
- * @param WP_REST_Request $request Optional. Full details about the request.
+ * @param array $prepared_args Prepared WP_Query arguments. Default empty array.
+ * @param WP_REST_Request $request Full details about the request.
* @return array Items query arguments.
*/
- protected function prepare_items_query( $prepared_args = array(), $request = null ) {
+ protected function prepare_items_query( array $prepared_args, WP_REST_Request $request ): array {
$query_args = array();
- if ( is_array( ! $prepared_args ) ) {
- $prepared_args = array();
- }
foreach ( $prepared_args as $key => $value ) {
/**
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
index cc483edacf..20a050a6e8 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
@@ -546,15 +546,12 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
*
* @since 5.0.0
*
- * @param array $prepared_args Optional. Prepared WP_Query arguments. Default empty array.
- * @param WP_REST_Request $request Optional. Full details about the request.
+ * @param array $prepared_args Prepared WP_Query arguments. Default empty array.
+ * @param WP_REST_Request $request Full details about the request.
* @return array Items query arguments.
*/
- protected function prepare_items_query( $prepared_args = array(), $request = null ) {
+ protected function prepare_items_query( array $prepared_args, WP_REST_Request $request ): array {
$query_args = array();
- if ( is_array( ! $prepared_args ) ) {
- $prepared_args = array();
- }
foreach ( $prepared_args as $key => $value ) {
/** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */However, this does not account for subclasses which may be calling this |
src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
Outdated
Show resolved
Hide resolved
src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
Outdated
Show resolved
Hide resolved
…T_Posts_Controller::prepare_items_query()`. The variable may get set to `null` by a filter or subclass. Developed in #7625 Follow-up to r38832. Props apermo, dmsnell, westonruter. Fixes #62287. git-svn-id: https://develop.svn.wordpress.org/trunk@61773 602fd350-edb4-49c9-b593-d223f7449a82
…T_Posts_Controller::prepare_items_query()`. The variable may get set to `null` by a filter or subclass. Developed in WordPress/wordpress-develop#7625 Follow-up to r38832. Props apermo, dmsnell, westonruter. Fixes #62287. Built from https://develop.svn.wordpress.org/trunk@61773 git-svn-id: http://core.svn.wordpress.org/trunk@61079 1a063a9b-81f0-0310-95a4-ce76da25c4cd
|
Thanks @westonruter — I had a commit prepared but had been stalled by some flakey PHP Unit Tests and was trying to wait until they passed. Appreciate the teamwork. |
|
@dmsnell oh! Sorry if I stepped on your toes. 🤝 |
As discribed in the track ticket, it is possible that
prepare_items_query()can receive a null value as$prepared_argswhich results in a warning. This fixes this issue.Trac ticket: https://core.trac.wordpress.org/ticket/62287
AI disclosure:
AI used for commit message.
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.