<?php
namespace App\Security;
use App\Entity\Collaborator;
use App\Entity\RH\Absence;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
class AbsenceVoter extends Voter
{
const VIEW = 'view';
const EDIT = 'edit';
const CHANGE_STATUS_PENDING = 'changeStatus'.Absence::PENDING;
const CHANGE_STATUS_VALID = 'changeStatus'.Absence::VALID;
const CHANGE_STATUS_REFUSED = 'changeStatus'.Absence::REFUSED;
const CHANGE_STATUS_CANCELLED = 'changeStatus'.Absence::CANCELLED;
const EDIT_MANAGER_COMMENT = 'canEditManagerComment';
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::EDIT_MANAGER_COMMENT, self::CHANGE_STATUS_PENDING,self::CHANGE_STATUS_REFUSED,self::CHANGE_STATUS_VALID,self::CHANGE_STATUS_CANCELLED])) {
return false;
}
// only vote on `Absence` objects
if (!$subject instanceof Absence) {
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 Absence object, thanks to `supports()`
/** @var Absence $absence */
$absence = $subject;
switch ($attribute) {
case self::VIEW:
return $this->canView($absence, $collaborator);
case self::CHANGE_STATUS_PENDING:
case self::CHANGE_STATUS_REFUSED:
case self::CHANGE_STATUS_VALID:
case self::CHANGE_STATUS_CANCELLED:
return $this->canChangeStatus($absence, $collaborator,$attribute);
case self::EDIT:
return $this->canEdit($absence, $collaborator);
case self::EDIT_MANAGER_COMMENT:
return $this->canEditManagerComment($absence,$collaborator);
}
throw new \LogicException('This code should not be reached!');
}
private function canView(Absence $absence, Collaborator $collaborator): bool
{
if(
!$this->isGranted('ROLE_ADMIN')
and !$this->isGranted('ROLE_ASSISTANT_RH')
and $absence->getCollaborator()!=$collaborator
and !in_array($absence->getCollaborator(),$collaborator->getAllListNMoins()->toArray())
){
return false;
}
return true;
}
private function canChangeStatus(Absence $absence, Collaborator $collaborator,$attribute): bool
{
if (!$this->canView($absence,$collaborator))return false;
/*
si statut existant => PENDING
=>VALID/REFUSED =>MANAGER ASSISTANT RH OU ADMIN
=>CANCEL => TOUS
*/
/*
si statut existant => VALID
=>CANCEL => ASSISTANT RH OU ADMIN
*/
/*
si statut existant => REFUSED
=>RIEN
*/
/*
si statut existant => CANCELLED
=>RIEN
*/
$new_status=str_replace('changeStatus','',$attribute);
if ($absence->getStatus()==$new_status){
return false;
}
if($absence->getStatus()==Absence::PENDING and in_array($new_status,[Absence::VALID,Absence::REFUSED]) and (!$this->isGranted('ROLE_ASSISTANT_RH') and !in_array( $absence->getCollaborator(),$collaborator->getListNMoins1()->toArray()))){
return false;
}
if($absence->getStatus()==Absence::PENDING and $new_status==Absence::CANCELLED and (!$this->isGranted('ROLE_ASSISTANT_RH')) and ( $absence->getCollaborator()!=$collaborator and!$this->isGranted('ROLE_ASSISTANT_RH') and !in_array( $absence->getCollaborator(),$collaborator->getListNMoins1()->toArray()))){
return false;
}
if($absence->getStatus()==Absence::VALID and $new_status==Absence::CANCELLED and (!$this->isGranted('ROLE_ASSISTANT_RH'))){
return false;
}
if(in_array($absence->getStatus(),[Absence::CANCELLED, Absence::REFUSED])){
return false;
}
return true;
}
private function canEditManagerComment(Absence $absence, Collaborator $collaborator): bool
{
if(
!$this->isGranted('ROLE_ADMIN')
and !$this->isGranted('ROLE_ASSISTANT_RH')
and !$this->isGranted('ROLE_MANAGER_RH')
//and !in_array($absence->getCollaborator(),$collaborator->getAllListNMoins()->toArray())
){
return false;
}
return true;
}
private function canEdit(Absence $absence, Collaborator $collaborator): bool
{
return false;
}
private function isGranted($role)
{
return $this->security->isGranted($role);
}
}