1 <?php 
declare(strict_types
=1); 
   4  * This file is part of the Rapsys UserBundle 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\UserBundle\Controller
; 
  14 use Doctrine\DBAL\Exception\UniqueConstraintViolationException
; 
  16 use Rapsys\UserBundle\RapsysUserBundle
; 
  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\Mailer\Exception\TransportExceptionInterface
; 
  24 use Symfony\Component\Mime\Address
; 
  25 use Symfony\Component\Routing\Generator\UrlGeneratorInterface
; 
  26 use Symfony\Component\Security\Http\Authentication\AuthenticationUtils
; 
  31 class UserController 
extends AbstractController 
{ 
  35          * @param Request $request The request 
  36          * @return Response The response 
  38         public function index(Request 
$request): Response 
{ 
  40                 if (!$this->checker
->isGranted($this->config
['default']['admin'])) { 
  42                         throw $this->createAccessDeniedException($this->translator
->trans('Unable to list users', [], $this->alias
)); 
  46                 $this->context
['count'] = $this->doctrine
->getRepository($this->config
['class']['user'])->findCountAsInt(); 
  48                 //With not enough users 
  49                 if ($this->context
['count'] - $this->page 
* $this->limit 
< 0) { 
  51                         throw $this->createNotFoundException($this->translator
->trans('Unable to find users', [], $this->alias
)); 
  55                 $this->context
['groups'] = $this->doctrine
->getRepository($this->config
['class']['user'])->findIndexByGroupId($this->page
, $this->limit
); 
  60                         $this->config
['index']['view']['name'], 
  62                         $this->context+
$this->config
['index']['view']['context'] 
  67          * Confirm account from mail link 
  69          * @param Request $request The request 
  70          * @param string $hash The hashed password 
  71          * @param string $mail The shorted mail address 
  72          * @return Response The response 
  74         public function confirm(Request 
$request, string $hash, string $mail): Response 
{ 
  76                 if ($hash != $this->slugger
->hash($mail)) { 
  78                         throw new BadRequestHttpException($this->translator
->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias
)); 
  82                 $mail = $this->slugger
->unshort($smail = $mail); 
  85                 if (filter_var($mail, FILTER_VALIDATE_EMAIL
) === false) { 
  87                         //XXX: prevent slugger reverse engineering by not displaying decoded mail 
  88                         throw new BadRequestHttpException($this->translator
->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail], $this->alias
)); 
  91                 //Without existing registrant 
  92                 if (!($user = $this->doctrine
->getRepository($this->config
['class']['user'])->findOneByMail($mail))) { 
  93                         //Add error message mail already exists 
  94                         //XXX: prevent slugger reverse engineering by not displaying decoded mail 
  95                         $this->addFlash('error', $this->translator
->trans('Account do not exists', [], $this->alias
)); 
  97                         //Redirect to register view 
  98                         return $this->redirectToRoute($this->config
['route']['register']['name'], $this->config
['route']['register']['context']); 
 102                 $user->setActive(true); 
 105                 $this->manager
->persist($user); 
 108                 $this->manager
->flush(); 
 110                 //Add error message mail already exists 
 111                 $this->addFlash('notice', $this->translator
->trans('Your account has been activated', [], $this->alias
)); 
 113                 //Redirect to user view 
 114                 return $this->redirectToRoute($this->config
['route']['edit']['name'], ['mail' => $smail, 'hash' => $this->slugger
->hash($smail)]+
$this->config
['route']['edit']['context']); 
 118          * Edit account by shorted mail 
 120          * @param Request $request The request 
 121          * @param string $hash The hashed password 
 122          * @param string $mail The shorted mail address 
 123          * @return Response The response 
 125         public function edit(Request 
$request, string $hash, string $mail): Response 
{ 
 127                 if ($hash != $this->slugger
->hash($mail)) { 
 129                         throw new BadRequestHttpException($this->translator
->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias
)); 
 133                 $mail = $this->slugger
->unshort($smail = $mail); 
 135                 //With existing subscriber 
 136                 if (empty($user = $this->doctrine
->getRepository($this->config
['class']['user'])->findOneByMail($mail))) { 
 138                         //XXX: prevent slugger reverse engineering by not displaying decoded mail 
 139                         throw $this->createNotFoundException($this->translator
->trans('Unable to find account', [], $this->alias
)); 
 142                 //Prevent access when not admin, user is not guest and not currently logged user 
 143                 if (!$this->checker
->isGranted($this->config
['default']['admin']) && $user != $this->security
->getUser() || !$this->checker
->isGranted('IS_AUTHENTICATED_FULLY')) { 
 144                         //Throw access denied 
 145                         //XXX: prevent slugger reverse engineering by not displaying decoded mail 
 146                         throw $this->createAccessDeniedException($this->translator
->trans('Unable to access user', [], $this->alias
)); 
 149                 //Create the EditType form and give the proper parameters 
 150                 $edit = $this->factory
->create($this->config
['edit']['view']['edit'], $user, [ 
 151                         //Set action to edit route name and context 
 152                         'action' => $this->generateUrl($this->config
['route']['edit']['name'], ['mail' => $smail, 'hash' => $this->slugger
->hash($smail)]+
$this->config
['route']['edit']['context']), 
 154                         'civility_class' => $this->config
['class']['civility'], 
 155                         //Set civility default 
 156                         'civility_default' => $this->doctrine
->getRepository($this->config
['class']['civility'])->findOneByTitle($this->config
['default']['civility']), 
 158                         'mail' => $this->checker
->isGranted('ROLE_ADMIN'), 
 164                         'translation_domain' => $this->alias
 
 165                 ]+
($this->checker
->isGranted($this->config
['default']['admin'])?$this->config
['edit']['admin']:$this->config
['edit']['field'])); 
 168                 if ($this->checker
->isGranted($this->config
['default']['admin'])) { 
 169                         //Create the EditType form and give the proper parameters 
 170                         $reset = $this->factory
->create($this->config
['edit']['view']['reset'], $user, [ 
 171                                 //Set action to edit route name and context 
 172                                 'action' => $this->generateUrl($this->config
['route']['edit']['name'], ['mail' => $smail, 'hash' => $this->slugger
->hash($smail)]+
$this->config
['route']['edit']['context']), 
 176                                 'translation_domain' => $this->alias
 
 180                         if ($request->isMethod('POST')) { 
 181                                 //Refill the fields in case the form is not valid. 
 182                                 $reset->handleRequest($request); 
 184                                 //With reset submitted and valid 
 185                                 if ($reset->isSubmitted() && $reset->isValid()) { 
 187                                         $data = $reset->getData(); 
 190                                         $data->setPassword($this->hasher
->hashPassword($data, $data->getPassword())); 
 193                                         $this->manager
->persist($data); 
 195                                         //Flush to get the ids 
 196                                         $this->manager
->flush(); 
 199                                         $this->addFlash('notice', $this->translator
->trans('Account password updated', [], $this->alias
)); 
 201                                         //Redirect to cleanup the form 
 202                                         return $this->redirectToRoute($this->config
['route']['edit']['name'], ['mail' => $smail = $this->slugger
->short($mail), 'hash' => $this->slugger
->hash($smail)]+
$this->config
['route']['edit']['context']); 
 207                         $this->config
['edit']['view']['context']['reset'] = $reset->createView(); 
 211                 if ($request->isMethod('POST')) { 
 212                         //Refill the fields in case the form is not valid. 
 213                         $edit->handleRequest($request); 
 215                         //With edit submitted and valid 
 216                         if ($edit->isSubmitted() && $edit->isValid()) { 
 218                                 $data = $edit->getData(); 
 221                                 $this->manager
->persist($data); 
 223                                 //Try saving in database 
 225                                         //Flush to get the ids 
 226                                         $this->manager
->flush(); 
 229                                         $this->addFlash('notice', $this->translator
->trans('Account updated', [], $this->alias
)); 
 231                                         //Redirect to cleanup the form 
 232                                         return $this->redirectToRoute($this->config
['route']['edit']['name'], ['mail' => $smail = $this->slugger
->short($mail), 'hash' => $this->slugger
->hash($smail)]+
$this->config
['route']['edit']['context']); 
 233                                 //Catch double slug or mail 
 234                                 } catch (UniqueConstraintViolationException 
$e) { 
 235                                         //Add error message mail already exists 
 236                                         $this->addFlash('error', $this->translator
->trans('Account already exists', [], $this->alias
)); 
 240                 //XXX: prefer a reset on login to force user unspam action 
 241                 } elseif (!$this->checker
->isGranted($this->config
['default']['admin'])) { 
 243                         $this->addFlash('notice', $this->translator
->trans('To change your password login with your mail and any password then follow the procedure', [], $this->alias
)); 
 247                 return $this->render( 
 249                         $this->config
['edit']['view']['name'], 
 251                         ['register' => $edit->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->config
['edit']['view']['context'] 
 258          * @param Request $request The request 
 259          * @param AuthenticationUtils $authenticationUtils The authentication utils 
 260          * @param ?string $hash The hashed password 
 261          * @param ?string $mail The shorted mail address 
 262          * @return Response The response 
 264         public function login(Request 
$request, AuthenticationUtils 
$authenticationUtils, ?string $hash, ?string $mail): Response 
{ 
 265                 //Create the LoginType form and give the proper parameters 
 266                 $login = $this->factory
->create($this->config
['login']['view']['form'], null, [ 
 267                         //Set action to login route name and context 
 268                         'action' => $this->generateUrl($this->config
['route']['login']['name'], $this->config
['route']['login']['context']), 
 272                         'translation_domain' => $this->alias
 
 279                 if (!empty($mail) && !empty($hash)) { 
 281                         if ($hash != $this->slugger
->hash($mail)) { 
 283                                 throw new BadRequestHttpException($this->translator
->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias
)); 
 287                         $mail = $this->slugger
->unshort($smail = $mail); 
 290                         if (filter_var($mail, FILTER_VALIDATE_EMAIL
) === false) { 
 292                                 throw new BadRequestHttpException($this->translator
->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail], $this->alias
)); 
 296                         $login->get('mail')->setData($mail); 
 297                 //Last username entered by the user 
 298                 } elseif ($lastUsername = $authenticationUtils->getLastUsername()) { 
 299                         $login->get('mail')->setData($lastUsername); 
 302                 //Get the login error if there is one 
 303                 if ($error = $authenticationUtils->getLastAuthenticationError()) { 
 304                         //Get translated error 
 305                         $error = $this->translator
->trans($error->getMessageKey(), [], $this->alias
); 
 307                         //Add error message to mail field 
 308                         $login->get('mail')->addError(new FormError($error)); 
 310                         //Create the RecoverType form and give the proper parameters 
 311                         $recover = $this->factory
->create($this->config
['recover']['view']['form'], null, [ 
 312                                 //Set action to recover route name and context 
 313                                 'action' => $this->generateUrl($this->config
['route']['recover']['name'], $this->config
['route']['recover']['context']), 
 319                                 'translation_domain' => $this->alias
 
 322                         //Get recover mail entity 
 323                         $recover->get('mail') 
 324                                 //Set mail from login form 
 325                                 ->setData($login->get('mail')->getData()) 
 327                                 ->addError(new FormError($this->translator
->trans('Use this form to recover your account', [], $this->alias
))); 
 329                         //Add recover form to context 
 330                         $context['recover'] = $recover->createView(); 
 333                         $this->addFlash('notice', $this->translator
->trans('To change your password login with your mail and any password then follow the procedure', [], $this->alias
)); 
 337                 return $this->render( 
 339                         $this->config
['login']['view']['name'], 
 341                         ['login' => $login->createView(), 'disabled' => $request->query
->get('disabled', 0), 'sent' => $request->query
->get('sent', 0)]+
$context+
$this->config
['login']['view']['context'] 
 348          * @param Request $request The request 
 349          * @param ?string $hash The hashed password 
 350          * @param ?string $pass The shorted password 
 351          * @param ?string $mail The shorted mail address 
 352          * @return Response The response 
 354         public function recover(Request 
$request, ?string $hash, ?string $pass, ?string $mail): Response 
{ 
 361                 //With mail, pass and hash 
 362                 if (!empty($mail) && !empty($pass) && !empty($hash)) { 
 364                         if ($hash != $this->slugger
->hash($mail.$pass)) { 
 366                                 throw new BadRequestHttpException($this->translator
->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias
)); 
 370                         $mail = $this->slugger
->unshort($smail = $mail); 
 373                         if (filter_var($mail, FILTER_VALIDATE_EMAIL
) === false) { 
 375                                 //XXX: prevent slugger reverse engineering by not displaying decoded mail 
 376                                 throw new BadRequestHttpException($this->translator
->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail], $this->alias
)); 
 379                         //With existing subscriber 
 380                         if (empty($user = $this->doctrine
->getRepository($this->config
['class']['user'])->findOneByMail($mail))) { 
 382                                 //XXX: prevent slugger reverse engineering by not displaying decoded mail 
 383                                 throw $this->createNotFoundException($this->translator
->trans('Unable to find account', [], $this->alias
)); 
 386                         //With unmatched pass 
 387                         if ($pass != $this->slugger
->hash($user->getPassword())) { 
 389                                 //XXX: prevent use of outdated recover link 
 390                                 throw $this->createNotFoundException($this->translator
->trans('Outdated recover link', [], $this->alias
)); 
 394                         $context = ['mail' => $smail, 'pass' => $pass, 'hash' => $hash]; 
 397                 //Create the LoginType form and give the proper parameters 
 398                 $form = $this->factory
->create($this->config
['recover']['view']['form'], $user, [ 
 399                         //Set action to recover route name and context 
 400                         'action' => $this->generateUrl($this->config
['route']['recover']['name'], $context+
$this->config
['route']['recover']['context']), 
 401                         //With user disable mail 
 402                         'mail' => ($user === null), 
 403                         //With user enable password 
 404                         'password' => ($user !== null), 
 408                         'translation_domain' => $this->alias
 
 412                 if ($request->isMethod('POST')) { 
 413                         //Refill the fields in case the form is not valid. 
 414                         $form->handleRequest($request); 
 416                         //With form submitted and valid 
 417                         if ($form->isSubmitted() && $form->isValid()) { 
 419                                 $data = $form->getData(); 
 422                                 if ($user !== null) { 
 423                                         //Set hashed password 
 424                                         $hashed = $this->hasher
->hashPassword($user, $user->getPassword()); 
 427                                         $pass = $this->slugger
->hash($hashed); 
 430                                         $user->setPassword($hashed); 
 433                                         $this->manager
->persist($user); 
 436                                         $this->manager
->flush(); 
 439                                         $this->addFlash('notice', $this->translator
->trans('Account password updated', [], $this->alias
)); 
 441                                         //Redirect to user login 
 442                                         return $this->redirectToRoute($this->config
['route']['login']['name'], ['mail' => $smail, 'hash' => $this->slugger
->hash($smail)]+
$this->config
['route']['login']['context']); 
 443                                 //Find user by data mail 
 444                                 } elseif ($user = $this->doctrine
->getRepository($this->config
['class']['user'])->findOneByMail($data['mail'])) { 
 447                                                 'recipient_mail' => $user->getMail(), 
 448                                                 'recipient_name' => $user->getRecipientName() 
 449                                         ] + 
array_replace_recursive( 
 450                                                 $this->config
['context'], 
 451                                                 $this->config
['recover']['view']['context'], 
 452                                                 $this->config
['recover']['mail']['context'] 
 455                                         //Generate each route route 
 456                                         foreach($this->config
['recover']['route'] as $route => $tag) { 
 457                                                 //Only process defined routes 
 458                                                 if (!empty($this->config
['route'][$route])) { 
 459                                                         //Process for recover mail url 
 460                                                         if ($route == 'recover') { 
 461                                                                 //Set the url in context 
 462                                                                 $context[$tag] = $this->router
->generate( 
 463                                                                         $this->config
['route'][$route]['name'], 
 464                                                                         //Prepend recover context with tag 
 466                                                                                 'mail' => $smail = $this->slugger
->short($context['recipient_mail']), 
 467                                                                                 'pass' => $spass = $this->slugger
->hash($pass = $user->getPassword()), 
 468                                                                                 'hash' => $this->slugger
->hash($smail.$spass) 
 469                                                                         ]+
$this->config
['route'][$route]['context'], 
 470                                                                         UrlGeneratorInterface
::ABSOLUTE_URL
 
 476                                         //Iterate on keys to translate 
 477                                         foreach($this->config
['translate'] as $translate) { 
 479                                                 $keys = explode('.', $translate); 
 482                                                 $current =& $context; 
 484                                                 //Iterate on each subkey 
 486                                                         //Skip unset translation keys 
 487                                                         if (!isset($current[current($keys)])) { 
 491                                                         //Set current to subkey 
 492                                                         $current =& $current[current($keys)]; 
 493                                                 } while(next($keys)); 
 496                                                 $current = $this->translator
->trans($current, [], $this->alias
); 
 503                                         $context['subject'] = $subject = ucfirst( 
 504                                                 $this->translator
->trans( 
 505                                                         $this->config
['recover']['mail']['subject'], 
 506                                                         $this->slugger
->flatten($context, null, '.', '%', '%'), 
 512                                         $message = (new TemplatedEmail()) 
 514                                                 ->from(new Address($this->config
['contact']['address'], $this->translator
->trans($this->config
['contact']['name'], [], $this->alias
))) 
 516                                                 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 517                                                 ->to(new Address($context['recipient_mail'], $context['recipient_name'])) 
 519                                                 ->subject($context['subject']) 
 521                                                 //Set path to twig templates 
 522                                                 ->htmlTemplate($this->config
['recover']['mail']['html']) 
 523                                                 ->textTemplate($this->config
['recover']['mail']['text']) 
 528                                         //Try sending message 
 529                                         //XXX: mail delivery may silently fail 
 532                                                 $this->mailer
->send($message); 
 535                                                 $this->addFlash('notice', $this->translator
->trans('Your recovery mail has been sent, to retrieve your account follow the recuperate link inside', [], $this->alias
)); 
 538                                                 $this->addFlash('warning', $this->translator
->trans('If you did not receive a recovery mail, check your Spam or Junk mail folder', [], $this->alias
)); 
 540                                                 //Redirect on the same route with sent=1 to cleanup form 
 541                                                 return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+
$request->get('_route_params'), 302); 
 542                                         //Catch obvious transport exception 
 543                                         } catch(TransportExceptionInterface 
$e) { 
 544                                                 //Add error message mail unreachable 
 545                                                 $form->get('mail')->addError(new FormError($this->translator
->trans('Unable to reach account', [], $this->alias
))); 
 552                 return $this->render( 
 554                         $this->config
['recover']['view']['name'], 
 556                         ['recover' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->config
['recover']['view']['context'] 
 561          * Register an account 
 563          * @param Request $request The request 
 564          * @return Response The response 
 566         public function register(Request 
$request): Response 
{ 
 568                 if (!empty($_POST['register']['mail'])) { 
 570                         $this->logger
->emergency( 
 571                                 $this->translator
->trans( 
 572                                         'register: mail=%mail% locale=%locale% confirm=%confirm% ip=%ip%', 
 574                                                 '%mail%' => $postMail = $_POST['register']['mail'], 
 575                                                 '%locale%' => $request->getLocale(), 
 576                                                 '%confirm%' => $this->router
->generate( 
 577                                                         $this->config
['route']['confirm']['name'], 
 578                                                         //Prepend subscribe context with tag 
 580                                                                 'mail' => $postSmail = $this->slugger
->short($postMail), 
 581                                                                 'hash' => $this->slugger
->hash($postSmail) 
 582                                                         ]+
$this->config
['route']['confirm']['context'], 
 583                                                         UrlGeneratorInterface
::ABSOLUTE_URL
 
 585                                                 '%ip%' => $request->getClientIp() 
 593                 $reflection = new \
ReflectionClass($this->config
['class']['user']); 
 596                 $user = $reflection->newInstance('', ''); 
 598                 //Create the RegisterType form and give the proper parameters 
 599                 $form = $this->factory
->create($this->config
['register']['view']['form'], $user, [ 
 600                         //Set action to register route name and context 
 601                         'action' => $this->generateUrl($this->config
['route']['register']['name'], $this->config
['route']['register']['context']), 
 605                         'civility_class' => $this->config
['class']['civility'], 
 606                         //Set civility default 
 607                         'civility_default' => $this->doctrine
->getRepository($this->config
['class']['civility'])->findOneByTitle($this->config
['default']['civility']), 
 611                         'translation_domain' => $this->alias
 
 612                 ]+
($this->checker
->isGranted($this->config
['default']['admin'])?$this->config
['register']['admin']:$this->config
['register']['field'])); 
 615                 if ($request->isMethod('POST')) { 
 616                         //Refill the fields in case the form is not valid. 
 617                         $form->handleRequest($request); 
 619                         //With form submitted and valid 
 620                         if ($form->isSubmitted() && $form->isValid()) { 
 622                                 $data = $form->getData(); 
 625                                 $user->setPassword($this->hasher
->hashPassword($user, $user->getPassword())); 
 628                                 $this->manager
->persist($user); 
 630                                 //Iterate on default group 
 631                                 foreach($this->config
['default']['group'] as $i => $groupTitle) { 
 633                                         if (($group = $this->doctrine
->getRepository($this->config
['class']['group'])->findOneByTitle($groupTitle))) { 
 635                                                 //XXX: see vendor/symfony/security-core/Role/Role.php 
 636                                                 $user->addGroup($group); 
 640                                                 //XXX: consider missing group as fatal 
 641                                                 throw new \
Exception(sprintf('Group %s listed in %s.default.group[%d] not found by title', $groupTitle, RapsysUserBundle
::getAlias(), $i)); 
 647                                         'recipient_mail' => $user->getMail(), 
 648                                         'recipient_name' => $user->getRecipientName() 
 649                                 ] + 
array_replace_recursive( 
 650                                         $this->config
['context'], 
 651                                         $this->config
['register']['view']['context'], 
 652                                         $this->config
['register']['mail']['context'] 
 655                                 //Generate each route route 
 656                                 foreach($this->config
['register']['route'] as $route => $tag) { 
 657                                         //Only process defined routes 
 658                                         if (!empty($this->config
['route'][$route])) { 
 659                                                 //Process for confirm mail url 
 660                                                 if ($route == 'confirm') { 
 661                                                         //Set the url in context 
 662                                                         $context[$tag] = $this->router
->generate( 
 663                                                                 $this->config
['route'][$route]['name'], 
 664                                                                 //Prepend register context with tag 
 666                                                                         'mail' => $smail = $this->slugger
->short($context['recipient_mail']), 
 667                                                                         'hash' => $this->slugger
->hash($smail) 
 668                                                                 ]+
$this->config
['route'][$route]['context'], 
 669                                                                 UrlGeneratorInterface
::ABSOLUTE_URL
 
 675                                 //Iterate on keys to translate 
 676                                 foreach($this->config
['translate'] as $translate) { 
 678                                         $keys = explode('.', $translate); 
 681                                         $current =& $context; 
 683                                         //Iterate on each subkey 
 685                                                 //Skip unset translation keys 
 686                                                 if (!isset($current[current($keys)])) { 
 690                                                 //Set current to subkey 
 691                                                 $current =& $current[current($keys)]; 
 692                                         } while(next($keys)); 
 695                                         $current = $this->translator
->trans($current, [], $this->alias
); 
 702                                 $context['subject'] = $subject = ucfirst( 
 703                                         $this->translator
->trans( 
 704                                                 $this->config
['register']['mail']['subject'], 
 705                                                 $this->slugger
->flatten($context, null, '.', '%', '%'), 
 711                                 $message = (new TemplatedEmail()) 
 713                                         ->from(new Address($this->config
['contact']['address'], $this->translator
->trans($this->config
['contact']['name'], [], $this->alias
))) 
 715                                         //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 716                                         ->to(new Address($context['recipient_mail'], $context['recipient_name'])) 
 718                                         ->subject($context['subject']) 
 720                                         //Set path to twig templates 
 721                                         ->htmlTemplate($this->config
['register']['mail']['html']) 
 722                                         ->textTemplate($this->config
['register']['mail']['text']) 
 727                                 //Try saving in database 
 730                                         $this->manager
->flush(); 
 732                                         //Add error message mail already exists 
 733                                         $this->addFlash('notice', $this->translator
->trans('Account created', [], $this->alias
)); 
 735                                         //Try sending message 
 736                                         //XXX: mail delivery may silently fail 
 739                                                 $this->mailer
->send($message); 
 741                                                 //Redirect on the same route with sent=1 to cleanup form 
 742                                                 return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+
$request->get('_route_params')); 
 743                                         //Catch obvious transport exception 
 744                                         } catch(TransportExceptionInterface 
$e) { 
 745                                                 //Add error message mail unreachable 
 746                                                 $form->get('mail')->addError(new FormError($this->translator
->trans('Unable to reach account', [], $this->alias
))); 
 748                                 //Catch double subscription 
 749                                 } catch (UniqueConstraintViolationException 
$e) { 
 750                                         //Add error message mail already exists 
 751                                         $this->addFlash('error', $this->translator
->trans('Account already exists', [], $this->alias
)); 
 757                 return $this->render( 
 759                         $this->config
['register']['view']['name'], 
 761                         ['register' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->config
['register']['view']['context']