Welcome to Abdul Malik Ikhsan's Blog

Zend Framework 2 : Getting Closer with EventManager

Posted in Tutorial PHP, Zend Framework 2 by samsonasik on March 30, 2013

zf2-zendframework2I have posted a dozen of posts that utilize EventManager, but i think, it’s time to post detail about EventManager itself. Zend Framework 2 has component named EventManager. An EventManager is an object that aggregates listeners for one or more named events, and which triggers events, which a Listener is a callback ( closure, static method, typical array callback ) that can react to an event, and An Event is an action that is triggered by an EventManager.
This is a simple example :

use Zend\EventManager\EventManager;

$events = new EventManager;
$events->attach('do', function($e) {
    $event  = $e->getName();
    $params = $e->getParams();
    
    printf(
        'Handled event "%s" with parameter "%s"',
        $event,
        json_encode($params)
    );
});

$params = array('foo' => 'bar','baz' => 'bat');
$events->trigger('do', null, $params); //event, target, parameter
//print : Handled event "do" with parameter "{"foo":"bar","baz":"bat"}"

Features

  1. Wildcard Attachment
  2. Shared Manager
  3. Short-Circuiting
  4. Listener response Aggregation

Ok, let’s learn one by one.
1.Wildcard Attachment
We can attach to many events at once.
for example :

$events = new EventManager();
$events->attach(array('these', 'are', 'event', 'names'), $callback);

or using ‘*’ to make $callback available in all events.

$events = new EventManager();
$events->attach('*', $callback);

2.Shared Manager
This is to allow attaching to events when you don’t have access to the object. You should implements Zend\EventManager\EventManagerAwareInterface to make it run.
For example, we create a class like the following :

use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;

class Foo implements EventManagerAwareInterface 
{
    protected $events;
    
    public function setEventManager(EventManagerInterface $events) 
    {
        $this->events = $events;
        return $this;
    }
    
    public function getEventManager()
    {
        if (!$this->events) { 
             $this->setEventManager(new EventManager(__CLASS__)); 
        }
        return $this->events;
    }
    
    public function bar($baz, $bat = null) {
        $params = compact('baz', 'bat');
        $this->getEventManager()->trigger(__FUNCTION__, $this, $params);
    }
}

and you can attach to it by :

use Zend\EventManager\SharedEventManager;

$sharedEvent = new SharedEventManager;
$sharedEvent->attach('Foo', 'bar', function($e) {
    $event  = $e->getName();
    $target = get_class($e->getTarget());
    $params = json_encode($e->getParams());

    printf(
        '%s called on %s, using params %s',
        $event,
        $target,
        $params
    );
});

$foo = new Foo();
$foo->getEventManager()->setSharedManager($sharedEvent);
$foo->bar('bazvalue', 'batvalue');
//print : bar called on Foo, using params {"baz":"bazvalue","bat":"batvalue"} 

We can call other class too, let’s assume we have two class that had virtually no knowledge of each other.
Let’s create class 1 named Class1 :

use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;

class Class1 implements EventManagerAwareInterface {
    
    protected $events;
    
    public function setEventManager(EventManagerInterface $events) {
        $this->events = $events;
        return $this;
    }
    
    public function getEventManager() {
        if (!$this->events) { $this->setEventManager(new EventManager(__CLASS__)); }
        return $this->events;
    }
    
    public function run() {
        $this->getEventManager()->trigger('cls',$this);
    }
}

and class 2 named Class2 :

use Zend\EventManager\Event;
                    
class Class2 {
    public function listen(Event $e) {
        echo get_class($this) . ' has been called by ' . get_class($e->getTarget());
    }
}

Check it :

use Zend\EventManager\StaticEventManager;
                     
StaticEventManager::getInstance()->attach('Class1', 'cls', array(new Class2, 'listen'));
$cls = new Class1();
$cls->run();
 //print : Class2 has been called by Class1 

3.Short-Circuiting
This feature utilize if a particular result is obtained, or if a listener determines that something is wrong, or that it can return something quicker than the target.
for example, we have a class FooShortCircuit :

use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;

class FooShortCircuit implements EventManagerAwareInterface
{
    protected $events;
    
    public function setEventManager(EventManagerInterface $events) {
        $this->events = $events;
        return $this;
    }
    
    public function getEventManager() {
        if (!$this->events) { $this->setEventManager(new EventManager(__CLASS__)); }
        return $this->events;
    }
    
    public function execute($obj)
    {
        $argv = array();
        $results = $this->getEventManager()->triggerUntil(__FUNCTION__, $this, $argv,
                function($v) use ($obj) {
            return ($obj instanceof Foo); 
        });
         
        // if $obj instanceof foo, so stopped 
        if ($results->stopped()) {
            return $results->last();
        }
        // continue...
        echo 'hei, i\'m continue :p';
    }
}

if $obj in execute function instance of Foo class, it will stopped.
Let’s create a default execution :

$sharedEvent = new SharedEventManager;
$sharedEvent->attach('FooShortCircuit', 'execute', function($e) {
    echo 'standard execution...';
});

if we pass new Foo() to execute() function, it should execute ‘standard execution…’ only, and stopped. Let’s check it :

$fooShortCircuit = new FooShortCircuit;
$fooShortCircuit->getEventManager()->setSharedManager($sharedEvent);
$fooShortCircuit->execute(new Foo()) ;
//print : standard execution...

4.Listener response Aggregation
Single class can listen to multiple events.
For example, we have a class :

use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;

class Baz  implements EventManagerAwareInterface
{
     protected $events;
    
    public function setEventManager(EventManagerInterface $events) {
        $this->events = $events;
        return $this;
    }
    
    public function getEventManager() {
        if (!$this->events) { $this->setEventManager(new EventManager(__CLASS__)); }
        return $this->events;
    }
   
    public function get($id)
    {
        $params = compact('id');
        $results = $this->getEventManager()->trigger('Bar.pre', $this, $params);

        // If an event stopped propagation, return the value
        if ($results->stopped()) {
            return $results->last();
        }

        // do some work...

        $this->getEventManager()->trigger('Bar.post', $this, $params);
    }
}

and make a class that listen to multiple events.

use Zend\EventManager\ListenerAggregateInterface;
use Zend\EventManager\EventInterface;

class Bar implements ListenerAggregateInterface
{
    protected $listeners = array();
    
    public function attach(EventManagerInterface $e)
    {  
        $this->listeners[] = $e->attach('Bar.pre', array($this, 'load'));
        $this->listeners[] = $e->attach('Bar.post', array($this, 'save'));
    }
    
    public function detach(EventManagerInterface $e) 
    {
        foreach ($this->listeners as $index => $listener) {
            if ($e->detach($listener)) {
                unset($this->listeners[$index]);
            }
        }
    }
    
    public function load(EventInterface $e) { echo 'load...'; }
    public function save(EventInterface $e) { echo 'save...'; }
}

Let’s aggregate it :

$baz = new Baz;
$barListeners = new Bar;
$baz->getEventManager()->attachAggregate($barListeners);

$baz->get(1);

EventManager in ZF2 MVC Architecture
So, how EventManager works in ZF2 MVC Architecture ? Everything is an event !

  • A bootstrap is an Event
  • A Routing is an Event
  • A Dispatch is an Event
  • A Rendering View is an Event
  • etc

To make event triggered early, place it to init() function in Module.php

class Module
{ 
    public function init(ModuleManager $m)
    {
        $event = $m->getEventManager()->getSharedManager();
        $event->attach('Zend\Mvc\Application', 'bootstrap', function($e) { 
            echo 'executed on bootstrap app process <br />'; 
        });
    }
}

And if init() is too early, ModuleManager automatically registers the onBootstrap method if found in the module.

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $event = $e->getApplication()->getEventManager();
       
        $event->attach('route', function($e) {
            echo 'executed on route process'; 
        });

         $event->attach('dispatch', function($e) {
            echo 'executed on dispatch process'; 
         });

        $event->attach('dispatch.error', function($e) {
            echo $e->getParam('exception');
            echo 'executed only if found an error <br />,
            for ex : sm not found <br />'; 
        });

        $event->attach('render', function($e) {
            $e->getViewModel()->setVariable('test', 'test');
            echo 'executed on render process <br />';
        });

         $event->attach('render.error', function($e) {
            echo 'executed on render  error found'; 
         });

         $event->attach('finish', function($e) {
            echo 'executed on finish process'; 
         });
    }
}

A sample Use Case
We want to check if logged in, setting up the userid variable of controllers.

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $event->getSharedManager()
          ->attach('Zend\Mvc\Controller\AbstractActionController',
                    'dispatch', 
         function($e) {
              $controller = $e->getTarget();
    
             //check if logged in, setting up the userid variable of controllers
            if ($e->getApplication()->getServiceManager()->get('AuthService')
                                            ->hasIdentity()) {
                   $users = $e->getApplication()->getServiceManager()
                            ->get('SanAuth\Model\AuthStorage')->read();

                   $controller->userid = $users['id'];
             }
        }, 100);
    }
}

So Full ? make it separate…

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $event = $e->getApplication()->getEventManager();
        $event->getSharedManager()
          ->attach('Zend\Mvc\Controller\AbstractActionController',
                    'dispatch',
                array($this, 'settingUpControllerVariables'), 100
        );
    }

    public function settingUpControllerVariables(MvcEvent $e)
    {
        $controller = $e->getTarget();
    
        //check if logged in, setting up the userid variable of controllers
        if ($e->getApplication()->getServiceManager()
                            ->get('AuthService')
                            ->hasIdentity()) {
            $users = $e->getApplication()->getServiceManager()
                            ->get('SanAuth\Model\AuthStorage')->read();

            $controller->userid = $users['id'];
        }
    }
}

Hm…, i think it’s enough 😀

References :

66 Responses

Subscribe to comments with RSS.

  1. […] Zend Framework 2: Getting Closer With EventManager […]

  2. Onsite said, on March 31, 2013 at 12:56 am

    Great article!
    Are you going to make similar post about ServiceManager?

  3. Khiem said, on March 31, 2013 at 9:26 pm

    dear samsonasik,

    Thank you for your great article!

    I have a question that I want to put to you.

    Is there any relationship between setEventManager(), getControllerConfig() and OnBootstrap() ? Which of these is being called first? and then, and last?

    Because I read an article at: http://www.mwop.net/blog/2012-07-30-the-new-init.html , see the author attach dispatch event here, in setEventManager() and in getControllerConfig(), and we can also attach dispatch in OnBootstrap(), so I’m wondering which has the high priority?

    Thank you!

    • samsonasik said, on March 31, 2013 at 9:59 pm

      it should be based on the priority, if priority is negative, it should be executed after action dispatched. it based on event you used too. if you place it at ‘route’ event, it should be executed before action dispatched.

  4. Khiem said, on April 1, 2013 at 12:30 am

    Hi samsonasik,
    We register to listen to ‘dispatch’ event onBootstrap() function. In this case, it will check authentication is valid or not. Is it OK if I put all check-authentication-code in onDispatch() function like ZF 1? I think It should be run because Zend\Mvc\AbstractController has already register to listen to ‘dispatch’ event which is triggered by Application class. When this event triggers, onDispatch() function in AbstractController should be called. Do you have any idea?

    Thank you!

    • samsonasik said, on April 1, 2013 at 12:46 am

      I think what you mean is authorization. if yes, the answer is “No”. use at ‘route’ event, it should executed before dispatched action for security reason.

      public function onBootstrap(MvcEvent $e)
      {
              //load ACL
              $eventManager->attach('route', array($this, 'loadAcl'));
      }
      
      public function loadAcl(MvcEvent $e)
      {
            	$controller = $e->getTarget();
              $controllerClass = get_class($controller);
              $namespace = substr($controllerClass, 0, strpos($controllerClass, '\\'));
      
             //check ACL here....
      }
      
      • Khiem said, on April 1, 2013 at 1:22 am

        Thanks for your answer! It helps me understand more about ‘route’ event.
        Correct me if I’m wrong. (And sorry for my English if there is anything make you confusing).

        I have some ideas to make thing clearer.

        We have 2 jobs here. Check for ACL and check for already logging or not.

        Sometime, user don’t need to log in to visit our site, we call that ‘anonymous’ and of course, their rights are restricted. If they’ve already logged in, their right will change. We do this functionality with ‘route’ event. (like the comment above).

        But before that we have to check if user log in or not in some page that user have to login before visiting. We do this functionality with ‘dispatch’ event, right? In your article, you attach such that code in OnBootstrap() function in Module.php file. It’s OK. Code following:

        $event->getSharedManager()
        ->attach(‘Zend\Mvc\Controller\AbstractActionController’,
        ‘dispatch’,
        function($e) {
        $controller = $e->getTarget();

        //check if logged in, setting up the userid variable of controllers
        if ($e->getApplication()->getServiceManager()->get(‘AuthService’)
        ->hasIdentity()) {
        $users = $e->getApplication()->getServiceManager()
        ->get(‘SanAuth\Model\AuthStorage’)->read();

        $controller->userid = $users[‘id’];
        }
        });
        }

        My question is: Can I override the function onDispatch() of AbstractActionController Class like this:

        public function onDispatch(MvcEvent $e) {
        if ($e->getApplication()->getServiceManager()->get(‘AuthService’)
        ->hasIdentity()) {
        $users = $e->getApplication()->getServiceManager()
        ->get(‘SanAuth\Model\AuthStorage’)->read();

        $controller->userid = $users[‘id’];
        }
        }

        like ZF 1.

        If so, is there any problem with that way?

        Thank you so much!

      • samsonasik said, on April 1, 2013 at 1:38 am

        if i’m not missunderstand your question. yes, you can. use something like this :

        namespace YourModule\Controller;
        
        use Zend\Mvc\Controller\AbstractActionController;
        use Zend\Mvc\MvcEvent;
        
        class YourController extends AbstractActionController
        {
            public function onDispatch(MvcEvent $e)
            {
                //do something before dispatch...    
                
                parent::onDispatch($e); //call parent so parent is still executed.
                
                //do something after dispatch...
            }
        }
        

        and No. i’m the one that poor in English. so pardon me 😉

  5. Khiem said, on April 1, 2013 at 1:47 am

    Thank you!

    I’ve just run it. I works well. Just one thing more. what do we do at ‘//do something after dispatch…’ above?

    Thank you again. 🙂 You always have good articles about Zend 2. I’m working on Zend 2 project now and you help me out a lot through series of your article.

    • samsonasik said, on April 1, 2013 at 1:51 am

      you’re welcome. it means, if you want to execute something that happen before view rendered, but after action code ( before return viewmodel), you can place on it.

  6. Khiem said, on April 1, 2013 at 9:38 pm

    Sorry to bother you, samsonasik,

    I follow you instruction in https://samsonasik.wordpress.com/2012/08/23/zend-framework-2-controllerpluginmanager-append-controller-pluginto-all-controller/, I add redirection in else condition if hasIdentity() failed. Like the following:

    if($e->getApplication()->getServiceManager()
    ->get(‘AuthService’)->hasIdentity())
    {
    $users = $e->getApplication()->getServiceManager()->get(‘User\Model\TtkAuthStorage’)->read();
    }
    else
    {
    $url = $e->getRouter()->assemble(array(‘controller’=>’auth’, ‘action’=>’index’), array(‘name’ => ‘user/process’));

    $response = $e->getResponse();

    $response->setStatusCode(302);

    $response->getHeaders()->addHeaderLine(‘Location’, $url);

    $e->stopPropagation(true);

    return $response;
    }
    But It acts weirdly. http://zf2-dev.localhost/user/auth/login don’t redirect.

    The browser says: Firefox has detected that the server is redirecting the request for this address in a way that will never complete.

    Could you help me?

    Thank you!

    • samsonasik said, on April 2, 2013 at 11:45 pm

      check your route !

      • Khiem said, on April 3, 2013 at 10:58 am

        Not make sense, samsonasik.

        I guest the problem here is: when we redirect to user/auth/login, it still catches ‘dispatch’ event. Because hasIdentity() still returns false so we redirect to user/auth/login repeatedly. We don’t have code to check if it’s already in user/auth/login, stop check for hasIdentity(). Let me give it a try!

        Thank you!

  7. Onsite said, on April 2, 2013 at 5:10 pm

    When I’m using:
    $users = $e->getApplication()->getServiceManager()
    ->get(‘Zend\Authentication\Storage\Session’)->read();
    I get error:
    Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Zend\Authentication\Storage\Session

    Any idea why is that?

    • samsonasik said, on April 2, 2013 at 5:40 pm

      not every component registered in ZF2 ServiceManager. extends and register yourself first.

  8. Khiem said, on April 2, 2013 at 10:57 pm

    Hi samsonasik,
    Is it possible If I load a module on my own, not let the module name in application.config.php file. In fact I want store all modules name in database.

    • samsonasik said, on April 2, 2013 at 11:41 pm

      yes, just change in index.php :

      Zend\Mvc\Application::init(require 'config/application.config.php')->run();
      

      with something like this :

      $configuration = require 'config/application.config.php';
      
      use Zend\Db\Adapter\Adapter;
      
      $adapter = new Zend\Db\Adapter\Adapter(array(
          'driver'   => 'pdo_pgsql',
          'database' => 'zf2',
          'username' => 'developer',
          'password' => '123456'
      ));
      
      use Zend\Db\TableGateway\TableGateway;
      use Zend\Db\ResultSet\HydratingResultSet;
      
      $modulesTable = new TableGateway('modules_table', $adapter, null,new HydratingResultSet());
      $rowset = $modulesTable->select()->toArray();
      
      $modules = array();
      foreach($rowset as $row)
      {
          $modules[] = $row['module_name_in_your_db'];
      }
      
      //set array of modules...
      $configuration['modules'] = $modules;
      $smConfig = isset($configuration['service_manager']) ? $configuration['service_manager'] : array();
      $serviceManager = new ServiceManager(new Service\ServiceManagerConfig($smConfig));
      $serviceManager->setService('ApplicationConfig', $configuration);
      $serviceManager->get('ModuleManager')->loadModules();
      
      //run the app
      $serviceManager->get('Application')->bootstrap()->run();
      
      • Khiem said, on April 2, 2013 at 11:46 pm

        Thank you million times!

      • samsonasik said, on April 2, 2013 at 11:52 pm

        you’re welcome 😉

      • Khiem said, on April 2, 2013 at 11:56 pm

        I’ve tried to do lot of things like: catch ‘loadmodules’ event, get ModuleManager and then call its loadModule() function but it all does not make sense. In daily work, I usually get Database Adapter via Service Manager, so I think we can not get Adapter at the very early time before the Application bootstrap so that we have not had Service Manager yet. Your way is the key I need. Thank you!

  9. tmquang said, on April 3, 2013 at 2:57 pm

    Dear Samsonasik,

    I try to code my project example with your tutorial above, but I simple assign variable to controller like that.

    class Module
    {

    public function onBootstrap(MvcEvent $e)
    {
    $e->getApplication()
    ->getEventManager()
    ->getSharedManager()
    ->attach(‘Zend\Mvc\Controller\AbstractActionController’, ‘dispatch’, function($e)
    {

    $controller = $e->getTarget();

    $controller->test = ‘hello world’;
    }
    );

    $eventManager = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);
    }
    }

    And in my IndexController, indexAction, I wanna get ‘test’ has been assigned, but I cannot get it, it return NULL. Below that’s my code:
    class IndexController extends AbstractActionController
    {

    public function indexAction()
    {
    var_dump($this->test);
    return new ViewModel();
    }
    }

    And result display on browser
    Notice: Undefined property: Application\Controller\IndexController::$test
    NULL

    What’s wrong with my code. Can you help me or suggestion.
    Thanks and best regard,

  10. samsonasik said, on April 3, 2013 at 3:43 pm

    Ooops, i forgot to mention a priority. pass a priority to attaching event.

    $e->getApplication()->getEventManager()
       ->getSharedManager()
       ->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', function($e) {
           $controller = $e->getTarget();
           $controller->test = 'hello world';
    }, 100);
    

    post updated.

    • tmquang said, on April 3, 2013 at 4:08 pm

      Thanks Samsonasik, I done it. By the way, let me ask “why do you choose priority = 100? What else priority?”

      • samsonasik said, on April 3, 2013 at 4:15 pm

        priority is positive and negative, you can set as your own, 999 maybe. higher, will be serve first.

  11. tmquang said, on April 3, 2013 at 4:26 pm

    Thanks your explaination.

  12. Mohammed Abuelezz said, on April 8, 2013 at 2:36 am

    @samsonasik you are awesome, it seems that you are helping all people here, ZF2 lucky that such person like you write an articles about it 🙂

    • samsonasik said, on April 8, 2013 at 3:37 am

      thanks 😉

      • heik said, on June 11, 2013 at 4:23 am

        @samsonasik: thanks from my side too! i found a lot of good hints in your posts around here that finally initiated the *click* in my head.

        Keep it up – already bookmarked this blog 😉

      • samsonasik said, on June 11, 2013 at 4:53 am

        you’re welcome ;). Yes, I will 😉

  13. […] Zend Framework 2: Getting Closer With EventManager […]

  14. leonv said, on June 15, 2013 at 12:22 am

    @samsonasik, thanks for the article.

    A quick question. If one attaches events inside onBootstrap without using the SharedManager, does it only apply to MvcEvents, i.e. route, dispatch, dispatch.error etc?

    • samsonasik said, on June 15, 2013 at 12:59 am

      no. as far the class implement EventManagerAwareInterface, you can do it to attach other class.

  15. srushti said, on June 24, 2013 at 12:51 am

    great article!!helped me understand event manger better..thnx 🙂

  16. George said, on September 20, 2013 at 8:42 pm

    Great work! Now how about an event that is triggered on all events in a single Module. Something like a front controller plugin. Because everything I put in any module.php gets trigered across the entire application, all modules.

    • samsonasik said, on September 21, 2013 at 1:11 pm
          public function onBootstrap(MvcEvent $e)
          {
              $eventManager        = $e->getApplication()->getEventManager();
              $sharedEventManager  = $eventManager->getSharedManager();
              
              $sharedEventManager->attach(__NAMESPACE__, '*', function($e) {
                  echo 'hei';            
              });
          }
      
  17. tmquang6805 said, on October 4, 2013 at 5:33 pm

    Hi Samsonasik,

    Can you help me get Service Locator when attach Event.
    My code is below
    class Attributes implements ListenerAggregateInterface
    {

    protected $_service;

    protected $_listeners = array();

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

    public function attach(EventManagerInterface $events)
    {
    $anotherService = $this->_service->get(‘AnotherService’);

    // Listener for event add new attribute
    $this->_listeners[] = $events
    ->getSharedManager()
    ->attach(‘Background\Model\AbstractModel’, ‘addNewAttribute.post’, function ($e) use ($anotherService)
    {
    /* Execute event */
    }, -10);
    }

    public function detach(EventManagerInterface $events)
    {
    foreach ($this->_listeners as $index => $listener)
    {
    if ($events->detach($listener))
    {
    unset($this->_listeners[$index]);
    }
    }
    }

    }
    In lambda function, can I use $e to get Service Locator. Thanks so much

    • samsonasik said, on October 4, 2013 at 5:59 pm

      the easiest way to pass $this->_service that you’ve assign at __construct.

      $events
          ->getSharedManager()
          ->attach("Background\Model\AbstractModel", "addNewAttribute.post", function ($e) use ($this->_service) {
              
              $serviceManager = $this->_service;
              $anotherService = $serviceManager->get(‘AnotherService’);
              
      }, -10);
      
      • tmquang6805 said, on October 4, 2013 at 8:27 pm

        That means Event Object cann’t get Service Locator directly?

      • samsonasik said, on October 5, 2013 at 12:04 am

        as far as $e represent MvcEvent, then we can call via $e->getTarget()->getServiceLocator() or $e->getApplication()->getServiceLocator(). we often see it at Module::onBootstrap. so the answer is depend $e represent of.

  18. tmquang6805 said, on October 5, 2013 at 9:04 am

    Thanks so much Samsonasik, I got it. 🙂

  19. Been pink said, on December 17, 2013 at 10:22 am

    terima kasih pak atas pencerahannya 😀

  20. tmquang6805 said, on December 19, 2013 at 10:27 am

    Dear Samsonasik,

    Can you help me to explain: what is “callback” parameter (4th parameter) in trigger function? When use it? Can you show me example for it?

    Thank so lot.

    • samsonasik said, on December 29, 2013 at 2:57 am

      callback on this case is a term for something that react to event, it can be closure, static method, or typical array callback

  21. chirag said, on December 28, 2013 at 4:39 pm

    I want to access this $controller->userid outside means layout.phtml file. but its value cant get why?

    • samsonasik said, on December 29, 2013 at 2:55 am

      you can set controller var via layout with

      $this->layout()->userid = "the user id";
      

      and got it from layout :

      echo $this->layout()->userid ;
      
  22. chirag said, on December 30, 2013 at 12:10 pm

    I am using this method

    public function onBootstrap(MvcEvent $e)
    {
    $event = $e->getApplication()->getEventManager();
    $event->getSharedManager()
    ->attach(‘Zend\Mvc\Controller\AbstractActionController’,
    ‘dispatch’,
    array($this, ‘settingUpControllerVariables’), 100
    );
    }

    public function settingUpControllerVariables(MvcEvent $e)
    {
    $controller = $e->getTarget();

    //check if logged in, setting up the userid variable of controllers
    if ($e->getApplication()->getServiceManager()
    ->get(‘AuthService’)
    ->hasIdentity()) {
    $users = $e->getApplication()->getServiceManager()
    ->get(‘SanAuth\Model\AuthStorage’)->read();

    $controller->userid = $users[‘id’];
    $e->getViewModel()->setVariable(‘user_data’, $controller->userid);
    }
    }

    I want to this $controller->userid outside means my layout file and also in my footer file. Thanks in Advance.

  23. Dennis said, on February 18, 2014 at 9:10 pm

    Hi, if you often use ListenerAggregates you could extend Zend\EventManager\AbstractListenerAggregate

  24. mohamed said, on April 21, 2014 at 1:39 am

    i need to load module from another module

    Say i have Modules A,B

    how to load module “B” From Module “A” but not through application.config.php

  25. BehRang said, on July 20, 2014 at 8:14 pm

    samsonasik,
    Greate article about event managers

  26. Denis said, on August 7, 2014 at 1:44 pm

    I read MANUAL and I found Modifying Arguments, I understand that is good Idea, but i don’t understand how i can use it

  27. nomaanp153 said, on March 4, 2015 at 8:41 pm

    Hello Samsonasik,

    Stuck in a problem where I would like to append a query string such as ?id=somestring to each and every url. There are around 150 to 200 urls in application. So Is there a way to do it using event (route).

    Waiting for your reply.

    • samsonasik said, on March 4, 2015 at 9:17 pm

      probably you could do this :

          public function onBootstrap($e)
          {
              $e->getTarget()->getEventManager()
                ->attach('route', array($this, 'redirectId'));
          }
          
          public function redirectId($e)
          {
              $uri = $e->getRequest()->getUri();
              if (strpos($uri, "?id=something") === FALSE) {
                  $newUri = $uri . "?id=something";
      
                  $e->getResponse()->setStatusCode(301)
                    ->getHeaders()->addHeaderLine('Location', $newUri);
              }
          }
      

Leave a reply to samsonasik Cancel reply