Formulaire multiples

Depuis la 1.1, les formulaires imbriqués sont gérés grace à la méthode embedForm de la classe sfForm

Un exemple avec le module sfDoctrineGuard que l’on veut éttendre avec un profil.

La classe du formulaire principal :

class sfGuardUserForm extends PluginsfGuardUserForm
{
  public function configure()
  {
    unset(
      $this['is_active'],
      ...
      $this['permissions_list']
    );
 
    $profile = new ProfileForm();
 
    unset(
      $profile['sf_guard_user_id']
    );
 
    $this->embedForm('Profile', $profile);
  }
}

L’action :

public function executeIndex(sfWebRequest $request)
{
  $this->form = new sfGuardUserForm();
 
  if( $request->isMethod('post') && $this->form->bindAndSave() )
  {
    $this->getUser()->setFlash('notice', 'Utilisateur enregistré.');
    $this->redirect('utilisateur/index');
  }
}

Le problème c’est que le de bindAndSave() sur le formulaire principal provoque 2 save sur le formulaire embarqué.

Du coup si il y a des champs unique dans le formulaire embarqué et surtout un notnull sur la clé de jointure, ca plante.

La méthode alternative pour arriver au même résultat :

Pas la peine de redéfinir la classe formulaire.

Tout se passe dans la classe action ou on va définir les 2 formulaires à utiliser dans la vue et le traitement associé.

  public function executeInscription(sfWebRequest $request)
  {
    $this->formUser    = new sfGuardUserFormInscription();
    $this->formProfile = new UtilisateurFormInscription();
 
    if( $request->isMethod('post') )
    {
      $this->formUser->bind($request->getParameter('sf_guard_user', array()));
      $this->formProfile->bind($request->getParameter('utilisateur', array()));
 
      if( $this->formUser->isValid() && $this->formProfile->isValid() )
      {
        $con = Doctrine_Manager::connection();
 
        try
        {
          $con->beginTransaction();
 
          $newUser = $this->formUser->save($con);
          $newProfil = $this->formProfile->save($con);
 
          $newProfil->setUserId($newUser->getId());
          $newProfil->save($con);
 
          $con->commit();
        }
        catch(Exception $e)
        {
          $con->rollback();
 
          throw $e;
        }
 
        $this->getUser()->setFlash('notice', "Votre inscription a bien été prise en compte.\nVous allez recevoir un email dans quelques minutes pour valider votre inscription.");
        $this->redirect('utilisateur/index');
      }
 
    }
  }

Pour garantir l’intégrité des données il faut passer par une transaction que l’on est obligé de gérer à la main. (avec embedForm elle est gérée automatiquement)

Le code html avec les deux formulaires :

<form action="<?php echo url_for('utilisateur/inscription'); ?>" method="post">
  <table>
    <?php echo $formUser ?>
    <?php echo $formProfile ?>
    <tr>
      <td colspan="2"><input type="submit" value="<?php echo __('Signin') ?>" /></td>
    </tr>
  </table>
</form>
    

One Response to “Formulaire multiples”

  1. yOye dit :

    Après moulte recherche j’ai trouvé ceci :

    sfGuardUserProfile

    En gros dans tu as tes deux formulaires celui pour le profil et celui pour l’user.

    Tu crais un formulaire d’inscription et tu mets le code suivant :
    $profileForm = new UserProfileForm($this->object->UserProfile);

    Tu te retrouves avec une classe comme ceci :


    class sfGuardAddUserForm extends sfGuardUserForm{

    public function configure()
    {

    $profileForm = new UserProfileForm($this->object->UserProfile);

    $this->embedForm('profile', $profileForm);
    }

Leave a Reply

Security Code: