<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 21826 -->
<!-- Reviewed: yes -->
<sect1 id="learning.quickstart.create-project">
    <title>Utworzenie projektu</title>

    <para>
        Aby utworzyć nowy projekt należy wcześniej pobrać i rozpakować Zend Framework.
    </para>

    <sect2 id="learning.quickstart.create-project.install-zf">
        <title>Instalacja Zend Framework</title>

        <para>
            Najprostszym sposobem pobrania Zend Framework razem z całym środowiskiem
            <acronym>PHP</acronym> jest zainstalowanie
            <ulink url="http://www.zend.com/en/products/server-ce/downloads">Zend Server</ulink>.
            Zend Server zawiera instalatory dla Mac OS X, Windows, Fedora Core oraz Ubuntu.
            Oprócz tego dostępna jest uniwersalna paczka instalacyjna kompatybilna z większością
            dystrybucji Linux.
        </para>

        <para>
            Po zainstalowaniu Zend Server, pliki frameworka są dostępne w katalogu
            <filename>/usr/local/zend/share/ZendFramework</filename> dla Mac OS X oraz Linux,
            lub <filename>C:\Program Files\Zend\ZendServer\share\ZendFramework</filename> dla
            Windows. Zmienna <constant>include_path</constant> będzie automatycznie ustawiona
            tak aby obejmowała Zend Framework.
        </para>

        <para>
            Alternatywnie można <ulink url="http://framework.zend.com/download/latest">pobrać
            najnowszą wersję Zend Framework</ulink> i rozpakować zawartość do dowolnego katalogu;
            należy zapamiętać wybraną lokalizację instalacji.
        </para>

        <para>
            Opcjonalnie w pliku <filename>php.ini</filename> można umieścić w
            zmiennej <constant>include_path</constant> ścieżkę do
            podkatalogu <filename>library/</filename> znajdującego się w pobranym archiwum.
        </para>

        <para>
            Instalacja zakończona! Zend Framework jest zainstalowany i gotowy do użycia.
        </para>
    </sect2>

    <sect2 id="learning.quickstart.create-project.create-project">
        <title>Tworzenie projektu</title>

        <note>
            <title>Narzędzie wiersza poleceń zf</title>

            <para>
                W katalogu instalacji Zend Framework znajduje się podkatalog
                <filename>bin/</filename>.
                Zawiera on skrypty <filename>zf.sh</filename> oraz <filename>zf.bat</filename>
                odpowiednio dla użytkowników Unix oraz Windows. Należy zapamiętać ścieżkę dostępu
                do tych skryptów.
            </para>

            <para>
                Jeśli w dokumentacji pojawią się odniesienia do komendy <command>zf</command>,
                proszę pamiętać o zastąpieniu ich pełną ścieżką dostępu do odpowiedniego skryptu.
                Dla systemów Unix można skorzystać z polecenia alias:
                <command>alias zf.sh=path/to/ZendFramework/bin/zf.sh</command>.
            </para>

            <para>
                W przypadku problemów z konfiguracją narzędzia wiersza poleceń proszę zapoznać się
                z <link linkend="zend.tool.framework.clitool.setup-general">jego instrukcją</link>.
            </para>
        </note>

        <para>
            Aby utworzyć nowy projekt należy otworzyć terminal (dla Windows - wiersz polecenia
            <command>Start -> Run</command> i polecenie <command>cmd</command>). Należy przejść do
            katalogu nowego projektu. Następnie, używając ścieżki do odpowiedniego skryptu, należy
            wywołać następujące polecenie:
        </para>

        <programlisting language="shell"><![CDATA[
% zf create project quickstart
]]></programlisting>

        <para>
            Wywołanie tego polecenia spowoduje utworzenie podstawowej struktury katalogów, razem
            z początkowymi kontrolerami i widokami. Drzewo katalogów powinno wyglądać podobnie do
            poniższego:
        </para>

        <programlisting language="text"><![CDATA[
quickstart
|-- application
|   |-- Bootstrap.php
|   |-- configs
|   |   `-- application.ini
|   |-- controllers
|   |   |-- ErrorController.php
|   |   `-- IndexController.php
|   |-- models
|   `-- views
|       |-- helpers
|       `-- scripts
|           |-- error
|           |   `-- error.phtml
|           `-- index
|               `-- index.phtml
|-- library
|-- public
|   |-- .htaccess
|   `-- index.php
`-- tests
    |-- application
    |   `-- bootstrap.php
    |-- library
    |   `-- bootstrap.php
    `-- phpunit.xml
]]></programlisting>

        <para>
            W tym momencie, jeśli Zend Framework nie jest umieszczony w zmiennej
            <constant>include_path</constant>, zaleca się skopiowanie lub umieszczenie
            linku symbolicznego do podkatalogu <filename>library/</filename> projektu.
            Najistotniejsze jest aby zawartość katalogu <filename>library/Zend/</filename>
            instalacji Zend Framework była dostępna w katalogu <filename>library/</filename>
            projektu. Na systemach Unix można tego dokonać za pomocą następujących poleceń:
        </para>

        <programlisting language="shell"><![CDATA[
# Symlink:
% cd library; ln -s path/to/ZendFramework/library/Zend .

# Kopia:
% cd library; cp -r path/to/ZendFramework/library/Zend .
]]></programlisting>

        <para>
            W systemach Windows najprostszym rozwiązaniem będzie wykonanie tego z poziomu Explorera.
        </para>

        <para>
            Teraz, kiedy nowy projekt jest utworzony należy zapoznać się z podstawowymi założeniami:
            bootstrapem, konfiguracją, kontrolerami oraz widokami.
        </para>
    </sect2>

    <sect2 id="learning.quickstart.create-project.bootstrap">
        <title>Bootstrap</title>

        <para>
            Klasa <classname>Bootstrap</classname> definiuje zasoby i komponenty do inicjalizacji.
            Domyślnie uruchamiany jest <link linkend="zend.controller.front">kontroler frontowy</link>
            ze standardowym katalogiem w którym szukane są kontrolery akcji (o których mowa później)
            ustawionym na <filename>application/controllers/</filename>. Klasa przedstawia się
            następująco:
        </para>

        <programlisting language="php"><![CDATA[
// application/Bootstrap.php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
}
]]></programlisting>

        <para>
            Jak widać, na początek wymagane jest niewiele.
        </para>
    </sect2>

    <sect2 id="learning.quickstart.create-project.configuration">
        <title>Konfiguracja</title>

        <para>
            Sam Zend Framework nie wymaga konfiguracji ale tworzona aplikacja - najczęściej tak.
            Standardowo plik konfiguracyjny umieszczony jest w
            <filename>application/configs/application.ini</filename>. Zawiera on podstawowe
            instrukcje ustawienia środowiska <acronym>PHP</acronym>
            (np. włączanie/wyłączanie raportowania błędów),
            wskazanie ścieżki i klasy <classname>Bootstrap</classname> oraz ścieżkę do katalogu
            kontrolerów akcji. Domyślny plik wygląda następująco:
        </para>

        <programlisting language="ini"><![CDATA[
; application/configs/application.ini

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
]]></programlisting>

        <para>
            Należy zwrócić uwagę na kilka cech tego pliku. Po pierwsze, używając konfiguracji
            w pliku <acronym>INI</acronym>, można bezpośrednio używać stałych;
            <constant>APPLICATION_PATH</constant> to stała PHP (opisana później).
            Dodatkowo, zdefiniowane zostały oddzielne sekcje:
            production, staging, testing oraz development. Ostatnie trzy dziedziczą ustawienia ze
            środowiska produkcyjnego (production). Podany sposób stanowi użyteczny przykład
            organizacji konfiguracji, dzięki której odpowiednie ustawienia są dostępne w
            odpowiednim momencie cyklu rozwoju oprogramowania.
        </para>
    </sect2>

    <sect2 id="learning.quickstart.create-project.action-controllers">
        <title>Kontrolery akcji (action controllers)</title>

        <para>
            Zawarte w aplikacji <emphasis>kontrolery akcji</emphasis> przechowują ścieżki
            działania programu i odwzorowują żądania na odpowiednie modele i widoki.
        </para>

        <para>
            Kontroler akcji powinien posiadać co najmniej jedną metodę o nazwie zakończonej na
            "Action". Te metody stają się dostępne dla użytkowników. Domyślnie URLe w Zend
            Framework stosują schemat <constant>/kontroler/akcja</constant>, gdzie
            "kontroler" jest odwzorowany na nazwę kontrolera akcji
            (z pominięciem sufiksu "Controller")
            a "akcja" jest odwzorowana na metodę w tym kontrolerze
            (z pominięciem sufiksu "Action").
        </para>

        <para>
            W typowym projekcie niezbędny jest kontroler <classname>IndexController</classname>,
            który jest początkowym punktem odniesienia i stanowi stronę początkową aplikacji,
            oraz <classname>ErrorController</classname> czyli kontroler obsługujący błędy
            <acronym>HTTP</acronym> 404 (brak kontrolera i/lub akcji) lub
            <acronym>HTTP</acronym> 500 (błąd aplikacji).
        </para>

        <para>
            Domyślnie <classname>IndexController</classname> wygląda następująco:
        </para>

        <programlisting language="php"><![CDATA[
// application/controllers/IndexController.php

class IndexController extends Zend_Controller_Action
{

    public function init()
    {
        /* Inicjalizacja kontrolera akcji */
    }

    public function indexAction()
    {
        // ciało akcji
    }
}
]]></programlisting>

        <para>
            Domyślny <classname>ErrorController</classname> przedstawia się jak poniżej:
        </para>

        <programlisting language="php"><![CDATA[
// application/controllers/ErrorController.php

class ErrorController extends Zend_Controller_Action
{

    public function errorAction()
    {
        $errors = $this->_getParam('error_handler');

        switch ($errors->type) {
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:

                // błąd 404 -- brak kontrolera i/lub akcji
                $this->getResponse()->setHttpResponseCode(404);
                $this->view->message = 'Page not found';
                break;
            default:
                // błąd aplikacji
                $this->getResponse()->setHttpResponseCode(500);
                $this->view->message = 'Application error';
                break;
        }

        $this->view->exception = $errors->exception;
        $this->view->request   = $errors->request;
    }
}
]]></programlisting>

        <para>
            Należy zwrócić uwagę, iż <classname>IndexController</classname> nie zawiera żadnego
            kodu oraz <classname>ErrorController</classname> odnosi się do właściwości "view". To
            prowadzi do następnego tematu.
        </para>
    </sect2>

    <sect2 id="learning.quickstart.create-project.views">
        <title>Widoki (views)</title>

        <para>
            Widoki (view scripts) w Zend Framework są napisane w starym dobrym
            <acronym>PHP</acronym>. Domyślnie
            znajdują się w <filename>application/views/scripts/</filename>, gdzie są w dalszym
            stopniu dzielone wg kontrolerów do których należą. W obecnym przypadku istnieją
            dwa kontrolery: <classname>IndexController</classname> oraz
            <classname>ErrorController</classname>. Oznacza to, że w katalogu widoków powinny się
            znaleźć dwa podkatalogi: <filename>index/</filename> oraz <filename>error/</filename>.
            W nich należy umieścić skrypty widoków odpowiednie dla każdej z akcji danego kontrolera.
            Domyślnie tworzone są skrypty <filename>index/index.phtml</filename> oraz
            <filename>error/error.phtml</filename>.
        </para>

        <para>
            Skrypty widoków mogą zawierać dowolny kod <acronym>HTML</acronym>
            i używać <code>&lt;?php</code> jako tagów
            otwarcia i <code>?&gt;</code> jako tagów zamknięcia dla poleceń <acronym>PHP</acronym>.
        </para>

        <para>
            Domyślnie skrypt <filename>index/index.phtml</filename> zawiera następującą zawartość:
        </para>

        <programlisting language="php"><![CDATA[
<!-- application/views/scripts/index/index.phtml -->
<style>

    a:link,
    a:visited
    {
        color: #0398CA;
    }

    span#zf-name
    {
        color: #91BE3F;
    }

    div#welcome
    {
        color: #FFFFFF;
        background-image: url(http://framework.zend.com/images/bkg_header.jpg);
        width:  600px;
        height: 400px;
        border: 2px solid #444444;
        overflow: hidden;
        text-align: center;
    }

    div#more-information
    {
        background-image: url(http://framework.zend.com/images/bkg_body-bottom.gif);
        height: 100%;
    }

</style>
<div id="welcome">
    <h1>Welcome to the <span id="zf-name">Zend Framework!</span><h1 />
    <h3>This is your project's main page<h3 />
    <div id="more-information">
        <p>
            <img src="http://framework.zend.com/images/PoweredBy_ZF_4LightBG.png" />
        </p>

        <p>
            Helpful Links: <br />
            <a href="http://framework.zend.com/">Zend Framework Website</a> |
            <a href="http://framework.zend.com/manual/en/">Zend Framework
                Manual</a>
        </p>
    </div>
</div>
]]></programlisting>

        <para>
            Skrypt <filename>error/error.phtml</filename> jest nieco bardziej interesujący - używa
            instrukcji warunkowych <acronym>PHP</acronym>:
        </para>

        <programlisting language="php"><![CDATA[
<!-- application/views/scripts/error/error.phtml -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN";
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Zend Framework Default Application</title>
</head>
<body>
  <h1>An error occurred</h1>
  <h2><?php echo $this->message ?></h2>

  <?php if ('development' == $this->env): ?>

  <h3>Exception information:</h3>
  <p>
      <b>Message:</b> <?php echo $this->exception->getMessage() ?>
  </p>

  <h3>Stack trace:</h3>
  <pre><?php echo $this->exception->getTraceAsString() ?>
  </pre>

  <h3>Request Parameters:</h3>
  <pre><?php echo var_export($this->request->getParams(), 1) ?>
  </pre>
  <?php endif ?>

</body>
</html>
]]></programlisting>
    </sect2>

    <sect2 id="learning.quickstart.create-project.vhost">
        <title>Utworzenie wirtualnego hosta</title>

        <para>
            Na potrzeby tego wprowadzenia, założono użycie <ulink url="http://httpd.apache.org/">
            web serwera Apache</ulink>. Zend Framework działa równie dobrze z innymi
            serwerami - włączając Microsoft Internet Information Services, lighttpd, nginx i
            wiele innych. Większość programistów jednak jest najbardziej zaznajomiona z Apache, który
            ułatwia zrozumienie struktury katalogów Zend Framework i posiada szerokie możliwości
            przepisywania linków (mod_rewrite).
        </para>

        <para>
            Aby utworzyć wirtualnego hosta należy odnaleźć plik <filename>httpd.conf</filename> oraz
            ewentualne pozostałe pliki konfiguracyjne serwera. Popularne katalogi:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <filename>/etc/httpd/httpd.conf</filename> (Fedora, RHEL i inne)
                </para>
            </listitem>

            <listitem>
                <para>
                    <filename>/etc/apache2/httpd.conf</filename> (Debian, Ubuntu i inne)
                </para>
            </listitem>

            <listitem>
                <para>
                    <filename>/usr/local/zend/etc/httpd.conf</filename> (Zend Server
                    na maszynach *nix)
                </para>
            </listitem>

            <listitem>
                <para>
                    <filename>C:\Program Files\Zend\Apache2\conf</filename> (Zend Server
                    na maszynach Windows)
                </para>
            </listitem>
        </itemizedlist>

        <para>
            W pliku <filename>httpd.conf</filename> (lub <filename>httpd-vhosts.conf</filename>
            dla niektórych systemów) należy dokonać dwóch zmian. Po pierwsze - upewnić się, że
            jest zainicjowana zmienna <varname>NameVirtualHost</varname>; Typowe ustawienie to
            "*:80". Po drugie - zdefiniować wirtualnego hosta:
        </para>

        <programlisting language="apache"><![CDATA[
<VirtualHost *:80>
    ServerName quickstart.local
    DocumentRoot /sciezka/do/quickstart/public

    SetEnv APPLICATION_ENV "development"

    <Directory /sciezka/do/quickstart/public>
        DirectoryIndex index.php
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>
]]></programlisting>

        <para>
            Należy zwrócić uwagę na kilka szczegółów. Po pierwsze, <varname>DocumentRoot</varname>
            wskazuje na podkatalog projektu o nazwie <filename>public</filename>. To oznacza, że
            jedynie pliki znajdujące się w tym podkatalogu mogą być zwracane przez serwer
            bezpośrednio. Po drugie, instrukcje <varname>AllowOverride</varname>,
            <varname>Order</varname> oraz <varname>Allow</varname> umożliwiają stosowanie plików
            <filename>htacess</filename> w projekcie. W środowisku programistycznym (development)
            jest to uznawane za dobrą praktykę ponieważ eliminuje potrzebę resetowania
            serwera po każdej zmianie instrukcji konfiguracyjnych. Jednak w środowisku produkcyjnym
            (production), zalecane jest przeniesienie zawartości pliku <filename>htaccess</filename>
            do głównego pliku konfiguracyjnego serwera oraz wyłączenie obsługi
            <filename>htaccess</filename>. Po trzecie, instrukcja
            <varname>SetEnv</varname> pozwala zainicjować zmienną środowiskową oraz
            przekazać ją do PHP i <filename>index.php</filename>.
            Dzięki temu stanie się ona podstawą stałej
            <constant>APPLICATION_ENV</constant> aplikacji Zend Framework.
            W środowisku produkcyjnym można ją ustawić na "production" lub zrezygnować
            z tej instrukcji ("production" jest domyślną wartością stałej
            <constant>APPLICATION_ENV</constant>).
        </para>

        <para>
            Na koniec należy dodać wpis w pliku <filename>hosts</filename> odnoszący się do wartości
            <varname>ServerName</varname>. Na systemach *nix jest to zazwyczaj
            <filename>/etc/hosts</filename>. Na maszynach Windows typową lokalizacją jest
            <filename>C:\WINDOWS\system32\drivers\etc</filename>. Wpis powinien być podobny do:
        </para>

        <programlisting language="text"><![CDATA[
127.0.0.1 quickstart.local
]]></programlisting>

        <para>
            Po uruchomieniu webserwera (lub restarcie) projekt powinien być gotowy do użytku.
        </para>
    </sect2>

    <sect2 id="learning.quickstart.create-project.checkpoint">
        <title>Punkt kontrolny</title>

        <para>
            W tym momencie aplikacja Zend Framework jest gotowa do uruchomienia. Po wpisaniu
            w przeglądarce nazwy serwera (ustalonej w poprzednim punkcie) powinna się pojawić
            strona powitalna.
        </para>
    </sect2>
</sect1>
