From ebfb030ba6e377c556b251a3a5c1d592fef18715 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 11:20:27 +0200 Subject: [PATCH] add querybuilder method to repository --- .../Repository/CalendarRepository.php | 236 +++++++++++++++--- 1 file changed, 202 insertions(+), 34 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php index 55fba5f80..626a9f29f 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php @@ -12,52 +12,220 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Repository; use Chill\CalendarBundle\Entity\Calendar; -use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Chill\MainBundle\Entity\User; +use Chill\PersonBundle\Entity\AccompanyingPeriod; +use DateTimeImmutable; +use Doctrine\DBAL\Types\Types; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; -use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\Query\ResultSetMapping; +use Doctrine\ORM\QueryBuilder; +use Doctrine\Persistence\ObjectRepository; +use function count; -/** - * @method Calendar|null find($id, $lockMode = null, $lockVersion = null) - * @method Calendar|null findOneBy(array $criteria, array $orderBy = null) - * @method Calendar[] findAll() - * @method Calendar[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) - */ -class CalendarRepository extends ServiceEntityRepository +class CalendarRepository implements ObjectRepository { - // private EntityRepository $repository; + private EntityManagerInterface $em; - public function __construct(ManagerRegistry $registry) + private EntityRepository $repository; + + public function __construct(EntityManagerInterface $entityManager) { - parent::__construct($registry, Calendar::class); - // $this->repository = $entityManager->getRepository(AccompanyingPeriodWork::class); + $this->repository = $entityManager->getRepository(Calendar::class); + $this->em = $entityManager; } - // /** - // * @return Calendar[] Returns an array of Calendar objects - // */ - /* - public function findByExampleField($value) + public function countByAccompanyingPeriod(AccompanyingPeriod $period): int { - return $this->createQueryBuilder('c') - ->andWhere('c.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('c.id', 'ASC') - ->setMaxResults(10) + return $this->repository->count(['accompanyingPeriod' => $period]); + } + + public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder + { + return $this->repository->createQueryBuilder($alias, $indexBy); + } + + public function countByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to): int + { + return $this->buildQueryByUser($user, $from, $to) + ->select('COUNT(c)') ->getQuery() - ->getResult() - ; + ->getSingleScalarResult(); } - */ - /* - public function findOneBySomeField($value): ?Calendar + public function find($id): ?Calendar { - return $this->createQueryBuilder('c') - ->andWhere('c.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; + return $this->repository->find($id); } + + /** + * @return array|Calendar[] */ + public function findAll(): array + { + return $this->repository->findAll(); + } + + /** + * @return array|Calendar[] + */ + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + /** + * @return array|Calendar[] + */ + public function findByAccompanyingPeriod(AccompanyingPeriod $period, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->findBy( + [ + 'accompanyingPeriod' => $period, + ], + $orderBy, + $limit, + $orderBy + ); + } + + public function findByNotificationAvailable(DateTimeImmutable $startDate, DateTimeImmutable $endDate, ?int $limit = null, ?int $offset = null): array + { + $qb = $this->queryByNotificationAvailable($startDate, $endDate)->select('c'); + + if (null !== $limit) { + $qb->setMaxResults($limit); + } + + if (null !== $offset) { + $qb->setFirstResult($offset); + } + + return $qb->getQuery()->getResult(); + } + + /** + * @return array|Calendar[] + */ + public function findByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to, ?int $limit = null, ?int $offset = null): array + { + $qb = $this->buildQueryByUser($user, $from, $to)->select('c'); + + if (null !== $limit) { + $qb->setMaxResults($limit); + } + + if (null !== $offset) { + $qb->setFirstResult($offset); + } + + return $qb->getQuery()->getResult(); + } + + public function findOneBy(array $criteria): ?Calendar + { + return $this->repository->findOneBy($criteria); + } + + /** + * Given a list of remote ids, return an array where + * keys are the remoteIds, and value is a boolean, true if the + * id is present in database. + * + * @param array|list $remoteIds + * + * @return array + */ + public function findRemoteIdsPresent(array $remoteIds): array + { + if (0 === count($remoteIds)) { + return []; + } + + $remoteIdsStr = implode( + ', ', + array_fill(0, count($remoteIds), '((?))') + ); + + $sql = "SELECT + sq.remoteId as remoteid, + EXISTS (SELECT 1 FROM chill_calendar.calendar c WHERE c.remoteId = sq.remoteId) AS present + FROM + ( + VALUES {$remoteIdsStr} + ) AS sq(remoteId); + "; + + $rsm = new ResultSetMapping(); + $rsm + ->addScalarResult('remoteid', 'remoteId', Types::STRING) + ->addScalarResult('present', 'present', Types::BOOLEAN); + + $rows = $this->em + ->createNativeQuery( + $sql, + $rsm + ) + ->setParameters(array_values($remoteIds)) + ->getResult(); + + $results = []; + + foreach ($rows as $r) { + $results[$r['remoteId']] = $r['present']; + } + + return $results; + } + + public function getClassName() + { + return Calendar::class; + } + + private function buildQueryByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to): QueryBuilder + { + $qb = $this->repository->createQueryBuilder('c'); + + return $qb + ->where( + $qb->expr()->andX( + $qb->expr()->eq('c.mainUser', ':user'), + $qb->expr()->gte('c.startDate', ':startDate'), + $qb->expr()->lte('c.endDate', ':endDate'), + ) + ) + ->setParameters([ + 'user' => $user, + 'startDate' => $from, + 'endDate' => $to, + ]); + } + + private function queryByNotificationAvailable(DateTimeImmutable $startDate, DateTimeImmutable $endDate): QueryBuilder + { + $qb = $this->repository->createQueryBuilder('c'); + + $qb->where( + $qb->expr()->andX( + $qb->expr()->eq('c.sendSMS', ':true'), + $qb->expr()->gte('c.startDate', ':startDate'), + $qb->expr()->lt('c.startDate', ':endDate'), + $qb->expr()->orX( + $qb->expr()->eq('c.smsStatus', ':pending'), + $qb->expr()->eq('c.smsStatus', ':cancel_pending') + ) + ) + ); + + $qb->setParameters([ + 'true' => true, + 'startDate' => $startDate, + 'endDate' => $endDate, + 'pending' => Calendar::SMS_PENDING, + 'cancel_pending' => Calendar::SMS_CANCEL_PENDING, + ]); + + return $qb; + } }