Skip to content
Jim Martens edited this page Dec 2, 2014 · 8 revisions

Cleared for editing

The goal of this page is to determine the usage of the event system. This includes the places where events should be offered and the way how to do it (look at Symfony doc for that).

General placement of events

Events allow the inclusion of new code in existing old code without modifying it. They can be used to add features (e.g. do something when a new user is registered) or to extend the existing functionality (modify a restricted set of variables). Another use-case is the explicit usage to gather content from various listeners in one place for unified processing. They are NOT to be used to redefine the execution and change the behaviour of the code that hosts the events. Therefore they are not allowed to change the state of the class/object (alter it's properties).

This leads to these placements:

  • before changes of persistent data
  • after changes of persistent data
  • before showing a new page to the user
  • before form validation
  • after form validation
  • custom locations that have to be documented in the bundle's documentation

General Usage

Now that we know where to find events, we will go into how to use them. This does not mean the technical usage but the semantic usage. It also explains when alternative solutions are at hand.

You can use the PHP events for mere execution points of your functionality (e.g. do A when B happens) or for specific additions to the functionality providing the event. In the case of a form you could add a form field. This includes several things:

  • add the field by using the form builder provided by the event object
  • adding code to validate the input (includes reading the parameters and throwing an exception if input invalid)
  • saving the input
  • assigning the input to the template (ensures that input is not lost on validation exception and is required anyway in an edit form)

All the PHP code is assigned to different events, so it is perfectly viable to have one plugin being stretched over multiple events in one class or even multiple classes.

Bringing it to life

The event system uses the EventDispatcher component of Symfony. Each controller will use the dispatcher to dispatch events as described above. Services will do the same. So far so easy. The listener part is covered by the respective bundles themselves. The listeners are defined as services in the services.yml and are connected to the events with tags.

The listeners themselves will get the provided Event object, the event name and a reference to the EventDispatcher itself. Via the EventObject they have the chance to communicate with the providing class.

Examples

An example for the usage of the EventSystem is the group system or more specifically the group options. The service responsible for returning the value of a group option will first look in the database. If it can't find the answer there and under the premise that only group options of installed packages are asked for, it will use an event to gather the necessary information. The event object will contain the information what option is required. The event listeners will then look if this options falls into their area of responsibility. If it does not, they won't process. If it does however, they will return the options of the entire bundle so that next time, options of this particular bundle will be available from database.

This procedure is called lazy initialization: The database is filled when needed. This is possible, because MongoDB does not require predefined schemas and is incredibly fast.

Clone this wiki locally