在Sonata Admin中,如何在sonata_type_collection嵌入式管理员中获取未映射的字段

时间:2016-09-21 17:38:57

标签: php symfony sonata-admin symfony-sonata sonata

我正在使用Sonata Admin和Symfony 2.8.9。

两个实体:Skill和SkillStep。技能与SkillSteps有一对多的关系。

技能管理员有一个sonata_type_collection字段,它嵌入了多个SkillStep管理员。

每个SkillStep管理员都有一个名为“data”的未映射文本字段。它不直接映射到SkillStep实体中的任何值。

当用户保存或更新技能时,我想根据sonata_type_collection中每个SkillStep管理员的“数据”字段的输入运行任意代码。

在SkillStep管理员中,显而易见的地方是prePersist()preUpdate()。然而,

  

将一个管理员嵌入另一个管理员时,例如使用   <{1}}字段类型,子管理员的挂钩不会被触发。

如何在保存顶级实体时使用与sonata_type_collection一起嵌入的管理员的未映射字段?这些未映射的字段与他们所在的管理员对象相关联非常重要

相关代码:

sonata_type_admin
# Entity/Skill.php

class Skill {
    /**
     * @ORM\OneToMany(targetEntity="SkillStep", mappedBy="skill")
     */
    private $steps;

    // ...
}
# Entity/SkillStep.php

class SkillStep {
    /**
     * @ORM\ManyToOne(targetEntity="Skill")
     * @ORM\JoinColumn(name="skill_id", referencedColumnName="id")
     **/
    protected $skill;

    // ..
}
# Admin/SkillAdmin.php

class SkillAdmin extends Admin 
{
    // Fields to be shown on create/edit forms
    protected function configureFormFields(FormMapper $formMapper) {
        $formMapper
            ->add('name')
            ->add('steps', 'sonata_type_collection',
                ['required' => false, 'label' => 'Manage the skill steps'],
                ['edit'=>'inline','inline'=>'standard']
            )
        ;
    }
}

1 个答案:

答案 0 :(得分:2)

您需要手动管理。查看this example in the official documentationthe related issue entry

关于您的示例,您可以执行以下操作(将skill_step_admin_service_id替换为您的服务ID以使其正常工作):

# Admin/SkillAdmin.php    
private function getStepAdmin() {
    return $this->getConfigurationPool()
                ->getAdminByAdminCode('skill_step_admin_service_id');
}

public function prePersist($skill)
{
    foreach ($skill->getSteps() as $step) {
        $this->getStepAdmin->prePersist($step); 
    }
}

public function preUpdate($skill)
{
    foreach ($skill->getSteps() as $step) {
        $this->getStepAdmin->preUpdate($step); 
    }
}