Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony] Konfigurowanie formularzy za pomocą plików YAML
Forum PHP.pl > Forum > PHP > Frameworki
mike
Po trzecim czy czwartym napisanym formularzu w symfony 1.2 szlag mnie niemal trafił. Nowy form framework jest bardzo fajny i funkcjonalny. System validatorów również. Niestety sposób konfiguracji to jakaś kara za grzechy.

Nie byłbym sobą gdybym nie ułatwił sobie życia. Oto przykład formularza dla obiektu User (jakiś zwykły użyszkodnik):
  1. <?php
  2.  
  3. /**
  4.  * @author Michal Mech
  5.  */
  6. class UserForm extends sfFormPropel {
  7.  
  8.    public function configure() {
  9.        $this->widgetSchema->setNameFormat('user[%s]');
  10.    }
  11.  
  12.    public function getModelName() {
  13.        return 'User';
  14.    }
  15. }
  16.  
  17. ?>

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):
  1. <?php
  2.  
  3. $userForm = new UserForm();
  4. $formConfigurator = new FormConfigurator();
  5. $formConfigurator->setYmlPath(sfConfig::get('sf_app_module_dir') . '/user/form/user.yml');
  6. $formConfigurator->configure($userForm);
  7.  
  8. ?>

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


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ć tongue.gif

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 tongue.gif

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
Lonas
Fajne narzędzie. Moje pytanie co jeśli w zależności od tego czy formularz jest nowy czy nie pewne założenia walidacji się zmieniają ?
mike
Cytat(Lonas @ 25.03.2009, 13:02:17 ) *
Moje pytanie co jeśli w zależności od tego czy formularz jest nowy czy nie pewne założenia walidacji się zmieniają ?
Na ta okoliczność zaimportuj innego YAML'a.
LBO
mike, bardzo funkcjonalna klasa smile.gif Dzięki.

Mam pytanie, pomyślałbyś nad dobrze dobranymi wartościami domyślnymi? Można by wtedy znacznie skrócić plik konfiguracyjny
Ewentualnie czy dajesz zgodę na modyfikację[edit] i zamieszczenie jej tutaj[/edit]?

Pozdrawiam, Alan

P.S. Czemu usunąłeś klasę z neta?
mike
Cytat(LBO @ 26.03.2009, 19:35:52 ) *
Mam pytanie, pomyślałbyś nad dobrze dobranymi wartościami domyślnymi?
Na dobrą sprawę tylko fieldset, widget, class są wymagane. Chyba, że chcesz iść dalej i na przykład jak jest widget to domyślnie sfWidgetFormInput i takie tam.
Cytat(LBO @ 26.03.2009, 19:35:52 ) *
Ewentualnie czy dajesz zgodę na modyfikację[edit] i zamieszczenie jej tutaj[/edit]?
Śmiało.
Cytat(LBO @ 26.03.2009, 19:35:52 ) *
P.S. Czemu usunąłeś klasę z neta?
To dziwne ale to nie ja. Poprawiłem linka a tu jeszcze raz: http://wklej.org/id/70052/
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.