<?php
namespace App\Security\Voter;
use App\Entity\RequestBase;
use App\Entity\RequestBaseProposals;
use App\Entity\User;
use App\Enum\RequestsNotificationsEnum;
use App\Enum\UserEnum;
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;
class RequestBaseVoter extends Voter
{
public const READ = "READ";
public const DELETE = "DELETE";
/**
* @var Security
*/
private $security;
public function __construct(Security $security)
{
$this->security = $security;
}
protected function supports($attribute, $subject)
{
$attributesSupported = [
self::READ,
self::DELETE
];
if (!in_array($attribute, $attributesSupported)) {
return false;
}
if (!$subject instanceof RequestBase) {
return false;
}
return true;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
/** @var User $user */
$user = $token->getUser();
if (!$user instanceof UserInterface) {
return false;
}
if ($this->security->isGranted(UserEnum::SUPER_ADMIN)) {
return true;
}
switch ($attribute) {
case self::READ:
return $this->canRead($user, $subject);
break;
case self::DELETE:
return $this->canDelete($user, $subject);
break;
}
return false;
}
private function canRead(User $currentUser, RequestBase $subject): bool
{
$requestIsWaitProposal = $subject->getStatus() === RequestsNotificationsEnum::REQUEST_WAITING_PROPOSAL;
$requestIsInProgress = $subject->getStatus() === RequestsNotificationsEnum::REQUEST_IN_PROGRESS;
$requestIsClosed = $subject->getStatus() === RequestsNotificationsEnum::REQUEST_CLOSED;
$requestIsRefused = $subject->getStatus() === RequestsNotificationsEnum::REQUEST_REFUSED;
if ($currentUser->isTeacher()) {
if ($requestIsWaitProposal) {
/** @var RequestBaseProposals[] $teacherProposalEntity */
$teacherProposalEntities = $subject->getRequestBaseProposals()->filter(function (RequestBaseProposals $requestProposal) use ($currentUser) {
return $requestProposal->getCorrector()->getId() === $currentUser->getId();
});
$teacherProposalEntity = $teacherProposalEntities->isEmpty() ? null : $teacherProposalEntities->first();
if ($teacherProposalEntity && $teacherProposalEntity->getStatus() !== RequestBaseProposals::STATUS_REFUSE) {
return true;
}
return false;
}
if(!$subject->getTeacher()) {
return false;
}
else {
return ($requestIsInProgress || $requestIsClosed || $requestIsRefused) && $currentUser->getId() === $subject->getTeacher()->getId();
}
}
if ($currentUser->isStudent()) {
return $currentUser->getId() === $subject->getStudent()->getId();
}
return false;
}
private function canDelete(User $currentUser, RequestBase $subject): bool
{
return $currentUser->getId() === $subject->getStudent()->getId();
}
}