Files
chill-bundles/src/Bundle/ChillMainBundle/Repository/AuditTrailRepository.php
Julien Fastré ceb58de858 Add pagination support to Audit Trail listing
- Added `countByCriteria` method in `AuditTrailRepository` to retrieve the total count of records based on criteria.
- Injected `PaginatorFactoryInterface` into `AuditTrailSearchController` and updated the controller to handle pagination logic.
- Updated the `list.html.twig` template to render the pagination controls using `chill_pagination`.
2026-02-17 11:07:12 +01:00

132 lines
4.6 KiB
PHP

<?php
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\MainBundle\Repository;
use Chill\MainBundle\Audit\Subject;
use Chill\MainBundle\Entity\AuditTrail;
use Chill\MainBundle\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<AuditTrail>
*/
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<Subject>, from_date?: \DateTimeImmutable, to_date?: \DateTimeImmutable, by_users?: list<User>} $criteria
*
* @return array<AuditTrail>
*/
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<Subject>, from_date?: \DateTimeImmutable, to_date?: \DateTimeImmutable, by_users?: list<User>} $criteria
*/
public function countByCriteria(array $criteria): int
{
return $this->buildByCriteriaQuery($criteria)
->select('COUNT(audit)')
->getQuery()->getSingleScalarResult();
}
/**
* @param array{subjects?: list<Subject>, from_date?: \DateTimeImmutable, to_date?: \DateTimeImmutable, by_users?: list<User>} $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;
}
}