# delete: Delete
# delete_confirm: Are you sure?
# back_to_list: Back to list
+ search:
+ # label: Filter
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
delete: Löschen
delete_confirm: Bist du sicher?
back_to_list: Zurück zur Liste
+ search:
+ # label: Filter
+ # placeholder: Filter by username or email
error:
page_title: Ein Fehler ist aufgetreten
delete: Delete
delete_confirm: Are you sure?
back_to_list: Back to list
+ search:
+ label: Filter
+ placeholder: Filter by username or email
error:
page_title: An error occurred
delete: Eliminar
delete_confirm: ¿Estás seguro?
back_to_list: Volver a la lista
+ search:
+ # label: Filter
+ # placeholder: Filter by username or email
error:
page_title: Ha ocurrido un error
# delete: Delete
# delete_confirm: Are you sure?
# back_to_list: Back to list
+ search:
+ # label: Filter
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
delete: "Supprimer"
delete_confirm: "Voulez-vous vraiment ?"
back_to_list: "Revenir à la liste"
+ search:
+ label: Filtrer
+ placeholder: Filtrer par nom d'utilisateur ou email
error:
page_title: Une erreur est survenue
# delete: Delete
# delete_confirm: Are you sure?
# back_to_list: Back to list
+ search:
+ # label: Filter
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
delete: 'Suprimir'
delete_confirm: 'Sètz segur ?'
back_to_list: 'Tornar a la lista'
+ search:
+ # label: Filter
+ # placeholder: Filter by username or email
error:
page_title: Una error s'es produsida
delete: Usuń
delete_confirm: Jesteś pewien?
back_to_list: Powrót do listy
+ search:
+ # label: Filter
+ # placeholder: Filter by username or email
error:
page_title: Wystąpił błąd
delete: 'Apagar'
delete_confirm: 'Tem certeza?'
back_to_list: 'Voltar para a lista'
+ search:
+ # label: Filter
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
# delete: Delete
# delete_confirm: Are you sure?
# back_to_list: Back to list
+ search:
+ # label: Filter
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
# delete: Delete
# delete_confirm: Are you sure?
# back_to_list: Back to list
+ search:
+ # label: Filter
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Wallabag\UserBundle\Entity\User;
use Wallabag\CoreBundle\Entity\Config;
+use Wallabag\UserBundle\Form\SearchUserType;
/**
* User controller.
->getForm()
;
}
+
+ /**
+ * @param Request $request
+ * @param int $page
+ *
+ * @Route("/search/{page}", name="user-search", defaults={"page" = 1})
+ *
+ * Default parameter for page is hardcoded (in duplication of the defaults from the Route)
+ * because this controller is also called inside the layout template without any page as argument
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
+ */
+ public function searchFormAction(Request $request, $page = 1, $currentRoute = null)
+ {
+ // fallback to retrieve currentRoute from query parameter instead of injected one (when using inside a template)
+ if (null === $currentRoute && $request->query->has('currentRoute')) {
+ $currentRoute = $request->query->get('currentRoute');
+ }
+
+ $form = $this->createForm(SearchUserType::class);
+
+ $form->handleRequest($request);
+
+ if ($form->isSubmitted() && $form->isValid()) {
+ $this->get('logger')->info('searching users');
+ $em = $this->getDoctrine()->getManager();
+
+ $searchTerm = (isset($request->get('search_user')['term']) ? $request->get('search_user')['term'] : '');
+
+ $users = $em->getRepository('WallabagUserBundle:User')->getUsersForSearch($searchTerm);
+
+ return $this->render('WallabagUserBundle:Manage:index.html.twig', array(
+ 'users' => $users,
+ ));
+ }
+
+ return $this->render('WallabagUserBundle:Manage:search_form.html.twig', [
+ 'form' => $form->createView(),
+ 'currentRoute' => $currentRoute,
+ ]);
+ }
}
--- /dev/null
+<?php
+
+namespace Wallabag\UserBundle\Form;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class SearchUserType extends AbstractType
+{
+ public function buildForm(FormBuilderInterface $builder, array $options)
+ {
+ $builder
+ ->setMethod('GET')
+ ->add('term', TextType::class, [
+ 'required' => true,
+ 'label' => 'user.new.form_search.term_label',
+ ])
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults([
+ 'csrf_protection' => false,
+ ]);
+ }
+}
->getQuery()
->getSingleScalarResult();
}
+
+ /**
+ * Retrieves users filtered with a search term.
+ *
+ * @param string $term
+ *
+ * @return QueryBuilder
+ */
+ public function getUsersForSearch($term)
+ {
+ return $this->createQueryBuilder('u')
+ ->andWhere('lower(u.username) LIKE lower(:term) OR lower(u.email) LIKE lower(:term) OR lower(u.name) LIKE lower(:term)')->setParameter('term', '%'.$term.'%')
+ ->getQuery()
+ ->getResult();
+ }
}
<div class="col s12">
<div class="card-panel">
<div class="row">
- <div class="input-field col s12">
+ <div class="col s6">
<p class="help">{{ 'user.description'|trans|raw }}</p>
-
- <table class="bordered">
- <thead>
- <tr>
- <th>{{ 'user.form.username_label'|trans }}</th>
- <th>{{ 'user.form.email_label'|trans }}</th>
- <th>{{ 'user.form.last_login_label'|trans }}</th>
- <th>{{ 'user.list.actions'|trans }}</th>
- </tr>
- </thead>
- <tbody>
- {% for user in users %}
- <tr>
- <td>{{ user.username }}</td>
- <td>{{ user.email }}</td>
- <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td>
- <td>
- <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a>
- </td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
- <br />
- <p>
- <a href="{{ path('user_new') }}" class="waves-effect waves-light btn">{{ 'user.list.create_new_one'|trans }}</a>
- </p>
</div>
+ <div class="col s6">
+ <div class="input-field">
+ {{ render(controller("WallabagUserBundle:Manage:searchForm", {'currentRoute': app.request.attributes.get('_route')})) }}
+ </div>
+ </div>
+
+ <table class="bordered">
+ <thead>
+ <tr>
+ <th>{{ 'user.form.username_label'|trans }}</th>
+ <th>{{ 'user.form.email_label'|trans }}</th>
+ <th>{{ 'user.form2017-03-10 16:51:07.last_login_label'|trans }}</th>
+ <th>{{ 'user.list.actions'|trans }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for user in users %}
+ <tr>
+ <td>{{ user.username }}</td>
+ <td>{{ user.email }}</td>
+ <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td>
+ <td>
+ <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ <br />
+ <p>
+ <a href="{{ path('user_new') }}" class="waves-effect waves-light btn">{{ 'user.list.create_new_one'|trans }}</a>
+ </p>
</div>
</div>
</div>
--- /dev/null
+<form name="search" method="GET" action="{{ path('user-search')}}">
+ {% if form_errors(form) %}
+ <span class="black-text">{{ form_errors(form) }}</span>
+ {% endif %}
+
+ {% if form_errors(form.term) %}
+ <span class="black-text">{{ form_errors(form.term) }}</span>
+ {% endif %}
+
+ <i class="material-icons prefix">search</i>
+ {{ form_widget(form.term, { 'attr': {'autocomplete': 'off', 'placeholder': 'user.search.placeholder'} }) }}
+ <label for="search_user_term" class="active">{{ 'user.search.label' | trans }}</label>
+
+ {{ form_rest(form) }}
+</form>