]> Raphaël G. Git Repositories - airbundle/blob - Controller/UserController.php
eaec69046d85abdf55da0638fbb1f0ef582d05ca
[airbundle] / Controller / UserController.php
1 <?php declare(strict_types=1);
2
3 /*
4 * This file is part of the Rapsys UserBundle package.
5 *
6 * (c) Raphaël Gertz <symfony@rapsys.eu>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Rapsys\AirBundle\Controller;
13
14 use Doctrine\Bundle\DoctrineBundle\Registry;
15 use Doctrine\ORM\EntityManagerInterface;
16 use Symfony\Component\HttpFoundation\Request;
17 use Symfony\Component\HttpFoundation\Response;
18 use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
19
20 use Rapsys\PackBundle\Util\SluggerUtil;
21
22 use Rapsys\UserBundle\Controller\DefaultController;
23
24 class UserController extends DefaultController {
25 /**
26 * {@inheritdoc}
27 */
28 public function edit(Request $request, Registry $doctrine, UserPasswordEncoderInterface $encoder, EntityManagerInterface $manager, SluggerUtil $slugger, $mail, $hash): Response {
29 //With invalid hash
30 if ($hash != $slugger->hash($mail)) {
31 //Throw bad request
32 throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash]));
33 }
34
35 //Get mail
36 $mail = $slugger->unshort($smail = $mail);
37
38 //With existing subscriber
39 if (empty($user = $doctrine->getRepository($this->config['class']['user'])->findOneByMail($mail))) {
40 //Throw not found
41 //XXX: prevent slugger reverse engineering by not displaying decoded mail
42 throw $this->createNotFoundException($this->translator->trans('Unable to find account %mail%', ['%mail%' => $smail]));
43 }
44
45 //Prevent access when not admin, user is not guest and not currently logged user
46 if (!$this->isGranted('ROLE_ADMIN') && $user != $this->getUser() || !$this->isGranted('IS_AUTHENTICATED_FULLY')) {
47 //Throw access denied
48 //XXX: prevent slugger reverse engineering by not displaying decoded mail
49 throw $this->createAccessDeniedException($this->translator->trans('Unable to access user: %mail%', ['%mail%' => $smail]));
50 }
51
52 //With admin
53 if ($this->isGranted('ROLE_ADMIN')) {
54 //With pseudonym and without slug
55 if (!empty($pseudonym = $user->getPseudonym()) && empty($user->getSlug())) {
56 //Preset slug
57 $user->setSlug($slugger->slug($pseudonym));
58 }
59 }
60
61 //Create the RegisterType form and give the proper parameters
62 $edit = $this->createForm($this->config['edit']['view']['edit'], $user, [
63 //Set action to register route name and context
64 'action' => $this->generateUrl($this->config['route']['edit']['name'], ['mail' => $smail, 'hash' => $slugger->hash($smail)]+$this->config['route']['edit']['context']),
65 //Set civility class
66 'civility_class' => $this->config['class']['civility'],
67 //Set civility default
68 'civility_default' => $doctrine->getRepository($this->config['class']['civility'])->findOneByTitle($this->config['default']['civility']),
69 //Disable mail
70 'mail' => $this->isGranted('ROLE_ADMIN'),
71 //Disable pseudonym
72 'pseudonym' => $this->isGranted('ROLE_GUEST'),
73 //Disable slug
74 'slug' => $this->isGranted('ROLE_ADMIN'),
75 //Disable password
76 'password' => false,
77 //Set method
78 'method' => 'POST'
79 ]+$this->config['edit']['field']);
80
81 //With admin role
82 if ($this->isGranted('ROLE_ADMIN')) {
83 //Create the LoginType form and give the proper parameters
84 $reset = $this->createForm($this->config['edit']['view']['reset'], $user, [
85 //Set action to register route name and context
86 'action' => $this->generateUrl($this->config['route']['edit']['name'], ['mail' => $smail, 'hash' => $slugger->hash($smail)]+$this->config['route']['edit']['context']),
87 //Disable mail
88 'mail' => false,
89 //Set method
90 'method' => 'POST'
91 ]);
92
93 //With post method
94 if ($request->isMethod('POST')) {
95 //Refill the fields in case the form is not valid.
96 $reset->handleRequest($request);
97
98 //With reset submitted and valid
99 if ($reset->isSubmitted() && $reset->isValid()) {
100 //Set data
101 $data = $reset->getData();
102
103 //Set password
104 $data->setPassword($encoder->encodePassword($data, $data->getPassword()));
105
106 //Queue snippet save
107 $manager->persist($data);
108
109 //Flush to get the ids
110 $manager->flush();
111
112 //Add notice
113 $this->addFlash('notice', $this->translator->trans('Account %mail% password updated', ['%mail%' => $mail = $data->getMail()]));
114
115 //Redirect to cleanup the form
116 return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail = $slugger->short($mail), 'hash' => $slugger->hash($smail)]+$this->config['route']['edit']['context']);
117 }
118 }
119
120 //Add reset view
121 $this->config['edit']['view']['context']['reset'] = $reset->createView();
122 //Without admin role
123 //XXX: prefer a reset on login to force user unspam action
124 } else {
125 //Add notice
126 $this->addFlash('notice', $this->translator->trans('To change your password login with your mail and any password then follow the procedure'));
127 }
128
129 //With post method
130 if ($request->isMethod('POST')) {
131 //Refill the fields in case the form is not valid.
132 $edit->handleRequest($request);
133
134 //With edit submitted and valid
135 if ($edit->isSubmitted() && $edit->isValid()) {
136 //Set data
137 $data = $edit->getData();
138
139 //Queue snippet save
140 $manager->persist($data);
141
142 //Try saving in database
143 try {
144 //Flush to get the ids
145 $manager->flush();
146
147 //Add notice
148 $this->addFlash('notice', $this->translator->trans('Account %mail% updated', ['%mail%' => $mail = $data->getMail()]));
149
150 //Redirect to cleanup the form
151 return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail = $slugger->short($mail), 'hash' => $slugger->hash($smail)]+$this->config['route']['edit']['context']);
152 //Catch double slug or mail
153 } catch (UniqueConstraintViolationException $e) {
154 //Add error message mail already exists
155 $this->addFlash('error', $this->translator->trans('Account %mail% or with slug %slug% already exists', ['%mail%' => $data->getMail(), '%slug%' => $slug]));
156 }
157 }
158 }
159
160 //Render view
161 return $this->render(
162 //Template
163 $this->config['edit']['view']['name'],
164 //Context
165 ['edit' => $edit->createView(), 'sent' => $request->query->get('sent', 0)]+$this->config['edit']['view']['context']
166 );
167 }
168 }