mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-14 22:34:24 +00:00
222 lines
7.6 KiB
PHP
222 lines
7.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
|
|
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\CalendarBundle\Repository;
|
|
|
|
use Chill\CalendarBundle\Entity\Calendar;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
|
use Chill\PersonBundle\Entity\Person;
|
|
use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface;
|
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Doctrine\ORM\QueryBuilder;
|
|
|
|
class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface
|
|
{
|
|
public function __construct(private readonly AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository, private readonly EntityManagerInterface $em)
|
|
{
|
|
}
|
|
|
|
public function buildQueryByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): QueryBuilder
|
|
{
|
|
$qb = $this->em->createQueryBuilder();
|
|
$qb->from(Calendar::class, 'c');
|
|
|
|
$andX = $qb->expr()->andX($qb->expr()->eq('c.accompanyingPeriod', ':period'));
|
|
$qb->setParameter('period', $period);
|
|
|
|
if (null !== $startDate) {
|
|
$andX->add($qb->expr()->gte('c.startDate', ':startDate'));
|
|
$qb->setParameter('startDate', $startDate);
|
|
}
|
|
|
|
if (null !== $endDate) {
|
|
$andX->add($qb->expr()->lte('c.endDate', ':endDate'));
|
|
$qb->setParameter('endDate', $endDate);
|
|
}
|
|
|
|
$qb->where($andX);
|
|
|
|
return $qb;
|
|
}
|
|
|
|
public function buildQueryByAccompanyingPeriodIgnoredByDates(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): QueryBuilder
|
|
{
|
|
$qb = $this->em->createQueryBuilder();
|
|
$qb->from(Calendar::class, 'c');
|
|
|
|
$andX = $qb->expr()->andX($qb->expr()->eq('c.accompanyingPeriod', ':period'));
|
|
$qb->setParameter('period', $period);
|
|
|
|
if (null !== $startDate) {
|
|
$andX->add($qb->expr()->lt('c.startDate', ':startDate'));
|
|
$qb->setParameter('startDate', $startDate);
|
|
}
|
|
|
|
if (null !== $endDate) {
|
|
$andX->add($qb->expr()->gt('c.endDate', ':endDate'));
|
|
$qb->setParameter('endDate', $endDate);
|
|
}
|
|
|
|
$qb->where($andX);
|
|
|
|
return $qb;
|
|
}
|
|
|
|
/**
|
|
* Base implementation. The list of allowed accompanying period is retrieved "manually" from @see{AccompanyingPeriodACLAwareRepository}.
|
|
*/
|
|
public function buildQueryByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): QueryBuilder
|
|
{
|
|
$qb = $this->em->createQueryBuilder()
|
|
->from(Calendar::class, 'c');
|
|
|
|
$this->addQueryByPersonWithoutDate($qb, $person);
|
|
|
|
// filter by date
|
|
if (null !== $startDate) {
|
|
$qb->andWhere($qb->expr()->gte('c.startDate', ':startDate'))
|
|
->setParameter('startDate', $startDate);
|
|
}
|
|
|
|
if (null !== $endDate) {
|
|
$qb->andWhere($qb->expr()->lte('c.endDate', ':endDate'))
|
|
->setParameter('endDate', $endDate);
|
|
}
|
|
|
|
return $qb;
|
|
}
|
|
|
|
/**
|
|
* Base implementation. The list of allowed accompanying period is retrieved "manually" from @see{AccompanyingPeriodACLAwareRepository}.
|
|
*/
|
|
public function buildQueryByPersonIgnoredByDates(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): QueryBuilder
|
|
{
|
|
$qb = $this->em->createQueryBuilder()
|
|
->from(Calendar::class, 'c');
|
|
|
|
$this->addQueryByPersonWithoutDate($qb, $person);
|
|
|
|
// filter by date
|
|
if (null !== $startDate) {
|
|
$qb->andWhere($qb->expr()->lt('c.startDate', ':startDate'))
|
|
->setParameter('startDate', $startDate);
|
|
}
|
|
|
|
if (null !== $endDate) {
|
|
$qb->andWhere($qb->expr()->gt('c.endDate', ':endDate'))
|
|
->setParameter('endDate', $endDate);
|
|
}
|
|
|
|
return $qb;
|
|
}
|
|
|
|
public function countByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int
|
|
{
|
|
$qb = $this->buildQueryByAccompanyingPeriod($period, $startDate, $endDate)->select('count(c)');
|
|
|
|
return $qb->getQuery()->getSingleScalarResult();
|
|
}
|
|
|
|
public function countByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int
|
|
{
|
|
return $this->buildQueryByPerson($person, $startDate, $endDate)
|
|
->select('COUNT(c)')
|
|
->getQuery()
|
|
->getSingleScalarResult();
|
|
}
|
|
|
|
public function countIgnoredByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int
|
|
{
|
|
$qb = $this->buildQueryByAccompanyingPeriodIgnoredByDates($period, $startDate, $endDate)->select('count(c)');
|
|
|
|
return $qb->getQuery()->getSingleScalarResult();
|
|
}
|
|
|
|
public function countIgnoredByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int
|
|
{
|
|
return $this->buildQueryByPersonIgnoredByDates($person, $startDate, $endDate)
|
|
->select('COUNT(c)')
|
|
->getQuery()
|
|
->getSingleScalarResult();
|
|
}
|
|
|
|
/**
|
|
* @return array|Calendar[]
|
|
*/
|
|
public function findByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?array $orderBy = [], ?int $offset = null, ?int $limit = null): array
|
|
{
|
|
$qb = $this->buildQueryByAccompanyingPeriod($period, $startDate, $endDate)->select('c');
|
|
|
|
foreach ($orderBy as $sort => $order) {
|
|
$qb->addOrderBy('c.'.$sort, $order);
|
|
}
|
|
|
|
if (null !== $offset) {
|
|
$qb->setFirstResult($offset);
|
|
}
|
|
|
|
if (null !== $limit) {
|
|
$qb->setMaxResults($limit);
|
|
}
|
|
|
|
return $qb->getQuery()->getResult();
|
|
}
|
|
|
|
public function findByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?array $orderBy = [], ?int $offset = null, ?int $limit = null): array
|
|
{
|
|
$qb = $this->buildQueryByPerson($person, $startDate, $endDate)
|
|
->select('c');
|
|
|
|
foreach ($orderBy as $sort => $order) {
|
|
$qb->addOrderBy('c.'.$sort, $order);
|
|
}
|
|
|
|
if (null !== $offset) {
|
|
$qb->setFirstResult($offset);
|
|
}
|
|
|
|
if (null !== $limit) {
|
|
$qb->setMaxResults($limit);
|
|
}
|
|
|
|
return $qb->getQuery()->getResult();
|
|
}
|
|
|
|
private function addQueryByPersonWithoutDate(QueryBuilder $qb, Person $person): void
|
|
{
|
|
// find the reachable accompanying periods for person
|
|
$periods = $this->accompanyingPeriodACLAwareRepository->findByPerson($person, AccompanyingPeriodVoter::SEE);
|
|
|
|
$qb
|
|
->where(
|
|
$qb->expr()->orX(
|
|
// the calendar where the person is the main person:
|
|
$qb->expr()->eq('c.person', ':person'),
|
|
// when the calendar is in a reachable period, and contains person
|
|
$qb->expr()->andX(
|
|
$qb->expr()->in('c.accompanyingPeriod', ':periods'),
|
|
$qb->expr()->isMemberOf(':person', 'c.persons')
|
|
)
|
|
)
|
|
)
|
|
->setParameter('person', $person)
|
|
->setParameter('periods', $periods);
|
|
}
|
|
}
|