security = $security; $this->voterHelper = $voterHelperFactory->generate(self::class) ->addCheckFor(Person::class, [self::SEE, self::CREATE]) ->addCheckFor(AccompanyingPeriod::class, [self::SEE, self::CREATE]) ->addCheckFor(Activity::class, self::ALL) ->build(); } public function getRoles(): array { return [ self::SEE, self::SEE_DETAILS, self::CREATE_PERSON, self::CREATE_ACCOMPANYING_COURSE, self::UPDATE, self::DELETE, self::FULL, ]; } public function getRolesWithHierarchy(): array { return ['Activity' => $this->getRoles()]; } public function getRolesWithoutScope(): array { return []; } protected function supports($attribute, $subject): bool { return $this->voterHelper->supports($attribute, $subject); } protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool { if (!$token->getUser() instanceof User) { return false; } if ($subject instanceof Activity) { if ($subject->getPerson() instanceof Person) { // the context is person: we must have the right to see the person if (!$this->security->isGranted(PersonVoter::SEE, $subject->getPerson())) { return false; } // change attribute CREATE if (self::CREATE === $attribute) { return $this->voterHelper->voteOnAttribute(self::CREATE_PERSON, $subject->getPerson(), $token); } } elseif ($subject->getAccompanyingPeriod() instanceof AccompanyingPeriod) { if (!$this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject->getAccompanyingPeriod())) { return false; } if (self::CREATE === $attribute) { if (AccompanyingPeriod::STEP_CLOSED === $subject->getAccompanyingPeriod()->getStep()) { return false; } return $this->voterHelper->voteOnAttribute(self::CREATE_ACCOMPANYING_COURSE, $subject->getAccompanyingPeriod(), $token); } } else { throw new RuntimeException('Could not determine context of activity.'); } } elseif ($subject instanceof AccompanyingPeriod) { if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { if (in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE], true)) { return false; } } // transform the attribute if (self::CREATE === $attribute) { return $this->voterHelper->voteOnAttribute(self::CREATE_ACCOMPANYING_COURSE, $subject, $token); } } elseif ($subject instanceof Person) { // transform the attribute if (self::CREATE === $attribute) { return $this->voterHelper->voteOnAttribute(self::CREATE_PERSON, $subject, $token); } } return $this->voterHelper->voteOnAttribute($attribute, $subject, $token); } }