new Email(array('message' => 'error.changeemail.email.invalid')), )); return $this->createFormBuilder(null, array( //'validation_constraint' => $collectionConstraint, UPGRADE 2.1 'constraints' => $collectionConstraint, )) ->add('email', 'text') ->getForm() ; } protected function getPreferencesForm() { /** * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine. * Docrine le voit si on faire une requete directe. */ if ($this->container->getParameter('env') == 'test') { $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById( $this->container->get('security.context')->getToken()->getUser()->getId(), array() )->getSingleResult(); } else { $user = $this->getUser(); } return $this->createFormBuilder($user) ->add('mail_newsletter', 'checkbox', array('required' => false)) ->add('mail_partner', 'checkbox', array('required' => false)) ->getForm() ; } protected function getTagsFavoritesForm($user) { $ids = array(); foreach ($this->getTagsFavorites() as $id => $name) { $ids[] = $id; } return $this->createForm( new TagFavoritesForm(), array('tags' => json_encode($ids)) ); } protected function getTagsFavorites($force = false) { if ($this->tags_favorites === null || $force) { $user = $this->getUser(); /** * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine. * Docrine le voit si on faire une requete directe. */ if ($this->container->getParameter('env') == 'test') { $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById( $this->container->get('security.context')->getToken()->getUser()->getId(), array() )->getSingleResult(); } $this->tags_favorites = $this->getDoctrine()->getRepository('MuzichCoreBundle:User') ->getTagsFavorites($user->getId()) ; } return $this->tags_favorites; } /** * Page de configuration de son compte * * @Template() */ public function accountAction() { $user = $this->getUser(); $form_password = $this->container->get('fos_user.change_password.form'); $form_tags_favorites = $this->getTagsFavoritesForm($user); $change_email_form = $this->getChangeEmailForm(); return array( 'user' => $user, 'form_password' => $form_password->createView(), 'form_tags_favorites' => $form_tags_favorites->createView(), 'form_tags_favorites_name' => $form_tags_favorites->getName(), 'favorite_tags_id' => $this->getTagsFavorites(), 'change_email_form' => $change_email_form->createView(), 'avatar_form' => $this->getAvatarForm()->createView(), 'preferences_form' => $this->getPreferencesForm()->createView() ); } protected function getAvatarForm() { return $this->createFormBuilder($this->getUser()) ->add('avatar') ->getForm() ; } /** * Un bug étrange empêche la mise ne place de contraintes sur le formulaire * d'inscription. On effectue alors les vérifications ici. * * C'est sale, mais ça marche ... * * @return array of string errors */ protected function checkRegistrationInformations($form) { $errors = array(); $form->bind($this->getRequest()); $form_values = $this->getRequest()->request->get($form->getName()); $user = $form->getData(); /* * Contrôle de la taille du pseudo * min: 3 * max: 32 */ if (strlen($user->getUsername()) < 3) { $errors[] = $this->get('translator')->trans( 'error.registration.username.min', array('%limit%' => 3), 'validators' ); } if (strlen($user->getUsername()) > 32) { $errors[] = $this->get('translator')->trans( 'error.registration.username.max', array('%limit%' => 32), 'validators' ); } /** * Mot de passes indentiques */ if ($form_values['plainPassword']['first'] != $form_values['plainPassword']['second']) { $errors[] = $this->get('translator')->trans( 'error.registration.password.notsame', array(), 'validators' ); } return $errors; } public function registerAction() { $form = $this->container->get('fos_user.registration.form'); $formHandler = $this->container->get('fos_user.registration.form.handler'); $confirmationEnabled = $this->container->getParameter('fos_user.registration.confirmation.enabled'); $errors = array(); // On contrôle le token en premier lieu $form_values = $this->getRequest()->request->get($form->getName()); $r_token = $this->getDoctrine()->getRepository('MuzichCoreBundle:RegistrationToken') ->findOneBy(array('token' => $form_values["token"], 'used' => false)) ; if ($r_token) { if (count(($errors = $this->checkRegistrationInformations($form))) < 1) { $process = $formHandler->process($confirmationEnabled); if ($process) { $user = $form->getData(); if ($confirmationEnabled) { $this->container->get('session')->set('fos_user_send_confirmation_email/email', $user->getEmail()); $route = 'fos_user_registration_check_email'; } else { $this->authenticateUser($user); $route = 'start'; } $this->setFlash('fos_user_success', 'registration.flash.user_created'); $url = $this->generateUrl($route); $r_token->addUseCount(); $em = $this->getDoctrine()->getEntityManager(); $em->persist($r_token); $em->flush(); return new RedirectResponse($url); } } } else { $form->bind($this->getRequest()); $errors[] = $this->get('translator')->trans( 'registration.token.error', array(), 'validators' ); } return $this->container->get('templating')->renderResponse( 'MuzichIndexBundle:Index:index.html.twig', array( 'form' => $form->createView(), 'error' => null, 'registration_errors' => $form->getErrors(), 'registration_errors_pers' => $errors, 'last_username' => null, 'registration_page' => true, 'presubscription_form' => $this->getPreSubscriptionForm()->createView() ) ); } /** * Un bug étrange empêche la mise ne place de contraintes sur le formulaire * d'inscription. On effectue alors les vérifications ici. * * C'est sale, mais ça marche ... * * @return array of string errors */ protected function checkChangePasswordInformations($form) { $errors = array(); $form_values = $this->getRequest()->request->get($form->getName()); $user = $form->getData(); /** * Mot de passes indentiques */ if ($form_values['new']['first'] != $form_values['new']['second']) { $errors[] = $this->get('translator')->trans( 'error.changepassword.new.notsame', array(), 'validators' ); } return $errors; } public function changePasswordAction() { $user = $this->getUser(); /** * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine. * Docrine le voit si on faire une requete directe. */ if ($this->container->getParameter('env') == 'test') { $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById( $this->container->get('security.context')->getToken()->getUser()->getId(), array() )->getSingleResult(); } if (!is_object($user) || !$user instanceof UserInterface) { throw new AccessDeniedException('This user does not have access to this section.'); } $form = $this->container->get('fos_user.change_password.form'); $formHandler = $this->container->get('fos_user.change_password.form.handler'); $process = $formHandler->process($user); if (count(($errors = $this->checkChangePasswordInformations($form))) < 1 && $process) { $this->container->get('session')->setFlash('fos_user_success', 'change_password.flash.success'); return new RedirectResponse($this->generateUrl('my_account')); } else { $form_tags_favorites = $this->getTagsFavoritesForm($user); $change_email_form = $this->getChangeEmailForm(); return $this->container->get('templating')->renderResponse( 'MuzichUserBundle:User:account.html.twig', array( 'form_password' => $form->createView(), 'errors_pers' => $errors, 'user' => $user, 'form_tags_favorites' => $form_tags_favorites->createView(), 'form_tags_favorites_name' => $form_tags_favorites->getName(), 'favorite_tags_id' => $this->getTagsFavorites(), 'change_email_form' => $change_email_form->createView(), 'avatar_form' => $this->getAvatarForm()->createView() ) ); } } /** * Page ouverte après l'inscription sur laquelle on propose de saisir ses * tags favoris. * * @Template() */ public function startAction() { $user = $this->getUser(); $form_tags_favorites = $this->getTagsFavoritesForm($user); return array( 'favorite_tags_id' => $this->getTagsFavorites(), 'form_tags_favorites' => $form_tags_favorites->createView(), 'form_tags_favorites_name' => $form_tags_favorites->getName(), ); } /** * * @param string $redirect */ public function updateTagFavoritesAction($redirect) { $request = $this->getRequest(); $user = $this->getUser(true, array('join' => array('favorites_tags'))); /** * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine. * Docrine le voit si on faire une requete directe. */ if ($this->container->getParameter('env') == 'test') { $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById( $this->container->get('security.context')->getToken()->getUser()->getId(), array() )->getSingleResult(); } $form = $this->getTagsFavoritesForm($user); if ($request->getMethod() == 'POST') { $form->bind($request); if ($form->isValid()) { $data = $form->getData(); $user->updateTagsFavoritesById($this->getDoctrine()->getEntityManager(), $data['tags']); // On réinitialise l'eventuel session de recherche en mémoire $session = $this->get("session"); $session->remove('user.element_search.params'); $this->container->get('session')->setFlash('success', 'Vos tags péférés ont correctements été mis a jour.'); } else { return $this->container->get('templating')->renderResponse( 'MuzichUserBundle:User:start.html.twig', array( 'form' => $form->createView() ) ); } } // (Il y aura aussi une redirection vers "mon compte / tags") if ($redirect == 'home') { return $this->redirect($this->generateUrl('home')); } else { return $this->redirect($this->generateUrl('my_account')); } } protected function checkChangeEmailFrequencies($user, $new_email) { $delay = $this->container->getParameter('changeemail_security_delay'); if (($last_request_datetime = $user->getEmailRequestedDatetime())) { if ((time() - $last_request_datetime) < $delay) { return false; } } return true; } /** * Procédure de demande de changement de mot de passe */ public function changeEmailRequestAction() { $em = $this->getDoctrine()->getEntityManager(); $user = $this->getUser(); /** * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine. * Docrine le voit si on faire une requete directe. */ if ($this->container->getParameter('env') == 'test') { $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById( $this->container->get('security.context')->getToken()->getUser()->getId(), array() )->getSingleResult(); } $request = $this->getRequest(); $change_email_form = $this->getChangeEmailForm(); $change_email_form->bind($request); if ($change_email_form->isValid()) { $data = $change_email_form->getData(); $email = $data['email']; if (!$this->checkChangeEmailFrequencies($user, $email)) { $this->setFlash('error', 'user.changeemail.wait'); return new RedirectResponse($this->generateUrl('my_account')); } /* * Optimisation: Ecrire une lib Mailer pour gérer les envois. * cf le mailer de FOSUserBundle */ // On renseigne en base l'email demandé $user->setEmailRequested($email); $user->setEmailRequestedDatetime(time()); //$user->generateConfirmationToken(); UPGRADE FOSUserBundle 1.3 $tokenGenerator = $this->container->get('fos_user.util.token_generator'); $user->setConfirmationToken($tokenGenerator->generateToken()); $token = hash('sha256', $user->getConfirmationToken().$email); $url = $this->get('router')->generate('change_email_confirm', array('token' => $token), true); $rendered = $this->get('templating')->render('MuzichUserBundle:User:change_email_mail.txt.twig', array( 'user' => $user, 'confirmationUrl' => $url )); //$this->sendEmailMessage($rendered, $this->parameters['from_email']['resetting'], $user->getEmail()); // Render the email, use the first line as the subject, and the rest as the body $renderedLines = explode("\n", trim($rendered)); $subject = $renderedLines[0]; $body = implode("\n", array_slice($renderedLines, 1)); $message = \Swift_Message::newInstance() ->setSubject($subject) ->setFrom('noreply@muzi.ch') ->setTo($email) ->setBody($body); $mailer = $this->get('mailer'); $mailer->send($message); $this->setFlash('success', 'user.changeemail.mail_send'); $em->flush(); return new RedirectResponse($this->generateUrl('my_account')); } // En cas d'échec $form_password = $this->container->get('fos_user.change_password.form'); $form_tags_favorites = $this->getTagsFavoritesForm($user); return $this->container->get('templating')->renderResponse( 'MuzichUserBundle:User:account.html.twig', array( 'user' => $user, 'form_password' => $form_password->createView(), 'form_tags_favorites' => $form_tags_favorites->createView(), 'form_tags_favorites_name' => $form_tags_favorites->getName(), 'favorite_tags_id' => $this->getTagsFavorites(), 'change_email_form' => $change_email_form->createView(), 'avatar_form' => $this->getAvatarForm()->createView() ) ); } /** * Procédure de confirmation de la nouvelle adresse email. */ public function changeEmailConfirmAction($token) { $em = $this->getDoctrine()->getEntityManager(); $um = $this->get('muzich_user_manager'); $user = $this->getUser(); /** * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine. * Docrine le voit si on faire une requete directe. */ if ($this->container->getParameter('env') == 'test') { $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById( $this->container->get('security.context')->getToken()->getUser()->getId(), array() )->getSingleResult(); } $token_ = hash('sha256', $user->getConfirmationToken().($email = $user->getEmailRequested())); // Le token est-il valide if ($token_ != $token) { $this->setFlash('error', 'user.changeemail.token_invalid'); return new RedirectResponse($this->generateUrl('my_account')); } $user->setEmail($email); $user->setEmailRequested(null); $um->updateCanonicalFields($user); $em->flush(); $this->setFlash('success', 'user.changeemail.success'); return new RedirectResponse($this->generateUrl('my_account')); } /** * * @param string $town * @param string $country * @param string $token * @return Response */ public function updateAddressAction($token) { if (($response = $this->mustBeConnected(true))) { return $response; } /** * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine. * Docrine le voit si on faire une requete directe. */ $user = $this->getUser(); if ($this->container->getParameter('env') == 'test') { $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById( $this->container->get('security.context')->getToken()->getUser()->getId(), array() )->getSingleResult(); } $errors = array(); if ($user->getPersonalHash() != $token) { $errors[] = 'NotAllowed'; } if (!trim($this->getRequest()->request->get('town'))) { $errors[] = $this->trans('my_account.address.form.errors.notown', array(), 'userui'); } if (!trim($this->getRequest()->request->get('country'))) { $errors[] = $this->trans('my_account.address.form.errors.nocountry', array(), 'userui'); } if (count($errors)) { return $this->jsonResponse(array( 'status' => 'error', 'errors' => $errors )); } $user->setTown(trim($this->getRequest()->request->get('town'))); $user->setCountry(trim($this->getRequest()->request->get('country'))); $this->getDoctrine()->getEntityManager()->persist($user); $this->getDoctrine()->getEntityManager()->flush(); return $this->jsonResponse(array( 'status' => 'success' )); } public function updateAvatarAction(Request $request) { $form = $this->getAvatarForm(); $form->bind($request); if ($form->isValid()) { $em = $this->getEntityManager(); $form->getData()->preUploadAvatar(); $form->getData()->uploadAvatar(); $em->persist($form->getData()); $em->flush(); $this->setFlash('success', $this->trans('my_account.avatar.success', array(), 'userui')); return $this->redirect($this->generateUrl('my_account')); } $this->setFlash('error', $this->trans('my_account.avatar.error', array(), 'userui')); return $this->redirect($this->generateUrl('my_account')); } public function updatePreferencesAction(Request $request) { $form = $this->getPreferencesForm(); $form->bind($request); if ($form->isValid()) { $em = $this->getEntityManager(); $em->persist($form->getData()); $em->flush(); $this->setFlash('success', $this->trans('my_account.preferences.success', array(), 'userui')); return $this->redirect($this->generateUrl('my_account')); } $this->setFlash('error', $this->trans('my_account.preferences.error', array(), 'userui')); return $this->redirect($this->generateUrl('my_account')); } }