Nie byłbym sobą gdybym nie ułatwił sobie życia. Oto przykład formularza dla obiektu User (jakiś zwykły użyszkodnik):
<?php /** * @author Michal Mech */ class UserForm extends sfFormPropel { public function configure() { $this->widgetSchema->setNameFormat('user[%s]'); } public function getModelName() { return 'User'; } } ?>
Formularz ten posiada pola do wpisania loginu, hasła, adresu email oraz dwa dodatkowe pola do powtórzenia hasła i adresu email. Konfiguracja zawiera oczywiście pełen zestaw walidatorów. Jak to możliwe?
Tak jest on jest tworzony i konfigurowany (gdzieś wewnątrz akcji):
<?php $userForm = new UserForm(); $formConfigurator = new FormConfigurator(); $formConfigurator->setYmlPath(sfConfig::get('sf_app_module_dir') . '/user/form/user.yml'); $formConfigurator->configure($userForm); ?>
Plik user.yml jest wewnątrz folderu /form wewnątrz modułu użytkownika oraz wygląda tak:
Kod
fieldset:
id:
widget:
class: sfWidgetFormInputHidden
validator:
class: sfValidatorPropelChoice
options:
required: false
model: User
column: id
login:
widget:
class: sfWidgetFormInput
options:
label: Login
validator:
class: sfValidatorString
options:
required: true
trim: true
max_length: 255
messages:
required: Proszę podać login
max_length: Maksymalna długość loginu to 255 znaków
password:
widget:
class: sfWidgetFormInputPassword
options:
label: Hasło
validator:
class: sfValidatorString
options:
required: true
messages:
required: Proszę podać hasło
password_repeat:
widget:
class: sfWidgetFormInputPassword
options:
label: Powtórz hasło
email:
widget:
class: sfWidgetFormInput
options:
label: Email
validator:
class: sfValidatorEmail
options:
required: true
max_length: 255
messages:
required: Proszę podać adres email
max_length: Maksymalna długość adresu email to 255 znaków
invalid: Podany adres email jest niepoprawny
email_repeat:
widget:
class: sfWidgetFormInput
options:
label: Powtórz email
postValidator:
class: sfValidatorAnd
validator_1:
class: sfValidatorSchemaCompare
left_field: password_repeat
operator: ==
right_field: password
messages:
invalid: Podane hasła są różne
validator_2:
class: sfValidatorSchemaCompare
left_field: email_repeat
operator: ==
right_field: email
messages:
invalid: Podane adresy email są różne
validator_3:
class: sfValidatorPropelUnique
options:
model: User
column: email
messages:
invalid: Istnieje już użytkownik o podanym adresie email
validator_4:
class: sfValidatorPropelUnique
options:
model: User
column: login
messages:
invalid: Istnieje już użytkownik o podanym loginie
id:
widget:
class: sfWidgetFormInputHidden
validator:
class: sfValidatorPropelChoice
options:
required: false
model: User
column: id
login:
widget:
class: sfWidgetFormInput
options:
label: Login
validator:
class: sfValidatorString
options:
required: true
trim: true
max_length: 255
messages:
required: Proszę podać login
max_length: Maksymalna długość loginu to 255 znaków
password:
widget:
class: sfWidgetFormInputPassword
options:
label: Hasło
validator:
class: sfValidatorString
options:
required: true
messages:
required: Proszę podać hasło
password_repeat:
widget:
class: sfWidgetFormInputPassword
options:
label: Powtórz hasło
email:
widget:
class: sfWidgetFormInput
options:
label: Email
validator:
class: sfValidatorEmail
options:
required: true
max_length: 255
messages:
required: Proszę podać adres email
max_length: Maksymalna długość adresu email to 255 znaków
invalid: Podany adres email jest niepoprawny
email_repeat:
widget:
class: sfWidgetFormInput
options:
label: Powtórz email
postValidator:
class: sfValidatorAnd
validator_1:
class: sfValidatorSchemaCompare
left_field: password_repeat
operator: ==
right_field: password
messages:
invalid: Podane hasła są różne
validator_2:
class: sfValidatorSchemaCompare
left_field: email_repeat
operator: ==
right_field: email
messages:
invalid: Podane adresy email są różne
validator_3:
class: sfValidatorPropelUnique
options:
model: User
column: email
messages:
invalid: Istnieje już użytkownik o podanym adresie email
validator_4:
class: sfValidatorPropelUnique
options:
model: User
column: login
messages:
invalid: Istnieje już użytkownik o podanym loginie
I na koniec klasa, która robi magię: FormConfigurator.
Mechanizm działa ze wszystkimi typami widgetów oraz validatorów w symfony 1.2 (w chwili pisania 1.2.4). Składnia pliku YAML jest niemal samo dokumentująca się więc wspomnę tylko o kilku kwestiach:
1. Blok validator dla widgeta nie jest wymagany (co widać w pliku), ponieważ w takiej sytuacji automatycznie zostanie wygenerowany dla widgeta obiekt sfValidatorPass;
2. Z racji na inną składnię konstruktora dla sfValidatorSchemaCompare konfiguracja ma zawierać elementy jak w pokazanym pliku;
3. Walidatory sfValidatorAnd oraz sfValidatorOr z razji na inną składnię muszą być konfigurowane jak w w pokazanym pliku. Bloki typu validator_1, validator_2, validator_3 to niestety wymóg powodowany niedoskonałością YAMLa. Bloki mogą nazywać się jak chcą: validator_1, validator_[1], validator_{1}. Ważne by zawierały słowo validator;
4. Plik pokazuje jak utworzyć postValidator dla formularza. W identyczny sposób tworzymy preValidator. Oba bloki są opcjonalne;
5. Pomijając reklamowy bulszit z początku posta klasa nie obsługuje trzech wynalazków: sfValidatorFromDescription, sfValidatorSchemaFilter i sfValidatorSchemaForEach. Dopiszę jak zacznę potrzebować

W chili obecnej to czego nie można lub czego się nie da zrobić za pomocą mojego narzędzia dopisać sobie wewnątrz funkcji sfForm::configure(). Mechanizmy nie kłócą się ze sobą.
Klasa nie jest udokumentowana ponieważ jest prosta a poza tym dokumentuję w chwili kiedy to czytasz

Miłej zabawy.
P.S.
Moderatorze, który to czytasz. Z racji na popularność zagadnienia i dostępność klasy chyba nie ma co przenosić do działu Algorytmy, klasy, funkcje