From 5f3544dba0d92a3a293f748d4300c17ad469c743 Mon Sep 17 00:00:00 2001 From: Damien Date: Fri, 14 Jan 2022 15:23:12 +0100 Subject: [PATCH 1/2] Add filter & sort --- src/Configuration/Parser/GeneralParser.php | 1 + src/Controller/Backend/UserController.php | 14 ++++- src/Repository/UserRepository.php | 35 +++++++++++ templates/users/listing.html.twig | 72 ++++++++++++++++++++++ 4 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/Configuration/Parser/GeneralParser.php b/src/Configuration/Parser/GeneralParser.php index 58a4d97c4..45536d13a 100644 --- a/src/Configuration/Parser/GeneralParser.php +++ b/src/Configuration/Parser/GeneralParser.php @@ -119,6 +119,7 @@ protected function getDefaultConfig(): array 'extensions_allowed' => ['png', 'jpeg', 'jpg', 'gif'], 'default_avatar' => '', ], + 'user_show_sort&filter' => false ]; } } diff --git a/src/Controller/Backend/UserController.php b/src/Controller/Backend/UserController.php index ef545ffb7..a0a208a71 100644 --- a/src/Controller/Backend/UserController.php +++ b/src/Controller/Backend/UserController.php @@ -35,7 +35,17 @@ public function __construct(UserRepository $users) */ public function users(Query $query): Response { - $users = new ArrayAdapter($this->users->findBy([], ['username' => 'ASC'], 1000)); + $order = 'username'; + if ($this->request->get('sortBy')) { + $order = $this->getFromRequest('sortBy'); + } + + $like = ''; + if ($this->request->get('filter')) { + $like = '%' . $this->getFromRequest('filter') . '%'; + } + + $users = new ArrayAdapter($this->users->findUsers($like, $order)); $currentPage = (int) $this->getFromRequest('page', '1'); $users = new Pagerfanta($users); $users->setMaxPerPage(self::PAGESIZE) @@ -45,6 +55,8 @@ public function users(Query $query): Response 'title' => 'controller.user.title', 'subtitle' => 'controller.user.subtitle', 'users' => $users, + 'sortBy' => $this->getFromRequest('sortBy'), + 'filterValue' => $this->getFromRequest('filter'), ]; return $this->render('@bolt/users/listing.html.twig', $twigVars); diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index a0696beb6..2f02fcca8 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -6,10 +6,14 @@ use Bolt\Entity\User; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\Query\Expr; use Doctrine\Persistence\ManagerRegistry; class UserRepository extends ServiceEntityRepository { + /** @var string[] */ + private $userColumns = ['id', 'displayName', 'username', 'roles', 'email', 'lastIp']; + public function __construct(ManagerRegistry $registry) { parent::__construct($registry, User::class); @@ -46,6 +50,25 @@ public function findOneByCredentials(string $username): ?User return $user instanceof User ? $user : null; } + public function findUsers(string $like, string $orderBy = null) + { + $alias = 'user'; + $qb = $this->createQueryBuilder($alias); + + if ($like) { + foreach ($this->userColumns as $col) { + $qb + ->orWhere( + $qb->expr()->like(sprintf('%s.%s', $alias, $col), sprintf(':%s', $col)) + ) + ->setParameter($col, $like); + } + } + $qb->orderBy($this->createSortBy($orderBy, $alias)); + + return $qb->getQuery()->getResult(); + } + public function getFirstAdminUser(): ?User { $qb = $this->createQueryBuilder('user'); @@ -71,4 +94,16 @@ public static function factory(string $displayName = '', string $username = '', return $user; } + + private function createSortBy($order, $alias): Expr\OrderBy + { + if (mb_strpos($order, '-') === 0) { + $direction = 'DESC'; + $order = sprintf('%s.%s', $alias, mb_substr($order, 1)); + } else { + $direction = 'ASC'; + $order = sprintf('%s.%s', $alias, $order); + } + return new Expr\OrderBy($order, $direction); + } } diff --git a/templates/users/listing.html.twig b/templates/users/listing.html.twig index 0c31ec2f6..986852202 100644 --- a/templates/users/listing.html.twig +++ b/templates/users/listing.html.twig @@ -146,4 +146,76 @@ {# The 'aside' section is the right sidebar of the page. If omitted, 'main' will take up the full width. #} {% block aside %} {{ widgets('users_aside_top') }} + + {% if config.get('general/user_show_sort&filter') %} + {% set filterOptions = { + 'id': "id", + 'displayName': "displayName", + 'username': "username", + 'roles': "roles", + 'lastseenAt': "lastseenAt", + 'lastIp': "lastIp" + } %} + +
+
+ {{ macro.icon('star') }} {{ title|trans }} +
+
+

+ {% if is_granted('user:add') %} + + {{ macro.icon('user-plus') }} {{ __('action.add_user') }} + + + {{ macro.icon('user-cog') }} {{ __('action.edit_permissions') }} + + {% endif %} +

+
+
+

+ {{ 'listing.title_sortby'|trans }}: + +

+ +

+ {{ 'listing.title_filterby'|trans }}: + +

+
+ + {{ macro.button('listing.button_filter', 'filter', 'secondary mb-0', {'type': 'submit'}) }} + + {% if sortBy is not empty or filterValue is not empty %} + {{ macro.buttonlink('listing.button_clear', path('bolt_users'), 'times', 'tertiary mb-0') }} + {% endif %} +
+
+
+ {% endif %} {% endblock %} From 3e812d087cdd2bec04fe3f253848aa7ba27e2117 Mon Sep 17 00:00:00 2001 From: Damien Date: Fri, 14 Jan 2022 15:55:06 +0100 Subject: [PATCH 2/2] update config file --- config/bolt/config.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/bolt/config.yaml b/config/bolt/config.yaml index 3cdd4952a..b6c5683fe 100644 --- a/config/bolt/config.yaml +++ b/config/bolt/config.yaml @@ -238,3 +238,6 @@ reset_password_settings: mail_name: "Bolt CMS" mail_subject: "Your password reset request" mail_template: "reset_password/email.html.twig" + +# Adds sorting and filtering users in backend +user_show_sort&filter: true