I am currently learning/experimenting with the stable version of ZF2. The last couple of days has been used trying to find a solution to my problem, which is: I want to be able to write some setup logic general to a set of controllers. In ZF! I would then just write a general controller and derive from it, using the init() method for my setup logic. After a bit of searching I found that the init() method was removed in ZF2 and that there were alternative approaches to get the same functionality.
I tried to follow the guide by M. W. O'Phinney: http://mwop.net/blog/2012-07-30-the-new-init.html
In my case I have to be able to retrieve and check route params for my setup logic, so the method overriding alternatives didn't work due to one not having access to the MvcEvent at that point. So, I tried the Update: serviceManager solution, and this is where I got stuck. First I just tried to copy the code from the guide into my Module class and echo some text to see if the callback was at all called. Which it isn't.
After more searching on the web i found a possible solution; attaching the callback in the constructor of the general controller. The same problem appeared to be here as well. The constructor gets called of course, but the callback is either not attached or triggered properly (or at all).
I'll attach some of my code from the two different solutions:
In Module.php:
public function getControllerConfig() {
return array(
'factories' => array(
'Game\Controller\Mapsquare' => function($controllers) {
$serviceManager = $controllers->getServiceLocator();
$eventManager = $serviceManager->get('EventManager');
$controller = new Controller\MapsquareController();
echo "this text is echoed";
$eventManager->attach('dispatch', function ($e) use ($controller) {
echo "this text is NOT echoed";
$request = $e->getRequest();
$method = $request->getMethod();
if (!in_array($method, array('PUT', 'DELETE', 'PATCH'))) {
// nothing to do
return;
}
if ($controller->params()->fromRoute('id', false)) {
// nothing to do
return;
}
// Missing identifier! Redirect.
return $controller->redirect()->toRoute(/* ... */);
}, 100); // execute before executing action logic
$controller->setEventManager($eventManager);
return $controller;
}
)
);
}
In MapsquareController.php (the general controller):
public function __construct() {
$this->getEventManager()->attach('dispatch', array($this, 'preDispatch'), 1000);
echo "construct";
}
public function preDispatch() {
echo "This is preDispatch()!";
}
Is there someone out there that can help me with this problem, eventually tell what I'm missunderstanding here? Any help is appreciated :)
You cannot attach to dispatch from a factory because factory is called a long time after the dispatch has been processed.
To make it work, open your Module.php and edit onBootstrap(), so that you attach there. For example:
public function onBootstrap($e)
{
...
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach("dispatch", function($e) {
echo "Dispatch!";
});
}
Alternatively, you can also do this from a specific controller. Not in the constructor, but by overriding setEventManager:
public function setEventManager(EventManagerInterface $events) {
parent::setEventManager($events);
$controller = $this;
$events->attach("dispatch", function($e) use ($controller) {
echo "Dispatch!";
});
}
Hope this helps!