我正在尝试获取和操纵与SonataAdmin中的ImageAdmin类相关的实际对象(使用Symfony 2.3)。当ImageAdmin类是唯一使用的类时,这很好。但是当ImageAdmin嵌入另一个管理员时,它会出现严重错误。
以下是没有嵌入式管理员时的作用:
class ImageAdmin extends Admin {
protected $baseRoutePattern = 'image';
protected function configureFormFields(FormMapper $formMapper) {
$subject = $this->getSubject();
}
}
但是当您使用以下方法在ParentAdmin中嵌入ImageAdmin时:
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);
,它交叉引用Parent id和Image id。糟糕!
所以...我想要做的是能够掌握当前ImageAdmin实例中正在渲染/编辑的实际对象,无论是直接编辑还是通过嵌入的表单编辑,然后能够用它做事。
也许getSubject()是一个错误的树,但是我注意到{Image:}在从ImageAdmin :: configureFormFields()调用时返回false,即使使用sonata_type_admin字段类型嵌入了ImageAdmin也是如此。我很困惑......
无论如何,我希望有可能以一种我忽略的显而易见的方式抓住这个对象,这里有人可以帮助启发我!
答案 0 :(得分:13)
感谢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
答案 1 :(得分:2)
caponica的解决方案只适用于oneOoOne关系,对吗?在我的oneToMany案例中,这个:$ parent-&gt; $ getter()返回一个集合,我不知道如何识别当前主题。 我发现了这个错误报告: https://github.com/sonata-project/SonataAdminBundle/issues/1568,其中包含一个修复程序,但它仍处于打开状态,所以我希望它们很快合并:(
修改强>
通过一些研究,可以暂时解决这个问题:Fixed getting wrong subject in sonata_type_collection
简而言之:
创建一个类并复制此文件的内容:AdminType 然后将其添加到services.yml中,并将类命名空间更改为新的类命名空间:
services:
sonata.admin.form.type.admin:
class: ACME\AdminBundle\Form\Type\AdminType
tags:
- { name: form.type, alias: sonata_type_admin }
但它仍有一个错误:
在父文档和嵌入表单中启用cascade_validation时出错也无法解决
答案 2 :(得分:0)
您可以在ImageAdmin中试用$this->getForm()->getViewData();
吗?这应该会为您提供正确的子实体。
答案 3 :(得分:0)
我尝试了所有这些解决方案,但没有一个证明有效
所以,我努力寻找解决方案。我的解决方案基于caponica的解决方案,但是在oneToMany案例上工作。我找到的解决方案是一种解决方法,但效果很好
它正在使用会话。
public function getCurrentObjectFromCollection($adminChild)
{
$getter = 'get' . $adminChild->getParentFieldDescription()
->getFieldName();
$parent = $adminChild->getParentFieldDescription()
->getAdmin()
->getSubject();
$collection = $parent->$getter();
$session = $adminChild->getRequest()->getSession();
$number = 0;
if ($session->get('adminCollection')) {
$number = $session->get('adminCollection');
$session->remove('adminCollection');
}
else {
$session->set('adminCollection', 1 - $number);
}
return $collection[$number];
}
您可以通过以下方式获取管理员中的正确对象:
$object = $this->getCurrentObjectFromCollection($this)
因此,当父母需要显示子管理员列表时,每个子管理员都将运行此功能并更新会话参数。取出所有元素后,会删除会话参数
此代码仅适用于包含2个元素的列表,但可以针对任意数量的元素进行更新。
希望这有助于某人:)
答案 4 :(得分:0)
我有同样的问题,我可以通过&#34;自定义表格类型扩展&#34;在链接上提供了哪些文档&#34; http://symfony.com/doc/current/cookbook/form/create_form_type_extension.html&#34;
这是完美的解决方案..