Reputation: 2800
In Easy Admin, I already have a list/edit form of users. I want to add an extra form to change password of any member user. (password, repeat password, submit)
In the documentation custom forms are told to be entity specific. For example, to create a custom product form, you create a custom controller:
easy_admin:
entities:
# ...
Product:
controller: AppBundle\Controller\ProductController
# ...
But this solution doesn't fit to my problem. I already set a user form and use that form.
I can set an event listener and manage saving the password but I'm stuck with adding this simple form.
Upvotes: 0
Views: 1592
Reputation: 607
Firstly, you need a controller to handle requests associated with your users (create one if you don't have it already)
/**
* @Route("/user/change-password", name="change_password")
*/
public function changePassword(Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
$changePasswordModel = new ChangePassword();
$form = $this->createForm(ChangePasswordType::class, $changePasswordModel);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$user = $entityManager->find(User::class, $this->getUser()->getId());
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$form->get('newPassword')->getData()
)
);
$entityManager->persist($user);
$entityManager->flush();
return $this->redirect('/?entity=User&action=show&id='. $this->getUser()->getId());
}
return $this->render('admin/theme/changePassword/change_password.html.twig', array(
'changePasswordForm' => $form->createView(),
));
}
Then I created a form type that looks like this:
class ChangePasswordType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('oldPassword', PasswordType::class, [
'required' => true,
'label' => 'Type your current password',
])
->add('newPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Passwords do not match.',
'first_options' => ['label' => 'Type your new password'],
'second_options' => ['label' => 'Retype your new password']
]);
}
public function setDefaultOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => ChangePassword::class,
));
}
public function getName()
{
return 'change_passwd';
}
}
I created a form model with custom validation, you can edit this however you like
class ChangePassword
{
/**
* @SecurityAssert\UserPassword(
* message = "Wrong value for your current password!"
* )
*/
public $oldPassword;
/**
* @Assert\Length(
* min = 6,
* minMessage = "Password must be at least 6 characters long!"
* )
*/
public $newPassword;
}
Lastly, extend your base twig with someting like this
{% extends 'base.html.twig' %}
{% block title %}Change password
{% endblock %}
{% block stylesheets %}
{{ parent() }}
{{ encore_entry_link_tags('change-password') }}
{% endblock %}
{% block body %}
{{ parent() }}
<body id="{% block body_id %}{% endblock %}">
<div class="container-fluid h-100">
<div class="row justify-content-center align-items-center h-100">
<div class="col col-sm-8 col-md-8 col-lg-6 col-xl-4">
{{ form_start(changePasswordForm, {'attr':{'class':'form-signin'}}) }}
{{ form_row(changePasswordForm.oldPassword, {'attr': {'class':'form-control mb-2'} }) }}
{{ form_row(changePasswordForm.newPassword.first, {'attr': {'class':'form-control mb-2'} }) }}
{{ form_row(changePasswordForm.newPassword.second, {'attr': {'class':'form-control mb-2'} }) }}
<button class="btn btn-dark btn-lg btn-block mt-3" type="submit">Change password</button>
{{ form_end(changePasswordForm) }}
</div>
</div>
</div>
</body>
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('change-password') }}
{% endblock %}
I created a button on my show user action that takes you to /user/change-password and that is pretty much it.
Upvotes: 3