The background here is that a colleague has set up a View with VBO functionality to act as a moderation queue for nodes that have been flagged for 'abuse' by end users. The flag in question allows for anonymous flagging.

The current VBO callbacks use the Flag module flag('unflag', 'flag_name', $content_id, $account) function to remove the flag from the node ('allow' action removes the flag only, 'remove' action removes the flag and unpublishes the node). This works if the flag in question is from an authenticated user but it does not work when the flag was done by an anonymous user.

The flag method of the flag object expects that for a $flag->flag() method call that if it's an anonymous user that that user is the current user in context. However if you are processing nodes with flags in an admin context such as via VBO there is no current anonymous user context

In flag.inc:

    // Find out which user id to use.
    $uid = $this->global ? 0 : $account->uid;

    // Find out which session id to use.
    if ($this->global) {
      $sid = 0;
    }
    else {
      $sid = flag_get_sid($uid, TRUE);
      // Anonymous users must always have a session id.
      if ($sid == 0 && $account->uid == 0) {
        return FALSE;
      }
    }

If one has the content_id, uid, and sid of a flag_content record then it's possible to directly call the private method $flag->_unflag() to remove the flag thus bypassing the check above for current user context for anonymous flags. It's something of a workaround but it gets the job done absent an alternative form of removing a flag record programmitically.

Since for anonymous user flags the only distinction from one record in flag_content to the next is the flag_content.sid field, I'd like to have that field available as a Views field. Once the sid field is able to be used in a View then for the case of our VBO action callback we can use the sid to invoke the private _unflag() method.

The attached patch adds sid to the hook_views_data implementation.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

quicksketch’s picture

Thanks, this patch looks and sounds pretty reasonable to me. Though it's a shame that you're needing to call _flag() and _unflag() methods directly. If we were to move to a fully "correct" object implementation, these would be marked "private" methods and your code would break. Can you suggest further changes to make it so that this is unnecessary?

jaydub’s picture

Well I guess the quickest route would be to extend the $flag->flag() method to accept a parameter for the $sid and alter the logic noted above that calls flag_get_sid($uid, TRUE) to get the $sid (which would only work in current user context) to only attempt to get the $sid if not passed as a parameter. That way if called programmatically you could still use $flag->flag('unflag').

Now this makes more sense for unflag where there is a record to act on already but in theory you could use it for flag actions if you programmatically created a $sid via session_api in advance of the call.

You wouldn't be able to do anything about the cookies set in the browser for an anonymous flag if you were to programmtically remove that flag record since the anonymous user isn't in context but I don't see what you could do about that really.

attached patch is a quick and dirty.

joachim’s picture

Status: Needs review » Needs work

Patch adds a variable without adding the docs for it.

joachim’s picture

Ok, I'm now confused -- the two patches here are completely different.

Will come back to this one when it's not pre-breakfast + migraine ;)

joachim’s picture

Version: 6.x-2.x-dev » 7.x-3.x-dev

Upping the version. Still confused by this though.

imclean’s picture

The original request to add the flagging sid to the Views data is a very good idea. I actually thought it was part of the Flag module already.

Adding the sid of the flagging to views will allow admin screens and viewing others people's flagging lists/sharing ( #1044560: Possible to expose flag lists made by anonymous users to general public? ).

In our case, we wanted to view content flagged by anonymous users linking them to particular sessions. It can optionally be filtered by individual sessions. We use the session ID elsewhere to link them to other content.

This patch is an updated version of the first one, adding flagging.sid to the views data.

It doesn't allow (un)flagging by a user/session ID other than the logged in user, which would require further changes to the methods and how the links are generated.

imclean’s picture

Status: Needs work » Needs review

Updated status as the patch fits the title of the issue.

The last submitted patch, flag_views_data-flag_content.sid_.patch, failed testing.

The last submitted patch, 2: flag_add_sid_parameter-1312760-2.patch, failed testing.

joachim’s picture

Status: Needs review » Fixed

Thanks! Committed.

About the other patch, I should point out that this approach:

> If one has the content_id, uid, and sid of a flag_content record then it's possible to directly call the private method $flag->_unflag() to remove the flag thus bypassing the check above for current user context for anonymous flags. It's something of a workaround but it gets the job done absent an alternative form of removing a flag record programmitically.

-- will no longer work, as _unflag() is gone.

  • joachim committed c0f427e on 7.x-3.x authored by imclean
    Issue #1312760 by imclean, jaydub: Added flagging.sid to hook_views_data...

Status: Fixed » Closed (fixed)

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