I've just created a module that integrates flag with organic groups (http://drupal.org/project/og_flag). In order to fully complete the integration I need to have a new hook call added to the flag module.
The new hook, hook_flag_user_access, allows other modules to perform user access checks.
The attached patch adds this hook to the 2.x branch. I'll also create a patch for the 3.x branch shortly.
NOTE: The existing hook_flag_access() is not appropriate here since implementing this hook could potentially completely bypass any additional non-role access checks that custom flags perform.
Comments
Comment #1
shawn_smiley commentedAttached is the patch for hook_user_access() on Flag 7.x-2.x.
Comment #2
shawn_smiley commentedComment #3
joachim commentedIntegration between Flag and OG sounds great!! :)
> NOTE: The existing hook_flag_access() is not appropriate here since implementing this hook could potentially completely bypass any additional non-role access checks that custom flags perform.
Could you explain more about this please?
We recently added hook_flag_validate(), so this would be a third 'can this flagging happen?' type hook, which is starting to feel like a lot.
This would also need to go on 3.x, not 2.x.
Comment #4
shawn_smiley commentedI'll be working on a 3.x patch this coming weekend. I've taken a quick look at flag 3.x and it appears that the permissions checks/hook apis have changed significantly so most likely a different solution will be needed for compatibility with the 3.x branch of the Flag module.
We need this hook added to the 2.x branch since our specific use case for the og_flag module is in support of Drupal Commons 3.x which is still using Flag 2.x.
As to why hook_flag_access() isn't appropriate for use here, let me provide a specific use case where using hook_flag_access() doesn't work in this context:
We created a custom flag module (Commons Correct Answer) which adds a custom flag to Drupal Commons. This flag uses hook_flag_access() to make sure the flag can only be applied to one answer node for any related question node.
If the og_flag module also used hook_flag_accesss() to control visibility based on user permissions, then the og_flag module would end up completely bypassing the node relationship checks in the commons_correct_answer module. This is because the $flag->access() function, which invokes hook_flag_access(), works on the basis of the last executed hook implementation has final say on visibility. Thus if the og_flag module said the user had permission access, the node relationship check of the custom flag module would be ignored.
What we really needed to do within the og_flag module was to modify the result of $flag->user_access() since the conditional checking is entirely permission based. This allows custom flags to still maintain their own conditional display logic while relying on $flag->user_access() to tell them if the user has the necessary permission to use the flag.
Comment #5
joachim commented> This is because the $flag->access() function, which invokes hook_flag_access(), works on the basis of the last executed hook implementation has final say on visibility.
I don't think that's quite it, but clearly something of that ilk is going on:
I read that as the first module that either says 'Yes' or 'No' is the decider.
That's fine if it's a 'No', as we want a denial by a single module to deny totally.
But it's no good for granting access.
I would be more inclined to say this behaviour is incorrect and needs to be changed.
Compare with node_access()'s code:
Comment #6
shawn_smiley commentedI agree that the code in $flag->access() should be modified to be more like the access checks done by the node module.
I was reluctant to go down that path initially though since this is an existing API and this type of change potentially could break other modules if we change the way it works. I can certainly create a patch to implement this type of access change if you would like.
I think implementing the node_access style checks in the hook_flag_access() is better suited for the Flag 3.x branch. I'll look into that this weekend when I'm updating the og_flag module to work with Flag 3.
Comment #7
joachim commented> since this is an existing API and this type of change potentially
That's what the new major version is for! :)
Changing title accordingly.
Comment #8
shawn_smiley commentedHere is a patch that changes the return values for hook_flag_access() to be more like way node_access() works.
Comment #9
joachim commentedChanges look good, but we don't need to have new constants here:
The standard in other parts of Drupal is:
TRUE: grant access
FALSE: explicitly deny access
NULL: say nothing
Comment #10
joachim commentedI'm tagging this as Novice as the patch doesn't need much more work.
Would be great to get this in for 3.0, as it's an API change -- if it doesn't make it in soon, it's postponed till D8!
Comment #11
shawn_smiley commentedThanks for the review and feedback. I should have some time this coming weekend to reroll the patch without the constants.
Comment #12
joachim commentedGreat! Look forward to it.
After that, I'll roll a beta and hopefully a 3.0 soon after that!
Comment #13
shawn_smiley commentedHere is the updated patch. Changes in this patch include:
NOTE: I had some trouble with my IDE applying the patch where it didn't create the new simpletest submodule. But everything works perfectly when applying the patch with "git apply".
Comment #14
alesr commentedHere is a simplified patch from #8.
EDIT: After I committed it I noticed that @shawn_smiley wrote a very similar patch few minutes before me ;)
Well, at least we're closer to get Flag 7.x-3.x stable release out now.
Comment #15
joachim commentedThanks -- both of you! :)
And tests, wow!
Committing this patch, which is #13 with a few tweaks to comments and a change to this assertion text:
> $this->assertNoLink('Flag this item', 0, 'The flag link does not appear on the page.');
I assume the message should say 'does not appear' rather than 'appears', since we're asserting it's not there.
git commit -m "Issue #1965040 by shawn_smiley: Changed handling of return values from hook_flag_user_access() to allow all implementing modules to be considered."
And with that, I'm rolling a beta release tonight!
Comment #16
joachim commentedChange record: http://drupal.org/node/1994208