The HLEB2 framework has several predefined general events, each assigned to a specific action type.
All event classes are located in the /app/Bootstrap/Events/ folder and are open to modifications. Technically, they replace the configuration, removing unnecessary "magic" from the project.
Since these classes are tied to global events, it is recommended to segregate code depending on private implementations into separate classes.
Unoptimized code within Events can lead to reduced overall project performance.
The before() method of this class is executed before each controller call from the framework. It allows you to determine which class and method are involved and, if necessary, alter the arguments given as a named array, returning them to the invoked controller method.
For instance, if an incoming Request validation by a third-party library is used, this check can be implemented through the ControllerEvent event.
If present, the after() method allows you to override the controller's response and is executed immediately after the controller. The method receives this result in the 'result' argument by reference, allowing you to change the returned data for a specific class and method of the controller.
Globally, this might involve transforming a returned array not into JSON as set by default, but into another format like XML.
The following example demonstrates attaching an additional action before calling a specific class and method of the controller:
The before() method of this middleware class is executed before each middleware call from the framework. The method's arguments allow you to determine which class and method are involved, and whether this middleware is executed after the main action.
If necessary, there are options to modify the target middleware method's arguments, altering them, and returning them from the current method. In such a case, it is necessary to specify the condition to terminate the script execution after the result is output, by returning false from the after() method.
The order of middlewares execution can be changed in routes, and this must be accounted for when assigning events to them, if necessary replacing elements of the Event depending on the execution order with corresponding separate middlewares.
Since modules exist in isolation, each module's controllers have their own Event.
The before() method of the ModuleEvent class is executed before each controller call of any module in the framework.
Unlike ControllerEvent, there is an additional argument $module to determine the module name.
Similar to the controller event, this Event can also have an after() method.
This is another event similar to ControllerEvent, tied to calls of special 'page controllers'.
Such pages are used in the framework's registration library for the admin panel and also on this documentation site.
The execution occurs before each framework command launch, excluding those built into it by default. It also allows determining the called class and the source of the call (from the code or from the console). TaskEvent receives and returns the final data for the arguments of the final method, thus allowing the connection of a third-party library here. For example, this could be a standard console handler from Symfony.
The after() method for this event differs in that it has access to the data set in the task as setResult().
This data is passed by reference to the 'result' argument and can be modified.
If necessary, you can similarly change the returned response status using the statusCode() method.
A demonstration example showing one of the ways to organize response (with a single common interface) to the execution of various tasks:
This principle can be applied not only to task events but to other Events as well.
The switch operator is chosen for the Event due to its ability to match one result to multiple case blocks.
Associated actions can also be assigned based on other conditions, for example, by a general group in the namespace:
Additionally, event classes are inherited from Hleb\Base\Container, allowing them to use services from the container.
These services can also be obtained in the event class constructors through Dependency Injection.
The possibilities of using them are not limited, provided the code remains readable and optimized.
Here's how you can set a condition based on the HTTP request method for a specific class and method: