I'm using Symfony 5.4 to learn how to use this framework, now I'm working on the admin panel (EasyAdmin) and I got stuck on the change password functionality.
I have this in my DashboardController:
#[Route('/panel/settings', name: 'settings')]
public function settings(UserPasswordEncoderInterface $passwordEncoder): Response
{
return $this->render('admin/settings.html.twig');
}
I have tried using the documentation here: https://symfony.com/doc/5.4/forms.html#creating-forms-in-controllers to add the code to the function above, but it is about making a new entry in the current entity.
I just want to add a change password field to my settings page in EasyAdmin. How I can achieve that?
EDIT
DashboardController.php after modifications:
#[Route('/panel/settings', name: 'settings')]
public function settings(): Response
{
$user = $this->security->getUser();
$changePasswordForm = $this->createForm(UserFormType::class, $user);
$changePasswordForm->handleRequest($adminContext->getRequest());
if ($changePasswordForm->isSubmitted() && $changePasswordForm->isValid()) {
$user->setPassword(HASHED_PASSWORD_HERE);
$this->manager->persist($user);
$this->manager->flush();
}
return $this->render('admin/settings.html.twig', [
'change_password_form' => $changePasswordForm->createView(),
]);
}
EDIT 2 If someone was struggling to find information, below I'm pasting working code:
This goes into the controller (for example DashboardController.php)
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use App\Form\Type\UserFormType;
#[Route('/panel/settings', name: 'settings')]
public function settings(Request $req, UserPasswordEncoderInterface $passwordEncoder): Response
{
$user = $this->security->getUser();
$changePasswordForm = $this->createForm(UserFormType::class, $user);
$changePasswordForm->handleRequest($req);
if ($changePasswordForm->isSubmitted() && $changePasswordForm->isValid()) {
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$changePasswordForm->get('plainPassword')->getData()
)
);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
}
return $this->render('admin/settings.html.twig', [
'change_password_form' => $changePasswordForm->createView(),
]);
}
CodePudding user response:
You haven't put many details but I guess this could help:
- You have to add the
configureCrudmethod to your crud controller like this (so that you can add another action there):
public function configureActions(Actions $actions): Actions
{
$changePassword = Action::new('changePassword', 'Change Password', 'fas fa-key')->setCssClass('btn btn-label')->linkToCrudAction('changePassword');
return $actions->add(Action::EDIT, $changePassword);
}
- And then below you should create the
changePasswordcrud action/method, (I am taking for granted you know how to create a symfony form):
public function changePassword(AdminContext $adminContext): Response
{
$user = $adminContext->getEntity()->getInstance();
$changePasswordForm = $this->createForm(UserFormType::class, $user);
$changePasswordForm->handleRequest($adminContext->getRequest());
if ($changePasswordForm->isSubmitted() && $changePasswordForm->isValid()) {
$user->setPassword(HASHED_PASSWORD_HERE);
$this->manager->persist($user);
$this->manager->flush();
}
}
return $this->render('security/change-password.html.twig', [
'change_password_form' => $changePasswordForm->createView(),
]);
}
- I am putting the UserForm here also for the password change :):
<?php
declare(strict_types=1);
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\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class UserFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'The password fields must match.',
'options' => ['attr' => ['class' => 'password-field']],
'required' => true,
'first_options' => ['label' => 'New Password'],
'second_options' => ['label' => 'Repeat Password'],
'attr' => ['autocomplete' => 'off'],
])
->add('submit', SubmitType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}
