src/V4/Voters/TaskVoter.php line 18

Open in your IDE?
  1. <?php
  2. namespace App\V4\Voters;
  3. use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
  4. use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
  5. use App\Model\ModuleConfiguration\ModuleConfiguration;
  6. use App\Security\SecurityConfig;
  7. use App\Security\User;
  8. use App\V4\Enum\Tag\TagConfigEnum;
  9. use App\V4\Model\Task\Task;
  10. use App\V4\Repository\TaskTagRepository;
  11. use LogicException;
  12. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  13. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  14. use Symfony\Component\Security\Core\Security;
  15. class TaskVoter extends Voter
  16. {
  17.     public const TASK_MANAGE_LIST 'task_manage_list';
  18.     public const TASK_SHOW_LIST 'task_show_list';
  19.     public const TASK_ADD_EDIT 'task_add_edit';
  20.     public const TASK_MANAGE_FIELDS 'task_manage_fields';
  21.     public const TASK_STATE_ADD_EDIT 'task_state_add_edit';
  22.     public const CAN_CHANGE_TASK_STATUS 'can_change_task_status';
  23.     /**
  24.      * @var Security
  25.      */
  26.     private $security;
  27.     /**
  28.      * @var TaskTagRepository
  29.      */
  30.     private $taskTagRepository;
  31.     /**
  32.      * @var CollectionDataProviderInterface
  33.      */
  34.     private $collectionDataProvider;
  35.     public function __construct(
  36.         Security                        $security,
  37.         TaskTagRepository               $taskTagRepository,
  38.         CollectionDataProviderInterface $collectionDataProvider
  39.     ) {
  40.         $this->security $security;
  41.         $this->taskTagRepository $taskTagRepository;
  42.         $this->collectionDataProvider $collectionDataProvider;
  43.     }
  44.     /**
  45.      * @param $attribute
  46.      * @param $subject
  47.      *
  48.      * @return bool
  49.      */
  50.     protected function supports($attribute$subject): bool
  51.     {
  52.         return in_array($attribute, [
  53.             self::TASK_MANAGE_LIST,
  54.             self::TASK_SHOW_LIST,
  55.             self::TASK_ADD_EDIT,
  56.             self::TASK_MANAGE_FIELDS,
  57.             self::TASK_STATE_ADD_EDIT,
  58.             self::CAN_CHANGE_TASK_STATUS,
  59.         ], true);
  60.     }
  61.     /**
  62.      * @param $attribute
  63.      * @param $subject
  64.      * @param TokenInterface $token
  65.      *
  66.      * @return bool
  67.      *
  68.      * @throws LogicException
  69.      */
  70.     protected function voteOnAttribute($attribute$subjectTokenInterface $token): bool
  71.     {
  72.         $user $token->getUser();
  73.         if (!$user instanceof User) {
  74.             return false;
  75.         }
  76.         switch ($attribute) {
  77.             case self::TASK_MANAGE_LIST:
  78.                 return $this->canTaskManageList();
  79.             case self::TASK_SHOW_LIST:
  80.                 return $this->canTaskShowList();
  81.             case self::TASK_ADD_EDIT:
  82.                 return $this->canTaskAddEdit();
  83.             case self::TASK_MANAGE_FIELDS:
  84.                 return $this->canTaskManageFields();
  85.             case self::TASK_STATE_ADD_EDIT:
  86.                 return $this->canTaskStateAddEdit();
  87.             case self::CAN_CHANGE_TASK_STATUS:
  88.                 return $this->canOpenCloseTask($user$subject);
  89.         }
  90.         throw new LogicException('This should never happen');
  91.     }
  92.     private function canTaskManageList(): bool
  93.     {
  94.         return $this->canAccessTask();
  95.     }
  96.     private function canTaskShowList(): bool
  97.     {
  98.         return $this->canAccessTask();
  99.     }
  100.     private function canTaskAddEdit(): bool
  101.     {
  102.         return $this->canAccessTask();
  103.     }
  104.     private function canTaskManageFields(): bool
  105.     {
  106.         return $this->canAccessTask();
  107.     }
  108.     private function canTaskStateAddEdit(): bool
  109.     {
  110.         return $this->canAccessTask();
  111.     }
  112.     /**
  113.      * @TODO: Si le client n'a pas le droit "task show", il peut tout de même voir les actions qu'il gère.
  114.      *
  115.      * @return bool
  116.      */
  117.     private function canAccessTask(): bool
  118.     {
  119.         return true;
  120.     }
  121.     private function canUseModuleTag(User $user): bool
  122.     {
  123.         return in_array(SecurityConfig::MODULE_TAG$user->getRoles(), true);
  124.     }
  125.     /**
  126.      * @throws ResourceClassNotSupportedException
  127.      */
  128.     private function canOpenCloseTask(User $user$task): bool
  129.     {
  130.         if (!$this->canUseModuleTag($user)) {
  131.             return true;
  132.         }
  133.         if (!$task instanceof Task) {
  134.             return false;
  135.         }
  136.         $moduleConfigs $this->collectionDataProvider->getCollection(ModuleConfiguration::class, null, [
  137.             'filters' => [
  138.                 'moduleId' => SecurityConfig::MODULE_TAG,
  139.                 'keyConf' => TagConfigEnum::CRM_TASK_PREVENT_CLOSING_WHEN_TAG_UNCLOSED,
  140.             ],
  141.         ]);
  142.         if (!== count($moduleConfigs) || "true" !== $moduleConfigs[0]->getValue()) {
  143.             return true;
  144.         }
  145.         $tags $this->taskTagRepository->findBy(['taskId' => $task->getId()]);
  146.         foreach ($tags as $tag) {
  147.             if (!$tag->getDone()) {
  148.                 return false;
  149.             }
  150.         }
  151.         return true;
  152.     }
  153. }