Ability to disallow a flag/unflag operation
mooffie - July 21, 2008 - 11:13
| Project: | Flag |
| Version: | 6.x-1.x-dev |
| Component: | Flag core |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | closed |
Description
Currently, all users who have a certain role are allowed to flag/unflag.
But some users want refinements:
- One wants to be able to flag his nodes only.
- Another wants the opposite: to be able to flag only nodes that aren't his.
- Yet another wants to allow users to flag nodes but not to unflag them.
A relatively simple mechanism to allow all this is to introduce a 'flag_veto' hook:
<?php
/**
* 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.
}
}
}
?>
#1
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.
#2
Where would you put this code?
#3
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.
#4
Ah, sorry about that. Thanks for clearing it up.
txcrew
#5
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
#6
Subscribe. Thanks
#7
subscribe. :)
#8
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_accessswitch ($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.
#9
This issue has several sub-issues. I've just opened an offshoot issue:
#322034: Have a $flag->access() method
#10
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.)
#11
+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.
#12
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.
#13
subscribe. interested
#14
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.
#15
+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
#16
subscribe
#17
subscribe. interested
#18
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..."
#19
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.
#20
Marking #429426: only author of a node to flag comments a duplicate of this.
#21
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
#22
Marking #455268: New permissions: view all flags, clear all flags a duplicate of this one.
#23
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)
#24
+1 subscribe to it
#25
#19: If flags are not set to global then they can't do that, can they?
#26
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.
#27
I shared here a code snippet that was stupid. I deleted it
#28
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.
#29
Subscribe. Interested in:
* author only can flag his own nodes (sold flag)
#30
Particularly interested in:
* to allow users to flag nodes but not to unflag them.
#31
Very important for using flags as a reporting/moderation tool for abuse/bad comments/broken pages etc etc.
#32
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.
#33
This update adds support for the one not-solved situation described in #18:
And it fixes some problems with the unflag_denied_message being required when it shouldn't be.
#34
Revised patch to accommodate for #589562: $flag->validate() should return a list of validation errors.
#35
Er, right here's the revised patch.
#36
Updated tests to pass with the new changes. We need to add the access check tests eventually also.
#37
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.
#38
@quicksketch
I don't see this section:
Rules:[X] Users can flag content they create
[X] Users can flag content created by others
#39
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.
#40
@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.
#41
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.
#42
@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!
#43
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:
<?phpfunction 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);
}
}
}
?>
#44
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?
#45
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:
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:
It's loosely the same thing, where the user is always capable, but you as the administrator are granting permission.
#46
@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
#47
@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.
#48
Is this:
http://drupal.org/node/224685
Being implemented?
#49
@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).
#50
Thanks, def will. Made me uncomfortable that it wasn't on the frontpage, but since you recommended I will try.
Thanks again.
#51
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. So we can mark this as fixed. Please open a new issue for any problems discovered with the access system.
#52
@quicksketch
Thank you very much.
#53
How about to add a user role that can override all flag? (global and no global flag?)...
#54
Automatically closed -- issue fixed for 2 weeks with no activity.