src/Security/Voters/Olympiad/ParticipantVoter.php line 14
<?phpnamespace App\Security\Voters\Olympiad;use App\Entity\Common\Country;use App\Entity\Olympiad\Online\Participant;use App\Entity\Olympiad\Online\Participant\Result;use App\Service\Olympiads\Online\MoodleCourseChooser;use Doctrine\ORM\EntityManagerInterface;use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;use Symfony\Component\Security\Core\Authorization\Voter\Voter;use Symfony\Component\Security\Core\Security;class ParticipantVoter extends Voter{public const EDIT_PARTICIPANT = 'participant_edit';public const PARTICIPANT_APPLY_TEST = 'participant_apply_test';public const PARTICIPANT_VIEW_RESULT = 'participant_view_result';public const PARTICIPANT_VIEW_APPLY_TEST = 'participant_view_apply_test';public const VIEW_PARTICIPANT = 'participant_view';private Security $security;private EntityManagerInterface $em;private MoodleCourseChooser $moodleCourseChooser;public function __construct(Security $security, EntityManagerInterface $em, MoodleCourseChooser $moodleCourseChooser){$this->security = $security;$this->em = $em;$this->moodleCourseChooser = $moodleCourseChooser;}/*** Determines if the attribute and subject are supported by this voter.** @param string $attribute An attribute* @param mixed $subject The subject to secure, e.g. an object the user wants to access or any other PHP type** @return bool True if the attribute and subject are supported, false otherwise*/protected function supports($attribute, $subject): bool{if (!in_array($attribute, [self::EDIT_PARTICIPANT, self::VIEW_PARTICIPANT, self::PARTICIPANT_APPLY_TEST, self::PARTICIPANT_VIEW_APPLY_TEST, self::PARTICIPANT_VIEW_RESULT])) {return false;}// only vote on Post objects inside this voterif (!$subject instanceof Participant) {return false;}return true;}/*** Perform a single access check operation on a given attribute, subject and token.* It is safe to assume that $attribute and $subject already passed the "supports()" method check.** @param string $attribute* @param Participant $subject* @param TokenInterface $token** @return bool*/protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool{switch ($attribute) {case self::EDIT_PARTICIPANT:return ($subject->getState() == $subject::STATE_NEW&& false == $subject->isCanceled()&& $subject->getUser() == $token->getUser());case self::VIEW_PARTICIPANT:return $subject->getUser() == $token->getUser();case self::PARTICIPANT_APPLY_TEST:return $this->isApplyTest($subject, $token);case self::PARTICIPANT_VIEW_APPLY_TEST:return $this->isViewApplyTest($subject, $token);case self::PARTICIPANT_VIEW_RESULT:return $this->isViewResult($subject, $token);}throw new \LogicException('This code should not be reached!');}/*** @param Participant $subject* @param TokenInterface $token* @return bool*/protected function isApplyTest(Participant $subject, TokenInterface $token): bool{/*$correctState = $subject->getState() == $subject::STATE_SEND && $subject->isCanceled() == false && $subject->isConfirmed() == true;$correctUser = $subject->getUser() == $token->getUser();$correctTime = false;$now = new \DateTime();if ($subject->getDirection()->getTestTime()->getFrom() <= $now && $subject->getDirection()->getTestTime()->getTo() >= $now) {$correctTime = true;}return ($correctState && $correctUser && $correctTime)||$this->security->isGranted('ROLE_ADMIN');*/$correctState = $subject->isCanceled() == false && $this->isParticipantActiveState($subject);$correctUser = $subject->getUser() == $token->getUser();// $direction = $subject->getDirection();$moodleCourse = $this->moodleCourseChooser->choose($subject);if (!$moodleCourse) {return false;}// dump($moodleCourse);/* if ($direction->getTestTime()->getFrom() <= $now && $direction->getTestTime()->getTo() >= $now) {}*/$rulesCheck = $this->checkDirectionRules($subject);/* $regionCorrect = false;if ($direction->getId() == 1) {$regionCorrect = true;} elseif ($direction->getId() == 2) {if ($subject->getCountry()&& $subject->getCountry()->getId() == 173&& $subject->getRegion()&& $subject->getRegion()->getDistrict()->getId() == 1) {$regionCorrect = true;}}*/return ($correctState && $correctUser && $rulesCheck /*&& $regionCorrect*/) || $this->security->isGranted('ROLE_TEST_ANY_TIME');}/*** @param Participant $subject* @return bool*/protected function isParticipantActiveState(Participant $subject): bool{return in_array($subject->getState(), [Participant::STATE_ACCEPTED, Participant::STATE_SEND, Participant::STATE_NEW]);}/*** @param Participant $subject* @return bool*/private function checkDirectionRules(Participant $subject): bool{$direction = $subject->getDirection();if ($direction->getApplyAllow() & $direction::APPLY_BY_TEST_TIME) {$now = new \DateTime();if ($direction->getTestTime()->getFrom() > $now || $direction->getTestTime()->getTo() < $now) {return false;}// if ($direction->getTestTime()->getFrom() <= $now && $direction->getTestTime()->getTo() >= $now) {//// } else return false;}return $this->checkUserAccess($subject);}/*** @param \App\Entity\Olympiad\Online\Direction|null $direction* @param Participant $subject* @return bool*/private function checkUserAccess(Participant $subject): bool{$direction = $subject->getDirection();if ($direction->getApplyAllow() & $direction::APPLY_IMPLICIT) {if (false == $subject->isApplyAllow()) {return false;}}if ($direction->getApplyAllow() & $direction::APPLY_RULE_RUSSIAN) {$country = $subject->getCountry();if (!$country || $country->getId() != Country::C_RUSSIA) {return false;}}if ($direction->getApplyAllow() & $direction::APPLY_RULE_REGION_CFO) {if (false == $this->checkDistrict($subject, 1)) {return false;}}return true;}private function checkDistrict(Participant $participant, int $districtId): bool{$region = $participant->getRegion();if (!$region || !$region->getDistrict()) {return false;}return $region->getDistrict()->getId() == $districtId;}/*** @param Participant $subject* @param TokenInterface $token* @return bool*/protected function isViewApplyTest(Participant $subject, TokenInterface $token): bool{/*$corretState = $subject->getState() == $subject::STATE_SEND && $subject->isCanceled() == false && $subject->isConfirmed() == true;$correctUser = $subject->getUser() == $token->getUser();$correctTime = false;$now = new \DateTime();if ($subject->getDirection()->getTestTime()->getFrom() <= $now && $subject->getDirection()->getTestTime()->getTo() >= $now) {$correctTime = true;}return ($corretState && $correctUser && $correctTime)||$this->security->isGranted('ROLE_ADMIN');*/$corretState = $subject->isCanceled() == false && $this->isParticipantActiveState($subject);$correctUser = $subject->getUser() == $token->getUser();$moodleCourse = $this->moodleCourseChooser->choose($subject);if (!$moodleCourse) {return false;}$userAccess = $this->checkUserAccess($subject);/* $regionCorrect = false;if ($direction->getId() == 1) {$regionCorrect = true;} elseif ($direction->getId() == 2) {if ($subject->getCountry()&& $subject->getCountry()->getId() == 173&& $subject->getRegion()&& $subject->getRegion()->getDistrict()->getId() == 1) {$regionCorrect = true;}}*/return ($corretState && $correctUser && $userAccess/* && $regionCorrect*/) || $this->security->isGranted('ROLE_TEST_ANY_TIME');}private function isViewResult(Participant $subject, TokenInterface $token): bool{$resultRepo = $this->em->getRepository(Result::class);$result = $resultRepo->find($subject);return !!$result;}}