zend-framework2zend-framework-mvczend-framework-moduleszend-framework-routing

ZF2: How to attach listener on the event in the Module class?


I want to set a basePath to be the same for every component of my Mvc for a given request. I mean when I call these methods I want to get the same result, lets say '/spam/ham/':

echo $this->headLink()->prependStylesheet($this->basePath() . '/styles.css')  // $this->basePath() has to be '/spam/ham/'

$this->getServiceLocator()
     ->get('viewhelpermanager')
     ->get('headLink')
     ->rependStylesheet($this->getRequest()->getBasePath() . '/styles.css')   // $this->setRequest()->getBasePath() has to be /spam/ham/

How to set the basePath for the first case I have found already, here's my question. By the way, the original manual doesn't have any info I received from the answer.

And now the second one - the basePath has to be set in the Request:

$this->getRequest()->getBasePath()

Here I found some answer that in fact doesn't work at all http://zend-framework-community.634137.n4.nabble.com/Setting-the-base-url-in-ZF2-MVC-td3946284.html. As said here StaticEventManager is deprecated so I changed it with SharedEventManager :

// In my Application\Module.php

namespace Application;
use Zend\EventManager\SharedEventManager

    class Module {
        public function init() {             

                $events = new SharedEventManager(); 
                $events->attach('bootstrap', 'bootstrap', array($this, 'registerBasePath')); 
            } 

            public function registerBasePath($e) { 

                $modules = $e->getParam('modules'); 
                $config  = $modules->getMergedConfig(); 
                $app     = $e->getParam('application'); 
                $request = $app->getRequest(); 
                $request->setBasePath($config->base_path); 
            } 
        } 
    }

And in my modules/Application/configs/module.config.php I add:

'base_path' => '/spam/ham/' 

But it desn't work. The problems are:

1) The run never comes to the registerBasePath function. But it has to. I've attached an event with the listener in the init function.

2) When I change SharedEventManager for just EventManager it happens to come to the registerBasePath function but an exeption is thrown:

Fatal error: Call to undefined method Zend\EventManager\EventManager::getParam()

What do I do wrong? Why the run of the program doesn't come to the registerBasePath function? If this is the only way to set the basePath globally then how to do it right?


Solution

  • I know the documentation is lacking of these kinds of things. But you are right in the way to approach this:

    1. Be early (so at bootstrap)
    2. Grab the request from the application
    3. Set the base path in the request

    The docs are lacking this information and the post you refer to is quite old. The fastest and easiest way to do this is using the onBootstrap() method:

    namespace MyModule;
    
    class Module
    {
        public function onBootstrap($e)
        {
            $app = $e->getApplication();
            $app->getRequest()->setBasePath('/foo/bar');
        }
    }
    

    If you want to grab the base path from your config, you can load the service manager there:

    namespace MyModule;
    
    class Module
    {
        public function onBootstrap($e)
        {
            $app = $e->getApplication();
            $sm  = $app->getServiceManager();
    
            $config = $sm->get('config');
            $path   = $config->base_path;
    
            $app->getRequest()->setBasePath($path);
        }
    }