0

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(&$node) {
    if(user_is_logged_in()) {
        global $user;
        $account = user_load($user->uid);
        $account_uid = intval($account->uid);
        $asker = field_get_items('node', $node, 'field_asker');
        $asker_uid = intval($asker[0]['uid']);
        $author_uid = intval($node->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(&$vars) {
    if(!_comment_access_check_permission($vars['node'])) {
        $vars['content']['comment_form'] = array();
    }
}

function comment_access_preprocess_comment(&$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…

1
  • I think it may help if you phrase the above into a question. Without question marks I'm guessing as to where you're looking for help. Programmatically closing comments is generally a simple task on its own.
    – Citricguy
    Commented Feb 3, 2012 at 4:17

3 Answers 3

1

Implement hook_menu_alter() and use your custom access function to control access to the comment system.

// Minimalist Example
function MYMODULENAME_menu_alter($items) {
  $items['<path known to hook_menu()>']['access callback'] = 'your_callback_function'; 
  $items['<path known to hook_menu()>']['access arguments'] = array('your args'); 
}
1

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).

2
  • I actually thought of going via the preprocess_node and hiding the comment form (I think you can actually hide it and possibly render it in another place) but I was trying to avoid confusing presentation (theme) with logic (module). Thank you for you reply, though: at least I know I wasn't going crazy :)
    – Morpheu5
    Commented Feb 2, 2012 at 13:58
  • You can preprocess in a module, which helps with the separation of duties. Your situation is a grey area.
    – mpdonadio
    Commented Feb 2, 2012 at 14:35
1

If you're looking to automate the closing of comments based on potentially complex logic the Rules module may be exactly what you're looking for. Managing the comments status of a given node is built in Rules functionality.

If using a contrib module is not an option, seeing how Rules would accomplish this could save you time developing your custom code.

Using nothing more than Rules and maybe the Flag and References modules, you can accomplish everything you mentioned in your original question and it would still allow for additional, possibly more complex logic in the future without needing to write custom code.

7
  • Hey, I'm definitely going to check this module. How could I miss it? I've been searching for two days in a row…
    – Morpheu5
    Commented Feb 2, 2012 at 13:59
  • I checked the Rules module and it's great. The only problem is that I need to "temporarily hide" the comment form (and possibly "temporarily block" comment saving) on a per request basis, while Rules seems to only allow me to change [node:comment] value permanently, thus making it persistent across requests.
    – Morpheu5
    Commented Feb 2, 2012 at 16:11
  • Rules can be triggered in both directions. You can unset settings just as easily as you set them. This would require the creating of a new rule to handle the 're-enabling' of the feature. At what points specifically do comments need to be disabled and at what point specifically do the need them to be re-enabled? The 'specific conditions' that must be met to trigger each transition would be necessary to help further.
    – Citricguy
    Commented Feb 3, 2012 at 4:21
  • Ok, bad phrasing. I don't really need to open/close comments, I just need to show them open or closed depending on which user views a node. I think I've explained the "specific conditions" but here they are: a node has an author (obviously) and another user referenced via a field_asker user reference field. The condition is: disallow comments on the node if the user viewing it is not admin, the author, or the asker referenced by field_asker. I thought it was quite clear in the code I pasted above.
    – Morpheu5
    Commented Feb 3, 2012 at 9:40
  • 2
    Would hook_menu_alter() be useful here to modify the access callbacks on the comment/reply paths? Rules isn't the solution for sure.
    – Citricguy
    Commented Feb 3, 2012 at 10:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.