Blog post: Laminas Event Manager and Lazy listeners

Post about Laminas Event Manager with some examples of implementations. Any feedback is appreciated.

Thanks for creating and sharing your blog post! :+1:

My first comment is related to your listeners: never inject the entire service manager in a class. If you do that, then you have a design fault from the start and you are on the best way to an anti-pattern. Your class should not even know that there is a dependency injection container. Give only what is necessary.

The problem can be found in User\Event\EventLogListener and in Order\Event\HideDiscountListener.

My second hint is related to the module class of Application. The method onPreRoute can be strongly reduced:

  1. The method Application\Module::onPreRoute() is called on every request and on every request the language code is saved in a session. This is unnecessary, as a session should be used to transport information across multiple requests, which is not the case here.
  2. In all Laminas and Mezzio projects it is recommended to use laminas-component-installer via global installation. If you then install laminas-mvc-i18n the translator will be set for the router. No further steps are necessary because Laminas\Mvc\I18n\Router\HttpRouterDelegatorFactory is used then.
  3. There is no need to fetch the translator from the container. You can use PHP’s Locale::setDefault('…') and the translator and all helpers of laminas-i18n will use the set value. (This also allows you to retrieve the current locale via Locale::getDefault() within your entire application.)
  4. Adding the translation files in this way is unnecessary because adding a translation file does not mean it will be loaded in the same step. The corresponding file is only loaded when a translation is retrieved. You can use the module config or the global config file to add translation files.

Another example of the use of listeners can be found in the laminas-view documentation.

2 Likes

Thank you for reply froschdesign …

Yes, I’m aware of this anti-pattern. But in example the UsersActionsLogTable model was “wraped” with delegator class also. And because listener is registered during onBootstrap, so the UsersActionsLogTable class is not decorated with decorator class during this proces yet … If I’m right.

(Decorator was setting identity property, but this property was still empty in the model UsersActionsLogTable. So I injected Service Manager class in listener construct instead of UsersActionsLogTable and access the model later.)

Hm, didn’t know about this :+1:

See: