Hello everybody (please excuse my English).
I want to do an application which needs to allow that the users must fill out on a form their personal data, their children, grandchildren and great-grandchildren (a little family tree).
class Person
{
/**
* @var int
*
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var string
*
* @ORM\Column(type="string")
*/
private $firstname;
/**
* @var string
*
* @ORM\Column(type="string")
*/
private $lastname;
/**
* @var \DateTime
*
* @ORM\Column(type="datetime")
*/
private $dateOfBirth;
/**
* @var Person
*
* @ORM\ManyToMany(targetEntity="Person")
*/
private $children;
public function __construct()
{
$this->children = new ArrayCollection();
}
}
}
In the PersonType class, I do the following:
class PersonType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('firstname');
$builder->add('lastname');
$builder->add('dateOfBirth');
$builder->add('children', 'collection', array(
'type' => new PersonType(),
'allow_add' => true,
'by_reference' => false,)
);
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Anything\YourBundle\Entity\Person'
));
}
/**
* @return string
*/
public function getName()
{
return 'person';
}
}
In this way, I use the PersonType in the controller as below:
public function newAction()
{
$entity = new Person();
$form = $this->createForm(new PersonType(), $entity, array(
'action' => $this->generateUrl('person_create'),
'method' => 'POST',
));
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
But the problem is when I request the url of this action, and the view of this action has to be rendered, there is a problem because doesn't give a response, because is in a infinite loop (I think that is the reason). I would like to know if is this possible to do using the Symfony forms, or if I have to look at other alternatives. If this was possible, how could I do that and how could I limit the form to only render the four levels that I need (me, my children, my grandchildren and my great-grandchildren)??
I hope that the problem has been understood.
Thanks in advance.
Thanks for the answer Ferdynator!!
I didn't solve the problem in the way you proposed, but that approach helped me. I passed the recursion level in the constructor of the Person form, and thus, I could know when I had to stop:
class PersonType extends AbstractType
{
private $recursionLevel;
public function __construct( $recursionLevel ){
$this->recursionLevel = $recursionLevel;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
if($this->recursionLevel > 0)
{
$builder->add('children', 'collection', array(
'type' => new PersonType(--$this->recursionLevel),
'allow_add' => true,
'by_reference' => false,)
);
}
}
}