From 79b9f4ccb4b544de100357e8b2e1e28519d6692d Mon Sep 17 00:00:00 2001 From: Ivo Valchev Date: Mon, 26 Jul 2021 14:17:58 +0200 Subject: [PATCH] Creating and listening to events --- docs/extensions/event.md | 176 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 3 deletions(-) diff --git a/docs/extensions/event.md b/docs/extensions/event.md index 8a32bf0c..f262c43e 100644 --- a/docs/extensions/event.md +++ b/docs/extensions/event.md @@ -5,9 +5,179 @@ title: Event Dispatcher Event dispatcher (Event Listeners and Subscribers) ================================================== -Read more about this topic in Symfony's official documentation: [Event Dispatcher][docs]. -[todo] +During the execution of a Symfony/Bolt application, +lots of event notifications are triggered. Your project can create and listen to +these notifications and respond to them by executing any piece of code. + +## Listening to events + +Symfony allows two distinct ways for executing code in response to an event: +*Listeners* and *Subscribers*. + +While similar in what they accomplish, there are a couple of differences that may +sometimes sway you to use a listener or a subscriber: + +* *Subscribers* are easier to reuse because the knowledge of the events is kept +in the class rather than in the service definition. +This is the reason why Symfony uses subscribers internally; +* Listeners are more flexible because bundles can enable or disable each of them +conditionally depending on some configuration value. +* Listeners require further configuration in the `services.yaml` file. Subscribers do not. + +

Due to the last difference (see above), the recommended way in Bolt +is to use subscribers, unless you have a good reason for preferring listeners.

+ +### Creating an event subscriber + +Each subscriber has two required components: + +* An event or events it subscribers to (i.e., in when does your custom code execute) +* A handler or handlers that contain the custom code in response to the triggered event. + +The list of available events is available by running `php bin/console debug:event-dispatcher` + +You can put subscribers in the `src` folder in the root of your Bolt project, like so: + +```php +getContent(); + + // Do something with it, e.g. print the ID. + dump($content->getId()); + } + + /** + * Returns an array of event names this subscriber wants to listen to. + * + * The array keys are event names and the value can be: + * + * * The method name to call (priority defaults to 0) + * * An array composed of the method name to call and the priority + * * An array of arrays composed of the method names to call and respective + * priorities, or 0 if unset + * + * For instance: + * + * * ['eventName' => 'methodName'] + * * ['eventName' => ['methodName', $priority]] + * * ['eventName' => [['methodName1', $priority], ['methodName2']]] + * + * The code must not depend on runtime state as it will only be called at compile time. + * All logic depending on runtime state must be put into the individual methods handling the events. + * + * @return array The event names to listen to + */ + public static function getSubscribedEvents() + { + return [ + // This is the event + ContentEvent::POST_SAVE => ['onPostSave', self::PRIORITY] + ]; + } +} +``` + +## Creating a custom event +Assuming there is a class that handles custom work in your project, +called `CustomWorker`, you can use the `EventDispatcher` service to create an event. + +First, we need a new `Event` object. For example, here is Bolt's own `ContentEvent`: + +```php +content = $content; + } + + // Methods that are available in the event handlers (listeners and subscribers) + public function getContent(): Content + { + return $this->content; + } +} +``` + +Now, we can dispatch (also known as trigger) that event in the example `CustomWorker` class: + +```php +dispatcher = $dispatcher; + } + + public function work(): void + { + // Do some work... + $content = new Content(); + + // Dispatch a new event, in this case a PRE_SAVE. + $event = new ContentEvent($content); + $this->dispatcher->dispatch($event, ContentEvent::PRE_SAVE); + } +} +``` + + +Read more about this topic in Symfony's official documentation: [Event Dispatcher][docs]. -[docs]: https://symfony.com/doc/current/event_dispatcher.html \ No newline at end of file +[docs]: https://symfony.com/doc/current/event_dispatcher.html