Search code examples
eventszend-framework3

Zend SharedEventManager attaching custom target


I'm playing with SharedEventManager here is a working portion of code :

public function init(ModuleManager $moduleManager) {
        echo("<H1>LISTENER</H1>");

        $eventManager = $moduleManager->getEventManager(); 
        $sharedEventManager=$eventManager->getSharedManager();

        // attach a listener        
        $sharedEventManager->attach('*','do', function ($e) {
         echo("<H4>Message receveid</H4>");   
         echo("<p>name={$e->getName()}<p>");
         echo("<p>Target {$e->getTarget()}</p>");
         echo("<p>param1={$e->getParams()['param1']}</p>");
        });

        // sending event
        //  set params        
        $params = ['param1' => 'value of param1'];
        //  way 1 : works...
        $eventManager->trigger('do', 'CUSTOM_IDENTIFIER', $params);
        //  way 2 : works too
        $event1=new  \Zend\EventManager\Event('do', 'CUSTOM_IDENTIFIER', $params);
        $eventManager->triggerEvent($event1);
    }

and the output is ok :

LISTENER
Message receveid
name=do
Target CUSTOM_IDENTIFIER
param1=value of param1
Message receveid
name=do
Target CUSTOM_IDENTIFIER
param1=value of param1

so... $sharedEventManager->attach('*','do', function ($e) ... attach all targets *, for 'do' event name it works...

A)

 $sharedEventManager->attach('CUSTOM_IDENTIFIER','do', function ($e) ...

it doesn't work. ...i mean : no output , the message is not handled, why ??

B)

 $sharedEventManager->attach('CUSTOM_IDENTIFIER','*', function ($e) ...

it doesn't work. ...i mean : no output , the message is not handled, why ??

Question : it is possible to attach events but only for CUSTOM_IDENTIFIER target without using * ?


Solution

  • Looking at your code, you are mixing Event's target and SharedEventManager's identifiers.

    The correct version of your code, with correct names, is:

    public function init(ModuleManager $moduleManager) {
        echo("<H1>LISTENER</H1>");
    
        $eventManager = $moduleManager->getEventManager();
        $sharedEventManager = $eventManager->getSharedManager();
    
        // attach a listener        
        $identifier = '*'; // Use all identifiers
        $eventName = 'do';
        $sharedEventManager->attach($identifier, $eventName, function ($e) {
            echo '<p>Event received, <b>name:</b> "'.$e->getName().'", <b>Target:</b> '.$e->getTarget().'</p>';
        });
    
        // Sending event
        $eventManager->trigger('do', 'CUSTOM_TARGET');
        $eventManager->triggerEvent(new \Zend\EventManager\Event('do', 'CUSTOM_TARGET_NEW_EVENT'));
    
    }
    

    Which gives the following result:

    LISTENER
    Event received, name: "do", Target: CUSTOM_TARGET
    Event received, name: "do", Target: CUSTOM_TARGET_NEW_EVENT
    

    You must set the identifier to the EventManager, otherwise your CUSTOM_IDENTIFIER won't be used when the event will be triggered.

    public function init(ModuleManager $moduleManager) {
        echo("<H1>LISTENER</H1>");
    
        $eventManager = $moduleManager->getEventManager();
        $sharedEventManager = $eventManager->getSharedManager();
    
        // Attach listener to all identifiers       
        $identifier = '*'; // Use all identifiers
        $eventName = 'do';
        $sharedEventManager->attach($identifier, $eventName, function ($e) {
            echo '<p>ALL identifier, Event received, <b>name:</b> "'.$e->getName().'", <b>Target:</b> '.$e->getTarget().'</p>';
        });       
        // Attach listener to custom identifier
        $customIdentifier = 'MY_CUSTOM_IDENTIFIER'; // Use all identifiers
        $sharedEventManager->attach($customIdentifier, $eventName, function ($e) {
            echo '<p>Custom identifier, Event received, <b>name:</b> "'.$e->getName().'", <b>Target:</b> '.$e->getTarget().'</p>';
        });
    
        // Sending event
        $eventManager->trigger('do', 'CUSTOM_TARGET');
        $eventManager->triggerEvent(new \Zend\EventManager\Event('do', 'CUSTOM_TARGET_NEW_EVENT'));
    
        $eventManager->addIdentifiers(['MY_CUSTOM_IDENTIFIER']);
        $eventManager->trigger('do', 'CUSTOM_TARGET_CUSTOM_IDENTIFIER');
        $eventManager->triggerEvent(new \Zend\EventManager\Event('do', 'CUSTOM_TARGET_CUSTOM_IDENTIFIER_NEW_EVENT'));
    
    }
    

    The result is:

    LISTENER
    ALL identifier, Event received, name: "do", Target: CUSTOM_TARGET
    ALL identifier, Event received, name: "do", Target: CUSTOM_TARGET_NEW_EVENT
    Custom identifier, Event received, name: "do", Target: CUSTOM_TARGET_CUSTOM_IDENTIFIER
    ALL identifier, Event received, name: "do", Target: CUSTOM_TARGET_CUSTOM_IDENTIFIER
    Custom identifier, Event received, name: "do", Target: CUSTOM_TARGET_CUSTOM_IDENTIFIER_NEW_EVENT
    ALL identifier, Event received, name: "do", Target: CUSTOM_TARGET_CUSTOM_IDENTIFIER_NEW_EVENT
    

    As you can see, the identifier * catches all events (therefore, the 4 lines of ALL identifier), whilst there are only 2 lines for the custom identifier.

    Obviously, it'd be better to use a better (and more comprehensible) custom identifier, such as a class name, or an interface.

    Hope this will help you