Currently, all users who have a certain role are allowed to flag/unflag.

But some users want refinements:

A relatively simple mechanism to allow all this is to introduce a 'flag_veto' hook:

/**
 * Implement this hook in your module to disallow a 'flag' or 'unflag'
 * operation. This hook is called before a flag link is shown, or before
 * a flag/unflag operation is carried out. If your hook returns FALSE,
 * the action won't be allowed, or the flag link won't be shown.
 *
 * @param $flag_action
 *   Either 'flag' or 'unflag'
 * ...
 */
function mymodule_flag_veto($flag_action, $flag, $content_id) {

  // EXAMPLE: How to disallow flagging a node which isn't ours
  global $user;
  if ($flag->content_type == 'node' && ($node = node_load($content_id))) {
    if ($node->uid != $user->uid) {
      return FALSE; // veto this operation.
    }
  }

}
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mooffie’s picture

One wants to be able to flag his nodes only.

To be exact, that user asked to be able to flag nodes only if another flag was already set on them (e.g., to flag as 'completed!' nodes that were flagged as 'a goal of mine'). This too will be possible with the proposed hook.

Anonymous’s picture

Where would you put this code?

mooffie’s picture

txcrew, this is only an idea for a feature. It doesn't exist yet. You would put that code in a custom module. It's customary in the Drupal world to create a little module specific to your site that implements various hooks to refine the way Drupal behaves. This would be just another hook.

Anonymous’s picture

Ah, sorry about that. Thanks for clearing it up.

txcrew

quicksketch’s picture

I wouldn't mind seeing some of this functionality built into Flag module directly. Adding in a hook would probably be icing on the cake though. Maybe we can name the hook "hook_flag_access()", which will fit in a little better with the typical Drupal terminology.

All access settings could probably be grouped in a fieldset in the Flag configuration:

- Flag Access -

Roles:
Flag   Unflag   Role
 [X]     [X]     authenticated user
 [ ]     [ ]     moderator
etc....

Content types:
[X] Blog
[X] Page
etc...

Rules:
[X] Users can flag content they create
[X] Users can flag content created by others

gausarts’s picture

Subscribe. Thanks

Flying Drupalist’s picture

subscribe. :)

aaron’s picture

Excellent idea. As quicksketch noted, #319224: Support for flagging flaggings would be a use case for this. If hook_flag_access were in place, a module might be fairly easily built, using that API.

However, we'd probably need more than just access. In this specific use case, we'd want to allow each user to be able to flag the other user, but only mark the flag as active if both have marked that flag. On the other hand, maybe that would be better as its own thing, as it might just be a third "flag". (Does the Flag module have an API allowing for the easy creation of internal flags? Would that be desirable for a case like this?)

We'd also want to be able to notify the other user about the actions, although that could happen under the proposed API hook.

Maybe a hypothetical Flag Reciprocity module could work like this:

Implement hook_flag_access
  switch ($op)
    case 'flag':
      if (the other user hasn't yet flagged this user) then
        tell the other user about this user's flag request
        allow the op
      else
        tell the other user the flag has been marked active
        set an internal marker linking the two users
      break
    case 'unflag':
      reverse the above work flow
      break;

Thinking about it more, I guess we should get this hook in there, start building another module, then see what more we might want from a Flag API.

mooffie’s picture

This issue has several sub-issues. I've just opened an offshoot issue:

#322034: Have a $flag->access() method

mooffie’s picture

A reminder:

All access checks need to be duplicated in the applies_to_content_id_array() method, where, for efficiency reasons, we don't load the nodes. (This is used for 'table' Views, for example. See documentation of this method.)

Apollo610’s picture

+1 for these 2:

* to be able to flag only nodes that aren't his.
* to allow users to flag nodes but not to unflag them.

johnnytyranno’s picture

For a global flag, it would also be great to have the option to only allow a node's author or the administrator to unflag the node.

robertdjung’s picture

subscribe. interested

Dave Reid’s picture

Subscribing. I'm looking into writing a 'spam report' flag module for drupal.org, and it would require to not allow users to unflag items. It's a one-time thing.

RoboPhred’s picture

+1, I will try my hand at making a patch for the access hook.
Not marking as assigned until I manage to get something concrete though.

Speaking for a flexible API, should there be a case where a flag should be hidden from the user? What about with global flags, should we support a case where we would want to let others see the flag but not access it, or hide it from those without access?

Probably the best way to deal with this would be to add a 'view' op in addition to flag/unflag

tobiberlin’s picture

subscribe

manop’s picture

subscribe. interested

gunzip’s picture

subscribe.

i need to be able to flag other users but prevent theme to flag themselves,
ie. "become a fan of..." but not "become a fan of yourself..."

netentropy’s picture

yes this is very much needed. if you are using it to flag bad content, then someone could just unflag their own content and no node would get reviewed.

mooffie’s picture

minus’s picture

yes this is very much needed! :)

If you use it to mark a node as sold, and the only user who can use/see that function is the node creator. When the node is mark sold only a message should appear on the node, not the unflag option :) And what bjraines said about reporting/abuse :)

Flagmodule <3

mooffie’s picture

aharown07’s picture

Subscribing. I think all of the above sounds very useful and would provide a much cleaner solution than what I have at present (and much lighter than some of the alternatives)

RicardoJBarrios’s picture

+1 subscribe to it

Anonymous’s picture

Component: Code » Flag core

#19: If flags are not set to global then they can't do that, can they?

Mtt-2’s picture

Subscribing as well :

* to be able to flag only nodes that aren't his.
* to allow users to flag nodes but not to unflag them.

Mtt-2’s picture

I shared here a code snippet that was stupid. I deleted it

ordually’s picture

Subscribing. Particularly interested in:

* to be able to flag only nodes that aren't his.
* to allow users to flag nodes but not to unflag them.

jontyler’s picture

Subscribe. Interested in:
* author only can flag his own nodes (sold flag)

dhalgren’s picture

Particularly interested in:
* to allow users to flag nodes but not to unflag them.

highvoltage’s picture

Very important for using flags as a reporting/moderation tool for abuse/bad comments/broken pages etc etc.

quicksketch’s picture

Status: Active » Needs review
FileSize
39.97 KB

This patch implements all the functionality described in #5. It turned out to be a much bigger patch than I expected, because this additional functionality requires quite a bit of additional validation, as well as a database update.

Changes:
- The "roles" are no longer stored in a dedicated database column. They're now merged into "options" with everything else.
- $flag->roles is now an array with 2 keys: $flag->roles['flag'] and $flag->roles['unflag'].
- Restructuring of the admin form to group together "access" options together.
- Added the option for "unflag_denied_message", which will be shown if the user has access to Flag but not to Unflag (such as "Thanks for flagging!" or something similar).
- The admin form was getting unwieldly with the new text fields, so I broke out link-specific textfields into a new section. This ultimately resulted in link-specific options becoming a universally supported functionality, so other contrib modules can create new link types and have a place for their custom options.
- Users must have "flag" permission to have the "unflag" permission. This made it so that we didn't have to drastically change our flag access checking, since we can assume "flag" is the minimum permission a user must have.

quicksketch’s picture

This update adds support for the one not-solved situation described in #18:

i need to be able to flag other users but prevent theme to flag themselves,
ie. "become a fan of..." but not "become a fan of yourself..."

And it fixes some problems with the unflag_denied_message being required when it shouldn't be.

quicksketch’s picture

quicksketch’s picture

Er, right here's the revised patch.

quicksketch’s picture

Updated tests to pass with the new changes. We need to add the access check tests eventually also.

quicksketch’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

I committed the patch in #36 so that it won't block other issues due to the size of the changes here. Between this, the export patch and anonymous flagging, this nearly wraps up the changes before a 2.0 beta.

We really need tests for this functionality though, switching users and trying out as different roles is a very tedious process, so I'm marking needs work until that is completed.

xn2001’s picture

@quicksketch
I don't see this section:

Rules:
[X] Users can flag content they create
[X] Users can flag content created by others
quicksketch’s picture

FileSize
45.47 KB

It's actually a set of radio buttons, since I didn't want users to have to check both boxes to get "all content" as flaggable. It also would cause a problem if neither box was checked, which would be "no content" was flaggable. Anyway, screenshot attached of actual functionality.

xn2001’s picture

FileSize
19.36 KB

@quicksketch
I got the nightly build flag-6.x-2.x-dev.tar.gz.(Last updated: September 28, 2009 - 12:16)[http://ftp.drupal.org/files/projects/flag-6.x-2.x-dev.tar.gz]
And there is no "Rules" section.
Probably, it is not the latest build. I will try again tomorrow.

quicksketch’s picture

xn2001, it looks like you've got the right version, since the table for flag/unflag was added at the same time. It's probably because the flag you're editing is a comment flag, not a node flag. The functionality for comment flag's based on authorship has not been implemented.

xn2001’s picture

@quicksketch,
You are right. I was editing a comment flag.

What I was trying to do is to implement a "question and answer" flagging system.
The node is the question and 1 of the comments is the answer. The system would only allow the node(question) creator to flag 1 of the comments as the answer.
Can Flag module be extended to do what I need or should I forget about Flag module and create my own module?

thx!

quicksketch’s picture

The system would only allow the node(question) creator to flag 1 of the comments as the answer.

Hm, that's an interesting use-case that I hadn't thought of. Sounds like the options for comments should be implemented as such:

Flag access by authorship:
(•) No additional restrictions
( ) Users may only flag own comments
( ) Users may only flag comments by others
( ) Users may only flag comments of nodes they own
( ) Users may only flag comments of nodes by others

So for your situation you could use "Users may only flag comments of nodes they own". However, this would not limit the number of "correct answers" to 1. However you're only a single step away from having exactly what you want, for which I'd recommend implementing hook_flag() and unflagging other comments within the same node though some custom PHP.

Note this code is completely non-functional, but a good idea of how it would be done:

function mymodule_flag($action, $flag, $content_id, $account) {
  if ($action == 'flag' && $flag->name == 'correct_answer') {
    $comment = comment_load($content_id);
    $node = node_load($comment->nid);
    // Get a list of comments for the current node.
    foreach ($comments as $comment) {
      $flag->flag('unflag', $comment->cid, $comment);
    }   
  }
}
xn2001’s picture

Thx quicksketch.
Let me know when it is committed. I will try it out.

Can I know why you put 'may' in 'Users may only flag...' . Wouldn't 'can' be more affirmative?

quicksketch’s picture

The difference between may and can gets pretty fuzzy. Here's a reference that seems to have some pretty good rules: http://www.businesswritingblog.com/business_writing/2006/08/can_vs_mayno...

The summary:

If you intend "able to," use can.
If you mean "will possibly," use may.
If you intend "permitted to," use may.

I would say that a user is always "able" to flag a piece of content (if they were allowed), there's nothing physically preventing them from doing the flagging. So my use of the word "may" is to indicate permission.

I didn't reference that website when I chose the terminology, I just based it on the frequent elementary school correction:

Teacher, can may I use the bathroom?

It's loosely the same thing, where the user is always capable, but you as the administrator are granting permission.

xn2001’s picture

@quicksketch
Do you intend to implement the use case mentionned in your post#43?

Flag access by authorship:
(•) No additional restrictions
( ) Users may only flag own comments
( ) Users may only flag comments by others
( ) Users may only flag comments of nodes they own
( ) Users may only flag comments of nodes by others
quicksketch’s picture

@xn2001 yes eventually, but things have gotten crazy in my day-job and code freeze is this week. It will probably be a while before I can return to the Flag queue.

Flying Drupalist’s picture

Is this:
http://drupal.org/node/224685

Being implemented?

quicksketch’s picture

@Flying Drupalist: That's already done as per #36. Download the 2.x version to try it out (click "View all versions" on the project page).

Flying Drupalist’s picture

Thanks, def will. Made me uncomfortable that it wasn't on the frontpage, but since you recommended I will try.

Thanks again.

quicksketch’s picture

Status: Needs work » Fixed
FileSize
4.38 KB

I added this patch for comment functionality as requested #39-43.

I'm splitting the tests out into a separate issue #616524: Add tests for Flag access for own/others' content. So we can mark this as fixed. Please open a new issue for any problems discovered with the access system.

xn2001’s picture

@quicksketch
Thank you very much.

milham’s picture

Issue tags: -Needs tests

How about to add a user role that can override all flag? (global and no global flag?)...

Status: Fixed » Closed (fixed)

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

greg.harvey’s picture

Version: 6.x-1.x-dev » 6.x-2.x-dev

Slightly confused, this is marked as a 6.x-1.x-dev issue, but I do not see this UI in the latest 6.x-1.2 version, and it is packaged after this issue was closed. Does this mean the work above went in to 6.x-2.x-dev and I should use 6.x-2.0-beta2 if I need it? Tentatively altering the version number, assuming I'm correct, to save others being confused too.

Edit: 6.x-2.0-beta2 seems to have this feature, so seems I was correct to change the branch, if only for reference. =)

inuninu’s picture

Issue tags: +flag access control

Is it possible to allow flagging a node with flag 2.x only if the actual logged in user has a certain uid?

At the moment I've got a big problem because all the possibilities with giving access to flag a node based on roles, or giving access only if it's the author of a node, or not the author of a node doesn't fit my needs.

I have to work with rules to unflag nodes, that a wrong user has flagged and that's really annoying.

I've looked up the API for PHP and also found of course a lot of stuff like this http://drupal.org/node/322034 ,

but could it be possible to work out a method that I can implement in for e.g. the node.tpl like:

global $user;
 $flag = flag_get_flag('example');
  if ($flag && $flag->content_type == 'node' && ($node = node_load($content_id))) {
    if ($user->uid != $node->field_something[0]['value']) {
      return FALSE; // veto this operation.
    }
  }

Or do I have to find another module? But which one? I've tried to find another solution, but the only way would be to change the ownership of a node, which is not the way I wanna go now.

Thanks

lameei’s picture

+1

pribeh’s picture

+1 for disallowing end-users from unflagging content, aka "like" on Facebook.

mansspams’s picture

Status: Closed (fixed) » Fixed

System set wrong status, this is in dev...

pribeh’s picture

Hi mansspams,

Which dev is this in? This is set to 2.x but there is currently only a 2-beta (2.3 latest) release and no devs that I can find. I can't find this option in the 2.3-beat release.

Thanks,

quicksketch’s picture

When you configure a flag, there are separate permissions for "Flag" and "Unflag" for each role. Just remove the ability to Unflag while keeping the Flag permission.

pribeh’s picture

Wicked, Thanks quicksketch!

Status: Fixed » Closed (fixed)

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

Gabriel R.’s picture

Having separate Flag and Unflag permissions is an incredibly useful.