<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.loader.autoloader-resource">
    <title>Resource Autoloaders</title>

    <para>
        Resource autoloaders are intended to manage namespaced library code that
        follow Zend Framework coding standard guidelines, but which do not have
        a 1:1 mapping between the class name and the directory structure. Their
        primary purpose is to facilitate autoloading application resource code,
        such as application-specific models, forms, and ACLs.
    </para>

    <para>
        Resource autoloaders register with the <link
            linkend="zend.loader.autoloader">autoloader</link> on instantiation,
        with the namespace to which they are associated. This allows you to
        easily namespace code in specific directories, and still reap the
        benefits of autoloading.
    </para>

    <sect2 id="zend.loader.autoloader-resource.usage">
        <title>Resource autoloader usage</title>

        <para>
            Let's consider the following directory structure:
        </para>

        <programlisting role="text"><![CDATA[
path/to/some/directory/
    acls/
        Site.php
    forms/
        Login.php
    models/
        User.php
]]></programlisting>

        <para>
            Within this directory, all code is prefixed with the namespace
            "My_". Within the "acls" subdirectory, the component prefix "Acl_"
            is added, giving a final class name of "My_Acl_Site". Similarly, the
            "forms" subdirectory maps to "Form_", giving "My_Form_Login".  The
            "models" subdirectory has no component namespace, giving "My_User".
        </para>

        <para>
            You can use a resource autoloader to autoload these classes. To
            instantiate the resource autoloader, you are required to pass at the
            minimum the base path and namespace for the resources it will be
            responsible for:
        </para>

        <programlisting role="php"><![CDATA[
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
    'basePath'  => 'path/to/some/directory',
    'namespace' => 'My',
));
]]></programlisting>

        <note>
            <title>Base namespace</title>

            <para>
                In <classname>Zend_Loader_Autoloader</classname>, you are expected to
                provide the trailing underscore ("_") in your namespace if your
                autoloader will use it to match the namespace.
                <classname>Zend_Loader_Autoloader_Resource</classname> makes the
                assumption that all code you are autoloading will use an
                underscore separator between namespaces, components, and
                classes. As a result, you do not need to use the trailing
                underscore when registering a resource autoloader.
            </para>
        </note>

        <para>
            Now that we have setup the base resource autoloader, we can add some
            components to it to autoload. This is done using the
            <code>addResourceType()</code> method, which accepts three
            arguments: a resource "type", used internally as a reference name;
            the subdirectory path underneath the base path in which these
            resources live; and the component namespace to append to the base
            namespace. As an example, let's add each of our resource types.
        </para>

        <programlisting role="php"><![CDATA[
$resourceLoader->addResourceType('acl', 'acls/', 'Acl')
               ->addResourceType('form', 'forms/', 'Form')
               ->addResourceType('model', 'models/');
]]></programlisting>

        <para>
            Alternately, you could pass these as an array to
            <code>addResourceTypes()</code>; the following is equivalent to the
            above:
        </para>

        <programlisting role="php"><![CDATA[
$resourceLoader->addResourceTypes(array(
    'acl' => array(
        'path'      => 'acls/',
        'namespace' => 'Acl',
    ),
    'form' => array(
        'path'      => 'forms/',
        'namespace' => 'Form',
    ),
    'model' => array(
        'path'      => 'models/',
    ),
));
]]></programlisting>

        <para>
            Finally, you can specify all of this when instantiating the object,
            by simply specifying a "resourceTypes" key in the options passed and
            a structure like that above:
        </para>

        <programlisting role="php"><![CDATA[
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
    'basePath'      => 'path/to/some/directory',
    'namespace'     => 'My',
    'resourceTypes' => array(
        'acl' => array(
            'path'      => 'acls/',
            'namespace' => 'Acl',
        ),
        'form' => array(
            'path'      => 'forms/',
            'namespace' => 'Form',
        ),
        'model' => array(
            'path'      => 'models/',
        ),
    ),
));
]]></programlisting>
    </sect2>

    <sect2 id="zend.loader.autoloader-resource.module">
        <title>The Module Resource Autoloader</title>

        <para>
            Zend Framework ships with a concrete implementation of
            <classname>Zend_Loader_Autoloader_Resource</classname> that contains resource
            type mappings that cover the default recommended directory structure
            for Zend Framework MVC applications. This loader,
            <classname>Zend_Application_Module_Autoloader</classname>, comes with the
            following mappings:
        </para>

        <programlisting role="text"><![CDATA[
api/         => Api
forms/       => Form
models/      => Model
    DbTable/ => Model_DbTable
plugins/     => Plugin
]]></programlisting>

        <para>
            As an example, if you have a module with the prefix of "Blog_", and
            attempted to instantiate the class "Blog_Form_Entry", it would look
            in the resource directory's "forms/" subdirectory for a file named
            "Entry.php".
        </para>

        <para>
            When using module bootstraps with <classname>Zend_Application</classname>, an
            instance of <classname>Zend_Application_Module_Autoloader</classname> will be
            created by default for each discrete module, allowing you to
            autoload module resources.
        </para>
    </sect2>

    <sect2 id="zend.loader.autoloader-resource.factory">
        <title>Using Resource Autoloaders as Object Factories</title>
        <para></para>
        <!-- @todo -->
    </sect2>

    <sect2 id="zend.loader.autoloader-resource.reference">
        <title>Resource Autoloader Reference</title>
        <para></para>
        <!-- @todo -->
    </sect2>

    <!-- @todo
            Write section on using load() functionality
                Potentially add functionality to load() to allow passing arguments
                Show how to use overloading to retrieve class instances
            Write reference section
    -->
</sect1>
