Symfony2 __toString() error - symfony

I have a problem with saving entities back to me this error:
Catchable Fatal Error: Method My\BusinessBundle\Entity\Type::__toString()
must return a string value in
/var/www/MyBusiness0_1/vendor/doctrine/orm/lib/Doctrine/ORM/ORMInvalidArgumentException.php line 113
The strange thing is that the method __ toString () is the entity Type!
class Type
{
//..
/**
* #var string
*
* #ORM\Column(name="type", type="string", length=100)
*/
private $type;
/**
* #ORM\OneToMany(targetEntity="MailTelCont", mappedBy="type")
*/
protected $mailTelContacts;
public function __construct()
{
$this->mailTelContacts = new \Doctrine\Common\Collections\ArrayCollection();
}
public function __toString()
{
return $this->getType();
}
//...
Another strange thing is that if I put cascade ={"persist"} class MailTelCont on ManyToOne relationship "type" does not show me this error, but save a new field in Type ..
class MailTelCont
class MailTelCont
{
//..
/**
* #var string
*
* #ORM\Column(name="contact", type="string", length=100)
*/
private $contact;
/**
* #ORM\ManyToOne(targetEntity="Type", inversedBy="mailTelContacts")
* #ORM\JoinColumn(name="type_id", referencedColumnName="id")
*/
private $type;
/**
* #ORM\ManyToOne(targetEntity="Anagrafica", inversedBy="mailTelContacts", cascade={"persist"})
* #ORM\JoinColumn(name="anagrafica_id", referencedColumnName="id")
* #Assert\Type(type="My\BusinessBundle\Entity\Anagrafica")
*/
private $anagrafica;
public function __toString()
{
return $this->getContact();
}
Call the form of nested "AnagraficType" in this way:
class TypeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', 'entity', array(
'class' => 'My\BusinessBundle\Entity\Type',
'attr' => array('class' => 'conct'),
'property' => 'type',
'label' => 'Tipologia',
))
;
}
*****
class MailTelContType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', new TypeType())
->add('contact', 'text', array('label' => 'Contatto'))
;
}
*****
class AnagraficaType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('mailTelContacts', 'collection', array('type' => new MailTelContType(),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false
))
Where am I doing wrong?

I think those values are null then. Did you try:
public function __toString()
{
return (string) $this->getType();
}
and
public function __toString()
{
return (string) $this->getContact();
}
That way when value is null will be casted to string and you should not get this exception.

Related

Expected argument of type "integer", "App\Entity\Entreprise" given

I uses two entitys: stagiaire and entreprise. Each stagiaire have one entreprise. I just need to save the id entreprise in the stagiaire table.
When I create a new stagiaire, choose an enterprise for him and save the form, I have the following error
"Expected argument of type "integer" in the stagiaire controller:
"App\Entity\Entreprise" given
Here is the code of the stagiaire entity:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\StagiaireRepository")
*/
class Stagiaire
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="civilite", type="string", length=3, nullable=false)
*/
private $civilite = 'Mr';
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=24, nullable=false)
*/
private $nom;
/**
* #var string
*
* #ORM\Column(name="prenom", type="string", length=16, nullable=false)
*/
private $prenom;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Entreprise")
* #ORM\JoinColumn(nullable=false)
*/
private $entreprise;
/**
* #var string
*
* #ORM\Column(name="status", type="string", length=12, nullable=false)
*/
private $status;
public function __construct()
{
//$this->date = new \Datetime();
//$this->entreprise = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getCivilite(): ?string
{
return $this->civilite;
}
public function setCivilite(string $civilite): self
{
$this->civilite = $civilite;
return $this;
}
public function getNom(): ?string
{
return $this->nom;
}
public function setNom(string $nom): self
{
$this->nom = $nom;
return $this;
}
public function getPrenom(): ?string
{
return $this->prenom;
}
public function setPrenom(string $prenom): self
{
$this->prenom = $prenom;
return $this;
}
public function getEntreprise(): ?int
{
return $this->entreprise;
}
public function setEntreprise(int $entreprise): self
{
$this->entreprise = $entreprise;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
Here is the code of the form:
use App\Entity\Stagiaire;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
class StagiaireType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$choicesCivil = [
'Mr' => '1',
'Mme' => '2'
];
$choicesStatus = [
'Gérant' => '1',
'Salarié' => '2'
];
$builder
->add('civilite', ChoiceType::class, [
'data' => '1', // cochée par défaut
'choices' => $choicesCivil,
'expanded' => true, // => boutons
'label' => 'Civilité',
'multiple' => false
])
->add('nom')
->add('prenom')
->add('entreprise', EntityType::class, array(
'class' => 'App:Entreprise',
'placeholder' => 'Choisir une entreprise',
'choice_label' => 'enseigne',
))
->add('status', ChoiceType::class, [
'data' => '1', // cochée par défaut
'choices' => $choicesStatus,
'expanded' => true, // => boutons
'label' => 'Statut',
'multiple' => false
])
->add('create', SubmitType::class, ['label' => 'Enregistrer', 'attr' => ['class' => 'btn btn-primary']]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Stagiaire::class,
]);
}
}
And here is the controller:
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Entity\Stagiaire;
use App\Entity\Entreprise;
use App\Repository\StagiaireRepository;
use App\Form\StagiaireType;
class StagiaireController extends Controller
{
public function fStagiaire($id,$cat,$action, Request $request)
{
if ($action=='insert') {
$stagiaire = new Stagiaire();
}
elseif($action=='update' || $action=='delete') {
$stagiaire = $this->getDoctrine()
->getManager()
->getRepository('App:Stagiaire')
->find($id)
;
}
else { return;}
$form = $this->get('form.factory')->create(StagiaireType::Class, $stagiaire);
if ($request->isMethod('POST')) {
$form->handleRequest($request);
if ($form->isValid()) {...
The error occurs at the line $form->handleRequest($request);
I am searching for a few days but I do not found the solution.
Has anybody an idea to help?
Your function setEntreprise(int $entreprise): self is being given an object (an App\Entity\Entreprise), which is not what it is expecting. While the record in the database will be an int (the primary key id on the Entreprise entity - and in fact, it will be a separate database table that refers back to this record's ID with zero or more Entreprise records), it is made available to your code (from getEntreprise()) as the object (so returning the nullable int there would also fail when you come to read the linked entity out - it should be an empty ArrayCollection()).
Your setter & getter need to deal with the objects - and since it's a 'ManyToOne' relationship, there can more more than one. You will likely also want an addEntreprise() function to be able to add more objects. The ORM will deal with saving the data in them to the database, and linking them back in later when this record is read in.
public function __construct()
{
//$this->date = new \Datetime();
//$this->entreprise = new ArrayCollection();
}
# These lines say that `$this->entreprise` is an array - by default empty, but
# it can be filled up with a number of linked objects.
You need to change your functions to accept an entreprise object instead of an id:
public function getEntreprise(): ?Entreprise
{
return $this->entreprise;
}
public function setEntreprise(Entreprise $entreprise): self
{
$this->entreprise = $entreprise;
return $this;
}
and you have to add use App\Entity\Entreprise; to the Stagiaire class.

Expected argument of type "string", "App\Entity" given

I try to insert records with relations OneToMany-ManyToOne, but I got error.
Expected argument of type "string", "App\Entity\Question" given.
I have next entities question and answer.
class Question
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="text")
*/
private $title;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Answer", mappedBy="question", orphanRemoval=true)
*/
private $answers;
public function __construct()
{
$this->answers = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
/**
* #return Collection|Answer[]
*/
public function getAnswers(): Collection
{
return $this->answers;
}
public function addAnswer(Answer $answer): self
{
if (!$this->answers->contains($answer)) {
$this->answers[] = $answer;
$answer->setQuestion($this);
}
return $this;
}
public function removeAnswer(Answer $answer): self
{
if ($this->answers->contains($answer)) {
$this->answers->removeElement($answer);
if ($answer->getQuestion() === $this) {
$answer->setQuestion(null);
}
}
return $this;
}
}
Entity Answer
class Answer
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="text")
*/
private $text;
/**
* #ORM\Column(type="boolean")
*/
private $is_correct;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Question", inversedBy="answers")
* #ORM\JoinColumn(nullable=false)
*/
private $question;
public function getId(): ?int
{
return $this->id;
}
public function getText(): ?string
{
return $this->text;
}
public function setText(string $text): self
{
$this->text = $text;
return $this;
}
public function getIsCorrect(): ?bool
{
return $this->is_correct;
}
public function setIsCorrect(bool $is_correct): self
{
$this->is_correct = $is_correct;
return $this;
}
public function getQuestion(): ?question
{
return $this->question;
}
public function setQuestion(?Question $question): self
{
$this->question = $question;
return $this;
}
}
My form
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', EntityType::class, array(
'class' => Question::class,
'choice_label' => 'title',
'label' => 'Question'
));
$builder
->add('answers', CollectionType::class, array(
'entry_type' => AnswerType::class,
'entry_options' => array('label' => false),
'allow_add' => true,
'by_reference' => false,
));
$builder
->add('create', SubmitType::class, ['label' => 'Add', 'attr' => ['class' => 'btn btn-primary']]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Question::class
]);
}
My fragment of controller
$question = new Question();
$answer = new Answer();
$question->addAnswer($answer);
$form1 = $this->createForm(QuestionAnswerType::class, $question);
$form1->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($question);
$em->flush();
}
The error pointer at next line
$form1->handleRequest($request);
I know I have problem with my controller, but I don't know how resolve it.
I don't get it how right insert records with relations OneToMany-ManyToOne. Could you help me?
I think the reason that you are seeing this error is due to the fact that in your Question class you have defined the title field as a Text type (#ORM\Column(type="text")).
However in your Form you have defined the form field title as an EntityType this is the reason I think why you are seeing this error.
You can fix this by changing the database mapping of the title field in your Question class or you could change your Form to use a TextType instead of an EntityType
Hope this helps
You have to do changes into two places.
1) First change into "Question" class
/**
* #ORM\Column(type="string")
*/
private $title;
2) Second into your form class replace "EntityType::class" with "TextType::class" and remove 'class' and 'choice_label' attribute from title
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, array(
'label' => 'Question'
));
..... your other code ...
}
In class Question __toString function is missing
public function __toString()
{
return $this->property-to-show;
}

Symfony Form - Allow removal of nested form associated entity

I have a /checkout JSON API endpoint which allows an optional billingAddress parameter alongside other parameters such as email and deliveryAddress.
These addresses are stored in an Address entity related to an Order entity.
Everything works nicely if a user enters their billingAddress, but if a user removes a previously submitted billing address, I can find no way to remove the billingAddress entity. Ideally to remove the billing address I'd use the following JSON POST request.
{
"email": "nick#example.com",
"deliveryAddress": {
"line1": "1 Box Lane"
},
"billingAddress": null
}
Is this at all possible with Symfony forms?
See below for a simplified explanation of the current setup.
Entities
/**
* #ORM\Entity
*/
class Order
{
// ...
/**
* #var Address
*
* #ORM\OneToOne(targetEntity = "Address", cascade = {"persist", "remove"})
* #ORM\JoinColumn(name = "deliveryAddressId", referencedColumnName = "addressId")
*/
private $deliveryAddress;
/**
* #var Address
*
* #ORM\OneToOne(targetEntity = "Address", cascade = {"persist", "remove"}, orphanRemoval = true)
* #ORM\JoinColumn(name = "billingAddressId", referencedColumnName = "addressId", nullable = true)
*/
private $billingAddress;
public function setDeliveryAddress(Address $deliveryAddress = null)
{
$this->deliveryAddress = $deliveryAddress;
return $this;
}
public function getDeliveryAddress()
{
return $this->deliveryAddress;
}
public function setBillingAddress(Address $billingAddress = null)
{
$this->billingAddress = $billingAddress;
return $this;
}
public function getBillingAddress()
{
return $this->billingAddress;
}
// ...
}
.
/**
* #ORM\Entity
*/
class Address
{
// ...
/**
* #var string
*
* #ORM\Column(type = "string", length = 45, nullable = true)
*/
private $line1;
// ...
}
Forms
class CheckoutType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class)
->add('deliveryAddress', AddressType::class, [
'required' => true
])
->add('billingAddress', AddressType::class, [
'required' => false
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Order::class,
'csrf_protection' => false,
'allow_extra_fields' => true,
'cascade_validation' => true
]);
}
public function getBlockPrefix()
{
return '';
}
}
.
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add('line1', TextType::class);
// ...
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Address::class,
'allow_extra_fields' => true
]);
}
public function getBlockPrefix()
{
return '';
}
}
Form events are what you need: https://symfony.com/doc/current/form/events.html
For example if you want to remove the billingAddress field after the form submission you can do that:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class)
->add('deliveryAddress', AddressType::class, [
'required' => true
])
->add('billingAddress', AddressType::class, [
'required' => false
]);
$builder->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
if (empty($data['billingAddress'])) {
$form->remove('billingAddress');
}
});
}
Read carefully the documentation to know which event will be the best for your scenario.
Try setting the "by_reference" option for the "billingAddress" field to false in order to make sure that the setter is called.
http://symfony.com/doc/current/reference/forms/types/form.html#by-reference
Big thanks to Renan and Raphael's answers as they led me to discovering the below solution which works for both a partial PATCH and full POST request.
class CheckoutType extends AbstractType
{
/** #var bool */
private $removeBilling = false;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class)
->add('deliveryAddress', AddressType::class, [
'constraints' => [new Valid]
])
->add('billingAddress', AddressType::class, [
'required' => false,
'constraints' => [new Valid]
])
->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit'])
->addEventListener(FormEvents::POST_SUBMIT, [$this, 'onPostSubmit']);
}
public function onPreSubmit(FormEvent $event)
{
$data = $event->getData();
$this->removeBilling = array_key_exists('billingAddress', $data) && is_null($data['billingAddress']);
}
public function onPostSubmit(FormEvent $event)
{
if ($this->removeBilling) {
$event->getData()->setBillingAddress(null);
}
}
}

Symfony2 forms and many to many relation

(Symfony version 2.7)
Hi, I have a problem with form in field with many to many relation.
Class Notification {
public function __construct()
{
$this->assigneduser = new \Doctrine\Common\Collections\ArrayCollection();
$this->flags = new ArrayCollection();
}
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Flag", inversedBy="notificationflags", cascade={"persist"})
* #ORM\JoinTable(name="sla_notificationflags",
* joinColumns={#ORM\JoinColumn(name="notification_id", referencedColumnName="notificationId")},
* inverseJoinColumns={#ORM\JoinColumn(name="flag_id", referencedColumnName="flagId")}
* )
*
*/
private $flags;
/**
* Add flag
*
* #param \AppBundle\Entity\Flag $flag
* #return Notification
*/
public function addFlag(Flag $flag)
{
$flag->addNotificationflag($this);
$this->flags[] = $flag;
return $this;
}
}
Class Flag {
public function __construct()
{
$this->notificationflags = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Notification", mappedBy="flags")
*/
protected $notificationflags;
/**
* Add notificationflags
*
* #param \AppBundle\Entity\Notification $notificationflag
* #return Flag
*/
public function addNotificationflag(Notification $notificationflag)
{
if(!$this->notificationflags->contains($notificationflag)) {
$this->notificationflags->add($notificationflag);
}
return $this;
}
}
My Form Class
class NotificationSingleFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('flags','entity',array(
'label' => false,
'attr' => array(
'class' => 'select'
),
'class' => 'AppBundle\Entity\Flag',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('p')
->addOrderBy('p.name','ASC');
},
'property' => 'name',
'required' => false
)
);
}
}
When i send the form i see error:
Neither the property "flags" nor one of the methods
"addFlag()"/"removeFlag()", "setFlags()", "flags()", "__set()" or
"__call()" exist and have public access in class
"AppBundle\Entity\Notification".
You have to genrate getters/setters and add/remove methods of flag attribute.
use php app/console doctrine:generate:entities to generate them automatically

Symfony2 - Display a form recursively

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.
You could add a custom parameter to your form that indicates the current level of recursion.
To archive this you first need to implement a new option:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Anything\YourBundle\Entity\Person',
'recursionLevel' => 4
));
}
Now you update this value in your buildForm method:
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
if (--$options['recursionLevel'] > 0) {
$resolver = new OptionsResolver();
$resolver->setDefaults(
$options
);
$childType = new PersonType();
$childType->setDefaultOptions($resolver);
$builder->add('children', 'collection', array(
'type' => $childType,
'allow_add' => true,
'by_reference' => false
));
}
}
This is not tested.
I had the same problem and tried the solutions provided here.
They come with significant drawbacks like a depth limitation and performance overhead - you always create form objects even if there is no data submited.
What I did to overcome this problem was to add a listener for the FormEvents::PRE_SUBMIT event and add the collection type field dynamically if there is data to be parsed.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('content');
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$node = $event->getData();
$form = $event->getForm();
if (!$node) {
return;
}
if(sizeof(#$node['children'])){
$form->add('children', CollectionType::class,
array(
'entry_type' => NodeType::class,
'allow_add' => true,
'allow_delete' => true
));
}
});
}
I hope this helps someone that has this issue in the future
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,)
);
}
}
}
Ferdynator, thanks for your answers. And I want to propose my decision based on yours:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Anything\YourBundle\Entity\Person',
'recursionLevel' => 4
));
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
if (--$options['recursionLevel'] > 0) {
$builder->add('children', 'collection', array(
'type' => $childType,
'allow_add' => true,
'by_reference' => false,
'options' => [
'recursionLevel' => $options['recursionLevel']
],
));
}
}
It solves our problem.

Resources