# Action Helpers

## Introduction

Action Helpers allow developers to inject runtime and/or on-demand functionality into any Action Controllers that extend `Zend_Controller_Action`. Action Helpers aim to minimize the necessity to extend the abstract Action Controller in order to inject common Action Controller functionality.

There are a number of ways to use Action Helpers. Action Helpers employ the use of a brokerage system, similar to the types of brokerage you see in Zend_View_Helper, and that of Zend_Controller_Plugin. Action Helpers (like `Zend_View_Helper`) may be loaded and called on demand, or they may be instantiated at request time (bootstrap) or action controller creation time (`init()`). To understand this more fully, please see the usage section below.

## Helper Initialization

A helper can be initialized in several different ways, based on your needs as well as the functionality of that helper.

The helper broker is stored as the `$_helper` member of `Zend_Controller_Action`; use the broker to retrieve or call on helpers. Some methods for doing so include:

- Explicitly using `getHelper()`. Simply pass it a name, and a helper object is returned:

      $flashMessenger = $this->_helper->getHelper('FlashMessenger');
      $flashMessenger->addMessage('We did something in the last request');

- Use the helper broker's `__get()` functionality and retrieve the helper as if it were a member property of the broker:

      $flashMessenger = $this->_helper->FlashMessenger;
      $flashMessenger->addMessage('We did something in the last request');

- Finally, most action helpers implement the method `direct()` which will call a specific, default method in the helper. In the example of the FlashMessenger, it calls `addMessage()`:

      $this->_helper->FlashMessenger('We did something in the last request');

All of the above examples are functionally equivalent.

You may also instantiate helpers explicitly. You may wish to do this if using the helper outside of an action controller, or if you wish to pass a helper to the helper broker for use by any action. Instantiation is as per any other PHP class.

## The Helper Broker

`Zend_Controller_Action_HelperBroker` handles the details of registering helper objects and helper paths, as well as retrieving helpers on-demand.

To register a helper with the broker, use `addHelper()`:

    Zend_Controller_Action_HelperBroker::addHelper($helper);

Of course, instantiating and passing helpers to the broker is a bit time and resource intensive, so two methods exists to automate things slightly: `addPrefix()` and `addPath()`.

- `addPrefix()` takes a class prefix and uses it to determine a path where helper classes have been defined. It assumes the prefix follows Zend Framework class naming conventions.

      // Add helpers prefixed with My_Action_Helpers in My/Action/Helpers/
      Zend_Controller_Action_HelperBroker::addPrefix('My_Action_Helpers');

- `addPath()` takes a directory as its first argument and a class prefix as the second argument (defaulting to '`Zend_Controller_Action_Helper`'). This allows you to map your own class prefixes to specific directories.

      // Add helpers prefixed with Helper in Plugins/Helpers/
      Zend_Controller_Action_HelperBroker::addPath('./Plugins/Helpers',
                                                   'Helper');

Since these methods are static, they may be called at any point in the controller chain in order to dynamically add helpers as needed.

Internally, the helper broker uses a PluginLoader instance to maintain paths. You can retrieve the PluginLoader using the static method `getPluginLoader()`, or, alternately, inject a custom PluginLoader instance using `setPluginLoader()`.

To determine if a helper exists in the helper broker, use `hasHelper($name)`, where `$name` is the short name of the helper (minus the prefix):

    // Check if 'redirector' helper is registered with the broker:
    if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
        echo 'Redirector helper registered';
    }

There are also two static methods for retrieving helpers from the helper broker: `getExistingHelper()` and `getStaticHelper()`. `getExistingHelper()` will retrieve a helper only if it has previously been invoked by or explicitly registered with the helper broker; it will throw an exception if not. `getStaticHelper()` does the same as `getExistingHelper()`, but will attempt to instantiate the helper if has not yet been registered with the helper stack. `getStaticHelper()` is a good choice for retrieving helpers which you wish to configure.

Both methods take a single argument, `$name`, which is the short name of the helper (minus the prefix).

    // Check if 'redirector' helper is registered with the broker, and fetch:
    if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
        $redirector =
            Zend_Controller_Action_HelperBroker::getExistingHelper('redirector');
    }

    // Or, simply retrieve it, not worrying about whether or not it was
    // previously registered:
    $redirector =
        Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
    }

Finally, to delete a registered helper from the broker, use `removeHelper($name)`, where `$name` is the short name of the helper (minus the prefix):

    // Conditionally remove the 'redirector' helper from the broker:
    if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
        Zend_Controller_Action_HelperBroker::removeHelper('redirector')
    }

## Built-in Action Helpers

Zend Framework includes several action helpers by default: AutoComplete for automating responses for AJAX autocompletion; ContextSwitch and AjaxContext for serving alternate response formats for your actions; a FlashMessenger for handling session flash messages; Json for encoding and sending JSON responses; a Redirector, to provide different implementations for redirecting to internal and external pages from your application; and a ViewRenderer to automate the process of setting up the view object in your controllers and rendering views.

## Writing Your Own Helpers

Action helpers extend `Zend_Controller_Action_Helper_Abstract`, an abstract class that provides the basic interface and functionality required by the helper broker. These include the following methods:

- `setActionController()` is used to set the current action controller.

- `init()`, triggered by the helper broker at instantiation, can be used to trigger initialization in the helper; this can be useful for resetting state when multiple controllers use the same helper in chained actions.

- `preDispatch()`, is triggered prior to a dispatched action.

- `postDispatch()` is triggered when a dispatched action is done -- even if a `preDispatch()` plugin has skipped the action. Mainly useful for cleanup.

- `getRequest()` retrieves the current request object.

- `getResponse()` retrieves the current response object.

- `getName()` retrieves the helper name. It retrieves the portion of the class name following the last underscore character, or the full class name otherwise. As an example, if the class is named `Zend_Controller_Action_Helper_Redirector`, it will return Redirector; a class named FooMessage will simply return itself.

You may optionally include a `direct()` method in your helper class. If defined, it allows you to treat the helper as a method of the helper broker, in order to allow easy, one-off usage of the helper. As an example, the redirector defines `direct()` as an alias of `goto()`, allowing use of the helper like this:

    // Redirect to /blog/view/item/id/42
    $this->_helper->redirector('item', 'view', 'blog', array('id' => 42));

Internally, the helper broker's `__call()` method looks for a helper named redirector, then checks to see if that helper has a defined `direct()` method, and calls it with the arguments provided.

Once you have created your own helper class, you may provide access to it as described in the sections above.