<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="migration.06">
    <title>Zend Framework 0.6</title>

    <para>
        When upgrading from a previous release to Zend Framework 0.6 or higher you
        should note the following migration notes.
    </para>

    <sect2 id="migration.06.zend.controller">
        <title>Zend_Controller</title>

        <para>
            The most basic usage of the <acronym>MVC</acronym> components has not changed; you can
            still do each of the following:
        </para>

        <programlisting language="php"><![CDATA[
Zend_Controller_Front::run('/path/to/controllers');
]]></programlisting>

        <programlisting language="php"><![CDATA[
/* -- create a router -- */
$router = new Zend_Controller_RewriteRouter();
$router->addRoute('user',
                  'user/:username',
                  array('controller' => 'user', 'action' => 'info')
);

/* -- set it in a controller -- */
$ctrl = Zend_Controller_Front::getInstance();
$ctrl->setRouter($router);

/* -- set controller directory and dispatch -- */
$ctrl->setControllerDirectory('/path/to/controllers');
$ctrl->dispatch();
]]></programlisting>

        <para>
            We encourage use of the Response object to aggregate content and
            headers. This will allow for more flexible output format switching
            (for instance, <acronym>JSON</acronym> or <acronym>XML</acronym> instead of
            <acronym>XHTML</acronym>) in your applications.
            By default, <methodname>dispatch()</methodname> will render the response, sending both
            headers and rendering any content. You may also have the front
            controller return the response using <methodname>returnResponse()</methodname>,
            and then render the response using your own logic. A future version
            of the front controller may enforce use of the response object via
            output buffering.
        </para>

        <para>
            There are many additional features that extend the existing <acronym>API</acronym>,
            and these are noted in the documentation.
        </para>

        <para>
            The main changes you will need to be aware of will be found when
            subclassing the various components. Key amongst these are:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>Zend_Controller_Front::dispatch()</methodname> by default
                    traps exceptions in the response object, and does not render
                    them, in order to prevent sensitive system information from
                    being rendered. You can override this in several ways:
                </para>

                <itemizedlist>
                    <listitem>
                        <para>
                            Set <methodname>throwExceptions()</methodname> in the front
                            controller:
                        </para>

                        <programlisting language="php"><![CDATA[
$front->throwExceptions(true);
]]></programlisting>
                    </listitem>

                    <listitem>
                        <para>
                            Set <methodname>renderExceptions()</methodname> in the response
                            object:
                        </para>

                        <programlisting language="php"><![CDATA[
$response->renderExceptions(true);
$front->setResponse($response);
$front->dispatch();

// or:
$front->returnResponse(true);
$response = $front->dispatch();
$response->renderExceptions(true);
echo $response;
]]></programlisting>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>
                    <methodname>Zend_Controller_Dispatcher_Interface::dispatch()</methodname>
                    now accepts and returns a <link linkend="zend.controller.request">The
                    Request Object</link> instead of a dispatcher token.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>Zend_Controller_Router_Interface::route()</methodname>
                    now accepts and returns a <link linkend="zend.controller.request">The
                    Request Object</link> instead of a dispatcher token.
                </para>
            </listitem>

            <listitem>
                <para><classname>Zend_Controller_Action</classname> changes include:</para>

                <itemizedlist>
                    <listitem>
                        <para>
                            The constructor now accepts exactly three arguments,
                            <classname>Zend_Controller_Request_Abstract</classname>
                            <varname>$request</varname>,
                            <classname>Zend_Controller_Response_Abstract</classname>
                            <varname>$response</varname>,
                            and <type>Array</type> <varname>$params</varname> (optional).
                            <methodname>Zend_Controller_Action::__construct()</methodname> uses
                            these to set the request, response, and invokeArgs
                            properties of the object, and if overriding the
                            constructor, you should do so as well. Better yet, use
                            the <methodname>init()</methodname> method to do any instance
                            configuration, as this method is called as the final
                            action of the constructor.
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>run()</methodname> is no longer defined as final, but is
                            also no longer used by the front controller; its sole
                            purpose is for using the class as a page controller. It
                            now takes two optional arguments, a
                            <classname>Zend_Controller_Request_Abstract</classname>
                            <varname>$request</varname>
                            and a <classname>Zend_Controller_Response_Abstract</classname>
                            <varname>$response</varname>.
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>indexAction()</methodname> no longer needs to be
                            defined, but is encouraged as the default action. This
                            allows using the RewriteRouter and action controllers to
                            specify different default action methods.
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>__call()</methodname> should be overridden to handle any
                            undefined actions automatically.
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>_redirect()</methodname> now takes an optional second
                            argument, the <acronym>HTTP</acronym> code to return with the redirect,
                            and an optional third argument, <varname>$prependBase</varname>,
                            that can indicate that the base <acronym>URL</acronym> registered with
                            the request object should be prepended to the url specified.
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            The <varname>$_action</varname> property is no longer set. This property
                            was a <classname>Zend_Controller_Dispatcher_Token</classname>,
                            which no longer exists in the current incarnation.
                            The sole purpose of the token was to provide
                            information about the requested controller, action,
                            and <acronym>URL</acronym> parameters. This information is now
                            available in the request object, and can be accessed
                            as follows:
                        </para>

                        <programlisting language="php"><![CDATA[
// Retrieve the requested controller name
// Access used to be via: $this->_action->getControllerName().
// The example below uses getRequest(), though you may also directly
// access the $_request property; using getRequest() is recommended as
// a parent class may override access to the request object.
$controller = $this->getRequest()->getControllerName();

// Retrieve the requested action name
// Access used to be via: $this->_action->getActionName().
$action = $this->getRequest()->getActionName();

// Retrieve the request parameters
// This hasn't changed; the _getParams() and _getParam() methods simply
// proxy to the request object now.
$params = $this->_getParams();
// request 'foo' parameter, using 'default' as default value if not found
$foo = $this->_getParam('foo', 'default');
]]></programlisting>
                    </listitem>

                    <listitem>
                        <para>
                            <methodname>noRouteAction()</methodname> has been removed. The
                            appropriate way to handle non-existent action
                            methods should you wish to route them to a default
                            action is using <methodname>__call()</methodname>:
                        </para>

                        <programlisting language="php"><![CDATA[
public function __call($method, $args)
{
    // If an unmatched 'Action' method was requested, pass on to the
    // default action method:
    if ('Action' == substr($method, -6)) {
        return $this->defaultAction();
    }

    throw new Zend_Controller_Exception('Invalid method called');
}
]]></programlisting>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>
                    <methodname>Zend_Controller_RewriteRouter::setRewriteBase()</methodname> has
                    been removed. Use <methodname>Zend_Controller_Front::setBaseUrl()</methodname>
                    instead (or <methodname>Zend_Controller_Request_Http::setBaseUrl()</methodname>,
                    if using that request class).
                </para>
            </listitem>

            <listitem>
                <para>
                    <classname>Zend_Controller_Plugin_Interface</classname> was replaced
                    by <classname>Zend_Controller_Plugin_Abstract</classname>. All methods now
                    accept and return a <link linkend="zend.controller.request">The Request
                    Object</link> instead of a dispatcher token.
                </para>
            </listitem>
        </itemizedlist>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
