简体   繁体   中英

Multiple nested collection fields in Sonata Admin

I have little experience in using Sonata Admin and i need help.

There are 4 entities: Poll, Field (question), PollHasField, Option (answer). I need to make one page PollAdmin where it will be possible to create Fields and Options for them.

在此处输入图像描述

Now I managed to make a FieldAdmin page where you can create options, and a PollAdmin page where you can add existing Fields. But when i'm try to bind FieldAdmin with PollHasFieldAdmin by setting 'sonata_type_collection' type in PollHasFieldAdmin i'm getting error:

request.CRITICAL: Uncaught PHP Exception Symfony\Component\Form\Exception\UnexpectedTypeException: "Expected argument of type "array or \Traversable", "Proxies_ CG _\SIP\ResourceBundle\Entity\Poll\Field" given" at C:\wamp64\www\butler.backend\vendor\sonata-project\core-bundle\Form\EventListener\ResizeFormListener.php line 96

PollAdmin class:

protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->with('General')
                ->add('title', null, array('label' => 'sip.customer.title'))
                ->add('active', null, array('label' => 'is active'))
                ->add('howOftenToShow', null, array('label' => 'Frequency'))

                ->add('fields', 'sonata_type_collection', array(
                        'label'              => 'Fields',
                        'cascade_validation' => true,
                        'by_reference'       => false,
                        'required'           => false,
                        'attr'               => array(
                            'class' => 'form-control'
                        )
                    ), array(
                        'edit'         => 'inline',
                        'inline'       => 'table',
                        'sortable'     => 'position',
                        'admin_code'   => 'sip.content.pollhasfield.admin',
                    )
                )
            ->end()

        ;
    }

PollHasFieldAdmin class:

protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->with('General')
             ->add('field', 'sonata_type_collection', array(
                    'label'              => 'Options',
                    'cascade_validation' => true,
                    'by_reference'       => false,
                    'required'           => false,
                    'attr'               => array(
                        'class' => 'form-control'
                    )
                ), array(
                    'edit'         => 'inline',
                    'inline'       => 'table',
                    'sortable'     => 'position',
                    'admin_code'   => 'sip.content.field.admin',
                )
            )
            ->add('position', 'hidden',
                array(
                    'label' => 'sip_position',
                )
            )
            ->end();
    }

FieldAdmin class

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ->with('General')
        ->add('title', null, array('label' => 'sip.customer.title'))
        ->add('type', 'choice', array('label' => 'Type', 'choices' => Field::getTypes()))

        ->add('options', 'sonata_type_collection', array(
                'label'              => 'Options',
                'cascade_validation' => true,
                'by_reference'       => false,
                'required'           => false,
                'attr'               => array(
                    'class' => 'form-control'
                )
            ), array(
                'edit'         => 'inline',
                'inline'       => 'table',
                'sortable'     => 'position',
                'admin_code'   => 'sip.content.option.admin',
            )
        )
        ->end()
    ;
}

OptionAdmin class:

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ->with('General')
            ->add('title', null, array('label' => 'sip.customer.title'))
            ->add('position', null, array('label' => 'sip_position'))
        ->end()
    ; 
}

What am I doing wrong?

Fixed it with replacement ManyToMany relationship for OneToMany in Poll class. So the PollHasField\PollHasFieldAdmin classes are not needed anymore.

PollAdmin class:

protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->with('General')
                ->add('title', null, array('label' => 'sip.customer.title'))
                ->add('active', null, array('label' => 'Active'))
                ->add('howOftenToShow', null, array('label' => 'Frequency'))

                ->add('fields', 'sonata_type_collection', array(
                        'label'              => 'Fields',
                        'cascade_validation' => true,
                        'by_reference'       => false,
                        'required'           => false,
                        'attr'               => array(
                            'class' => 'form-control'
                        )
                    ), array(
                        'edit'         => 'inline',
                        'inline'       => 'table',
                        'admin_code'   => 'sip.content.field.admin',
                    )
                )
            ->end()
        ;
    }

Additionally, because project uses SonataAdminBundle 2.4 i had to add support of nested (> 2nd level) sonata_type_collection in Sonata\AdminBundle\Admin\AdminHelper class from this pull request https://github.com/sonata-project/SonataAdminBundle/pull/3553

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM