A edição incorreta do usuário com erro altera temporariamente o app.user.username, como resolvê-lo?
Usamos a estrutura Symfony2 e o FOSUserBundle para nossos usuários. Portanto, temos nosso próprio UserBundle que herda de FOSUserBundle. O problema é: quando enviamos o formulário para editar um usuário com uma senha incorreta, o app.user.username exibido no cabeçalho muda quando não deveria, pois o formulário não está correto. Então, quando recarregamos a página, o app.user.username possui o nome de usuário normal (já que não foi alterado no banco de dados). A questão é: por que o app.user.username muda temporariamente para o valor do formulário (editar usuário) que acabamos de enviar com uma senha errada?
usamos o roteamento normal do FOSUser:
fos_user_security:
resource: "@FOSUserBundle/Resources/config/routing/security.xml"
fos_user_profile:
resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
prefix: /profile
fos_user_register:
resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
prefix: /register
fos_user_resetting:
resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
prefix: /resetting
fos_user_change_password:
resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
prefix: /profile
E o controlador padrão do FOSUser:
public function editAction(Request $request)
{
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
/** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->get('event_dispatcher');
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
/** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('fos_user.profile.form.factory');
$form = $formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isValid()) {
/** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_SUCCESS, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_profile_show');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
return $this->render('FOSUserBundle:Profile:edit.html.twig', array(
'form' => $form->createView()
));
}
Aqui está a parte do código que é exibida no cabeçalho que NÃO deve ser alterada ao enviar o formulário com uma senha incorreta. (app.user.username)
<ul class="nav navbar-nav navbar-right">
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
<li>
<a href="{{ path('fos_user_profile_show') }}">{{ app.user.username }}
</a>
</li>
<li>
<a href="{{ path('fos_user_security_logout') }}">
{{ 'layout.logout'|trans({}, 'FOSUserBundle') }}
</a>
</li>
{% else %}
<li>
<a href="{{ path('fos_user_registration_register') }}">{{ 'layout.register'|trans({}, 'FOSUserBundle') }}</a>
</li>
<li>
<a href="{{ path('fos_user_security_login') }}">{{ 'layout.login'|trans({}, 'FOSUserBundle') }}</a>
</li>
{% endif %}
</ul>
E aqui está o código da fórmula que é exibida:
<div class="well">
{{ form_start(form, {'attr': {'class': 'form-horizontal'}}) }}
{{ form_errors(form) }}
<div class="form-group">
{# Génération du label username. #}
{{ form_label(form.username, 'register.form.username'|trans, {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
{# Affichage des erreurs pour ce champ précis. #}
{{ form_errors(form.username) }}
<div class="col-sm-4">
{{ form_widget(form.username, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
<div class="form-group">
{# Génération du label adresse. #}
{{ form_label(form.address, 'register.form.address'|trans, {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
{# Affichage des erreurs pour ce champ précis. #}
{{ form_errors(form.address) }}
<div class="col-sm-4">
{{ form_widget(form.address, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
<div class="form-group">
{# Génération du label nom du contact. #}
{{ form_label(form.contactName, 'register.form.contact_name'|trans, {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
{# Affichage des erreurs pour ce champ précis. #}
{{ form_errors(form.contactName) }}
<div class="col-sm-4">
{{ form_widget(form.contactName, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
<div class="form-group">
{# Génération du label email. #}
{{ form_label(form.email, 'register.form.email'|trans, {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
{# Affichage des erreurs pour ce champ précis. #}
{{ form_errors(form.email) }}
<div class="col-sm-4">
{{ form_widget(form.email, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
<div class="form-group">
{# Génération du label numéro de téléphone. #}
{{ form_label(form.phone, 'register.form.phone'|trans, {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
{# Affichage des erreurs pour ce champ précis. #}
{{ form_errors(form.phone) }}
<div class="col-sm-4">
{{ form_widget(form.phone, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
<div class="form-group">
{# Génération du label mot de passe. #}
{{ form_label(form.current_password, 'register.form.password'|trans, {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
{# Affichage des erreurs pour ce champ précis. #}
{{ form_errors(form.current_password) }}
<div class="col-sm-4">
{{ form_widget(form.current_password, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
{# Pour le bouton, pas de label ni d'erreur, on affiche juste le widget #}
{{ form_widget(form.saveButton, {'attr': {'class': 'btn btn-primary'}, 'label': 'profile.edit.submit'|trans }) }}
{# Génération automatique des champs pas encore écrits.
Dans cet exemple, ce serait le champ CSRF (géré automatiquement par Symfony !)
et tous les champs cachés (type « hidden »). #}
{{ form_rest(form) }}
{# Fermeture de la balise <form> du formulaire HTML #}
{{ form_end(form) }}
</div>
E aqui está o FormType que usamos para este formulário específico:
public function buildForm(FormBuilderInterface $builder, array $options)
{
// add your custom field
$builder->add('contactName', 'text')
->add('phone', 'text')
->add('address', 'text')
->add('saveButton', 'submit');
}
O FormType herda de ProfileFormType (padrão em FOSUserBundle) graças a uma função getParent ().
Obrigado por sua ajuda para descobrir o que está errado. Não entendemos por que o app.user.username é alterado no cabeçalho, pois o formulário é enviado com uma senha incorreta e os dados no banco de dados não são alterados, e desculpe pelos comentários em francês no código :).