src/Order/Security/Voter/OrderVoter.php line 16

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Order\Security\Voter;
  4. use App\Program\Doctrine\Entity\Program;
  5. use App\Order\Doctrine\Entity\Order;
  6. use App\Security\Doctrine\Entity\User;
  7. use App\Security\Security\Store\Roles;
  8. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  9. use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
  10. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  11. use Symfony\Component\Workflow\WorkflowInterface;
  12. final class OrderVoter extends Voter
  13. {
  14.     public const CANCEL 'cancel';
  15.     public const PREPARE 'prepare';
  16.     public const PROCESS 'process';
  17.     public const SHIP 'ship';
  18.     public const DELIVER 'deliver';
  19.     public const ITEM 'item';
  20.     public function __construct(
  21.         private WorkflowInterface $orderStateMachine,
  22.         private AccessDecisionManagerInterface $accessDecisionManager
  23.     ) {
  24.     }
  25.     protected function supports(string $attributemixed $subject): bool
  26.     {
  27.         return $subject instanceof Order
  28.             && in_array($attribute, [self::ITEMself::CANCELself::PREPAREself::PROCESSself::SHIPself::DELIVER], true);
  29.     }
  30.     protected function voteOnAttribute(string $attributemixed $subjectTokenInterface $token): bool
  31.     {
  32.         /** @var Order $order */
  33.         $order $subject;
  34.         if (($program $token->getUser()) instanceof Program) {
  35.             return $attribute === self::ITEM && $order->getAccount()->getProfile()->getProgram() === $program;
  36.         }
  37.         if (!($user $token->getUser()) instanceof User) {
  38.             return false;
  39.         }
  40.         return match ($attribute) {
  41.             self::DELIVER => $this->accessDecisionManager->decide($token, [Roles::ORDER_PROCESS])
  42.                 && $this->orderStateMachine->getMarking($order)->has('prepared')
  43.                 && $order->getDetailsToDeliver()->count() > 0,
  44.             self::SHIP => $this->accessDecisionManager->decide($token, [Roles::ORDER_PROCESS])
  45.                 && $this->orderStateMachine->getMarking($order)->has('prepared')
  46.                 && $order->getDetailsToShip()->count() > 0,
  47.             self::PROCESS => $this->accessDecisionManager->decide($token, [Roles::ORDER_PROCESS])
  48.                 && $this->orderStateMachine->getMarking($order)->has('prepared')
  49.                 && $order->getDetailsToProcess()->count() > 0,
  50.             self::PREPARE => $this->orderStateMachine->can($orderself::PREPARE)
  51.                 && $this->accessDecisionManager->decide($token, [Roles::ORDER_PREPARE]),
  52.             self::CANCEL => !$this->orderStateMachine->getMarking($order)->has('pending')
  53.                 && $this->accessDecisionManager->decide($token, [Roles::ORDER_CANCEL]),
  54.             default => false
  55.         };
  56.     }
  57. }