aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/UserBundle
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag/UserBundle')
-rw-r--r--src/Wallabag/UserBundle/Controller/ManageController.php71
-rw-r--r--src/Wallabag/UserBundle/Entity/User.php38
-rw-r--r--src/Wallabag/UserBundle/EventListener/CreateConfigListener.php3
-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
6 files changed, 173 insertions, 58 deletions
diff --git a/src/Wallabag/UserBundle/Controller/ManageController.php b/src/Wallabag/UserBundle/Controller/ManageController.php
index 92ee2b41..084f2c67 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")
@@ -47,9 +33,7 @@ class ManageController extends Controller
47 // enable created user by default 33 // enable created user by default
48 $user->setEnabled(true); 34 $user->setEnabled(true);
49 35
50 $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user, [ 36 $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user);
51 'validation_groups' => ['Profile'],
52 ]);
53 $form->handleRequest($request); 37 $form->handleRequest($request);
54 38
55 if ($form->isSubmitted() && $form->isValid()) { 39 if ($form->isSubmitted() && $form->isValid()) {
@@ -146,4 +130,49 @@ class ManageController extends Controller
146 ->getForm() 130 ->getForm()
147 ; 131 ;
148 } 132 }
133
134 /**
135 * @param Request $request
136 * @param int $page
137 *
138 * @Route("/list/{page}", name="user_index", defaults={"page" = 1})
139 *
140 * Default parameter for page is hardcoded (in duplication of the defaults from the Route)
141 * because this controller is also called inside the layout template without any page as argument
142 *
143 * @return \Symfony\Component\HttpFoundation\Response
144 */
145 public function searchFormAction(Request $request, $page = 1)
146 {
147 $em = $this->getDoctrine()->getManager();
148 $qb = $em->getRepository('WallabagUserBundle:User')->createQueryBuilder('u');
149
150 $form = $this->createForm(SearchUserType::class);
151 $form->handleRequest($request);
152
153 if ($form->isSubmitted() && $form->isValid()) {
154 $this->get('logger')->info('searching users');
155
156 $searchTerm = (isset($request->get('search_user')['term']) ? $request->get('search_user')['term'] : '');
157
158 $qb = $em->getRepository('WallabagUserBundle:User')->getQueryBuilderForSearch($searchTerm);
159 }
160
161 $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false);
162 $pagerFanta = new Pagerfanta($pagerAdapter);
163 $pagerFanta->setMaxPerPage(50);
164
165 try {
166 $pagerFanta->setCurrentPage($page);
167 } catch (OutOfRangeCurrentPageException $e) {
168 if ($page > 1) {
169 return $this->redirect($this->generateUrl('user_index', ['page' => $pagerFanta->getNbPages()]), 302);
170 }
171 }
172
173 return $this->render('WallabagUserBundle:Manage:index.html.twig', [
174 'searchForm' => $form->createView(),
175 'users' => $pagerFanta,
176 ]);
177 }
149} 178}
diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php
index 3a167de7..ed6ce331 100644
--- a/src/Wallabag/UserBundle/Entity/User.php
+++ b/src/Wallabag/UserBundle/Entity/User.php
@@ -4,11 +4,11 @@ namespace Wallabag\UserBundle\Entity;
4 4
5use Doctrine\Common\Collections\ArrayCollection; 5use Doctrine\Common\Collections\ArrayCollection;
6use Doctrine\ORM\Mapping as ORM; 6use Doctrine\ORM\Mapping as ORM;
7use JMS\Serializer\Annotation\Groups;
8use JMS\Serializer\Annotation\XmlRoot;
7use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface; 9use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
8use Scheb\TwoFactorBundle\Model\TrustedComputerInterface; 10use Scheb\TwoFactorBundle\Model\TrustedComputerInterface;
9use FOS\UserBundle\Model\User as BaseUser; 11use FOS\UserBundle\Model\User as BaseUser;
10use JMS\Serializer\Annotation\ExclusionPolicy;
11use JMS\Serializer\Annotation\Expose;
12use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 12use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
13use Symfony\Component\Security\Core\User\UserInterface; 13use Symfony\Component\Security\Core\User\UserInterface;
14use Wallabag\ApiBundle\Entity\Client; 14use Wallabag\ApiBundle\Entity\Client;
@@ -18,23 +18,25 @@ use Wallabag\CoreBundle\Entity\Entry;
18/** 18/**
19 * User. 19 * User.
20 * 20 *
21 * @XmlRoot("user")
21 * @ORM\Entity(repositoryClass="Wallabag\UserBundle\Repository\UserRepository") 22 * @ORM\Entity(repositoryClass="Wallabag\UserBundle\Repository\UserRepository")
22 * @ORM\Table(name="`user`") 23 * @ORM\Table(name="`user`")
23 * @ORM\HasLifecycleCallbacks() 24 * @ORM\HasLifecycleCallbacks()
24 * @ExclusionPolicy("all")
25 * 25 *
26 * @UniqueEntity("email") 26 * @UniqueEntity("email")
27 * @UniqueEntity("username") 27 * @UniqueEntity("username")
28 */ 28 */
29class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface 29class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface
30{ 30{
31 /** @Serializer\XmlAttribute */
31 /** 32 /**
32 * @var int 33 * @var int
33 * 34 *
34 * @Expose
35 * @ORM\Column(name="id", type="integer") 35 * @ORM\Column(name="id", type="integer")
36 * @ORM\Id 36 * @ORM\Id
37 * @ORM\GeneratedValue(strategy="AUTO") 37 * @ORM\GeneratedValue(strategy="AUTO")
38 *
39 * @Groups({"user_api"})
38 */ 40 */
39 protected $id; 41 protected $id;
40 42
@@ -42,20 +44,40 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
42 * @var string 44 * @var string
43 * 45 *
44 * @ORM\Column(name="name", type="text", nullable=true) 46 * @ORM\Column(name="name", type="text", nullable=true)
47 *
48 * @Groups({"user_api"})
45 */ 49 */
46 protected $name; 50 protected $name;
47 51
48 /** 52 /**
49 * @var date 53 * @var string
54 *
55 * @Groups({"user_api"})
56 */
57 protected $username;
58
59 /**
60 * @var string
61 *
62 * @Groups({"user_api"})
63 */
64 protected $email;
65
66 /**
67 * @var \DateTime
50 * 68 *
51 * @ORM\Column(name="created_at", type="datetime") 69 * @ORM\Column(name="created_at", type="datetime")
70 *
71 * @Groups({"user_api"})
52 */ 72 */
53 protected $createdAt; 73 protected $createdAt;
54 74
55 /** 75 /**
56 * @var date 76 * @var \DateTime
57 * 77 *
58 * @ORM\Column(name="updated_at", type="datetime") 78 * @ORM\Column(name="updated_at", type="datetime")
79 *
80 * @Groups({"user_api"})
59 */ 81 */
60 protected $updatedAt; 82 protected $updatedAt;
61 83
@@ -135,7 +157,7 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
135 } 157 }
136 158
137 /** 159 /**
138 * @return string 160 * @return \DateTime
139 */ 161 */
140 public function getCreatedAt() 162 public function getCreatedAt()
141 { 163 {
@@ -143,7 +165,7 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
143 } 165 }
144 166
145 /** 167 /**
146 * @return string 168 * @return \DateTime
147 */ 169 */
148 public function getUpdatedAt() 170 public function getUpdatedAt()
149 { 171 {
diff --git a/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php b/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php
index 0bdd1cae..e4d55c19 100644
--- a/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php
+++ b/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php
@@ -5,7 +5,6 @@ namespace Wallabag\UserBundle\EventListener;
5use Doctrine\ORM\EntityManager; 5use Doctrine\ORM\EntityManager;
6use FOS\UserBundle\Event\UserEvent; 6use FOS\UserBundle\Event\UserEvent;
7use FOS\UserBundle\FOSUserEvents; 7use FOS\UserBundle\FOSUserEvents;
8use Symfony\Component\EventDispatcher\EventDispatcherInterface;
9use Symfony\Component\EventDispatcher\EventSubscriberInterface; 8use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10use Wallabag\CoreBundle\Entity\Config; 9use Wallabag\CoreBundle\Entity\Config;
11 10
@@ -47,7 +46,7 @@ class CreateConfigListener implements EventSubscriberInterface
47 ]; 46 ];
48 } 47 }
49 48
50 public function createConfig(UserEvent $event, $eventName = null, EventDispatcherInterface $eventDispatcher = null) 49 public function createConfig(UserEvent $event)
51 { 50 {
52 $config = new Config($event->getUser()); 51 $config = new Config($event->getUser());
53 $config->setTheme($this->theme); 52 $config->setTheme($this->theme);
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>