我正在尝试获取和操纵与SonataAdmin中的ImageAdmin类相关的实际对象(使用Symfony 2.3)。当ImageAdmin类是唯一使用的类时,这可以很好地工作。但是,当ImageAdmin嵌入另一个Admin中时,它会发生严重错误。

当您没有嵌入式管理员时,这是可行的方法:

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

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

但是,当您使用以下方法将ImageAdmin嵌入ParentAdmin时:
class PageAdmin extends Admin {
    protected function configureFormFields(FormMapper $formMapper) {
        $formMapper->add('image1', 'sonata_type_admin');
    }
}

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

换句话说,getSubject()从URL中提取ID,然后调用$this->getModelManager()->find($this->getClass(), $id);,该ID交叉引用了Parent ID和Image ID。糟糕!

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

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

无论如何,我希望可以以一种我已经忽略的明显方式来掌握该物体,并且这里的人可以帮助启发我!

最佳答案

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

在ImageAdmin中设置以下内容:

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)
    ;
}

我将很快将其发​​布在即将发行的SonataAdmin食谱中!

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

10-01 05:42