]> Raphaël G. Git Repositories - userbundle/blob - Controller/UserController.php
Use gone http exception for outdated recover links
[userbundle] / 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\UserBundle\Controller;
13
14 use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
15
16 use Rapsys\UserBundle\RapsysUserBundle;
17
18 use Symfony\Bridge\Twig\Mime\TemplatedEmail;
19 use Symfony\Component\Form\FormError;
20 use Symfony\Component\HttpFoundation\Request;
21 use Symfony\Component\HttpFoundation\Response;
22 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
23 use Symfony\Component\HttpKernel\Exception\GoneHttpException;
24 use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
25 use Symfony\Component\Mime\Address;
26 use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
27 use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
28
29 /**
30 * {@inheritdoc}
31 */
32 class UserController extends AbstractController {
33 /**
34 * User index
35 *
36 * @param Request $request The request
37 * @return Response The response
38 */
39 public function index(Request $request): Response {
40 //Without admin
41 if (!$this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin']))) {
42 //Throw 403
43 throw $this->createAccessDeniedException($this->translator->trans('Unable to list users', [], $this->alias));
44 }
45
46 //Get count
47 $this->context['count'] = $this->doctrine->getRepository($this->config['class']['user'])->findCountAsInt();
48
49 //With not enough users
50 if ($this->context['count'] - $this->page * $this->limit < 0) {
51 //Throw 404
52 throw $this->createNotFoundException($this->translator->trans('Unable to find users', [], $this->alias));
53 }
54
55 //Get users by groups
56 $this->context['groups'] = $this->doctrine->getRepository($this->config['class']['user'])->findIndexByGroupId($this->page, $this->limit);
57
58 //Render view
59 return $this->render(
60 //Template
61 $this->config['index']['view']['name'],
62 //Context
63 $this->context+$this->config['index']['view']['context']
64 );
65 }
66
67 /**
68 * Confirm account from mail link
69 *
70 * @param Request $request The request
71 * @param string $hash The hashed password
72 * @param string $mail The shorted mail address
73 * @return Response The response
74 */
75 public function confirm(Request $request, string $hash, string $mail): Response {
76 //With invalid hash
77 if ($hash != $this->slugger->hash($mail)) {
78 //Throw bad request
79 throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias));
80 }
81
82 //Get mail
83 $mail = $this->slugger->unshort($smail = $mail);
84
85 //Without valid mail
86 if (filter_var($mail, FILTER_VALIDATE_EMAIL) === false) {
87 //Throw bad request
88 //XXX: prevent slugger reverse engineering by not displaying decoded mail
89 throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail], $this->alias));
90 }
91
92 //Without existing registrant
93 if (!($user = $this->doctrine->getRepository($this->config['class']['user'])->findOneByMail($mail))) {
94 //Add error message mail already exists
95 //XXX: prevent slugger reverse engineering by not displaying decoded mail
96 $this->addFlash('error', $this->translator->trans('The account do not exists', [], $this->alias));
97
98 //Redirect to register view
99 return $this->redirectToRoute($this->config['route']['register']['name'], $this->config['route']['register']['context']);
100 }
101
102 //Set active
103 $user->setActive(true);
104
105 //Persist user
106 $this->manager->persist($user);
107
108 //Send to database
109 $this->manager->flush();
110
111 //Add error message mail already exists
112 $this->addFlash('notice', $this->translator->trans('Your account has been activated', [], $this->alias));
113
114 //Redirect to user view
115 return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail, 'hash' => $this->slugger->hash($smail)]+$this->config['route']['edit']['context']);
116 }
117
118 /**
119 * Edit account by shorted mail
120 *
121 * @param Request $request The request
122 * @param string $hash The hashed password
123 * @param string $mail The shorted mail address
124 * @return Response The response
125 */
126 public function edit(Request $request, string $hash, string $mail): Response {
127 //With invalid hash
128 if ($hash != $this->slugger->hash($mail)) {
129 //Throw bad request
130 throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias));
131 }
132
133 //Get mail
134 $mail = $this->slugger->unshort($smail = $mail);
135
136 //With existing subscriber
137 if (empty($user = $this->doctrine->getRepository($this->config['class']['user'])->findOneByMail($mail))) {
138 //Throw not found
139 //XXX: prevent slugger reverse engineering by not displaying decoded mail
140 throw $this->createNotFoundException($this->translator->trans('Unable to find account', [], $this->alias));
141 }
142
143 //Prevent access when not admin, user is not guest and not currently logged user
144 if (!$this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin'])) && $user != $this->security->getUser() || !$this->checker->isGranted('IS_AUTHENTICATED_FULLY')) {
145 //Throw access denied
146 //XXX: prevent slugger reverse engineering by not displaying decoded mail
147 throw $this->createAccessDeniedException($this->translator->trans('Unable to access user', [], $this->alias));
148 }
149
150 //Create the EditType form and give the proper parameters
151 $edit = $this->factory->create($this->config['edit']['view']['edit'], $user, [
152 //Set action to edit route name and context
153 'action' => $this->generateUrl($this->config['route']['edit']['name'], ['mail' => $smail, 'hash' => $this->slugger->hash($smail)]+$this->config['route']['edit']['context']),
154 //Set civility class
155 'civility_class' => $this->config['class']['civility'],
156 //Set civility default
157 'civility_default' => $this->doctrine->getRepository($this->config['class']['civility'])->findOneByTitle($this->config['default']['civility']),
158 //Disable mail
159 'mail' => $this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin'])),
160 //Disable password
161 'password' => false,
162 //Set method
163 'method' => 'POST',
164 //Set domain
165 'translation_domain' => $this->alias
166 ]+($this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin']))?$this->config['edit']['admin']:$this->config['edit']['field']));
167
168 //With admin role
169 if ($this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin']))) {
170 //Create the EditType form and give the proper parameters
171 $reset = $this->factory->create($this->config['edit']['view']['reset'], $user, [
172 //Set action to edit route name and context
173 'action' => $this->generateUrl($this->config['route']['edit']['name'], ['mail' => $smail, 'hash' => $this->slugger->hash($smail)]+$this->config['route']['edit']['context']),
174 //Set method
175 'method' => 'POST',
176 //Set domain
177 'translation_domain' => $this->alias
178 ]);
179
180 //With post method
181 if ($request->isMethod('POST')) {
182 //Refill the fields in case the form is not valid.
183 $reset->handleRequest($request);
184
185 //With reset submitted and valid
186 if ($reset->isSubmitted() && $reset->isValid()) {
187 //Set data
188 $data = $reset->getData();
189
190 //Set password
191 $data->setPassword($this->hasher->hashPassword($data, $data->getPassword()));
192
193 //Queue snippet save
194 $this->manager->persist($data);
195
196 //Flush to get the ids
197 $this->manager->flush();
198
199 //Add notice
200 $this->addFlash('notice', $this->translator->trans('Account password updated', [], $this->alias));
201
202 //Redirect to cleanup the form
203 return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail = $this->slugger->short($mail), 'hash' => $this->slugger->hash($smail)]+$this->config['route']['edit']['context']);
204 }
205 }
206
207 //Add reset view
208 $this->config['edit']['view']['context']['reset'] = $reset->createView();
209 }
210
211 //With post method
212 if ($request->isMethod('POST')) {
213 //Refill the fields in case the form is not valid.
214 $edit->handleRequest($request);
215
216 //With edit submitted and valid
217 if ($edit->isSubmitted() && $edit->isValid()) {
218 //Set data
219 $data = $edit->getData();
220
221 //Queue snippet save
222 $this->manager->persist($data);
223
224 //Try saving in database
225 try {
226 //Flush to get the ids
227 $this->manager->flush();
228
229 //Add notice
230 $this->addFlash('notice', $this->translator->trans('Account updated', [], $this->alias));
231
232 //Redirect to cleanup the form
233 return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail = $this->slugger->short($mail), 'hash' => $this->slugger->hash($smail)]+$this->config['route']['edit']['context']);
234 //Catch double slug or mail
235 } catch (UniqueConstraintViolationException $e) {
236 //Add error message mail already exists
237 $this->addFlash('error', $this->translator->trans('The account already exists', [], $this->alias));
238 }
239 }
240 //Without admin role
241 //XXX: prefer a reset on login to force user unspam action
242 } elseif (!$this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin']))) {
243 //Add notice
244 $this->addFlash('notice', $this->translator->trans('To change your password login with your mail and any password then follow the procedure', [], $this->alias));
245 }
246
247 //Render view
248 return $this->render(
249 //Template
250 $this->config['edit']['view']['name'],
251 //Context
252 ['register' => $edit->createView()]+$this->config['edit']['view']['context']
253 );
254 }
255
256 /**
257 * Login
258 *
259 * @param Request $request The request
260 * @param AuthenticationUtils $authenticationUtils The authentication utils
261 * @param ?string $hash The hashed password
262 * @param ?string $mail The shorted mail address
263 * @return Response The response
264 */
265 public function login(Request $request, AuthenticationUtils $authenticationUtils, ?string $hash, ?string $mail): Response {
266 //Create the LoginType form and give the proper parameters
267 $login = $this->factory->create($this->config['login']['view']['form'], null, [
268 //Set action to login route name and context
269 'action' => $this->generateUrl($this->config['route']['login']['name'], $this->config['route']['login']['context']),
270 //Set method
271 'method' => 'POST',
272 //Set domain
273 'translation_domain' => $this->alias
274 ]);
275
276 //Init context
277 $context = [];
278
279 //With mail
280 if (!empty($mail) && !empty($hash)) {
281 //With invalid hash
282 if ($hash != $this->slugger->hash($mail)) {
283 //Throw bad request
284 throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias));
285 }
286
287 //Get mail
288 $mail = $this->slugger->unshort($smail = $mail);
289
290 //Without valid mail
291 if (filter_var($mail, FILTER_VALIDATE_EMAIL) === false) {
292 //Throw bad request
293 throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail], $this->alias));
294 }
295
296 //Prefilled mail
297 $login->get('mail')->setData($mail);
298 //Last username entered by the user
299 } elseif ($lastUsername = $authenticationUtils->getLastUsername()) {
300 $login->get('mail')->setData($lastUsername);
301 }
302
303 //Get the login error if there is one
304 if ($error = $authenticationUtils->getLastAuthenticationError()) {
305 //Get translated error
306 $error = $this->translator->trans($error->getMessageKey(), [], $this->alias);
307
308 //Add error message to mail field
309 $login->get('mail')->addError(new FormError($error));
310
311 //Create the RecoverType form and give the proper parameters
312 $recover = $this->factory->create($this->config['recover']['view']['form'], null, [
313 //Set action to recover route name and context
314 'action' => $this->generateUrl($this->config['route']['recover']['name'], $this->config['route']['recover']['context']),
315 //Without password
316 'password' => false,
317 //Set method
318 'method' => 'POST',
319 //Set domain
320 'translation_domain' => $this->alias
321 ]);
322
323 //Get recover mail entity
324 $recover->get('mail')
325 //Set mail from login form
326 ->setData($login->get('mail')->getData())
327 //Add recover error
328 ->addError(new FormError($this->translator->trans('Use this form to recover your account', [], $this->alias)));
329
330 //Add recover form to context
331 $context['recover'] = $recover->createView();
332 } else {
333 //Add notice
334 $this->addFlash('notice', $this->translator->trans('To change your password login with your mail and any password then follow the procedure', [], $this->alias));
335 }
336
337 //Render view
338 return $this->render(
339 //Template
340 $this->config['login']['view']['name'],
341 //Context
342 ['login' => $login->createView(), 'disabled' => $request->query->get('disabled', 0)]+$context+$this->config['login']['view']['context']
343 );
344 }
345
346 /**
347 * Recover account
348 *
349 * @param Request $request The request
350 * @param ?string $hash The hashed password
351 * @param ?string $pass The shorted password
352 * @param ?string $mail The shorted mail address
353 * @return Response The response
354 */
355 public function recover(Request $request, ?string $hash, ?string $pass, ?string $mail): Response {
356 //Set user
357 $user = null;
358
359 //Set context
360 $context = [];
361
362 //With mail, pass and hash
363 if (!empty($mail) && !empty($pass) && !empty($hash)) {
364 //With invalid hash
365 if ($hash != $this->slugger->hash($mail.$pass)) {
366 //Throw bad request
367 throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias));
368 }
369
370 //Get mail
371 $mail = $this->slugger->unshort($smail = $mail);
372
373 //Without valid mail
374 if (filter_var($mail, FILTER_VALIDATE_EMAIL) === false) {
375 //Throw bad request
376 //XXX: prevent slugger reverse engineering by not displaying decoded mail
377 throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail], $this->alias));
378 }
379
380 //With existing subscriber
381 if (empty($user = $this->doctrine->getRepository($this->config['class']['user'])->findOneByMail($mail))) {
382 //Throw not found
383 //XXX: prevent slugger reverse engineering by not displaying decoded mail
384 throw $this->createNotFoundException($this->translator->trans('Unable to find account', [], $this->alias));
385 }
386
387 //With unmatched pass
388 if ($pass != $this->slugger->hash($user->getPassword())) {
389 //Throw not found
390 //XXX: prevent use of outdated recover link
391 throw new GoneHttpException($this->translator->trans('Outdated recover link', [], $this->alias));
392 }
393
394 //Set context
395 $context = ['mail' => $smail, 'pass' => $pass, 'hash' => $hash];
396 }
397
398 //Create the LoginType form and give the proper parameters
399 $form = $this->factory->create($this->config['recover']['view']['form'], $user, [
400 //Set action to recover route name and context
401 'action' => $this->generateUrl($this->config['route']['recover']['name'], $context+$this->config['route']['recover']['context']),
402 //With user disable mail
403 'mail' => ($user === null),
404 //With user enable password
405 'password' => ($user !== null),
406 //Set method
407 'method' => 'POST',
408 //Set domain
409 'translation_domain' => $this->alias
410 ]);
411
412 //With post method
413 if ($request->isMethod('POST')) {
414 //Refill the fields in case the form is not valid.
415 $form->handleRequest($request);
416
417 //With form submitted and valid
418 if ($form->isSubmitted() && $form->isValid()) {
419 //Set data
420 $data = $form->getData();
421
422 //With user
423 if ($user !== null) {
424 //Set hashed password
425 $hashed = $this->hasher->hashPassword($user, $user->getPassword());
426
427 //Update pass
428 $pass = $this->slugger->hash($hashed);
429
430 //Set user password
431 $user->setPassword($hashed);
432
433 //Persist user
434 $this->manager->persist($user);
435
436 //Send to database
437 $this->manager->flush();
438
439 //Add notice
440 $this->addFlash('notice', $this->translator->trans('Account password updated', [], $this->alias));
441
442 //Redirect to user login
443 return $this->redirectToRoute($this->config['route']['login']['name'], ['mail' => $smail, 'hash' => $this->slugger->hash($smail)]+$this->config['route']['login']['context']);
444 //Find user by data mail
445 } elseif ($user = $this->doctrine->getRepository($this->config['class']['user'])->findOneByMail($data['mail'])) {
446 //Set context
447 $context = [
448 'recipient_mail' => $user->getMail(),
449 'recipient_name' => $user->getRecipientName()
450 ] + array_replace_recursive(
451 $this->config['context'],
452 $this->config['recover']['view']['context'],
453 $this->config['recover']['mail']['context']
454 );
455
456 //Generate each route route
457 foreach($this->config['recover']['route'] as $route => $tag) {
458 //Only process defined routes
459 if (!empty($this->config['route'][$route])) {
460 //Process for recover mail url
461 if ($route == 'recover') {
462 //Set the url in context
463 $context[$tag] = $this->router->generate(
464 $this->config['route'][$route]['name'],
465 //Prepend recover context with tag
466 [
467 'mail' => $smail = $this->slugger->short($context['recipient_mail']),
468 'pass' => $spass = $this->slugger->hash($pass = $user->getPassword()),
469 'hash' => $this->slugger->hash($smail.$spass)
470 ]+$this->config['route'][$route]['context'],
471 UrlGeneratorInterface::ABSOLUTE_URL
472 );
473 }
474 }
475 }
476
477 //Translate subject
478 $context['subject'] = $subject = ucfirst(
479 $this->translator->trans(
480 $this->config['recover']['mail']['subject'],
481 $this->slugger->flatten($context, null, '.', '%', '%'),
482 $this->alias
483 )
484 );
485
486 //Create message
487 $message = (new TemplatedEmail())
488 //Set sender
489 ->from(new Address($this->config['contact']['address'], $this->translator->trans($this->config['contact']['name'], [], $this->alias)))
490 //Set recipient
491 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46
492 ->to(new Address($context['recipient_mail'], $context['recipient_name']))
493 //Set subject
494 ->subject($context['subject'])
495
496 //Set path to twig templates
497 ->htmlTemplate($this->config['recover']['mail']['html'])
498 ->textTemplate($this->config['recover']['mail']['text'])
499
500 //Set context
501 ->context($context);
502
503 //Add created notice
504 $this->addFlash('notice', $this->translator->trans('Account recovered', [], $this->alias));
505
506 //Try sending message
507 //XXX: mail delivery may silently fail
508 try {
509 //Send message
510 $this->mailer->send($message);
511
512 //Add sent notice
513 $this->addFlash('notice', $this->translator->trans('Your recovery mail has been sent, to retrieve your account follow the recuperate link inside', [], $this->alias));
514
515 //Add junk warning
516 $this->addFlash('warning', $this->translator->trans('If you did not receive a recovery mail, check your Spam or Junk mail folder', [], $this->alias));
517
518 //Redirect on home route to cleanup form
519 return $this->redirectToRoute($this->config['route']['home']['name'], $this->config['route']['home']['context']);
520 //Catch obvious transport exception
521 } catch(TransportExceptionInterface $e) {
522 //Add error message mail unreachable
523 $form->get('mail')->addError(new FormError($this->translator->trans('Unable to reach account', [], $this->alias)));
524 }
525 }
526 }
527 }
528
529 //Render view
530 return $this->render(
531 //Template
532 $this->config['recover']['view']['name'],
533 //Context
534 ['recover' => $form->createView()]+$this->config['recover']['view']['context']
535 );
536 }
537
538 /**
539 * Register an account
540 *
541 * @param Request $request The request
542 * @return Response The response
543 */
544 public function register(Request $request): Response {
545 //With mail
546 if (!empty($_POST['register']['mail'])) {
547 //Log new user infos
548 $this->logger->emergency(
549 $this->translator->trans(
550 'register: mail=%mail% locale=%locale% confirm=%confirm% ip=%ip%',
551 [
552 '%mail%' => $postMail = $_POST['register']['mail'],
553 '%locale%' => $request->getLocale(),
554 '%confirm%' => $this->router->generate(
555 $this->config['route']['confirm']['name'],
556 //Prepend subscribe context with tag
557 [
558 'mail' => $postSmail = $this->slugger->short($postMail),
559 'hash' => $this->slugger->hash($postSmail)
560 ]+$this->config['route']['confirm']['context'],
561 UrlGeneratorInterface::ABSOLUTE_URL
562 ),
563 '%ip%' => $request->getClientIp()
564 ],
565 $this->alias
566 )
567 );
568 }
569
570 //Init reflection
571 $reflection = new \ReflectionClass($this->config['class']['user']);
572
573 //Create new user
574 $user = $reflection->newInstance('', '');
575
576 //Create the RegisterType form and give the proper parameters
577 $form = $this->factory->create($this->config['register']['view']['form'], $user, [
578 //Set action to register route name and context
579 'action' => $this->generateUrl($this->config['route']['register']['name'], $this->config['route']['register']['context']),
580 //Set captcha
581 'captcha' => true,
582 //Set civility class
583 'civility_class' => $this->config['class']['civility'],
584 //Set civility default
585 'civility_default' => $this->doctrine->getRepository($this->config['class']['civility'])->findOneByTitle($this->config['default']['civility']),
586 //Set method
587 'method' => 'POST',
588 //Set domain
589 'translation_domain' => $this->alias
590 ]+($this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin']))?$this->config['register']['admin']:$this->config['register']['field']));
591
592 //With post method
593 if ($request->isMethod('POST')) {
594 //Refill the fields in case the form is not valid.
595 $form->handleRequest($request);
596
597 //With form submitted and valid
598 if ($form->isSubmitted() && $form->isValid()) {
599 //Set data
600 $data = $form->getData();
601
602 //Set password
603 $user->setPassword($this->hasher->hashPassword($user, $user->getPassword()));
604
605 //Persist user
606 $this->manager->persist($user);
607
608 //Iterate on default group
609 foreach($this->config['default']['group'] as $i => $groupTitle) {
610 //Fetch group
611 if (($group = $this->doctrine->getRepository($this->config['class']['group'])->findOneByTitle($groupTitle))) {
612 //Set default group
613 //XXX: see vendor/symfony/security-core/Role/Role.php
614 $user->addGroup($group);
615 //Group not found
616 } else {
617 //Throw exception
618 //XXX: consider missing group as fatal
619 throw new \Exception(sprintf('Group %s listed in %s.default.group[%d] not found by title', $groupTitle, $this->alias, $i));
620 }
621 }
622
623 //Set context
624 $context = [
625 'recipient_mail' => $user->getMail(),
626 'recipient_name' => $user->getRecipientName()
627 ] + array_replace_recursive(
628 $this->config['context'],
629 $this->config['register']['view']['context'],
630 $this->config['register']['mail']['context']
631 );
632
633 //Generate each route route
634 foreach($this->config['register']['route'] as $route => $tag) {
635 //Only process defined routes
636 if (!empty($this->config['route'][$route])) {
637 //Process for confirm mail url
638 if ($route == 'confirm') {
639 //Set the url in context
640 $context[$tag] = $this->router->generate(
641 $this->config['route'][$route]['name'],
642 //Prepend register context with tag
643 [
644 'mail' => $smail = $this->slugger->short($context['recipient_mail']),
645 'hash' => $this->slugger->hash($smail)
646 ]+$this->config['route'][$route]['context'],
647 UrlGeneratorInterface::ABSOLUTE_URL
648 );
649 }
650 }
651 }
652
653 //Translate subject
654 $context['subject'] = $subject = ucfirst(
655 $this->translator->trans(
656 $this->config['register']['mail']['subject'],
657 $this->slugger->flatten($context, null, '.', '%', '%'),
658 $this->alias
659 )
660 );
661
662 //Create message
663 $message = (new TemplatedEmail())
664 //Set sender
665 ->from(new Address($this->config['contact']['address'], $this->translator->trans($this->config['contact']['name'], [], $this->alias)))
666 //Set recipient
667 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46
668 ->to(new Address($context['recipient_mail'], $context['recipient_name']))
669 //Set subject
670 ->subject($context['subject'])
671
672 //Set path to twig templates
673 ->htmlTemplate($this->config['register']['mail']['html'])
674 ->textTemplate($this->config['register']['mail']['text'])
675
676 //Set context
677 ->context($context);
678
679 //Try saving in database
680 try {
681 //Send to database
682 $this->manager->flush();
683
684 //Add created notice
685 $this->addFlash('notice', $this->translator->trans('Account created', [], $this->alias));
686
687 //Try sending message
688 //XXX: mail delivery may silently fail
689 try {
690 //Send message
691 $this->mailer->send($message);
692
693 //Add verification notice
694 $this->addFlash('notice', $this->translator->trans('Your verification mail has been sent, to activate your account you must follow the confirmation link inside', [], $this->alias));
695
696 //Add junk warning
697 $this->addFlash('warning', $this->translator->trans('If you did not receive a verification mail, check your Spam or Junk mail folders', [], $this->alias));
698
699 //Redirect on home route to cleanup form
700 return $this->redirectToRoute($this->config['route']['home']['name'], $this->config['route']['home']['context']);
701 //Catch obvious transport exception
702 } catch(TransportExceptionInterface $e) {
703 //Add error message mail unreachable
704 $form->get('mail')->addError(new FormError($this->translator->trans('Unable to reach account', [], $this->alias)));
705 }
706 //Catch double subscription
707 } catch (UniqueConstraintViolationException $e) {
708 //Add error message mail already exists
709 $this->addFlash('error', $this->translator->trans('The account already exists', [], $this->alias));
710 }
711 }
712 }
713
714 //Render view
715 return $this->render(
716 //Template
717 $this->config['register']['view']['name'],
718 //Context
719 ['register' => $form->createView()]+$this->config['register']['view']['context']
720 );
721 }
722 }