Nowości

Zend Framework 2.0 i system formularzy

Witam bardzo serdecznie, W tym artykule chciałbym podzielić się z Wami nowoczesnym podejściem do tematu formularzy obsługiwanych poprzez framework Zend 2.0.Wraz z nowymi możliwościami…

Witam bardzo serdecznie,

W tym artykule chciałbym podzielić się z Wami nowoczesnym podejściem do tematu formularzy obsługiwanych poprzez framework Zend 2.0.Wraz z nowymi możliwościami PHP 5.3, 5.4 czy 5.5 (o 5.6 na razie nie wspominam ponieważ jest w wersji alpha) wiele się zmieniło w samym frameworku jak i sposobie tworzenia bazując na nim.

Zend daje nam do dyspozycji możliwość budowania swoich formularzy za pomocą obiektowego kodu PHP. Z pozoru może wydać się to przerostem formy nad treścią, szczególnie gdy budujemy mniejszą aplikację tudzież stronę internetową. Okazuje się jednak, że taka „rozrzutność” opłaca się. Dzięki wygenerowaniu formularza bazując na programowaniu obiektowym możemy taki formularz bardzo łatwo generować, debugować czy choćby bindować (łączyć) z przesyłanym żądaniem np. POST.

Gdyby tego było jeszcze mało Zend daje nam możliwość filtrowania i walidowania takiego formularza.. oczywiście obiektowo.

Od czego zacząć aby zbudować własny formularz ? Najlepiej od klasy formularza. W wybranym przez siebie module, utwórz katalog Form – będą w nim przechowywane utworzone formularze. Do jego stworzenia posłużymy się metodą określoną jako factory-backed form. Więcej o tej metodzie znajdziesz w dokumentacji. W katalogu Form tworzymy plik o nazwie typu naszego formularza np. logowanie – LoginForm, newsletter – NewsletterForm itd.. pamiętając jedynie o nazewnictwie proponowanym przez Zend’a UpperCamelCase. Powiedzmy, że nazwiemy go NewsletterForm.php

W nowo utworzonym pliku należy dodać przestrzeń nazw np.  Application\Form jeśli tworzymy tą formę w module application oraz zdefiniować klasę nazywającą się w ten sam sposób co nazwa pliku, jednak bez rozszerzenia php. W ciele klasy NewsletterForm dodajemy konstruktor, tak aby całość wyglądała mniej więcej tak:

<?php

namespace Application\Form;

class NewsletterForm extends Form 
{
    public function __construct($name = null) 
    {
        //...
    }
}

?>

Jak na pewno zauważyłeś, klasa NewsletterForm dziedziczy z klasy Form, ze środka framework’a Zend. Jest to niezbędne aby nasza klasa przestała być „bez-imienna” stając się pełnoprawnym formularzem, z wszystkimi właściwościami klasy Form. Oprócz tego musimy zdefiniować lokalizację klasy Form, aby interpreter wiedział skąd ma ją pobrać. W tym celu pod przestrzenią nazw umieszczamy

<?php

namespace Application\Form;

use Zend\Form\Element; 
use Zend\Form\Form; 

// ...

?>

Mamy już naszą bazę. Teraz należy ją wypełnić. Zaczynamy od wybrania metody przesyłu danych naszego formularza np. POST czy GET. W konstruktorze, posługując się metodą z klasy Form o nazwie setAttribute ustawiamy odpowiednie atrybuty np.

$this->setAttribute('method', 'post');

a następnie wykorzystując metodę add z tej samej klasy, dodajemy kolejne elementy formularza. Będą to odpowiednio adres e-mail oraz przycisk Prześlij. Do dzieła.

public function __construct($name = null) 
{
    $this->setAttribute('method', 'post');

    $this->add(array( 
        'name' => 'email', 
        'type' => 'Zend\Form\Element\Text', 
        'attributes' => array( 
            'placeholder' => '@', 
            'required' => 'required', 
        ), 
        'options' => array( 
            'label' => 'E-mail', 
        ), 
    )); 

    $this->add(array(
        'name' => 'submit',
        'attributes' => array(
            'type' => 'submit',
            'value' => 'Prześlij',
            )
        )
    ); 
}

Kilka słów wyjaśnienia dla powyższego kodu. W metodzie add tworzymy strukturę drzewa tablic. Większości z tych elementów nawet nie muszę tłumaczyć. Pod tablica attributes służy do dopinania opcji tworzonego pola. To samo tyczy się przycisku Prześlij.

Mamy nasz formularz. Proste, prawda ? Teraz najważniejszy element – walidacja i obsługa błędów. W środku katalogu Form umieszczamy plik NewsletterFilter.php. Wewnątrz niego klasę NewsletterFilter implementującą interfejs InputFilter. Aby interpreter nie rościł pretnesji, że czegoś mu brakuje dodajmy ścieżki poprzez słowo kluczowe use. Całość powinna wyglądać tak

<?php

namespace Application\Form;

use Zend\InputFilter\InputFilter;

class NewsletterFilter extends InputFilter
{
    // ...
}

?>

Następnie w konstruktorze umieszczamy warunki walidacji odnosząc się do metody add oraz stosując podobną strukturę tablic jak ostatnio.

<?php

namespace Application\Form;

use Zend\InputFilter\InputFilter;

class NewsletterFilter extends InputFilter
{
    public function __construct()
    {
        $this->add(array(
            'name'       => 'email',
            'required'   => true,
            'validators' => array(
                array(
                    'name'    => 'EmailAddress',
                    'options' => array(
                        'domain' => true,
                    ),
                ),
            ),
        ));
    }
}

?>

Jeśli interesuje Was utworzenie profesjonalnej walidacji pól formularza możecie skorzystać z wyrażeń regularnych. Polecić mogę aplikację Expression Studio, w której w „czasie rzeczywistym” można testować swoje wyrażenia oglądając rezultat bez przeładowania. Dodatkowo możesz wyeksportować utworzone wyrażenie do wielu języków programowania.

exs

Warunki walidacji są proste. Odnosimy się do pola określonego poprzez atrybut name (email), sprawdzamy czy pole nie jest puste lub istnieje, stosujemy walidator EmailAddress polegający na tym iż sprawdza on nazwę hosta wprowadzonego adresu e-mail. jest to pełne sprawdzenia całego pola email.

Jeśli jest sprawdzenie to musi być również miejsce aby wykryć potencjalne błędy i je wyświetlić. Wyświetlać będziemy w widoku a sprawdzać w kontrolerze.

Powiedzmy, że mamy utworzony kontroler w naszym module o nazwie NewsletterController (<moduł>src/Application/Controller/NewsletterController.php) oraz dwie metody indexAction oraz processAction. Pierwsza z nich wyświetla formularz, druga przetwarza wprowadzone dane.

use Users\Form\NewsletterForm;

//...
public function indexAction()
{
    $form = new NewsletterForm();
    $viewModel = new ViewModel(array('form' => $form));
    return $viewModel;
}
//...
?>

Formularz tworzymy tak jak zwykły obiekt poprzez słowo kluczowe new. Następnie musimy podać go do widoku jeśli ma by w nim wyświetlony. Plik <moduł>/view/application/newsletter/index.phtml

<?php
    $form = $this->form;
    $form->prepare();
    $form->setAttribute('action', $this->url(NULL, array('controller' => 'newsletter', 'action' => 'process'))); 
?>

<div class="container">
	<h2>Zapisz się!</h2>
	<?=$this->form()->openTag($form)?>
	<?=$this->formLabel($form->get('email'))?>
	<?=$this->formElement($form->get('email'))?>
	<?=$this->formElementErrors($form->get('email'))?>
	<?=$this->formElement($form->get('submit'))?>
	<?=$this->form()->closeTag()?>
</div>

Do lokalnej zmiennej $form wpisujemy to co przechwyciliśmy z kontrolera następnie przygotowujemy formę do wyświetlenia prepare(). Ustawiamy również atrybut, który po zatwierdzeniu formularza przekieruje nas na wybraną stronę. W tym momencie do kontrolera NewsletterController i metody processAction.

Dla każdego z elementów możemy wyświetlić 3 rodzaje pól: Label (opis pola), samo pole (input) oraz element błędu (uaktywniany gdy się pojawi). Formę zamykamy pomiędzy metodami openTag() oraz closeTag – analogia do <form>…</form>

W kontrolerze NewsletterController, towrzymy metodę processAction, która będzie parsowała przesyłane dane. Wypełaniamy ją następującą treścią.

public function processAction()
{
    if(!$this->request->isPost())
    {
        return $this->redirect()->toRoute(null, array('controller' => 'newsletter', 'action' => 'index'));
    }

    $post = $this->request->getPost();
    $form = new NewsletterForm();
    $inputFilter = new \Users\Form\NewsletterFilter();
    $form->setInputFilter($inputFilter);
    $form->setData($post);

    if(!$form->isValid())
    {
        $model = new ViewModel(array('form' => $form));

        $model->setTemplate('users/newsletter/index');
        return $model;
    }

    // ... zapis do bazy mailingowej...

    return $this->redirect()->toRoute(NULL , array('controller' => 'newsletter', 'action' => 'confirm'));
}

Kolejność jest równie prosta. Najpierw sprawdzamy czy żądanie, któro właśnie przyszło jest to POST. Jeśli nie to kierujemy użytkownika na stronę główną formularza, jeśli tak to je przechwytujemy. Potem tworzymy jeszcze raz pustą formę, następnie nowy egzemplarz naszego walidatora NewsletterFilter.

Aby filtr mógł zadziałać musi być połączony z formularzem metodą setInputFilter(). Następnie wypełniamy formularz wcześniej przesłanymi danymi (bindujemy) a w końcowym etapie wywołujemy jego sprawdzenie przez walidator. Jeśli wszystko jest ok, zapisujemy naszego delikwenta do bazy i kierujemy na stronę podziękowania. W przeciwnym razie tworzymy nowy obiekt ViewModel aby móc przekazać zmienne do widoku. Jako że jesteśmy w innej metodzie niż indexAction a chcemy aby wyświetlił się nam szablon index.phtml a nie domyślny dla tej metody process.phtml musimy go ustawić odnosząc się do klasy ViewModel metodą setTemplate(). 

To wszystko 🙂 Gdy wystąpi błąd zobaczymy piękny komunikat. Najlepsze jest jednak w tym wszystkim, że mimo błędu cały formularz jest nadal wypełniony.

Podstawowy błąd

badmail1

Gdy użytkownik jednak wpisze odniesienie się do domeny, która nie istnieje to zobaczy niezbyt przyjemny widok, w którym zadziałała opcja ’domain' => true

badmail2

 

s’il vous plaît!

Serdecznie zapraszam do komentowania i oceniania na moim blogu: http://mateuszmanaj.pl/

manaj project banner

UDOSTĘPNIJ ARTYKUŁ:

Powiązane artykuły

Nowości

Nasz Manifest

Grafika i Interfejsy

Koniec promocji Affinity! Co dalej?

Trwająca od ponad pół roku promocja w sklepie Affinity dobiegła końca. W tym wydaniu chciałbym krótko podsumować co dzięki wspomnianej promocji mogliśmy zyskać oraz czego w dalszej…

Fotografia i Photoshop

Fotografia to też miejsce na zabawę, a nie tylko chłodną kalkulację

Po premierze każdej nowej Leiki czy Hasselblada zawsze podnoszą się głosy, że w tej cenie można mieć lepszy aparat. Tylko czy zawsze musi nam zależeć na najlepszym…

Programowanie i WWW

Proces rekrutacji w IT z różnych perspektyw

Podczas ostatnich konsultacji Full-Stack Dev Q&A padło kilka pytań o proces rekrutacyjny. Ze względu na pozytywny feedback oraz zwrócenie uwagi na istotę tego tematu, pomyślałem że zbiorę…

Pozostań na bieżąco!

Już nigdy nie przegapisz ważnych informacji, promocji oraz nowych kursów. Zapisz się na newsletter już teraz!

Zapisując się do newslettera akceptujesz naszą politykę prywatności