aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/UserBundle
diff options
context:
space:
mode:
authorThomas Citharel <tcit@tcit.fr>2017-05-04 14:35:14 +0200
committerGitHub <noreply@github.com>2017-05-04 14:35:14 +0200
commit6b76ae3d1f6a061237f983622b2d3708beded368 (patch)
treec0085b25c6ff8eec25f2b785cf985a8e95f25b09 /src/Wallabag/UserBundle
parent3b4502e0e663866e7bac00164fd935fdc92309d6 (diff)
parentb5b6877976bc32f23e51c2fb0f3f973f0d571b10 (diff)
downloadwallabag-6b76ae3d1f6a061237f983622b2d3708beded368.tar.gz
wallabag-6b76ae3d1f6a061237f983622b2d3708beded368.tar.zst
wallabag-6b76ae3d1f6a061237f983622b2d3708beded368.zip
Merge pull request #3060 from wallabag/search-users
Search & paginate users
Diffstat (limited to 'src/Wallabag/UserBundle')
-rw-r--r--src/Wallabag/UserBundle/Controller/ManageController.php67
-rw-r--r--src/Wallabag/UserBundle/Form/SearchUserType.php29
-rw-r--r--src/Wallabag/UserBundle/Repository/UserRepository.php13
-rw-r--r--src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig77
4 files changed, 141 insertions, 45 deletions
diff --git a/src/Wallabag/UserBundle/Controller/ManageController.php b/src/Wallabag/UserBundle/Controller/ManageController.php
index 92ee2b41..1c5c86d4 100644
--- a/src/Wallabag/UserBundle/Controller/ManageController.php
+++ b/src/Wallabag/UserBundle/Controller/ManageController.php
@@ -4,12 +4,15 @@ namespace Wallabag\UserBundle\Controller;
4 4
5use FOS\UserBundle\Event\UserEvent; 5use FOS\UserBundle\Event\UserEvent;
6use FOS\UserBundle\FOSUserEvents; 6use FOS\UserBundle\FOSUserEvents;
7use Pagerfanta\Adapter\DoctrineORMAdapter;
8use Pagerfanta\Exception\OutOfRangeCurrentPageException;
9use Pagerfanta\Pagerfanta;
7use Symfony\Component\HttpFoundation\Request; 10use Symfony\Component\HttpFoundation\Request;
8use Symfony\Bundle\FrameworkBundle\Controller\Controller; 11use Symfony\Bundle\FrameworkBundle\Controller\Controller;
9use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; 12use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
10use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 13use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
11use Wallabag\UserBundle\Entity\User; 14use Wallabag\UserBundle\Entity\User;
12use Wallabag\CoreBundle\Entity\Config; 15use Wallabag\UserBundle\Form\SearchUserType;
13 16
14/** 17/**
15 * User controller. 18 * User controller.
@@ -17,23 +20,6 @@ use Wallabag\CoreBundle\Entity\Config;
17class ManageController extends Controller 20class ManageController extends Controller
18{ 21{
19 /** 22 /**
20 * Lists all User entities.
21 *
22 * @Route("/", name="user_index")
23 * @Method("GET")
24 */
25 public function indexAction()
26 {
27 $em = $this->getDoctrine()->getManager();
28
29 $users = $em->getRepository('WallabagUserBundle:User')->findAll();
30
31 return $this->render('WallabagUserBundle:Manage:index.html.twig', array(
32 'users' => $users,
33 ));
34 }
35
36 /**
37 * Creates a new User entity. 23 * Creates a new User entity.
38 * 24 *
39 * @Route("/new", name="user_new") 25 * @Route("/new", name="user_new")
@@ -146,4 +132,49 @@ class ManageController extends Controller
146 ->getForm() 132 ->getForm()
147 ; 133 ;
148 } 134 }
135
136 /**
137 * @param Request $request
138 * @param int $page
139 *
140 * @Route("/list/{page}", name="user_index", defaults={"page" = 1})
141 *
142 * Default parameter for page is hardcoded (in duplication of the defaults from the Route)
143 * because this controller is also called inside the layout template without any page as argument
144 *
145 * @return \Symfony\Component\HttpFoundation\Response
146 */
147 public function searchFormAction(Request $request, $page = 1)
148 {
149 $em = $this->getDoctrine()->getManager();
150 $qb = $em->getRepository('WallabagUserBundle:User')->createQueryBuilder('u');
151
152 $form = $this->createForm(SearchUserType::class);
153 $form->handleRequest($request);
154
155 if ($form->isSubmitted() && $form->isValid()) {
156 $this->get('logger')->info('searching users');
157
158 $searchTerm = (isset($request->get('search_user')['term']) ? $request->get('search_user')['term'] : '');
159
160 $qb = $em->getRepository('WallabagUserBundle:User')->getQueryBuilderForSearch($searchTerm);
161 }
162
163 $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false);
164 $pagerFanta = new Pagerfanta($pagerAdapter);
165 $pagerFanta->setMaxPerPage(50);
166
167 try {
168 $pagerFanta->setCurrentPage($page);
169 } catch (OutOfRangeCurrentPageException $e) {
170 if ($page > 1) {
171 return $this->redirect($this->generateUrl('user_index', ['page' => $pagerFanta->getNbPages()]), 302);
172 }
173 }
174
175 return $this->render('WallabagUserBundle:Manage:index.html.twig', [
176 'searchForm' => $form->createView(),
177 'users' => $pagerFanta,
178 ]);
179 }
149} 180}
diff --git a/src/Wallabag/UserBundle/Form/SearchUserType.php b/src/Wallabag/UserBundle/Form/SearchUserType.php
new file mode 100644
index 00000000..9ce46ee1
--- /dev/null
+++ b/src/Wallabag/UserBundle/Form/SearchUserType.php
@@ -0,0 +1,29 @@
1<?php
2
3namespace Wallabag\UserBundle\Form;
4
5use Symfony\Component\Form\AbstractType;
6use Symfony\Component\Form\Extension\Core\Type\TextType;
7use Symfony\Component\Form\FormBuilderInterface;
8use Symfony\Component\OptionsResolver\OptionsResolver;
9
10class SearchUserType extends AbstractType
11{
12 public function buildForm(FormBuilderInterface $builder, array $options)
13 {
14 $builder
15 ->setMethod('GET')
16 ->add('term', TextType::class, [
17 'required' => true,
18 'label' => 'user.new.form_search.term_label',
19 ])
20 ;
21 }
22
23 public function configureOptions(OptionsResolver $resolver)
24 {
25 $resolver->setDefaults([
26 'csrf_protection' => false,
27 ]);
28 }
29}
diff --git a/src/Wallabag/UserBundle/Repository/UserRepository.php b/src/Wallabag/UserBundle/Repository/UserRepository.php
index f913f52d..6adbe329 100644
--- a/src/Wallabag/UserBundle/Repository/UserRepository.php
+++ b/src/Wallabag/UserBundle/Repository/UserRepository.php
@@ -52,4 +52,17 @@ class UserRepository extends EntityRepository
52 ->getQuery() 52 ->getQuery()
53 ->getSingleScalarResult(); 53 ->getSingleScalarResult();
54 } 54 }
55
56 /**
57 * Retrieves users filtered with a search term.
58 *
59 * @param string $term
60 *
61 * @return QueryBuilder
62 */
63 public function getQueryBuilderForSearch($term)
64 {
65 return $this->createQueryBuilder('u')
66 ->andWhere('lower(u.username) LIKE lower(:term) OR lower(u.email) LIKE lower(:term) OR lower(u.name) LIKE lower(:term)')->setParameter('term', '%'.$term.'%');
67 }
55} 68}
diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig
index daba29e4..15002632 100644
--- a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig
+++ b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig
@@ -7,37 +7,60 @@
7 <div class="row"> 7 <div class="row">
8 <div class="col s12"> 8 <div class="col s12">
9 <div class="card-panel"> 9 <div class="card-panel">
10 {% if users.getNbPages > 1 %}
11 {{ pagerfanta(users, 'twitter_bootstrap_translated', {'proximity': 1}) }}
12 {% endif %}
10 <div class="row"> 13 <div class="row">
11 <div class="input-field col s12"> 14 <div class="col s6">
12 <p class="help">{{ 'user.description'|trans|raw }}</p> 15 <p class="help">{{ 'user.description'|trans|raw }}</p>
16 </div>
17 <div class="col s6">
18 <div class="input-field">
19 <form name="search_users" method="GET" action="{{ path('user_index')}}">
20 {% if form_errors(searchForm) %}
21 <span class="black-text">{{ form_errors(searchForm) }}</span>
22 {% endif %}
23
24 {% if form_errors(searchForm.term) %}
25 <span class="black-text">{{ form_errors(searchForm.term) }}</span>
26 {% endif %}
13 27
14 <table class="bordered"> 28 {{ form_widget(searchForm.term, { 'attr': {'autocomplete': 'off', 'placeholder': 'user.search.placeholder'} }) }}
15 <thead> 29
16 <tr> 30 {{ form_rest(searchForm) }}
17 <th>{{ 'user.form.username_label'|trans }}</th> 31 </form>
18 <th>{{ 'user.form.email_label'|trans }}</th> 32 </div>
19 <th>{{ 'user.form.last_login_label'|trans }}</th>
20 <th>{{ 'user.list.actions'|trans }}</th>
21 </tr>
22 </thead>
23 <tbody>
24 {% for user in users %}
25 <tr>
26 <td>{{ user.username }}</td>
27 <td>{{ user.email }}</td>
28 <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td>
29 <td>
30 <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a>
31 </td>
32 </tr>
33 {% endfor %}
34 </tbody>
35 </table>
36 <br />
37 <p>
38 <a href="{{ path('user_new') }}" class="waves-effect waves-light btn">{{ 'user.list.create_new_one'|trans }}</a>
39 </p>
40 </div> 33 </div>
34
35 <table class="bordered">
36 <thead>
37 <tr>
38 <th>{{ 'user.form.username_label'|trans }}</th>
39 <th>{{ 'user.form.email_label'|trans }}</th>
40 <th>{{ 'user.form.last_login_label'|trans }}</th>
41 <th>{{ 'user.list.actions'|trans }}</th>
42 </tr>
43 </thead>
44 <tbody>
45 {% for user in users %}
46 <tr>
47 <td>{{ user.username }}</td>
48 <td>{{ user.email }}</td>
49 <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td>
50 <td>
51 <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a>
52 </td>
53 </tr>
54 {% endfor %}
55 </tbody>
56 </table>
57 <br />
58 <p>
59 <a href="{{ path('user_new') }}" class="waves-effect waves-light btn">{{ 'user.list.create_new_one'|trans }}</a>
60 </p>
61 {% if users.getNbPages > 1 %}
62 {{ pagerfanta(users, 'twitter_bootstrap_translated', {'proximity': 1}) }}
63 {% endif %}
41 </div> 64 </div>
42 </div> 65 </div>
43 </div> 66 </div>