getRoles(), true)) { return true; } if (in_array('ROLE_SELF', $user->getRoles(), true)) { return $user->getEmployee()?->getId() === $employee->getId(); } $employeeSiteId = $employee->getSite()?->getId(); if (!$employeeSiteId) { return false; } return in_array($employeeSiteId, $this->getAllowedSiteIds($user), true); } /** * Retourne la liste des sites accessibles via user_site_roles. * * @return list */ public function getAllowedSiteIds(User $user): array { $siteIds = []; foreach ($user->getSiteRoles() as $siteRole) { if (self::SITE_ACCESS_ROLE !== $siteRole->getRole()) { continue; } $siteId = $siteRole->getSite()?->getId(); if ($siteId) { $siteIds[] = $siteId; } } return array_values(array_unique($siteIds)); } /** * Applique le scope directement sur un QueryBuilder Doctrine. * Cette méthode est utilisée pour filtrer les collections SQL * avant sérialisation (plus sûr et plus performant). */ public function applyEmployeeScope(QueryBuilder $qb, string $employeeAlias, string $paramPrefix, User $user): void { if (in_array('ROLE_ADMIN', $user->getRoles(), true)) { return; } if (in_array('ROLE_SELF', $user->getRoles(), true)) { $employeeId = $user->getEmployee()?->getId(); if (!$employeeId) { $qb->andWhere('1 = 0'); return; } $qb->andWhere(sprintf('%s.id = :%s_employee_id', $employeeAlias, $paramPrefix)) ->setParameter(sprintf('%s_employee_id', $paramPrefix), $employeeId) ; return; } $siteIds = $this->getAllowedSiteIds($user); if ([] === $siteIds) { $qb->andWhere('1 = 0'); return; } $qb->andWhere(sprintf('%s.site IN (:%s_site_ids)', $employeeAlias, $paramPrefix)) ->setParameter(sprintf('%s_site_ids', $paramPrefix), $siteIds) ; } }