*/ class AuditTrailRepository extends ServiceEntityRepository { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, AuditTrail::class); } /** * Persist an AuditTrail without storing it in the entity manager. */ public function persistImmediately(AuditTrail $auditTrail): void { $metadata = $this->getClassMetadata(); $sql = $this->getEntityManager()->getConnection()->createQueryBuilder(); $sql ->insert($metadata->getTableName()) ->values([ 'id' => ':id', 'action' => ':action', 'occurredat' => ':occured_at', 'user_id' => ':user_id', 'description' => ':description', 'main_subject' => ':main_subject', 'subjects' => ':subjects', 'metadata' => ':metadata', ]) ->setParameter('id', $auditTrail->getId()) ->setParameter('action', $auditTrail->getAction()) ->setParameter('occured_at', $auditTrail->getOccurredAt(), Types::DATETIMETZ_IMMUTABLE) ->setParameter('user_id', $auditTrail->getUser()?->getId(), Types::INTEGER) ->setParameter('description', $auditTrail->getDescription()) ->setParameter('main_subject', $auditTrail->getMainSubject(), Types::JSON) ->setParameter('subjects', $auditTrail->getSubjects(), Types::JSON) ->setParameter('metadata', $auditTrail->getMetadata(), Types::JSON); $sql->executeQuery(); } /** * @param array{subjects?: list, from_date?: \DateTimeImmutable, to_date?: \DateTimeImmutable, by_users?: list} $criteria * * @return array */ public function findByCriteria(array $criteria, int $offset = 0, int $limit = 100): array { return $this->buildByCriteriaQuery($criteria) ->orderBy('audit.occurredAt', 'DESC') ->setMaxResults($limit) ->setFirstResult($offset) ->getQuery()->getResult(); } /** * @param array{subjects?: list, from_date?: \DateTimeImmutable, to_date?: \DateTimeImmutable, by_users?: list} $criteria */ public function countByCriteria(array $criteria): int { return $this->buildByCriteriaQuery($criteria) ->select('COUNT(audit)') ->getQuery()->getSingleScalarResult(); } /** * @param array{subjects?: list, from_date?: \DateTimeImmutable, to_date?: \DateTimeImmutable, by_users?: list} $criteria */ private function buildByCriteriaQuery(array $criteria): QueryBuilder { $qb = $this->createQueryBuilder('audit'); $k = 0; if (null !== $fromDate = $criteria['from_date'] ?? null) { $qb->andWhere('audit.occurredAt >= :from_date'); $qb->setParameter('from_date', $fromDate); } if (null !== $toDate = $criteria['to_date'] ?? null) { $qb->andWhere('audit.occurredAt <= :to_date'); $qb->setParameter('to_date', $toDate); } if ([] !== $subjects = $criteria['subjects'] ?? []) { $orx = $qb->expr()->orX(); foreach ($subjects as $subject) { $orx->add($qb->expr()->eq('audit.mainSubject', ':subject_'.$k)); $qb->setParameter('subject_'.$k, $subject->asArray(), Types::JSON); ++$k; $orx->add('TRUE = JSONB_CONTAINS(audit.subjects, :subject_'.$k.')'); $qb->setParameter('subject_'.$k, [$subject->asArray()], Types::JSON); ++$k; } $qb->andWhere($orx); } if ([] !== $users = $criteria['by_users'] ?? []) { $orx = $qb->expr()->orX(); foreach ($users as $user) { $orx->add($qb->expr()->eq('audit.user', ':user_'.$k)); $qb->setParameter('user_'.$k, $user); ++$k; } $qb->andWhere($orx); } return $qb; } }