<sect1 id="zend.controller.modular">
    <title>Użycie konwencjonalnej modularnej struktury katalogów</title>

    <sect2 id="zend.controller.modular.introduction">
        <title>Wprowadzenie</title>
        <para>
            Konwencjonalna modularna struktura katalogów pozwala ci na
            oddzielenie różnych aplikacji MVC w osobne jednostki i użycie ich
            z różnymi kontrolerami frontowymi. Przykładem może być taka
            struktura katalogów:
        </para>

        <programlisting role="php"><![CDATA[
docroot/
    index.php
application/
    default/
        controllers/
            IndexController.php
            FooController.php
            models/
            views/
                scripts/
                    index/
                    foo/
                helpers/
                filters/
    blog/
        controllers/
            IndexController.php
        models/
        views/
            scripts/
                index/
            helpers/
            filters/
    news/
        controllers/
            IndexController.php
            ListController.php
        models/
        views/
            scripts/
                index/
                list/
            helpers/
            filters/
]]>
        </programlisting>

        <para>
            W tym modelu, nazwa modułu uwidacznia się jako przedrostek nazw
            kontrolerów, ktore zawiera moduł. Powyższy przykład zawiera trzy
            kontrolery modułów, 'Blog_IndexController', 'News_IndexController',
            oraz 'News_ListController'. Dwa globalne kontrolery, 'IndexController'
            oraz 'FooController' są także zdefiniowane; żaden z nich nie posiada
            własnej przestrzeni nazw. Ta struktura katalogów będzie używana w
            przykładach w tym rozdziale.
        </para>

        <note>
            <title>Brak przestrzeni nazw w domyślnym module</title>
            <para>
                Zauważ, że w domyślnym module nazwa kontrolera nie ma
                przedrostka defniującego przestrzeń nazw. Dlatego w powyższym
                przykładzie kontrolery w domyślnym module nie potrzebują
                przedrostka 'Default_' -- są one po prostu uruchamiane jako
                'IndexController' oraz 'FooController'. Przedrostek definiujący
                przestrzeń nazw jest jednak używany we wszystkich innych
                modułach.
            </para>
        </note>

        <para>
            Więc jak implementujesz taką strukturę katalogów używając
            komponentów MVC Zend Framework?
        </para>
    </sect2>

    <sect2 id="zend.controller.modular.directories">
        <title>Określanie ścieżek kontrolera modułów</title>

        <para>
            Pierwszym krokiem użycia modułów jest zmodyfikowanie sposobu
            określania listy ścieżek do kontrolerów w kontrolerze frontowym.
            W podstawowej wersji MVC, przekazujesz tablicę lub łańcuch znaków
            do metody <code>setControllerDirectory()</code>, lub ścieżkę do
            metody <code>addControllerDirectory()</code>. Gdy używasz modułów,
            musisz także odpowiednio zmienić wywołania tych metod.
        </para>

        <para>
            W metodzie <code>setControllerDirectory()</code>, musisz przekazać
            tablicę asocjacyjną i określić pary klucz/wartość w postaci
            moduł/ścieżka. Specjalny klucz <code>default</code> będzie użyty dla
            globalnych kontrolerów (tych, które nie potrzebują przestrzeni nazw).
            Wszystkie wpisy powinny zawierać łańcuch znaków wskazujący na
            pojedynczą ścieżkę, a klucz <code>default</code> musi istnieć. Na
            przykład:
        </para>

        <programlisting role="php"><![CDATA[
$front->setControllerDirectory(array(
      'default' => '/path/to/application/controllers',
      'blog'    => '/path/to/application/blog/controllers'
));
]]>
        </programlisting>

        <para>
            Metoda <code>addControllerDirectory()</code> przyjmuje opcjonalny
            drugi argument. Gdy używasz modułów, przekaż nazwę modułu jak drugi
            argument; jeśli nie określisz drugiego argumentu, ścieżka zostanie
            dodana dla domyślnej przestrzeni nazw. Na przykład:
        </para>

        <programlisting role="php"><![CDATA[
$front->addControllerDirectory('/path/to/application/news/controllers', 'news');
]]>
        </programlisting>

        <para>
            Zostawiając najlepsze na koniec, najprostszym sposobem określenia
            katalogu modułów jest określenie ich wszystkich na raz, gdy
            wszystkie moduły znajdują się w jednym katalogu i posiadają taką
            samą strukturę. Można to zrobić za pomocą metody
            <code>addModuleDirectory()</code>:
        </para>

        <programlisting role="php"><![CDATA[
/**
 * Zakładając, że tak wygląda struktura katalogów:
 * application/
 *     modules/
 *         default/
 *             controllers/
 *         foo/
 *             controllers/
 *         bar/
 *             controllers/
 */
$front->addModuleDirectory('/path/to/application/modules');
]]>
        </programlisting>

        <para>
            Powyższy przykład definiuje moduły <code>default</code>,
            <code>foo</code>, oraz <code>bar</code>, każdy wskazujący na
            podkatalog <code>controllers</code> danego modułu.
        </para>

        <para>
            Możesz określić nazwę podkatalogu kontrolerów używaną w modułach
            za pomocą metody <code>setModuleControllerDirectoryName()</code>:
        </para>

        <programlisting role="php"><![CDATA[
/**
 * Zmieniamy nazwę podkatalogu kontrolerów na 'con'
 * application/
 *     modules/
 *         default/
 *             con/
 *         foo/
 *             con/
 *         bar/
 *             con/
 */
$front->setModuleControllerDirectoryName('con');
$front->addModuleDirectory('/path/to/application/modules');
]]>
        </programlisting>

        <note><para>
            Możesz określić aby podkatalog kontrolerów nie był używany w
            modułach, przekazując pustą wartość do metody
            <code>setModuleControllerDirectoryName()</code>.
        </para></note>
    </sect2>

    <sect2 id="zend.controller.modular.router">
        <title>Dopasowanie tras do modułów</title>

        <para>
            Domyślna trasa w
            <code>Zend_Controller_Router_Rewrite</code> jest obiektem typu
            <code>Zend_Controller_Router_Route_Module</code>. Ta trasa obsługuje
            takie schematy routingu:
        </para>

        <itemizedlist>
            <listitem><para><code>:module/:controller/:action/*</code></para></listitem>
            <listitem><para><code>:controller/:action/*</code></para></listitem>
        </itemizedlist>

        <para>
            Innymi słowy, dopasuje ona tylko kontroler oraz akcję, lub wraz
            z poprzedzającym je modułem. Zasady dopasowania określają, że
            moduł będzie dopasowany tylko wtedy, gdy klucz o takiej samej nazwie
            istnieje w tablicy ze ścieżkami kontrolerów przekazanej do kontrolera
            frontowego i obiektu uruchamiającego.
        </para>

    </sect2>

    <sect2 id="zend.controller.modular.defaultcontroller">
        <title>Moduł lub globalny domyślny kontroler</title>

        <para>
            W domyślnym routerze jeśli w URL nie został określony kontroler,
            użyty zostanie domyślny kontroler (<code>IndexController</code>,
            jeśli nie określono inaczej). Gdy używamy kontrolerów modularnych,
            jeśli moduł został określony, ale kontroler nie, obiekt
            uruchamiający wpierw będzie szukał domyślnego kontrolera w ścieżce
            modułu, a w drugiej kolejności będzie szukał w ścieżce dla domyślnej
            globalnej przestrzeni nazw 'default'.
        </para>

        <para>
            Jeśli chcesz zawsze używać domyślnej przestrzeni nazw, ustaw
            parametr <code>useDefaultControllerAlways</code> w kontrolerze frontowym:
        </para>

        <programlisting role="php"><![CDATA[
$front->setParam('useDefaultControllerAlways', true);
]]>
        </programlisting>
    </sect2>
</sect1>