Autor wpisu: Śpiechu, dodany: 05.12.2010 21:32, tagi: zend_framework, php
Dzisiaj będzie coś dla wielbicieli Zend Frameworka. A dokładniej coś, z czym mamy do czynienia przetwarzając jakikolwiek formularz, czyli walidatory. Walidacja, a więc sprawdzanie czy wprowadzone przez użytkownika dane odpowiadają pewnemu schematowi jest obok filtracji, czyli wyrzucaniu zbędnych/niebezpiecznych rzeczy z danych chyba najważniejszą sprawą przy tworzeniu witryn WWW.
Zend Framework dysponuje zestawem kilkudziesięciu walidatorów, które można łączyć w łańcuchy przy walidowaniu poszczególnych pól formularza, np. pytając o wiek użytkownika pole musi zawierać wyłącznie liczby, czyli aż prosi się o Zend_Validate_Digits
, a następnie należy sprawdzić czy podana liczba znajduje się w jakimś ludzkim przedziale, tzn. powiedzmy pomiędzy 1 a 100, co załatwi za nas Zend_Validate_Between
.
Co w przypadku jeżeli musimy dopasowywać coś, czego nie przewidzieli twórcy ZF? Możemy napisać własny walidator.
Każdy walidator musi implementować interfejs Zend_Validate_Interface
, czyli dwie publiczne metody:
isValid($value)
— zwracająca buliona prawda/fałszgetMessages()
— zwracająca tablicę komunikatów co jest nie tak z wartością testowaną w isValid(). Komunikaty zwracane są w postaci kod_błędu => komunikat_w_ludzkiej_formie
W celu uniknięcia babrania się obsługą błędów i komunikatów twórcy ZF stworzyli abstrakcyjną klasę Zend_Validate_Abstract
, która zrobi za nas większość brudnej roboty. Pozostanie nam tylko napisanie właściwej logiki co ma być sprawdzane i ewentualnie jaki błąd zgłaszany.
Na potrzeby swojej aplikacji napisałem własny w miarę uniwersalny walidator, który sprawdzi czy klucz podstawowy danej tablicy istnieje. Może mieć zastosowanie jeżeli ktoś sprawdza czy np. identyfikator wybranej przez użytkownika kategorii istnieje w bazie.
Poniżej przedstawiem kod z objaśnieniami po co coś jest. Po przeczytaniu stwierdzicie, że pisanie walidatorów to fajna zabawa
<?php // rozszerzamy klasę abstrakcyjną dla walidatorów class Spiechu_Validators_IsIdExists extends Zend_Validate_Abstract { // definiujemy kody błędów i jakieś wartości dla nich const IDNOTEXISTS = 'idnotexists'; const EMPTYSTRING = 'emptystring'; const NULLVALUE = 'nullvalue'; // definiujemy tablicę komunikatów błędów dla poszczególnych kodów // zwracam uwagę na '%value', które może być w locie zamienione na sprawdzaną wartość protected $_messageTemplates = array( self::IDNOTEXISTS => "id '%value%' not exists", self::EMPTYSTRING => 'given value is empty', self::NULLVALUE => 'given value is null' ); // zmienna typu Zend_Db_Table_Abstract, której klucz będziemy testować protected $_table; public function __construct(Zend_Db_Table_Abstract $table) { $this->_table = $table; } public function isValid($value) { // sprawdzamy czy zmienna nie jest nulem, a jeżeli tak to ustawiamy błąd if ($value === null) { $this->_error(self::NULLVALUE); return false; } // to samo dla pustego stringa if ($value === '') { $this->_error(self::EMPTYSTRING); return false; } $value = (int) $value; // ustawiamy wartość dla ewentualnego komunikatu %value% $this->_setValue($value); // metoda find szuka po kluczu podstawowym i zwraca rowset wyników $foundRows = $this->_table->find($value); // jeżeli nic nie znaleziono tzn. że sprawdzany klucz nie istenieje w tabeli bazy if (count($foundRows) == 0) { $this->_error(self::IDNOTEXISTS); return false; } else { return true; } } }
Wszystko działa na tyle automagicznie, że tworząc jakiś element formularza wystarczy dodać stworzony walidator np. tak:
$formElement = new Zend_Form_Element_Select('pole_formularza'); $formElement->setRequired(true) ->setLabel('Jakaś etykieta') ->setMultiOptions($dane_do_wyboru) ->addValidator(new Spiechu_Validators_IsIdExists(new Sprawdzana_Tabela()));