<?php
namespace App\Security;
use App\Entity\Enrollment;
use App\Entity\Module;
use App\Entity\User;
use App\Repository\EnrollmentRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* Checks if a user is able to access a given module.
*/
class StudentModuleAccessVoter extends Voter
{
private EnrollmentRepository $enrollmentRepository;
public function __construct(EnrollmentRepository $enrollmentRepository)
{
$this->enrollmentRepository = $enrollmentRepository;
}
protected function supports(string $attribute, $subject): bool
{
if (!$subject instanceof Module) {
return false;
}
return true;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof User) {
// must be logged in
return false;
}
// confirmed $subject is a Course object, thanks to `supports()`
/** @var Module $module */
$module = $subject;
$enrollments = $this->enrollmentRepository->findBy(['student' => $user->getId()]);
$enrolledModuleIds = array_map(function(Enrollment $enrollment) {
return $enrollment->getModule()->getId();
}, $enrollments);
if (!in_array($module->getId(), $enrolledModuleIds)) {
return false;
}
return true;
}
}