【问题标题】:In Sonata Admin, How To Get Unmapped Field in sonata_type_collection Embedded Admins在 Sonata Admin 中,如何在 sonata_type_collection 嵌入式管理员中获取未映射的字段
【发布时间】: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


【解决方案1】:

您需要手动管理。查看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); 
    }
}

【讨论】:

  • 感谢您的回复。这确实适用于调用嵌入式管理员的钩子。但是,当以这种方式调用时,管理员不知道未映射字段的输入。我在 SkillStepAdmin 挂钩中尝试了$this->getForm()->get('data')->getData();,但这给了我 NULL,即使在数据字段中输入了文本。
猜你喜欢
  • 1970-01-01
  • 2015-01-09
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 2015-04-22
  • 2017-02-20
  • 2017-06-23
  • 2015-12-30
相关资源
最近更新 更多