em = $entityManager; $this->repository = $entityManager->getRepository(Notification::class); } public function countAllForAttendee(User $addressee): int { return $this->queryByAddressee($addressee) ->select('count(n)') ->getQuery() ->getSingleScalarResult(); } public function countAllForSender(User $sender): int { return $this->queryBySender($sender) ->select('count(n)') ->getQuery() ->getSingleScalarResult(); } public function countNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user): array { if (null === $this->notificationByRelatedEntityAndUserAssociatedStatement) { $sql = 'SELECT SUM((EXISTS (SELECT 1 AS c FROM chill_main_notification_addresses_unread cmnau WHERE user_id = 1812 and cmnau.notification_id = cmn.id))::int) AS unread, SUM((cmn.sender_id = 1812)::int) AS sent, COUNT(cmn.*) AS total FROM chill_main_notification cmn WHERE relatedentityclass = :relatedEntityClass AND relatedentityid = :relatedEntityId AND sender_id IS NOT NULL'; $this->notificationByRelatedEntityAndUserAssociatedStatement = $this->em->getConnection()->prepare($sql); } $results = $this->notificationByRelatedEntityAndUserAssociatedStatement ->executeQuery(['relatedEntityClass' => $relatedEntityClass, 'relatedEntityId' => $relatedEntityId]); $result = $results->fetchAssociative(); $results->free(); return $result; } public function countUnreadByUser(User $user): int { $sql = 'SELECT count(*) AS c FROM chill_main_notification_addresses_unread WHERE user_id = :userId'; $rsm = new Query\ResultSetMapping(); $rsm->addScalarResult('c', 'c', Types::INTEGER); $nq = $this->em->createNativeQuery($sql, $rsm) ->setParameter('userId', $user->getId()); return $nq->getSingleScalarResult(); } public function countUnreadByUserWhereAddressee(User $user): int { $qb = $this->repository->createQueryBuilder('n'); $qb ->select('count(n)') ->where($qb->expr()->isMemberOf(':user', 'n.addressees')) ->andWhere($qb->expr()->isMemberOf(':user', 'n.unreadBy')) ->setParameter('user', $user); return $qb->getQuery()->getSingleScalarResult(); } public function countUnreadByUserWhereSender(User $user): int { $qb = $this->repository->createQueryBuilder('n'); $qb ->select('count(n)') ->where($qb->expr()->eq('n.sender', ':user')) ->andWhere($qb->expr()->isMemberOf(':user', 'n.unreadBy')) ->setParameter('user', $user); return $qb->getQuery()->getSingleScalarResult(); } public function find($id, $lockMode = null, $lockVersion = null): ?Notification { return $this->repository->find($id, $lockMode, $lockVersion); } /** * @return Notification[] */ public function findAll(): array { return $this->repository->findAll(); } /** * @param mixed|null $limit * @param mixed|null $offset * * @return Notification[] */ public function findAllForAttendee(User $addressee, $limit = null, $offset = null): array { $query = $this->queryByAddressee($addressee)->select('n'); if ($limit) { $query = $query->setMaxResults($limit); } if ($offset) { $query = $query->setFirstResult($offset); } $query->addOrderBy('n.date', 'DESC'); return $query->getQuery()->getResult(); } public function findAllForSender(User $sender, $limit = null, $offset = null): array { $query = $this->queryBySender($sender)->select('n'); if ($limit) { $query = $query->setMaxResults($limit); } if ($offset) { $query = $query->setFirstResult($offset); } $query->addOrderBy('n.date', 'DESC'); return $query->getQuery()->getResult(); } /** * @param mixed|null $limit * @param mixed|null $offset * * @return Notification[] */ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } /** * @return array|Notification[] */ public function findNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user): array { return $this->buildQueryNotificationByRelatedEntityAndUserAssociated($relatedEntityClass, $relatedEntityId, $user) ->select('n') ->getQuery() ->getResult(); } public function findOneBy(array $criteria, ?array $orderBy = null): ?Notification { return $this->repository->findOneBy($criteria, $orderBy); } /** * @return array|Notification[] */ public function findUnreadByUser(User $user, int $limit = 20, int $offset = 0): array { $rsm = new Query\ResultSetMappingBuilder($this->em); $rsm->addRootEntityFromClassMetadata(Notification::class, 'cmn'); $sql = 'SELECT ' . $rsm->generateSelectClause(['cmn' => 'cmn']) . ' ' . 'FROM chill_main_notification cmn ' . 'WHERE ' . 'EXISTS (select 1 FROM chill_main_notification_addresses_unread cmnau WHERE cmnau.user_id = :userId and cmnau.notification_id = cmn.id) ' . 'ORDER BY cmn.date DESC ' . 'LIMIT :limit OFFSET :offset'; $nq = $this->em->createNativeQuery($sql, $rsm) ->setParameter('userId', $user->getId()) ->setParameter('limit', $limit) ->setParameter('offset', $offset); return $nq->getResult(); } public function getClassName() { return Notification::class; } private function buildQueryNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user): QueryBuilder { $qb = $this->repository->createQueryBuilder('n'); $qb ->where($qb->expr()->eq('n.relatedEntityClass', ':relatedEntityClass')) ->andWhere($qb->expr()->eq('n.relatedEntityId', ':relatedEntityId')) ->andWhere($qb->expr()->isNotNull('n.sender')) ->andWhere( $qb->expr()->orX( $qb->expr()->isMemberOf(':user', 'n.addressees'), $qb->expr()->eq('n.sender', ':user') ) ) ->setParameter('relatedEntityClass', $relatedEntityClass) ->setParameter('relatedEntityId', $relatedEntityId) ->setParameter('user', $user); return $qb; } private function queryByAddressee(User $addressee, bool $countQuery = false): QueryBuilder { $qb = $this->repository->createQueryBuilder('n'); $qb ->where($qb->expr()->isMemberOf(':addressee', 'n.addressees')) ->setParameter('addressee', $addressee); return $qb; } private function queryBySender(User $sender): QueryBuilder { $qb = $this->repository->createQueryBuilder('n'); $qb ->where($qb->expr()->eq('n.sender', ':sender')) ->setParameter('sender', $sender); return $qb; } }