Walidacja jednego pola formularza w symfony
Natknąłem się ostatnio na problem. Otóż wszystkie formularze walidujemy przy wykorzystaniu symfoniowych Formsów. Standardowe użycie podczas aktualizacji obiektu Place wygląda następująco:
$this->form = new PlaceForm ($place);
$this->form->bind ($request->getParameter ('place'));
if ($this->form->isValid())
{
$place = $this->form->updateObject();
$place->save();
}
Co jednak kiedy nie chcemy walidować całego formularza? Np. w przypadku kiedy używając InPlaceEditora zmieniamy jedno pole. Podpowiem, że próba wysłania tylko tego jednego pola i wykorzystaniu tej samej akcji skończy się wyzerowaniem pozostałych pól.
Dokumentacja symfony niestety milczy na ten temat (choć przyznam się, że nie szukałem jakoś strasznie dokładnie), a wiemy chyba wszyscy co jest jej największą bolączką – opisanie tylko kilku funkcjonalności poszczególnych modułów. Jak się chce czegoś więcej, to droga wolna – szukajcie sobie sami w kodzie.
Tak też postąpiłem. I po koszmarnie długim czasie odkryłem, że do walidowania każdego z pól służy metoda o intuicyjnej nazwie… clean(). Przykład walidacji jednego pola:
$form = new PlaceForm($place);
try
{
$cleaned = $form->getValidator($field_name)->clean($value); #1
$place->setByName($field_name, $cleaned, BasePeer::TYPE_FIELDNAME); #2
$place->save();
}
catch (sfValidatorError $e) #3
{
#Obsługa błędu
}
- Pobranie odpowiedniego walidatora oraz wywołanie na nim metody
clean(), która w przypadku, gdy pole ma poprawną wartość zwraca je. A w przypadku błędu wyrzuca wyjąteksfValidatorError, - Zapisanie wyczyszczonej wartości tego pola do obiektu,
- Kod obsługujący przypadek niewalidującego się pola.
Mam nadzieję, że ten krótki artykuł pozwoli komuś zaoszczędzić trochę czasu.
Wpis opublikowałem także na prywatnym blogu reinmar.jogger.pl.
Podobne wpisy:





Fajny sposób, ale coś mi się wydaje, że metoda setByName z propela kiepsko współgra z I18N – tzn. zwraca byle co, a nie to, co wynikałoby z „kultury obiektu”.
Jeżeli się mylę, to niech ktoś mnie oświeci, ale morał z tego jest jeden – Propel jest do bani i trzeba się nauczyć Doctrine, żeby móc robić krótkie i ogólne metody, a nie klepać ręcznie każdy przypadek – mogłaby być w końcu osobna akcja do każdego pola, którą trzeba byłoby pisać i aktualizować przy każdej zmianie formularza…
No tak, pewnie masz rację, bo ja sam w I18N się nie wyznaję :)
Ale pomijając propela i jego metodę setByName, to w tym wpisie bardziej chciałem poruszyć temat validatorów i ten motyw z setByName można sobie do woli wymienić na Doctrine’owy.
Chyba, że się mylę, to proszę o poprawienie :)