5

There is no registered users (apart from user/1 of course ...) in the website and anonymous visitors have the permission to comment on the website.

Comments are not shown before approval.

What I want to do is to display a comment to commenter only before I approve it. So this is what I'm looking for:

Only display a comment posted by 'X' to 'X' (nobody else) for as long as the comment has not been approved by a reviewer, AND on condition X is using the same browser as the one the comment got posted with.

I couldn't use "userid" etc. for (anonymous) visitors. What can be used for that (session, IP address etc.)?


The feature I asked for is similar to the peer review feature you see on any SE site, which is like so:

enter image description here

How can I do it?

  • And what you use to moderate comments in the first place? – Mołot Aug 3 '15 at 8:19
  • @Mołot sorry, couldn't understand what you ask. – herci Aug 3 '15 at 8:20
  • Hımm, I think I have to re-ask my question with more and more details. – herci Aug 3 '15 at 8:52
  • @herci there are 2 downvotes, one close vote, and a lot of details posted in comments, but not in question body... First thing - move details from comments to question, maybe that will help. – Mołot Aug 3 '15 at 8:54
  • 1
    @herci : don't worry about downvotes (you get used to it). And know that downvoting "questions" is cheap: it doesn't cost any reputation (points) to the downvoter. As opposed to downvoting answers (where the downvoter pays with -1). Moreover, 1 upvote compensates for 2,5 downvotes ... About "long questions": be aware that I have a similar problem, and keep struggling with that (I also always want to be as detailed as possible, to avoid all possible questions/doubts). And then people may ... downvote it because of its length ... Oh well, so what? I just keep trying, and ignore downvotes ... – Pierre.Vriens Aug 3 '15 at 9:16
6
+50

Things you need to know:

  1. hook_node_view
  2. hook_query_TAG_alter
  3. db_or

Step I read code.

Step 1: find function comment_node_view this function define element comment in array render of node.

Step 2 find line 711

$node->content['comments'] = comment_node_page_additions($node);//define comment

Step 3 go to function comment_node_page_additions see code.

if (($node->comment_count && user_access('access comments')) || user_access('administer comments')) {
    $mode = variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED);
    $comments_per_page = variable_get('comment_default_per_page_' . $node->type, 50);
    if ($cids = comment_get_thread($node, $mode, $comments_per_page)) {
      $comments = comment_load_multiple($cids);
      comment_prepare_thread($comments);
      $build = comment_view_multiple($comments, $node);
      $build['pager']['#theme'] = 'pager';
      $additions['comments'] = $build;
    }
  }

Step 4 If user is anonymous $node->comment_count = 0. so condition is false. Don't add comment. (Problem 1)

Step 5 function comment_get_thread

if (!user_access('administer comments')) {
    $query->condition('c.status', COMMENT_PUBLISHED);
    $count_query->condition('c.status', COMMENT_PUBLISHED);
  }

this function return array store cids (all comment of node) with condition status is published (don't get comment of user is anonymous) Problem 2.

Problem solving

Problem 1: Use hook_node_view to set $node->commentcount != 0 (require this function run before function comment_node_view. You can set weigh of module (sure test with value is -1) or name of module start with a or b (not sure)).

/**
 * Implements hook_node_view().
 */
function ModuleName_node_view($node, $view_mode, $langcode) {
  global $user;
  if ($user->uid == 0 && $node->comment_count == 0) {
    $node->comment_count = 1;
  }
}

Problem 2 You need alter this query to get comment published or current user is author of comment. To do it i need hook_query_TAG_alter. You can write a custom module with code:

/**
 * Implements hook_query_TAG_alter().
 */
function ModuleName_query_comment_filter_alter(QueryAlterableInterface $query){
  global $user;
  if (!user_access('administer comments')) {
    $conditions = &$query->conditions();
    foreach ($conditions as $key => $condition) {
      if (is_array($condition) && is_string($condition['field'])
        && $condition['field'] == 'c.status'
        && $condition['value'] == COMMENT_PUBLISHED) {
        unset($conditions[$key]); // unset condition comment is public
        $or = db_or();
        $or->condition('c.status', COMMENT_PUBLISHED);
        //$or->condition('c.uid', $user->uid); this case for require use login to comment
        $or->condition('c.hostname', $user->hostname); // Ip of user
        $query->condition($or);
        return;
      }
    }
  }
}   

NOTE: All the users have the same IP are seeing comment.

  • Please avoid code-only answers, unless code itself is well documented with comments. – Mołot Aug 5 '15 at 14:17
  • Thanks for the answer. As @Mołot said, could you please add some comment to the code for us to understand what's going on :) – herci Aug 5 '15 at 19:02
  • @MrD, could you please explain the code a bit more? What piece of the code does what? Does this code really do what I want? I couldn't see any session etc. info in the code to understand the commenter to show the comment. – herci Aug 10 '15 at 9:48
  • You seem not to try my code for solution but only doubt. I think your question is an interesting one. I used to ask myself that question and spent a lot of time finding the answer. However, I see no effort of you even just trying to find the answer. You just try to show your kindness via bouty point, which the person, who answers your questions, will get. With me, bouty point is just the inspiration. I help others not because of this point. You are just waiting for solutions from others and copy it. This is the last time I answer your question. Thanks – MrD Aug 10 '15 at 10:35
  • @MrD, keep calm. I'm just trying to understand your code. I'm not a "just copy and paste the codes and look if it's working or not" person but I want to learn which function does what. // Yes, you're right I couldn't try it until now but I wanted to understand the whole picture. OK, I will try it and share whether if it works or not. But then, what will happen? By only seeing it's working (or not) do I understand it? Thanks for your answer. I'm sorry if I mis-explained myself. – herci Aug 10 '15 at 14:02
3

Try the Comment Access module

Maybe you should look at the Comment Access module.

It seems to not exactly match what you're looking for, but possibly with some tweaks you can get it to work somehow for anonymous users also.

The issues about "Still display a message to anonymous users after they post an unpublished comment." might inspire you to create such tweaks.

Investigate the Comment Trust module

The Comment Trust module can be used to auto-approve comments from trusted visitors. Here is a quote from its project page (bold markup added here):

Comment Trust auto-approves comments by users with previously-approved comments. It rewards trusted commenters with immediate approvals, while requiring you to approve the comments by new visitors. Works for both anonymous and authenticated users.

Even though that is not really what you want in this question, you may want to investigate how this module does its magic for anonymous users. It might be straight forward to clone its magic in what you are looking for.

Use cookies

Since this is about anonymous users, we don't have "a lot" to connect our logic to. But using a technique based on cookies might work. Here are the main steps that would be required:

  • including the jquery.cookie.js file (part of Drupal core), which includes some utility functions for working with cookies.
  • set a cookie using a Drupal function in PHP.
  • do something with that cookie in a JavaScript.

So this cookie should keep track of the comment Ids somehow, so that by using some jQuery you could apply some CSS to hide or show comments.

I'm not an expert in these kind of things, but maybe the answer(s) to these questions may help to complete this:

Look at other modules from old Drupal releases

Maybe you want to look at the answers to drupal 7 comment moderation modules also (it may help to get some more inspiration). In there you'll find suggestions for contributed modules also, though none of them have a D7 version:

Maybe somebody wants to make a D7 version available for either of those modules?

Remark

In a prior version of this answer I suggested using the Privatemsg module. However after you refined (clarified) the question, that is not what will help you solve your question.

  • I think I mis-explained the question or you mis-understood it :) I didn't understand your answer, sorry. – herci Aug 5 '15 at 13:22
  • 1
    hm, oeps! The edited question is indeed not how "I" first understood it. I'd be happy to try to rework my answer (if I can). But can you first let me know if "only display a comment posted by 'X' to 'X' (nobody else) for as long as the comment has not been approved by a reviewer, AND on condition X is using the same browser as the one the comment got posted with" is a correct rewording of "display a comment to commenter only before I approve it" ... If so please copy-paste that in an enhanced version of your question. – Pierre.Vriens Aug 5 '15 at 13:37
  • Yes, you're absolutely right. The correct question should include that: only display a comment posted by 'X' to 'X' (nobody else) for as long as the comment has not been approved by a reviewer, AND on condition X is using the same browser as the one the comment got posted with. I'm editing the question. – herci Aug 5 '15 at 13:42
  • 1
    Thank you for considering my suggested qustion refinement. Note that I slightly tuned it AbitMORE (no need for "credits" there). Feel free to further correct/refine if needed. Up to the "rework" of my answer now also (obviously no longer using Privatemsg) ... – Pierre.Vriens Aug 6 '15 at 5:56
3

This would be easily achieved using views if your users were logging in.

If you look at this question you see how you can use the current user in a view. All you'd then do is to create a view of comments where status is not approved and user=user and nid=the node you're on. You can then use that in a block.


To get a 'user like' token for an anonymous user, you can only really use the the session.

So extending the view idea further. I'd approach this problem as follows

  1. Create a field in the comment called session.
  2. Hide this from display.
  3. Populate this on submit (use a form alter in a module), so it gets created on save - you might be able to use rules.
  4. Add this logic into your view for filtering - you'll do that with a contextual filter again:

    • add a PHP contextual filter.
    • get the user (global $user).
    • return $user->sid (the users session id).
  • Good points, thank you. As I said, it's for anonymous user only and using session id (sid) would be good. Your answer also gave me other ideas to use session id for anonymous users. Thanks again. – herci Aug 11 '15 at 16:57

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.