0
votes

i try to follow this forum to give email confermation to profile edit fos user bundle . i create file

/src/AppBundle/EventListener.php

namespace AppBundle\EventListener;

use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Mailer\MailerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class ChangeProfileListener implements EventSubscriberInterface
{
    private $mailer;
    private $tokenGenerator;
    private $router;
    private $session;
    private $tokenStorage;

    public function __construct(
        MailerInterface $mailer,
        TokenGeneratorInterface $tokenGenerator,
        UrlGeneratorInterface $router,
        SessionInterface $session, TokenStorageInterface $tokenStorage
    ) {
        $this->mailer = $mailer;
        $this->tokenGenerator = $tokenGenerator;
        $this->router = $router;
        $this->session = $session;
        $this->tokenStorage = $tokenStorage;
    }

    public static function getSubscribedEvents()
    {
        return array(
            FOSUserEvents::PROFILE_EDIT_INITIALIZE => 'onProfileEditInitialize',
            FOSUserEvents::PROFILE_EDIT_SUCCESS => 'onProfileEditSuccess',
        );
    }

    public function onProfileEditInitialize(GetResponseUserEvent $event)
    {
        // required, because when Success's event is called, session already contains new email
        $this->email = $event->getUser()->getEmail();
    }

    public function onProfileEditSuccess(FormEvent $event)
    {
        $user = $event->getForm()->getData();
        if ($user->getEmail() !== $this->email)
        {
            // disable user
            $user->setEnabled(false);

            // send confirmation token to new email
            $user->setConfirmationToken($this->tokenGenerator->generateToken());
            $this->mailer->sendConfirmationEmailMessage($user);

            // force user to log-out
            $this->tokenStorage->setToken();

            // redirect user to check email page
            $this->session->set('fos_user_send_confirmation_email/email', $user->getEmail());
            $url = $this->router->generate('fos_user_registration_check_email');
            $event->setResponse(new RedirectResponse($url));
        }
    }
}

After in service.yml

parameters:
    #parameter_name: value
    oc_user.email_change.listener.class: AppBundle\EventListener\ChangeProfileListener

services:
    app.form.registration:
        class: AppBundle\Form\RegistrationType
        tags:
            - { name: form.type, alias: app_user_registration }
    app.form.profileedit:
        class: AppBundle\Form\ProfileType
        tags:
            - { name: form.type, alias: app_profile_edit }
...

    oc_user.email_change.listener:
        class: %oc_user.email_change.listener.class%
        arguments: ['@fos_user.mailer', '@fos_user.util.token_generator', '@router', '@session', '@security.token_storage']
        tags:
          - { name: kernel.event_subscriber }

but i have always this error

(1/1) AutowiringFailedException Cannot autowire service "AppBundle\EventListener\ChangeProfileListener": argument "$mailer" of method "__construct()" references interface "FOS\UserBundle\Mailer\MailerInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "fos_user.mailer.default", "fos_user.mailer.twig_swift", "fos_user.mailer.noop".

i have also override the form but it work

Can help me??

my config file

# app/config/config.yml
fos_user:
    db_driver: orm # other valid values are 'mongodb' and 'couchdb'
    firewall_name: main
    user_class: AppBundle\Entity\User
    from_email:
        address: "%mailer_user%"
        sender_name: "%mailer_user%"
    registration:
        form:

            type: AppBundle\Form\RegistrationType
            # if you are using Symfony < 2.8 you should use the type name instead
            # type: app_user_registration
        confirmation:
            enabled: true
    profile:
        form:
            type: AppBundle\Form\ProfileType
fos_user.mailer:
   alias: 'fos_user.mailer.default'
1

1 Answers

1
votes

The error message laready says it:

You should maybe alias this interface to one of these existing services: "fos_user.mailer.default", "fos_user.mailer.twig_swift", "fos_user.mailer.noop".

The error occurs in your configuration (service marked with --> <--):

oc_user.email_change.listener:
    class: %oc_user.email_change.listener.class%
    arguments: [--> '@fos_user.mailer', <-- '@fos_user.util.token_generator', '@router', '@session', '@security.token_storage']
    tags:
      - { name: kernel.event_subscriber }

You probably have to enable the notification feature in FOS UserBundle:

# app/config/config.yml
fos_user:
    # ...
    registration:
        confirmation:
            enabled: true

as is described in the docs: https://symfony.com/doc/current/bundles/FOSUserBundle/emails.html#registration-confirmation

If that doesn't help you might want to either reference one of the mentioned services in the error message or create an alias the points to one of them, e.g. fos_user.mailer.default:

fos_user.mailer:
    alias: 'fos_user.mailer.default'

Then you can keep your service as is and whenever you refer to fos_user.mail it will use the service referenced in the alias.