src/Security/Voter/DocumentVoter.php line 13
<?php
namespace App\Security\Voter;
use App\Entity\Document;
use App\Enum\RoleType;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;
use function PHPUnit\Framework\isInstanceOf;
class DocumentVoter extends Voter
{
public const EDIT = 'DOCUMENT_EDIT';
public const SHOW = 'DOCUMENT_SHOW';
public const DELETE = 'DOCUMENT_DELETE';
private $security;
public function __construct(Security $security)
{
$this->security = $security;
}
protected function supports(string $attribute, mixed $subject): bool
{
// dd($subject);
return in_array($attribute, [self::EDIT, self::SHOW, self::DELETE]) &&
isInstanceOf(Document::class);
}
/**
* @param string $attribute
* @param array $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof UserInterface) {
return false;
}
/**
* @var $isRelated bool controls if the document belongs to the student or parent
* @var $allow bool controls if the user is allowed to access the document
* both variables will help determine who can access the document
*/
$isRelated = false;
$allow = false;
// Who it belongs to:
// Does it belong to a student?
if ($subject['document']->getStudent()) {
// does it belong to the student itself?
if ($subject['document']->getStudent()->getId() === $subject['id']) {
$isRelated = true;
// Who can access it
// Currently only the guardian who made the document can access it
// When Parent and Student are associated to User, they should be able to access their related documents
// Is the user the guardian who made this document?
if ($user === $subject['document']->getStudent()->getGuardian()->getUser()) {
$allow = true;
}
}
} // Does it belong to a parent?
elseif ($subject['document']->getParentalDocument()) {
// does it belong to the parent itself?
if ($subject['document']->getParentalDocument()->getParentData()->getId() === $subject['id']) {
$isRelated = true;
// Is the user the guardian who made this document?
if ($user === $subject['document']->getParentalDocument()->getParentData()->getGuardian()->getUser()) {
$allow = true;
}
}
} else
return false;
$accessIsGranted = match ($attribute) {
'DOCUMENT_SHOW' =>
$allow
||
$isRelated && (
$this->security->isGranted(RoleType::ROLE_ADMIN) ||
$this->security->isGranted(RoleType::ROLE_EMPLOYEE) ||
$this->security->isGranted(RoleType::ROLE_FINANCIAL_DIRECTOR) ||
$this->security->isGranted(RoleType::ROLE_PEDAGOGICAL_DIRECTOR)
),
'DOCUMENT_EDIT' =>
$allow
||
$isRelated && $this->security->isGranted(RoleType::ROLE_ADMIN),
'DOCUMENT_DELETE' => $isRelated && $this->security->isGranted(RoleType::ROLE_ADMIN),
};
return $accessIsGranted;
}
}