Hello again!
You’ve got the right idea to alter the query with ‘posts_where’, but things start to unravel after that. If I’m not mistaken, the general concept is to display all posts as usual, except in the case of contributors that cannot publish posts, their posts that are pending show up as though they have been published, though no one else can see their posts yet. Is that the general idea? You realize that if the user is not logged in, it would be difficult to show them their own posts? It will be somewhat obvious their posts are not published immediately.
The first task is to decide if the current user can contribute posts but cannot publish them. We use the current_user_can() function for this. We are looking for the condition where the user can ‘edit_posts’ and cannot ‘publish_posts’. Do not use numeric roles to check capabilities, the numeric roles were deprecated some time ago. You do not need to focus on roles at all for this sort of thing, focus solely on capabilities.
You also will not need to worry about removing this filter. It would apply to the main query for the current request if the capabilities conditions apply. It will not impact other queries run during the same request, and everything is reset for the next request. We should also check that the query is not a single request. It would be silly to add another post to the single requested post.
We can assume the current query is returning all the correct posts when it reaches our filter callback. We merely need to get the query to find the current user’s pending posts as well as all the usual posts. So we need to add on to the existing WHERE clause something along the lines of OR (post_status=pending AND post_author=$user_id AND post_type=post)
This is in no way intended to be proper syntax, it’s merely illustrating the concept. You can get $user_id from get_current_user_id() No need to get the entire user object, all we need is the ID.
There’s also no need for the global $post
object. In fact, it hasn’t been defined yet. We are constructing a query that will find all the posts that will eventually be assigned to $post
.
I’m not sure what impact the ‘always_display’ option has, if any. There’s several similar complicating factors that will need to be addressed, like time restricted queries. The time restriction by default will only apply to the main query results, not the pending posts. We need to determine if there are such restrictions and ensure they are also applied to the pending posts as well.
This might be done by either copying from the existing WHERE clause or by parsing the query vars for applicable restrictions. I suggest you first focus on getting the basic query correctly returning pending posts and worry about these sorts of details later.
In summary, here’s a list of what needs to happen to show pending posts to the author along with normal content.
- add a filter callback to ‘posts_where’
- define the callback which will:
- confirm it is_main() query and ! is_single()
- confirm current user can ‘edit_posts’ and ! ‘publish_posts’
- append our OR clause to the existing clause and return the modified version