7 nap a Symfony1.1 rendszerrel – Űrlapok, Widget-ek és Validator-ok (2. nap)

Ez alábbi bejegyzés a Thatsquality.com oldalon található 7 Days of Symfony1.1 – Forms, Widgets and Validators (Day2) í­rás fordí­tása, Ryan Weaver jóváhagyásával.

Űrlapok létrehozása könnyedén

2. nap, épp ideje, hogy készí­tsünk néhány űrlapot. Vágjunk bele. Először definiáljuk a modelt, amivel játszani fogunk:

schema.yml:

propel:
  author:
    _attributes:         { phpName: Author }
    id:
    first_name:          varchar(30)
    last_name:           varchar(30)
    email:               varchar(75)
    website:             varchar(100)
    birthday:            date
    years_experience:    integer
  article:
    _attributes:         { phpName: Article }
    id:
    author_id:
    body:                longvarchar
    file_attachment:     varchar(255)

Ezzel készen is van egy egyszerű model, amivel kipróbálhatjuk az új űrlapkezelő mechanizmust. Symfony 1.1 alatt ugyanazzal a paranccsal készí­thető el a model, mint korábban, a különbség, hogy egy kicsit több dolgot csinál. Parancssorból:

symfony propel-build-all

Mint eddig, a Symfony létrehozza a modeleket a lib/model projekt könyvtárban. Ezen túl létrehoz egy új könyvtárat is: lib/forms. Ide generálja a megfelelő modelhez tartozó űrlap osztály(oka)t.

Menjünk tovább és próbáljuk is ki. Készí­tsünk egy új modulet, “articles”-nek fogom hí­vni. Ebben hozzunk létre egy action-t (editAuthor):

public function executeEditAuthor() {
  $this->form = new AuthorForm();
}

Hozzuk létre az editSuccess.php templatet:

<form action="" method="post">

Voila! Nézzük meg az oldalt és egy komplett, formázott űrlapot találunk. A mezők többsége szöveges mező, ahogy azt vártuk. A születésnap mező 3 selectként jelenik meg (év, hónap, nap). Később látni fogjuk, hogy az idegen kulcsok automatikusan selectként jelennek meg.

Menjünk tovább, küldjük el az űrlapot. Nem történt semmi, visszakerültünk ugyanarra az oldalra és megjelent újra az űrlap. Szerkesszük meg az hozzá tartozó action-n:

public function executeEditAuthor() {
  $this->form = new AuthorForm();
  if ($this->getRequest()->isMethod('post')) {
    $this->form->bind($this->getRequestParameter('author'));
  }
}

Most frissí­tsük az oldalt és küldjük el újra az űrlapot. Ha hibát kapsz válassz egy megfelelő dátumt (nem vagyok benne biztos, hogy ez egy bug-e, de a symfony nem szereti, ha üresen hagyjuk őket – szerk.: ez a hiba már nem áll fent (r7184)). Mi változott? Sok minden. Add meg a neved, küld el újra és a megadott mező(ke)t automatikusan kitölti. Ennél azért lényegesen többről van szó! Próbáld meg kitölteni a “years experience” mezőt mondjuk “tí­z”-zel. Mikor elküldöd hibát kell kapnod. Ez van, nem í­rtunk egy sor űrlap kódot sem, ehhez képes az űrlap már automatikusan ellenőrzi a bejövő adatokat. Emlékezzünk vissza, hogy a név mezőnk tí­pusának varchar(30)-at választottunk. Próbálj meg 30-nál több karaktert bevinni azon mezők egyikébe. Újra tapasztalhatod, hogy a symfony automatikusan ellenőriz az adatokat és hibát ad, ha 30 karakternél hosszabb az nevek egyike (szerk.: jelen pillanatban a generált form osztály nem végez ilyen tí­pusú hossz ellenőrzést, ezért itt nem kapunk hibát (r7184)). Még egyszer, a symfony automatikusan ellenőrzi a mezőket és hibát ad. Mi több, csak egy sor kód választ el minket, hogy a szerző adatait mentsük az adatbázisba, akkor (és csak akkor), ha a bejövő adatok helyesek.

Hogyan készí­ti el a symfony az űrlapot? Vessünk egy pillantást a lib/forms/AuthorForm.class.php filera:

class AuthorForm extends BaseAuthorForm {
  public function configure() {
  }
}

Mint a modelek esetén, a symfony automatikusan biztosí­t egy osztályt amelyet módosí­thatunk (amit meg is fogunk tenni). A munka oroszlán részét a BaseAuthorForm alap osztály végzi, amely a base/ alkönyvtárban található (mint a modeleknél). Nézzük meg:

class BaseAuthorForm extends BaseFormPropel {
  public function setup() {
    $this->setWidget(array(
      'id'               => new sfWidgetFormInputHidden(),
      'first_name'       => new sfWidgetFormInput(),
      'last_name'        => new sfWidgetFormInput(),
      'email'            => new sfWidgetFormInput(),
      'website'          => new sfWidgetFormInput(),
      'birthday'         => new sfWidgetFormDate(),
      'years_experience' => new sfWidgetFormInput(),
      'bio'              => new sfWidgetFormTextarea(),
    ));

    $this->setValidators(array(
      'id'               => new sfValidatorInteger(array('required' => false)),
      'first_name'       => new sfValidatorString(array('max_length' => 30, 'required' => false)),
      'last_name'        => new sfValidatorString(array('max_length' => 30, 'required' => false)),
      'email'            => new sfValidatorString(array('max_length' => 75, 'required' => false)),
      'website'          => new sfValidatorString(array('max_length' => 100, 'required' => false)),
      'birthday'         => new sfValidatorDate(array('required' => false)),
      'years_experience' => new sfValidatorInteger(array('required' => false)),
      'bio'              => new sfValidatorString(array('required' => false)),
    ));

    $this->widgetSchema->setNameFormat('author[%s]');

    $this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema);

    parent::setup();
  }
  ...
}

Van még néhány dolog ebben az osztályban, amit később mutatok be. A kód kicsit ijesztő lehet, de lássuk sorjában.

Minden űrlap widget-ekből áll. Mik a widgetek? Egy widget lehet bármi, ami html képes előállí­tani. Pontosabban minden widget egy űrlap mezőt ábrázol. Mikor megjelení­tjük az űrlapot, egyszerűen csak megjelení­tjük az űrlapban lévő widget-eket. Ez ennyire egyszerű, de tényleg.

Az űrlap elemeinek “egyben tartását” segí­ti az sfWidgetFormSchema osztály. Ez sokkal bonyolultabb, mint elsőre hangzik. Alapvetően tömbként viselkedik, amelynek elemei widget-ek. Ez í­gy egyszerűbb. A setWidgets() metódus hí­vással a widget-einket belepakoljuk a saját sfWidgetFormSchema osztályunkban (amely tömbként viselkedik!). Ez elintézi nekünk az sfWidgetFormSchema létrehozását és feltöltését, í­gy nem nekünk kell megtenni. Igazából ennek használatával csak kevesebbet kell í­rnunk.

$this->setWidgets(array(
      'id'               => new sfWidgetFormInputHidden(),
      'first_name'       => new sfWidgetFormInput(),
      'last_name'        => new sfWidgetFormInput(),
      'email'            => new sfWidgetFormInput(),
      'website'          => new sfWidgetFormInput(),
      'birthday'         => new sfWidgetFormDate(),
      'years_experience' => new sfWidgetFormInput(),
      'bio'              => new sfWidgetFormTextarea(),
    ));

Mikor létrehozunk egy űrlapot (a mi esetünkben a $this->form = new AuthorForm paranccsal), akkor lefut a setup() metódus. Ennek feladata, hogy az üres űrlapot megtöltse “valós” mezőkkel. Ezt a setWidgets() metódus végzi. Fontos, az sfWidgets a widget-einket egy tömbszerű osztályba pakolja bele, sfWidgetFormSchema.

Ez azt jelenti: "egy hidden mezőre van szükségem, melynek neve 'id'"
'id' => new sfWidgetFormInputHidden(),

Ez pedig: "egy input mezőre van szükségem, melynek neve legyen 'first_name'"
'first_name' => new sfWidgetFormInput(),

Ez a szépsége az egésznek. A symfony beállí­tja automatikusan az űrlapot, annak minden szükséges mezőjét ÉS a megfelelő űrlap elemet használja fel hozzá. Az eddig látottaknál sokkal több űrlap elem van, majd a következő napokban megismerkedünk velük.

Az űrlap nem csak widget-eket tartalmaz, hanem validator-okat is, a widget-eknek megfelelő nevekkel. Ehhez van nekünk egy sfValidatorSchema osztályunk – jó név egy tömbnek, mely az űrlaphoz tartozó validator-okat tartalmazza. Ebben az esetben a setValidators() metódus gondoskodik az sfValidatorSchema objektum létrehozásáról.

$this->setValidators(array(
  'id'               => new sfValidatorInteger(array('required' => false)),
  'first_name'       => new sfValidatorString(array('max_length' => 30, 'required' => false)),
  'last_name'        => new sfValidatorString(array('max_length' => 30, 'required' => false)),
  'email'            => new sfValidatorString(array('max_length' => 75, 'required' => false)),
  'website'          => new sfValidatorString(array('max_length' => 100, 'required' => false)),
  'birthday'         => new sfValidatorDate(array('required' => false)),
  'years_experience' => new sfValidatorInteger(array('required' => false)),
  'bio'              => new sfValidatorString(array('required' => false)),
));

Most megvan minden szükséges mezőn, ezek bejövő értékeit szeretnénk bizonyos feltételekhez kötni. Ez í­gy működik:

Ez a rész: "A 'first_name' nevű mező értékét elfogadom, ha a maximális hossza 30 karakter, de nem kötelező megadni.
'first_name' => new sfValidatorString(array('max_length' => 30, 'required' => false)),

Még jónéhány példát fogunk látni, mi mindent lehet a validator-okkat megcsinálni. Az utolsó, nagyon fontos része a kódnak, amely a generált html elemek name tulajdonságának formátumát megadja.

A "first_name" mező (és az összes többi) name tulajdonásága legyen "article[first_name]"
$this->widgetSchema->setNameFormat('article[%s]');

Most nézzük meg az action-ben található kódot.

public function executeEditAuthor() {
  $this->form = new AuthorForm();
  if ($this->getRequest()->isMethod('post')) {
    $this->form->bind($this->getRequestParameter('author'));
  }
}

Nézzük végig. Mikor létrehozunk egy űrlapot, az automatikusan beállí­tja az alapvető mezőket és validator-okat. Mi az a bind() metódus? Egy elég fontos és erőteljes dolog. Az űrlap számára átadja az elküldött adatokat (amelyet a $this->getRequestParameter(‘author’)-ból nyerhetünk ki) és hozzáköti az űrlap objektumaihoz. Ennek következménye:

  1. ellenőrzi az adatot és hibát dob ha szükséges
  2. lehetővé teszi, hogy “mentsük” az űrlapot, amelyhez egy megfelő model objektumot hoz létre
  3. ha újra meg kell jelení­tni az űrlapot, akkor azt az újonnan átadott adatokkal együtt teszi

Ennyi volt mára (micsoda maraton). Legközelebb jelentősen kibőví­tjük projektünket mindenféle validator-ral, módosí­tjuk a widget-eket és mentjük az aktuális szerzőt!

Kategória: dokumentáció, php, symfony
Címke: , , , ,
Közvetlen link a könyvjelzőhöz.

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s