<?php
namespace App\Security\Voter;
use App\Entity\Common\RoleInterface;
use App\Entity\Common\TypeProjectInterface;
use App\Entity\Project;
use App\Entity\User;
use App\Entity\UserProject;
use App\Entity\UserWorkroom;
use App\Repository\UserProjectRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
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 CreateProjectVoter extends Voter
{
private int $maxPrivateProjects;
public const CREATE_PUBLIC_PROJECT = 'create_public_project';
public const CREATE_PRIVATE_PROJECT = 'create_private_project';
protected array $attributes = [
self::CREATE_PUBLIC_PROJECT,
self::CREATE_PRIVATE_PROJECT
];
protected AuthorizationCheckerInterface $authChecker;
public function __construct(
private UserProjectRepository $userProjectRepository,
ParameterBagInterface $parameterBag
) {
$this->maxPrivateProjects = $parameterBag->get('MAX_PRIVATE_PROJECTS');
}
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::CREATE_PUBLIC_PROJECT:
return $this->canCreatePublicProject($user);
case self::CREATE_PRIVATE_PROJECT:
return $this->canCreatePrivateProject($user);
default:
return false;
}
}
private function canCreatePublicProject(User $user): bool
{
return $user->hasRole(User::ROLE_PROJECT_MANAGER);
}
private function canCreatePrivateProject(User $user): bool
{
return $user->hasRole(User::ROLE_PROJECT_MANAGER)
|| ($user->hasRole(User::ROLE_LEADER_WORKROOM)
&& $this->userProjectRepository->getCountPrivateProjects($user) < $this->maxPrivateProjects);
}
}