mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
143 lines
4.8 KiB
PHP
143 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\EventBundle\Repository;
|
|
|
|
use Chill\EventBundle\Entity\Event;
|
|
use Chill\EventBundle\Entity\Participation;
|
|
use Chill\EventBundle\Security\Authorization\EventVoter;
|
|
use Chill\MainBundle\Entity\User;
|
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface;
|
|
use Chill\PersonBundle\Entity\Person;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Doctrine\ORM\NonUniqueResultException;
|
|
use Doctrine\ORM\NoResultException;
|
|
use Doctrine\ORM\QueryBuilder;
|
|
use Symfony\Component\Security\Core\Security;
|
|
|
|
final readonly class EventACLAwareRepository implements EventACLAwareRepositoryInterface
|
|
{
|
|
public function __construct(
|
|
private AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser,
|
|
private EntityManagerInterface $entityManager,
|
|
private Security $security,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @throws NonUniqueResultException
|
|
* @throws NoResultException
|
|
*/
|
|
public function countAllViewable(array $filters): int
|
|
{
|
|
if (!$this->security->getUser() instanceof User) {
|
|
return 0;
|
|
}
|
|
|
|
$qb = $this->buildQueryByAllViewable($filters);
|
|
$this->addFilters($filters, $qb);
|
|
|
|
$qb->select('COUNT(event.id)');
|
|
|
|
return $qb->getQuery()->getSingleScalarResult();
|
|
}
|
|
|
|
public function findAllViewable(array $filters, int $offset = 0, int $limit = 50): array
|
|
{
|
|
if (!$this->security->getUser() instanceof User) {
|
|
return [];
|
|
}
|
|
|
|
$qb = $this->buildQueryByAllViewable($filters)->select('event');
|
|
$this->addFilters($filters, $qb);
|
|
|
|
$qb->setFirstResult($offset)->setMaxResults($limit);
|
|
|
|
$qb->addOrderBy('event.date', 'DESC');
|
|
|
|
return $qb->getQuery()->getResult();
|
|
}
|
|
|
|
private function addFilters(array $filters, QueryBuilder $qb): void
|
|
{
|
|
if (($filters['q'] ?? '') !== '') {
|
|
$qb->andWhere('event.name LIKE :content');
|
|
$qb->setParameter('content', '%'.$filters['q'].'%');
|
|
}
|
|
|
|
if (array_key_exists('dates', $filters)) {
|
|
$dates = $filters['dates'];
|
|
if (null !== ($dates['from'] ?? null)) {
|
|
$qb->andWhere('event.date >= :date_from');
|
|
$qb->setParameter('date_from', $dates['from']);
|
|
}
|
|
if (null !== ($dates['to'] ?? null)) {
|
|
$qb->andWhere('event.date <= :date_to');
|
|
$qb->setParameter('date_to', $dates['to']);
|
|
}
|
|
}
|
|
|
|
if (0 < count($filters['event_types'] ?? [])) {
|
|
$qb->andWhere('event.type IN (:event_types)');
|
|
$qb->setParameter('event_types', $filters['event_types']);
|
|
}
|
|
}
|
|
|
|
public function buildQueryByAllViewable(array $filters): QueryBuilder
|
|
{
|
|
$qb = $this->entityManager->createQueryBuilder();
|
|
$qb->from(Event::class, 'event');
|
|
|
|
$aclConditions = $qb->expr()->orX();
|
|
|
|
$i = 0;
|
|
foreach ($this->authorizationHelperForCurrentUser->getReachableCenters(EventVoter::SEE) as $center) {
|
|
foreach ($this->authorizationHelperForCurrentUser->getReachableScopes(EventVoter::SEE, $center) as $scopes) {
|
|
$aclConditions->add(
|
|
$qb->expr()->andX(
|
|
'event.circle IN (:scopes_'.$i.')',
|
|
$qb->expr()->orX(
|
|
'event.center = :center_'.$i,
|
|
$qb->expr()->exists(
|
|
'SELECT 1 FROM '.Participation::class.' participation_'.$i.' JOIN participation_'.$i.'.event event_'.$i.
|
|
' JOIN '.Person\PersonCenterHistory::class.' person_center_history_'.$i.
|
|
' WITH IDENTITY(person_center_history_'.$i.'.person) = IDENTITY(participation_'.$i.'.person) '.
|
|
' AND event_'.$i.'.date <= person_center_history_'.$i.'.startDate AND (person_center_history_'.$i.'.endDate IS NULL OR person_center_history_'.$i.'.endDate > event_'.$i.'.date) '.
|
|
' WHERE participation_'.$i.'.event = event'
|
|
)
|
|
)
|
|
)
|
|
);
|
|
$qb->setParameter('scopes_'.$i, $scopes);
|
|
$qb->setParameter('center_'.$i, $center);
|
|
|
|
++$i;
|
|
}
|
|
}
|
|
|
|
if (0 === $i) {
|
|
$aclConditions->add('FALSE = TRUE');
|
|
}
|
|
|
|
$qb
|
|
->andWhere(
|
|
$qb->expr()->orX(
|
|
'event.createdBy = :user',
|
|
$aclConditions
|
|
)
|
|
);
|
|
|
|
$qb->setParameter('user', $this->security->getUser());
|
|
|
|
return $qb;
|
|
}
|
|
}
|