LazyListenerAggregate

I would like to implement listener, which is not required on every request (that is the purpose of LazyListener). But I can’t figure out working example. Here is the code:

<?php
namespace Order;

use Laminas\Config;
use Laminas\Mvc\MvcEvent;
use Laminas\EventManager\LazyListenerAggregate;

class Module
{

    public function onBootstrap(MvcEvent $event)
    {
        $application = $event->getApplication();
        $eventManager = $application->getEventManager();

        // demo lazy
        $definition = array(
            'listener' => Event\DemoLazyListener::class,
            'method' => 'onEchoVal',
            'event' => 'echoVal',
            'priority' => - 100
        );
        $aggregate = new LazyListenerAggregate([$definition], $application->getServiceManager());
        $aggregate->attach($eventManager);
       // dump($aggregate); exit;
    }
   .....
}

Listener is class with factory to access services later.

<?php
namespace Order\Event;

use Laminas\ServiceManager\ServiceLocatorInterface;
use Laminas\EventManager\EventInterface;

class DemoLazyListener
{

    public $serviceManager;

    public function __construct(ServiceLocatorInterface $serviceManager)
    {
        $this->serviceManager = $serviceManager;
    }

    public function onEchoVal(EventInterface $event)
    {
        $param = $event->getParam('param');

        $writer = new \Laminas\Log\Writer\Stream(__DIR__ . '/../../../../data/log/event_demo.log');
        $logger = new \Laminas\Log\Logger();
        $logger->addWriter($writer);
        $logger->info('Param ' . $param . '.');
    }
}

Event is triggered in controller action.

$this->getEventManager()->trigger('echoVal', null, [
    'param' => 'demo'
]);

When I dump the LazyListenerAggregate the listener key is null. I’m not sure if this is not the case.

listener

Thank you in advance for help.

Hello and welcome to the forums! :smiley:

Please test the following example. (I hope I remember correctly.)

use Laminas\EventManager\LazyListener;
use Laminas\Mvc\MvcEvent;
use Laminas\Mvc\Controller\AbstractController;

class Module
{
    public function onBootstrap(MvcEvent $event) : void
    {
        $application  = $event->getApplication();
        $container    = $application->getServiceManager();
        $eventManager = $application->getEventManager()->getSharedManager();

        $eventManager->attach(
            AbstractController::class,
            'echoVal',
            new LazyListener(
                [
                    'listener' => Event\DemoLazyListener::class,
                    'method'   => 'onEchoVal',
                ],
                $container
            )
        );
    }

    // …
}

Ok, the upper example with LazyListenerAggregate works only when the ‘event’ attribute is one of the MVC events (The MvcEvent).

When I have “custom” event then listener needs to be attached to Shared Event Manager.

Example of registering listeners:

<?php
namespace Order;

use Laminas\Config;
use Laminas\Mvc\MvcEvent;
use Laminas\EventManager\LazyListenerAggregate;
use Laminas\EventManager\LazyListener;
use Laminas\Mvc\Controller\AbstractController;

class Module
{

    public function onBootstrap(MvcEvent $event)
    {
        $application = $event->getApplication();
        $eventManager = $application->getEventManager();
        $serviceManager = $application->getServiceManager();

        // register Listener Aggregates
        $listener = $serviceManager->get(Event\HideDiscountListener::class);
        $listener->attach($eventManager);
        $listener = $serviceManager->get(Event\StopTerminListener::class);
        $listener->attach($eventManager);

        // register Lazy Listeners
        $definition = array(
            'listener' => Event\DemoLazyListener::class,
            'method' => 'onEchoVal'
        );
        $sharedEventManager = $eventManager->getSharedManager();
        $sharedEventManager->attach(AbstractController::class, 'echoVal',
            new LazyListener($definition, $serviceManager), - 100);
    }
    ...
}

shared

Thank you froschdesign.

1 Like