Przykładowa klasa formularza - nieobowiązkowa
class UsersController extends Phalcon\Mvc\Controller { public function addAction() { $user = new User; $form = new UserForm($user); if($this->request->isPost()) { //Metoda także dokonuje $user->assign($_POST) $form->bind($_POST, $user); //Walidacja nr 1 - formularz if($form->isValid()) { //Walidacja nr 2 - model if($user->save()) { $this->view->disable(); $this->response->redirect('users'); } else { //Walidacja nr 2 - odczyt błędów foreach($user->getMessages() as $msg) { $this->flash->error($msg); } } } else { //Walidacja nr 1 - błędy formularza foreach($form->getMessages() as $msg) { $this->flash->error($msg); } } } $this->view->form = $form; $this->view->user = $user; } }
Za dużo kodu w kontrolerze? Za bardzo skomplikowany? Tak. Musimy osobno sprawdzać poprawność danych w formularzu i modelu. Prowadzi to do sytuacji, że wiele pól sprawdzamy 2 razy - najpierw w formularzu, a potem w modelu. Nie możemy pominąć walidacji w modelu - przecież błędne dane mogą doprowadzić do destabilizacji systemu! Zazwyczaj jeśli pole ma mieć określony format, musi taki mieć niezależnie, czy dane wejściowe pochodzą z formularza, czy z innego źródła.
<?php use Phalcon\Forms\Form; use Phalcon\Forms\Element\Text; use Phalcon\Forms\Element\Password; use Phalcon\Forms\Element\Select; use Phalcon\Validation\Validator\Confirmation; use Phalcon\Validation\Validator\StringLength; class UserForm extends Form { public function initialize() { //Niedogodność w Phalconie //Chociaż dodamy mu 100 walidatorów //Sam nie doda atrybutów, tylko trzeba wszystko ręcznie 'maxlength' => 25, 'required' => 'required', //nie da się dodać pustych atrybutów 'pattern' => '.....', 'placeholder' => 'Wpisz login' 'autofocus' => 'autofocus' //już lepiej pisać czysty HTML w widoku )); 'min' => 200, 'max' => 25, 'messageMinimum' => 'Login musi miec min 2 znaki!', 'messageMaximum' => 'Login jest za dlugi - max 25!' ))); //Tutaj też ciekawy fragment $pass = new Password('pass'); 'min' => 5, 'messageMinimum' => 'Password too short' )), 'with' => 'confirm', 'message' => 'Password confirmation not the same.' )) )); //Wielką zaletą jest tworzenie pól select //Nie musimy męczyć się z ifami w widoku //Podajemy mu, skąd pobrać dane lub przekazujemy tablicę //Jednak nie musimy tego robić w klasie - można też w widoku 'using' => ['ID', 'name'] 'useEmpty' => true, 'emptyText' => 'Nie ma sąsiada' )); //Add fields to the form $this->add($login); $this->add($pass); $this->add($select); } }
Gdzie przeprowadzać walidację? Czy wszystko sprawdzać w modelu?
Tak byłoby najwygodniej i bez powtórzeń.
Mamy formularz rejestracji. Trzeba powtórzyć hasło. Gdzie sprawdzimy, czy oba hasła zgadzają się? Jeśli przekażemy całą tablicę $_POST do modelu, możemy tam odczytać pole "confirm". Niektórzy powiedzą, że tak nie wolno, bo wychodzimy poza kompetencje modelu, a ten przypadek powinien sprawdzić kontroler. Co o tym myślicie?
Gdzie przeprowadzać kontrolę poprawności danych?
Kolejne zagadnienie to... formularze.
Czysta klasa Form w Phalconie jest bez sensu. Żadnych korzyści. Więcej problemów. Pola możemy sprawdzić w akcji kontrolera, cały kod HTML napisać ręcznie (metoda render() jedynie wypluje kod pojedynczej kontrolki), funkcję pomocniczą {{select()}} wywołać w widoku, kilka plików mniej. Jedyna zaleta to możliwość większej automatyki po rozszerzeniu klasy Form inną klasą bazową lub stworzenie uniwersalnego szablonu formularza (niektóre i tak będą wymagać osobnego kształtu):
LOL
