voterHelper = $voterHelperFactory ->generate(self::class) ->addCheckFor(AccompanyingCourseDocument::class, $this->getRoles()) ->addCheckFor(AccompanyingPeriod::class, [self::SEE, self::CREATE]) ->build(); } public function getRoles(): array { return [ self::CREATE, self::SEE, self::SEE_DETAILS, self::UPDATE, self::DELETE, ]; } public function getRolesWithHierarchy(): array { return ['accompanyingCourseDocument' => $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 AccompanyingPeriod) { if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { if (self::CREATE === $attribute) { return false; } } } elseif ($subject instanceof AccompanyingCourseDocument) { if (!$this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject->getCourse())) { return false; } if ( AccompanyingPeriod::STEP_CLOSED === $subject->getCourse()->getStep() && \in_array($attribute, [self::CREATE, self::DELETE, self::UPDATE], true) ) { return false; } if (self::CREATE === $attribute && null !== $subject->getCourse()) { return $this->voterHelper->voteOnAttribute($attribute, $subject->getCourse(), $token); } } return $this->voterHelper->voteOnAttribute($attribute, $subject, $token); } }