Symfony unsetAllExcept + i18n = unsetAllExceptI18n

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…

Catégorie : Symfony | #, #, #, # | Permalink

3 commentaires

  1. eddie

    Merci pour ton article et de ton aide par mp.
    Par contre je pense que la méthode est plus complexe quand on utilise l’admin generator.

    D’ailleurs je pense qu’il est préférable de ne pas utiliser l’admin generator car dans la plupart des cas on fini par se retrouver coincé dès que l’on souhaite dévier de l’affichage classique.

  2. Jonathan Martin

    Je suis d’accord sur le fait que l’on peut se retrouver plus ou moins bloquer comme toi avec l’admin générator selon nos besoins spécifiques, après il faut faire un choix:

    - soit revoir nos exigences à la baisse et s’adapter aux contraintes de l’admin générator.

    - soit redévelopper un back office from-scratch comme un front en utilisant les CRUD (je ne suis pas forcément pour, mais je peux comprendre qu’on en arrive à faire cela)

  3. merci sinon très bon article !

Laisser un commentaire

*