<?php
namespace App\Security\Voter;
use App\Entity\LearningAgreement;
use App\Entity\User;
use App\HeiAdministration\StaffDirectory;
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 LearningAgreementVoter extends Voter
{
public const VIEW = 'LA_VIEW';
public const ADMIN = 'LA_ADMIN';
public const SENDING_ACCEPT = 'LA_SENDING_ACCEPT';
public const SENDING_REJECT = 'LA_SENDING_REJECT';
public const RECEIVING_ACCEPT = 'LA_RECEIVING_ACCEPT';
public const RECEIVING_REJECT = 'LA_RECEIVING_REJECT';
public const STUDENT_SUBMIT = 'LA_STUDENT_SUBMIT';
private Security $security;
private StaffDirectory $staffDirectory;
public function __construct(
Security $security,
StaffDirectory $staffDirectory,
) {
$this->security = $security;
$this->staffDirectory = $staffDirectory;
}
protected function supports(string $attribute, mixed $subject): bool
{
return in_array($attribute, [
self::VIEW,
self::ADMIN,
self::SENDING_ACCEPT,
self::SENDING_REJECT,
self::RECEIVING_ACCEPT,
self::RECEIVING_REJECT,
self::STUDENT_SUBMIT,
])
&& $subject instanceof LearningAgreement
;
}
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
/**
* @var User $user
*/
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof UserInterface) {
return false;
}
if ($this->security->isGranted('ROLE_SUPER_ADMIN')) {
return true;
}
$student = $user->getStudent();
$isCorrectStudent = null !== $student && $subject->getStudent() === $student;
switch ($attribute) {
case self::VIEW:
return
$this->staffDirectory->isStaffAtSendingHei($user, $subject)
|| $this->staffDirectory->isStaffAtReceivingHei($user, $subject)
|| (
$isCorrectStudent
);
case self::ADMIN:
case self::STUDENT_SUBMIT:
return $isCorrectStudent;
case self::SENDING_ACCEPT:
case self::SENDING_REJECT:
return $this->staffDirectory->isStaffAtSendingHei($user, $subject);
case self::RECEIVING_ACCEPT:
case self::RECEIVING_REJECT:
return $this->staffDirectory->isStaffAtReceivingHei($user, $subject);
}
return false;
}
}