<?php
namespace App\Security\Voter;
use App\Entity\Common\RoleInterface;
use App\Entity\Common\StateInterface;
use App\Entity\Project;
use App\Entity\User;
use App\Entity\UserProject;
use App\Entity\UserWorkroom;
use App\Entity\Workroom;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Class UserProjectVoter.
*/
class UserProjectVoter extends Voter
{
// Permissions.
const PROJECT_MANAGE_VIEW_CDP = 'project_manage_view_cdp';
const PROJECT_MANAGE_VIEW_CDP_AND_WL = 'project_manage_view_cdp_and_wl';
// Full list.
const PERMISSIONS = [
self::PROJECT_MANAGE_VIEW_CDP,
self::PROJECT_MANAGE_VIEW_CDP_AND_WL,
];
private EntityManagerInterface $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* {@inheritdoc}
*/
protected function supports($attribute, $subject): bool
{
return in_array($attribute, self::PERMISSIONS) && ($subject instanceof Project);
}
/**
* {@inheritdoc}
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
/** @var User $user */
$user = $token->getUser();
// If the user is anonymous, do not grant access.
if (!$user instanceof UserInterface) {
return false;
}
// Check conditions and provide access bases on it.
switch ($attribute) {
case self::PROJECT_MANAGE_VIEW_CDP:
return $this->canViewCdp($subject, $user);
case self::PROJECT_MANAGE_VIEW_CDP_AND_WL:
return $this->canViewCdpAndWl($subject, $user);
default:
break;
}
return false;
}
/**
* Check that the user can view the workroom
* If the user has UserWorkroom entity we provide access, otherwise - not !!!
*/
public function canViewCdp(Project $project, User $user): bool
{
if ($project->getState() == StateInterface::STATE_ARCHIVED_INT) return false;
$userProject = $this->em->getRepository(UserProject::class)->findOneBy([
'user' => $user,
'project' => $project
]);
return ($userProject->getRole() == RoleInterface::ROLE_PROJECT_MANAGER_INT) ? true : false;
}
/**
* Check that the user can view the workroom
* If the user has UserWorkroom entity we provide access, otherwise - not !!!
*/
public function canViewCdpAndWl(Project $project, User $user): bool
{
if ($project->getState() == StateInterface::STATE_ARCHIVED_INT) return false;
$userProject = $this->em->getRepository(UserProject::class)->findOneBy([
'user' => $user,
'project' => $project
]);
if ($userProject->getRole() == RoleInterface::ROLE_PROJECT_MANAGER_INT) return true;
$workroomsOfProject = $project->getWorkroomsIds();
$workroomsOfUser = $user->getUserWorkrooms();
foreach ($workroomsOfUser as $workroomUser) {
if (in_array($workroomUser->getWorkroom()->getId(), $workroomsOfProject)) {
if ($workroomUser->getRole() == RoleInterface::ROLE_LEADER_WORKROOM_INT) {
return true;
}
}
}
return false;
}
}