mgluesenkamp
mgluesenkamp

Reputation: 529

Manually send password resetting email for user in FOSUserBundle

I have to create a simple user administration for a symfony 3 project.

One part of it is to start the password reset process for users. (Yes, I know every user can trigger it himself but this is a request from our customer.)

Now I don't know how to start the process with a simple click in the admin interface for every user. Is there a method or a service in the UserBundle I can use?

Upvotes: 2

Views: 3034

Answers (3)

sneaky
sneaky

Reputation: 447

From the information Kamil provided, this would be a full working function

        /**
         * Sends the user a new password
         *
         * @Route("reset_password/{id}", name="user_reset_password")
         * @Security("has_role('ROLE_ADMIN')")
         *
         * @param User $user
         * @return \Symfony\Component\HttpFoundation\RedirectResponse
         */
        public function resetPasswordAction(User $user)
        {
    
            if (null === $user->getConfirmationToken()) {
                /** @var $tokenGenerator TokenGeneratorInterface */
                $tokenGenerator = $this->get('fos_user.util.token_generator');
                $user->setConfirmationToken($tokenGenerator->generateToken());
            }
    
            $this->get('fos_user.mailer')->sendResettingEmailMessage($user);
            $user->setPasswordRequestedAt(new \DateTime());
            $this->get('fos_user.user_manager')->updateUser($user);
    
            $this->addFlash('notice', "User {$user->getFullName()} got an email for resetting his password!");
            return $this->redirectToRoute('user_index');
    
        }

Upvotes: 1

Bananaapple
Bananaapple

Reputation: 3114

Here's a service based solution written with Symfony 4.1 you can use without having to call in services form the container via get()

First you have to add an alias to services.yaml because the FOS mailer can't auto-wire:

FOS\UserBundle\Mailer\Mailer:
    alias: fos_user.mailer.default
    public: true

With that in place you can create the below class as service:

namespace App\Service; # change to your namespace

use FOS\UserBundle\Mailer\Mailer;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;

/**
 * Class UserPasswordResetService
 */
class UserPasswordResetService
{
    /**
     * @var Mailer
     */
    private $mailer;

    /**
     * @var UserManagerInterface
     */
    private $userManager;

    /**
     * @var TokenGeneratorInterface
     */
    private $tokenGenerator;

    /**
     * UserPasswordResetService constructor.
     *
     * @param Mailer               $mailer
     * @param UserManagerInterface $userManager
     */
    public function __construct(
        Mailer $mailer,
        UserManagerInterface $userManager,
        TokenGeneratorInterface $tokenGenerator
    )
    {
        $this->mailer         = $mailer;
        $this->userManager    = $userManager;
        $this->tokenGenerator = $tokenGenerator;
    }

    /**
     * @param UserInterface $user
     */
    public function resetPassword(UserInterface $user)
    {
        if (null === $user->getConfirmationToken()) {
            $user->setConfirmationToken($this->tokenGenerator->generateToken());
        }

        // send email you requested
        $this->mailer->sendResettingEmailMessage($user);

        // this depends on requirements
        $user->setPasswordRequestedAt(new \DateTime());
        $this->userManager->updateUser($user);
    }

}

Assuming you then add that service to a class via DI you can use it like this within a given method:

$this->passwordResetService->resetPassword($user);

Upvotes: 2

Kamil Adryjanek
Kamil Adryjanek

Reputation: 3338

There is no all in one method but this can be achieved by:

if (null === $user->getConfirmationToken()) {
    $user->setConfirmationToken($this->tokenGenerator->generateToken());
}

// send email you requested
$this->mailer->sendResettingEmailMessage($user);
// this depends on requirements
$user->setPasswordRequestedAt(new \DateTime());
$this->userManager->updateUser($user);

with proper dependencies set.

Upvotes: 4

Related Questions