Muy buenas,
tengo hecho un sistema de login, registro y recuperación de contraseña con FOSUserBundle y SonataUserBundle en Ajax.
Es un código que ya había usado en otro proyecto sin problemas pero ahora me surge uno y es que al lanzar el formulario de recuperación de contraseña, éste que es enviado por AJAX me está devolviendo una vista y no una respuesta en Json que es lo que en el controlador extendido de ApplicacitionSonataUserBundle tengo puesto.
Os dejo el controlador por si veis algun fallo:
Código PHP:
<?php
namespace Application/Sonata/UserBundle/Controller;
use Symfony/Component/DependencyInjection/ContainerAware;
use Symfony/Component/HttpFoundation/JsonResponse;
use Symfony/Component/HttpFoundation/Response;
use Symfony/Component/HttpFoundation/RedirectResponse;
use Symfony/Component/HttpFoundation/Request;
use Symfony/Component/HttpKernel/Exception/NotFoundHttpException;
use Symfony/Component/Security/Core/Exception/AccountStatusException;
use FOS/UserBundle/Model/UserInterface;
class ResettingController extends ContainerAware
{
const SESSION_EMAIL = 'fos_user_send_resetting_email/email';
/**
* Request reset user password: show form
*/
public function requestAction()
{
return $this->container->get('templating')->renderResponse('FOSUserBundle:Resetting:request.html.'.$this->getEngine());
}
/**
* Request reset user password: submit form and send email
*/
public function sendEmailAction(Request $request)
{
$username = $request->get('username');
/** @var $user UserInterface */
$user = $this->container->get('fos_user.user_manager')->findUserByUsernameOrEmail($username);
if (null === $user) {
if ($request->isXmlHttpRequest()) {
$result = array(
'success' => false,
'message' => $this->container->get('translator')->trans('resetting.request.invalid_username', array('%username%' => $username), 'FOSUserBundle')
);
return new JsonResponse($result);
} else {
return $this->container->get('templating')->renderResponse('FOSUserBundle:Resetting:request.html.'.$this->getEngine(), array('invalid_username' => $username));
}
}
if ($user->isPasswordRequestNonExpired($this->container->getParameter('fos_user.resetting.token_ttl'))) {
if ($request->isXmlHttpRequest()) {
$result = array(
'success' => false,
'message' => $this->container->get('translator')->trans('resetting.password_already_requested', array(), 'FOSUserBundle')
);
return new JsonResponse($result);
} else {
return $this->container->get('templating')->renderResponse('FOSUserBundle:Resetting:passwordAlreadyRequested.html.'.$this->getEngine());
}
}
if (null === $user->getConfirmationToken()) {
/** @var $tokenGenerator \FOS\UserBundle\Util\TokenGeneratorInterface */
$tokenGenerator = $this->container->get('fos_user.util.token_generator');
$user->setConfirmationToken($tokenGenerator->generateToken());
}
$this->container->get('session')->set(static::SESSION_EMAIL, $this->getObfuscatedEmail($user));
$this->container->get('fos_user.mailer')->sendResettingEmailMessage($user);
$user->setPasswordRequestedAt(new DateTime());
$this->container->get('fos_user.user_manager')->updateUser($user);
if ($request->isXmlHttpRequest()) {
$result = array(
'success' => true,
'message' => $this->container->get('templating')->render('FOSUserBundle:Resetting:checkEmail.html.'.$this->getEngine(), array(
'email' => $user->getEmail(),
))
);
return new JsonResponse($result);
} else {
return new RedirectResponse($this->container->get('router')->generate('fos_user_resetting_check_email'));
}
}
/**
* Tell the user to check his email provider
*/
public function checkEmailAction()
{
$session = $this->container->get('session');
$email = $session->get(static::SESSION_EMAIL);
$session->remove(static::SESSION_EMAIL);
if (empty($email)) {
// the user does not come from the sendEmail action
return new RedirectResponse($this->container->get('router')->generate('fos_user_resetting_request'));
}
return $this->container->get('templating')->renderResponse('FOSUserBundle:Resetting:checkEmail.html.'.$this->getEngine(), array(
'email' => $email,
));
}
/**
* Reset user password
*/
public function resetAction($token, Request $request)
{
$user = $this->container->get('fos_user.user_manager')->findUserByConfirmationToken($token);
if (null === $user) {
throw new NotFoundHttpException(sprintf('The user with "confirmation token" does not exist for value "%s"', $token));
}
if (!$user->isPasswordRequestNonExpired($this->container->getParameter('fos_user.resetting.token_ttl'))) {
return new RedirectResponse($this->container->get('router')->generate('fos_user_resetting_request'));
}
$form = $this->container->get('fos_user.resetting.form');
$formHandler = $this->container->get('fos_user.resetting.form.handler');
$process = $formHandler->process($user);
if ($process) {
$this->setFlash('fos_user_success', 'resetting.flash.success');
$url = $this->getRedirectionUrl($user);
$response = new RedirectResponse($url);
$this->authenticateUser($user, $response);
if ($request->isXmlHttpRequest()) {
$result = array(
'success' => true,
'url' => $url
);
return new JsonResponse($result);
} else {
return $response;
}
}
if ($request->isXmlHttpRequest()) {
$errors = $this->container->get('form_serializer')->serializeFormErrors($form, true, true);
$result = array(
'success' => false,
'message' => $errors
);
return new JsonResponse($result);
} else {
return $this->container->get('templating')->renderResponse('FOSUserBundle:Resetting:reset.html.'.$this->getEngine(), array(
'token' => $token,
'form' => $form->createView(),
));
}
}
/**
* Authenticate a user with Symfony Security
*
* @param \FOS\UserBundle\Model\UserInterface $user
* @param \Symfony\Component\HttpFoundation\Response $response
*/
protected function authenticateUser(UserInterface $user, Response $response)
{
try {
$this->container->get('fos_user.security.login_manager')->loginUser(
$this->container->getParameter('fos_user.firewall_name'),
$user,
$response);
} catch (AccountStatusException $ex) {
// We simply do not authenticate users which do not pass the user
// checker (not enabled, expired, etc.).
}
}
/**
* Generate the redirection url when the resetting is completed.
*
* @param \FOS\UserBundle\Model\UserInterface $user
*
* @return string
*/
protected function getRedirectionUrl(UserInterface $user)
{
return $this->container->get('router')->generate('fos_user_profile_show');
}
/**
* Get the truncated email displayed when requesting the resetting.
*
* The default implementation only keeps the part following @ in the address.
*
* @param \FOS\UserBundle\Model\UserInterface $user
*
* @return string
*/
protected function getObfuscatedEmail(UserInterface $user)
{
$email = $user->getEmail();
if (false !== $pos = strpos($email, '@')) {
$email = '...' . substr($email, $pos);
}
return $email;
}
/**
* @param string $action
* @param string $value
*/
protected function setFlash($action, $value)
{
$this->container->get('session')->getFlashBag()->set($action, $value);
}
protected function getEngine()
{
return $this->container->getParameter('fos_user.template.engine');
}
}
El caso es que creo que Symfony está ignorando por completo este controlador y coge de manera directa el de SonataUser en lugar del de ApplicationSonataUser.
He revisado la documentacion de
SonataUser y no hay ningún parametro que especifique esto, por lo que no entiendo como el propio sistema de dependencias de Symfony me ignora esto.