How to programmatically disallow some users to comment on some nodes? I've been asked to implement the following:


I have a content type with a user reference field from the References module;
a user creates a node and references another user using that field;
only that user and the node's author are allowed to add comments to that node;
at some point the author closes comments, but that's part of another question :)


I've browsed the API of node (both module and API itself) and comment, and couldn't find anything useful. In fact I tried with two of the most promising functions (hook_node_view and hook_node_view_alter) without success.

I'd appreciate pointers to look at.

(yes, I know I said "complex", but this is just the starting point :)

EDIT: Partial solution ahead

function _comment_access_check_permission(&amp;$node) {
    if(user_is_logged_in()) {
        global $user;
        $account = user_load($user-&gt;uid);
        $account_uid = intval($account-&gt;uid);
        $asker = field_get_items('node', $node, 'field_asker');
        $asker_uid = intval($asker[0]['uid']);
        $author_uid = intval($node-&gt;uid);

        if($account_uid == 1 or $account_uid == $asker_uid or $account_uid == $author_uid) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
    return true;
}

function comment_access_preprocess_comment_wrapper(&amp;$vars) {
    if(!_comment_access_check_permission($vars['node'])) {
        $vars['content']['comment_form'] = array();
    }
}

function comment_access_preprocess_comment(&amp;$vars) {
    if(!_comment_access_check_permission($vars['node'])) {
        unset($vars['content']['links']['comment']['#links']['comment-reply']);
    }
}


This code effectively hides the comment form for those users that are not supposed to comment on a given node.

BUT. If one goes to comment/reply/$nid or comment/reply/$nid/$cid the form is still shown, which is not acceptable. Another overview of the API didn't ring any bell to me, so if you have any suggestion…
I would hook_form_alter the comment form, and use your logic to set #access on the form.  You may need to explicitly call menu_get_item to get your node to use in the logic.

You could also use a template_preprocess_node that would perform your logic, and hide or show the comment form in the node's render array based on your logic (this assumes it is in that render array, which I am not 100% positive about).