Opened 7 months ago
Last modified 3 months ago
#63768 new defect (bug)
WP_Query will generate an unexpected SQL query when using switch_to_blog and post_type = any
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | Query | Keywords: | needs-testing |
| Focuses: | multisite | Cc: |
Description
When running a WP_Query with the post_type argument set to any, WP_Query will write out the registered post types which aren't excluded from search into WHERE clauses: https://github.com/WordPress/wordpress-develop/blob/6.8.2/src/wp-includes/class-wp-query.php#L2600-L2606
However, it does so by calling get_post_types(), which gets data from the $wp_post_types global. This global, as expected, doesn't get updated when using switch_to_blog().
In turn, if you want to run a WP_Query in a switched-blog contents to fetch posts from a site which has different registered post types to the site handling the request itself, you must set the post_type param manually to a value other than 'any', to avoid WP_Query interpreting your 'any' value itself and populating the query in the context of the site handling the request.
This is only relevant in cases where there is a difference between post types which get registered on different sites in the network, but breaks expectations around the meaning of the 'post_type=any' argument.
Example:
<?php include 'wp-load.php'; $query_args = [ 'post_type' => 'any'; ]; $q1 = new WP_Query($query_args); // returns all post types not excluded from search on the site handling the request // Assume site 2 has the same post types as the site handling the request switch_to_blog(2); $q2 = new WP_Query($query_args); // returns all the expected results, as the post types match the site handling the request. restore_current_blog(); // Assume site 3 has no shared post types with the site handling the request, but instead has entirely different post types. switch_to_blog(3); $q3 = new WP_Query($query_args); // returns nothing, as no post type that exists on site 3 exists on the site handling the request restore_current_blog();
I couldn't find a single reference to this multisite-specific behaviour in documentation, so I believe that this is a bug. If not, perhaps this behaviour should be documented in a clear way.
Further to the original posted issue which I can confirm having the same issue,
The same is also true of the internal global $wp_taxonomies, so if you switch blogs then try and do any kind of Taxonomy functionality, they are tested and run against the list of the original blog and not the one you have switched to.