7

Does anybody know if there is any way I can restrict each site user to making only one comment per node on my Drupal 7 site? I haven't found anything yet.

I've just tried a complicated setup with flags and rules and triggers and actions and redirects. This didn't work too well.

8

Implement hook_form_alter() in a module. If the form is the node comment form, check if the currently logged-in user has commented on this node earlier. (You might have to write a custom function for this.) If the user has commented on the node, disable the submit button and the textarea.

  • Would this still work if the comment form is on the same page as the node? Also, how do I see if the current global $user has commented on it before? That's what I wasn't clear on. – BenjaminRH Oct 11 '11 at 13:16
  • Depending on the code you write you can make it work anywhere. I think the node in question comes with the $form object or can be retrieved from the url parameters. Get the node, load all of it's comments, parse thru each author and if the author uid matches $user then disable or hide the comment form – LSU_JBob Oct 11 '11 at 13:34
  • 1
    Just tried a test on an actual comment form. It works great, so I should be able to make it work for what I want. Thanks! – BenjaminRH Oct 11 '11 at 13:36
1

Tagged Drupal 7, but I'm going to throw caution to the wind and supply an answer for Drupal 8…

My method: hide the form completely by setting $form['access'] = false;

Here's some code for mymodule.module that identifies the parent node, then does a database query on the comments attached to it, filtered by user. (This is taken from a project where I'd creating a "ratings" comment type in addition to standard comments).

/*
 * Implements HOOK_form_alter
 */
function mymodule_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

  switch ($form_id) {
    // change this to the correct form name for your site
    case 'comment_ratings_form':
      $current_user = \Drupal::currentUser();

      // Find which node this comment form is attached to
      $comment_entity = $form_state->getFormObject()->getEntity();
      $review_nid     = $comment_entity->get('entity_id')->target_id;

      // Remember: the comments field in a node doesn't contain the actual
      // comments, just settings and stats.  We need to do an entity query
      // and find all the comments pointing to the node.

      // Has user already commented?
      $rating_ids = \Drupal::entityTypeManager()
                           ->getStorage('comment')
                           ->getQuery('AND')
                            // attached to the current node
                           ->condition('entity_id', $review_nid)
                           // authored by current user
                           ->condition('uid', $current_user->id())

                           // if you have multiple comment types, you could
                           // filter by those too
                           //->condition('comment_type', 'ratings')

                           ->execute();

      if (!empty($rating_ids)) {
        // already commented, hide the form
        $form['#access'] = FALSE;
      }
      break;
  }

}
0

5 years later ... If you don't want to write custom code, or use the Comment limit module (which only has a dev version for D7), then you can use the Rules and Flag module for this, as described below.

Step 1: flag nodes with comments

Use the Flag module to create a (none-global) flag with a label of something like "Comment submitted" (and machine name comment_submitted).

Step 2: register comment submission

Use Rules to create a custom rule with Rules Event "After saving a new comment.".

This rule should perform a Rules Action "Flag node" (using the flag created in step 1).

Step 3: unpublish additional comments

Use Rules to create a custom rule to unpublish additional comments from users for nodes to which a user commented before (= nodes that were flagged by the comment author). Here is the rule you can use for that (in Rules export format, update the machine name of the flag you use and then import it in your own site):

{ "rules_unpublish_additional_comments" : {
    "LABEL" : "Unpublish additional comments",
    "PLUGIN" : "reaction rule",
    "ACTIVE" : false,
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "flag", "comment" ],
    "ON" : { "comment_insert" : [] },
    "IF" : [
      { "flag_flagged_node" : {
          "flag" : "comment_submittedr",
          "node" : [ "comment:node" ],
          "flagging_user" : [ "comment:author" ]
        }
      }
    ],
    "DO" : [ { "data_set" : { "data" : [ "comment:status" ], "value" : "0" } } ]
  }
}

Note: this rule does as in the title of Step 3 (= unpublish additional comments). So it does not hide the comment form (which is not asked explicitly in the question either). Adding a "set message" as an extra rules action could help clarify that. So as per the comment from OPer below the question, this answer should illustrate that there is "a" way to achieve a similar result using Rules (which I'd rather use instead of adding another module which has a dev version only).

  • 1
    create a (global) flag You do not want to use Global Flag here, because you want each user to have his own individual flag. – No Sssweat Jun 12 '16 at 2:47
  • I still find this answer a bit iffy. What exactly does this rule do? So it flags a node the user comments for the 1st time, but does it stop the user from commenting again? Seems to me that it just unpublishes any further attempts to comment, but it doesn't hide the comment box... is this correct? – No Sssweat Jun 12 '16 at 6:13
  • Fair enough, I guess this is as good as a zero coding solution gets. – No Sssweat Jun 12 '16 at 6:48
  • @NoSssweat: that seems like a good summary, though zero "custom" code (and only contributed code and admin configs) is probably an even more accurate summary. Also, if a site is using Rules already (can't imagine any such site, but that's another topic ...) for other reasons, that would lower the barrier to go for this approach Similar for the Flag module. PS: time to cleanup some comments (cfr the "please avoid ..." ... I do not like chat aaround here). – Pierre.Vriens Jun 12 '16 at 6:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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