From aec01df20225dcac630c4bb7a8ca16086509268e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 13 May 2022 16:00:34 +0200 Subject: [PATCH] admin users: filter by name or email --- .../Controller/UserController.php | 57 ++++++++++++++----- .../Repository/UserRepository.php | 23 ++++++-- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/UserController.php b/src/Bundle/ChillMainBundle/Controller/UserController.php index af4c3b6ad..484d878ea 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserController.php @@ -19,6 +19,7 @@ use Chill\MainBundle\Form\UserCurrentLocationType; use Chill\MainBundle\Form\UserPasswordType; use Chill\MainBundle\Form\UserType; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface; use LogicException; @@ -38,24 +39,62 @@ class UserController extends CRUDController { public const FORM_GROUP_CENTER_COMPOSED = 'composed_groupcenter'; - private FilterOrderHelperFactoryInterface $filterOrderHelperFactory; private LoggerInterface $logger; private UserPasswordEncoderInterface $passwordEncoder; + private UserRepository $userRepository; + private ValidatorInterface $validator; + public function __construct( LoggerInterface $chillLogger, ValidatorInterface $validator, UserPasswordEncoderInterface $passwordEncoder, - FilterOrderHelperFactoryInterface $filterOrderHelperFactory + UserRepository $userRepository ) { $this->logger = $chillLogger; + $this->userRepository = $userRepository; $this->validator = $validator; $this->passwordEncoder = $passwordEncoder; - $this->filterOrderHelperFactory = $filterOrderHelperFactory; + } + + protected function countEntities(string $action, Request $request, ?FilterOrderHelper $filterOrder = null): int + { + if (!$filterOrder instanceof FilterOrderHelper) { + return parent::countEntities($action, $request, $filterOrder); + } + + if (null === $filterOrder->getQueryString()) { + return parent::countEntities($action, $request, $filterOrder); + } + + return $this->userRepository->countByUsernameOrEmail($filterOrder->getQueryString()); + } + + 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); + } + + if (null === $filterOrder->getQueryString()) { + return parent::getQueryResult($action, $request, $totalItems, $paginator, $filterOrder); + } + + return $this->userRepository->findByUsernameOrEmail($filterOrder->getQueryString(), ['usernameCanonical' => 'ASC'], + $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber()); } /** @@ -230,15 +269,6 @@ class UserController extends CRUDController ->build(); } - protected function countEntities(string $action, Request $request, ?FilterOrderHelper $filterOrder = null): int - { - if (null === $filterOrder) { - throw new LogicException('filterOrder should not be null'); - } - - return parent::countEntities($action, $request, $filterOrder); - } - protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface { // for "new", add special config @@ -288,7 +318,8 @@ class UserController extends CRUDController protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { - $query->addOrderBy('e.usernameCanonical', 'ASC'); + $query + ->addOrderBy('e.usernameCanonical', 'ASC'); return parent::orderQuery($action, $query, $request, $paginator); } diff --git a/src/Bundle/ChillMainBundle/Repository/UserRepository.php b/src/Bundle/ChillMainBundle/Repository/UserRepository.php index fc3a6e187..79ab5fc3d 100644 --- a/src/Bundle/ChillMainBundle/Repository/UserRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/UserRepository.php @@ -83,10 +83,24 @@ final class UserRepository implements ObjectRepository return $this->findBy(['enabled' => true], $orderBy, $limit, $offset); } - public function findByUsernameOrEmail(string $pattern) + public function findByUsernameOrEmail(string $pattern, ?array $orderBy = [], ?int $limit = null, ?int $offset = null): array { $qb = $this->queryByUsernameOrEmail($pattern); + $qb->select('u'); + + if (null !== $limit) { + $qb->setMaxResults($limit); + } + + if (null !== $offset) { + $qb->setFirstResult($offset); + } + + foreach ($orderBy as $field => $order) { + $qb->addOrderBy('u.'.$field, $order); + } + return $qb->getQuery()->getResult(); } @@ -164,13 +178,14 @@ final class UserRepository implements ObjectRepository private function queryByUsernameOrEmail(string $pattern): QueryBuilder { - $qb = $this->entityManager->createQueryBuilder('u'); + $qb = $this->entityManager->createQueryBuilder()->from(User::class, 'u'); $searchByPattern = $qb->expr()->orX(); $searchByPattern - ->add($qb->expr()->eq('u.usernameCanonical', 'LOWER(UNACCENT(:pattern))')) - ->add($qb->expr()->eq('u.emailCanonical', 'LOWER(UNACCENT(:pattern))')); + ->add($qb->expr()->like('u.usernameCanonical', 'CONCAT(\'%\', LOWER(UNACCENT(:pattern)), \'%\')')) + ->add($qb->expr()->like('u.emailCanonical', 'CONCAT(\'%\', LOWER(UNACCENT(:pattern)), \'%\')')); + $qb ->where($searchByPattern)