首页 > 解决方案 > Sonata Admin - CollectionType 和动态添加抽象类

问题描述

我在一个 Symfony 3.4 项目上工作,我对特定的 Sonata Admin 案例有疑问,这是我的情况:

我有一个具有元素的课程实体:

/**
 * @ORM\OneToMany(targetEntity="App\Entity\Lessons\ElementLesson", mappedBy="lesson", cascade={"persist"})
 */
protected $elements;

Elements 是具有继承的抽象类

/**
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({
 *     "element_lesson" = "ElementLesson",
 *     "popup_element_lesson" = "PopupElementLesson",
 *     "advice_element_lesson" = "AdviceElementLesson",
 *     "accordion_element_lesson" = "AccordionElementLesson",
 *     "title_element_lesson" = "TitleElementLesson",
 *     "text_element_lesson" = "TextElementLesson",
 *     "separator_element_lesson" = "SeparatorElementLesson"
 * })
 */
abstract class ElementLesson
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Lessons\Lesson", inversedBy="elements")
     * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
     */
    protected $lesson;

所以我想在我的奏鸣曲管理员中,创建一个课程并向她添加一些元素,为此我处理如下:

我定义了这两个服务:

app.admin.lesson.all:
    class: App\Admin\Lessons\LessonAdmin
    arguments: [~, App\Entity\Lessons\Lesson, ~]
    tags:
        - { name: sonata.admin, manager_type: orm, label: Cours }
    public: true

app.admin.lesson.element:
    class: App\Admin\Lessons\ElementLessonAdmin
    arguments: [~, App\Entity\Lessons\ElementLesson, ~]
    tags:
        - { name: sonata.admin, manager_type: orm, group: lesson, label: Element  }
    calls:
        - [setSubclasses, [{'TitleElementLesson': App\Entity\Lessons\TitleElementLesson, 'TextElementLesson': App\Entity\Lessons\TextElementLesson}]]
    public: true

并创建一个 ElementLessonAdmin :

class ElementLessonAdmin extends AbstractAdmin
{

protected function configureFormFields(FormMapper $form)
{
    $subject = $this->getSubject();

    if ($subject instanceof TitleElementLesson) {
        $form->add('title');
    }

    if ($subject instanceof TextElementLesson) {
        $form->add('text');
    }
}

和课程管理员:

class LessonAdmin extends AbstractAdmin
{

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper

        ->with('Contenu', ['class' => 'col-md-9'])

        ->add('elements', CollectionType::class, array(
            'btn_add' => 'New Element',
            'type_options' => array(
                // Prevents the "Delete" option from being displayed
                'delete' => false,
                'delete_options' => array(
                    // You may otherwise choose to put the field but hide it
                    'type'         => 'hidden',
                    // In that case, you need to fill in the options as well
                    'type_options' => array(
                        'mapped'   => false,
                        'required' => false,
                    )
                )
            )
        ), array(
            'edit' => 'standard',
            'inline' => 'natural',
            'sortable' => 'position'
        ))
        ->end()
        ;
    }

    public function toString($lesson)
    {
        return $lesson instanceof Lesson
            ? $lesson->getTitle()
            : 'Cours'; // shown in the breadcrumb on the create view
    }

    public function prePersist($lesson)
    {
        foreach ($lesson->getElements() as $element) {
            $element->setLesson($lesson);
        }
    }

    public function preUpdate($lesson)
    {
        foreach ($lesson->getElements() as $element) {
            $element->setLesson($lesson);
        }
    }
}

结果看起来像我想要的:

结果 1

结果 2

结果 3

但我在 2 个实体之间没有任何联系:

错误 1

错误 2

我不确定我想要什么,或者我是否需要用其他方法来做到这一点。

谢谢

标签: symfonyabstract-classsonata-adminsonata

解决方案


推荐阅读