3 namespace Rapsys\UserBundle\Controller
; 
   5 use Rapsys\UserBundle\Utils\Slugger
; 
   6 use Symfony\Bridge\Twig\Mime\TemplatedEmail
; 
   7 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController
; 
   8 use Symfony\Component\DependencyInjection\ContainerInterface
; 
   9 use Symfony\Component\Form\FormError
; 
  10 use Symfony\Component\HttpFoundation\Request
; 
  11 use Symfony\Component\Mailer\Exception\TransportExceptionInterface
; 
  12 use Symfony\Component\Mailer\MailerInterface
; 
  13 use Symfony\Component\Mime\Address
; 
  14 use Symfony\Component\Routing\Generator\UrlGeneratorInterface
; 
  15 use Symfony\Component\Routing\RouterInterface
; 
  16 use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface
; 
  17 use Symfony\Component\Security\Http\Authentication\AuthenticationUtils
; 
  18 use Symfony\Component\Translation\TranslatorInterface
; 
  20 class DefaultController 
extends AbstractController 
{ 
  25         protected $translator; 
  27         public function __construct(ContainerInterface 
$container, TranslatorInterface 
$translator, RouterInterface 
$router) { 
  29                 $this->config 
= $container->getParameter($this->getAlias()); 
  32                 $this->translator 
= $translator; 
  35                 //XXX: we don't use this as it would be too slow, maybe ??? 
  36                 #$action = str_replace(self::getAlias().'_', '', $container->get('request_stack')->getCurrentRequest()->get('_route')); 
  38                 //Inject every requested route in view and mail context 
  39                 foreach($this->config 
as $tag => $current) { 
  40                         //Look for entry with route subkey 
  41                         if (!empty($current['route'])) { 
  42                                 //Generate url for both view and mail 
  43                                 foreach(['view', 'mail'] as $view) { 
  44                                         //Check that context key is usable 
  45                                         if (isset($current[$view]['context']) && is_array($current[$view]['context'])) { 
  46                                                 //Process every routes 
  47                                                 foreach($current['route'] as $route => $key) { 
  48                                                         //Skip recover_mail route as it requires some parameters 
  49                                                         if ($route == 'recover_mail') { 
  52                                                         //Check that key is empty 
  53                                                         if (!isset($current[$view]['context'][$key])) { 
  55                                                                 $this->config
[$tag][$view]['context'][$key] = $router->generate( 
  56                                                                         $this->config
['route'][$route]['name'], 
  57                                                                         $this->config
['route'][$route]['context'], 
  58                                                                         //Generate absolute url for mails 
  59                                                                         $view=='mail'?UrlGeneratorInterface
::ABSOLUTE_URL
:UrlGeneratorInterface
::ABSOLUTE_PATH
 
  69         public function login(Request 
$request, AuthenticationUtils 
$authenticationUtils) { 
  70                 //Create the LoginType form and give the proper parameters 
  71                 $login = $this->createForm($this->config
['login']['view']['form'], null, [ 
  72                         //Set action to login route name and context 
  73                         'action' => $this->generateUrl($this->config
['route']['login']['name'], $this->config
['route']['login']['context']), 
  80                 //Last username entered by the user 
  81                 if ($lastUsername = $authenticationUtils->getLastUsername()) { 
  82                         $login->get('mail')->setData($lastUsername); 
  85                 //Get the login error if there is one 
  86                 if ($error = $authenticationUtils->getLastAuthenticationError()) { 
  87                         //Get translated error 
  88                         $error = $this->translator
->trans($error->getMessageKey()); 
  90                         //Add error message to mail field 
  91                         $login->get('mail')->addError(new FormError($error)); 
  93                         //Create the RecoverType form and give the proper parameters 
  94                         $recover = $this->createForm($this->config
['recover']['view']['form'], null, [ 
  95                                 //Set action to recover route name and context 
  96                                 'action' => $this->generateUrl($this->config
['route']['recover']['name'], $this->config
['route']['recover']['context']), 
 100                         //Set mail from login form 
 101                         $recover->get('mail')->setData($login->get('mail')->getData()); 
 104                         $recover->addError(new FormError( 
 105                                 $this->translator
->trans('Use this form to recover your account') 
 108                         //Add recover form to context 
 109                         $context['recover'] = $recover->createView(); 
 113                 return $this->render( 
 115                         $this->config
['login']['view']['name'], 
 117                         ['login' => $login->createView()]+
$context+
$this->config
['login']['view']['context'] 
 121         public function recover(Request 
$request, Slugger 
$slugger, MailerInterface 
$mailer) { 
 122                 //Create the RecoverType form and give the proper parameters 
 123                 $form = $this->createForm($this->config
['recover']['view']['form'], null, array( 
 124                         //Set action to recover route name and context 
 125                         'action' => $this->generateUrl($this->config
['route']['recover']['name'], $this->config
['route']['recover']['context']), 
 129                 if ($request->isMethod('POST')) { 
 130                         //Refill the fields in case the form is not valid. 
 131                         $form->handleRequest($request); 
 133                         if ($form->isValid()) { 
 135                                 $doctrine = $this->getDoctrine(); 
 138                                 $data = $form->getData(); 
 141                                 if ($user = $doctrine->getRepository($this->config
['class']['user'])->findOneByMail($data['mail'])) { 
 143                                         $mail =& $this->config
['recover']['mail']; 
 145                                         //Generate each route route 
 146                                         foreach($this->config
['recover']['route'] as $route => $tag) { 
 147                                                 //Only process defined routes 
 148                                                 if (empty($mail['context'][$tag]) && !empty($this->config
['route'][$route])) { 
 149                                                         //Process for recover mail url 
 150                                                         if ($route == 'recover_mail') { 
 151                                                                 //Prepend recover context with tag 
 152                                                                 $this->config
['route'][$route]['context'] = [ 
 153                                                                         'recipient' => $slugger->short($user->getMail()), 
 154                                                                         'hash' => $slugger->hash($user->getPassword()) 
 155                                                                 ]+
$this->config
['route'][$route]['context']; 
 157                                                         //Set the url in context 
 158                                                         $mail['context'][$tag] = $this->get('router')->generate( 
 159                                                                 $this->config
['route'][$route]['name'], 
 160                                                                 $this->config
['route'][$route]['context'], 
 161                                                                 UrlGeneratorInterface
::ABSOLUTE_URL
 
 168                                         $mail['context']['recipient_mail'] = $data['mail']; 
 171                                         $mail['context']['recipient_name'] = trim($user->getForename().' '.$user->getSurname().($user->getPseudonym()?' ('.$user->getPseudonym().')':'')); 
 173                                         //Init subject context 
 174                                         $subjectContext = []; 
 176                                         //Process each context pair 
 177                                         foreach($mail['context']+
$this->config
['recover']['view']['context'] as $k => $v) { 
 178                                                 //Reinsert each context pair with the key surrounded by % 
 179                                                 $subjectContext['%'.$k.'%'] = $v; 
 183                                         $mail['subject'] = ucfirst($this->translator
->trans($mail['subject'], $subjectContext)); 
 186                                         $message = (new TemplatedEmail()) 
 188                                                 ->from(new Address($this->config
['contact']['mail'], $this->config
['contact']['name'])) 
 190                                                 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 191                                                 ->to(new Address($mail['context']['recipient_mail'], $mail['context']['recipient_name'])) 
 193                                                 ->subject($mail['subject']) 
 195                                                 //Set path to twig templates 
 196                                                 ->htmlTemplate($mail['html']) 
 197                                                 ->textTemplate($mail['text']) 
 200                                                 ->context(['subject' => $mail['subject']]+
$mail['context']+
$this->config
['recover']['view']['context']); 
 202                                         //Try sending message 
 203                                         //XXX: mail delivery may silently fail 
 206                                                 $mailer->send($message); 
 208                                                 //Redirect on the same route with sent=1 to cleanup form 
 209                                                 #return $this->redirectToRoute('rapsys_user_register', array('sent' => 1)); 
 210                                                 return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+
$request->get('_route_params')); 
 211                                         //Catch obvious transport exception 
 212                                         } catch(TransportExceptionInterface 
$e) { 
 213                                                 //Add error message mail unreachable 
 214                                                 $form->get('mail')->addError(new FormError($this->translator
->trans('Account found but unable to contact: %mail%', array('%mail%' => $data['mail'])))); 
 218                                         //Add error message to mail field 
 219                                         $form->get('mail')->addError(new FormError($this->translator
->trans('Unable to find account: %mail%', ['%mail%' => $data['mail']]))); 
 225                 return $this->render( 
 227                         $this->config
['recover']['view']['name'], 
 229                         ['form' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->config
['recover']['view']['context'] 
 233         public function recoverMail(Request 
$request, UserPasswordEncoderInterface 
$encoder, Slugger 
$slugger, MailerInterface 
$mailer, $recipient, $hash) { 
 234                 //Create the RecoverType form and give the proper parameters 
 235                 $form = $this->createForm($this->config
['recover_mail']['view']['form'], null, array( 
 236                         //Set action to recover route name and context 
 237                         'action' => $this->generateUrl($this->config
['route']['recover_mail']['name'], ['recipient' => $recipient, 'hash' => $hash]+
$this->config
['route']['recover_mail']['context']), 
 242                 $doctrine = $this->getDoctrine(); 
 248                 if (($user = $doctrine->getRepository($this->config
['class']['user'])->findOneByMail($slugger->unshort($recipient))) && $found = ($hash == $slugger->hash($user->getPassword()))) { 
 249                         if ($request->isMethod('POST')) { 
 250                                 //Refill the fields in case the form is not valid. 
 251                                 $form->handleRequest($request); 
 253                                 if ($form->isValid()) { 
 255                                         $data = $form->getData(); 
 257                                         //set encoded password 
 258                                         $encoded = $encoder->encodePassword($user, $data['password']); 
 261                                         $user->setPassword($encoded); 
 264                                         $manager = $doctrine->getManager(); 
 267                                         $manager->persist($user); 
 273                                         $mail =& $this->config
['recover_mail']['mail']; 
 276                                         $hash = $slugger->hash($encoded); 
 278                                         //Generate each route route 
 279                                         foreach($this->config
['recover_mail']['route'] as $route => $tag) { 
 280                                                 //Only process defined routes 
 281                                                 if (empty($mail['context'][$tag]) && !empty($this->config
['route'][$route])) { 
 282                                                         //Process for recover mail url 
 283                                                         if ($route == 'recover_mail') { 
 284                                                                 //Prepend recover context with tag 
 285                                                                 $this->config
['route'][$route]['context'] = [ 
 286                                                                         'recipient' => $recipient, 
 288                                                                 ]+
$this->config
['route'][$route]['context']; 
 290                                                         //Set the url in context 
 291                                                         $mail['context'][$tag] = $this->get('router')->generate( 
 292                                                                 $this->config
['route'][$route]['name'], 
 293                                                                 $this->config
['route'][$route]['context'], 
 294                                                                 UrlGeneratorInterface
::ABSOLUTE_URL
 
 300                                         $mail['context']['recipient_mail'] = $user->getMail(); 
 303                                         $mail['context']['recipient_name'] = trim($user->getForename().' '.$user->getSurname().($user->getPseudonym()?' ('.$user->getPseudonym().')':'')); 
 305                                         //Init subject context 
 306                                         $subjectContext = []; 
 308                                         //Process each context pair 
 309                                         foreach($mail['context']+
$this->config
['recover_mail']['view']['context'] as $k => $v) { 
 310                                                 //Reinsert each context pair with the key surrounded by % 
 311                                                 $subjectContext['%'.$k.'%'] = $v; 
 315                                         $mail['subject'] = ucfirst($this->translator
->trans($mail['subject'], $subjectContext)); 
 318                                         $message = (new TemplatedEmail()) 
 320                                                 ->from(new Address($this->config
['contact']['mail'], $this->config
['contact']['name'])) 
 322                                                 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 323                                                 ->to(new Address($mail['context']['recipient_mail'], $mail['context']['recipient_name'])) 
 325                                                 ->subject($mail['subject']) 
 327                                                 //Set path to twig templates 
 328                                                 ->htmlTemplate($mail['html']) 
 329                                                 ->textTemplate($mail['text']) 
 332                                                 ->context(['subject' => $mail['subject']]+
$mail['context']+
$this->config
['recover_mail']['view']['context']); 
 334                                         //Try sending message 
 335                                         //XXX: mail delivery may silently fail 
 338                                                 $mailer->send($message); 
 340                                                 //Redirect on the same route with sent=1 to cleanup form 
 341                                                 return $this->redirectToRoute($request->get('_route'), ['recipient' => $recipient, 'hash' => $hash, 'sent' => 1]+
$request->get('_route_params')); 
 342                                         //Catch obvious transport exception 
 343                                         } catch(TransportExceptionInterface 
$e) { 
 344                                                 //Add error message mail unreachable 
 345                                                 $form->get('password')->get('first')->addError(new FormError($this->translator
->trans('Account password updated but unable to contact: %mail%', array('%mail%' => $mail['context']['recipient_mail'])))); 
 351                         //Add error message to mail field 
 352                         $form->addError(new FormError($this->translator
->trans('Unable to find account: %mail%', ['%mail%' => $slugger->unshort($recipient)]))); 
 356                 return $this->render( 
 358                         $this->config
['recover_mail']['view']['name'], 
 360                         ['form' => $form->createView(), 'sent' => $request->query
->get('sent', 0), 'found' => $found]+
$this->config
['recover_mail']['view']['context'] 
 364         public function register(Request 
$request, UserPasswordEncoderInterface 
$encoder, MailerInterface 
$mailer) { 
 365                 //Create the RegisterType form and give the proper parameters 
 366                 $form = $this->createForm($this->config
['register']['view']['form'], null, array( 
 367                         'class_title' => $this->config
['class']['title'], 
 368                         //Set action to register route name and context 
 369                         'action' => $this->generateUrl($this->config
['route']['register']['name'], $this->config
['route']['register']['context']), 
 373                 if ($request->isMethod('POST')) { 
 374                         //Refill the fields in case the form is not valid. 
 375                         $form->handleRequest($request); 
 377                         if ($form->isValid()) { 
 379                                 $data = $form->getData(); 
 382                                 $mail =& $this->config
['register']['mail']; 
 384                                 //Generate each route route 
 385                                 foreach($this->config
['register']['route'] as $route => $tag) { 
 386                                         if (empty($mail['context'][$tag]) && !empty($this->config
['route'][$route])) { 
 387                                                 $mail['context'][$tag] = $this->get('router')->generate( 
 388                                                         $this->config
['route'][$route]['name'], 
 389                                                         $this->config
['route'][$route]['context'], 
 390                                                         UrlGeneratorInterface
::ABSOLUTE_URL
 
 396                                 $mail['context']['recipient_mail'] = $data['mail']; 
 399                                 $mail['context']['recipient_name'] = trim($data['forename'].' '.$data['surname'].($data['pseudonym']?' ('.$data['pseudonym'].')':'')); 
 401                                 //Init subject context 
 402                                 $subjectContext = []; 
 404                                 //Process each context pair 
 405                                 foreach($mail['context']+
$this->config
['register']['view']['context'] as $k => $v) { 
 406                                         //Reinsert each context pair with the key surrounded by % 
 407                                         $subjectContext['%'.$k.'%'] = $v; 
 411                                 $mail['subject'] = ucfirst($this->translator
->trans($mail['subject'], $subjectContext)); 
 414                                 $message = (new TemplatedEmail()) 
 416                                         ->from(new Address($this->config
['contact']['mail'], $this->config
['contact']['name'])) 
 418                                         //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 419                                         ->to(new Address($mail['context']['recipient_mail'], $mail['context']['recipient_name'])) 
 421                                         ->subject($mail['subject']) 
 423                                         //Set path to twig templates 
 424                                         ->htmlTemplate($mail['html']) 
 425                                         ->textTemplate($mail['text']) 
 428                                         ->context(['subject' => $mail['subject']]+
$mail['context']+
$this->config
['register']['view']['context']); 
 431                                 $doctrine = $this->getDoctrine(); 
 434                                 $manager = $doctrine->getManager(); 
 437                                 $reflection = new \
ReflectionClass($this->config
['class']['user']); 
 440                                 $user = $reflection->newInstance(); 
 442                                 $user->setMail($data['mail']); 
 443                                 $user->setPseudonym($data['pseudonym']); 
 444                                 $user->setForename($data['forename']); 
 445                                 $user->setSurname($data['surname']); 
 446                                 $user->setPhone($data['phone']); 
 447                                 $user->setPassword($encoder->encodePassword($user, $data['password'])); 
 448                                 $user->setActive(true); 
 449                                 $user->setTitle($data['title']); 
 451                                 //XXX: For now there is no point in setting a role at subscription 
 452                                 //TODO: see if we can't modify group constructor to set role directly from args 
 453                                 //XXX: see vendor/symfony/symfony/src/Symfony/Component/Security/Core/Role/Role.php 
 454                                 #$user->addGroup($doctrine->getRepository($this->config['class']['group'])->findOneByRole('ROLE_USER')); 
 456                                 $user->setCreated(new \
DateTime('now')); 
 457                                 $user->setUpdated(new \
DateTime('now')); 
 460                                 $manager->persist($user); 
 462                                 //Try saving in database 
 467                                         //Try sending message 
 468                                         //XXX: mail delivery may silently fail 
 471                                                 $mailer->send($message); 
 473                                                 //Redirect on the same route with sent=1 to cleanup form 
 474                                                 #return $this->redirectToRoute('rapsys_user_register', array('sent' => 1)); 
 475                                                 return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+
$request->get('_route_params')); 
 476                                         //Catch obvious transport exception 
 477                                         } catch(TransportExceptionInterface 
$e) { 
 478                                                 //Add error message mail unreachable 
 479                                                 $form->get('mail')->addError(new FormError($this->translator
->trans('Account created but unable to contact: %mail%', array('%mail%' => $data['mail'])))); 
 481                                 //Catch double subscription 
 482                                 } catch (\Doctrine\DBAL\Exception\UniqueConstraintViolationException 
$e) { 
 483                                         //Add error message mail already exists 
 484                                         $form->get('mail')->addError(new FormError($this->translator
->trans('Account already exists: %mail%', ['%mail%' => $data['mail']]))); 
 490                 return $this->render( 
 492                         $this->config
['register']['view']['name'], 
 494                         ['form' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->config
['register']['view']['context'] 
 501         public function getAlias() { 
 502                 return 'rapsys_user';