<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.controller.actionhelpers" xmlns:xi="http://www.w3.org/2001/XInclude">
    <title>Action Helpers</title>

    <sect2 id="zend.controller.actionhelper.introduction">
        <title>Introduction</title>

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

        <para>
            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 <link
                linkend="zend.view.helpers">Zend_View_Helper</link>, and that
            of <link
                linkend="zend.controller.plugins">Zend_Controller_Plugin</link>.
            Action Helpers (like <classname>Zend_View_Helper</classname>) may be
            loaded and called on demand, or they may be instantiated at
            request time (bootstrap) or action controller creation time
            (<methodname>init()</methodname>). To understand this more fully, please see the usage
            section below.
        </para>
    </sect2>

    <sect2 id="zend.controller.actionhelper.initialization">
        <title>Helper Initialization</title>

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

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

        <itemizedlist>
            <listitem>
                <para>
                    Explicitly using <methodname>getHelper()</methodname>. Simply pass it a
                    name, and a helper object is returned:
                </para>

                <programlisting language="php"><![CDATA[
$flashMessenger = $this->_helper->getHelper('FlashMessenger');
$flashMessenger->addMessage('We did something in the last request');
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    Use the helper broker's <methodname>__get()</methodname> functionality
                    and retrieve the helper as if it were a member property of
                    the broker:
                </para>

                <programlisting language="php"><![CDATA[
$flashMessenger = $this->_helper->FlashMessenger;
$flashMessenger->addMessage('We did something in the last request');
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    Finally, most action helpers implement the method
                    <methodname>direct()</methodname> which will call a specific, default
                    method in the helper. In the example of the
                    <emphasis>FlashMessenger</emphasis>, it calls
                    <methodname>addMessage()</methodname>:
                </para>

                <programlisting language="php"><![CDATA[
$this->_helper->FlashMessenger('We did something in the last request');
]]></programlisting>
            </listitem>
        </itemizedlist>

        <note>
            <para>All of the above examples are functionally equivalent.</para>
        </note>

        <para>
            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 <acronym>PHP</acronym> class.
        </para>
    </sect2>

    <sect2 id="zend.controller.actionhelper.broker">
        <title>The Helper Broker</title>

        <para>
            <classname>Zend_Controller_Action_HelperBroker</classname> handles the details
            of registering helper objects and helper paths, as well as
            retrieving helpers on-demand.
        </para>

        <para>
            To register a helper with the broker, use <methodname>addHelper()</methodname>:
        </para>

        <programlisting language="php"><![CDATA[
Zend_Controller_Action_HelperBroker::addHelper($helper);
]]></programlisting>

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

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>addPrefix()</methodname> 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.
                </para>

                <programlisting language="php"><![CDATA[
// Add helpers prefixed with My_Action_Helpers in My/Action/Helpers/
Zend_Controller_Action_HelperBroker::addPrefix('My_Action_Helpers');
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    <methodname>addPath()</methodname> takes a directory as its first
                    argument and a class prefix as the second argument
                    (defaulting to '<classname>Zend_Controller_Action_Helper</classname>').
                    This allows you to map your own class prefixes to specific directories.
                </para>

                <programlisting language="php"><![CDATA[
// Add helpers prefixed with Helper in Plugins/Helpers/
Zend_Controller_Action_HelperBroker::addPath('./Plugins/Helpers',
                                             'Helper');
]]></programlisting>
            </listitem>
        </itemizedlist>

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

        <para>
            Internally, the helper broker uses <link
                linkend="zend.loader.pluginloader">a PluginLoader
                instance</link> to maintain paths. You can retrieve the
            PluginLoader using the static method <methodname>getPluginLoader()</methodname>,
            or, alternately, inject a custom PluginLoader instance using
            <methodname>setPluginLoader()</methodname>.
        </para>

        <para>
            To determine if a helper exists in the helper broker, use
            <methodname>hasHelper($name)</methodname>, where <varname>$name</varname> is the short
            name of the helper (minus the prefix):
        </para>

        <programlisting language="php"><![CDATA[
// Check if 'redirector' helper is registered with the broker:
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
    echo 'Redirector helper registered';
}
]]></programlisting>

        <para>
            There are also two static methods for retrieving helpers from the helper
            broker: <methodname>getExistingHelper()</methodname> and
            <methodname>getStaticHelper()</methodname>.
            <methodname>getExistingHelper()</methodname>
            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. <methodname>getStaticHelper()</methodname> does the same as
            <methodname>getExistingHelper()</methodname>, but will attempt to instantiate
            the helper if has not yet been registered with the helper stack.
            <methodname>getStaticHelper()</methodname> is a good choice for retrieving
            helpers which you wish to configure.
        </para>

        <para>
            Both methods take a single argument, <varname>$name</varname>, which is
            the short name of the helper (minus the prefix).
        </para>

        <programlisting language="php"><![CDATA[
// 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');
}
]]></programlisting>

        <para>
            Finally, to delete a registered helper from the broker, use
            <methodname>removeHelper($name)</methodname>, where <varname>$name</varname> is the
            short name of the helper (minus the prefix):
        </para>

        <programlisting language="php"><![CDATA[
// Conditionally remove the 'redirector' helper from the broker:
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
    Zend_Controller_Action_HelperBroker::removeHelper('redirector')
}
]]></programlisting>
    </sect2>

    <sect2 id="zend.controller.actionhelper.stockhelpers">
        <title>Built-in Action Helpers</title>

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

        <xi:include href="Zend_Controller-ActionHelpers-ActionStack.xml" />
        <xi:include href="Zend_Controller-ActionHelpers-AutoComplete.xml" />
        <xi:include href="Zend_Controller-ActionHelpers-ContextSwitch.xml" />
        <xi:include href="Zend_Controller-ActionHelpers-FlashMessenger.xml" />
        <xi:include href="Zend_Controller-ActionHelpers-Json.xml" />
        <xi:include href="Zend_Controller-ActionHelpers-Redirector.xml" />
        <xi:include href="Zend_Controller-ActionHelpers-ViewRenderer.xml" />
    </sect2>

    <sect2 id="zend.controller.actionhelper.writingyourown">
        <title>Writing Your Own Helpers</title>

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

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>setActionController()</methodname> is used to set the current
                    action controller.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>init()</methodname>, 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.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>preDispatch()</methodname>, is triggered prior to a
                    dispatched action.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>postDispatch()</methodname> is triggered when a dispatched
                    action is done -- even if a <methodname>preDispatch()</methodname>
                    plugin has skipped the action. Mainly useful for cleanup.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getRequest()</methodname> retrieves the current request
                    object.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getResponse()</methodname> retrieves the current response
                    object.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getName()</methodname> 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
                    <classname>Zend_Controller_Action_Helper_Redirector</classname>, it
                    will return <emphasis>Redirector</emphasis>; a class named
                    <emphasis>FooMessage</emphasis> will simply return itself.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            You may optionally include a <methodname>direct()</methodname> 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 <link
                linkend="zend.controller.actionhelpers.redirector">redirector</link>
            defines <methodname>direct()</methodname> as an alias of
            <methodname>goto()</methodname>, allowing use of the helper like this:
        </para>

        <programlisting language="php"><![CDATA[
// Redirect to /blog/view/item/id/42
$this->_helper->redirector('item', 'view', 'blog', array('id' => 42));
]]></programlisting>

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

        <para>
            Once you have created your own helper class, you may provide access
            to it as described in the sections above.
        </para>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
