A pre- és post validátorokról

Nem találtam túl sok leírás a témában, pedig érdekes tud lenni. Előljáróban: pre- és post validátorok az összes mezőt kapják meg és validáció után az összeset kell visszaadniuk. Ezért az összeállított validátor-strukúra alján (általában) sfValidatorSchema leszármazottak állnak. Ez nem kötelező jellegű, csupán ezek a validátorok fogadnak több mezőt.

Nézzünk egy példát, hogyan lehet egy mező értékétől függően más mező(k)höz ellenőrzéseket kötni. A példában felhasználóink megadhatják nickjüket, a teljes nevüket és hogy a profiljuk publikus-e. A hozzá tartozó séma:

User:
  tableName: users
  columns:
    id: ~
    nick: string(200)
    fullname: string(200)
    is_public: boolean

Tegyük fel, hogy az adatai, így a teljes neve is csak akkor jelenik meg, ha a profil publikus; a nick mindig megjelenik. Így a szokásos ellenőrzések mellett be kell vezetni, hogy az is_public mező bejelölése mellett a fullnamet is ki kell tölteni.

Ehhez a következő struktúrát kell kialakítani (sfValidatorOr):

  1. ha kijelöltük az is_public mezőt, akkor a fullname mezőt is ki kell tölteni (sfValidatorSchema)
  2. ha nem jelöltük meg az is_public mezőt, akkor teljesen mindegy, hogy a fullname ki van-e töltve (sfValidatorSchema)

Ehhez az is hozzá tartozik, hogy az 1. ágon történik a fullname valódi validálása, a mezők között egy egyszerűsített változat is megteszi.

Lássuk a kódot:

class MyForm extends sfForm {
//...
  public function configure() {
    //...
    $this->setValidators(array(
      'nick'      => new sfValidatorString(array('min' => 6, 'max' => 200)),
      'fullname'  => new sfValidatorString(array('required' => false)),
      'is_public' => new sfValidatorBoolean()
    ));

    $this->validatorSchema->setPostValidator(new sfValidatorOr(
      new sfValidatorSchema(
        array(
          'is_public' => new sfValidatorChoice(array('choices' => array(false)))
        ),
        array('allow_extra_fields' => true, 'filter_extra_fields' => false)
      ),
      new sfValidatorSchema(
        array(
          'is_public' => new sfValidatorChoice(array('choices' => array(true))),
          'fullname'  => new sfValidatorString(array('min' => 10, 'max' => 200))
        ),
        array('allow_extra_fields' => true, 'filter_extra_fields' => false)
      )
    ));
  }
//...
}

A két ág összefogására az sfValidatorOr osztály teljesen megfelelő. Ez alatt két sfValidatorSchema foglal helyet, ezek reprezentálják az egyes ágakat (az összes értéket megkapják és azt vissza is kell adniuk!). Fontos, hogy az ‘allow_extra_fields‘ és ‘filter_extra_fields‘ opciókat beállítsd, különben kellemetlen meglepetésekben lesz részed. A sémákon belül pedig az eddig megszokott módon leírhatók az egyes ágakban a mezőkkel szemben támasztott követelmények.

A példa alapján remélhetőleg könnyen létre tudsz hozni saját validálási szabályokat. Személy szerint a pre validálásnak nem sok értelmét látom. Nem tudok olyan esetet mondani, ahol ne lenne jó a post változat, valamit abba érdemes belegondolni, hogy post validátorok esetén az átadott értékek már a validátorok által tisztított értékeket tartalmazzák (pl sfValidatorFile esetén már az sfValidatedFile objektum példányt), míg ez pre validátorok esetén nem így van. A struktúra kicsit bonyolult lehet, de hát ez van🙂 .

Kategória: fejlesztés, symfony
Címke: , , , , ,
Közvetlen link a könyvjelzőhöz.

9 hozzászólás a(z) A pre- és post validátorokról bejegyzéshez

  1. j. szerint:

    A Symfony-s doksikra sajnos az a jellemző (és ez nagy negatívuma a Symfonynak szerintem), hogy a doksija látszólag terjedelmes és részletes, viszont tartalmilag kb. 80% olyan információkból áll amire egy fejlesztő magától kb. 10 perc alatt rájön, viszont az összetettebb és bonyolultabb részek pedig iszonyatosan aluldokumentáltak és legjobb esetben is csak egy-egy fórum témában lehet róluk olvasni…persze még így sem lehet okunk panaszra, hiszen ez egy Open Source rendszer, tehát lehet bővíteni önkéntes alapon, de egy kis plusz doksi azért nem ártana ezen a téren, meg a validátorokhoz úgy általában sem…

  2. Sulik Szabolcs szerint:

    Hát a dokumentáció az ilyen, kicsit hiányos az advanced felhasználói rész.

    Anno a taskokról akartam írni egy cikket, aztán meggondoltam magam. 1.1 előtt nagyon hypeolták az új task rendszert. Azóta erről hallgatnak (igéret volt, hogy kódból is lehet példányosítani őket). Plusz kicsit over-engineered cuccnak tűnik az egész. Kb 3 osztályból örököl dolgokat az sfBaseTask (ill. az sfPropelBaseTask, sfDoctrineBaseTask). Kérem jelentkezzen az, aki nem sfBaseTask alapú taskokat ír. Nem értem minek ez az egész molyolás, mikor azért írok taskot, mert szükségem van arra a nyűves projectConfiguration példányra. Ha nem lenne szükségem rá, akkor írok egy vacak batchet és kész. Ebben az is benne van, hogy ez egy fölösleges tanulási körre rákényszeríti a fejlesztőt, ha symfony taskot akar használni, gyakorlatilag a semmiért.

    Egyre inkább úgy érzem, hogy igaza van Terry Chay-nek: ahol egy könyvre van szükség, hogy használni tudj egy keretrendszert, ott valami gáz van. És mint tapasztaltuk, az említett könyv helyenként igencsak az alapokat adja jelenleg (és akkor a félbehagyott form könyvet hagyjuk).

    Mindettől függetlenül úgy gondolom, hogy a symfony rendelkezik az egyik legmasszívabb MVC alappal, tele jó ötlettel. Csak gyorsabban jutnak be az újíŧások a kódba, mint a dokumentációba.

    Tipp: nézd meg a kód kommenteket. Azok általában jobbak, mint maga a doksi.

  3. j. szerint:

    A Symfony képességeit és erényeit szerintem nem lehet vitatni, aki ezt teszi az valamit nagyon nem ért🙂 vagy félerért – jobb esetben. Ebben maximálisan egyetértek veled.
    Terry Chay irományához kapcsolódóan: picit félreérthető amit ír, nem mindenben értek egyet azzal, hogy “ahol egy könyvre van szükség, hogy használni tudj egy keretrendszert, ott valami gáz van”, mert bár van ebben igazság, de ha jobban belegondolsz egészében csak féligazság🙂 Populista picit…, nyuszikásvicc…mert ha meg nem kéne könyv, akkor senki nem venné komolyan😀, ahogyan pl. nem veszik komolyan a kisebb keretrendszereket (olyakor okkal, olykor ok nélkül – keretrendszere válogatja).

    Engem a Symfonyban továbbra is az zavar legjobban amit írtam: a kézenfekvő dolgok agyon vannak dokumentálva, az ún. össszetettebb témák pedig egy-egy mondatban vannak megemlítve, néha mintha szándékosan szivatnák az embert…MENJ A FÓRUMBA és kuncsorogj…és ez oda vezet, hogy bár a rendszer jó: túl nagy a konkurencia ma már ahhoz, hogy egy fejlesztő rá legyen kényszerülve egy keretrendszerre. Viszont a Symfony-nak annyi jó tulajdonsága van, hogy még így is bőven megéri a rááldozott időt, mert a Zend-en kívül talán az egyetlen keretrendszer amire akár egy nagyobb fejlesztő cég is építhet hosszabb távon, talán még a Kohana sorolható ide, de már ez is sokkal “lightesebb” kategória. de ez csak szubjektiv vélemény🙂

  4. Sulik Szabolcs szerint:

    Hát ja. A dokumentáció kicsit ördögi kör🙂 Nem mintha a Zend-é olyan kicsi lenne🙂 A symfony teljesen megfelel a céljaimnak, a hogyan használd rész pedig inkább az Askeet ill. Jobeet doksikban van benne jobban.

    A Kohanaról mostanában sok jót hallottam, csak egy My First Project tutorialt sem találtam az oldalukon. A CodeIgniter meg nem tetszett amikor nézegettem. Viszont a Harry Fuecks név biztatóan hangzik (bár lehet, hogy csak az utf8 kezelést vették tőle).

    A Terry Chay idézet pedig nagyon “durva” megfogalmazás, az ő kontextusából teljesen kiragadva. Érdemes elolvasni néhány cikket tőle (szórakoztató tud lenni, ha bírod a stílusát).🙂

  5. Sulik Szabolcs szerint:

    Ja, és a taskos kritika nem az egyetlen. Másik példa: sfWidget osztály. Miért is van ilyen? Hiszen azt csak az sfWidgetForm osztály terjeszti ki. Ez nem csak nekem tűnt fel. Ehhez csak annyit fűznék hozzá, hogy ami html kimenetet generál az a partial. Arra pedig nem árt figyelni, hogy ha egy absztrakt osztályból (sfWidget) származik egy másik absztrakt osztály (sfWidgetForm), akkor ott valami bibi van.

    Bármilyen jó is egy rendszer, nem árt némi egészséges kritikával szemlélni.

  6. j. szerint:

    Szerintem az sfWidget osztály egy tervezési minta következetes használata miatt lett🙂 És bár teljesen igazad van abban, hogy “minek van” mégis ha megnézel klasszikus OOP nyelveken írt kódgyűjteményeket (pl. Javávban, Delphiben), akkor ott hasonló dolgokkal fogsz találkozni🙂 Nekem úgy tűnik, hogy ez a fajta “felesleges” felaprózódás az OOP következetes használatának egyik mellékterméke😀 Ballaszt amit mégsem lehet kilőni az űrbe🙂 (sajnos)😀

  7. Sulik Szabolcs szerint:

    Bocs, de ez marhaság (mármint nem amit írsz, hanem ez a hozadékos dolog). A for future purpose tűnik a logikus magyarázatnak, csakhát honnan tudják, hogy majd mire akarják még használni, ha jelenleg nem használják semmi másra (és akkor majd jó lesz-e a jelenlegi kialakítás)? Ráadásul pont a symfony az a rendszer, amelyik a folyamatos refactoring útját járja. Így még érthetetlenebb a dolog számomra.

    Egy dolog annyira egyszerű, amennyire csak lehetséges, de semmivel sem egyszerűbb. Albert Einstein

    Ez most nem tűnik a lehető legegyszerűbbnek.

    Egyébként szerinted melyik minta használatának következménye ez?
    Delphit régen használtam, nem nagyon emlékszem az ottani dolgokra.
    Félreértés ne essék, nem az a baj, hogy van egy absztrakt osztály és abból más absztrakt osztályok származnak, amelyek más és más irányban terjesztik ki azt. Itt az a probléma, hogy EGYETLEN osztály származik az alaposztályból.

  8. j. szerint:

    Ez nem egy konkrét minta használata, hanem minták félreértelmezéséből keletkező hiba, én nem azt mondtam, hogy ez jó, hanem azt, hogy nagyon sok, általam eddig átnézett, átnyálazott forráskódban előfordulnak hasonló bibik és szerintem nem véletlenül, hanem azért mert az OOP alap filozófiája félreértelmezhető úgy, hogy a dolgok túl lesznek variálva és akkor ilyen “hibák” keletkeznek. Remélem így már érthető mire gondoltam🙂 és nem fog “marhaságnak” tűnni.

  9. Sulik Szabolcs szerint:

    Így már nem.😀

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