<?php
namespace App\Security\Voter;
use App\Entity\Common\RoleInterface;
use App\Entity\Project;
use App\Entity\User;
use App\Entity\UserProject;
use App\Entity\UserWorkroom;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;
class ManageProjectVoter extends Voter
{
private EntityManagerInterface $entityManager;
private RequestStack $requestStack;
public const ACTION_PROJECT = 'action_project';
public const ACTION_PROJECT_CDP_WL = 'action_project_cdp_wl';
protected array $attributes = [
self::ACTION_PROJECT,
self::ACTION_PROJECT_CDP_WL,
];
protected AuthorizationCheckerInterface $authChecker;
public function __construct(AuthorizationCheckerInterface $authChecker, EntityManagerInterface $entityManager, RequestStack $requestStack)
{
$this->authChecker = $authChecker;
$this->entityManager = $entityManager;
$this->requestStack = $requestStack;
}
private function getCurrentProjectId()
{
$session = $this->requestStack->getSession();
return $session->get('project_id');
}
protected function supports($attribute, $subject): bool
{
if (!\in_array($attribute, $this->attributes)) {
return false;
}
return true;
}
/**
* @param mixed $subject
*/
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof UserInterface) {
return false;
}
switch ($attribute) {
case self::ACTION_PROJECT:
return $this->canDoActionOnProject($user->getId());
case self::ACTION_PROJECT_CDP_WL:
return $this->canDoActionOnProjectByCdpAndWl($user->getId());
default:
return false;
}
}
public function canDoActionOnProject(int $id): bool
{
$projectId = $this->getCurrentProjectId();
return true == $this->entityManager->getRepository(UserProject::class)->checkIfProjectManagerInProject($id, $projectId);
}
public function canDoActionOnProjectByCdpAndWl(int $id): bool
{
$projectId = $this->getCurrentProjectId();
if ($this->entityManager->getRepository(UserProject::class)->checkIfProjectManagerInProject($id, $projectId)) {
return true;
}
$repoProject = $this->entityManager->getRepository(Project::class);
/** @var Project $project */
$project = $repoProject->find($projectId);
$repoUser = $this->entityManager->getRepository(User::class);
/** @var User $user */
$user = $repoUser->find($id);
$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;
}
}