Chapters
26 Chapters
|
2:53:08
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
02.
Hooking into Symfony with an Event Subscriber
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
This tutorial also works well for Symfony 6!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.2",
"ext-iconv": "*",
"antishov/doctrine-extensions-bundle": "^1.4", // v1.4.3
"aws/aws-sdk-php": "^3.87", // 3.133.20
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.12.1
"doctrine/doctrine-bundle": "^2.0", // 2.2.3
"doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // 2.2.2
"doctrine/orm": "^2.5.11", // 2.8.2
"easycorp/easy-log-handler": "^1.0", // v1.0.9
"http-interop/http-factory-guzzle": "^1.0", // 1.0.0
"knplabs/knp-markdown-bundle": "^1.7", // 1.9.0
"knplabs/knp-paginator-bundle": "^5.0", // v5.4.2
"knplabs/knp-snappy-bundle": "^1.6", // v1.7.1
"knplabs/knp-time-bundle": "^1.8", // v1.16.0
"league/flysystem-aws-s3-v3": "^1.0", // 1.0.24
"league/flysystem-cached-adapter": "^1.0", // 1.0.9
"league/html-to-markdown": "^4.8", // 4.9.1
"liip/imagine-bundle": "^2.1", // 2.5.0
"oneup/flysystem-bundle": "^3.0", // 3.7.0
"php-http/guzzle6-adapter": "^2.0", // v2.0.2
"phpdocumentor/reflection-docblock": "^5.2", // 5.2.2
"sensio/framework-extra-bundle": "^5.1", // v5.6.1
"symfony/asset": "5.0.*", // v5.0.11
"symfony/console": "5.0.*", // v5.0.11
"symfony/dotenv": "5.0.*", // v5.0.11
"symfony/flex": "^1.9", // v1.21.6
"symfony/form": "5.0.*", // v5.0.11
"symfony/framework-bundle": "5.0.*", // v5.0.11
"symfony/mailer": "5.0.*", // v5.0.11
"symfony/messenger": "5.0.*", // v5.0.11
"symfony/monolog-bundle": "^3.5", // v3.6.0
"symfony/property-access": "5.0.*|| 5.1.*", // v5.1.11
"symfony/property-info": "5.0.*|| 5.1.*", // v5.1.10
"symfony/routing": "5.1.*", // v5.1.11
"symfony/security-bundle": "5.0.*", // v5.0.11
"symfony/sendgrid-mailer": "5.0.*", // v5.0.11
"symfony/serializer": "5.0.*|| 5.1.*", // v5.1.10
"symfony/twig-bundle": "5.0.*", // v5.0.11
"symfony/validator": "5.0.*", // v5.0.11
"symfony/webpack-encore-bundle": "^1.4", // v1.11.1
"symfony/yaml": "5.0.*", // v5.0.11
"twig/cssinliner-extra": "^2.12", // v2.14.3
"twig/extensions": "^1.5", // v1.5.4
"twig/extra-bundle": "^2.12|^3.0", // v3.3.0
"twig/inky-extra": "^2.12", // v2.14.3
"twig/twig": "^2.12|^3.0" // v2.14.4
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0", // 3.4.0
"fakerphp/faker": "^1.13", // v1.13.0
"symfony/browser-kit": "5.0.*", // v5.0.11
"symfony/debug-bundle": "5.0.*", // v5.0.11
"symfony/maker-bundle": "^1.0", // v1.29.1
"symfony/phpunit-bridge": "5.0.*", // v5.0.11
"symfony/stopwatch": "^5.1", // v5.1.11
"symfony/var-dumper": "5.0.*", // v5.0.11
"symfony/web-profiler-bundle": "^5.0" // v5.0.11
}
}
23 Comments
Hello, with S6, Php8,1 i got a deprication message
User Deprecated: Method "Symfony\Component\EventDispatcher\EventSubscriberInterface::getSubscribedEvents()" might add "array" as a native return type declaration in the future. Do the same in implementation "App\EventListener\UserAgentSubscriber" now to avoid errors or add an explicit @return annotation to suppress this message.
Hey Mepcuk
So what's the issue? is anything work bad or unexpected?
PS BTW to fix it will be enough to add
: arrayto theApp\EventListener\UserAgentSubscriber::getSubscribedEvents()Cheers!
Heya! Looking to confirm that event subscriber services are lazily instantiated only when the events they listen to are actually dispatched. Some simple tests show they are not in debug mode (guessing because of the traceable dispatcher) but are in prod (non-debug mode).
I recently converted several subscribers to service subscribers to make them "lazy" but looks like that wasn't required.
Yo Kevin B. !
Ah, that laziness is a really good point to bring up! Ok, so let's look at this:
A) You're correct that event subscribers (and listeners) are lazy in the "prod" environment, meaning that your listener/subscriber service won't be instantiated unless the event is actually dispatched. I haven't tested this, but if I'm wrong, it would be a big ol' bug in Symfony :).
B) What about the dev environment? I had assumed it worked the same... though that was just a guess. I just did a quick and dirty test on my side and it seems like my event subscriber IS indeed still lazy in the dev mode (tested by putting a die() in the constructor of an event subscriber for a security-related event and then refreshed the page). You're seeing something different? It doesn't really matter, of course, but I'm curious.
So... you're correct that you "shouldn't" need to convert your event subscriber/listener into a "service subscriber" (to help others, the term "service subscriber" here has nothing to do with an event subscriber - we're talking about this concept https://symfonycasts.com/sc... ). That's because, as you already know, your listener/subscriber service isn't instantiated unless it's necessary.
However, if you have an event subscriber/listener that is called very often (most importantly the "kernel" events)... but that only does its real work SOME of the time, then you might still want a subscriber so that your subscriber/listener can be instantiated, executed, but then "exit early" ("no work to do on this request!") before instantiating any services. So, your conversion to service subscribers might still have been a good idea :).
Cheers!
Thanks for the confirmation!
I did the same dd in constructor thing but I should note that the testing I did was in 4.4 so maybe some things have changed. Regardless, in prod, they are lazy.
Indeed, the request subscribers I converted were definitely a good call. It's the non-standard event subscribers (3rd party) where I made the unnecessary conversion.
I have project with EasyAdmin3 and i do not have logs in Symfony profiler -> logs tabs. However can clearly see it in terminal, dev server runned by symfony serve command.
Hey Mepcuk!
Try running
composer require symfony/monolog-bundle- that's my guess.By default, Symfony ships with a barebones logger service. One thing it does (which is kind of annoying) is that it dumps out to the terminal. But when you install Monolog, the default logger is replaced with the real one. I don't remember for sure, but my guess is that you only see the logs in the profiler once you have the "real" logger installed.
Cheers!
Hello,
I am kind of struggling with even subscriber:
so when I am saving or updating it should trigger below, basically set createdBy,At,updatedBy,At
Then I will click on create or save but this event is not even triggered.
I cleared cache and it wont display dd(Are we here);
Hey Peter!
Hmm. So this is a different event system than the one we talk about here, but both work using the same fundamental principle of dependency injection tags. So, I don't see anything obviously wrong with your code: you've attached the tag correctly. So, it's time to debug! There are 2 things I can think of:
1) Run
php bin/console debug:container App\EventListener\CreatedUpdatedListenerand verify that the "tags" are listed on it. Alternatively, you can runphp bin/console debug:container --tagsto see which services have the doctrine.event_listener tag.2) Internally, the class (compiler pass) that handles finding the services with the tag is here: https://github.com/symfony/symfony/blob/c71c8727cc665c9e9b56e299fcfcc0adfbf02bac/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php#L75 - I would debug that
$taggedServicesvariable to verify your service is there).Let me know if this helps!
Cheers!
- lorenzo/pinky 1.0.5 requires ext-xsl * -> it is missing from your system. Install or enable PHP's xsl extension.
I'm getting this error on composer install
I tried composer update, but that didn't work.
Can't find anything regarding xsl in php.ini (This extension has no configuration directives defined in php.ini.)
nevermind. I had to enable them in php.ini. Was using 7.4, switched to 7.3, but not sure if that had to do with it.
If I went back to the first video conversation I would've seen someone solved this already.
No worries Will T. sorry you hit the issue! Most operating systems come with some standard PHP extensions like this... so I sometimes forget that a few OS's / ways to install PHP do *not* and cause problems.
Good luck after this! Cheers!
I recently moved from Mac to Windows after being a long time Mac user. Macbook was 10 years old and in dire need of an upgrade. I can get so much more value for a loaded PC.
Finding it can be some what more challenging to get set up running, though, AMP on OSX is not without it's own frustrations.
I think even though it's irritating, it becomes more like working on a job; it gives me valuable troubleshooting skills that give me more experience.
Hey Will T.!
Switching between *anything* will definitely involve a few bumps on the road - probably you're already through the worst - and I love that attitude! Plus, with the Unix subsystem, Windows has come a long way to being a good dev environment :).
Cheers!
Hello guys,
I'm trying to use Swiftmailer with EventSubscriber. Basically, after the user is created with a POST, I would like to send an Email. Unfortunately, I'm missing something. In the .env I declare the configuration MAIL_URL and then the follow Subscriber.
<blockquote>Registered Listeners for "kernel.view" Event
============================================
Order Callable Priority
#1 ApiPlatform\Core\Validator\EventListener\ValidateListener::onKernelView() 64
#2 ApiPlatform\Core\EventListener\WriteListener::onKernelView() 32
#3 App\EventSubscriber\UserMailSubscriber::sendMail() 31
#4 ApiPlatform\Core\EventListener\SerializeListener::onKernelView() 16
#5 ApiPlatform\Core\EventListener\RespondListener::onKernelView() 8
</blockquote>
The problem: the method sendMail is not called baecause (I think) the event subscriber doesn't work.
Could you help me, please?
Hey Gaetano,
It would be good to know for sure if you hit the sendMail() or no. I see you have dd() commented out, did you run the website with it uncommented? Didn't you hit that "dd()" line? Also, I don't see what namespaces you're using... could you show what namespace are used in your UserMailSubscriber? Probably you extend a wrong namespace so you listener was never called, though I see it in the output... so probably that extra check in sendMail() does not work for you? I'm talking about "if (!$user instanceof User || Request::METHOD_POST !== $method) {", could you double-check its logic? It would be good to debug why you hit that return statement. Are you sure User's namespace is correct? Do you really have POST request?
Btw, why do you want to send the email via listener? How users registered in your application? Do you FOSUserBundle?
Cheers!
Hi,
thanks for your help. I explain you the project. There is a front-end (Angular) and a back-end (ApiPlatform). When I hit the route ../api/v1/users/create, a user is registered in the database and after registration, my Mailsubscriber send an email. Finally I changed strategy and it works.
This my Subscriber:
It calls my event:
Then in my userManager (you see only a part of code) I use the dispatcher:
The registeraccount method is called by the __invoke($data) inside the createUser class (this is the controller called in the collectionOperations by ApiResource).
I hope this explanation is good to better understand.
Thanks again for your help.
Great overview Ryan. One thing I don't understand. You don't configure the eventsubscriber in the services.yml and it works out-of-the-box. But when I want to subscribe to a doctrine event I have to put it explicitely in the services.yml, also according to this docs https://symfony.com/doc/cur...
Can you explain why?
Hey Paul Rijke
That's a good question. The thing here is that Doctrine comes with its own event-dispatching system, in other words Symfony events and Doctrine events are two different systems. Symfony has the "auto configure" feature, so you only need to implement the "EventSubscriber" interface and forget configuration but because of what I said Doctrine cannot benefit of that feature and you have to add the required configuration.
Cheers!
"Houston: no signs of life"
Start the conversation!