diff --git a/src/Controller/Teamer/Application/CreateController.php b/src/Controller/Teamer/Application/CreateController.php index 6070167..ab82d55 100644 --- a/src/Controller/Teamer/Application/CreateController.php +++ b/src/Controller/Teamer/Application/CreateController.php @@ -31,6 +31,27 @@ class CreateController extends AbstractController /** @var User $user */ $user = $this->getUser(); $teamer = $user->getTeamer(); + + // Only allow applications on empty slots + $availableSlots = (int) $assignment->getAvailableDispositions(); + if (0 < $availableSlots) { + $this->addFlash('error', 'Auf diesem Einsatz sind bereits alle Plätze belegt'); + + return $this->redirectToRoute('app_teamer_index'); + } + + // Only teamers without existing applications may apply to the assignment + $existingApplication = $this + ->entityManager + ->getRepository(Application::class) + ->findOneBy(['teamer' => $teamer, 'assignment' => $assignment]); + + if (null !== $existingApplication) { + $this->addFlash('error', 'Du hast dich bereits auf diesen Einsatz beworben'); + + return $this->redirectToRoute('app_teamer_index'); + } + $application = new Application($assignment, $teamer); $form = $this->createForm(TeamerApplicationType::class, $application); diff --git a/src/Security/Voter/AssignmentVoter.php b/src/Security/Voter/AssignmentVoter.php index 6395513..fa14f8e 100644 --- a/src/Security/Voter/AssignmentVoter.php +++ b/src/Security/Voter/AssignmentVoter.php @@ -2,10 +2,7 @@ namespace App\Security\Voter; -use App\Entity\Application; use App\Entity\Assignment; -use App\Entity\User; -use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; @@ -18,10 +15,8 @@ class AssignmentVoter extends Voter public const PUBLISH = 'PUBLISH'; public const CALL_OFF = 'CALL_OFF'; - public function __construct( - private readonly Security $security, - private readonly EntityManagerInterface $entityManager, - ) { + public function __construct(private readonly Security $security) + { } protected function supports(string $attribute, mixed $subject): bool @@ -30,65 +25,31 @@ class AssignmentVoter extends Voter return false; } - return in_array($attribute, [static::VIEW, static::EDIT, static::APPLY, static::PUBLISH, static::CALL_OFF]); + return in_array($attribute, [self::VIEW, self::EDIT, self::APPLY, self::PUBLISH, self::CALL_OFF], true); } protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool { - /** @var Assignment $assignment */ - $assignment = $subject; - - // All authenticated users may view assignments - if (static::VIEW === $attribute && null !== $token->getUser()) { - return true; - } - - // Only users with administrative role may edit assignments - if (static::EDIT === $attribute) { - return $this->security->isGranted('ROLE_ADMINISTRATIVE'); - } - - // Only users with administrative role may publish assignments currently in draft - if (static::PUBLISH === $attribute) { - return Assignment::STATUS_DRAFT === $assignment->getStatus() - && $this->security->isGranted('ROLE_ADMINISTRATIVE'); - } - - // Only users with administrative role may call off assignments - if (static::CALL_OFF === $attribute) { - return Assignment::STATUS_CALLED_OFF !== $assignment->getStatus() - && $this->security->isGranted('ROLE_ADMINISTRATIVE'); - } - - // Only allow applications to published, not deleted and not called off assignments - if ( - true === in_array($assignment->getStatus(), [ - Assignment::STATUS_DRAFT, - Assignment::STATUS_DELETED, - Assignment::STATUS_CALLED_OFF, - ])) { + if (null === $token->getUser()) { return false; } - // Only allow applications on empty slots - $availableSlots = (int) $assignment->getAvailableDispositions(); - if (0 < $availableSlots) { - return $assignment->getDispositions()->count() < $availableSlots; - } + /** @var Assignment $assignment */ + $assignment = $subject; - // Only teamers without existing applications may apply to the assignment - if ($this->security->isGranted('ROLE_TEAMER')) { - /** @var User $user */ - $user = $token->getUser(); - $teamer = $user->getTeamer(); - $application = $this - ->entityManager - ->getRepository(Application::class) - ->findOneBy(['teamer' => $teamer, 'assignment' => $assignment]); - - return null === $application; - } - - return false; + return match ($attribute) { + self::VIEW => true, + self::EDIT => $this->security->isGranted('ROLE_ADMINISTRATIVE'), + self::PUBLISH => Assignment::STATUS_DRAFT === $assignment->getStatus() + && $this->security->isGranted('ROLE_ADMINISTRATIVE'), + self::CALL_OFF => Assignment::STATUS_CALLED_OFF !== $assignment->getStatus() + && $this->security->isGranted('ROLE_ADMINISTRATIVE'), + self::APPLY => false === in_array($assignment->getStatus(), [ + Assignment::STATUS_DRAFT, + Assignment::STATUS_DELETED, + Assignment::STATUS_CALLED_OFF, + ], true), + default => false, + }; } }