I would like a list of users who flagged a comment to get displayed under/in the comment itself. I have created a view of list of flaggers, but it lists all the users who have ever flagged any comment:

$view = new view;
$view->name = 'Endorse';
$view->description = '';
$view->tag = 'endorse';
$view->base_table = 'users';
$view->api_version = '3.0-alpha1';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Defaults */
$handler = $view->new_display('default', 'Defaults', 'default');
$handler->display->display_options['use_more_text'] = 'more';
$handler->display->display_options['access']['type'] = 'none';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['exposed_form']['options']['reset_button_label'] = 'Cancel';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Relationship: Flags: User's flagged content */
$handler->display->display_options['relationships']['flag_user_content_rel']['id'] = 'flag_user_content_rel';
$handler->display->display_options['relationships']['flag_user_content_rel']['table'] = 'users';
$handler->display->display_options['relationships']['flag_user_content_rel']['field'] = 'flag_user_content_rel';
$handler->display->display_options['relationships']['flag_user_content_rel']['flag'] = 'endorse';
/* Field: User: Name */
$handler->display->display_options['fields']['name']['id'] = 'name';
$handler->display->display_options['fields']['name']['table'] = 'users';
$handler->display->display_options['fields']['name']['field'] = 'name';
$handler->display->display_options['fields']['name']['label'] = '';
$handler->display->display_options['fields']['name']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['name']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['name']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['name']['alter']['trim'] = 0;
$handler->display->display_options['fields']['name']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['name']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['name']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['name']['alter']['html'] = 0;
$handler->display->display_options['fields']['name']['hide_empty'] = 0;
$handler->display->display_options['fields']['name']['empty_zero'] = 0;
$handler->display->display_options['fields']['name']['link_to_user'] = 1;
$handler->display->display_options['fields']['name']['overwrite_anonymous'] = 0;

It uses the following MySQL query:

SELECT users.name AS users_name, users.uid AS uid FROM users users  INNER JOIN flag_content flag_content_users ON users.uid = flag_content_users.uid AND flag_content_users.fid = 3 

I would like to place the view to comment.tpl.php, so that it generated separate lists for every comment flagged, but am confused how to pass cid to the view as an argument and what else I need to change in my view, so that it listed per comment lists and not all the users for all the flagged comments.

Probably, it is better to place direct MySQL query to comment.tpl.php without involving the views module, but then I can't figure out what exact query I should use. Any help would be much appreciated. Thanks!

P.S. There is long discussion here with regard to the similar need, but it seems little complicated and confused: #277716: Allow Views2 listing of users who have flagged content

Comments

quicksketch’s picture

You need to add an argument for Comment: CID to your view, then in your comment.tpl.php use this code:

<?php print views_embed_view('name_of_your_view', 'default', $comment->cid); ?>

yngens’s picture

quicksketch, will try that later. For now I am quite satisfied with the one-less-module-involved result of a direct DB query:

  $query="SELECT name, users.uid AS uid FROM users INNER JOIN flag_content flag_content_users ON users.uid = flag_content_users.uid AND flag_content_users.fid = 3 AND flag_content_users.content_id = $comment->cid";
  $result=db_query($query);
     while ($row = db_fetch_array($result)) { print '<a href="/user/'.$row['uid'].'">'.$row['name'].'</a>, ';   } 

Final problem here is to enable a user to see her/his name in the list immediately (via ajax for instance), but not only after reloading the whole page. I wonder If flags+views can do that? That is can flag module trigger loading a view into division immediately upon clicking the flag?

quicksketch’s picture

See the JavaScript API in the handbook: http://drupal.org/handbook/modules/flag.

mooffie’s picture

Status: Active » Fixed

That is can flag module trigger loading a view into division immediately upon clicking the flag?

- See Views Flag Refresh.

- (Or the JavaScript API page Nate mentioned.)

- (There's also a relevant feature-request: #926252: Factor out the JavaScript info building . The hook_flag_javascript_info_alter() feature.)

- It's a pity you posted your question on the API page as well. At most you should have provided a link pointing here. Periodically those pages have to be cleaned and it's a bureaucratic process to delete comments. Besides, you teach new programmers bad coding habits.

yngens’s picture

You need to add an argument for Comment: CID to your view, then in your comment.tpl.php use this code:

print views_embed_view('name_of_your_view', 'default', $comment->cid);

quicksketch, wanted to try this way, but unfortunately argument for Comment: CID is not available in views of User type. And we need to use User type views in order to get listed users' names under the comments. Is there any other way to use views?

Edit: Have figured out an argument "Flags: User's flagged content" instead works perfectly well. Thanks!

yngens’s picture

mooffie, thank you very much, everything worked out perfectly. Sorry for posting on the API page, thought that someone could be looking for the solution of the similar issue.

yngens’s picture

Status: Fixed » Active

quicksketch, could you please explain is it possible to pass node->uid to the same view? My view is of User type, where node arguments are not available. Looked and couldn't find in the Relationship section also.

quicksketch’s picture

You'll need to start with a view of type "Node" or "Comment" in order to get this information. You can't start with a user view and then add a comment relationship or argument to it.

yngens’s picture

quicksketch, but my view is all about users who flag comments. If I switch to another type of View, then I will not be able to list users who flag comments. Look at the initial issue. I achieved almost everything, but the last final problem - to pass node details to the view. I really hope that there is some way to do it.

Edit: Tried with a view of Comment type. Alas, could not get users, who flagged comments, listed.

mooffie’s picture

@yngens,

There are two different ways to construct a view that lists the bookmarking users for a specific comment. One is to use a user-type view (that's what you have in mind), another is to use a comment-type view (that's what Nate has in mind).

Both methods are explained here:

How to setup a "Who's bookmarked this" tab

(That page talks about nodes, but it's exactly the same for comments. It also talks about a "tab", but that only means that it's getting its argument from the URL (in your case you'll pass this argument in the views_embed_view() call).

but my view is all about users who flag comments. If I switch to another type of View, then I will not be able to list users

You can list users even if your view isn't of type "user": simply don't display the comment title.

is it possible to pass node->uid to the same view?
[...]
the last final problem - to pass node details to the view

If I understand correctly, you need to pass the comment's ID to the view, don't you? So you don't need to know anything about the node (and you certainly don't need "node->uid", which gives you the node's author).

mooffie’s picture

Status: Active » Fixed

@yngens: feel free to re-open this issue if you encounter any difficulties.

yngens’s picture

Status: Fixed » Active

moofie, thank you for the detailed explanation. I tried both ways and, unfortunately, could not pass node->uid to my view. And I really need to pass node->uid together, as you correctly noted, with comment's ID. Why? Let me try to explain. A project that I am working on needs to display endorsers of the commets within such comments bodies (which is done by now) and in case if the node's author is among those endorsers - to make her/his name bold (strong). Imagine number of usernames who endorsed the comment and among them one in bold, and that will be the node's author's name.

So I have currently the view of comment type (switched from user type), which correctly gives me the names of endorsers and I pass to it (to the view) comments ID by putting the following code into comment.tpl.php: print views_embed_view('endorse', 'default', $comment->cid);

Now how can I make the same view to work with $node->uid? Is it possible to pass two arguments to one view?

Thanks a lot!

mooffie’s picture

if the node's author is among those endorsers - to make her/his name bold (strong)

I'll assume everything else works.

There are several ways to print the name in bold. I think the simplest and the most flexible way is to override theme_username: to envelope the normal output in <span class="author"> if the user name is the same as the current node's author. However, this won't work with AJAX (because there's no "current node" then).

So instead you'll theme the field. Click the "Theme: Information" link to see possible .tpl names for the flagger's name field. Let's assume it's 'views-view-field--endorse--name.tpl.php'. Create this file. In it put:

$node = $view->args[1]; // The second argument we get is the node.
$flagger = $row->{$field->field_alias};

if ($node->name == $flagger) {
  print '<span class="author">' . $output . '</span>';
  // Or just use the <b> tag instead of <span> if you're lazy.
}
else {
  print $output;
}

This snippet wants you to pass the node as an argument. Change your calling code to:

print views_embed_view('endorse', 'default', $comment->cid, $node); 

Unfortunately, when you use this code you lose much of the advantage of using contrib modules in the fist place (which is to avoid coding). Perhaps people in the forums could give you better solutions (your question has little to do with Flag).

yngens’s picture

mooffie, your snippet first made a trick - it worked for the first comment flagged, but then I tried to flag another comment on the same page the class .author was gone for all the comments, so the node author's name everywhere became normal. It turns bold everywhere after manual refreshing the page. So my guess is that Views Flag Refresh, that you suggested me to use above (and I have successfully implemented it to load the view locally - it loads, but for all the comments on the page - of course, because it is in comment.tpl.php) catches $node only after reloading.

Works almost like desired, feels like some little trick is somewhere near. As I understand theme_username will attribute class .author for everywhere, right? Which is ok. But will Views Flag Refresh module take it correctly then?

Edit: I now paid attention to your words: "However, this won't work with AJAX (because there's no "current node" then)". So theme_username does not worth trying then. But I tried second way suggested and found out that it works, but the page have to be reloaded in order all the node author's name appearances to become bold.

mooffie’s picture

it works, but the page have to be reloaded in order all the node author's name appearances to become bold.

So Views can't handle a complete node object as an argument. It makes sense (because all arguments should be "stringable"). So instead we'll send the node ID only (I'll later explain why I didn't do that right from the start).

Change your calling code to:

print views_embed_view('endorse', 'default', $comment->cid, $node->nid);

And have your 'views-view-field--endorse--name.tpl.php' be:

$nid = $view->args[1]; // The second argument we get is the node ID.

print 'the node id: ' . $nid;

It's just for debugging. Do you see a correct "the node id: 456" displayed (even when you don't refresh the whole page) ?

If it works, use the code I posted previously for 'views-view-field--endorse--name.tpl.php', but change the "$node = ..." line to:

$node = node_load($view->args[1]); // The second argument we get is the node ID.
mooffie’s picture

BTW, your first approach, of using your own PHP code instead of Views isn't bad (and eventually you'll have less components to maintain (excluding that piece of code)). One reason Nate and I directed you to Views is because it's much easier to tell you "use Views" than to teach you how to program.

I now see that there's another, relatively easy solution: copy 'flag.tpl.php' to 'flag--bookmarks.tpl.php' (in your theme folder) and put your PHP code (to list all the flagging users) there. This will work fine with AJAX. You'll probably want to use flag_create_link() (see our handbook) to put this link at a more comfortable (design-wise) spot.

yngens’s picture

yay, moofie, your #16 works like a charm. After finally reaching needed effect I am not that much eager to try method with initial PHP code, described in #17. Because, as you might have noticed I am not that much of a coder, but provided exact instructions can accurately follow them. And with PHP-code I am afraid for local loading part. Because with views I used Views Flag Refresh, but what about just PHP code? Is ti difficult to load it locally in comment.tpl.php? Will I need somehow team Views Flag Refresh to work with PHP code or will have to deal with javascript coding?

mooffie’s picture

Status: Active » Fixed

Hurrey! So I'm closing this.

but what about just PHP code? Is it difficult to load it [via AJAX] [...] Will I need somehow [...] to deal with javascript coding?

When you put your PHP code in 'flag--bookmarks.tpl.php' you don't need to bother with JavaScript/AJAX: it work's automatically. Here's a proof: put <? print time(); ?> in that file (inside the "wrapper" span) and see that it refreshes as you click the link. (That's the reason the [flag-bookmarks-count] token works so beautifully.)

yngens’s picture

Status: Closed (fixed) » Fixed

Thank you very much, moofie, I'll try it some time. For now I am quite satisfied with the result, and I hope your instructions on this thread will help other Drupalers too.

P.S. Completely out of scope of the thread's issue I started to wonder how much it is efficient for Views Flag Refresh in order to change a detail in one comment to reload comment.tpl.php for all the comments on the page. I know that to deal with a given Drupal comment separately, we have to have its own template file and to auto-generate separate template files for every comment in Drupal installation would be crazy. On the other hand I would like to believe there will be found some way to load Ajax only for given cid and not for all the comments.

mooffie’s picture

[...] wonder how much it is efficient for Views Flag Refresh to [...]

You don't have to use Views Flag Refresh. Put the views_embed_view() call in 'flag--bookmarks.tpl.php' and that's all (in that file, the variables $comment and $node aren't recognized but you can get at them through $content_id).

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

yngens’s picture

Status: Fixed » Active

I now see that there's another, relatively easy solution: copy 'flag.tpl.php' to 'flag--bookmarks.tpl.php' (in your theme folder) and put your PHP code (to list all the flagging users) there. This will work fine with AJAX. You'll probably want to use flag_create_link() (see our handbook) to put this link at a more comfortable (design-wise) spot.

Hi moofie,

Everything works fine since the issue was closed, but to have the best possible method I decided to try alternative method today. Per your instructions have copied flag.tpl.php from the module's directory to my theme directory as flag--bookmarks.tpl.php, put a test code <? print time(); ?> inside of "wrapper" span and tried to click on Endorse flag. Unfortunately, it did not pick up local template file. Have tried to clear cache, tried to rename it to flag--endorse.tpl.php, again nothing happened. What could be the reason, preventing for local (in my theme directory) copy of template file for the flag?

mooffie’s picture

Status: Active » Closed (fixed)

It's very simple:

"copied flag.tpl.php [...] as flag--bookmarks.tpl.php [...] tried to click on Endorse"

Endorse is endorse. Bookmarks is bookmarks. Two different flags.

"Have tried to clear cache, tried to rename it to flag--endorse.tpl.php, again"

You have to clear the cache *after* renaming the file. Not before.

yngens’s picture

Status: Closed (fixed) » Active

Trying this today, again. My flag is called 'endorse', so I renamed default template file to flag--endorse.tpl.php and put to my theme's directory. The test code proved right, so I placed my code instead of test code, but for some reason nothing came up.

I don't understand why this code works:

<span class="<?php print $flag_wrapper_classes; ?>">
  <?php if ($link_href): ?>
    <a href="<?php print $link_href; ?>" title="<?php print $link_title; ?>" class="<?php print $flag_classes ?>" rel="nofollow"><?php print $link_text; ?></a><span class="flag-throbber">&nbsp;</span>
  <?php else: ?>
    <span class="<?php print $flag_classes ?>"><?php print $link_text; ?></span>
  <?php endif; ?>
  <?php if ($after_flagging): ?>
    <span class="flag-message flag-<?php print $last_action; ?>-message">
      <?php print $message_text; ?>
    </span>
  <?php endif; ?>

  <? print time(); ?>

</span>

but this one does not:

<span class="<?php print $flag_wrapper_classes; ?>">

  <?php if ($link_href): ?>
    <a href="<?php print $link_href; ?>" title="<?php print $link_title; ?>" class="<?php print $flag_classes ?>" rel="nofollow"><?php print $link_text; ?></a><span class="flag-throbber">&nbsp;</span>
  <?php else: ?>
    <span class="<?php print $flag_classes ?>"><?php print $link_text; ?></span>
  <?php endif; ?>
  <?php if ($after_flagging): ?>
    <span class="flag-message flag-<?php print $last_action; ?>-message">
      <?php print $message_text; ?>
    </span>
  <?php endif; ?>

<?php
  $query="SELECT name, users.uid AS uid FROM users INNER JOIN flag_content flag_content_users ON users.uid = flag_content_users.uid AND flag_content_users.fid = 3 AND flag_content_users.content_id = $comment->cid";
  $result=db_query($query);
     while ($row = db_fetch_array($result)) { print '<a href="/user/'.$row['uid'].'">'.$row['name'].'</a>, ';   } 
?>

</span>

Probably template file for the flag, even if it is called within comment.tpl.php, does not see variables of comment like $comment->cid? Any further comments or instructions would be appreciated.

mooffie’s picture

Status: Active » Fixed

Probably template file for the flag [...] does not see variables of comment

Right. (I mentioned that in comment #21.)

To get at the comment, add the following just before your code:

$comment = $flag->fetch_content($content_id);

(Alternatively, use "$content_id" instead of "$comment->cid".)

And, *after* everything works, improve your code:
- Use theme('username', ...) instead of (incorrectly) building the link.
- Use "$flag->fid", not "3".
- Use "{table_name}", not "table_name", in your SQL.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

yngens’s picture

Status: Closed (fixed) » Active

Now this is cool. Works at the spot, much faster than before, especially on the pages where there are hundreds of comments. I am struggling now to get endorsers' names separately under the comments and not within links. Applying divs and spans with css, nothing helps - the names appear within the links, just after endorse flag. And what is worse endorse flag is not the last link, but somewhere in the middle.

Also improved the code per your instructions. Thank you very much!

mooffie’s picture

Status: Active » Fixed

I am struggling now to get endorsers' names separately under the comments and not within links

I mentioned that in comment #17: ask Flag to *not* show the link. Instead, show it yourself using flag_create_link() in comment.tpl.php.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.