Chapters
This course is archived!
-
Course Code
Compatible PHP versions: >=5.5.9
Compatible PHP versions: >=5.5.9
- This Video
- Subtitles
- Course Script
Customize everything with Events
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
We can override templates. We can override translations. We can override forms. But there's more than that. For example, after we finish registration, we're redirected to this registration confirmation page. You know what? I'd rather do something else: I'd rather redirect to the homepage and skip this page entirely. How can we do that?
Well, let's do a little bit of digging. If you hover over the route name in the web debug toolbar, you can see that this is page rendered by RegistrationController
. Back in my editor I'll press Shift+Shift and look for RegistrationController
in the bundle. Specifically, registerAction()
is responsible for both rendering the registration page and processing the form submit.
And check this out: after the form is valid, it redirects to the confirmation page.
Events to the Rescue!
So at first, it seems like we need to override the controller itself. But not so fast! The controller - in fact every controller in FOSUserBundle is littered with events: REGISTRATION_INITIALIZE
, REGISTRATION_SUCCESS
, REGISTRATION_COMPLETED
and REGISTRATION_FAILURE
. Each of these represents a hook point where we can add custom logic.
In this case, if you look closely, you can see that after it dispatches an event called REGISTRATION_SUCCESS
, below, it checks to see if the $event
has a response set on it. If it does not, it redirects to the confirmation page. But if it does, it uses that response.
That's the key! If we can add a listener to REGISTRATION_SUCCESS
, we can create our own RedirectResponse
and set that on the event so that this controller uses it. Let's go!
Creating the Event Subscriber
Inside of AppBundle, create a new directory called EventListener
. And in there, a new PHP class: how about RedirectAfterRegistrationSubscriber
. Make this implement EventSubscriberInterface
: the interface that all event subscribers must have. I'll use our favorite Code->Generate menu, or Command+N on a Mac, go to "Implement Methods" and select getSubscribedEvents
.
Show Lines
|
// ... lines 1 - 2 |
namespace AppBundle\EventListener; | |
Show Lines
|
// ... lines 4 - 6 |
class RedirectAfterRegistrationSubscriber implements EventSubscriberInterface | |
{ | |
public static function getSubscribedEvents() | |
{ | |
} | |
} |
We want to attach a listener to FOSUserEvents::REGISTRATION_SUCCESS
, which, by the way, is just a constant that equals some string event name.
In getSubscribedEvents()
, add FOSUserEvents::REGISTRATION_SUCCESS
assigned to onRegistrationSuccess
. This means that when the REGISTRATION_SUCCESS
event is fired, the onRegistrationSuccess
method should be called. Create that above: public function onRegistrationSuccess()
.
<?php | |
Show Lines
|
// ... lines 2 - 8 |
class RedirectAfterRegistrationSubscriber implements EventSubscriberInterface | |
{ | |
public function onRegistrationSuccess(FormEvent $event) | |
{ | |
} | |
public static function getSubscribedEvents() | |
{ | |
return [ | |
FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess' | |
]; | |
} | |
} |
Oh, and notice that when this event is dispatched, the bundle passes a FormEvent
object. That will be the first argument to our listener method: FormEvent $event
. That's what we need to set the response onto.
Investigating all the Events
Before we go any further, I'll hold command and click into the FOSUserEvents
class... cause it's awesome! It holds a list of every event dispatched by FOSUserBundle, what its purpose is, and what event object you will receive. This is gold.
Creating the RedirectResponse
Back in onRegistrationSuccess
, we need to create a RedirectResponse
and set it on the event. But to redirect to the homepage, we'll need the router. At the top of the class, create public function __construct()
with a RouterInterface $router
argument. Next, I'll hit Option+Enter, select "Initialize Fields" and choose router
.
<?php | |
Show Lines
|
// ... lines 2 - 10 |
class RedirectAfterRegistrationSubscriber implements EventSubscriberInterface | |
{ | |
private $router; | |
public function __construct(RouterInterface $router) | |
{ | |
$this->router = $router; | |
} | |
Show Lines
|
// ... lines 19 - 32 |
} |
That was just a shortcut to create the private $router
property and set it in the constructor: nothing fancy.
Now, in onRegistrationSuccess()
we can say $url = $this->router->generate('homepage')
, and $response = new RedirectResponse($url)
. You may or may not be familiar with RedirectResponse
. In a controller, to redirect, you use $this->redirectToRoute()
. In reality, that's just a shortcut for these two lines!
Finally, add $event->setResponse($response)
.
<?php | |
Show Lines
|
// ... lines 2 - 10 |
class RedirectAfterRegistrationSubscriber implements EventSubscriberInterface | |
{ | |
Show Lines
|
// ... lines 13 - 19 |
public function onRegistrationSuccess(FormEvent $event) | |
{ | |
$url = $this->router->generate('homepage'); | |
$response = new RedirectResponse($url); | |
$event->setResponse($response); | |
} | |
Show Lines
|
// ... lines 26 - 32 |
} |
Ok, this class is perfect! To tell Symfony about the event subscriber, head to app/config/services.yml
. At the bottom, add app.redirect_after_registration_subscriber
, set the class, and add autowire: true
. By doing that, thanks to the RouterInterface
type-hint, Symfony will automatically know to pass us the router.
Finally, add a tag on the bottom: name: kernel.event_subscriber
. And we are done!
Show Lines
|
// ... lines 1 - 5 |
services: | |
Show Lines
|
// ... lines 7 - 22 |
app.redirect_after_registration_subscriber: | |
class: AppBundle\EventListener\RedirectAfterRegistrationSubscriber | |
autowire: true | |
tags: | |
- { name: kernel.event_subscriber } |
Try it out! Go back to /register
and signup as aquanaut5@gmail.com
. Fill out the rest of the fields and submit!
Boom! Back to our homepage! You can customize just about anything with events. So don't override the controller. Instead, hook into an event!
42 Comments
Hey Sami
Were you having problems or why you had to change the type-hint of the $event argument?
I can see that FOSUserBundle still sends the "FormEvent" object: https://github.com/FriendsO...
Cheers!
Hi, This is a great tutorial, thanks for it.
My dude is: how can i go back to the App\Form\RegistrationType if i need? for example the email is already register.
public function onRegistrationSuccess(FormEvent $event)
{
$user = $this->userManager->createUser();
$em = $this->em;
$r = $em->getRepository('App:User');
$form = $event->getForm();
if ($form->isSubmitted()) {
$email = $form->get('email');
$email_data = $email->getData();
$existe_email = $r->existeEmailUsername($email_data);
if ($existe_email) {
$event->getRequest()->getSession()->getFlashBag()->add('error', $this->translator->trans('Email already used.'));
$event = new FormEvent($form, $event->getRequest());
$dispatcher = new EventDispatcher();
if (null === $response = $event->getResponse()) {
$url = $this->router->generate('fos_user_registration_register');
$response = new RedirectResponse($url);
$event->setResponse($response);
}
// $dispatcher->dispatch($event, FOSUserEvents::REGISTRATION_FAILURE);
// $dispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, $event);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, new FilterUserResponseEvent($user, $event->getRequest(), $response));
if (null !== $response = $event->getResponse()) {
return $response;
}
}
Thanks a lot.
Hey Nacho,
> My dude is: how can i go back to the App\Form\RegistrationType if i need? for example the email is already register.
Just to clarify, I suppose you want to redirect user back to *login* page instead of register page if the give emails is already registered?
Actually, I'd recommend you to use a UniqueEntity (see https://symfony.com/doc/cur... ) for email field that will check if the give email is registered on form validation level, and if it is - the registration form will show a clear message about it.
Cheers!
Hi Victor,
Thank you so much for answering so quickly.
Checking the email is just an example, what i am trying to do is to go back to the register form showing an error.
Best regards
Hey Nacho,
OK, perfect, then my suggestion about using UniqueEntity showing validation error should fit well for you I think.
Cheers!
Hi victor,
Thanks again for answering.
I am sorry i did not express myself correctly.
The example that i would like to implement is:
I would like to use a promotional code. this promotional code do not belong to the user entity, so i can not use any Unique key o a validation on the form type. I need to check it on the onRegistrationSuccess and if the code is wrong [spelling o the code doesn't exist] go back to the from and show the error -> "this promotional code is not correct", but filling all fields of the form with the information already submitted.
Cheers! and thanks a lot for you time.
Hey Nacho,
See this code that is responsible for registration: https://github.com/FriendsO... - so when REGISTRATION_SUCCESS even is dispatched - form is already valid, that means use will be stored into DB before the redirect. Somehow, you need to make form invalid before that isValid() check if promo code is not valid or does not exist. For this, the only way I see is to override the registration form with your custom form. An this would be the first step, as you also want to render an additional field (called "promotional code" I suppose?) so it will be rendered in that form and users would be able to input the code there. Have you done that already?
Anyway, for more complex solutions, I'd recommend you to look into direction of Symfony Guard instead of using FOSUserBundle, Guard is much more flexible and you just write the any business logic you want from scratch. See this course for more information: https://symfonycasts.com/sc... . With FOSUserBundle you would need to override things to get it working
I hope this helps!
Cheers!
Hi Victor,
Thanks a lot for your time. Of course your answer helps me. I have resolved it as you mention by doing my own controller, but when i saw this tutorial i was very impressive how register can be resolved in an easy way, so i was tempted to change everything.
It is true that FOSUserBundle force you to override a lot of things, but after many years using it i have a lot templates, services and controllers that i can reused easily. How knows in the future.
For those how doesn't know what are we talking about, create a register controller in src and use a different link to go there.
{# a href="{{ path('fos_user_registration_register') }}">{{ 'Regístrate'|trans }} /a #}
a href="{{ path('user_registration') }}">{{ 'Regístrate'|trans }} /a
At the controller use the registrationType in stead of defined it on the server.yml
$form = $this->createForm(RegistrationType::class, $user, $params);
And reused the templates of the fosuser bundles if you already have them
return $this->render('@FOSUser/Registration/register.html.twig', array(
'form' => $form->createView(),
'action' => $this->generateUrl('user_registration')
));
Do not forget to change the action to your new register controller, otherwise it will go to the fosuserbundles one.
You can override the templates at templates/bundles/FOSUserBundle/
Thanks a lot again for your help!
Cheers.
Hey Nacho,
Thanks for sharing your solution with others! And I'm happy you were able to got it working! :)
Cheers!
Using exactly the same code in symfony 3.4 and it ignores the listener. Does version 3.4 have anything different, that needs a different setting or approach?
Hey Gavin Moulton
In 3.4 I think you need to configure your listeners and tag them
Docs about listeners: https://symfony.com/doc/3.4...
Cheers
Thank you so much for those videos. You just saved me some reading times. I hate reading!!! Because I read very slowly.
Well, I did not do exactly what you did in your video when you declare the service into app/.../services.yml and I was wondering why didn't you put it into myBundle/.../services.yml. So I declare the service into myBundle/.../services.yml. When I register I keep redirected to the fos_user_registration_confirmed route. Then I spent an hour trying to find out why it did not work (checking if I wrote badly some words, try Xdebug which did not debug event subscriber class and also set die() but nothing happend). I just remembered you said set it into app/.../services then I cut and paste the service code from myBundle/.../services.yml to app/.../services.yml then it works.
What is the difference between app/.../services.yml and myBundle/.../services.yml? Note that myBundle/.../services.yml is imported after app/.../services.yml in the app/.../config.yml.
Hey Guervyl
We're glad to hear that you are liking our videos :)
> What is the difference between app/.../services.yml and myBundle/.../services.yml?
As far as I know the only difference is the loading order. Symfony loads first your config from "app" folder
> why didn't you put it into myBundle/.../services.yml
That's because in Symfony4 you don't have a bundle structure anymore (ignoring third party bundles), all your code live inside "src" folder
I'm not sure why it started working after you moved the config from your bundle to the "app" folder but the good part is you now know that you don't have to split your config into many bundles
Cheers!
Hi, first off, great tutorial as usual!
I want a newly registered user to redirect to a different route but I get this error:
The "MDBUserBundle" (from the _controller value "MDBUserBundle:User:confirmed") does not exist or is not enabled in your kernel! Did you mean "FOSUserBundle:User:confirmed"?
Hey Jelle,
Looks like your route does not registered in the application. You can double check it with consoler command:
bin/console debug:router --show-controllers | grep 'MDBUserBundle:User:confirmed'
Do you see your router in the output? Also, what do you exactly do to see this error, I mean, what code causes this error?
Cheers!
Yo there!
I would use an event subscriber for that :). Specifically, create a subscriber on the same event that we use in this chapter - FOSUserEvents::REGISTRATION_SUCCESS. The FormEvent object that you're passed allows you to say $user = $event->getForm()->getData()
. You can then update the User object, and it will be saved by FOSUserBundle right after.
Try it out and let me know how it goes :).
Cheers!
Wow ! Thank you this is cool !
I wish I knew this before I override all my controllers haha :D
Hey Kaizoku ,
Uh oh, sounds like a big piece of work ;) Yea, events rock! But sometimes you are not enough of them.
Cheers!
Hey Matt!
Woohoo! Nice work! And you're right, $form->handleRequest($request)
does also populate data on the underlying object ($user) in this case. There are 2 ways to set the underlying data. Most commonly, we say (in a controller) $this->createForm(SomeFormType::class, $someObject)
. The second argument becomes the object that the form modifies. The other way is by calling $form->setData($someObject)
, as you saw here. But actually, they're the same :). The first is just a shortcut to create the form and then call setData() on it. Hopefully that clarifies even more!
Cheers!
Dear KnpUniversitiy-Team
First, thanks a lot for the really great tutorial!!
I added some other fields like name or firstname to the user entity. Now I Have the problem, that the validation of the form works for this new fields fine and when a field with @Assert\NotBlank() is missing, a nice note is displayed in the form. But when the email field is empty, no note is displayed, but the error "Column 'email' cannot be null" is displayed. How can I fix this? I tried to find a solution in the web, but I haven't' found a solutions which I understand.
Best regards!
Michael
Hey Michael K.
We are glad to hear you are liking our tutorials :)
Have you tried using translations ? you can customize any message from the system, if you don't know how, you can check the docs here http://symfony.com/doc/curr...
or even better, check our video about it: https://knpuniversity.com/s...
Have a nice day!
Hi Diego
Thanks a lot for the fast replay!
I don't think it's a translation problem. For me, it seems to be a validation problem. Because with my own fields it works perfect. But with the standard fields like email, only the error-screen of symfony is displayed.
I got you now! (Sorry, I misunderstood you)
Indeed you are missing your validations, and the reason is because FOSUserBundle add's them via "Validation Groups", you have to specify which group you want to use in your FormType's (actually there are more ways of doing it), in this case you want the "Registration" group, you can do it like this:
//Registration Form Type
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => array('registration'),
));
}
You can read more about validation groups here http://symfony.com/doc/current/form/validation_groups.html
Or even better, we have a tutorial where Ryan explains it in a cool way https://knpuniversity.com/screencast/symfony-security/conditional-validation-groups
Cheers!
Dear Diego
And now I unterstand how it works and it works! ;-)
Thanks a lot for your help!
Michael
Hello,
Unfortunatly it seems to be different for redirecting after LOGIN.
There is not login event.
I found this two events
return [
FOSUserEvents::SECURITY_IMPLICIT_LOGIN => 'onLogin',
SecurityEvents::INTERACTIVE_LOGIN => 'onLogin',
];
But then the $event in onLogin is not of the correct type and it's isn't working.
Is it possible to have the eventsubscriber working for login redirection ?
Hey Kaizoku
What you want to achieve?
By default, symfony redirects you back to the last requested page that caused you to login, or if there isn't one, you can setup a default route (via config.yml)
If this behaviour doesn't fit your needs, as always, you can customize it, but it will require more work. You can find a lot of info here: https://symfony.com/doc/cur...
I hope it helps you :)
Cheers!
Hello Diego,
Thank you for your answer.
About login event it's a bit different than other events as I understood.
I had the redirection working implementing AuthenticationSuccessHandlerInterface instead of EventSubscriberInterface
class RedirectAfterLogin implements AuthenticationSuccessHandlerInterface {
private $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function onAuthenticationSuccess( Request $request, TokenInterface $token ) {
return new RedirectResponse($this->router->generate(...));
}
}
Ohhh the "AuthenticationSuccessHandlerInterface", interesting! I didn't know about it's existence. Thanks for sharing it!
Have a nice day :)
Hello together,
First, thankyou for your good work. I`ve tested your sample code - no problems. FOSUserEvents::REGISTRATION_SUCCESS is overriden and the "homepage" is displayed. But if I generate a new Symfony 3.3 application framework with friendsofsymfony/user-bundle the landing page with "The user has been created successfully.. " will be still dispayed but no homepage. If I debug onRegistrationSuccess in step over mode, I see how the line $this->router->generate('homepage') will be executed, but the result no homepage. Other FOSUserEvents do have the same problem. To avoid this problem I comment out all of the new code in services.yml but the result will be the same no homepage.
What is going wrong? Is there something more to do? Thank you... Greetings from Germany
Hey Jürgen Schatral
Can you show me the snippet of your listener ? I believe you forgot to attach the RedirectResponse object to the event, but I might be wrong
Cheers!
Dear Diego,
the code is identical to the code from your download - copy and paste. But I find a difference in the behavior if I disable the event in your sample code. A message shows that the new user is registered directly without sendig an e-mail to the user although the parameter.yml file has a correct mailer configuration.
Because of this behavior a take a look in my and your composer.json. I found differences in the version control
"friendsofsymfony/user-bundle" : "^2.0"
"friendsofsymfony/user-bundle" : "dev-master",
I don`t know how to handle that.
Here the copy of my code of the EventListener and my Composer.json for you. I hope it helps - Thank you. Greeting from Germany
Jürgen Schatral.
namespace AppBundle\EventListener;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\FOSUserEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class RedirectAfterRegistrationSubscriber implements EventSubscriberInterface
{
use TargetPathTrait;
private $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function onRegistrationSuccess(FormEvent $event)
{
// main is your firewall's name
$url = $this->getTargetPath($event->getRequest()->getSession(), 'main');
if (!$url) {
$url = $this->router->generate('homepage');
}
$response = new RedirectResponse($url);
$event->setResponse($response);
}
public static function getSubscribedEvents()
{
return [
FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess'
];
}
}
Composer.json
{
"name" : "js/istframework2",
"license" : "proprietary",
"type" : "project",
"autoload" : {
"psr-4" : {
"AppBundle\\" : "src/AppBundle"
},
"classmap" : [
"app/AppKernel.php",
"app/AppCache.php"
]
},
"autoload-dev" : {
"psr-4" : {
"Tests\\" : "tests/"
},
"files" : [
"vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
]
},
"require" : {
"php" : ">=5.5.9",
"doctrine/doctrine-bundle" : "^1.6",
"doctrine/orm" : "^2.5",
"friendsofsymfony/user-bundle" : "dev-master",
"incenteev/composer-parameter-handler" : "^2.0",
"sensio/distribution-bundle" : "^5.0.19",
"sensio/framework-extra-bundle" : "^3.0.2",
"symfony/monolog-bundle" : "^3.1.0",
"symfony/polyfill-apcu" : "^1.0",
"symfony/swiftmailer-bundle" : "^2.3.10",
"symfony/symfony" : "3.3.*",
"twig/twig" : "^1.0||^2.0"
},
"require-dev" : {
"sensio/generator-bundle" : "^3.0",
"symfony/phpunit-bridge" : "^3.0"
},
"scripts" : {
"symfony-scripts" : [
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
],
"post-install-cmd" : "@symfony-scripts",
"post-update-cmd" : "@symfony-scripts"
},
"config" : {
"sort-packages" : true
},
"extra" : {
"symfony-app-dir" : "app",
"symfony-bin-dir" : "bin",
"symfony-var-dir" : "var",
"symfony-web-dir" : "web",
"symfony-tests-dir" : "tests",
"symfony-assets-install" : "relative",
"incenteev-parameters" : {
"file" : "app/config/parameters.yml"
}
}
}
Sorry I have made a mistake here is the EventListerner again...
Mfg. J.Schatral
class RedirectAfterRegistrationSubscriber implements EventSubscriberInterface
{
use TargetPathTrait;
private $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function onRegistrationSuccess(FormEvent $event)
{
// main is your firewall's name
$url = $this->getTargetPath($event->getRequest()->getSession(), 'main');
if (!$url) {
$url = $this->router->generate('homepage');
}
$response = new RedirectResponse($url);
$event->setResponse($response);
}
public static function getSubscribedEvents()
{
return [
FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess'
];
}
}
Oh, you installed the "Dev" branch of FOSUserBundle, just change it to: "friendsofsymfony/user-bundle" : "^2.0"
as we do (composer.json), and run: composer update friendsofsymfony/user-bundle
If it doesn't fix it, I believe your listener is not been fired, what it means is, the listener is not registered, try adding a `die()` statement so we can tell if it's been executed or not, so we can keep debugging :)
Cheers!
Okay, if changed the version and run an composer update, clean and warm up the project...
If have set a breakpoint in the event onRegistrationSuccess() it halted definitly at the line with $url = $this->router->generate('homepage');
$response = new RedirectResponse($url); Debug information shows me that:
HTTP/1.0 302 Found
Cache-Control: no-cache, private
Date: Thu, 10 Aug 2017 10:33:32 GMT
Location: /ISTFramework2/web/app_dev.php/
<html>
<head>
<meta charset="UTF-8"/>
<meta http-equiv="refresh" content="1;url=/ISTFramework2/web/app_dev.php/"/> <title>Redirecting to /ISTFramework2/web/app_dev.php/</title>
</head>
<body>
Redirecting to /ISTFramework2/web/app_dev.php/.
</body>
</html>
The next line
$event->setResponse($response); brings me back zu my old problem :-)
Why not "Dev" instead of "^2.0" - Thank you!
Greeting from Germany
> Why not "Dev" ?
Because Dev branches might contain unknown bugs or backward incompatibilities
Hmm, look's like it is trying to redirect you to the homepage, exactly what you want, isn't it ?
Yes! At that point It look`s like, but it doesn`t :-)
Hmm, interesting, what does it do after ? could you open your browser's debugger and check the response status ?
Also I just noticed this line: $url = $this->getTargetPath($event->getRequest()->getSession(), 'main');
You are passing the whole session, I believe you need to access to the property which contains the name or the URL
First the Response status:
HTTP status 200 OK
Controller RegistrationController :: registerAction
Controller class FOS\UserBundle\Controller\RegistrationController
Route name fos_user_registration_register
Has session yes
Second the url property:
$url = $this->getTargetPath($event->getRequest()->getSession(), 'main');
if (!$url) {
$url = $this->router->generate('homepage');
#Debugger shows /ISTFramework2/web/app_dev.php/
}
Yes you are right the whole session will be used to reference to the $url at first but the $url will be empty and the access to the property which contain the name followed in the if block in the next code line.
After the execution of the overriden method we landed in C:/xampp/htdocs/ISTFramework2/vendor/friendsofsymfony/user-bundle/EventListener/EmailConfirmationListener.php.FOS\UserBundle\EventListener\EmailConfirmationListener->onRegistrationSuccess()
.
After that a e-mail confirmation will be send and the FOSUserEvents::REGISTRATION_COMPLETED
event will dispatched and the homepage event will be ignored again.
...But this code is identical to your download version and nothing has changed.
If it is posible for you to generate a simple new Symfony 3.3 application with friendsofsymfony/user-bundle with a copy of the eventlisner from your download code you can simply debug it with phpstorm or eclipse.
It is not much work. I think if you debug it on your own you see something more what I don`t see... :-) After that you can upload a actual version Symfony 3.3 application without errors - if possible
Thank you! Greetings from Germany.
Yo Jürgen Schatral!
Well, this is very interesting! So first, I don't think the issue is Symfony 3.3 - I can't think of a reason why this would cause an issue, and you (very smartly) tried commenting out all the new Symfony 3.3 services.yml code, which didn't change anything. Also, I just tried it :). I downloaded a fresh Symfony 3.3 project, installed FOSUserBundle, copy and pasted your subscriber and... it works! I'm redirected to the homepage as expected. You can see the code here: https://github.com/weaverryan/tmp-sf33-fosu
The issue is something different - and you discovered it in your last message: if you activate the email confirmation step, then that overrides the response that you're setting. The fix is a bit odd: you need to set the priority of your subscriber to be lower than the EmailConfirmationListener, so that your listener is called after. The change should look like this in your subscriber
public static function getSubscribedEvents()
{
return [
// use a -5 priority - the other listener uses a 0 priority
FOSUserEvents::REGISTRATION_SUCCESS => ['onRegistrationSuccess', -5]
];
}
I haven't tested this, so let me know if it works. And great issue - very tricky!
Cheers!
Thank you that`s it! It works with redirection to the homepage.
After that we looked again in you documention file controller_envents.rst - "Registration success listener with enabled confirmation at the same time". We have read your documention before but we have read it so badly. The solution of this facts stood very near by us, but we don`t have seen it. ...To change the priority is not so unusual. Now we are shure that we have with this bundle a great range of flexibity. We have learned a lot. Thank you for that.
Greeting from Germany - J.Schatral
Ah, I'm so happy it worked! Thanks for following up and good luck! :)
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.3.*", // v3.3.18
"doctrine/orm": "^2.5", // v2.7.0
"doctrine/doctrine-bundle": "^1.6", // 1.10.3
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.5
"symfony/swiftmailer-bundle": "^2.3", // v2.5.4
"symfony/monolog-bundle": "^2.8", // v2.12.1
"symfony/polyfill-apcu": "^1.0", // v1.3.0
"sensio/distribution-bundle": "^5.0", // v5.0.18
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.25
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"knplabs/knp-markdown-bundle": "^1.4", // 1.5.1
"doctrine/doctrine-migrations-bundle": "^1.1", // v1.3.2
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"friendsofsymfony/user-bundle": "^2.0" // v2.0.0
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.1.4
"symfony/phpunit-bridge": "^3.0", // v3.2.7
"nelmio/alice": "^2.1", // v2.3.1
"doctrine/doctrine-fixtures-bundle": "^2.3", // v2.4.1
"symfony/web-server-bundle": "^3.3"
}
}
Works like a charm, the only thing I had to update is the type of $event parameter :
public function onRegistrationSuccess( **GetResponseUserEvent** $event)