1 <?php
declare(strict_types
=1);
4 * This file is part of the Rapsys AirBundle package.
6 * (c) Raphaël Gertz <symfony@rapsys.eu>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Rapsys\AirBundle\Controller
;
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
;
20 use Rapsys\PackBundle\Util\SluggerUtil
;
22 use Rapsys\UserBundle\Controller\DefaultController
;
24 class UserController
extends DefaultController
{
28 public function edit(Request
$request, Registry
$doctrine, UserPasswordEncoderInterface
$encoder, EntityManagerInterface
$manager, SluggerUtil
$slugger, $mail, $hash): Response
{
30 if ($hash != $slugger->hash($mail)) {
32 throw new BadRequestHttpException($this->translator
->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash]));
36 $mail = $slugger->unshort($smail = $mail);
38 //With existing subscriber
39 if (empty($user = $doctrine->getRepository($this->config
['class']['user'])->findOneByMail($mail))) {
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]));
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')) {
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]));
52 //Create the RegisterType form and give the proper parameters
53 $edit = $this->createForm($this->config
['edit']['view']['edit'], $user, [
54 //Set action to register route name and context
55 'action' => $this->generateUrl($this->config
['route']['edit']['name'], ['mail' => $smail, 'hash' => $slugger->hash($smail)]+
$this->config
['route']['edit']['context']),
57 'civility_class' => $this->config
['class']['civility'],
58 //Set civility default
59 'civility_default' => $doctrine->getRepository($this->config
['class']['civility'])->findOneByTitle($this->config
['default']['civility']),
61 'mail' => $this->isGranted('ROLE_ADMIN'),
63 'pseudonym' => $this->isGranted('ROLE_GUEST'),
65 'slug' => $this->isGranted('ROLE_ADMIN'),
70 ]+
$this->config
['edit']['field']);
73 if ($this->isGranted('ROLE_ADMIN')) {
74 //Create the LoginType form and give the proper parameters
75 $reset = $this->createForm($this->config
['edit']['view']['reset'], $user, [
76 //Set action to register route name and context
77 'action' => $this->generateUrl($this->config
['route']['edit']['name'], ['mail' => $smail, 'hash' => $slugger->hash($smail)]+
$this->config
['route']['edit']['context']),
85 if ($request->isMethod('POST')) {
86 //Refill the fields in case the form is not valid.
87 $reset->handleRequest($request);
89 //With reset submitted and valid
90 if ($reset->isSubmitted() && $reset->isValid()) {
92 $data = $reset->getData();
95 $data->setPassword($encoder->encodePassword($data, $data->getPassword()));
98 $manager->persist($data);
100 //Flush to get the ids
104 $this->addFlash('notice', $this->translator
->trans('Account %mail% password updated', ['%mail%' => $mail = $data->getMail()]));
106 //Redirect to cleanup the form
107 return $this->redirectToRoute($this->config
['route']['edit']['name'], ['mail' => $smail = $slugger->short($mail), 'hash' => $slugger->hash($smail)]+
$this->config
['route']['edit']['context']);
112 $this->config
['edit']['view']['context']['reset'] = $reset->createView();
116 if ($request->isMethod('POST')) {
117 //Refill the fields in case the form is not valid.
118 $edit->handleRequest($request);
120 //With edit submitted and valid
121 if ($edit->isSubmitted() && $edit->isValid()) {
123 $data = $edit->getData();
126 if ($this->isGranted('ROLE_ADMIN')) {
127 //With pseudonym and without slug
128 if (!empty($pseudonym = $data->getPseudonym()) && empty($data->getSlug())) {
130 $data->setSlug($slugger->slug($pseudonym));
135 $manager->persist($data);
137 //Try saving in database
139 //Flush to get the ids
143 $this->addFlash('notice', $this->translator
->trans('Account %mail% updated', ['%mail%' => $mail = $data->getMail()]));
145 //Redirect to cleanup the form
146 return $this->redirectToRoute($this->config
['route']['edit']['name'], ['mail' => $smail = $slugger->short($mail), 'hash' => $slugger->hash($smail)]+
$this->config
['route']['edit']['context']);
147 //Catch double slug or mail
148 } catch (UniqueConstraintViolationException
$e) {
149 //Add error message mail already exists
150 $this->addFlash('error', $this->translator
->trans('Account %mail% already exists', ['%mail%' => $data->getMail()]));
154 //XXX: prefer a reset on login to force user unspam action
155 } elseif (!$this->isGranted('ROLE_ADMIN')) {
157 $this->addFlash('notice', $this->translator
->trans('To change your password login with your mail and any password then follow the procedure'));
161 return $this->render(
163 $this->config
['edit']['view']['name'],
165 ['edit' => $edit->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->config
['edit']['view']['context']