How to run same lines in all controllers init() function?

3k views Asked by At

I need same 2 lines in all my controllers, each controller have its own init logic, but these two lines are common for all of them.

public function init()
{
    $fm =$this->_helper->getHelper('FlashMessenger');
    $this->view->messages = $fm->getMessages();
}

How can I avoid repeat code ?

Update:

Ok, the FlashMessenger was only an example, let's say I need write a log line in every action except for 'someAction' @ 'someController'. So the new common lines should be.

$this->logger = new Zend_Log();
$writer = new Zend_Log_Writer_Stream(APPLICATION_PATH.'/../logs/log.txt');
$this->logger->addWriter($writer);
$this->logger->log('Some Message',Zend_Log::DEBUG);

The question is, where should I place these lines in order to avoid repeat them in all init() of each controller. These lines should be placed at bootstrap?. If so: How can skip log lines for 'someAction'. Or should I implement a 'BaseController' and make all my controller extend from it. If so: How can I Autoload it? (Fatal error: Class 'BaseController' not found) .

5

There are 5 answers

2
takeshin On BEST ANSWER

Just subclass the controller:

class Application_ControllerAction extends Zend_Controller_Action {
    public function init()
    {
        $fm =$this->_helper->getHelper('FlashMessenger');
        $this->view->messages = $fm->getMessages();
    }
}


class IndexController extends Application_ControllerAction {
}

You may also achieve the same writing Controller Plugin.

Edit:

Front controller plugins are executed on each request, just like the Controllers and have the same hook methods:

routeStartup(): prior to routing the request
routeShutdown(): after routing the request
dispatchLoopStartup(): prior to entering the dispatch loop
preDispatch(): prior to dispatching an individual action
postDispatch(): after dispatching an individual action
dispatchLoopShutdown(): after completing the dispatch loop

I addition, you may check controller params to execute the code only on selected requests:

if ('admin' == $this->getRequest()->getModuleName() 
&& 'update' == $this->getRequest()->getActionName() ) …
6
JF Dion On

You can access your flash messages through (you dont need to send anything from your controller to your view, it's all automated)

$fm = new Zend_Controller_Action_Helper_FlashMessenger();
Zend_Debug::dump($fm->getMessages());

in you view, i would also recommand that you encapsulate this code in a view helper like it is shown on this site http://grummfy.be/blog/191

2
Radek Benkel On

How can I avoid repeat code ?

Write your own custom controller, implement that in init method of that controller, and then extend all controllers in your app from your custom controller.

But approach with separate view helper as @Jeff mentioned (look at link) is often taken as a better solution. In your controller do only:

$this->_helper->flashMessanger('My message');

and view helper will do the rest.

1
KomarSerjio On

It's not the reason for creating new custom controller. Just add this line to all you init() methods.

$this->view->messages = $this->_helper->getHelper('FlashMessenger')->getMessages();
1
Stephen Fuhry On

In your bootstrap:

protected function _initMyActionHelpers() {
    $fm = new My_Controller_Action_Helper_FlashMessenger();
    Zend_Controller_Action_HelperBroker::addHelper($fm);;
}