Articles avec le tag ‘formulaire’

Symfony unsetAllExcept + i18n = unsetAllExceptI18n

Mardi 15 septembre 2009

Suite au commentaire de eddie sur l’article « Symfony – Formulaire en plusieurs étapes » voici un exemple d’un formulaire multilangue en plusieurs étapes.

symfony-logo

Petit rappel du contexte: symfony 1.2 + Doctrine

Dans le fichier schema.yml

Projet1Exemple:
  tableName: projet1_exemple
  actAs:
    I18n:
      fields: [titre, description, mots]
  columns:
    id:
      type: integer(4)
      primary: true
      unsigned: true
      notnull: true
      autoincrement: true
    fichier:
      type: string(255)
      unique: true
      notnull: true
    type:
      type: enum
      values: ['image', 'video', 'audio', 'document']
      notnull: true
      default: image
    titre:
      type: string(255)
      description:
      type: string(4000)
    mots:
      type: string(4000)

Nous avons donc deux champs communs à toutes les langues : fichier et type. Et trois champs multilangues : titre, description mots.

L’idée consisterait à mettre dans une première étape uniquement les champs : fichier (commun), titre (multilangue) et description (multilangue).

Dans le fichier actions.class.php

public function executeIndex(sfWebRequest $request) {
  $this->form = new Projet1ExempleForm()
}

Dans le fichier /lib/form/doctrine/BaseFormDoctrine.class.php, ajouter la fonction suivante :

public function unsetAllExceptI18n($keepFields = array(), $cultures = array(), $keepFieldsI18n = array()) {
  $keepFields[] = $cultures;
  foreach ($this as $key => $value)
    $baseFields[] = $key;
  $temp = array_diff($baseFields, $keepFields);
  foreach ($temp as $unsetField)
    unset($this[$unsetField]);
  $embeds = $this->getEmbeddedForms();
  foreach ($cultures as $culture)
    $formsI18n[$culture] = $embeds[$culture];
  foreach ($formsI18n as $culture => $formI18n)
  {
    foreach ($formI18n as $key => $value)
      $baseFieldsI18n[] = $key;
    $temp = array_diff($baseFieldsI18n, $keepFieldsI18n);
    foreach ($temp as $unsetField)
      unset($formI18n[$unsetField]);
    unset($this[$culture]);
    $this->embedForm($culture, $formI18n);
  }
}

Explication des paramètres :

  • -  »$keepFieds » : un tableau des champs ‘commun’ que vous souhaitez « garder ».
  • -  »$cultures » : un tableau des différentes cultures que vous voulez utiliser.
  • -  »$keepFieldsI18n » : un tableau des champs ‘multilangues’ que vous souhaitez « garder ».

Et enfin dans le fichier /lib/form/doctrine/Projet1ExempleForm.class.php

class Projet1ExempleForm extends BaseProjet1ExempleForm {
  public function configure() {
    //Introduire les formulaires multilangues dans un premier temps
    $this->embedI18n(array('fr'));
    $this->embedI18n(array('en'));
    //Garder uniquement les champs dont vous avez besoin
    $this->unsetAllExceptI18n(array('fichier'), array('fr', 'en'), array('titre', 'description'));
  }
}

Et enfin dans votre template

//Soit tout simplement
<?php echo $form;?>

//ou
<?php echo $form['fichier']->renderLabel()?>
<?php echo $form['fichier']->render()?>
<?php echo $form['fr']['description']->renderLabel()?>
<?php echo $form['fr']['description']->render()?>
//...

Voici un aperçu du résultat : Capture_d_ecran_2009-09-15_a_19.25.01

Vous pouvez ensuite continuer de la même manière pour les prochaines étapes de votre formulaire.

N’hésitez pas à me solliciter pour plus d’explications.

To be continued…

Symfony – Formulaire en plusieurs étapes

Vendredi 28 août 2009

Comment mettre en place un formulaire en plusieurs étapes avec Symfony 1.2 et Doctrine? Je vais tenter de vous expliquer cela par un exemple concret.

symfony-logo

Nous allons réaliser une inscription de membre en plusieurs étapes:

  • - Etape 1 : Identification  »(pseudo, mail, password) »
  • - Etape 2 : Informations complémentaires  »(nom, prenom, adresse, cp, ville) »

Dans le fichier /config/doctrine/schema.yml :

membre:
  columns:
    id: { type: integer(4), primary: true, notnull: true, autoincrement: true }
    pseudo: { type: string(255) }
    mail: { type: string(255) }
    password: { type: string(255) }
    nom: { type: string(255) }
    prenom: { type: string(255) }
    adresse: { type: string(255) }
    cp: { type: string(255) }
    ville: { type: string(255) }

Lancer ensuite la commande :

symfony doctrine:build-all

Editer le fichier /lib/form/doctrine/BaseFormDoctrine.class.php et ajouter cette fonction :

public function unsetAllExcept ($keepFields = array()) {
  foreach ($this as $key => $value)
    $baseFields[] = $key;
    $temp = array_diff($baseFields, $keepFields);
    foreach ($temp as $unsetField)
      unset($this[$unsetField]);
}

Nous allons maintenant créer deux formulaires ‘membre’ pour les deux étapes du formulaire.

Créer le fichier /lib/form/doctrine/membreEtape1Form.class.php

class membreEtape1Form extends BasemembreForm {
  public function configure () {
    $this->unsetAllExcept(array( 'pseudo', 'mail', 'password' ) );
  }
}

Créer maintenant le fichier /lib/form/doctrine/membreEtape2Form.class.php

class membreEtape2Form extends BasemembreForm {
  public function configure ()   {
    $this->unsetAllExcept(array( 'nom', 'prenom', 'adresse', 'cp', 'ville' ) );
  }
}

Lancer ensuite la commande pour vider le cache :

symfony cc

Vous pouvez maintenant initialiser vos formulaires dans actions.class.php

public function executeInscriptionEtape1(sfWebRequest $request) {
  $this->form = new membreEtape1Form();
}
public function executeInscriptionEtape2(sfWebRequest $request) {
  $this->form = new membreEtape2Form();
}

Vous pouvez dès à présent vous inspirer de cette base pour vos propres besoins.

N’hésitez pas à me contacter par commentaire pour plus d’explications.

To be continued…