We are in the process of allowing authors to collaboratively be a part of the editorial process. They will have access to all pending posts’ preview pages (not post-edit pages).
I want to allow these users to post a normal comment whenever the post is in pending post_status
.
Upon research, a comprehensive solution has been posted here, although that solution only enables commenting through the post-edit page, not the preview page which I am looking for.
Preface
Once post preview is frontend, the comment form depends on how theme handle it. I will assume in this answer that the comment form is shown using the standard
comment_form()
function.The previous assumption isn’t enough, in fact
comment_form
is probably the function in WordPress core with more hooks. There is almost an hook for every line. So what is shown on page, depends a lot on plugins or theme that can change it.After that,
comment_form
use to save comment aPOST
towp-comment-post.php
that contain a lot of hooks too, so even if my solution works on a vanilla install of WP using twenty* theme, I can’t assure it works also with some plugins or custom theme.Workflow
So, once we are assuming to be in a standard case, what you ask is simpler than the linked Q/A, because comment form don’t use ajax and because there are a lot of hooks that can help us to obtain the desired result (talked about negative side of this point in preface).
Essentially we have to:
The Code
First of all, let’s create a function that add a nonce field in comment form, only for allowed logged users and only in post preview. I will also write a function to check if the current user is one of the allowed, in this way I can use it for other scopes.
In this function I put a custom filter hook, in this way roles alloewd can be changed.
Now let’s tease WordPress. The way WP uses to check if the post status is good to be commented is to call
$status_obj = get_post_status_object($status)
(where$status
is thepost_status
field of the post being commented) then check if$status_obj
isprivate
orpublic
otherwisewp_die
. But the only thing thatget_post_status_object
does is to return a value from the global array$wp_post_statuses
(the one keyed with the requested post status).Faking the global variable means faking
get_post_status_object
and so also faking WordPress check.Change the global variable is super easy, however I will do some check to assure the post come from us (thanks to nonce hidden field previously added) and also check if the current user exists and is allowed:
Now, after a comment is inserted from post preview, we have to redirect browser again to post preview. As usual we assure the request comes from post preview and current user has
one of the allowed roles