admin users: filter by name or email

This commit is contained in:
Julien Fastré 2022-05-13 16:00:34 +02:00
parent a9df9f4880
commit aec01df202
2 changed files with 63 additions and 17 deletions

View File

@ -19,6 +19,7 @@ use Chill\MainBundle\Form\UserCurrentLocationType;
use Chill\MainBundle\Form\UserPasswordType; use Chill\MainBundle\Form\UserPasswordType;
use Chill\MainBundle\Form\UserType; use Chill\MainBundle\Form\UserType;
use Chill\MainBundle\Pagination\PaginatorInterface; use Chill\MainBundle\Pagination\PaginatorInterface;
use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface; use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
use LogicException; use LogicException;
@ -38,24 +39,62 @@ class UserController extends CRUDController
{ {
public const FORM_GROUP_CENTER_COMPOSED = 'composed_groupcenter'; public const FORM_GROUP_CENTER_COMPOSED = 'composed_groupcenter';
private FilterOrderHelperFactoryInterface $filterOrderHelperFactory;
private LoggerInterface $logger; private LoggerInterface $logger;
private UserPasswordEncoderInterface $passwordEncoder; private UserPasswordEncoderInterface $passwordEncoder;
private UserRepository $userRepository;
private ValidatorInterface $validator; private ValidatorInterface $validator;
public function __construct( public function __construct(
LoggerInterface $chillLogger, LoggerInterface $chillLogger,
ValidatorInterface $validator, ValidatorInterface $validator,
UserPasswordEncoderInterface $passwordEncoder, UserPasswordEncoderInterface $passwordEncoder,
FilterOrderHelperFactoryInterface $filterOrderHelperFactory UserRepository $userRepository
) { ) {
$this->logger = $chillLogger; $this->logger = $chillLogger;
$this->userRepository = $userRepository;
$this->validator = $validator; $this->validator = $validator;
$this->passwordEncoder = $passwordEncoder; $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(); ->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 protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface
{ {
// for "new", add special config // for "new", add special config
@ -288,7 +318,8 @@ class UserController extends CRUDController
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) 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); return parent::orderQuery($action, $query, $request, $paginator);
} }

View File

@ -83,10 +83,24 @@ final class UserRepository implements ObjectRepository
return $this->findBy(['enabled' => true], $orderBy, $limit, $offset); 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 = $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(); return $qb->getQuery()->getResult();
} }
@ -164,13 +178,14 @@ final class UserRepository implements ObjectRepository
private function queryByUsernameOrEmail(string $pattern): QueryBuilder private function queryByUsernameOrEmail(string $pattern): QueryBuilder
{ {
$qb = $this->entityManager->createQueryBuilder('u'); $qb = $this->entityManager->createQueryBuilder()->from(User::class, 'u');
$searchByPattern = $qb->expr()->orX(); $searchByPattern = $qb->expr()->orX();
$searchByPattern $searchByPattern
->add($qb->expr()->eq('u.usernameCanonical', 'LOWER(UNACCENT(:pattern))')) ->add($qb->expr()->like('u.usernameCanonical', 'CONCAT(\'%\', LOWER(UNACCENT(:pattern)), \'%\')'))
->add($qb->expr()->eq('u.emailCanonical', 'LOWER(UNACCENT(:pattern))')); ->add($qb->expr()->like('u.emailCanonical', 'CONCAT(\'%\', LOWER(UNACCENT(:pattern)), \'%\')'));
$qb $qb
->where($searchByPattern) ->where($searchByPattern)