<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.application.examples">
    <title>Examples</title>

    <para>
        The Bootstrap class itself will typically be fairly minimal; often,
        it will simply be an empty stub extending the base bootstrap class:
    </para>

    <programlisting language="php"><![CDATA[
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
}
]]></programlisting>

    <para>
        With a corresponding configuration file:
    </para>

    <programlisting language="ini"><![CDATA[
; APPLICATION_PATH/configs/application.ini
[production]
autoloaderNamespaces[] = "My_"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
pluginpaths.My_Bootstrap_Resource = "My/Bootstrap/Resource"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"

[testing : production]
[development : production]
]]></programlisting>

    <note>
        <title>Autoloader namespaces</title>

        <para>
            Because these examples use custom code, we need to register the namespace prefixes for
            that code with our configuration; this is done with the
            <property>autoloaderNamespaces</property> configuration key, which is an array.
        </para>

        <para>
            Additionally, to ensure that custom plugin resources are discovered, we need to register
            a plugin prefix path with the bootstrap. This is done with the
            <property>pluginpaths</property> configuration key, which is an associative array, with
            keys denoting the prefix to use, and values denoting the path related to that prefix.
        </para>
    </note>

    <para>
        However, should custom initialization be necessary, you have two
        choices. First, you can write methods prefixed with <emphasis>_init</emphasis>
        to specify discrete code to bootstrap. These methods will be called by
        <methodname>bootstrap()</methodname>, and can also be called as if they were public methods:
        <emphasis>bootstrap&lt;resource&gt;()</emphasis>. They should accept an optional
        array of options.
    </para>

    <para>
        If your resource method returns a value, it will be stored in a
        container in the bootstrap. This can be useful when different resources
        need to interact (such as one resource injecting itself into another).
        The method <methodname>getResource()</methodname> can then be used to retrieve those
        values.
    </para>

    <para>
        The example below shows a resource method for initializing the request
        object. It makes use of dependency tracking (it depends on the front
        controller resource), fetching a resource from the bootstrap, and
        returning a value to store in the bootstrap.
    </para>

    <programlisting language="php"><![CDATA[
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function _initRequest()
    {
        // Ensure front controller instance is present, and fetch it
        $this->bootstrap('FrontController');
        $front = $this->getResource('FrontController');

        // Initialize the request object
        $request = new Zend_Controller_Request_Http();
        $request->setBaseUrl('/foo');

        // Add it to the front controller
        $front->setRequest($request);

        // Bootstrap will store this value in the 'request' key of its container
        return $request;
    }
}
]]></programlisting>

    <para>
        Note in this example the call to <methodname>bootstrap()</methodname>;
        this ensures that the front controller has been initialized prior to
        calling this method. That call may trigger either a resource or another
        method in the class.
    </para>

    <para>
        The other option is to use resource plugins. Resource plugins are
        objects that perform specific initializations, and may be specified:
    </para>

    <itemizedlist>
        <listitem>
            <para>
                When instantiating the <classname>Zend_Application</classname> object
            </para>
        </listitem>

        <listitem>
            <para>
                During initialization of the bootstrap object
            </para>
        </listitem>

        <listitem>
            <para>
                By explicitly enabling them via method calls to the bootstrap
                object
            </para>
        </listitem>
    </itemizedlist>

    <para>
        Resource plugins implement
        <classname>Zend_Application_Resource_ResourceAbstract</classname>,
        which defines simply that they allow injection of the caller and
        options, and that they have an <methodname>init()</methodname> method. As an
        example, a custom "View" bootstrap resource might look like the
        following:
    </para>

    <programlisting language="php"><![CDATA[
class My_Bootstrap_Resource_View
    extends Zend_Application_Resource_ResourceAbstract
{
    public function init()
    {
        $view = new Zend_View($this->getOptions());
        Zend_Dojo::enableView($view);

        $view->doctype('XHTML1_STRICT');
        $view->headTitle()->setSeparator(' - ')->append('My Site');
        $view->headMeta()->appendHttpEquiv('Content-Type',
                                           'text/html; charset=utf-8');

        $view->dojo()->setDjConfigOption('parseOnLoad', true)
                     ->setLocalPath('/js/dojo/dojo.js')
                     ->registerModulePath('../spindle', 'spindle')
                     ->addStylesheetModule('spindle.themes.spindle')
                     ->requireModule('spindle.main')
                     ->disable();

        $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
            'ViewRenderer'
        );
        $viewRenderer->setView($view);

        return $view;
    }
}
]]></programlisting>

    <para>
        To tell the bootstrap to use this, you would need to provide either the
        class name of the resource plugin, or a combination of a plugin loader prefix
        path and the short name of the resource plugin (e.g, "view"):
    </para>

    <programlisting language="php"><![CDATA[
$application = new Zend_Application(
    APPLICATION_ENV,
    array(
        'resources' => array(
            'My_Bootstrap_Resource_View' => array(), // full class name; OR
            'view' => array(),                       // short name

            'FrontController' => array(
                'controllerDirectory' => APPLICATION_PATH . '/controllers',
            ),
        ),

        // For short names, define plugin paths:
        'pluginPaths = array(
            'My_Bootstrap_Resource' => 'My/Bootstrap/Resource',
        )
    )
);
]]></programlisting>

    <para>
        Resource plugins can call on other resources and initializers by accessing the
        parent bootstrap:
    </para>

    <programlisting language="php"><![CDATA[
class My_Bootstrap_Resource_Layout
    extends Zend_Application_Resource_ResourceAbstract
{
    public function init()
    {
        // ensure view is initialized...
        $this->getBootstrap()->bootstrap('view');

        // Get view object:
        $view = $this->getBootstrap()->getResource('view');

        // ...
    }
}
]]></programlisting>

    <para>
        In normal usage, you would instantiate the application, bootstrap it,
        and run it:
    </para>

    <programlisting language="php"><![CDATA[
$application = new Zend_Application(...);
$application->bootstrap()
            ->run();
]]></programlisting>

    <para>
        For a custom script, you might need to simply initialize specific
        resources:
    </para>

    <programlisting language="php"><![CDATA[
$application = new Zend_Application(...);
$application->getBootstrap()->bootstrap('db');

$service = new Zend_XmlRpc_Server();
$service->setClass('Foo');  // uses database...
echo $service->handle();
]]></programlisting>

    <para>
        Instead of using the <methodname>bootstrap()</methodname> method to call the
        internal methods or resources, you may also use overloading:
    </para>

    <programlisting language="php"><![CDATA[
$application = new Zend_Application(...);
$application->getBootstrap()->bootstrapDb();
]]></programlisting>
</sect1>
