<?php
namespace App\Security;
use App\Entity\Collaborator;
use App\Entity\Project\Task;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
class TaskVoter extends Voter
{
const VIEW = 'view';
const NEW = 'new';
const EDIT = 'edit';
private $security;
private $translator;
public function __construct(Security $security,TranslatorInterface $translator)
{
$this->security = $security;
$this->translator=$translator;
}
protected function supports(string $attribute, $subject): bool
{
// if the attribute isn't one we support, return false
if (!in_array($attribute, [self::VIEW, self::EDIT, self::NEW])) {
return false;
}
// only vote on `Task` objects
if (!$subject instanceof Task) {
return false;
}
return true;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$collaborator = $token->getUser()->getCollaborator();
if (!$collaborator instanceof Collaborator) {
return false;
}
// you know $subject is a Task object, thanks to `supports()`
/** @var Task $task */
$task = $subject;
switch ($attribute) {
case self::VIEW:
return $this->canView($task, $collaborator);
case self::EDIT:
return $this->canEdit($task, $collaborator);
case self::NEW:
return $this->canNew($task, $collaborator);
}
throw new \LogicException('This code should not be reached!');
}
private function canView(Task $task, Collaborator $collaborator): bool
{
if($project=$task->getProject()){
if(
!$this->isGranted('ROLE_ADMIN')
and !in_array($collaborator,$project->getCollaborators()->toArray())
and $task->getManager()!=$collaborator
){
return false;
}
}else{
if(
!$this->isGranted('ROLE_ADMIN')
and !in_array($collaborator,$task->getCollaborators()->toArray())
and $task->getManager()!=$collaborator
){
return false;
}
}
return true;
}
private function canEdit(Task $task, Collaborator $collaborator): bool
{
if(
!$this->isGranted('ROLE_ADMIN')
and $task->getManager()!=$collaborator
){
return false;
}
return true;
}
private function canNew(Task $task, Collaborator $collaborator): bool
{
if(
!$this->isGranted('ROLE_ADMIN')
and !$this->isGranted('ROLE_MANAGER_RH')
){
return false;
}
return true;
}
private function isGranted($role)
{
return $this->security->isGranted($role);
}
}