<?php
namespace App\Security;
use App\Entity\Course;
use App\Entity\Enrollment;
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 course.
*/
class StudentCourseAccessVoter extends Voter
{
private EnrollmentRepository $enrollmentRepository;
public function __construct(EnrollmentRepository $enrollmentRepository)
{
$this->enrollmentRepository = $enrollmentRepository;
}
protected function supports(string $attribute, $subject): bool
{
if (!$subject instanceof Course) {
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 Course $course */
$course = $subject;
$enrollments = $this->enrollmentRepository->findBy(['student' => $user->getId()]);
$enrolledCourseIds = array_map(function(Enrollment $enrollment) {
return $enrollment->getModule()->getCourse()->getId();
}, $enrollments);
if (!in_array($course->getId(), $enrolledCourseIds)) {
return false;
}
return true;
}
}