@Jeremiah you can fetch it and add it to the documentation yourself ;) Marco Pivetta
http://twitter.com/Ocramius http://ocramius.github.com/ On 15 May 2013 18:33, Jeremiah Small <m...@jsmall.us> wrote: > This is a very useful post. > > Is the application flow map that Evan Coury created as a Google Doc going > to get updated and folded into the documentation? > > I found that very useful, but it fell out of date in the beta rounds. It > would be a great addition to the docs, because it's very hard to know what > events will fire when without it. > > Jeremiah > > On May 13, 2013, at 4:40 AM, Matthew Weier O'Phinney wrote: > > > On Mon, May 13, 2013 at 12:20 AM, David Muir <davidkm...@gmail.com> > wrote: > >> On 10/05/13 23:11, Michael Gooden wrote: > >>> It should not be firing twice, however you are trying to use the shared > >>> event manager the wrong way. > >>> > >>> If you want to have a listener fire for EVERY dispatch ever, then just > >>> attach to normal event manager on EVENT_DISPATCH in one place. If you > attach > >>> it in the MyModule it will still fire when you access a controller in > the > >>> Application module. Is that what you need? > >> > >> > >> It was more as an experiment to see what would happen. I was more > confused > >> by different tutorials showing listeners being attached to the > EventManager > >> and the SharedEventManager without explaining why one should be used > over > >> the other. > >> > >> As for firing twice, I agree, that shouldn't be happening, but > >> Zend\Mvc\Application.php triggers MvcEvent::EVENT_DISPATCH on line 309 > and > >> Zend\Mvc\Controller\AbstractController triggers it on line 115. > >> In my opinion this is a bug, and those should be two separate events, > but > >> there's probably not much that can be done about it now without > breaking BC. > > > > They *ARE* two separate events, that simply happen to be named the same. > > > > What do I mean? > > > > Each object composes its own EventManager instance. This is not > > shared, and the fact that the instance is not shared is purposeful: > > it's to allow each object to trigger isolated events, as well as to > > prevent naming collisions. This latter is important -- you can have > > the same event name in multiple objects, but they will not trigger the > > same listeners due to the fact that the EM instances are separate. > > > > If you want a listener to trigger for the same event name on different > > objects, you have two choices: > > > > - attach to each object's EM instance separately > > - attach to the SharedEventManager, specifying identifiers for each > object > > > > The SharedEventManager is a shared container passed to all EM > > instances that were originally pulled from the ServiceManager. This > > object allows listeners to attach to events on objects with specific > > identifiers; when an event is triggered, the event manager will query > > the SharedEventManager to see if it has any listeners on identifiers > > it is interested in that correspond to the current event; if so, it > > will trigger those, too. > > > > This explains your original question: > > > >> Can someone explain why the shared event listener attached via the > Application module never gets called? > > > > When you attached to the SharedEventManager, you were attaching the > > the identifier "Application", which will only get triggered by an > > object that has the identifier "Application" -- most likely, this will > > be a controller, as the default controller implementations will add > > their top-level namespace as an event identifier. > > (Zend\Mvc\Application does not itself define that identifier, but > > instead the identifier "Zend\Mvc\Application".) > > > > You also ask the following: > > > >> Secondary to this, I've seen some examples attach listeners to the > shared manager, and others attach them to the event manager. When do I use > one instead of the other? > > > > The general rule of thumb is: > > > > - If you already have direct access to an object, and want to attach > > listeners to it, use its composed EventManager directly. > > - If you do not already have direct access to an object, or do not > > know if it will even come into scope in the current request, use the > > SharedEventManager to attach listeners. > > > > So, as concrete examples: Let's say I want to attach an event to > > trigger when routing has finished. I will generally do this during the > > bootstrap event from within my module. Inside a bootstrap listener, I > > can access the Application instance directly via either > > $e->getTarget() or $e->getApplication(). Since the route event is > > triggered directly by the Application instance, I can attach directly > > to its EM instance: > > > > $application = $e->getTarget(); > > $events = $application->getEventManager(); > > $events->attach('route', $callback, -10); > > > > Now let's say I want to attach a listener to an event triggered by a > > domain model. I don't know yet if that model will be used in this > > request, much less if the controller that will communicate with it > > will be selected. As such, I'll use the SharedEventManager, which I > > will pull from the EM instance composed in the Application instance. > > > > $application = $e->getTarget(); > > $events = $application->getEventManager(); > > $sharedEvents = $events->getSharedManager(); > > $sharedEvents->attach('My\Domain\Model', 'fetch', $callback); > > > > Hopefully that answers the questions you have! > > > >> > >> Cheers, > >> David > >> > >>> > >>> Cheers, > >>> > >>> Michael > >>> > >>> > >>> > >>> On 10 May 2013 15:01, David Muir <davidkm...@gmail.com > >>> <mailto:davidkm...@gmail.com>> wrote: > >>> > >>> Michael, > >>> > >>> Thanks for the explanation. It does explain the issue I have having. > >>> > >>> So the gist is: > >>> > >>>> $sharedEvents->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH > >>>> > >>> > >>> means that this even will only be triggered if the context is that > >>> namespace. So the one in Application will fire if the context is > >>> "Application" and the one in MyModule will fire if the context is > >>> "MyModule". > >>> > >>> So as an experiment, in Application I tried attaching a listener > >>> to 'MyModule' instead of __NAMESPACE__ and it work as expected. It > >>> only fires when hitting a controller in MyModule. > >>> > >>> But what if I want to attach something that is triggered in all > >>> contexts on the dispatch event? I tried using the * wildcard, but > >>> now the shared listeners get hit twice: > >>> > >>> shared event listener from application module called > >>> shared event listener from my module called > >>> event listener from application module called > >>> event listener from my module called > >>> shared event listener from application module called > >>> shared event listener from my module called > >>> > >>> If my understanding is correct, this happens because there are two > >>> EventManager involved. First is the Application's EventManager, > >>> which first triggers the shared events, then triggers the local > >>> events. Then the controller itself triggers > >>> MvcEvent::EVENT_DISPATCH on its own EventManager instance when the > >>> controller's dispatch() method gets called. This in turn triggers > >>> the shared events a 2nd time. > >>> > >>> I guess I got exactly what I asked for, but wasn't > >>> expecting MvcEvent::EVENT_DISPATCH to be triggered twice. Kind of > >>> feels wrong... > >>> > >>> Cheers, > >>> David > >>> > >>> On 10/05/2013, at 4:46 PM, Michael Gooden > >>> <mich...@bluepointweb.com <mailto:mich...@bluepointweb.com>> wrote: > >>> > >>>> Hi David, > >>>> > >>>> Keep in mind that you are working with the Zend\Mvc\Application's > >>>> EventManager instance. Try and follow the code execution in the > >>>> Application::run() function, to see when and why different events > >>>> fire. > >>>> > >>>> I would hazard a guess and say that you are accessing a > >>>> controller in the MyModule, and not in the main Application > >>>> module. If you run a controller from the Application module, you > >>>> will then see the 'shared event from application' message show > >>>> instead of from mymodule. The reason this is happening is because > >>>> the shared event manager listener you are attaching is listening > >>>> for the event identifier of __NAMESPACE__. When the dispatch > >>>> event gets called against a controller under MyModule, only the > >>>> listener tied to the namespace of that controller will be fired. > >>>> The reason you will always see both normal event listener > >>>> messages is because those listeners are both attached to the > >>>> dispatch event. > >>>> > >>>> I feel I am failing at explaining this, can you add me on Skype? > >>>> > >>>> Cheers, > >>>> > >>>> Michael Gooden > >>>> > >>>> > >>>> On 10 May 2013 03:41, David Muir <davidkm...@gmail.com > >>>> <mailto:davidkm...@gmail.com>> wrote: > >>>> > >>>> I'm getting some weird behaviour with the EventManager and > >>>> SharedEventManager when used in the Application module vs > >>>> other modules. > >>>> > >>>> Application Module: > >>>> > >>>> public function onBootstrap(MvcEvent $e) > >>>> { > >>>> //$e->getApplication()->getServiceManager()->get('translator'); > >>>> $eventManager = > >>>> $e->getApplication()->getEventManager(); > >>>> $moduleRouteListener = new ModuleRouteListener(); > >>>> $moduleRouteListener->attach($eventManager); > >>>> > >>>> $eventManager->attach(MvcEvent::EVENT_DISPATCH, function > >>>> ($event){ > >>>> echo 'event listener from application module > >>>> called' . PHP_EOL; > >>>> }); > >>>> > >>>> $sharedEvents = $eventManager->getSharedManager(); > >>>> > >>>> $sharedEvents->attach(__NAMESPACE__, > >>>> MvcEvent::EVENT_DISPATCH, function ($event){ > >>>> echo 'shared event listener from application > >>>> module called'. PHP_EOL; > >>>> }); > >>>> > >>>> } > >>>> > >>>> > >>>> My Module: > >>>> > >>>> public function onBootstrap(\Zend\EventManager\EventInterface > $e) > >>>> { > >>>> > >>>> $eventManager = > >>>> $e->getApplication()->getEventManager(); > >>>> $sharedEvents = $eventManager-> getSharedManager(); > >>>> > >>>> $eventManager->attach(MvcEvent::EVENT_DISPATCH, function > >>>> ($event){ > >>>> echo 'event listener from my module > called'.PHP_EOL; > >>>> }); > >>>> > >>>> $sharedEvents->attach(__NAMESPACE__, > >>>> MvcEvent::EVENT_DISPATCH, function ($event){ > >>>> echo 'shared event listener from my module > >>>> called'.PHP_EOL; > >>>> }); > >>>> > >>>> } > >>>> > >>>> > >>>> > >>>> outputs: > >>>> > >>>> shared event listener from my module called > >>>> event listener from application module called > >>>> event listener from my module called > >>>> > >>>> > >>>> Can someone explain why the shared event listener attached > >>>> via the Application module never gets called? > >>>> > >>>> Secondary to this, I've seen some examples attach listeners > >>>> to the shared manager, and others attach them to the event > >>>> manager. When do I use one instead of the other? > >>>> > >>>> Cheers, > >>>> David > >>>> > >>>> > >>>> -- > >>>> List: fw-general@lists.zend.com > >>>> <mailto:fw-general@lists.zend.com> > >>>> > >>>> Info: http://framework.zend.com/archives > >>>> Unsubscribe: fw-general-unsubscr...@lists.zend.com > >>>> <mailto:fw-general-unsubscr...@lists.zend.com> > >>>> > >>>> > >>>> > >>> > >>> > >> > > > > > > > > -- > > Matthew Weier O'Phinney > > Project Lead | matt...@zend.com > > Zend Framework | http://framework.zend.com/ > > PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc > > > > -- > > List: fw-general@lists.zend.com > > Info: http://framework.zend.com/archives > > Unsubscribe: fw-general-unsubscr...@lists.zend.com > > > > > > > -- > List: fw-general@lists.zend.com > Info: http://framework.zend.com/archives > Unsubscribe: fw-general-unsubscr...@lists.zend.com > > >