2

I am currently analyzing a project and am encountering the following situation, where I'd like to know your point of view.

For a specific content type we would like to allow users to place comments, but they should only see the comments made by users with the same role. Only administrators should be allowed to view them all.

Anyone encountered a similar situation?

1

Disclaimer: I have not had need for this myself, nor do I posses a database where I could perform suitable testing for this. Despite this, I feel confident I understand the problem enough to provide a useful solution.

While I've been writing this answer, I've been struck by the complexity of it. I've tried to take a step back, and consider if there are other options, but none other come to mind. Perhaps someone else will be able to offer an easier suggestion.

The standard Drupal answer will be use a View, and that is most likely the way I would go about this myself. Even if you require more flexibility than that, the SQL generated by Views would serve as an excellent boilerplate for your own code. It's important to understand, that in my example below, you are required to be able to pass in a "role-id", into the View. This in turn likely requires you to understand and use Page manager + Panels. PM+P can be considered daunting at first, but is a great tool every Drupal site-builder should be familiar with. Tutorial here.

Basic steps to creating such a View:

  1. Create a View. It's important to note the "Show" dropdown on the views/add page. It should be set to comments, not content, that is the default.
  2. By default, Views should create a relationship between the comments, and the content they are posted on. If it's missing, add it. (Comment: content).
  3. We also want information about the posting users group, we need to add a second relationship, (Comment: Author).
  4. Last, we must create a "contextual filter", a filter that asks the currently viewing user "Which role do you have?". Add (User: roles), as a contextual filter. The default settings in on the contextual filter, will likely have the "Relationship" configured to use "Content" for getting the role, but that will give us wrong data, so this needs to be changed to "author" instead.

Done! Test it out by giving the preview a rold-id as argument, and see what results you get back.

Query below, ready to be pasted into a db_query()-call. This query could also more readily be adapted to take a user-id and "WHERE IN()", the users roles, if necessary.

SELECT comment.subject AS comment_subject, comment.cid AS cid, comment.nid AS comment_nid, comment.created AS comment_created
FROM {comment} comment
INNER JOIN {node} node_comment ON comment.nid = node_comment.nid
LEFT JOIN {users} users_comment ON comment.uid = users_comment.uid
INNER JOIN {users_roles} users_comment__users_roles ON users_comment.uid = users_comment__users_roles.uid
WHERE (( (comment.status <> '0') AND (node_comment.status = '1') AND (users_comment__users_roles.rid = '1') ))
ORDER BY comment_created DESC
LIMIT 10 OFFSET 0

Below follows a full export of my View:

$view = new view;
$view->name = 'rolebasedcomments';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'comment';
$view->human_name = 'tmp';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['query']['options']['query_comment'] = FALSE;
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Relationship: Comment: Content */
$handler->display->display_options['relationships']['nid']['id'] = 'nid';
$handler->display->display_options['relationships']['nid']['table'] = 'comment';
$handler->display->display_options['relationships']['nid']['field'] = 'nid';
$handler->display->display_options['relationships']['nid']['required'] = 1;
/* Relationship: Comment: Author */
$handler->display->display_options['relationships']['uid']['id'] = 'uid';
$handler->display->display_options['relationships']['uid']['table'] = 'comment';
$handler->display->display_options['relationships']['uid']['field'] = 'uid';
$handler->display->display_options['relationships']['uid']['required'] = 0;
/* Field: Comment: Title */
$handler->display->display_options['fields']['subject']['id'] = 'subject';
$handler->display->display_options['fields']['subject']['table'] = 'comment';
$handler->display->display_options['fields']['subject']['field'] = 'subject';
$handler->display->display_options['fields']['subject']['label'] = '';
$handler->display->display_options['fields']['subject']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['subject']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['subject']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['subject']['alter']['word_boundary'] = 0;
$handler->display->display_options['fields']['subject']['alter']['ellipsis'] = 0;
$handler->display->display_options['fields']['subject']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['subject']['alter']['trim'] = 0;
$handler->display->display_options['fields']['subject']['alter']['html'] = 0;
$handler->display->display_options['fields']['subject']['hide_empty'] = 0;
$handler->display->display_options['fields']['subject']['empty_zero'] = 0;
$handler->display->display_options['fields']['subject']['link_to_comment'] = 1;
/* Sort criterion: Comment: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'comment';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Contextual filter: User: Roles */
$handler->display->display_options['arguments']['rid']['id'] = 'rid';
$handler->display->display_options['arguments']['rid']['table'] = 'users_roles';
$handler->display->display_options['arguments']['rid']['field'] = 'rid';
$handler->display->display_options['arguments']['rid']['relationship'] = 'uid';
$handler->display->display_options['arguments']['rid']['default_argument_type'] = 'fixed';
$handler->display->display_options['arguments']['rid']['default_argument_skip_url'] = 0;
$handler->display->display_options['arguments']['rid']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['rid']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['rid']['summary_options']['items_per_page'] = '25';
$handler->display->display_options['arguments']['rid']['break_phrase'] = 0;
$handler->display->display_options['arguments']['rid']['add_table'] = 0;
$handler->display->display_options['arguments']['rid']['require_value'] = 0;
$handler->display->display_options['arguments']['rid']['reduce_duplicates'] = 0;
/* Filter criterion: Comment: Approved */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'comment';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 0;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status_node']['id'] = 'status_node';
$handler->display->display_options['filters']['status_node']['table'] = 'node';
$handler->display->display_options['filters']['status_node']['field'] = 'status';
$handler->display->display_options['filters']['status_node']['relationship'] = 'nid';
$handler->display->display_options['filters']['status_node']['value'] = 1;
$handler->display->display_options['filters']['status_node']['group'] = 0;
$handler->display->display_options['filters']['status_node']['expose']['operator'] = FALSE;
  • Thank you very much for your extensive answer, I'll definitely check it out. It would be nice to achive this without programming... – Pieter Van Leuven Jan 6 '12 at 14:48
1

My proposal:

  • Copy the comment template into your theme folder.
  • Use global $user to access the current logged in user.
  • Use user_load($comment->uid) to load the user object for the commented user.
  • Loop through the roles in $user and check using in_array if that exists in $comment->roles.
  • If it's in the array, show the comment, otherwise hide it.
  • Hi, seems like a simple solution. I will definitely try out your solution. I'll report back! – Pieter Van Leuven Jan 6 '12 at 14:44
  • Up-voted, since this is a much easier solution than either of mine. It does have a performance drawback though, since this solution still both loads and "renders" all of the comments. – Letharion Jan 6 '12 at 14:59

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.