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                         //Get recover mail entity 
 101                         $recover->get('mail') 
 102                                 //Set mail from login form 
 103                                 ->setData($login->get('mail')->getData()) 
 105                                 ->addError(new FormError($this->translator
->trans('Use this form to recover your account'))); 
 107                         //Add recover form to context 
 108                         $context['recover'] = $recover->createView(); 
 112                 return $this->render( 
 114                         $this->config
['login']['view']['name'], 
 116                         ['login' => $login->createView()]+
$context+
$this->config
['login']['view']['context'] 
 120         public function recover(Request 
$request, Slugger 
$slugger, MailerInterface 
$mailer) { 
 121                 //Create the RecoverType form and give the proper parameters 
 122                 $form = $this->createForm($this->config
['recover']['view']['form'], null, array( 
 123                         //Set action to recover route name and context 
 124                         'action' => $this->generateUrl($this->config
['route']['recover']['name'], $this->config
['route']['recover']['context']), 
 128                 if ($request->isMethod('POST')) { 
 129                         //Refill the fields in case the form is not valid. 
 130                         $form->handleRequest($request); 
 132                         if ($form->isValid()) { 
 134                                 $doctrine = $this->getDoctrine(); 
 137                                 $data = $form->getData(); 
 140                                 if ($user = $doctrine->getRepository($this->config
['class']['user'])->findOneByMail($data['mail'])) { 
 142                                         $mail =& $this->config
['recover']['mail']; 
 144                                         //Generate each route route 
 145                                         foreach($this->config
['recover']['route'] as $route => $tag) { 
 146                                                 //Only process defined routes 
 147                                                 if (empty($mail['context'][$tag]) && !empty($this->config
['route'][$route])) { 
 148                                                         //Process for recover mail url 
 149                                                         if ($route == 'recover_mail') { 
 150                                                                 //Prepend recover context with tag 
 151                                                                 $this->config
['route'][$route]['context'] = [ 
 152                                                                         'recipient' => $slugger->short($user->getMail()), 
 153                                                                         'hash' => $slugger->hash($user->getPassword()) 
 154                                                                 ]+
$this->config
['route'][$route]['context']; 
 156                                                         //Set the url in context 
 157                                                         $mail['context'][$tag] = $this->get('router')->generate( 
 158                                                                 $this->config
['route'][$route]['name'], 
 159                                                                 $this->config
['route'][$route]['context'], 
 160                                                                 UrlGeneratorInterface
::ABSOLUTE_URL
 
 167                                         $mail['context']['recipient_mail'] = $data['mail']; 
 170                                         $mail['context']['recipient_name'] = trim($user->getForename().' '.$user->getSurname().($user->getPseudonym()?' ('.$user->getPseudonym().')':'')); 
 172                                         //Init subject context 
 173                                         $subjectContext = []; 
 175                                         //Process each context pair 
 176                                         foreach($mail['context']+
$this->config
['recover']['view']['context'] as $k => $v) { 
 177                                                 //Reinsert each context pair with the key surrounded by % 
 178                                                 $subjectContext['%'.$k.'%'] = $v; 
 182                                         $mail['subject'] = ucfirst($this->translator
->trans($mail['subject'], $subjectContext)); 
 185                                         $message = (new TemplatedEmail()) 
 187                                                 ->from(new Address($this->config
['contact']['mail'], $this->config
['contact']['name'])) 
 189                                                 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 190                                                 ->to(new Address($mail['context']['recipient_mail'], $mail['context']['recipient_name'])) 
 192                                                 ->subject($mail['subject']) 
 194                                                 //Set path to twig templates 
 195                                                 ->htmlTemplate($mail['html']) 
 196                                                 ->textTemplate($mail['text']) 
 199                                                 ->context(['subject' => $mail['subject']]+
$mail['context']+
$this->config
['recover']['view']['context']); 
 201                                         //Try sending message 
 202                                         //XXX: mail delivery may silently fail 
 205                                                 $mailer->send($message); 
 207                                                 //Redirect on the same route with sent=1 to cleanup form 
 208                                                 #return $this->redirectToRoute('rapsys_user_register', array('sent' => 1)); 
 209                                                 return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+
$request->get('_route_params')); 
 210                                         //Catch obvious transport exception 
 211                                         } catch(TransportExceptionInterface 
$e) { 
 212                                                 //Add error message mail unreachable 
 213                                                 $form->get('mail')->addError(new FormError($this->translator
->trans('Account found but unable to contact: %mail%', array('%mail%' => $data['mail'])))); 
 217                                         //Add error message to mail field 
 218                                         $form->get('mail')->addError(new FormError($this->translator
->trans('Unable to find account: %mail%', ['%mail%' => $data['mail']]))); 
 224                 return $this->render( 
 226                         $this->config
['recover']['view']['name'], 
 228                         ['form' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->config
['recover']['view']['context'] 
 232         public function recoverMail(Request 
$request, UserPasswordEncoderInterface 
$encoder, Slugger 
$slugger, MailerInterface 
$mailer, $recipient, $hash) { 
 233                 //Create the RecoverType form and give the proper parameters 
 234                 $form = $this->createForm($this->config
['recover_mail']['view']['form'], null, array( 
 235                         //Set action to recover route name and context 
 236                         'action' => $this->generateUrl($this->config
['route']['recover_mail']['name'], ['recipient' => $recipient, 'hash' => $hash]+
$this->config
['route']['recover_mail']['context']), 
 241                 $doctrine = $this->getDoctrine(); 
 247                 if (($user = $doctrine->getRepository($this->config
['class']['user'])->findOneByMail($slugger->unshort($recipient))) && $found = ($hash == $slugger->hash($user->getPassword()))) { 
 248                         if ($request->isMethod('POST')) { 
 249                                 //Refill the fields in case the form is not valid. 
 250                                 $form->handleRequest($request); 
 252                                 if ($form->isValid()) { 
 254                                         $data = $form->getData(); 
 256                                         //set encoded password 
 257                                         $encoded = $encoder->encodePassword($user, $data['password']); 
 260                                         $user->setPassword($encoded); 
 263                                         $manager = $doctrine->getManager(); 
 266                                         $manager->persist($user); 
 272                                         $mail =& $this->config
['recover_mail']['mail']; 
 275                                         $hash = $slugger->hash($encoded); 
 277                                         //Generate each route route 
 278                                         foreach($this->config
['recover_mail']['route'] as $route => $tag) { 
 279                                                 //Only process defined routes 
 280                                                 if (empty($mail['context'][$tag]) && !empty($this->config
['route'][$route])) { 
 281                                                         //Process for recover mail url 
 282                                                         if ($route == 'recover_mail') { 
 283                                                                 //Prepend recover context with tag 
 284                                                                 $this->config
['route'][$route]['context'] = [ 
 285                                                                         'recipient' => $recipient, 
 287                                                                 ]+
$this->config
['route'][$route]['context']; 
 289                                                         //Set the url in context 
 290                                                         $mail['context'][$tag] = $this->get('router')->generate( 
 291                                                                 $this->config
['route'][$route]['name'], 
 292                                                                 $this->config
['route'][$route]['context'], 
 293                                                                 UrlGeneratorInterface
::ABSOLUTE_URL
 
 299                                         $mail['context']['recipient_mail'] = $user->getMail(); 
 302                                         $mail['context']['recipient_name'] = trim($user->getForename().' '.$user->getSurname().($user->getPseudonym()?' ('.$user->getPseudonym().')':'')); 
 304                                         //Init subject context 
 305                                         $subjectContext = []; 
 307                                         //Process each context pair 
 308                                         foreach($mail['context']+
$this->config
['recover_mail']['view']['context'] as $k => $v) { 
 309                                                 //Reinsert each context pair with the key surrounded by % 
 310                                                 $subjectContext['%'.$k.'%'] = $v; 
 314                                         $mail['subject'] = ucfirst($this->translator
->trans($mail['subject'], $subjectContext)); 
 317                                         $message = (new TemplatedEmail()) 
 319                                                 ->from(new Address($this->config
['contact']['mail'], $this->config
['contact']['name'])) 
 321                                                 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 322                                                 ->to(new Address($mail['context']['recipient_mail'], $mail['context']['recipient_name'])) 
 324                                                 ->subject($mail['subject']) 
 326                                                 //Set path to twig templates 
 327                                                 ->htmlTemplate($mail['html']) 
 328                                                 ->textTemplate($mail['text']) 
 331                                                 ->context(['subject' => $mail['subject']]+
$mail['context']+
$this->config
['recover_mail']['view']['context']); 
 333                                         //Try sending message 
 334                                         //XXX: mail delivery may silently fail 
 337                                                 $mailer->send($message); 
 339                                                 //Redirect on the same route with sent=1 to cleanup form 
 340                                                 return $this->redirectToRoute($request->get('_route'), ['recipient' => $recipient, 'hash' => $hash, 'sent' => 1]+
$request->get('_route_params')); 
 341                                         //Catch obvious transport exception 
 342                                         } catch(TransportExceptionInterface 
$e) { 
 343                                                 //Add error message mail unreachable 
 344                                                 $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'])))); 
 350                         //Add error message to mail field 
 351                         $form->addError(new FormError($this->translator
->trans('Unable to find account: %mail%', ['%mail%' => $slugger->unshort($recipient)]))); 
 355                 return $this->render( 
 357                         $this->config
['recover_mail']['view']['name'], 
 359                         ['form' => $form->createView(), 'sent' => $request->query
->get('sent', 0), 'found' => $found]+
$this->config
['recover_mail']['view']['context'] 
 363         public function register(Request 
$request, UserPasswordEncoderInterface 
$encoder, MailerInterface 
$mailer) { 
 365                 $doctrine = $this->getDoctrine(); 
 367                 //Create the RegisterType form and give the proper parameters 
 368                 $form = $this->createForm($this->config
['register']['view']['form'], null, array( 
 369                         'class_title' => $this->config
['class']['title'], 
 370                         'title' => $doctrine->getRepository($this->config
['class']['title'])->findOneByTitle($this->config
['default']['title']), 
 371                         //Set action to register route name and context 
 372                         'action' => $this->generateUrl($this->config
['route']['register']['name'], $this->config
['route']['register']['context']), 
 376                 if ($request->isMethod('POST')) { 
 377                         //Refill the fields in case the form is not valid. 
 378                         $form->handleRequest($request); 
 380                         if ($form->isValid()) { 
 382                                 $data = $form->getData(); 
 385                                 $mail =& $this->config
['register']['mail']; 
 387                                 //Generate each route route 
 388                                 foreach($this->config
['register']['route'] as $route => $tag) { 
 389                                         if (empty($mail['context'][$tag]) && !empty($this->config
['route'][$route])) { 
 390                                                 $mail['context'][$tag] = $this->get('router')->generate( 
 391                                                         $this->config
['route'][$route]['name'], 
 392                                                         $this->config
['route'][$route]['context'], 
 393                                                         UrlGeneratorInterface
::ABSOLUTE_URL
 
 399                                 $mail['context']['recipient_mail'] = $data['mail']; 
 402                                 $mail['context']['recipient_name'] = trim($data['forename'].' '.$data['surname'].($data['pseudonym']?' ('.$data['pseudonym'].')':'')); 
 404                                 //Init subject context 
 405                                 $subjectContext = []; 
 407                                 //Process each context pair 
 408                                 foreach($mail['context']+
$this->config
['register']['view']['context'] as $k => $v) { 
 409                                         //Reinsert each context pair with the key surrounded by % 
 410                                         $subjectContext['%'.$k.'%'] = $v; 
 414                                 $mail['subject'] = ucfirst($this->translator
->trans($mail['subject'], $subjectContext)); 
 417                                 $message = (new TemplatedEmail()) 
 419                                         ->from(new Address($this->config
['contact']['mail'], $this->config
['contact']['name'])) 
 421                                         //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 422                                         ->to(new Address($mail['context']['recipient_mail'], $mail['context']['recipient_name'])) 
 424                                         ->subject($mail['subject']) 
 426                                         //Set path to twig templates 
 427                                         ->htmlTemplate($mail['html']) 
 428                                         ->textTemplate($mail['text']) 
 431                                         ->context(['subject' => $mail['subject']]+
$mail['context']+
$this->config
['register']['view']['context']); 
 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                                 //Iterate on default group 
 452                                 foreach($this->config
['default']['group'] as $i => $groupTitle) { 
 454                                         if (($group = $doctrine->getRepository($this->config
['class']['group'])->findOneByTitle($groupTitle))) { 
 456                                                 //XXX: see vendor/symfony/security-core/Role/Role.php 
 457                                                 $user->addGroup($group); 
 461                                                 //XXX: consider missing group as fatal 
 462                                                 throw new \
Exception(sprintf('Group from rapsys_user.default.group[%d] not found by title: %s', $i, $groupTitle)); 
 466                                 $user->setCreated(new \
DateTime('now')); 
 467                                 $user->setUpdated(new \
DateTime('now')); 
 470                                 $manager->persist($user); 
 472                                 //Try saving in database 
 477                                         //Try sending message 
 478                                         //XXX: mail delivery may silently fail 
 481                                                 $mailer->send($message); 
 483                                                 //Redirect on the same route with sent=1 to cleanup form 
 484                                                 #return $this->redirectToRoute('rapsys_user_register', array('sent' => 1)); 
 485                                                 return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+
$request->get('_route_params')); 
 486                                         //Catch obvious transport exception 
 487                                         } catch(TransportExceptionInterface 
$e) { 
 488                                                 //Add error message mail unreachable 
 489                                                 $form->get('mail')->addError(new FormError($this->translator
->trans('Account created but unable to contact: %mail%', array('%mail%' => $data['mail'])))); 
 491                                 //Catch double subscription 
 492                                 } catch (\Doctrine\DBAL\Exception\UniqueConstraintViolationException 
$e) { 
 493                                         //Add error message mail already exists 
 494                                         $form->get('mail')->addError(new FormError($this->translator
->trans('Account already exists: %mail%', ['%mail%' => $data['mail']]))); 
 500                 return $this->render( 
 502                         $this->config
['register']['view']['name'], 
 504                         ['form' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->config
['register']['view']['context'] 
 511         public function getAlias() { 
 512                 return 'rapsys_user';