Feature: [calendar] allow to create and generate calendar by person

This commit is contained in:
2022-10-21 13:24:02 +02:00
parent 43dcb46d38
commit bc1a7c1d7b
15 changed files with 677 additions and 245 deletions

View File

@@ -20,16 +20,24 @@ 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 DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\QueryBuilder;
class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface
{
private AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository;
private EntityManagerInterface $em;
public function __construct(EntityManagerInterface $em)
{
public function __construct(
AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository,
EntityManagerInterface $em
) {
$this->accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository;
$this->em = $em;
}
@@ -56,6 +64,46 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface
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
{
// find the reachable accompanying periods for person
$periods = $this->accompanyingPeriodACLAwareRepository->findByPerson($person, AccompanyingPeriodVoter::SEE);
$qb = $this->em->createQueryBuilder()
->from(Calendar::class, 'c');
$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);
// 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;
}
public function countByAccompanyingPeriod(AccompanyingPeriod $period, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): int
{
$qb = $this->buildQueryByAccompanyingPeriod($period, $startDate, $endDate)->select('count(c)');
@@ -63,6 +111,14 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface
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();
}
/**
* @return array|Calendar[]
*/
@@ -84,4 +140,24 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface
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();
}
}