manager = $manager; $this->security = $security; } protected function supports($attribute, $subject) { return $subject instanceof EntityWorkflow && in_array($attribute, self::getRoles(), true); } /** * @param EntityWorkflow $subject * @param mixed $attribute */ protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool { switch ($attribute) { case self::CREATE: case self::SEE: $handler = $this->manager->getHandler($subject); $entityAttribute = $handler->getRoleShow($subject); if (null === $entityAttribute) { return true; } $relatedEntity = $handler->getRelatedEntity($subject); if (null === $relatedEntity) { return true; } if ($this->security->isGranted($entityAttribute, $relatedEntity)) { return true; } foreach ($subject->getSteps() as $step) { if ($step->getAllDestUser()->contains($token->getUser())) { return true; } } return false; case self::DELETE: return $subject->getStep() === 'initial'; case self::SHOW_ENTITY_LINK: if ($subject->getStep() === 'initial') { return false; } $currentStep = $subject->getCurrentStepChained(); if ($currentStep->isFinal()) { return false; } return $currentStep->getPrevious()->getTransitionBy() === $this->security->getUser(); default: throw new UnexpectedValueException("attribute {$attribute} not supported"); } } private static function getRoles(): array { return [ self::SEE, self::CREATE, self::DELETE, self::SHOW_ENTITY_LINK, ]; } }