Hooks in Action Helpers
Following on from the discussion on Zend Framework Action Helpers, let's talk about hooks within them.
Hooks are a feature of action helpers that allow you to automatically run code at certain points in the dispatch cycle. Specially, there are two hook functions available for action helpers:
- preDispatch(): runs before the action function is called
- postDispatch(): runs after the action function has completed
These allow you to ensure that some functionality is always run for each request. Let's consider a simple example of displaying a random quote in the footer of a website.
We start with an action helper in our controllers/helpers directory called Quote:
<?php class Zend_Controller_Action_Helper_Quote extends Zend_Controller_Action_Helper_Abstract { function preDispatch() { $view = $this->getActionController()->view; $view->footerQuote = $this->getQuote(); } function getQuote() { $quotes[] = 'I want to run, I want to hide, I want to tear down the walls'; $quotes[] = 'One man come in the name of love, One man come and go'; return $quotes[rand(0, count($quotes)-1)]; } }
The preDispatch() method, collects the view from the action controller and then assigns a random quote to the footerQuote property.
We need to tell the helper broker that we want this helper's hooks to be run, so in addition to the addHelperPath() call, our bootstrap requires a call to addHelper(). The bootstrap therefore has this code within it:
// Action Helpers Zend_Controller_Action_HelperBroker::addPath( APPLICATION_PATH .'/controllers/helpers'); $hooks = Zend_Controller_Action_HelperBroker::getStaticHelper('Quote'); Zend_Controller_Action_HelperBroker::addHelper($hooks);
As we used addPath() to tell the helper broker where to find the action helpers, we can use getStaticHelper() as an easy way to instantiate the class without having to require() and then call new. We can then register it with the helper broker using addHelper().
As the quote is displayed in the footer, the HTML required lives in layout.phtml:
<div id="footer"> <div id="quote"> <?php echo $this->footerQuote; ?> </div> </div>
That's it - not too hard, is it?
Zip Files:
I've updated the example project from the last post so you can see it in context.
- ZF_Action_Helper_example.zip - 9.7kB
- ZF_Action_Helper_example_with_zf.zip (including ZF 1.6) - 3.5MB



November 5th, 2008 at 11:50 #
So what's the difference between an helper like this and a front controller plugin?
November 5th, 2008 at 14:07 #
Why hooks in getStaticHelper('Hooks'); ?
i dont see any link between your actionhelper and your bootstrap, AND your layout. You call footerQuote from your layout but the helper is called Quote? i dont see the link
November 5th, 2008 at 14:07 #
Cool!
BTW, in the example code, it should be getStaticHelper('Quote'), right? :)
thanks,
eddie
November 5th, 2008 at 14:52 #
Thank you!!! I now have one place with all the logic for the stuff like templates that is on every page instead of copied and pasted action helper calls - much nicer :)
November 5th, 2008 at 14:59 #
eddie,
oops :)
Thanks!
Regards,
Rob...
November 5th, 2008 at 15:02 #
Christian,
The Quote helper creates a view property called "footerQuote" which is then used in layout.phtml.
There was a bug in the bootstrap code, which is now fixed!
Regards,
Rob...
November 5th, 2008 at 15:07 #
Lorna,
Glad it was helpful :)
Regards,
Rob...
November 5th, 2008 at 16:24 #
hi, it's eddie again.
I just downloaded the updated ZF_Action_Helper_example.zip, but the "getStaticHelper('Hooks')" still in the bootstrap.php :)
November 15th, 2008 at 07:53 #
really very informative tutorial Rob...
November 17th, 2008 at 12:57 #
Hi Rob!
Very usefull post. Thanks.
I translate it to Russian if you don't mind.
November 21st, 2008 at 10:58 #
Rob,
//return $quotes[rand(0, count($quotes)-1)];//
Greate Rob, Thanks Lot
June 16th, 2009 at 05:24 #
Hi Rob,
So how would this code need to be modified to work in ZF 1.8+ ?
June 16th, 2009 at 09:06 #
Joe,
It shouldn't need any changes except to double check that the method signatures haven't changed.
Regards,
Rob...
June 16th, 2009 at 19:35 #
I was wondering about if the bootstrap section needed to change? Does that just go into Bootstrap.php?
" // Action Helpers
Zend_Controller_Action_HelperBroker::addPath(
APPLICATION_PATH .'/controllers/helpers');
$hooks = Zend_Controller_Action_HelperBroker::getStaticHelper('Quote');
Zend_Controller_Action_HelperBroker::addHelper($hooks);"
June 16th, 2009 at 20:15 #
Well, it needs to go somewhere in your bootstrapping process, so creating an _initActionHelpers() isn't a bad idea.
Regards,
Rob...
March 7th, 2010 at 03:04 #
Thanks for the informative post! I was stuck for hours trying to get this working. Now I have a custom context switcher that gets auto-run from an action helper. This makes for a very clean solution.
Rob's idea helped me get this to work in 1.8+
August 28th, 2010 at 03:20 #
I'm all for cleanly moving this kind of ancillary functionality - random quotes in a footer or sidebar, for example - out into a separate class. But an action helper seems an odd place for it. It seems to me an action helper is most useful for functionality that can be be called on demand from within an action itself. The kind of action-independent content we are discussing here strikes me as better suited to a view helper, kind of in-keeping with the "controllers are not the data police" philosophy. Whaddya think?
November 2nd, 2010 at 22:24 #
Note if you're doing something that's a bit more complex in your Action Helper...iow, something that might call Exceptions, be sure to check out my issue and resolution on Stack Overflow:
http://stackoverflow.com/questions/4076578/do-action-helpers-with-hooks-to-auto-run-throw-exceptions-or-not/4082325
November 9th, 2010 at 02:19 #
Hey Rob,
Another thought. Is it possible to get this working from the application.ini configs?
January 25th, 2011 at 09:26 #
Hey Rob,
Another thought. Is it possible to get this working from the application.ini configs?