symfony űrlapok további bővítési lehetőségei

Korábbi cikkemben bemutattam egy módszert, hogyan lehet részlegesen adatok validálni symfony formokkal. Most nézzünk meg további hasznos bővíŧési lehetőséget.

3 új funkciót fogok megmutatni:

  1. űrlap kötése közvetlenül a kéréshez (bindRequest())
  2. űrlap kéréshez kötése részlegesen (bindRequestPartial())
  3. error séma beszerzése tömbként (getErrorsAsArray())

Röviden nézzük végig egyesével és lássuk a kódot.🙂

1. űrlap kötése közvetlenül a kéréshez.

Az sfForm::bind() metódusa 2 adattömböt vár paraméterként: a postolt adatokat, ill. a fileok tömbjét. Az esetek többségében ezek a kérésből jönnek (request), így egyszerűbb lenne, ha közvetlenül a kérést köthetnénk a formhoz. Ezt valósíŧja meg a bindRequest(). Egyetlen paramétert vár: egy sfWebRequest példányt.

Ez a funkció azért hiányzik az alap formokból, mert Fabien nem akarta a requesthez kötni a formok használatát. Ami jó gondolat, csak ezt a feladatot nem kell feltétlenül a bind()-nek megvalósítania. Valamint a form kezelése is egyszerűsödik, hiszen a mezők “névterét” így mindig a kötés helyén is meg kell adni, pedig azt a form nagyon jól tudja. Ezt az symfony 1.2 úgy próbálja megoldani, hogy bevezette a sfForm::getName() metódust. Ez vezet olyan szépségekhez, mint:

$form = new FooForm();
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));

Ehhez kapcsolódóan bevezetek egy saját MyForm::getName() metódust, így symfony 1.1 alatt is működik a dolog.

2. űrlap kéréshez kötése részlegesen

A bindPartial() és a bindRequest() keresztezése.

3. error séma beszerzése tömbként

Egy kis extra. Néha jól jön, ha a mezőnevekhez tartozó hibaüzeneteket egyszerűen be tudjuk szerezni. Ebben segít a MyForm::getErrorsAsArray() metódusa.

Egy paramétert vár: $plain_keys. Az egymásba ágyazott űrlapok esetén a hibaüzeneteket több dimenziós tömb formájában akarjuk visszakapni, vagy sem. Alapértelmezetten false, tehát a tömbös formát kérjük.

Végül a kód:

class MyForm extends sfForm {
// ...
  /**
   * Convert error schema of the current form to array of error messages
   *
   * Usefull in json responses
   *
   * @param  boolean $plain_keys
   * @return array
   */
  public function getErrorsAsArray($plain_keys = false)
  {
    return self::convertErrorSchemaToArray($this->getErrorSchema(), $plain_keys);
  }

  /**
   * Convert an error schema to an array of error messages
   *
   * @param  sfValidatorErrorSchema $errors
   * @param  boolean                $plain_keys
   * @return array
   */
  public static function convertErrorSchemaToArray(sfValidatorErrorSchema $errors, $plain_keys = false)
  {
    $return = array();

    foreach ($errors as $field => $error) {
      if ($error instanceof sfValidatorErrorSchema) {
        $tmp = self::convertErrorSchemaToArray($error, $plain_keys);

        if ($plain_keys) {
          foreach ($tmp as $f => $e) {
            $return[$field.'_'.$f] = $e;
          }
        } else {
          $return[$field] = $tmp;
        }
      } else {
        $return[$field] = (string)$error;
      }
    }

    return $return;
  }

  /**
   * Bind the form with input values directly from the request
   *
   * @param  sfWebRequest $request
   * @return void
   */
  public function bindRequest(sfWebRequest $request)
  {
    $ns = $this->getName();

    if ($ns) {
      $values = $request->getParameter($ns);
      $files  = $request->getFiles($ns);
    } else {
      $values = $request->getParameterHolder()->getAll();
      $files  = $request->getFiles();
    }

    $this->bind($values, $files);
  }

  public function bindRequestPatrial(sfWebRequest $request)
  {
    $ns = $this->getName();

    if ($ns) {
      $values = $request->getParameter($ns);
      $files  = $request->getFiles($ns);
    } else {
      $values = $request->getParameterHolder()->getAll();
      $files  = $request->getFiles();
    }

    $this->bindPartial($values, $files);
  }

  /**
   * Get the plain name format of the widgets
   *
   * @see sfForm::getName() in symfony 1.2
   *
   * @return string
   */
  protected function getName()
  {
    return preg_replace('#\[?%s\]?#', '', $this->widgetSchema->getNameFormat());
  }
// ...
}

Észrevételek: (ezt még a bindPartial() használata közben vettem észre) ha megadtunk name formatnak valamilyen “névteret” és átadás előtt nem használom az sfForm::convertFileInformation() metódust, akkor a form képtelen észlelni a file adatokat, hiába vannak ott valójában. Erre valakinek valami ötlete?

Példa:

// formban
$this->widgetSchema->setNameFormat('test[%s]') ;

// majd actionben
$form = new FooForm();
$form->bind($request->getParameter('test'), $request->getFiles('test'));
Kategória: fejlesztés, symfony
Címke: , , , , , , ,
Közvetlen link a könyvjelzőhöz.

3 hozzászólás a(z) symfony űrlapok további bővítési lehetőségei bejegyzéshez

  1. j. szerint:

    Helló!

    Szuper amit írsz továbbra is🙂

    Az sfForm::convertFileInformation()-ban egy regex van, ami a

    static public function arrayToPaths($array = array(), $prefix = ”)

    statikus metódussal nyeri ki az adatokat feldolgozás előtt, szerintem ezzel te is ki tudod nyerni.

  2. Sulik Szabolcs szerint:

    kosz

    Az sfForm::convertFileInformation()-ban egy regex van, ami …

    De miért tennék ilyet? Ha jobban megnézed ott két static metódushivás van. Pont ezt használja az sfForm is, ezért gondoltam hogy jó az nekem is.

    Egyébként érdekes, hogy enélkül az előzetes átalakítás nélkül képtelen felfogni a bind(), hogy ez tömb valóban egy FILES tömb akar lenni. Számomra ez rejtély.

  3. j. szerint:

    Akkor csak félreértettelek, annyira nem néztem utána, csak segíteni akartam, hátha…de ezek szerint teljesen más volt a problémád.🙂

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