I'm creating an app and I want to enable users to change their data and password. I've created an email changing form and it works, but I've got a problem with password. I've got a page localhost:8000/user/{id} and here the buttons: edit email and edit password. Edit email is working and when I click on editing password - I got a blank page on localhost:8000/user/{id}/change_password (enter image description here enter image description here). Th PassType doesn't show there.
There are no syntax error on localhost:8000/user/{id} and localhost:8000/user/{id}/change_password.
I've added a function edit_pass to UserController, crated PassType (where is the form to change password) and make a template edit_password.html.twig.
I don't know where is the problem. I did the same thing as with other Forms which work. I've tried to clear the edit_password template (I've just left the base_html there and put some text) cause I've thought there is a problem in it, but it was still a blank page on localhost:8000/user/{id}/change_password.
PassType:
<?php
/*
* Password type.
*/
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Class PassType.
*/
class PassType extends AbstractType
{
/**
* Builds the form.
*
* This method is called for each type in the hierarchy starting from the
* top most type. Type extensions can further modify the form.
*
* @see FormTypeExtensionInterface::buildForm()
*
* @param FormBuilderInterface $builder The form builder
* @param array $options The options
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add(
'password',
RepeatedType::class,
[
'type' => PassType::class,
'required' => true,
'attr' => ['max_length' => 40],
'first_options' => ['label' => 'label.password'],
'second_options' => ['label' => 'label.repeat_password'],
]
);
}
/**
* Configures the options for this type.
*
* @param OptionsResolver $resolver The resolver for the options
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(['data_class' => User::class]);
}
/**
* Returns the prefix of the template block name for this type.
*
* The block prefix defaults to the underscored short class name with
* the "Type" suffix removed (e.g. "UserProfileType" => "user_profile").
*
* @return string The prefix of the template block name
*/
public function getBlockPrefix(): string
{
return 'user';
}
}
edit_password.html.twig
{% extends 'base.html.twig' %}
{% block title %}
{{ 'title_password_edit'|trans({'%id%': user.id|default('')}) }}
{% endblock %}
{% block body %}
<h1 class="display-4 d-flex justify-content-center">{{ 'title_password_edit'|trans({'%id%': user.id|default('')}) }}</h1>
{{ form_start(form, { method: 'PUT', action: url('password_edit', {id: user.id}) }) }}
{{ form_widget(form) }}
<div class="form-group row float-sm-right">
<input type="submit" value="{{ 'action_save'|trans }}" class="btn btn-primary" />
</div>
<div class="form-group row float-sm-left">
<a href="{{ url('user_index') }}" class="btn btn-link">
{{ 'action_back_to_list'|trans }}
</a>
</div>
{{ form_end(form) }}
{% endblock %}
and part of UserController whith edit_pass function
/**
* Edit Password.
*
* @param \Symfony\Component\HttpFoundation\Request $request HTTP request
* @param \App\Entity\User $user User entity
* @param \App\Repository\UserRepository $repository User repository
*
* @return \Symfony\Component\HttpFoundation\Response HTTP response
*
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*
* @Route(
* "/{id}/change_password",
* methods={"GET", "PUT"},
* requirements={"id": "[1-9]\d*"},
* name="password_edit",
* )
*/
public function edit_pass(Request $request, User $user, UserPasswordEncoderInterface $passwordEncoder, UserRepository $repository): Response
{
$form = $this->createForm(PassType::class, $user, ['method' => 'PUT']);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$form->get('password')->getData()
)
);
$repository->save($user);
$this->addFlash('success', 'message.updated_successfully');
return $this->redirectToRoute('user_show', array('id' => $this->getUser()->getId()));
}
return $this->render(
'user/edit_password.html.twig',
[
'form' => $form->createView(),
'user' => $user,
]
);
}
I'm also adding the user/show.html.twig
{% extends 'base.html.twig' %}
{% block title %}
{{ 'label_detail_users'|trans({'%id%': user.id|default('')}) }}
{% endblock %}
{% block body %}
<h1 class="display-4 d-flex justify-content-center">{{ 'label_detail_users'|trans({'%id%': user.id|default('')}) }}</h1>
{% if users is defined and users|length %}
<table class="table table-striped">
<thead>
<tr>
<th>{{ 'label_user_id'|trans }}</th>
<th>{{ 'label_email'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ users.id }}</td>
<td>{{ users.email }}</td>
</tr>
</tbody>
</table>
<p>
<a class="btn btn-info" href="{{ url('user_edit', {id: users.id}) }}" title="{{ 'edit_email'|trans }}">
{{ 'edit_email'|trans }}
</a>
</p>
<p>
<a class="btn btn-info" href="{{ url('password_edit', {id: users.id}) }}" title="{{ 'edit_password'|trans }}">
{{ 'edit_password'|trans }}
</a>
</p>
<p>
<a class="btn btn-info" href="{{ url('user_index') }}" title="{{ 'action_back_to_list'|trans }}">
{{ 'action_back_to_list'|trans }}
</a>
</p>
{% else %}
<p>
{{ 'message_item_not_found'|trans }}
</p>
{% endif %}
{% endblock %}
CodePudding user response:
You produced an endless loop - its PasswordType
in your RepeatedType
. PassType
is the name of your whole Form - you see the problem?
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add(
'password',
RepeatedType::class,
[
'type' => PasswordType::class,
'required' => true,
'attr' => ['max_length' => 40],
'first_options' => ['label' => 'label.password'],
'second_options' => ['label' => 'label.repeat_password'],
]
);
}
And may I ask why you limit the length of a password?