Symfony 1.2 admin generator

Elöljáróban

Ez már nem játék.🙂 Legalábbis nem teljesen. Elöljáróban megsúgom, annyira nem rossz a helyzet, mint korábbi cikkemben lefestettem. Az új admin generator egy nagyon rugalmas eszköz a kezünkben, amivel ha jól bánunk, mindenféle nagyobb hackelés nélkül teljesíti egyedi igényeinket is.

Ott folytatnám, ahol a hivatalos dokumentáció abbahagyja, hiszen itt kezd érdekessé válni a dolog. Ehhez persze szükséges némi előképzettség. A dokumentációban leírtakat nem taglalom újra, azt tessék elolvasni szép angol nyelven. Feltételezem, hogy tisztában vagy az 1.0 admin generátorával, valamint ismered az új generator.yml és a generator template (theme) felépítését.

Még egy megjegyzés: mivel Doctrine-nel dolgozom, így az itt leírtak is erős Doctrine függőséget fognak mutatni. Habár mindez (néhány különbséggel) teljesen így működik Propel alatt is.

Áttekintés

Az admin generátor nagy változáson ment át, ezt mindnyájan tudjuk. A működésében bekövetkezett alapvető változást nézzük most át.

Az admin generátor összességében egy kód generátor, amely a cacheben létrehozza azt a kódot, amely képes az alapvető adminisztrációs feladatok ellátására és amelyet majd saját magunk bővíthetünk. Eddig ez az actions/actions.class.php valamint a templates/ alatt található templatek létrehozását jelentette. Most bekerült két új osztály: a generatorConfiguration és a generatorHelper.
A generatorConfiguration osztály tartalmazza a generator.yml-ben leírt generátor konfigurációt (cache/ENV/APP/modules/foo/lib/BaseFooGeneratorConfiguration.class.php).
A generatorHelper osztály tartalmazza az egyes action-khöz használt helper metódusokat. Na most akkor mi is ez?.

Az űrlapok készítéséhez eddig a form helpereket használta a symfony. Mostantól minden űrlap sfForm alapú. Ezért bármilyen admin generator oldal használat előtt (ha még nem tettük meg) létre kell hozni azokat: doctrine-build-forms és doctrine-build-filters taskok. A new és edit oldalakhoz a doctrine-build-forms által létrehozott űrlapokat használja a rendszer (alapértelmezetten, ami persze megváltoztatható). A doctrine-build-filters pedig egy speciális űrlaptípust hoz létre minden model oszályhoz, amely kifejezetten a lista nézet szűréséhez lehet használni. Ezeknek az osztályoknak az őse az sfFormFilterDoctrine, illetve sfFormFilter (sfForm leszármazott). Bővebben kicsit később.

A generator.yml változásai

Nézzünk meg néhány alapvető változást:

  • a mezők nevének leírására használt name: bejegyzést mostantól label:ként ismer a rendszer
  • a _create action nincs többé, _new van helyette
  • a tömeges műveletek végrehajtására szolgáló bacth_actions alapértelmezetten be van kapcsolva. Kikapcsolás: bacth_actions: {} (a vicces, hogy ez már az eredeti admin generatorban is benne volt, csak nem volt bekapcsolva és ha nem tudtad, hogy van, akkor nem is kapcsoltad be sose)
  • list alatt az eddigi peer_method neve table_method. Ezzel az opcióval lehet beállíŧani egy táblametódust, amely preparálja a kezdő Doctrine_Queryt. Emellett elvileg elérhető egy table_count_method is. Azért elvileg, mert maga az admin generator lehetőséget biztosíŧ rá, viszont valami miatt a Doctrine vonalon ez beletették, majd kivették.
  • űrlap mentés esetén _save_and_list típus nincs többé

Filter formok

Mint azt korábban írtam a filter form egy speciális űrlaptípus, amely kifejezetten a lista nézet szűréséhez lehet használni. Az alapértelmezett osztálynév itt is megváltoztatható. Korábban ehhez a form helpereket használta a rendszer és az action addFiltersCriteria() metódusával juttatta érvényre a beállított értékeket. Ezzel az volt a baj, hogy nagyon rugalmatlan volt, különösen az addFiltersCriterias rész. Nézzük hogyan működik ez az új megoldással.

Minden, a sémában szereplő mezőhöz hozzárendel a rendszer egy típust. Ez nem egyezik meg az adatbázisban, vagy bárhol máshol használt típusokkal. A típust az adott űrlap getFields() metódusa definiálja MEZO => TIPUS alapú tömbben. A jelenleg használható típusok: ForeignKey, Enum, Text, Number, Boolean, Date. Nézzük meg, hogyan használhatjuk ezeket szűrőfeltételek készítéséhez.

Létező mező esetén a hozzáadott feltételt a mező típusa határozza meg. Ezek a metódusok a sfFormFilterDoctrine::addTIPUSQuery() néven érhetők el (pl szöveges típus esetén ez sfFormFilterDoctrine::addTextQuery()).
A típus alapján történő szűrést használva a ForeignKey, Enum, Boolean és Date típus esetén mindenképpen hozzáadja a kapott mező értéket a queryhez (de csak akkor, ha van érték). Enum esetén (tipikusan select mező) ez megkerülhető, ha a választható értékek közé felveszünk egy üres stringet, validatorba required false. Text és Number esetén csak akkor, ha a text kulcs nem üres.

Ha a típus alapú szűrés nem felel meg igényeinknek, akkor bármely mezőhöz tudunk felvenni egyedi metódust: addMEZONEVEColumnQuery($query, $field, $value) (pl. email mező esetén addEmailColumnQuery()). Ezek a metódusok mindig három paramétert kapnak:

  1. $query: maga a Doctrine_Query példány
  2. $field: a mező neve (ebben az esetben ezt azért enélkül is tudjuk🙂 )
  3. $value: a szűrő értéke, de ez egy kicsit kakukk tojás. Ugyanis ForeignKey, Enum és Boolean típus esetén magát a szűrő mező értékét tartalmazza, míg a többi esetben egy tömb, amely típusonként különböző. Text és Number esetén két kulcsa van: is_empty, text (ez utóbbi tartalmazza a mező értékét). Date esetén pedig három kulcs szerepel benne: is_empty, from, to.

Típus alapján történő szűrőfeltétel hozzáadás működése:

  • ForeignKey: egyszerű where feltétel
  • Enum: egyszerű where feltétel
  • Text: is_empty true esetén IS NULL feltétel, különben ha a text nem üres, akkor megy a where-be
  • Number: is_empty true esetén IS NULL feltétel, különben ha a text nem üres, akkor megy a where-be
  • Boolean: egyszerű where feltétel
  • Date: is_empty true esetén IS NULL feltétel, különben értelemszerűen a from és to értékei alapján állítja be a megfelelő intervallumokra szűrést.

Ha virtuális szűrőmezőt használunk, akkor a addMEZONEVEColumnQuery() metódus megadása kötelező.

Honnan jönnek ezek a szűrőmező értékek:

  • Date esetén a sfWidgetFormFilterDate/sfValidatorDateRange eredménye
  • Number esetén a sfWidgetFormFilterInput/sfValidatorSchemaFilter eredménye
  • minden más típus esetén a sfWidgetFormFilterInput/sfValidatorPass eredménye

Generator helper oszályok

Feladatuk az egyes template actionk linkelése testreszabott metódusok segítségével. Alapértelmezetten 6 metódust ad:

  • linkToDelete(), linkToList(), linkToSave(), linkToSaveAndAdd() – űrlap művelet
  • linkToNew() – lista nézet művelet
  • linkToDelete(), linkToEdit() – objektum művelet listában.

Ezek a metódusok alapvetően 2 típusba sorolhatók:

  • egy rekord/objektumhoz köthető műveletek: linkToDelete(), linkToSave(), linkToSaveAndAdd() és linkToEdit(). Mindig 2 paramétert kap:
    1. $object: az aktuális objektum példány
    2. $params: a generator.yml alatt az action-höz megadott paraméterek tömbje
  • “általános” művelet: linkToList() és linkToNew(). Egy paramétert kap: a generator.yml alatt az action-höz megadott paraméterek tömbjét.

A generator helpert a rendszer a következő templatekben használja: _form_actions, _list_actions, _list_td_actions. Egyedi helper metódus használatát alapvetően csak a _form_actions támogatja, de egyszerűen készíthetünk saját templatet és betehetjük a másik két helyre is.

A _list_actions.php 7. sorát kell cserélni a következőre:

[?php if (method_exists($helper, 'linkTo<?php echo $method = ucfirst(sfInflector::camelize($name)) ?>')): ?]
  <?php echo $this->addCredentialCondition('[?php echo $helper->linkTo'.$method.'('.$this->asPhp($params).') ?]', $params) ?>
[?php else: ?]
  <?php echo $this->addCredentialCondition($this->getLinkToAction($name, $params, false), $params) ?>
[?php endif; ?]

A _list_td_actions.php 12. sorát kell cserélni a következőre:

[?php if (method_exists($helper, 'linkTo<?php echo $method = ucfirst(sfInflector::camelize($name)) ?>')): ?]
  <?php echo $this->addCredentialCondition('[?php echo $helper->linkTo'.$method.'($'.$this->getSingularName().', '.$this->asPhp($params).') ?]', $params) ?>
[?php else: ?]
  <?php echo $this->addCredentialCondition($this->getLinkToAction($name, $params, false), $params) ?>
[?php endif; ?]

Az így létrejött template már jobb testreszabhatóságot biztosít, viszont tartsuk szem előtt, hogy verzióváltáskor magunknak kell a generator templatet karbantartani.

Példa: egy email címre szeretnénk levelet küldeni action linkkel (magyarul mailto).

generator:
  class: sfDoctrineGenerator
  param:
    model_class:           Foo
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              ~
    plural:                ~
    route_prefix:          foo
    with_propel_route:     1

    config:
      actions: ~
      list:
        title: Lista
        display: [ id, name, email ]
        object_actions:
          mailTo: []
      filter:  ~
      form:    ~
      edit:    ~
      new:     ~

class FooGeneratorHelper extends BaseFooGeneratorHelper
{
  public function linkToMailTo($foo, $params)
  {
    return sprintf('<a href="mailto:%s">%s</a>', $foo['email'], $foo['name']);
  }
}

Itt a vége

Ennyit mára a tudomány és technika újdonságaiból.

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

2 hozzászólás a(z) Symfony 1.2 admin generator bejegyzéshez

  1. saki szerint:

    Remek poszt!
    SF 1.4 alatt kicsit meg van variálva a dolog. Ott van ötleted, hogyan lehetne elérni a Helper osztály objektumát vagy nevét amit berakhatok a method_exists() -be? Köszönöm!

  2. Szabolcs Sulik szerint:

    kosz. hat regen volt mar symfony. ugy sejtem, hogy az admin generator templateben kellene kutakodni. amit, ahol atadja, ott tudod elerni. ha nem tetszik a “gyari” template siman csinalhatsz sajatot.

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