В Sonata Admin, как получить несопоставленное поле в sonata_type_collection Embedded Admins

Я использую Sonata Admin с Symfony 2.8.9.

Две сущности: Skill и SkillStep. Навыки имеют отношения «один ко многим» с SkillSteps.

У администратора Skill есть поле sonata_type_collection, которое включает несколько администраторов SkillStep.

У каждого администратора SkillStep есть несопоставленное текстовое поле под названием «данные». Он не сопоставляется напрямую ни с каким значением в сущности SkillStep.

Когда пользователь сохраняет или обновляет навык, я хочу запустить произвольный код на основе ввода в поле «данные» каждого администратора SkillStep в sonata_type_collection.

Очевидным местом для этого будут prePersist() и preUpdate() в админке SkillStep. Однако,

При встраивании одного администратора в другого, например, с использованием типа поля sonata_type_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
    }

}

person amacrobert    schedule 21.09.2016    source источник
comment
Если вы не можете обновить дочернюю сущность с помощью прослушивателей preUpdate и prePersist SonataAdmin, возможно, вы можете сделать это с помощью событий Doctrine prePersist и preUpdate? symfony.com/doc/current/doctrine/. Или, может быть, вы можете сделать это в методах prePersist и preUpdate SkillAdmin?   -  person Stephan Yamilov    schedule 22.09.2016


Ответы (1)


Вам нужно управлять этим вручную. Ознакомьтесь с этим пример в официальной документации и запись связанной проблемы

Что касается вашего примера, вы можете сделать что-то вроде этого (замените skill_step_admin_service_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); 
    }
}
person lordrhodos    schedule 22.09.2016
comment
Спасибо за ответ. Это работает для вызова хуков встроенных администраторов. Однако ввод несопоставленного поля неизвестен администратору при таком вызове. Я попробовал $this->getForm()->get('data')->getData(); в хуках SkillStepAdmin, но это дает мне NULL, даже если в поле данных введен текст. - person amacrobert; 23.09.2016