<?phpnamespace App\Security\Voter;use App\Entity\AbstractCollaborator;use App\Entity\Mandate;use App\Entity\PropertyVisitVoucher;use App\Entity\Reference\ReferenceMandateStatus;use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;use Symfony\Component\Security\Core\Authorization\Voter\Voter;use Symfony\Component\Security\Core\Security;use Symfony\Component\Security\Core\User\UserInterface;use Exception;class PropertyVisitVoucherVoter extends Voter{ public const POST = 'POST'; public const PUT = 'PUT'; public const DELETE = 'DELETE'; public const GET = 'GET'; /** * @var Security */ private Security $security; /** * @param Security $security */ public function __construct(Security $security) { $this->security = $security; } protected function supports(string $attribute, $subject) { return in_array( $attribute, [self::POST, self::PUT, self::DELETE, self::GET], true ) && $subject instanceof PropertyVisitVoucher; } /** * @throws Exception */ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token) { /** @var UserInterface $user */ $user = $this->security->getUser(); // Deny anonymous users if (!$user instanceof UserInterface) { return false; } $mandates = $subject->getMandates(); /** @var PropertyVisitVoucher $subject */ switch ($attribute) { case self::DELETE: if ( $subject->getCreatedBy() === $user->getId() && $this->security->isGranted(AbstractCollaborator::ROLE_AGENT) ) { return true; } break; case self::PUT: foreach ($mandates as $mandate) { if ( $this->isHaveValidMandate($mandate) && $this->security->isGranted(AbstractCollaborator::ROLE_AGENT) && $subject->getCreatedBy() === $user->getId() ) { return true; } } break; case self::GET: if ( $subject->getCreatedBy() === $user->getId() && $this->security->isGranted(AbstractCollaborator::ROLE_AGENT) ) { return true; } break; case self::POST: foreach ($mandates as $mandate) { if ($this->isHaveValidMandate($mandate)) { return true; } } return false; } throw new Exception(sprintf('Unhandled attribute "%s"', $attribute)); } public function isHaveValidMandate(Mandate $mandate): bool { if ( !($mandate->getReferenceMandateStatus()->getCode( ) === ReferenceMandateStatus::REFERENCE_CODE_MANDATE_STATUS_VALID || $mandate->getReferenceMandateStatus()->getCode( ) === ReferenceMandateStatus::REFERENCE_CODE_MANDATE_STATUS_RESERVED) ) { return false; } return true; }}