<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.form.quickstart">
    <title>Szybki start z Zend_Form</title>

    <para>
        Ten przewodnik opisuje podstawy tworzenia, weryfikacji oraz
        renderowania formularzy za pomocą komponentu <classname>Zend_Form</classname>.
    </para>

    <sect2 id="zend.form.quickstart.create">
        <title>Tworzenie obiektu formularza</title>

        <para>
            Tworzenie obiektu formularza jest bardzo proste: należy, po prostu, utworzyć
            egzemplarz klasy <classname>Zend_Form</classname>:
        </para>

        <programlisting language="php"><![CDATA[
$form = new Zend_Form;
]]>
        </programlisting>

        <para>
            W zaawansowanych przypadkach można rozszerzyć klasę
            <classname>Zend_Form</classname>, ale dla prostych formularzy wystarczy utworzenie
            i skonfigurowanie formularza za pomocą obiektu <classname>Zend_Form</classname>.
        </para>

        <para>
            Dla określenia akcji oraz metody wywołania formularza, można
            użyć metod dostępowych <methodname>setAction()</methodname> oraz
            <methodname>setMethod()</methodname>:
        </para>

        <programlisting language="php"><![CDATA[
$form->setAction('/resource/process')
     ->setMethod('post');
]]>
        </programlisting>

        <para>
            Powyższy kod ustawia akcję formularza na adres <acronym>URL</acronym>
            "<filename>/resource/process</filename>" oraz metodę wykonania formularza na
            <acronym>HTTP</acronym> <acronym>POST</acronym>.
            Będzie to wzięte pod uwagę podczas renderowania formularza.
        </para>

        <para>
            Można ustawić dodatkowe atrybuty dla znacznika
            <emphasis>&lt;form&gt;</emphasis> używając metod <methodname>setAttrib()</methodname>
            lub <methodname>setAttribs()</methodname>. Przykładowo aby ustawić identyfikator,
            należy ustawić atrybut "<property>id</property>":
        </para>

        <programlisting language="php"><![CDATA[
$form->setAttrib('id', 'login');
]]>
        </programlisting>
    </sect2>

    <sect2 id="zend.form.quickstart.elements">
        <title>Dodawanie elementów do formularza</title>

        <para>
            Formularz jest bezużyteczny jeśli nie posiada elementów.
            Komponent <classname>Zend_Form</classname> posiada kilkanaście domyślnych
            elementów które mogą być renderowane do postaci <acronym>XHTML</acronym> za pomocą
            klas pomocniczych <classname>Zend_View</classname>. Te elementy to:
        </para>

        <itemizedlist>
            <listitem><para>
                button (przycisk)
            </para></listitem>

            <listitem><para>
                checkbox (pole wyboru lub wiele pól za pomocą multiCheckbox)
            </para></listitem>

            <listitem><para>
                hidden (pole ukryte)
            </para></listitem>

            <listitem><para>
                image (obrazek)
            </para></listitem>

            <listitem><para>
                password (hasło)
            </para></listitem>

            <listitem><para>
                radio (pole opcji)
            </para></listitem>

            <listitem><para>
                reset (przycisk resetujący)
            </para></listitem>

            <listitem><para>
                select (lista zwykła oraz lista wielokrotnego wyboru)
            </para></listitem>

            <listitem><para>
                submit (przycisk wysyłający)
            </para></listitem>

            <listitem><para>
                text (pole tekstowe)
            </para></listitem>

            <listitem><para>
                textarea (wieloliniowe pole tekstowe)
            </para></listitem>
        </itemizedlist>

        <para>
            Istnieją dwie możliwości dodania elementów do formularza: utworzenie
            egzemplarza konkretnego elementu i przekazanie go do obiektu formularza lub
            po prostu przekazanie typu elementu i pozwolenie obiektowi
            <classname>Zend_Form</classname> na automatyczne utworzenie egzemplarzy
            obiektów określonego typu.
        </para>

        <para>
            Kilka przykładów:
        </para>

        <programlisting language="php"><![CDATA[
// Utworzenie egzemplarza elementu i przekazanie go do obiektu formularza:
$form->addElement(new Zend_Form_Element_Text('username'));

// Przekazanie typu elementu do obiektu:
$form->addElement('text', 'username');
]]>
        </programlisting>

        <para>
            Domyślnie, elementy te nie posiadają filtrów ani walidatorów.
            Oznacza to że należy samodzielnie skonfigurować dla nich
            walidatory i opcjonalnie filtry. Można to zrobić (a) przed
            przekazaniem elementu do formularza, (b) za pomocą opcji
            konfiguracyjnych przekazanych podczas tworzenia elementu poprzez
            obiekt <classname>Zend_Form</classname> lub (c) pobierając istniejący element
            z obiektu formularza i konfigurując go.
        </para>

        <para>
            Najpierw należy przyjrzeć się tworzeniu walidatorów dla konkretnego
            egzemplarza elementu. Można przekazać obiekt
            <classname>Zend_Validate_*</classname> lub nazwę walidatora który ma zostać
            użyty:
        </para>

        <programlisting language="php"><![CDATA[
$username = new Zend_Form_Element_Text('username');

// Przekazanie obiektu Zend_Validate_*:
$username->addValidator(new Zend_Validate_Alnum());

// Przekazanie nazwy walidatora:
$username->addValidator('alnum');
]]>
        </programlisting>

        <para>
            Dla drugiego sposobu, można przekazać w trzecim parametrze metody
            tablicę z argumentami konstruktora wybranego walidatora. 
        </para>

        <programlisting language="php"><![CDATA[
// Przekazanie wzoru
$username->addValidator('regex', false, array('/^[a-z]/i'));
]]>
        </programlisting>

        <para>
            (Drugi parametr jest używany aby określić czy niepowodzenie w
            weryfikacji ma przerwać następne weryfikacje czy nie; domyślnie
            ma wartość <constant>FALSE</constant>.)
        </para>

        <para>
            Można także określić element jako wymagany. Aby to osiągnąć należy
            użyć metody dostępowej lub przekazać opcję podczas tworzenia
            elementu. Oto pierwszy sposób:
        </para>

        <programlisting language="php"><![CDATA[
// Ustawienie elementu jako wymaganego:
$username->setRequired(true);
]]>
        </programlisting>

        <para>
            Gdy element jest wymagany, dodawany jest walidator 'NotEmpty' na
            sam początek łańcucha walidatorów, dzięki czemu można być pewnym,
            że element będzie posiadał wartość.
        </para>

        <para>
            Filtry są rejestrowane w taki sam sposób jak walidatory. Aby
            pokazać jak działają, można dodać filtr zamieniający znaki na małe
            litery:
        </para>

        <programlisting language="php"><![CDATA[
$username->addFilter('StringtoLower');
]]>
        </programlisting>

        <para>
            Finalnie konfiguracja elementu może wyglądać tak:
        </para>

        <programlisting language="php"><![CDATA[
$username->addValidator('alnum')
         ->addValidator('regex', false, array('/^[a-z]/'))
         ->setRequired(true)
         ->addFilter('StringToLower');

// lub bardziej zwięźle:
$username->addValidators(array('alnum',
        array('regex', false, '/^[a-z]/i')
    ))
    ->setRequired(true)
    ->addFilters(array('StringToLower'));
]]>
        </programlisting>

        <para>
            Tworzenie obiektu dla każdego z elementów formularza może być
            nieco kłopotliwe. Można spróbować użyć sposobu (b) przedstawionego
            wyżej. Podczas tworzenia nowego elementu metodą
            <methodname>Zend_Form::addElement()</methodname> jako fabryki, można
            opcjonalnie przekazać również opcje konfiguracyjne. Obejmuje to także
            konfigurację filtrów i walidatorów. Aby to zrobić można użyć kodu:
        </para>

        <programlisting language="php"><![CDATA[
$form->addElement('text', 'username', array(
    'validators' => array(
        'alnum',
        array('regex', false, '/^[a-z]/i')
    ),
    'required' => true,
    'filters'  => array('StringToLower'),
));
]]>
        </programlisting>

        <note>
            <para>
                Jeśli w kilku miejscach konfigurowane są elementy za pomocą tych samych
                opcji, można rozważyć stworzenie własnej klasy rozszerzającej
                klasę <classname>Zend_Form_Element</classname> i następnie użycie tej klasy do
                tworzenia własnych elementów. Może to oszczędzić nieco pracy.
            </para>
        </note>
    </sect2>

    <sect2 id="zend.form.quickstart.render">
        <title>Renderowanie formularza</title>

        <para>
            Renderowanie formularza jest proste. Większość elementów używa do
            tego klas pomocniczych <classname>Zend_View</classname>, więc potrzebny będzie
            do tego także obiekt widoku. Istnieją dwie możliwości: użycie metody
            formularza render() lub po prostu wyświetlenie formularza za pomocą
            konstrukcji echo.
        </para>

        <programlisting language="php"><![CDATA[
// Jawnie wywołanie metody render() i przekazanie opcjonalnego obiektu widoku:
echo $form->render($view);

// Zakładając że obiekt widoku został wcześniej ustawiony za pomocą setView():
echo $form;
]]>
        </programlisting>

        <para>
            Domyślnie obiekty <classname>Zend_Form</classname> oraz
            <classname>Zend_Form_Element</classname> używają obiektu widoku zainicjowanego
            w obiekcie <classname>ViewRenderer</classname>, co oznacza, że nie trzeba go
            ręcznie ustawiać dla wzorca MVC Zend Framework. Renderowanie
            formularza w skrypcie widoku jest wtedy bardzo proste:
        </para>

        <programlisting language="php"><![CDATA[
<? echo $this->form ?>
]]>
        </programlisting>

        <para>
            <classname>Zend_Form</classname> używa "dekoratorów" do przeprowadzania
            renderowania. Te dekoratory mogą zastępować zawartość, dodawać
            treść na początku lub na końcu, a także mieć pełny wgląd w
            element przekazany do nich. Można użyć kilku dekoratorów aby
            uzyskać wymagany efekt. Domyślnie <classname>Zend_Form_Element</classname>
            używa czterech dekoratorów aby wygenerować kod wyjściowy. Wygląda
            to w taki sposób:
        </para>

        <programlisting language="php"><![CDATA[
$element->addDecorators(array(
    'ViewHelper',
    'Errors',
    array('HtmlTag', array('tag' => 'dd')),
    array('Label', array('tag' => 'dt')),
));
]]>
        </programlisting>

        <para>
            (Gdzie &lt;HELPERNAME&gt; jest nazwą klasy pomocniczej widoku, która
            ma być użyta. Może ona różnić się dla różnych elementów.)
        </para>

        <para>
            Układ dekoratorów przedstawiony powyżej generuje następujący kod:
        </para>

        <programlisting language="html"><![CDATA[
<dt><label for="username" class="required">Username</dt>
<dd>
    <input type="text" name="username" value="123-abc" />
    <ul class="errors">
        <li>'123-abc' has not only alphabetic and digit characters</li>
        <li>'123-abc' does not match against pattern '/^[a-z]/i'</li>
    </ul>
</dd>
]]></programlisting>

        <para>
            (Jednak kod jest inaczej sformatowany.)
        </para>

        <para>
            Można zmienić dekoratory używane przez element jeśli pożądany jest
            inny kod wyjściowy. Należy zapoznać się z rozdziałem poświęconym dekoratorom
            aby uzyskać więcej informacji.
        </para>

        <para>
            Formularz przechodzi poprzez wszystkie elementy i umieszcza je
            wewnątrz znacznika <acronym>HTML</acronym> <emphasis>&lt;form&gt;</emphasis>.
            Akcja i metoda wysyłania formularza podane podczas jego konfigurowania
            zostaną dołączone do znacznika<emphasis>&lt;form&gt;</emphasis>, tak samo jak
            inne atrybuty ustawione za pomocą metody <methodname>setAttribs()</methodname>.
        </para>

        <para>
            Formularz przechodzi przez elementy w takiej kolejności w jakiej
            były one zarejestrowane lub jeśli określony element zawiera odpowiedni
            atrybut, zostanie on użyty w celu ustalenia kolejności. Można
            ustawiać kolejność elementów używając metody:
        </para>

        <programlisting language="php"><![CDATA[
$element->setOrder(10);
]]></programlisting>

        <para>
            Innym sposobem jest przekazanie kolejności jako opcji podczas tworzenia elementu:
        </para>

        <programlisting language="php"><![CDATA[
$form->addElement('text', 'username', array('order' => 10));
]]></programlisting>
    </sect2>

    <sect2 id="zend.form.quickstart.validate">
        <title>Sprawdzanie poprawności formularza</title>

        <para>
            Po tym jak formularz zostanie wysłany, należy sprawdzić czy pomyślnie
            przeszedł walidację. Każdy element jest sprawdzany w oparciu o
            podane dane. Jeśli nie ma klucza odpowiadającego nazwie elementu, a
            element jest oznaczony jako wymagany, weryfikacja zostanie
            przeprowadzona w oparciu o pustą wartość <constant>NULL</constant>.
        </para>

        <para>
            Skąd pochodzą dane? Możesz użyć tablic <varname>$_POST</varname>,
            <varname>$_GET</varname> lub dowolnych innych źródeł danych
            (np. żądań do web serwisów):
        </para>

        <programlisting language="php"><![CDATA[
if ($form->isValid($_POST)) {
    // dane są poprawne
} else {
    // dane nie są poprawne
}
]]></programlisting>

        <para>
            Przy korzystaniu z żądań AJAX, może zajść potrzeba przeprowadzenia
            weryfikacji pojedynczego elementu lub grupy elementów.
            Metoda <methodname>isValidPartial()</methodname> częściowo sprawdza formularz.
            W przeciwieństwie do metody <methodname>isValid()</methodname>, nie przeprowadza
            ona weryfikacji pól dla elementów których wartości nie zostały podane:
        </para>

        <programlisting language="php"><![CDATA[
if ($form->isValidPartial($_POST)) {
    // dane we wszystkich elementach pomyślnie przyszły weryfikację
} else {
    // jeden lub więcej elementów nie przeszło poprawnie weryfikacji
}
]]>
        </programlisting>

        <para>
            Do częściowej weryfikacji formularza można także użyć metody
            <methodname>processAjax()</methodname>.  W przeciwieństwie do metody
            <methodname>isValidPartial()</methodname>, zwraca ona łańcuch znaków w formacie
            JSON zawierający informacje o błędach.
        </para>

        <para>
            Zakładając że elementy zostały zweryfikowane i są poprawne, można
            pobrać przefiltrowane wartości:
        </para>

        <programlisting language="php"><![CDATA[
$values = $form->getValues();
]]>
        </programlisting>

        <para>
            Jeśli potrzeba niefiltrowanych wartości, należy użyć:
        </para>

        <programlisting language="php"><![CDATA[
$unfiltered = $form->getUnfilteredValues();
]]>
        </programlisting>
    </sect2>

    <sect2 id="zend.form.quickstart.errorstatus">
        <title>Pobieranie informacji o błędach</title>

        <para>
            Formularz nie przeszedł weryfikacji? W większości przypadków
            można po prostu powtórnie wyświetlić formularz, a błędy zostaną
            pokazane używając dekoratorów:
        </para>

        <programlisting language="php"><![CDATA[
if (!$form->isValid($_POST)) {
    echo $form;

    // przekazanie go do obiektu widoku i renderowanie widoku
    $this->view->form = $form;
    return $this->render('form');
}
]]>
        </programlisting>

        <para>
            Dostępne są dwie metody do sprawdzania błędów. Metoda
            <methodname>getErrors()</methodname> zwraca tablicę asocjacyjną zawierającą
            informacje o błędach w postaci nazwa elementu / kody (gdzie kody są
            tablicami kodów błędów). Metoda <methodname>getMessages()</methodname> zwraca
            tablicę asocjacyjną zawierającą informacje o błędach w postaci nazwa
            elementu / komunikaty (gdzie komunikaty są asocjacyjną tablicą w
            postaci kod / komunikat). Jeśli dany element nie zawiera błędów, nie
            będzie zawarty w tablicy.
        </para>
    </sect2>

    <sect2 id="zend.form.quickstart.puttingtogether">
        <title>Złożenie w całość</title>

        <para>
            Teraz można przystąpić do budowy prostego formularza logowania.
            Potrzebne będą elementy:
        </para>

        <itemizedlist>
            <listitem><para>nazwa użytkownika</para></listitem>
            <listitem><para>hasło</para></listitem>
            <listitem><para>przycisk wysyłający</para></listitem>
        </itemizedlist>

        <para>
            Na potrzeby przykładu można załóżyć że poprawna nazwa użytkownika powinna
            składać się jedynie ze znaków alfanumerycznych, powinna zaczynać
            się od litery, jej długość powinna zawierać się między 6 a 12
            znakami. Litery powinny zostać zamienione na małe. Hasło musi
            składać się minimalnie z 6 znaków. Wartość przycisku wysyłającego
            formularz można zignorować, więc nie musi podlegać walidacji.
        </para>

        <para>
            Aby zbudować formularz można skorzystać z metod konfiguracyjnych obiektu
            <classname>Zend_Form</classname>:
        </para>

        <programlisting language="php"><![CDATA[
$form = new Zend_Form();
$form->setAction('/user/login')
     ->setMethod('post');

// Utworzenie i skonfigurowanie elementu zawierającego nazwę użytkownika:
$username = $form->createElement('text', 'username');
$username->addValidator('alnum')
         ->addValidator('regex', false, array('/^[a-z]+/'))
         ->addValidator('stringLength', false, array(6, 20))
         ->setRequired(true)
         ->addFilter('StringToLower');

// Utworzenie i skonfigurowanie elementu zawierającego hasło:
$password = $form->createElement('password', 'password');
$password->addValidator('StringLength', false, array(6))
         ->setRequired(true);

// Dodanie elementów do formularza:
$form->addElement($username)
     ->addElement($password)
     // użycie metody addElement() jako fabryki tworzącej przycisk 'Zaloguj':
     ->addElement('submit', 'login', array('label' => 'Zaloguj'));
]]></programlisting>

        <para>
            Następnie należy utworzyć kontroler obsługujący formularz:
        </para>

        <programlisting language="php"><![CDATA[
class UserController extends Zend_Controller_Action
{
    public function getForm()
    {
        // tworzenie formularza jak wyżej
        return $form;
    }

    public function indexAction()
    {
        // renderowanie skryptu user/form.phtml
        $this->view->form = $this->getForm();
        $this->render('form');
    }

    public function loginAction()
    {
        if (!$this->getRequest()->isPost()) {
            return $this->_forward('index');
        }
        $form = $this->getForm();
        if (!$form->isValid($_POST)) {
            // Weryfikacja nieudana, ponowne wyświetlenie formularza
            $this->view->form = $form;
            return $this->render('form');
        }

        $values = $form->getValues();
        // Weryfikacja udana, można próbować uwierzytelnić
    }
}
]]></programlisting>

        <para>
            Utworzenie skryptu widoku wyświetlającego formularz:
        </para>

        <programlisting language="php"><![CDATA[
<h2>Zaloguj się:</h2>
<?= $this->form ?>
]]></programlisting>

        <para>
            Jak nietrudno zauważyć, w kod kontrolera może wymagać trochę dodatkowej
            pracy: jeśli wysłane dane będą poprawne, należy przeprowadzić
            uwierzytelnienie używając np. klasy <classname>Zend_Auth</classname>.
        </para>
    </sect2>

    <sect2 id="zend.form.quickstart.config">
        <title>Użycie obiektu Zend_Config</title>

        <para>
            Wszystkie klasy <classname>Zend_Form</classname> można skonfigurować za pomocą
            komponentu <classname>Zend_Config</classname>. Można przekazać obiekt klasy
            <classname>Zend_Config</classname> do konstruktora lub przekazać go za pomocą
            metody <methodname>setConfig()</methodname>.
            Oto jak można utworzyć powyższy formularz używając pliku INI.
            Najpierw, biorąc pod uwagę zalecenia, należy umieścić konfigurację
            w sekcjach odnoszących się do typu
            wdrożenia aplikacji i skupić się na sekcji 'development'.
            Następnie należy utwórzyć sekcję dla danego kontrolera ('user'), oraz klucz
            dla formularza ('login'):
        </para>

        <programlisting language="ini"><![CDATA[
[development]
; ogólna konfiguracja formularza
user.login.action = "/user/login"
user.login.method = "post"

; nazwa użytkownika
user.login.elements.username.type = "text"
user.login.elements.username.options.validators.alnum.validator = "alnum"
user.login.elements.username.options.validators.regex.validator = "regex"
user.login.elements.username.options.validators.regex.options.pattern = "/^[a-z]/i"
user.login.elements.username.options.validators.strlen.validator = "StringLength"
user.login.elements.username.options.validators.strlen.options.min = "6"
user.login.elements.username.options.validators.strlen.options.max = "20"
user.login.elements.username.options.required = true
user.login.elements.username.options.filters.lower.filter = "StringToLower"

; hasło
user.login.elements.password.type = "password"
user.login.elements.password.options.validators.strlen.validator = "StringLength"
user.login.elements.password.options.validators.strlen.options.min = "6"
user.login.elements.password.options.required = true

; przycisk wysyłający
user.login.elements.submit.type = "submit"
]]></programlisting>

        <para>
            Powyższe można przekazać do konstruktora obiektu formularza:
        </para>

        <programlisting language="php"><![CDATA[
$config = new Zend_Config_Ini($configFile, 'development');
$form   = new Zend_Form($config->user->login);
]]></programlisting>

        <para>
            w ten sposób cały formularz został zdefiniowany.
        </para>
    </sect2>

    <sect2 id="zend.form.quickstart.conclusion">
        <title>Podsumowanie</title>

        <para>
            Dzięki temu przewodnikowi czytelnik powinien być na dobrej drodze do wykorzystania mocy
            i elastyczności komponentu <classname>Zend_Form</classname>. Aby uzyskać
            bardziej szczegółowe informacje należy zapoznać się z dalszymi częściami dokumentacji.
        </para>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
