When a flag is flagged, and a user does not have the "unflag" permission, but has the "flag" permission, then flag_create_link should still return something. In this situation, template_preprocess_flag will check the flag, and replace the link with the "unflag_denied_text" if the user doesn't have access. At the moment, no flag is returned, so users never get to see the "unflag_denied_text" (I am creating my flags manually, and am not using javascript). The reason for this is that the flag_create_link() method ensures that no response is given if a check for $flag->access($content_id) fails.

Determining when to show and not show the link can be a bit confusing, I suggest that you switch the logic around so that you only generate a link if the following is true:
"if the user has flag access, or (the flag is flagged and the user has unflag access)"

i.e. flag_create_link should look as follows:

function flag_create_link($flag_name, $content_id) {
  $flag = flag_get_flag($flag_name);
  if (!$flag) {
    // Flag does not exist.
    return;
  }
  
  if ($flag->access($content_id, 'flag') || ( $flag->is_flagged($content_id) && $flag->access($content_id, 'unflag') ) )
  {
    return $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id);
  }
  
  return;
}
CommentFileSizeAuthor
#1 flag_create_link_unflag_access.patch623 bytesquicksketch

Comments

quicksketch’s picture

Status: Active » Fixed
StatusFileSize
new623 bytes

Thanks, I agree with this logic. We're actually already doing this exact thing in flag_link(), it makes sense to use the same logic in this scenario also. I just copied our existing logic, which is opposite yours in the way it's written but functionally the same.

Status: Fixed » Closed (fixed)

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