Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

symfony2 doctrine - Adding children to self-related Entity

I have an entity which relates to itself. The entity has fields: parent and children.

class A
{
    // ...

    /**
     * @var A
     * @ORM\ManyToOne(targetEntity="A", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
     */
    protected $parent;

    /**
     * @var A[]
     * @ORM\OneToMany(targetEntity="A", mappedBy="parent", cascade={"all"}, orphanRemoval=true)
     */
    protected $children;
}

I want to add children to this entity by setting up children in form. This entity type looks like this:

class AType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // ...
            ->add('children', 'collection', [
                'type' => new AType(),
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
                'prototype' => true,
            ])
        ;
    }
}

When I send data like this:

'a' => [
    [
        'name' => 'main a',
        'children' => [
            [
                'name' => 'child a 1',
            ],
            [
                'name' => 'child a 2',
            ],
        ],
    ],
],

(in test, I don't have view, because this application is based on full REST Api communication) I got this error:

PHP Fatal error: Maximum function nesting level of '100' reached, aborting!

So, is it even possible to add children to self-related entities?

It would work if I have 2 entities: entity A with field children related to entity B. But, can it work with this relation?

Should I change type in AType class from new AType() to something different.

EDIT: Actually I just want to get data and validate it. I don't need HTML form to display it. I can do it like this:

// controller
$jms = $this->get('jms_serializer');
$entity = $jms->deserialize($request->getContent(), 'AcmeBundle\Entity\A', 'json');

$this->em->persist($entity);
$this->em->flush();

without using Form in controller. But in this case my data won't be validated.

like image 221
Kamil P Avatar asked Nov 16 '15 17:11

Kamil P


1 Answers

PHP Fatal error: Maximum function nesting level of '100' reached, aborting!

Because you have recursion. When you call createForm, it tries resolve type.

You can find this part of code in the FormFactory function resolveType.

I think you can create second form type which includes title and parent.

class AType extends AbstractType{
   //...
   public function buildForm(FormBuilderInterface $builder, array $options)
   {
    $builder
        ->add('title')
        ->add('parent')
        ->add('children', 'collection', array(
            'type' => new BType(),
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
            'prototype' => true
        ));
   }
}

class BType extends AbstractType {
    //..
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
       $builder
         ->add('title')
         ->add('parent');
    }
 }

I think form builder can fetch and map Content-Type:application/x-www-form-urlencoded. I have implemented with html form. Also I have tried to send application/json but result is unsuccessful. That's why you can use json schema validators here.

like image 160
Isabek Tashiev Avatar answered Oct 25 '22 11:10

Isabek Tashiev