php - Symfony 2 : multi-steps form with CraueFormFlowBundle and FOSUserBundle
For my application, I have to create a multi-steps form for registering new users, so i have installed CraueFormFlowBundle, and I use FOSUserBundle too.
For the first step of my registering form, I want to register user's informations (login, password...) with FOSUserBundle, and after the user will be redirect to the next step of the form.
So I have embedding a collection of form type in single type called "RegistrationEtablissementForm".
But when I try to render the view of my multi-steps form, I have this error :
Warning: Missing argument 1 for FOS\UserBundle\Form\Type\RegistrationFormType::__construct(), called in C:\wamp\www\likabee_3\src\AppBundle\Form\RegistrationEtablissementForm.php on line 14 and defined
The type RegistrationEtablissementForm :
namespace AppBundle\Form;
// AppBundle/Form/RegistrationEtablissementForm.php
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class RegistrationEtablissementForm extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
switch ($options['flow_step']) {
case 1:
$builder->add('registration', array('type' => new RegistrationFormType()));
break;
case 2:
$builder->add('etablissement', array('type' => new EtablissementType()));
break;
case 3:
$builder->add('chambres', 'collection', array(
'type' => new ChambreType(),
'allow_add' => true,
'allow_delete' => true
));
break;
}
}
public function getName() {
return 'registrationEtablissement';
}
}
And the first form types :
namespace AppBundle\Form;
use Symfony\Component\Form\FormBuilderInterface;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
class RegistrationFormType extends BaseType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
// add your custom field
$builder
->add('nom', 'text')
->add('prenom', 'text')
->add('telephonePortable', 'text')
->add('telephoneFixe', 'text', array('required' => false))
->add('fax', 'text', array('required' => false))
->add('Civilite', 'text')
;
}
public function getName()
{
return 'homes_user_registration';
}
}
the second :
class EtablissementType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombre_place_total','choice', array('choices' => array('1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', '10' => '10', '11' => '11', '12' => '12', '13' => '13', '14' => '14', '15' => '15')))
->add('tarif_min', 'text')
->add('tarif_max', 'text')
->add('description', 'textarea')
->add('nom_etablissement', 'text')
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Etablissement'
));
}
/**
* @return string
*/
public function getName()
{
return 'appbundle_etablissement';
}
}
and the third :
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ChambreType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nom_chambre', 'text')
->add('nombre_place','choice', array('choices' => array('1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', '10' => '10')))
->add('nombre_lit','choice', array('choices' => array('1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6')))
->add('superficie', 'text')
->add('tarif_1', 'text')
->add('tarif_2', 'text')
->add('tarif_3', 'text')
->add('tarif_4', 'text')
->add('tarif_5', 'text')
->add('tarif_6', 'text')
//->add('etablissement')
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Chambre'
));
}
/**
* @return string
*/
public function getName()
{
return 'appbundle_chambre';
}
}
In my services.yml file, the form for registration with FOSUserBundle AND the multi-steps-form are enabled has service :
services:
# service_name:
# class: AppBundle\Directory\ClassName
# arguments: ["@another_service_name", "plain_value", "%parameter_name%"]
homes_user.registration.form.type:
class: AppBundle\Form\RegistrationFormType
arguments: [%fos_user.model.user.class%]
tags:
- { name: form.type, alias: homes_user_registration }
likabee.form.registrationEtablissement:
class: AppBundle\Form\RegistrationEtablissementForm
tags:
- { name: form.type, alias: registrationEtablissement }
likabee.form.flow.registrationEtablissement:
class: AppBundle\Form\RegistrationEtablissementFlow
parent: craue.form.flow
scope: request
calls:
- [ setFormType, [ "@likabee.form.registrationEtablissement" ] ]
In my controller, I have created this function for rendering the form in a view :
/**
* @Route("/registration-etablissement", name="registrationEtablissement")
*/
public function registrtationEtablissementAction() {
$formData = new RegistrationEtablissementForm(); // Your form data class. Has to be an object, won't work properly with an array.
$flow = $this->get('likabee.form.flow.registrationEtablissement'); // must match the flow's service id
$flow->bind($formData);
// form of the current step
$form = $flow->createForm();
if ($flow->isValid($form))
{
$flow->saveCurrentStepData($form);
if ($flow->nextStep()) {
// form for the next step
$form = $flow->createForm();
} else {
// flow finished
$em = $this->getDoctrine()->getManager();
$em->persist($formData);
$em->flush();
$flow->reset(); // remove step data from the session
return $this->redirect($this->generateUrl('index')); // redirect when done
}
}
return $this->render('registrationEtablissement.html.twig', array(
'form' => $form->createView(),
'flow' => $flow,
));
}
I search the solution for few days, but I doesn't find it ...
Thanks for your help, and sorry for my english ;)
Answer
Solution:
In your class RegistrationEtablissementForm on line 14 you are calling the FOS\UserBundle\Form\Type\RegistrationFormType constructor. If you check the code of the class in the FOSUserBundle you can see that the constructor requires the user class name as attribute:
Adding your user class when you call the constructor should solve this problem.