voter = $voterFactory ->generate(self::class) ->addCheckFor(AbstractElement::class, self::ROLES) ->addCheckFor(Person::class, [self::CREATE, self::SEE]) ->addCheckFor(Household::class, [self::CREATE, self::SEE]) ->build(); } public function getRoles(): array { return self::ROLES; } public function getRolesWithHierarchy(): array { return ['Budget elements' => self::ROLES]; } public function getRolesWithoutScope(): array { return self::ROLES; } protected function supports($attribute, $subject) { return $this->voter->supports($attribute, $subject); } protected function voteOnAttribute($attribute, $subject, TokenInterface $token) { if ( $subject instanceof Person || ($subject instanceof AbstractElement && null !== $person = $subject->getPerson())) { return $this->voter->voteOnAttribute($attribute, $person ?? $subject, $token); } if ( $subject instanceof Household || ($subject instanceof AbstractElement && null !== $household = $subject->getHousehold())) { foreach (($household ?? $subject)->getCurrentPersons() as $person) { if ($this->voter->voteOnAttribute($attribute, $person, $token)) { return true; } } return false; } throw new \UnexpectedValueException('This subject is not supported, or is an element not associated with person or household'); } }