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                 $form = $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']), 
  77                 //Get the login error if there is one 
  78                 if ($error = $authenticationUtils->getLastAuthenticationError()) { 
  79                         //Get translated error 
  80                         $error = $this->translator
->trans($error->getMessageKey()); 
  82                         //Add error message to mail field 
  83                         $form->get('mail')->addError(new FormError($error)); 
  86                 //Last username entered by the user 
  87                 if ($lastUsername = $authenticationUtils->getLastUsername()) { 
  88                         $form->get('mail')->setData($lastUsername); 
  94                         $this->config
['login']['view']['name'], 
  96                         ['form' => $form->createView(), 'error' => $error]+
$this->config
['login']['view']['context'] 
 100         public function recover(Request 
$request, Slugger 
$slugger, MailerInterface 
$mailer) { 
 101                 //Create the RecoverType form and give the proper parameters 
 102                 $form = $this->createForm($this->config
['recover']['view']['form'], null, array( 
 103                         //Set action to recover route name and context 
 104                         'action' => $this->generateUrl($this->config
['route']['recover']['name'], $this->config
['route']['recover']['context']), 
 108                 if ($request->isMethod('POST')) { 
 109                         //Refill the fields in case the form is not valid. 
 110                         $form->handleRequest($request); 
 112                         if ($form->isValid()) { 
 114                                 $doctrine = $this->getDoctrine(); 
 117                                 $data = $form->getData(); 
 120                                 if ($user = $doctrine->getRepository($this->config
['class']['user'])->findOneByMail($data['mail'])) { 
 122                                         $mail =& $this->config
['recover']['mail']; 
 124                                         //Generate each route route 
 125                                         foreach($this->config
['recover']['route'] as $route => $tag) { 
 126                                                 //Only process defined routes 
 127                                                 if (empty($mail['context'][$tag]) && !empty($this->config
['route'][$route])) { 
 128                                                         //Process for recover mail url 
 129                                                         if ($route == 'recover_mail') { 
 130                                                                 //Prepend recover context with tag 
 131                                                                 $this->config
['route'][$route]['context'] = [ 
 132                                                                         'recipient' => $slugger->short($user->getMail()), 
 133                                                                         'hash' => $slugger->hash($user->getPassword()) 
 134                                                                 ]+
$this->config
['route'][$route]['context']; 
 136                                                         //Set the url in context 
 137                                                         $mail['context'][$tag] = $this->get('router')->generate( 
 138                                                                 $this->config
['route'][$route]['name'], 
 139                                                                 $this->config
['route'][$route]['context'], 
 140                                                                 UrlGeneratorInterface
::ABSOLUTE_URL
 
 147                                         $mail['context']['recipient_mail'] = $data['mail']; 
 150                                         $mail['context']['recipient_name'] = trim($user->getForename().' '.$user->getSurname().($user->getPseudonym()?' ('.$user->getPseudonym().')':'')); 
 152                                         //Init subject context 
 153                                         $subjectContext = []; 
 155                                         //Process each context pair 
 156                                         foreach($mail['context']+
$this->config
['recover']['view']['context'] as $k => $v) { 
 157                                                 //Reinsert each context pair with the key surrounded by % 
 158                                                 $subjectContext['%'.$k.'%'] = $v; 
 162                                         $mail['subject'] = ucfirst($this->translator
->trans($mail['subject'], $subjectContext)); 
 165                                         $message = (new TemplatedEmail()) 
 167                                                 ->from(new Address($this->config
['contact']['mail'], $this->config
['contact']['name'])) 
 169                                                 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 170                                                 ->to(new Address($mail['context']['recipient_mail'], $mail['context']['recipient_name'])) 
 172                                                 ->subject($mail['subject']) 
 174                                                 //Set path to twig templates 
 175                                                 ->htmlTemplate($mail['html']) 
 176                                                 ->textTemplate($mail['text']) 
 179                                                 ->context(['subject' => $mail['subject']]+
$mail['context']+
$this->config
['recover']['view']['context']); 
 181                                         //Try sending message 
 182                                         //XXX: mail delivery may silently fail 
 185                                                 $mailer->send($message); 
 187                                                 //Redirect on the same route with sent=1 to cleanup form 
 188                                                 #return $this->redirectToRoute('rapsys_user_register', array('sent' => 1)); 
 189                                                 return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+
$request->get('_route_params')); 
 190                                         //Catch obvious transport exception 
 191                                         } catch(TransportExceptionInterface 
$e) { 
 192                                                 //Add error message mail unreachable 
 193                                                 $form->get('mail')->addError(new FormError($this->translator
->trans('Account found but unable to contact: %mail%', array('%mail%' => $data['mail'])))); 
 197                                         //Add error message to mail field 
 198                                         $form->get('mail')->addError(new FormError($this->translator
->trans('Unable to find account: %mail%', ['%mail%' => $data['mail']]))); 
 204                 return $this->render( 
 206                         $this->config
['recover']['view']['name'], 
 208                         ['form' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->config
['recover']['view']['context'] 
 212         public function recoverMail(Request 
$request, UserPasswordEncoderInterface 
$encoder, Slugger 
$slugger, MailerInterface 
$mailer, $recipient, $hash) { 
 213                 //Create the RecoverType form and give the proper parameters 
 214                 $form = $this->createForm($this->config
['recover_mail']['view']['form'], null, array( 
 215                         //Set action to recover route name and context 
 216                         'action' => $this->generateUrl($this->config
['route']['recover_mail']['name'], ['recipient' => $recipient, 'hash' => $hash]+
$this->config
['route']['recover_mail']['context']), 
 221                 $doctrine = $this->getDoctrine(); 
 227                 if (($user = $doctrine->getRepository($this->config
['class']['user'])->findOneByMail($slugger->unshort($recipient))) && $hash == $slugger->hash($user->getPassword())) { 
 231                         if ($request->isMethod('POST')) { 
 232                                 //Refill the fields in case the form is not valid. 
 233                                 $form->handleRequest($request); 
 235                                 if ($form->isValid()) { 
 237                                         $data = $form->getData(); 
 239                                         //set encoded password 
 240                                         $encoded = $encoder->encodePassword($user, $data['password']); 
 243                                         $user->setPassword($encoded); 
 246                                         $manager = $doctrine->getManager(); 
 249                                         $manager->persist($user); 
 255                                         $mail =& $this->config
['recover_mail']['mail']; 
 258                                         $hash = $slugger->hash($encoded); 
 260                                         //Generate each route route 
 261                                         foreach($this->config
['recover_mail']['route'] as $route => $tag) { 
 262                                                 //Only process defined routes 
 263                                                 if (empty($mail['context'][$tag]) && !empty($this->config
['route'][$route])) { 
 264                                                         //Process for recover mail url 
 265                                                         if ($route == 'recover_mail') { 
 266                                                                 //Prepend recover context with tag 
 267                                                                 $this->config
['route'][$route]['context'] = [ 
 268                                                                         'recipient' => $recipient, 
 270                                                                 ]+
$this->config
['route'][$route]['context']; 
 272                                                         //Set the url in context 
 273                                                         $mail['context'][$tag] = $this->get('router')->generate( 
 274                                                                 $this->config
['route'][$route]['name'], 
 275                                                                 $this->config
['route'][$route]['context'], 
 276                                                                 UrlGeneratorInterface
::ABSOLUTE_URL
 
 282                                         $mail['context']['recipient_mail'] = $user->getMail(); 
 285                                         $mail['context']['recipient_name'] = trim($user->getForename().' '.$user->getSurname().($user->getPseudonym()?' ('.$user->getPseudonym().')':'')); 
 287                                         //Init subject context 
 288                                         $subjectContext = []; 
 290                                         //Process each context pair 
 291                                         foreach($mail['context']+
$this->config
['recover_mail']['view']['context'] as $k => $v) { 
 292                                                 //Reinsert each context pair with the key surrounded by % 
 293                                                 $subjectContext['%'.$k.'%'] = $v; 
 297                                         $mail['subject'] = ucfirst($this->translator
->trans($mail['subject'], $subjectContext)); 
 300                                         $message = (new TemplatedEmail()) 
 302                                                 ->from(new Address($this->config
['contact']['mail'], $this->config
['contact']['name'])) 
 304                                                 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 305                                                 ->to(new Address($mail['context']['recipient_mail'], $mail['context']['recipient_name'])) 
 307                                                 ->subject($mail['subject']) 
 309                                                 //Set path to twig templates 
 310                                                 ->htmlTemplate($mail['html']) 
 311                                                 ->textTemplate($mail['text']) 
 314                                                 ->context(['subject' => $mail['subject']]+
$mail['context']+
$this->config
['recover_mail']['view']['context']); 
 316                                         //Try sending message 
 317                                         //XXX: mail delivery may silently fail 
 320                                                 $mailer->send($message); 
 322                                                 //Redirect on the same route with sent=1 to cleanup form 
 323                                                 return $this->redirectToRoute($request->get('_route'), ['recipient' => $recipient, 'hash' => $hash, 'sent' => 1]+
$request->get('_route_params')); 
 324                                         //Catch obvious transport exception 
 325                                         } catch(TransportExceptionInterface 
$e) { 
 326                                                 //Add error message mail unreachable 
 327                                                 $form->get('mail')->addError(new FormError($this->translator
->trans('Account password updated but unable to contact: %mail%', array('%mail%' => $mail['context']['recipient_mail'])))); 
 333                         //Add error message to mail field 
 334                         $form->get('mail')->addError(new FormError($this->translator
->trans('Unable to find account: %mail%', ['%mail%' => $slugger->unshort($recipient)]))); 
 338                 return $this->render( 
 340                         $this->config
['recover_mail']['view']['name'], 
 342                         ['form' => $form->createView(), 'sent' => $request->query
->get('sent', 0), 'notfound' => $notfound]+
$this->config
['recover_mail']['view']['context'] 
 346         public function register(Request 
$request, UserPasswordEncoderInterface 
$encoder, MailerInterface 
$mailer) { 
 347                 //Create the RegisterType form and give the proper parameters 
 348                 $form = $this->createForm($this->config
['register']['view']['form'], null, array( 
 349                         'class_title' => $this->config
['class']['title'], 
 350                         //Set action to register route name and context 
 351                         'action' => $this->generateUrl($this->config
['route']['register']['name'], $this->config
['route']['register']['context']), 
 355                 if ($request->isMethod('POST')) { 
 356                         //Refill the fields in case the form is not valid. 
 357                         $form->handleRequest($request); 
 359                         if ($form->isValid()) { 
 361                                 $data = $form->getData(); 
 364                                 $mail =& $this->config
['register']['mail']; 
 366                                 //Generate each route route 
 367                                 foreach($this->config
['register']['route'] as $route => $tag) { 
 368                                         if (empty($mail['context'][$tag]) && !empty($this->config
['route'][$route])) { 
 369                                                 $mail['context'][$tag] = $this->get('router')->generate( 
 370                                                         $this->config
['route'][$route]['name'], 
 371                                                         $this->config
['route'][$route]['context'], 
 372                                                         UrlGeneratorInterface
::ABSOLUTE_URL
 
 378                                 $mail['context']['recipient_mail'] = $data['mail']; 
 381                                 $mail['context']['recipient_name'] = trim($data['forename'].' '.$data['surname'].($data['pseudonym']?' ('.$data['pseudonym'].')':'')); 
 383                                 //Init subject context 
 384                                 $subjectContext = []; 
 386                                 //Process each context pair 
 387                                 foreach($mail['context']+
$this->config
['register']['view']['context'] as $k => $v) { 
 388                                         //Reinsert each context pair with the key surrounded by % 
 389                                         $subjectContext['%'.$k.'%'] = $v; 
 393                                 $mail['subject'] = ucfirst($this->translator
->trans($mail['subject'], $subjectContext)); 
 396                                 $message = (new TemplatedEmail()) 
 398                                         ->from(new Address($this->config
['contact']['mail'], $this->config
['contact']['name'])) 
 400                                         //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 
 401                                         ->to(new Address($mail['context']['recipient_mail'], $mail['context']['recipient_name'])) 
 403                                         ->subject($mail['subject']) 
 405                                         //Set path to twig templates 
 406                                         ->htmlTemplate($mail['html']) 
 407                                         ->textTemplate($mail['text']) 
 410                                         ->context(['subject' => $mail['subject']]+
$mail['context']+
$this->config
['register']['view']['context']); 
 413                                 $doctrine = $this->getDoctrine(); 
 416                                 $manager = $doctrine->getManager(); 
 419                                 $reflection = new \
ReflectionClass($this->config
['class']['user']); 
 422                                 $user = $reflection->newInstance(); 
 424                                 $user->setMail($data['mail']); 
 425                                 $user->setPseudonym($data['pseudonym']); 
 426                                 $user->setForename($data['forename']); 
 427                                 $user->setSurname($data['surname']); 
 428                                 $user->setPhone($data['phone']); 
 429                                 $user->setPassword($encoder->encodePassword($user, $data['password'])); 
 430                                 $user->setActive(true); 
 431                                 $user->setTitle($data['title']); 
 433                                 //XXX: For now there is no point in setting a role at subscription 
 434                                 //TODO: see if we can't modify group constructor to set role directly from args 
 435                                 //XXX: see vendor/symfony/symfony/src/Symfony/Component/Security/Core/Role/Role.php 
 436                                 #$user->addGroup($doctrine->getRepository($this->config['class']['group'])->findOneByRole('ROLE_USER')); 
 438                                 $user->setCreated(new \
DateTime('now')); 
 439                                 $user->setUpdated(new \
DateTime('now')); 
 442                                 $manager->persist($user); 
 444                                 //Try saving in database 
 449                                         //Try sending message 
 450                                         //XXX: mail delivery may silently fail 
 453                                                 $mailer->send($message); 
 455                                                 //Redirect on the same route with sent=1 to cleanup form 
 456                                                 #return $this->redirectToRoute('rapsys_user_register', array('sent' => 1)); 
 457                                                 return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+
$request->get('_route_params')); 
 458                                         //Catch obvious transport exception 
 459                                         } catch(TransportExceptionInterface 
$e) { 
 460                                                 //Add error message mail unreachable 
 461                                                 $form->get('mail')->addError(new FormError($this->translator
->trans('Account created but unable to contact: %mail%', array('%mail%' => $data['mail'])))); 
 463                                 //Catch double subscription 
 464                                 } catch (\Doctrine\DBAL\Exception\UniqueConstraintViolationException 
$e) { 
 465                                         //Add error message mail already exists 
 466                                         $form->get('mail')->addError(new FormError($this->translator
->trans('Account already exists: %mail%', ['%mail%' => $data['mail']]))); 
 472                 return $this->render( 
 474                         $this->config
['register']['view']['name'], 
 476                         ['form' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->config
['register']['view']['context'] 
 483         public function getAlias() { 
 484                 return 'rapsys_user';