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.

20 thoughts on “Hooks in Action Helpers

  1. 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

  2. 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 :)

  3. 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…

  4. hi, it's eddie again.
    I just downloaded the updated ZF_Action_Helper_example.zip, but the "getStaticHelper('Hooks')" still in the bootstrap.php :)

  5. Joe,

    It shouldn't need any changes except to double check that the method signatures haven't changed.

    Regards,

    Rob…

  6. 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);"

  7. Well, it needs to go somewhere in your bootstrapping process, so creating an _initActionHelpers() isn't a bad idea.

    Regards,

    Rob…

  8. 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+

  9. 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?

Comments are closed.