【发布时间】:2016-09-21 17:38:57
【问题描述】:
我在 Symfony 2.8.9 中使用 Sonata Admin。
两个实体:Skill 和 SkillStep。技能与 SkillSteps 是一对多的关系。
Skill 管理员有一个 sonata_type_collection 字段,其中嵌入了多个 SkillStep 管理员。
每个 SkillStep 管理员都有一个未映射的文本字段,称为“数据”。它不直接映射到 SkillStep 实体中的任何值。
当用户保存或更新技能时,我想根据 sonata_type_collection 中每个 SkillStep 管理员的“数据”字段的输入运行任意代码。
执行此操作的明显位置是 SkillStep 管理员中的 prePersist() 和 preUpdate()。然而,
将一个管理员嵌入另一个管理员时,例如使用
sonata_type_admin字段类型,子 Admin 的钩子不会被触发。
如何在保存顶级实体时使用嵌入了 sonata_type_collection 的管理员的未映射字段?这些未映射字段与他们所在的管理员对象相关联很重要.
相关代码:
# 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']
)
;
}
}
# Admin/SkillStepAdmin.php
class SkillStepAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper) {
$formMapper
->add('name')
->add('route')
->add('data', 'textarea', [
'mapped' => false,
'data' => $step_data,
])
;
}
// Before a new skill step is saved
public function prePersist($skill_step) {
// THIS IS NEVER CALLED BECAUSE THIS ADMIN IS EMBEDDED
}
// Before an existing skill step is updated
public function preUpdate($skill_step) {
// THIS IS NEVER CALLED BECAUSE THIS ADMIN IS EMBEDDED
}
}
【问题讨论】:
-
如果你不能通过 SonataAdmin preUpdate 和 prePersist 监听器更新子实体,也许你可以通过 Doctrine prePersist 和 preUpdate 事件来做到这一点? symfony.com/doc/current/doctrine/…。或者你可以在 SkillAdmin prePersist 和 preUpdate 方法中做到这一点?
标签: php symfony sonata-admin symfony-sonata sonata