From c1cf5a8bb2db2473d45cbe89459063c6fd8862b9 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 3 Dec 2025 11:15:12 +0100 Subject: [PATCH 1/5] Start implementation of filter within admin index pages --- .../SocialWork/EvaluationController.php | 36 +++++++++ .../Controller/SocialWork/GoalController.php | 10 +++ .../SocialWork/ResultController.php | 10 +++ .../SocialWork/SocialActionController.php | 10 +++ .../SocialWork/SocialIssueController.php | 10 +++ .../SocialWork/EvaluationRepository.php | 81 ++++++++++++++++++- .../SocialWork/Evaluation/index.html.twig | 3 + .../views/SocialWork/Goal/index.html.twig | 3 + .../views/SocialWork/Result/index.html.twig | 3 + .../SocialWork/SocialAction/index.html.twig | 3 + .../SocialWork/SocialIssue/index.html.twig | 3 + 11 files changed, 171 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php index 13a4aca99..4d0aba918 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php @@ -13,14 +13,50 @@ namespace Chill\PersonBundle\Controller\SocialWork; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Templating\Listing\FilterOrderHelper; +use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository; use Symfony\Component\HttpFoundation\Request; class EvaluationController extends CRUDController { + public function __construct(private readonly EvaluationRepository $repository) {} protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { $query->addOrderBy('e.id', 'ASC'); return parent::orderQuery($action, $query, $request, $paginator); } + + protected function getQueryResult( + string $action, + Request $request, + int $totalItems, + PaginatorInterface $paginator, + ?FilterOrderHelper $filterOrder = null, + ) { + if (0 === $totalItems) { + return []; + } + + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::getQueryResult($action, $request, $totalItems, $paginator, $filterOrder); + } + + $queryString = $filterOrder->getQueryString(); + $activeFilter = $filterOrder->getCheckboxData('activeFilter'); + $nb = $this->repository->countFilteredEvaluations($queryString, $activeFilter); + + $paginator = $this->getPaginatorFactory()->create($nb); + + return $this->repository->findFilteredEvaluations($queryString, $activeFilter, $paginator->getCurrentPageFirstItemNumber(), $paginator->getItemsPerPage()); + } + + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper + { + return $this->getFilterOrderHelperFactory() + ->create(self::class) + ->addSearchBox(['label']) + ->addCheckbox('activeFilter', [true => 'Active', false => 'Inactive'], ['Active']) + ->build(); + } } diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php index df57b012a..1655356bc 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php @@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Controller\SocialWork; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Symfony\Component\HttpFoundation\Request; class GoalController extends CRUDController @@ -23,4 +24,13 @@ class GoalController extends CRUDController return parent::orderQuery($action, $query, $request, $paginator); } + + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper + { + return $this->getFilterOrderHelperFactory() + ->create(self::class) + ->addSearchBox(['label']) + ->addCheckbox('activeFilter', [true => 'Active', false => 'Inactive'], ['Active']) + ->build(); + } } diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php index 274f7136e..775106a40 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php @@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Controller\SocialWork; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Symfony\Component\HttpFoundation\Request; class ResultController extends CRUDController @@ -23,4 +24,13 @@ class ResultController extends CRUDController return parent::orderQuery($action, $query, $request, $paginator); } + + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper + { + return $this->getFilterOrderHelperFactory() + ->create(self::class) + ->addSearchBox(['label']) + ->addCheckbox('activeFilter', [true => 'Active', false => 'Inactive'], ['Active']) + ->build(); + } } diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php index 69bbf7ace..a54c411f7 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php @@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Controller\SocialWork; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Symfony\Component\HttpFoundation\Request; class SocialActionController extends CRUDController @@ -23,4 +24,13 @@ class SocialActionController extends CRUDController return parent::orderQuery($action, $query, $request, $paginator); } + + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper + { + return $this->getFilterOrderHelperFactory() + ->create(self::class) + ->addSearchBox(['label']) + ->addCheckbox('activeFilter', [true => 'Active', false => 'Inactive'], ['Active']) + ->build(); + } } diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php index 316417583..d47a56a8a 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php @@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Controller\SocialWork; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; @@ -37,4 +38,13 @@ class SocialIssueController extends CRUDController return parent::orderQuery($action, $query, $request, $paginator); } + + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper + { + return $this->getFilterOrderHelperFactory() + ->create(self::class) + ->addSearchBox(['label']) + ->addCheckbox('activeFilter', [true => 'Active', false => 'Inactive'], ['Active']) + ->build(); + } } diff --git a/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php b/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php index 1c89a98f6..b09ee57b8 100644 --- a/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php @@ -11,15 +11,19 @@ declare(strict_types=1); namespace Chill\PersonBundle\Repository\SocialWork; +use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\SocialWork\Evaluation; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\NonUniqueResultException; +use Doctrine\ORM\NoResultException; +use Doctrine\ORM\QueryBuilder; final readonly class EvaluationRepository implements EvaluationRepositoryInterface { private EntityRepository $repository; - public function __construct(EntityManagerInterface $entityManager) + public function __construct(private EntityManagerInterface $entityManager) { $this->repository = $entityManager->getRepository(Evaluation::class); } @@ -65,4 +69,79 @@ final readonly class EvaluationRepository implements EvaluationRepositoryInterfa { return Evaluation::class; } + + public function getResult( + QueryBuilder $qb, + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = [], + ): array { + $qb->select('e'); + + $qb + ->setFirstResult($start) + ->setMaxResults($limit); + + foreach ($orderBy as $field => $direction) { + $qb->addOrderBy('e.'.$field, $direction); + } + + return $qb->getQuery()->getResult(); + } + + private function queryByTitle(string $pattern): QueryBuilder + { + $qb = $this->entityManager->createQueryBuilder()->from(Evaluation::class, 'e'); + + $qb->expr()->like('e.title', 'CONCAT(\'%\', LOWER(UNACCENT(:pattern)), \'%\')'); + + $qb->setParameter('pattern', $pattern); + + return $qb; + } + + public function buildFilterBaseQuery(?string $queryString, array $isActive): QueryBuilder + { + if (null !== $queryString) { + $qb = $this->queryByTitle($queryString); + } else { + $qb = $this->entityManager->createQueryBuilder()->from(Evaluation::class, 'e'); + } + + // Add condition based on active/inactive status + if (in_array('Active', $isActive, true) && !in_array('Inactive', $isActive, true)) { + $qb->andWhere('e.active = true'); + } elseif (in_array('Inactive', $isActive, true) && !in_array('Active', $isActive, true)) { + $qb->andWhere('e.active = false'); + } + + return $qb; + } + + public function findFilteredEvaluations( + ?string $queryString = null, + array $isActive = ['active'], + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = ['title' => 'ASC'], + ): array { + $qb = $this->buildFilterBaseQuery($queryString, $isActive); + + return $this->getResult($qb, $start, $limit, $orderBy); + } + + public function countFilteredEvaluations( + ?string $queryString = null, + array $isActive = ['active'], + ): int { + $qb = $this->buildFilterBaseQuery($queryString, $isActive); + + try { + return $qb + ->select('COUNT(e)') + ->getQuery()->getSingleScalarResult(); + } catch (NoResultException|NonUniqueResultException $e) { + throw new \LogicException('a count query should return one result', previous: $e); + } + } } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Evaluation/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Evaluation/index.html.twig index 556065e42..af7989b8f 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Evaluation/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Evaluation/index.html.twig @@ -2,6 +2,9 @@ {% block admin_content %} {% embed '@ChillMain/CRUD/_index.html.twig' %} + + {% block filter_order %}{{ filter_order|chill_render_filter_order_helper }}{% endblock %} + {% block table_entities_thead_tr %} {{ 'Id'|trans }} {{ 'Title'|trans }} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Goal/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Goal/index.html.twig index 14e9bab73..eac9d4bfc 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Goal/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Goal/index.html.twig @@ -2,6 +2,9 @@ {% block admin_content %} {% embed '@ChillMain/CRUD/_index.html.twig' %} + + {% block filter_order %}{{ filter_order|chill_render_filter_order_helper }}{% endblock %} + {% block table_entities_thead_tr %} {{ 'Id'|trans }} {{ 'Title'|trans }} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Result/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Result/index.html.twig index da9e71bc5..85286ab5b 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Result/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/Result/index.html.twig @@ -2,6 +2,9 @@ {% block admin_content %} {% embed '@ChillMain/CRUD/_index.html.twig' %} + + {% block filter_order %}{{ filter_order|chill_render_filter_order_helper }}{% endblock %} + {% block table_entities_thead_tr %} {{ 'Id'|trans }} {{ 'Title'|trans }} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialAction/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialAction/index.html.twig index 152b8981c..003965667 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialAction/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialAction/index.html.twig @@ -2,6 +2,9 @@ {% block admin_content %} {% embed '@ChillMain/CRUD/_index.html.twig' %} + + {% block filter_order %}{{ filter_order|chill_render_filter_order_helper }}{% endblock %} + {% block table_entities_thead_tr %} {{ 'Id' }} {{ 'Title'|trans }} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialIssue/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialIssue/index.html.twig index 7ca3c6636..9eb786b22 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialIssue/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialIssue/index.html.twig @@ -2,6 +2,9 @@ {% block admin_content %} {% embed '@ChillMain/CRUD/_index.html.twig' %} + + {% block filter_order %}{{ filter_order|chill_render_filter_order_helper }}{% endblock %} + {% block table_entities_thead_tr %} {{ 'Id'|trans }} {{ 'Title'|trans }} From 9af4d19744e2f6dc7f284993860152d8b1b2fa13 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 9 Dec 2025 17:07:05 +0100 Subject: [PATCH 2/5] Add repository methods for filtering --- .../SocialWork/EvaluationRepository.php | 16 ++- .../Repository/SocialWork/GoalRepository.php | 101 +++++++++++++++++- .../SocialWork/ResultRepository.php | 99 ++++++++++++++++- .../SocialWork/SocialActionRepository.php | 99 ++++++++++++++++- .../SocialWork/SocialIssueRepository.php | 99 ++++++++++++++++- 5 files changed, 406 insertions(+), 8 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php b/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php index b09ee57b8..e97640e4b 100644 --- a/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php @@ -18,12 +18,13 @@ use Doctrine\ORM\EntityRepository; use Doctrine\ORM\NonUniqueResultException; use Doctrine\ORM\NoResultException; use Doctrine\ORM\QueryBuilder; +use Symfony\Component\HttpFoundation\RequestStack; final readonly class EvaluationRepository implements EvaluationRepositoryInterface { private EntityRepository $repository; - public function __construct(private EntityManagerInterface $entityManager) + public function __construct(private EntityManagerInterface $entityManager, private RequestStack $requestStack) { $this->repository = $entityManager->getRepository(Evaluation::class); } @@ -70,6 +71,11 @@ final readonly class EvaluationRepository implements EvaluationRepositoryInterfa return Evaluation::class; } + private function getLang(): string + { + return $this->requestStack->getCurrentRequest()?->getLocale() ?? 'fr'; + } + public function getResult( QueryBuilder $qb, ?int $start = 0, @@ -93,9 +99,11 @@ final readonly class EvaluationRepository implements EvaluationRepositoryInterfa { $qb = $this->entityManager->createQueryBuilder()->from(Evaluation::class, 'e'); - $qb->expr()->like('e.title', 'CONCAT(\'%\', LOWER(UNACCENT(:pattern)), \'%\')'); - - $qb->setParameter('pattern', $pattern); + // Extract the current locale's value from the JSON `title` and search on it + $qb + ->where($qb->expr()->like('LOWER(UNACCENT(JSON_EXTRACT(e.title, :lang)))', "CONCAT('%', LOWER(UNACCENT(:pattern)), '%')")) + ->setParameter('pattern', $pattern) + ->setParameter('lang', $this->getLang()); return $qb; } diff --git a/src/Bundle/ChillPersonBundle/Repository/SocialWork/GoalRepository.php b/src/Bundle/ChillPersonBundle/Repository/SocialWork/GoalRepository.php index ec89c597d..ac25445f4 100644 --- a/src/Bundle/ChillPersonBundle/Repository/SocialWork/GoalRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/SocialWork/GoalRepository.php @@ -15,14 +15,17 @@ use Chill\PersonBundle\Entity\SocialWork\Goal; use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\NonUniqueResultException; +use Doctrine\ORM\NoResultException; use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ObjectRepository; +use Symfony\Component\HttpFoundation\RequestStack; final readonly class GoalRepository implements ObjectRepository { private EntityRepository $repository; - public function __construct(EntityManagerInterface $entityManager) + public function __construct(private EntityManagerInterface $entityManager, private RequestStack $requestStack) { $this->repository = $entityManager->getRepository(Goal::class); } @@ -101,6 +104,102 @@ final readonly class GoalRepository implements ObjectRepository return Goal::class; } + private function getLang(): string + { + return $this->requestStack->getCurrentRequest()?->getLocale() ?? 'fr'; + } + + public function getResult( + QueryBuilder $qb, + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = [], + ): array { + $qb->select('g'); + + $qb + ->setFirstResult($start) + ->setMaxResults($limit); + + foreach ($orderBy as $field => $direction) { + $qb->addOrderBy('g.'.$field, $direction); + } + + return $qb->getQuery()->getResult(); + } + + private function queryByTitle(string $pattern): QueryBuilder + { + $qb = $this->entityManager->createQueryBuilder()->from(Goal::class, 'g'); + + // search across locales by extracting the localized value + $qb + ->where($qb->expr()->like('LOWER(UNACCENT(JSON_EXTRACT(g.title, :lang)))', "CONCAT('%', LOWER(UNACCENT(:pattern)), '%')")) + ->setParameter('pattern', $pattern) + ->setParameter('lang', $this->getLang()); + + return $qb; + } + + public function buildFilterBaseQuery(?string $queryString, array $isActive): QueryBuilder + { + if (null !== $queryString) { + $qb = $this->queryByTitle($queryString); + } else { + $qb = $this->entityManager->createQueryBuilder()->from(Goal::class, 'g'); + } + + // Active when desactivationDate is null or in the future + $now = new \DateTime('now'); + if (in_array('Active', $isActive, true) && !in_array('Inactive', $isActive, true)) { + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->isNull('g.desactivationDate'), + $qb->expr()->gt('g.desactivationDate', ':now') + ) + )->setParameter('now', $now); + } elseif (in_array('Inactive', $isActive, true) && !in_array('Active', $isActive, true)) { + $qb->andWhere( + $qb->expr()->andX( + $qb->expr()->isNotNull('g.desactivationDate'), + $qb->expr()->lte('g.desactivationDate', ':now') + ) + )->setParameter('now', $now); + } + + return $qb; + } + + /** + * @return array + */ + public function findFilteredGoals( + ?string $queryString = null, + array $isActive = ['active'], + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = ['id' => 'ASC'], + ): array { + $qb = $this->buildFilterBaseQuery($queryString, $isActive); + + return $this->getResult($qb, $start, $limit, $orderBy); + } + + public function countFilteredGoals( + ?string $queryString = null, + array $isActive = ['active'], + ): int { + $qb = $this->buildFilterBaseQuery($queryString, $isActive); + + try { + return $qb + ->select('COUNT(g)') + ->getQuery()->getSingleScalarResult(); + } catch (NoResultException|NonUniqueResultException $e) { + throw new \LogicException('a count query should return one result', previous: $e); + } + } + private function buildQueryBySocialActionWithDescendants(SocialAction $action): QueryBuilder { $actions = $action->getDescendantsWithThis(); diff --git a/src/Bundle/ChillPersonBundle/Repository/SocialWork/ResultRepository.php b/src/Bundle/ChillPersonBundle/Repository/SocialWork/ResultRepository.php index 0d470d2d7..9e80ec491 100644 --- a/src/Bundle/ChillPersonBundle/Repository/SocialWork/ResultRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/SocialWork/ResultRepository.php @@ -16,14 +16,17 @@ use Chill\PersonBundle\Entity\SocialWork\Result; use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\NonUniqueResultException; +use Doctrine\ORM\NoResultException; use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ObjectRepository; +use Symfony\Component\HttpFoundation\RequestStack; final readonly class ResultRepository implements ObjectRepository { private EntityRepository $repository; - public function __construct(EntityManagerInterface $entityManager) + public function __construct(private EntityManagerInterface $entityManager, private RequestStack $requestStack) { $this->repository = $entityManager->getRepository(Result::class); } @@ -125,6 +128,100 @@ final readonly class ResultRepository implements ObjectRepository return Result::class; } + private function getLang(): string + { + return $this->requestStack->getCurrentRequest()?->getLocale() ?? 'fr'; + } + + public function getResult( + QueryBuilder $qb, + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = [], + ): array { + $qb->select('r'); + + $qb + ->setFirstResult($start) + ->setMaxResults($limit); + + foreach ($orderBy as $field => $direction) { + $qb->addOrderBy('r.'.$field, $direction); + } + + return $qb->getQuery()->getResult(); + } + + private function queryByTitle(string $pattern): QueryBuilder + { + $qb = $this->entityManager->createQueryBuilder()->from(Result::class, 'r'); + + $qb + ->where($qb->expr()->like('LOWER(UNACCENT(JSON_EXTRACT(r.title, :lang)))', "CONCAT('%', LOWER(UNACCENT(:pattern)), '%')")) + ->setParameter('pattern', $pattern) + ->setParameter('lang', $this->getLang()); + + return $qb; + } + + public function buildFilterBaseQuery(?string $queryString, array $isActive): QueryBuilder + { + if (null !== $queryString) { + $qb = $this->queryByTitle($queryString); + } else { + $qb = $this->entityManager->createQueryBuilder()->from(Result::class, 'r'); + } + + $now = new \DateTime('now'); + if (in_array('Active', $isActive, true) && !in_array('Inactive', $isActive, true)) { + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->isNull('r.desactivationDate'), + $qb->expr()->gt('r.desactivationDate', ':now') + ) + )->setParameter('now', $now); + } elseif (in_array('Inactive', $isActive, true) && !in_array('Active', $isActive, true)) { + $qb->andWhere( + $qb->expr()->andX( + $qb->expr()->isNotNull('r.desactivationDate'), + $qb->expr()->lte('r.desactivationDate', ':now') + ) + )->setParameter('now', $now); + } + + return $qb; + } + + /** + * @return array + */ + public function findFilteredResults( + ?string $queryString = null, + array $isActive = ['active'], + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = ['id' => 'ASC'], + ): array { + $qb = $this->buildFilterBaseQuery($queryString, $isActive); + + return $this->getResult($qb, $start, $limit, $orderBy); + } + + public function countFilteredResults( + ?string $queryString = null, + array $isActive = ['active'], + ): int { + $qb = $this->buildFilterBaseQuery($queryString, $isActive); + + try { + return $qb + ->select('COUNT(r)') + ->getQuery()->getSingleScalarResult(); + } catch (NoResultException|NonUniqueResultException $e) { + throw new \LogicException('a count query should return one result', previous: $e); + } + } + private function buildQueryByGoal(Goal $goal): QueryBuilder { $qb = $this->repository->createQueryBuilder('r'); diff --git a/src/Bundle/ChillPersonBundle/Repository/SocialWork/SocialActionRepository.php b/src/Bundle/ChillPersonBundle/Repository/SocialWork/SocialActionRepository.php index 4d37cb3d4..81da2c60c 100644 --- a/src/Bundle/ChillPersonBundle/Repository/SocialWork/SocialActionRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/SocialWork/SocialActionRepository.php @@ -14,14 +14,17 @@ namespace Chill\PersonBundle\Repository\SocialWork; use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\NonUniqueResultException; +use Doctrine\ORM\NoResultException; use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ObjectRepository; +use Symfony\Component\HttpFoundation\RequestStack; final readonly class SocialActionRepository implements ObjectRepository { private EntityRepository $repository; - public function __construct(EntityManagerInterface $entityManager) + public function __construct(private EntityManagerInterface $entityManager, private RequestStack $requestStack) { $this->repository = $entityManager->getRepository(SocialAction::class); } @@ -84,6 +87,100 @@ final readonly class SocialActionRepository implements ObjectRepository return SocialAction::class; } + private function getLang(): string + { + return $this->requestStack->getCurrentRequest()?->getLocale() ?? 'fr'; + } + + public function getResult( + QueryBuilder $qb, + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = [], + ): array { + $qb->select('sa'); + + $qb + ->setFirstResult($start) + ->setMaxResults($limit); + + foreach ($orderBy as $field => $direction) { + $qb->addOrderBy('sa.'.$field, $direction); + } + + return $qb->getQuery()->getResult(); + } + + private function queryByTitle(string $pattern): QueryBuilder + { + $qb = $this->entityManager->createQueryBuilder()->from(SocialAction::class, 'sa'); + + $qb + ->where($qb->expr()->like('LOWER(UNACCENT(JSON_EXTRACT(sa.title, :lang)))', "CONCAT('%', LOWER(UNACCENT(:pattern)), '%')")) + ->setParameter('pattern', $pattern) + ->setParameter('lang', $this->getLang()); + + return $qb; + } + + public function buildFilterBaseQuery(?string $queryString, array $isActive): QueryBuilder + { + if (null !== $queryString) { + $qb = $this->queryByTitle($queryString); + } else { + $qb = $this->entityManager->createQueryBuilder()->from(SocialAction::class, 'sa'); + } + + $now = new \DateTime('now'); + if (in_array('Active', $isActive, true) && !in_array('Inactive', $isActive, true)) { + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->isNull('sa.desactivationDate'), + $qb->expr()->gt('sa.desactivationDate', ':now') + ) + )->setParameter('now', $now); + } elseif (in_array('Inactive', $isActive, true) && !in_array('Active', $isActive, true)) { + $qb->andWhere( + $qb->expr()->andX( + $qb->expr()->isNotNull('sa.desactivationDate'), + $qb->expr()->lte('sa.desactivationDate', ':now') + ) + )->setParameter('now', $now); + } + + return $qb; + } + + /** + * @return array + */ + public function findFilteredSocialActions( + ?string $queryString = null, + array $isActive = ['active'], + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = ['ordering' => 'ASC'], + ): array { + $qb = $this->buildFilterBaseQuery($queryString, $isActive); + + return $this->getResult($qb, $start, $limit, $orderBy); + } + + public function countFilteredSocialActions( + ?string $queryString = null, + array $isActive = ['active'], + ): int { + $qb = $this->buildFilterBaseQuery($queryString, $isActive); + + try { + return $qb + ->select('COUNT(sa)') + ->getQuery()->getSingleScalarResult(); + } catch (NoResultException|NonUniqueResultException $e) { + throw new \LogicException('a count query should return one result', previous: $e); + } + } + private function buildQueryWithDesactivatedDateCriteria(): QueryBuilder { $qb = $this->repository->createQueryBuilder('sa'); diff --git a/src/Bundle/ChillPersonBundle/Repository/SocialWork/SocialIssueRepository.php b/src/Bundle/ChillPersonBundle/Repository/SocialWork/SocialIssueRepository.php index 40ec35855..638e1a869 100644 --- a/src/Bundle/ChillPersonBundle/Repository/SocialWork/SocialIssueRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/SocialWork/SocialIssueRepository.php @@ -14,14 +14,17 @@ namespace Chill\PersonBundle\Repository\SocialWork; use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\NonUniqueResultException; +use Doctrine\ORM\NoResultException; use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ObjectRepository; +use Symfony\Component\HttpFoundation\RequestStack; final readonly class SocialIssueRepository implements ObjectRepository { private EntityRepository $repository; - public function __construct(EntityManagerInterface $entityManager) + public function __construct(private EntityManagerInterface $entityManager, private RequestStack $requestStack) { $this->repository = $entityManager->getRepository(SocialIssue::class); } @@ -79,6 +82,100 @@ final readonly class SocialIssueRepository implements ObjectRepository return SocialIssue::class; } + public function getResult( + QueryBuilder $qb, + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = [], + ): array { + $qb->select('si'); + + $qb + ->setFirstResult($start) + ->setMaxResults($limit); + + foreach ($orderBy as $field => $direction) { + $qb->addOrderBy('si.'.$field, $direction); + } + + return $qb->getQuery()->getResult(); + } + + private function getLang(): string + { + return $this->requestStack->getCurrentRequest()?->getLocale() ?? 'fr'; + } + + private function queryByTitle(string $pattern): QueryBuilder + { + $qb = $this->entityManager->createQueryBuilder()->from(SocialIssue::class, 'si'); + + $qb + ->where($qb->expr()->like('LOWER(UNACCENT(JSON_EXTRACT(si.title, :lang)))', "CONCAT('%', LOWER(UNACCENT(:pattern)), '%')")) + ->setParameter('pattern', $pattern) + ->setParameter('lang', $this->getLang()); + + return $qb; + } + + public function buildFilterBaseQuery(?string $queryString, array $isActive): QueryBuilder + { + if (null !== $queryString) { + $qb = $this->queryByTitle($queryString); + } else { + $qb = $this->entityManager->createQueryBuilder()->from(SocialIssue::class, 'si'); + } + + $now = new \DateTime('now'); + if (in_array('Active', $isActive, true) && !in_array('Inactive', $isActive, true)) { + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->isNull('si.desactivationDate'), + $qb->expr()->gt('si.desactivationDate', ':now') + ) + )->setParameter('now', $now); + } elseif (in_array('Inactive', $isActive, true) && !in_array('Active', $isActive, true)) { + $qb->andWhere( + $qb->expr()->andX( + $qb->expr()->isNotNull('si.desactivationDate'), + $qb->expr()->lte('si.desactivationDate', ':now') + ) + )->setParameter('now', $now); + } + + return $qb; + } + + /** + * @return array + */ + public function findFilteredSocialIssues( + ?string $queryString = null, + array $isActive = ['active'], + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = ['ordering' => 'ASC'], + ): array { + $qb = $this->buildFilterBaseQuery($queryString, $isActive); + + return $this->getResult($qb, $start, $limit, $orderBy); + } + + public function countFilteredSocialIssues( + ?string $queryString = null, + array $isActive = ['active'], + ): int { + $qb = $this->buildFilterBaseQuery($queryString, $isActive); + + try { + return $qb + ->select('COUNT(si)') + ->getQuery()->getSingleScalarResult(); + } catch (NoResultException|NonUniqueResultException $e) { + throw new \LogicException('a count query should return one result', previous: $e); + } + } + private function buildQueryWithDesactivatedDateCriteria(): QueryBuilder { $qb = $this->repository->createQueryBuilder('si'); From 98cbfed054a2db63d90e981f9ee8251831db4d98 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 9 Dec 2025 17:07:42 +0100 Subject: [PATCH 3/5] Add filtering methods to controllers --- .../Controller/SocialWork/GoalController.php | 31 +++++++++++++++++++ .../SocialWork/ResultController.php | 31 +++++++++++++++++++ .../SocialWork/SocialActionController.php | 31 +++++++++++++++++++ .../SocialWork/SocialIssueController.php | 31 +++++++++++++++++++ 4 files changed, 124 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php index 1655356bc..1899e53a9 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php @@ -14,10 +14,12 @@ namespace Chill\PersonBundle\Controller\SocialWork; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; +use Chill\PersonBundle\Repository\SocialWork\GoalRepository; use Symfony\Component\HttpFoundation\Request; class GoalController extends CRUDController { + public function __construct(private readonly GoalRepository $repository) {} protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { $query->addOrderBy('e.id', 'ASC'); @@ -25,6 +27,35 @@ class GoalController extends CRUDController return parent::orderQuery($action, $query, $request, $paginator); } + protected function getQueryResult( + string $action, + Request $request, + int $totalItems, + PaginatorInterface $paginator, + ?FilterOrderHelper $filterOrder = null, + ) { + if (0 === $totalItems) { + return []; + } + + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::getQueryResult($action, $request, $totalItems, $paginator, $filterOrder); + } + + $queryString = $filterOrder->getQueryString(); + $activeFilter = $filterOrder->getCheckboxData('activeFilter'); + $nb = $this->repository->countFilteredGoals($queryString, $activeFilter); + + $paginator = $this->getPaginatorFactory()->create($nb); + + return $this->repository->findFilteredGoals( + $queryString, + $activeFilter, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage() + ); + } + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper { return $this->getFilterOrderHelperFactory() diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php index 775106a40..ac068f664 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php @@ -14,10 +14,12 @@ namespace Chill\PersonBundle\Controller\SocialWork; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; +use Chill\PersonBundle\Repository\SocialWork\ResultRepository; use Symfony\Component\HttpFoundation\Request; class ResultController extends CRUDController { + public function __construct(private readonly ResultRepository $repository) {} protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { $query->addOrderBy('e.id', 'ASC'); @@ -25,6 +27,35 @@ class ResultController extends CRUDController return parent::orderQuery($action, $query, $request, $paginator); } + protected function getQueryResult( + string $action, + Request $request, + int $totalItems, + PaginatorInterface $paginator, + ?FilterOrderHelper $filterOrder = null, + ) { + if (0 === $totalItems) { + return []; + } + + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::getQueryResult($action, $request, $totalItems, $paginator, $filterOrder); + } + + $queryString = $filterOrder->getQueryString(); + $activeFilter = $filterOrder->getCheckboxData('activeFilter'); + $nb = $this->repository->countFilteredResults($queryString, $activeFilter); + + $paginator = $this->getPaginatorFactory()->create($nb); + + return $this->repository->findFilteredResults( + $queryString, + $activeFilter, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage() + ); + } + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper { return $this->getFilterOrderHelperFactory() diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php index a54c411f7..b3bf127fa 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php @@ -14,10 +14,12 @@ namespace Chill\PersonBundle\Controller\SocialWork; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; +use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository; use Symfony\Component\HttpFoundation\Request; class SocialActionController extends CRUDController { + public function __construct(private readonly SocialActionRepository $repository) {} protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { $query->addOrderBy('e.ordering', 'ASC'); @@ -25,6 +27,35 @@ class SocialActionController extends CRUDController return parent::orderQuery($action, $query, $request, $paginator); } + protected function getQueryResult( + string $action, + Request $request, + int $totalItems, + PaginatorInterface $paginator, + ?FilterOrderHelper $filterOrder = null, + ) { + if (0 === $totalItems) { + return []; + } + + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::getQueryResult($action, $request, $totalItems, $paginator, $filterOrder); + } + + $queryString = $filterOrder->getQueryString(); + $activeFilter = $filterOrder->getCheckboxData('activeFilter'); + $nb = $this->repository->countFilteredSocialActions($queryString, $activeFilter); + + $paginator = $this->getPaginatorFactory()->create($nb); + + return $this->repository->findFilteredSocialActions( + $queryString, + $activeFilter, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage() + ); + } + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper { return $this->getFilterOrderHelperFactory() diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php index d47a56a8a..f92daad8a 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php @@ -14,11 +14,13 @@ namespace Chill\PersonBundle\Controller\SocialWork; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; +use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; class SocialIssueController extends CRUDController { + public function __construct(private readonly SocialIssueRepository $repository) {} protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface { if ('new' === $action) { @@ -39,6 +41,35 @@ class SocialIssueController extends CRUDController return parent::orderQuery($action, $query, $request, $paginator); } + protected function getQueryResult( + string $action, + Request $request, + int $totalItems, + PaginatorInterface $paginator, + ?FilterOrderHelper $filterOrder = null, + ) { + if (0 === $totalItems) { + return []; + } + + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::getQueryResult($action, $request, $totalItems, $paginator, $filterOrder); + } + + $queryString = $filterOrder->getQueryString(); + $activeFilter = $filterOrder->getCheckboxData('activeFilter'); + $nb = $this->repository->countFilteredSocialIssues($queryString, $activeFilter); + + $paginator = $this->getPaginatorFactory()->create($nb); + + return $this->repository->findFilteredSocialIssues( + $queryString, + $activeFilter, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage() + ); + } + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper { return $this->getFilterOrderHelperFactory() From 08897e09814e19c71e0ded537ef8a4d78c1ac5b0 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 10 Dec 2025 03:19:38 +0100 Subject: [PATCH 4/5] Fix count of total items for correct paginator display --- .changes/unreleased/Feature-20251210-032045.yaml | 6 ++++++ .../Controller/SocialWork/EvaluationController.php | 12 ++++++++++++ .../Controller/SocialWork/GoalController.php | 12 ++++++++++++ .../Controller/SocialWork/ResultController.php | 12 ++++++++++++ .../Controller/SocialWork/SocialActionController.php | 12 ++++++++++++ .../Controller/SocialWork/SocialIssueController.php | 12 ++++++++++++ 6 files changed, 66 insertions(+) create mode 100644 .changes/unreleased/Feature-20251210-032045.yaml diff --git a/.changes/unreleased/Feature-20251210-032045.yaml b/.changes/unreleased/Feature-20251210-032045.yaml new file mode 100644 index 000000000..67a648b15 --- /dev/null +++ b/.changes/unreleased/Feature-20251210-032045.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: 'Add filtering to admin lists: social actions, social issues, goals, results, and evaluations' +time: 2025-12-10T03:20:45.135973502+01:00 +custom: + Issue: "478" + SchemaChange: No schema change diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php index 4d0aba918..6a933a574 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php @@ -51,6 +51,18 @@ class EvaluationController extends CRUDController return $this->repository->findFilteredEvaluations($queryString, $activeFilter, $paginator->getCurrentPageFirstItemNumber(), $paginator->getItemsPerPage()); } + protected function countEntities(string $action, Request $request, ?FilterOrderHelper $filterOrder = null): int + { + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::countEntities($action, $request, $filterOrder); + } + + return $this->repository->countFilteredEvaluations( + $filterOrder->getQueryString(), + $filterOrder->getCheckboxData('activeFilter') + ); + } + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper { return $this->getFilterOrderHelperFactory() diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php index 1899e53a9..1eef6069e 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php @@ -56,6 +56,18 @@ class GoalController extends CRUDController ); } + protected function countEntities(string $action, Request $request, ?FilterOrderHelper $filterOrder = null): int + { + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::countEntities($action, $request, $filterOrder); + } + + return $this->repository->countFilteredGoals( + $filterOrder->getQueryString(), + $filterOrder->getCheckboxData('activeFilter') + ); + } + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper { return $this->getFilterOrderHelperFactory() diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php index ac068f664..2fc6cb880 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php @@ -56,6 +56,18 @@ class ResultController extends CRUDController ); } + protected function countEntities(string $action, Request $request, ?FilterOrderHelper $filterOrder = null): int + { + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::countEntities($action, $request, $filterOrder); + } + + return $this->repository->countFilteredResults( + $filterOrder->getQueryString(), + $filterOrder->getCheckboxData('activeFilter') + ); + } + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper { return $this->getFilterOrderHelperFactory() diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php index b3bf127fa..6fc82189a 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php @@ -56,6 +56,18 @@ class SocialActionController extends CRUDController ); } + protected function countEntities(string $action, Request $request, ?FilterOrderHelper $filterOrder = null): int + { + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::countEntities($action, $request, $filterOrder); + } + + return $this->repository->countFilteredSocialActions( + $filterOrder->getQueryString(), + $filterOrder->getCheckboxData('activeFilter') + ); + } + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper { return $this->getFilterOrderHelperFactory() diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php index f92daad8a..99fffd6ff 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php @@ -70,6 +70,18 @@ class SocialIssueController extends CRUDController ); } + protected function countEntities(string $action, Request $request, ?FilterOrderHelper $filterOrder = null): int + { + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::countEntities($action, $request, $filterOrder); + } + + return $this->repository->countFilteredSocialIssues( + $filterOrder->getQueryString(), + $filterOrder->getCheckboxData('activeFilter') + ); + } + protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper { return $this->getFilterOrderHelperFactory() From 11d742588332bdcd5a81e084fba9982d8775860c Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 15 Dec 2025 10:48:20 +0100 Subject: [PATCH 5/5] php cs fixes --- .../Controller/SocialWork/EvaluationController.php | 1 + .../ChillPersonBundle/Controller/SocialWork/GoalController.php | 1 + .../ChillPersonBundle/Controller/SocialWork/ResultController.php | 1 + .../Controller/SocialWork/SocialActionController.php | 1 + .../Controller/SocialWork/SocialIssueController.php | 1 + .../Repository/SocialWork/EvaluationRepository.php | 1 - 6 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php index 6a933a574..b52dba8b2 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/EvaluationController.php @@ -20,6 +20,7 @@ use Symfony\Component\HttpFoundation\Request; class EvaluationController extends CRUDController { public function __construct(private readonly EvaluationRepository $repository) {} + protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { $query->addOrderBy('e.id', 'ASC'); diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php index 1eef6069e..a746a89f1 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/GoalController.php @@ -20,6 +20,7 @@ use Symfony\Component\HttpFoundation\Request; class GoalController extends CRUDController { public function __construct(private readonly GoalRepository $repository) {} + protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { $query->addOrderBy('e.id', 'ASC'); diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php index 2fc6cb880..9cc8c38b3 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/ResultController.php @@ -20,6 +20,7 @@ use Symfony\Component\HttpFoundation\Request; class ResultController extends CRUDController { public function __construct(private readonly ResultRepository $repository) {} + protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { $query->addOrderBy('e.id', 'ASC'); diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php index 6fc82189a..9bdccda3a 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialActionController.php @@ -20,6 +20,7 @@ use Symfony\Component\HttpFoundation\Request; class SocialActionController extends CRUDController { public function __construct(private readonly SocialActionRepository $repository) {} + protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { $query->addOrderBy('e.ordering', 'ASC'); diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php index 99fffd6ff..df76b60f2 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWork/SocialIssueController.php @@ -21,6 +21,7 @@ use Symfony\Component\HttpFoundation\Request; class SocialIssueController extends CRUDController { public function __construct(private readonly SocialIssueRepository $repository) {} + protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface { if ('new' === $action) { diff --git a/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php b/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php index e97640e4b..e78fdb590 100644 --- a/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php @@ -11,7 +11,6 @@ declare(strict_types=1); namespace Chill\PersonBundle\Repository\SocialWork; -use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\SocialWork\Evaluation; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository;