In the latest version of git, flag links don't seem to know they are flagged.

Comments

quicksketch’s picture

Could you provide steps to reproduce? This report is rather ambiguous.

aidanlis’s picture

Sorry for the ambiguous report. I've got Flag, Flag Note, and Advanced Forum. I create a flag for comments and see a flag link appear on comments, but a user can flag each comment multiple times - the action never changes to unflag.

The flag is set up as non-global and can flag any content but their own content.

Thanks,

aidanlis’s picture

Project: Flag » Forum Access
Version: 6.x-2.x-dev » 6.x-1.x-dev
Component: Flag core » Code

Diving deep into the flag module, I found that $GLOBALS['user']->uid was 1 when the comment links were being rendered! This stumped me majorly ...

I dove further with the help of debug_backtrace, and eventually found this nugget in the forum_access module (forum_access_link_alter() line 398):

    if (!empty($link_is_missing)) {
      // One of the $required_links should be present, because the current
      // user has the corresponding permission, but it isn't.
      // We temporarily switch to UID 1 to 'harvest' all comment links.
      if (!isset($user1)) {
        $user1 = user_load(1);
      }
      $saved_user = $user;
      session_save_session(FALSE);
      $user = $user1;

      // With UID 1 we call hook_link(). This should give us the full set of
      // links that the site admin sees.
      $admin_links = module_invoke_all('link', 'comment', $comment, array_key_exists('comment_parent', $links));

      $user = $saved_user;
      session_save_session(TRUE);

      // Remove the links from $admin_links that are not in the reduced
      // set of $required_links AND not available to the current user anyway.
      // Afterwards, $admin_links should have the same content as $links, plus
      // one or more additional links from the original set in $required_links.
      foreach ($admin_links as $key => $target) {
        if (!in_array($key, $required_keys) && !array_key_exists($key, $links)) {
          unset($admin_links[$key]);
        }
      }

      // As the real current user, call hook_link_alter on the admin links.
      // First we set a static variable so that the next time this function is
      // called it will store a copy of the links at their current state. Then
      // we pull those links which have not been link_alter'ed by any modules
      // that come after forum_access.
      $recursing = TRUE;
      drupal_alter('link', $admin_links, $node, $comment);
      $recursing = FALSE;
      // Now return the stored links.
      $links = $stored_links;
    }

This was triggered by a link_alter in one of our modules:

   if (isset($comment)) {
    unset($links['comment_reply']);
  }

So ... not a bug in Flag.

Over to the forum_access module - what's the justification for switching to User 1 in the middle of a request? Can this be re-architected?

salvis’s picture

The comments are pretty clear. There's no use in repeating them again since you've already quoted them.

If I understand this correctly, then the issue is...

a user can flag each comment multiple times - the action never changes to unflag.

... and this is not working correctly for user 1. If the action changed as expected, also for user 1, then it would work correctly even under the circumstances that forum_access creates. Am I missing something?

The handling of comment links is very tricky, because the comment.module provides absolutely no support for adjusting access. We're coercing comments to follow the node access model, for example if a user is allowed to edit forum topics (in a given forum), then he should also be allowed to edit the comments under that topic. This means we need to force comment.module to give us the 'edit' link.

We also make an attempt to handle third-party links, but there's really no way for FA to decide whether a given third-party link requires 'view', 'edit', or 'delete' level access to be displayed. Until now I haven't been aware of any module that actually does provide third-party links, and this part of the FA code is not sufficiently tested. Still, I have to ask, why does Flag not change 'flag' to 'unflag' for user 1?

aidanlis’s picture

Hi salvis,

Indeed, it is a tricky problem you are trying to solve.

The reason why using UID1 when generating the links breaks Flag is this: Flags can be configured to be per-person per-item, not just per-item ... think bookmarking a comment, or marking it as a favourite. The forum_access module replaces these per-person flags with uid1's flags.

So, for example, User 1 marks a comment as favourite. Suddenly, that comment is now visually favourited by all users on the site. Additionally, users can no longer favourite that comment, because clicking the link takes them to the unflag action. Further, all users get administrator access to unflag an item because the access control check is done by drupal_get_token and drupal_valid_token, both of which use the UID from the session.

salvis’s picture

Title: Flagged comments can be flagged more than once and don't get a unflag-action class » FA does not properly support Flag module's flags on comments
Status: Active » Needs work

I understand — thank you for your research and explanations. This is a tough problem and I won't have any quick fix.

As usual, we'll have to look into the D7 version first. The D7 version uses a different approach and gets by without switching to user 1, but we still need to test this.

I won't be able to work on this before the end of the year...

salvis’s picture

Where do we stand here?

Have you been able to check whether the D7 versions get along better?

salvis’s picture

Status: Needs work » Postponed (maintainer needs more info)
aidanlis’s picture

RE fixing this in D7 first: There's no report of users having this problem in D7 in the flag issue queue, and if we're not swapping to UID1 when generating the links then I don't see why it would be a problem.

On my D6 site, I just got bitten by this again on a different site implementing "like this" functionality. I was crawling through the source and I had this strange feeling of deja-vou. then I remembered this issue ...

salvis’s picture

Status: Postponed (maintainer needs more info) » Active

@aidanlis: Is #9 about D6 or D7?

aidanlis’s picture

I've edited for clarity

salvis’s picture

Status: Active » Closed (won't fix)

@aidanlis:
Thank you for clarifying. You seem to be the only person trying to use Flag and FA on the same site, or IAC the only person who has this issue. I realize that this is a no-go for you. If you want to try to fix it, the tests and I will try to help, but it's too low on my priority list to have a chance that I get to work on it myself before D6 is obsolete.

We'll have to conclude that Flag and FA don't work together under D6. Sorry...