Opened 4 weeks ago
Last modified 7 days ago
#48556 new defect (bug)
Query for multiple post types not considering user permission to retrieve private posts
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | 5.4 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Query | Keywords: | has-patch |
Focuses: | Cc: | ||
PR Number: |
Description
When you query for posts not informing a specific post_status, WordPress will return posts that the current user can read (if there is a user logged in).
However, if you query for multiple post types, passing an array, or if you query for any
post type, WordPress will ignore this behavior and won't return any private posts at all.
Expected behavior is that it would return posts with private status if they belong to a post type for which the user has the read_private_posts
capability.
An existing, and rather undocumented, workaround is to grant the user the read_multiple_post_types
capability. But this, again, will not check the permission current user have in each queried post type and will simply return all private posts for all queried post types.
Proposal
The proposed solution for this is to change the SQL query when querying for multiple post types without informing a post status, and combining the post_status and post_type WHERE clauses, checking user capability for each post type and returning the appropriate query in the very same way WordPress already does when you query for only one post type.
Sample Query when querying for posts and pages, for a user that HAS read_private_posts
cap but DOES NOT HAVE read_private_pages
:
SELECT SQL_CALC_FOUND_ROWS wptests_posts.ID FROM wptests_posts WHERE 1=1 AND ( (wptests_posts.post_type = 'post' AND (wptests_posts.post_status = 'publish' OR wptests_posts.post_status = 'private') ) OR (wptests_posts.post_type = 'page' AND (wptests_posts.post_status = 'publish' OR wptests_posts.post_author = 4 AND wptests_posts.post_status = 'private' ) ) ) ORDER BY wptests_posts.post_date DESC LIMIT 0, 10 }}}
Attached a patch with the change and some tests.
I made an additional elseif statement so it do not touch all other cases and acts only in this very specific case.
Would love to have some feedback.
git branch: https://github.com/leogermani/wordpress-develop/tree/48556