VoterInterface interface constants

What's happening

Few weeks ago, I got strange behavior in voters return while using constants from VoterInterface interface ( VoterInterface::ACCESS_GRANTED, VoterInterface::ACCESS_DENIED and VoterInterface::ACCESS_ABSTAIN). As sidenote, here is the involved interface.

Below my Voter initial code:

 /**
     * @param string $attributes
     * @param mixed $subject
     * @param TokenInterface $token
     * @return int
     */
    public function voteOnAttribute($attributes, $subject, TokenInterface $token) {

      $user = $token->getUser();

      // If managed here, meaning support method said yes and subject got Rolable trait, and therefore getAuthorizedRoles() method.

      // skip everything if no roles set
      if(count($subject->getAuthorizedRoles()) > 0) {

        // Roles set and no user. Deny
        if(!$user instanceof User) {
            return static::ACCESS_DENIED;
        }

        // user connected (but skip if admin)
        if(!$user->hasRole(User::ROLE_ADMIN)) {

          // User connected, not admin, check roles intersections
          if(count(array_intersect($subject->getAuthorizedRoles(), $user->getRoles())) === 0) {
            return static::ACCESS_DENIED;
          }
        }
      }

      return static::ACCESS_GRANTED;
    }

A legacy

As a matter of fact, my StackOverflow post on topic is pointed on a back-compatibility SF 2.5-. Doc says for SF 2.5+, voters must return true or false.

It’s really important when it comes to VoterInterface::ACCESS_DENIED because where a today regular Voter must return false in denied access case, the matching constant got assigned to -1.

Nonetheless, still a question from my point of view so far : what about VoterInterface::ACCESS_ABSTAIN ? I found the abstaining capability very useful if Voter concludes that it can’t vote.

I will keep this post updated as soon as I will have the answer.

Tags: symfony, voters