UserController.php 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. <?php
  2. namespace Muzich\UserBundle\Controller;
  3. use Muzich\CoreBundle\lib\Controller;
  4. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  5. use Symfony\Component\HttpFoundation\RedirectResponse;
  6. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  7. use FOS\UserBundle\Model\UserInterface;
  8. use Muzich\CoreBundle\Form\Tag\TagFavoritesForm;
  9. use Symfony\Component\Validator\Constraints\Email;
  10. use Symfony\Component\Validator\Constraints\Collection;
  11. class UserController extends Controller
  12. {
  13. protected function getChangeEmailForm()
  14. {
  15. $collectionConstraint = new Collection(array(
  16. 'email' => new Email(array('message' => 'error.changeemail.email.invalid')),
  17. ));
  18. return $this->createFormBuilder(null, array(
  19. 'validation_constraint' => $collectionConstraint,
  20. ))
  21. ->add('email', 'text')
  22. ->getForm()
  23. ;
  24. }
  25. protected function getTagsFavoritesForm($user)
  26. {
  27. return $this->createForm(
  28. new TagFavoritesForm(),
  29. array('tags' => $this->getDoctrine()->getRepository('MuzichCoreBundle:User')
  30. ->getTagIdsFavorites($user->getId())
  31. ),
  32. array('tags' => $this->getTagsArray())
  33. );
  34. }
  35. /**
  36. * Page de configuration de son compte
  37. *
  38. * @Template()
  39. */
  40. public function accountAction()
  41. {
  42. $user = $this->getUser();
  43. $form_password = $this->container->get('fos_user.change_password.form');
  44. $form_tags_favorites = $this->getTagsFavoritesForm($user);
  45. $change_email_form = $this->getChangeEmailForm();
  46. return array(
  47. 'user' => $user,
  48. 'form_password' => $form_password->createView(),
  49. 'form_tags_favorites' => $form_tags_favorites->createView(),
  50. 'change_email_form' => $change_email_form->createView()
  51. );
  52. }
  53. /**
  54. * Un bug étrange empêche la mise ne place de contraintes sur le formulaire
  55. * d'inscription. On effectue alors les vérifications ici.
  56. *
  57. * C'est sale, mais ça marche ...
  58. *
  59. * @return array of string errors
  60. */
  61. protected function checkRegistrationInformations($form)
  62. {
  63. $errors = array();
  64. $form->bindRequest($this->getRequest());
  65. $form_values = $this->getRequest()->request->get($form->getName());
  66. $user = $form->getData();
  67. /*
  68. * Contrôle de la taille du pseudo
  69. * min: 3
  70. * max: 32
  71. */
  72. if (strlen($user->getUsername()) < 3)
  73. {
  74. $errors[] = $this->get('translator')->trans(
  75. 'error.registration.username.min',
  76. array('%limit%' => 3),
  77. 'validators'
  78. );
  79. }
  80. if (strlen($user->getUsername()) > 32)
  81. {
  82. $errors[] = $this->get('translator')->trans(
  83. 'error.registration.username.max',
  84. array('%limit%' => 32),
  85. 'validators'
  86. );
  87. }
  88. /**
  89. * Mot de passes indentiques
  90. */
  91. if ($form_values['plainPassword']['first'] != $form_values['plainPassword']['second'])
  92. {
  93. $errors[] = $this->get('translator')->trans(
  94. 'error.registration.password.notsame',
  95. array(),
  96. 'validators'
  97. );
  98. }
  99. return $errors;
  100. }
  101. public function registerAction()
  102. {
  103. $form = $this->container->get('fos_user.registration.form');
  104. $formHandler = $this->container->get('fos_user.registration.form.handler');
  105. $confirmationEnabled = $this->container->getParameter('fos_user.registration.confirmation.enabled');
  106. // Pour palier bug, verif interne
  107. if (count(($errors = $this->checkRegistrationInformations($form))) < 1)
  108. {
  109. $process = $formHandler->process($confirmationEnabled);
  110. if ($process) {
  111. $user = $form->getData();
  112. if ($confirmationEnabled) {
  113. $this->container->get('session')->set('fos_user_send_confirmation_email/email', $user->getEmail());
  114. $route = 'fos_user_registration_check_email';
  115. } else {
  116. $this->authenticateUser($user);
  117. $route = 'start';
  118. }
  119. $this->setFlash('fos_user_success', 'registration.flash.user_created');
  120. $url = $this->generateUrl($route);
  121. return new RedirectResponse($url);
  122. }
  123. }
  124. return $this->container->get('templating')->renderResponse(
  125. 'MuzichIndexBundle:Index:index.html.twig',
  126. array(
  127. 'form' => $form->createView(),
  128. 'error' => null,
  129. 'registration_errors' => $form->getErrors(),
  130. 'registration_errors_pers' => $errors,
  131. 'last_username' => null
  132. )
  133. );
  134. }
  135. /**
  136. * Un bug étrange empêche la mise ne place de contraintes sur le formulaire
  137. * d'inscription. On effectue alors les vérifications ici.
  138. *
  139. * C'est sale, mais ça marche ...
  140. *
  141. * @return array of string errors
  142. */
  143. protected function checkChangePasswordInformations($form)
  144. {
  145. $errors = array();
  146. $form_values = $this->getRequest()->request->get($form->getName());
  147. $user = $form->getData();
  148. /**
  149. * Mot de passes indentiques
  150. */
  151. if ($form_values['new']['first'] != $form_values['new']['second'])
  152. {
  153. $errors[] = $this->get('translator')->trans(
  154. 'error.changepassword.new.notsame',
  155. array(),
  156. 'validators'
  157. );
  158. }
  159. return $errors;
  160. }
  161. public function changePasswordAction()
  162. {
  163. $user = $this->getUser();
  164. /**
  165. * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine.
  166. * Docrine le voit si on faire une requete directe.
  167. */
  168. if ($this->container->getParameter('env') == 'test')
  169. {
  170. $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById(
  171. $this->container->get('security.context')->getToken()->getUser()->getId(),
  172. array()
  173. )->getSingleResult();
  174. }
  175. if (!is_object($user) || !$user instanceof UserInterface) {
  176. throw new AccessDeniedException('This user does not have access to this section.');
  177. }
  178. $form = $this->container->get('fos_user.change_password.form');
  179. $formHandler = $this->container->get('fos_user.change_password.form.handler');
  180. $process = $formHandler->process($user);
  181. if (count(($errors = $this->checkChangePasswordInformations($form))) < 1 && $process)
  182. {
  183. $this->container->get('session')->setFlash('fos_user_success', 'change_password.flash.success');
  184. return new RedirectResponse($this->generateUrl('my_account'));
  185. }
  186. else
  187. {
  188. $form_tags_favorites = $this->createForm(
  189. new TagFavoritesForm(),
  190. array('tags' => $this->getDoctrine()->getRepository('MuzichCoreBundle:User')
  191. ->getTagIdsFavorites($user->getId())
  192. ),
  193. array('tags' => $this->getTagsArray())
  194. );
  195. return $this->container->get('templating')->renderResponse(
  196. 'MuzichUserBundle:User:account.html.twig',
  197. array(
  198. 'form_password' => $form->createView(),
  199. 'errors_pers' => $errors,
  200. 'user' => $user,
  201. 'form_tags_favorites' => $form_tags_favorites->createView()
  202. )
  203. );
  204. }
  205. }
  206. /**
  207. * Page ouverte après l'inscription sur laquelle on propose de saisir ses
  208. * tags favoris.
  209. *
  210. * @Template()
  211. */
  212. public function startAction()
  213. {
  214. $user = $this->getUser();
  215. $form = $this->createForm(
  216. new TagFavoritesForm(),
  217. array('tags' => $this->getDoctrine()->getRepository('MuzichCoreBundle:User')
  218. ->getTagIdsFavorites($user->getId())
  219. ),
  220. array('tags' => $this->getTagsArray())
  221. );
  222. return array(
  223. 'form' => $form->createView()
  224. );
  225. }
  226. /**
  227. *
  228. * @param string $redirect
  229. */
  230. public function updateTagFavoritesAction($redirect)
  231. {
  232. $request = $this->getRequest();
  233. $user = $this->getUser(true, array('join' => array('favorites_tags')));
  234. /**
  235. * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine.
  236. * Docrine le voit si on faire une requete directe.
  237. */
  238. if ($this->container->getParameter('env') == 'test')
  239. {
  240. $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById(
  241. $this->container->get('security.context')->getToken()->getUser()->getId(),
  242. array()
  243. )->getSingleResult();
  244. }
  245. $form = $this->createForm(
  246. new TagFavoritesForm(),
  247. array('tags' => $this->getDoctrine()->getRepository('MuzichCoreBundle:User')
  248. ->getTagIdsFavorites($user->getId())
  249. ),
  250. array('tags' => $this->getTagsArray())
  251. );
  252. if ($request->getMethod() == 'POST')
  253. {
  254. $form->bindRequest($request);
  255. if ($form->isValid())
  256. {
  257. $data = $form->getData();
  258. $user->updateTagsFavoritesById($this->getDoctrine()->getEntityManager(), $data['tags']);
  259. $this->container->get('session')->setFlash('success', 'Vos tags péférés ont correctements été mis a jour.');
  260. }
  261. else
  262. {
  263. return $this->container->get('templating')->renderResponse(
  264. 'MuzichUserBundle:User:start.html.twig',
  265. array(
  266. 'form' => $form->createView()
  267. )
  268. );
  269. }
  270. }
  271. // (Il y aura aussi une redirection vers "mon compte / tags")
  272. if ($redirect == 'home')
  273. {
  274. return $this->redirect($this->generateUrl('home'));
  275. }
  276. else
  277. {
  278. return $this->redirect($this->generateUrl('my_account'));
  279. }
  280. }
  281. protected function checkChangeEmailFrequencies($user, $new_email)
  282. {
  283. $delay = $this->container->getParameter('changeemail_security_delay');
  284. if (($last_request_datetime = $user->getEmailRequestedDatetime()))
  285. {
  286. if ((time() - $last_request_datetime) < $delay)
  287. {
  288. return false;
  289. }
  290. }
  291. return true;
  292. }
  293. /**
  294. * Procédure de demande de changement de mot de passe
  295. */
  296. public function changeEmailRequestAction()
  297. {
  298. $em = $this->getDoctrine()->getEntityManager();
  299. $user = $this->getUser();
  300. $request = $this->getRequest();
  301. $change_email_form = $this->getChangeEmailForm();
  302. $change_email_form->bindRequest($request);
  303. if ($change_email_form->isValid())
  304. {
  305. $data = $change_email_form->getData();
  306. $email = $data['email'];
  307. if (!$this->checkChangeEmailFrequencies($user, $email))
  308. {
  309. $this->setFlash('error', 'user.changeemail.wait');
  310. return new RedirectResponse($this->generateUrl('my_account'));
  311. }
  312. // On renseigne en base l'email demandé
  313. $user->setEmailRequested($email);
  314. $user->setEmailRequestedDatetime(time());
  315. $user->generateConfirmationToken();
  316. $token = hash('sha256', $user->getConfirmationToken().$email);
  317. $url = $this->get('router')->generate('change_email_confirm', array('token' => $token), true);
  318. $rendered = $this->get('templating')->render('MuzichUserBundle:User:change_email_mail.txt.twig', array(
  319. 'user' => $user,
  320. 'confirmationUrl' => $url
  321. ));
  322. //$this->sendEmailMessage($rendered, $this->parameters['from_email']['resetting'], $user->getEmail());
  323. // Render the email, use the first line as the subject, and the rest as the body
  324. $renderedLines = explode("\n", trim($rendered));
  325. $subject = $renderedLines[0];
  326. $body = implode("\n", array_slice($renderedLines, 1));
  327. $message = \Swift_Message::newInstance()
  328. ->setSubject($subject)
  329. ->setFrom('noreply@muzi.ch')
  330. ->setTo($email)
  331. ->setBody($body);
  332. $mailer = $this->get('mailer');
  333. $mailer->send($message);
  334. $this->setFlash('info', 'user.changeemail.mail_send');
  335. $em->flush();
  336. }
  337. // En cas d'échec
  338. $form_password = $this->container->get('fos_user.change_password.form');
  339. $form_tags_favorites = $this->getTagsFavoritesForm($user);
  340. return $this->container->get('templating')->renderResponse(
  341. 'MuzichUserBundle:User:account.html.twig',
  342. array(
  343. 'user' => $user,
  344. 'form_password' => $form_password->createView(),
  345. 'form_tags_favorites' => $form_tags_favorites->createView(),
  346. 'change_email_form' => $change_email_form->createView()
  347. )
  348. );
  349. }
  350. /**
  351. * Procédure de confirmation de la nouvelle adresse email.
  352. */
  353. public function changeEmailConfirmAction($token)
  354. {
  355. $em = $this->getDoctrine()->getEntityManager();
  356. $um = $this->get('muzich_user_manager');
  357. $user = $this->getUser();
  358. $token_ = hash('sha256', $user->getConfirmationToken().($email = $user->getEmailRequested()));
  359. // Le token est-il valide
  360. if ($token_ != $token)
  361. {
  362. $this->setFlash('error', 'user.changeemail.token_invalid');
  363. return new RedirectResponse($this->generateUrl('my_account'));
  364. }
  365. $user->setEmail($email);
  366. $user->setEmailRequested(null);
  367. $um->updateCanonicalFields($user);
  368. $em->flush();
  369. $this->setFlash('success', 'user.changeemail.success');
  370. return new RedirectResponse($this->generateUrl('my_account'));
  371. }
  372. }