<?php
namespace App\Security\Voter;
use App\Entity\ClientOrder;
use App\Entity\UserAccess;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
class ClientOrderVoter extends AbstractVoter
{
public const VIEW = 'ClientOrder:View';
public const EDIT = 'ClientOrder:Edit';
private ?ClientOrder $clientOrder = null;
protected function supports(string $attribute, mixed $subject): bool
{
return in_array($attribute, [self::VIEW, self::EDIT])
&& $subject instanceof ClientOrder;
}
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$this->user = $token->getUser();
$this->clientOrder = $subject;
return match ($attribute) {
self::VIEW => $this->canViewClientOrder(),
self::EDIT => $this->canEditClientOrder(),
default => false,
};
}
private function canViewClientOrder(): bool
{
// Read-only superadmins can view all client orders
if ($this->isReadOnlySuperAdmin()) {
return true;
}
if ($this->isSuperAdmin()) {
return true;
}
// Check if user has access to the project's groupement or the project itself
$project = $this->clientOrder->getProject();
if (!$project) {
return false;
}
$magasin = $project->getMagasin();
if (!$magasin) {
return false;
}
// Check groupement access
if ($this->user->canAccessResource($magasin->getGroupement(), [UserAccess::ROLE_ADMIN])) {
return true;
}
// Check direct project/magasin access
return $this->isAdmin()
&& $this->user->canAccessResource($magasin, [UserAccess::ROLE_ADMIN]);
}
private function canEditClientOrder(): bool
{
// Full superadmins can always edit (not read-only)
if ($this->isSuperAdmin() && !$this->isReadOnlySuperAdmin()) {
return true;
}
// Check if user has admin access to the project's groupement or the project itself
$project = $this->clientOrder->getProject();
if (!$project) {
return false;
}
$magasin = $project->getMagasin();
if (!$magasin) {
return false;
}
// Check groupement admin access
if ($this->user->canAccessResource($magasin->getGroupement(), [UserAccess::ROLE_ADMIN])) {
return true;
}
// Check direct project/magasin admin access
return $this->isAdmin()
&& $this->user->canAccessResource($magasin, [UserAccess::ROLE_ADMIN]);
}
}