如何在 Sonata Admin 的嵌入式 Admin 类中获取子对象? [英] How to get child object in embedded Admin class in Sonata Admin?

查看:27
本文介绍了如何在 Sonata Admin 的嵌入式 Admin 类中获取子对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取和操作与 SonataAdmin 中的 ImageAdmin 类相关的实际对象(使用 Symfony 2.3).当 ImageAdmin 类是唯一使用的类时,这可以正常工作.但是当 ImageAdmin 嵌入到另一个 Admin 中时,它会出错.

当您没有嵌入式管理员时,以下是有效的:

class ImageAdmin 扩展了 Admin {受保护的 $baseRoutePattern = '图像';受保护的函数 configureFormFields(FormMapper $formMapper) {$subject = $this->getSubject();}}

但是当你使用这个在 ParentAdmin 中嵌入 ImageAdmin 时:

class PageAdmin 扩展了 Admin {受保护的函数 configureFormFields(FormMapper $formMapper) {$formMapper->add('image1', 'sonata_type_admin');}}

然后,当您编辑 ID 为 10 的父项并在 ImageAdmin 中调用 getSubject() 时,您将获得 ID 为 10 的 Image

换句话说,getSubject() 从 URL 中提取 id 然后调用 $this->getModelManager()->find($this->getClass(), $id);,它交叉引用父 ID 和图像 ID.糟糕!

<小时>

所以...我想要做的是能够掌握在当前 ImageAdmin 实例中正在渲染/编辑的实际对象,无论它是直接编辑还是通过嵌入表单进行编辑,然后能够用它做事.

也许 getSubject() 是错误的树,但我注意到 $this->getCurrentChild() 在从 ImageAdmin::configureFormFields() 调用时返回 false,即使ImageAdmin 使用 sonata_type_admin 字段类型嵌入.我很困惑...

无论如何,我希望有可能以某种我忽略的明显方式获得该对象,并且这里有人可以帮助启发我!

解决方案

感谢 Tautrimas 的一些想法,但我设法找到了答案:

在 ImageAdmin 中设置:

受保护的函数 configureFormFields(FormMapper $formMapper){if($this->hasParentFieldDescription()) {//这个 Admin 是嵌入的$getter = 'get' .$this->getParentFieldDescription()->getFieldName();$parent = $this->getParentFieldDescription()->getAdmin()->getSubject();如果($父母){$image = $parent->$getter();} 别的 {$图像=空;}} else {//此管理员未嵌入$image = $this->getSubject();}//然后你可以用 $image 做一些事情,比如在帮助中显示缩略图:$fileFieldOptions = array('required' => false);if ($image && ($webPath = $image->getWebPath())) {$fileFieldOptions['help'] = '<img src="'.$webPath.'" class="admin-preview"/>';}$formMapper->add('file', 'file', $fileFieldOptions);}

我很快会在即将出版的 SonataAdmin 食谱中发布此内容!

https://github.com/sonata-project/SonataAdminBundle/issues/1546

I'm trying to get and manipulate the actual object related to a ImageAdmin class in SonataAdmin (using Symfony 2.3). This works fine when the ImageAdmin class is the only one being used. But when ImageAdmin is embedded in another Admin it goes horribly wrong.

Here's what works when you don't have embedded Admins:

class ImageAdmin extends Admin {
    protected $baseRoutePattern = 'image';

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

But when you embed ImageAdmin in ParentAdmin using this:

class PageAdmin extends Admin {
    protected function configureFormFields(FormMapper $formMapper) {
        $formMapper->add('image1', 'sonata_type_admin');
    }
}

Then when you're editing a Parent item with id 10 and call getSubject() in ImageAdmin you get the Image with id 10!

In other words getSubject() extracts the id from the URL then calls $this->getModelManager()->find($this->getClass(), $id);, which cross-references the Parent id and the Image id. Oops!


So... what I want to do is be able to get hold of the actual object that is being rendered/edited in the current ImageAdmin instance, whether it's being edited directly or via an embedded form, and then be able to do things with it.

Maybe getSubject() is the wrong tree to be barking up, but I note that $this->getCurrentChild() returns false when called from ImageAdmin::configureFormFields(), even when that ImageAdmin is embedded using the sonata_type_admin field type. I'm quite confused...

Anyway, I hope it is possible to get hold of the object in some obvious way that I've overlooked and somebody here can help enlighten me!

解决方案

Thanks to Tautrimas for some ideas, but I managed to figure out an answer to this:

In ImageAdmin set this:

protected function configureFormFields(FormMapper $formMapper)
{
    if($this->hasParentFieldDescription()) { // this Admin is embedded
        $getter = 'get' . $this->getParentFieldDescription()->getFieldName();
        $parent = $this->getParentFieldDescription()->getAdmin()->getSubject();
        if ($parent) {
          $image = $parent->$getter();
        } else {
          $image = null;
        }
    } else { // this Admin is not embedded
        $image = $this->getSubject();
    }

    // You can then do things with the $image, like show a thumbnail in the help:
    $fileFieldOptions = array('required' => false);
    if ($image && ($webPath = $image->getWebPath())) {
        $fileFieldOptions['help'] = '<img src="'.$webPath.'" class="admin-preview" />';
    }

    $formMapper
        ->add('file', 'file', $fileFieldOptions)
    ;
}

I'll post this in the upcoming SonataAdmin cookbook soon!

https://github.com/sonata-project/SonataAdminBundle/issues/1546

这篇关于如何在 Sonata Admin 的嵌入式 Admin 类中获取子对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆