Hi guys! Great freaking module... seriously. I'm going to use it to take over the world... or at least some of the custom modules in our platform. :P

Anywho, one replacement was the flag_content module. While it works great as a replacement, it would be really great to have a function that will delete all of the flags for a given node id.

Here's the use case:
We have a view that shows all flags of a certain type (flag_abuse). These are shown to a moderator who either deletes the node, or does not agree that a node should be flagged as abuse. If they do not agree with the flag, it would be nice to have a way to remove this from their list by removing all flags on that node.

Maybe an easier solution would be to create another flag for the admin to ignore this and then filter it out of the view... but I really think it would be more beneficial to just remove all flags from a node, at least in this case.

Comments

mooffie’s picture

This would entail:
- Having a "clear" URL, say q=flag/clear/FLAGNAME/CONTENT_ID.
- Having a "clear" link (field) for Views.
- Having a "Roles who may clear this flag" permission in the flag editing screen.

Nathan, is it worth the bother?

BTW, the Rules support has a 'trim' action that clears flaggings. But connecting it to a link in Views (preferably an ajax link) is perhaps a challenge. Or perhaps it isn't. It's worth investigating this.

mooffie’s picture

Title: Flag as flag_content replacement » Flag as flag_content replacement: clearing a node's flaggings
mooffie’s picture

This would entail:
- Having a "clear" URL, say q=flag/clear/FLAGNAME/CONTENT_ID.
- Having a "clear" link (field) for Views.
- Having a "Roles who may clear this flag" permission in the flag editing screen.

Maybe we could integrate this functionality in the existing flag/unflag link. For example, we could have a "Treat this flag as global" checkbox in the settings page of this link (in Views) that will cause an unflag action to clear all flaggings.

sirkitree’s picture

I started looking for a way to do this with flag_get_flags() or flag_get_flag() and it started bending my mind since it would require changes to those functions and there didn't seem to be a function that just handled this request outright. I also thought the "clear" link for Views would be necessary, didn't think of the role.

However, your second idea, "Treat this flag as global" as just a Views option on the Operator (if I understand that correctly) sounds like it might be much less work. I'd rather utilize existing functions then try to extend the current ones. If you can point me in the right direction on how to do this I'll write up a patch. Still getting to know the module API.

quicksketch’s picture

I don't think this functionality is worth directly implementing just yet. A workaround for the time being would be to create a custom module that implements hook_flag(). If a user is a certain role and they unflag a piece of content, remove all the flags for that item. As Mooffie suggests, you'd also be able to do this without a custom module if Rules were fully implemented.

Then, once #322034: Have a $flag->access() method is implemented. You could even make it so that access to that flag would then be denied to all other users, since the administrator has already decided that individual piece of content is not offensive.

mooffie’s picture

Two other places mentioning this problem ("this problem" being: The user interface doesn't have a "clear all flaggings" function):

http://drupal.org/node/315865#comment-1084702
http://drupal.org/node/368330

dnewkerk’s picture

I would love to see this functionality as well (as with a few others in the aforementioned issues, I also tried to setup a View for admin and moderator role use to list and act on flagged-as-offensive content... and ran into the same roadblock). I'd love to get this working with Flag so I can avoid going with Abuse module (or Flag Content module, though I've found that one currently too buggy in D6).

I'm not an excellent programmer (theming's my thing), however if you need testers once a patch is ready, please let me know (I'll keep an eye here). I'm using D6 in my case, though if the initial patch is for D5, I can test that too.

sirkitree’s picture

Version: 5.x-1.x-dev » 6.x-1.1
Assigned: Unassigned » sirkitree

So I'm doing a little more work on this and am running into a problem with Nate's suggestion in #5.

Now, I can preprocess the link for the appropriate user, but in the case of a confirmation box, that user is still presented with the 'flag_confirmation' message. Is there a way we can add some preprocessing for the whole flag so that anything about it can be changed dynamically?

Also, changing the $vars['action'] has no effect on hook_flag(). i.e. I would assume that it would change the $event parameter.

Here's what I have currently:

/**
 * Implementation of hook_perm().
 */
function flag_abuse_perm() {
  return array('reset abuse flags');
}

/**
 * Implementation of hook_preprocess_flag().
 *
 * Here we change our flag event/action to 'reset'.
 */
function flag_abuse_preprocess_flag(&$vars) {
  global $user;
  
  // permmission check instead of a role
  if (user_access('reset abuse flags', $user)) {
    // is this one of our abuse flags
    // @todo: should be dynamic
    if (in_array($vars['flag']->name, array('abuse_node', 'abuse_comment', 'abuse_user'))) {
      // works
      $vars['action'] = 'reset';
      $vars['link_text'] = t('Reset flags');
      $vars['link_title'] = t('Remove all flags on this content');
      
      // doesn't work
      $vars['flag']->flag_confirmation = t('Are you sure you want to reset this content\'s flag?');
      $vars['flag']->link_type = 'link';
      dsm($vars);
    }
  }
}

/**
 * Implementation of hook_flag().
 *
 * If a user with appropriate permission/role flags this content from our view
 * we want to remove all flags. http://drupal.org/node/327901#comment-1085685
 *
 * @todo: When $flag->access() goes in, use this to limit access to a flag that
 * an administrator has already acted upon. http://drupal.org/node/322034
 */
function flag_abuse_flag($event, $flag, $content_id, $account) {
  // permmission check instead of a role
  if (user_access('reset abuse flags', $account)) {
    // is this one of our abuse flags
    // @todo: should be dynamic
    if (in_array($flag->name, array('abuse_node', 'abuse_comment', 'abuse_user'))) {
      // remove all flag on this content
      $query = db_query("SELECT uid FROM {flag_content} WHERE fid = %d", $flag->fid);
      while ($result = db_fetch_object($query)) {
        // Supposed to pass in a full $account here, let's see if we can fake it
        $flag->flag('unflag', $content_id, $result, TRUE);
      }
    }
  }
}
sirkitree’s picture

Also, I've created a project for this as it seems like it will be useful to more than just me.
http://drupal.org/project/flag_abuse

sirkitree’s picture

Status: Active » Fixed

going to mark this as fixed as there is a 'fix' for it now in the form of another module as suggest. Please reopen if you think I'm in error.

Status: Fixed » Closed (fixed)

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

mitchell’s picture

Title: Flag as flag_content replacement: clearing a node's flaggings » Action: clearing a node's flaggings
Status: Closed (fixed) » Active
Issue tags: +rules integration

@sirkitree: What do you think about pushing this action upstream?

Marked #455616: Integration for non global flags as a duplicate of this issue.

mitchell’s picture

Status: Active » Fixed

Actually, the rules integration provides this functionality with the trim action.

Moonshine’s picture

Component: Code » Actions integration

Does Rules actually allow for this w/ "trim" on *non-global flags though? Unless I've overlooked an option, I believe you have to choose what users flag you are clearing. I'd certainly find an action for clearing all flags on a node useful (global or non). Would you be open to a patch for an action like that?

Status: Fixed » Closed (fixed)

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

elijah lynn’s picture

All there needs to be is a box next to the flag. That says "reset".

I accidentally did not check "global" when creating a flag and have had the hardest time figuring out how to reset the flags after I checked "global" It would make sense to just have a "reset" button/column next to the flag in the flag list.

If anyone knows how I can do this that would be great.

elijah lynn’s picture

Status: Closed (fixed) » Active
sirkitree’s picture

Status: Active » Closed (duplicate)

A resolution to this problem would be handled by #571100: Add "reset" action and hooks to Flag. See quicksketch's concerns on it there. Since there is not really any code in this issue, there is nothing to really complete. The issue I referenced in this post is a continuation of this thought process (with code) and addresses the issue I mention in #8 where an inappropriate message is displayed. I'm going to mark this as duplicate since I think attention should be on the other thread instead, but will also check out how this is currently being handled with #547082: Make "Trim flag" an API function.

adam_c’s picture

I don't think the trim function is actually a solution to this problem, from the rules module, trim is described as:

"The trim action is used to restrict the number of objects that may be flagged. For example, you may wish your "Editor picks" queue (that is, flag) to contain a maximum of 3 nodes. The trim action is best understood when we think of a flag as a queue. The action works by discarding old flaggings; So newly flagged objects push older ones out of the queue."

Which just sounds like a '1-in-1-out' approach. Its not resetting at all.

After scanning all the relevant posts in this issue queue there dosn't actually appear to be a solution to this.

The reason I would like a reset (and not a trim) is because I have (or want) a rule which says:

After a flag has been flagged x number of times, do an action, then reset the number of flags to zero and start again.

Is there anyway of achieving this?

twistedindustries’s picture

I have solved this by using the flag modules integration in rules. I created a separate rule to clear all flags and it was easy. I modified two files:

flag.rules.inc
After (About line 183)

 'flag_rules_action_unflag_'. $type => array(
          'label' => t('Unflag a @type', array('@type' => $type)),
          'base' => 'flag_rules_action_unflag',
          'label callback' => 'flag_rules_action_unflag_label',
          'arguments' => $args + array(
            'flagging_user' => array(
              'type' => 'user',
              'label' => t('User on whose behalf to unflag'),
              'description' => t('For non-global flags, this is the user on whose behalf to unflag the object. In addition, if checked below, the access permissions to the flag are checked against this user.'),
            ),
          ),
          'module' => 'Flag',
        ),

Add this:

        'flag_rules_action_unflag_all_'. $type => array(
          'label' => t('Clear flags for @type', array('@type' => $type)),
          'base' => 'flag_rules_action_unflag_all',
          'label callback' => 'flag_rules_action_unflag_all_label',
          'arguments' => $args + array(
            'flagging_user' => array(
              'type' => 'user',
              'label' => t('User on whose behalf to unflag'),
              'description' => t('For non-global flags, this is the user on whose behalf to unflag the object. In addition, if checked below, the access permissions to the flag are checked against this user.'),
            ),
          ),
          'module' => 'Flag',
        ),

After (About line 225)

function flag_rules_action_unflag($flag, $object, $flagging_user, $settings) {
  $flag->flag('unflag', $flag->get_content_id($object), $flagging_user, !$settings['permission_check']);
}

Add this (taken from the flag abuse module):

function flag_rules_action_unflag_all($flag, $object, $flagging_user, $settings) {

$query = db_query("SELECT uid FROM {flag_content} WHERE fid = %d", $flag->fid);
      while ($result = db_fetch_object($query)) {
        // Supposed to pass in a full $account here, let's see if we can fake it
        $flag->flag('unflag', $flag->get_content_id($object), $result, TRUE);
		}
}

Now on the file flag.rules_forms.inc
After
(About line 36)

function flag_rules_action_unflag_label($settings, $argument_labels, $element) {
  $flag = rules_get_element_variable($element, 'flag');
  return t('Unflagtest @object, under "@flag-title"', $argument_labels + array('@flag-title' => $flag->get_title()));
}

Add this:

function flag_rules_action_unflag_all_label($settings, $argument_labels, $element) {
  $flag = rules_get_element_variable($element, 'flag');
  return t('Clear flags for @object, under "@flag-title"', $argument_labels + array('@flag-title' => $flag->get_title()));
}

I hope this solves everyones issues like it solved mine. I know I should have put this all in a diff file but that is out of my league, if anyone wants to create a diff file please do.

erikwebb’s picture

I took a different approach and simply added the clear functionality directly to the Flag module. So far the new functionality is added to the content list page as well as in a new Views field. I'm attaching the patch as well as the new file created for Views (flag_handler_field_ops_clear.inc - in a ZIP file).

erikwebb’s picture

Status: Closed (duplicate) » Needs review

I am re-opening this issue as a patch for 6.x-1.1. This issue was marked as a duplicate despite the other ticket being assigned to version 6.x-2.x. These tickets can live beside one another, affecting different versions.

quicksketch’s picture

New functionality won't be added to the 1.x version of Flag.

erikwebb’s picture

Status: Needs review » Closed (won't fix)

Thanks quicksketch. I'll leave this patch for other people on 6.x-1.1 to find.

mooffie’s picture

Issue tags: +flag reset

Tagging.

Matt G’s picture

Comment #20 worked for me.

I not have an action that clears all flags of one type from a node.

Very useful!

Thanks

notluap’s picture

#20 also worked for me. Thanks!

Ingumsky’s picture

Version: 6.x-1.1 » 6.x-2.0-beta5
StatusFileSize
new1.04 KB

I've created a patch based on #20 (thank you twistedindustries!). It works with flag 6.x-2.0-beta5. To apply this patch extract archive to /sites/all/modules/flag/includes, go there and run "patch -p0 " for both of extracted fies (see documentation if you don't know how to apply patches properly).