<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.controller.basics">
    <title>Zend_Controller Basics</title>

    <para>
        The <classname>Zend_Controller</classname> system is designed to be
        lightweight, modular, and extensible. It is a minimalist design to
        permit flexibility and some freedom to users while providing enough
        structure so that systems built around <classname>Zend_Controller</classname>
        share some common conventions and similar code layout.
    </para>

    <para>
        The following diagram depicts the workflow, and the narrative following
        describes in detail the interactions:
    </para>

    <para>
        <inlinegraphic width="483" scale="100" align="center" valign="middle"
            fileref="figures/zend.controller.basics.png" format="PNG" />
    </para>

    <para>
        The <classname>Zend_Controller</classname> workflow is implemented by several
        components. While it is not necessary to completely understand the
        underpinnings of all of these components to use the system, having a
        working knowledge of the process is helpful.
    </para>

    <itemizedlist>
        <listitem>
            <para>
                <classname>Zend_Controller_Front</classname> orchestrates the entire
                workflow of the <classname>Zend_Controller</classname> system. It is
                an interpretation of the FrontController pattern.
                <classname>Zend_Controller_Front</classname> processes all requests
                received by the server and is ultimately responsible for
                delegating requests to ActionControllers
                (<classname>Zend_Controller_Action</classname>).
            </para>
        </listitem>

        <listitem>
            <para>
                <classname>Zend_Controller_Request_Abstract</classname> (often
                referred to as the <emphasis>Request Object</emphasis>) represents
                the request environment and provides methods for setting and
                retrieving the controller and action names and any request
                parameters. Additionally it keeps track of whether or not
                the action it contains has been dispatched by
                <classname>Zend_Controller_Dispatcher</classname>. Extensions to the
                abstract request object can be used to encapsulate the
                entire request environment, allowing routers to pull
                information from the request environment in order to set the
                controller and action names.
            </para>

            <para>
                By default, <classname>Zend_Controller_Request_Http</classname> is
                used, which provides access to the entire <acronym>HTTP</acronym> request
                environment.
            </para>
        </listitem>

        <listitem>
            <para>
                <classname>Zend_Controller_Router_Interface</classname> is used to
                define routers. Routing is the process of examining the
                request environment to determine which controller, and
                action of that controller, should receive the request. This
                controller, action, and optional parameters are then set in
                the request object to be processed by
                <classname>Zend_Controller_Dispatcher_Standard</classname>. Routing
                occurs only once: when the request is initially received and
                before the first controller is dispatched.
            </para>

            <para>
                The default router,
                <classname>Zend_Controller_Router_Rewrite</classname>, takes a
                <acronym>URI</acronym> endpoint as specified in
                <classname>Zend_Controller_Request_Http</classname> and decomposes it
                into a controller, action, and parameters based on the path information
                in the <acronym>URL</acronym>. As an example, the <acronym>URL</acronym>
                <filename>http://localhost/foo/bar/key/value</filename> would be
                decoded to use the <emphasis>foo</emphasis> controller,
                <emphasis>bar</emphasis> action, and specify a parameter
                <emphasis>key</emphasis> with a value of <emphasis>value</emphasis>.
            </para>

            <para>
                <classname>Zend_Controller_Router_Rewrite</classname> can also be used
                to match arbitrary paths; see <link
                    linkend="zend.controller.router">the router documentation</link>
                for more information.
            </para>
        </listitem>

        <listitem>
            <para>
                <classname>Zend_Controller_Dispatcher_Interface</classname> is used to
                define dispatchers. Dispatching is the process of pulling
                the controller and action from the request object and
                mapping them to a controller file (or class) and action method in
                the controller class. If the controller or action do not
                exist, it handles determining default controllers and
                actions to dispatch.
            </para>

            <para>
                The actual dispatching process consists of instantiating the
                controller class and calling the action method in that
                class. Unlike routing, which occurs only once, dispatching
                occurs in a loop. If the request object's dispatched status
                is reset at any point, the loop will be repeated, calling
                whatever action is currently set in the request object. The
                first time the loop finishes with the request object's
                dispatched status set (<type>Boolean</type> <constant>TRUE</constant>),
                it will finish processing.
            </para>

            <para>
                The default dispatcher is
                <classname>Zend_Controller_Dispatcher_Standard</classname>. It defines
                controllers as MixedCasedClasses ending in the word
                Controller, and action methods as camelCasedMethods ending
                in the word Action:
                <methodname>FooController::barAction()</methodname>. In this case, the
                controller would be referred to as <emphasis>foo</emphasis> and
                the action as <emphasis>bar</emphasis>.
            </para>

            <note>
                <title>Case Naming Conventions</title>

                <para>
                    Since humans are notoriously inconsistent at
                    maintaining case sensitivity when typing links, Zend
                    Framework actually normalizes path information to
                    lowercase. This, of course, will affect how you name
                    your controller and actions... or refer to them in
                    links.
                </para>

                <para>
                    If you wish to have your controller class or action
                    method name have multiple MixedCasedWords or
                    camelCasedWords, you will need to separate those words
                    on the url with either a '-' or '.' (though you can
                    configure the character used).
                </para>

                <para>
                    As an example, if you were going to the action in
                    <methodname>FooBarController::bazBatAction()</methodname>, you'd
                    refer to it on the url as <filename>/foo-bar/baz-bat</filename>
                    or <filename>/foo.bar/baz.bat</filename>.
                </para>
            </note>
        </listitem>

        <listitem>
            <para>
                <classname>Zend_Controller_Action</classname> is the base action
                controller component. Each controller is a single class
                that extends the <classname>Zend_Controller_Action</classname> class
                and should contain one or more action methods.
            </para>
        </listitem>

        <listitem>
            <para>
                <classname>Zend_Controller_Response_Abstract</classname> defines a
                base response class used to collect and return responses
                from the action controllers. It collects both headers and
                body content.
            </para>

            <para>
                The default response class is
                <classname>Zend_Controller_Response_Http</classname>, which is
                suitable for use in an <acronym>HTTP</acronym> environment.
            </para>
        </listitem>
    </itemizedlist>

    <para>
        The workflow of <classname>Zend_Controller</classname> is relatively simple. A
        request is received by <classname>Zend_Controller_Front</classname>, which in turn
        calls <classname>Zend_Controller_Router_Rewrite</classname> to determine which
        controller (and action in that controller) to dispatch.
        <classname>Zend_Controller_Router_Rewrite</classname> decomposes the <acronym>URI</acronym>
        in order to set the controller and action names in the request.
        <classname>Zend_Controller_Front</classname> then enters a dispatch loop. It
        calls <classname>Zend_Controller_Dispatcher_Standard</classname>, passing it the
        request, to dispatch to the controller and action specified in the
        request (or use defaults). After the controller has finished, control
        returns to <classname>Zend_Controller_Front</classname>. If the controller has
        indicated that another controller should be dispatched by resetting the
        dispatched status of the request, the loop continues and another
        dispatch is performed. Otherwise, the process ends.
    </para>
</sect1>

<!--
vim:se ts=4 sw=4 et:
-->
