Sonataadminbundle:同一实体的多个管理部分

24

我有一个实体类 Page,其中包含列 type=integer。 当我执行以下操作时:

   <service id="sonata.admin.pages" class="Main\ProgramBundle\Admin\PageAdmin">
      <tag name="sonata.admin" manager_type="orm" group="dashboard" label="Pages"/>
      <argument />
      <argument>Main\ProgramBundle\Entity\Page</argument>
      <argument>SonataAdminBundle:CRUD</argument>
  </service>


   <service id="sonata.admin.groups" class="Main\ProgramBundle\Admin\GroupAdmin">
      <tag name="sonata.admin" manager_type="orm" group="stories" label="Groups"/>
      <argument />
      <argument>Main\ProgramBundle\Entity\Page</argument>
      <argument>SonataAdminBundle:CRUD</argument>
  </service>

简而言之,两个部分都在同一个实体上工作,只是它们有不同的查询和表单。

但问题是,即使我选择了PageAdmin,Sonata仍然会执行Admin/GroupAdmin。如何解决这个问题?

4个回答

42

我没有足够的声望在之前的答案中添加评论,但是以下信息缺失:

除了在您的管理类中定义 $baseRoutePattern 之外,您还需要定义一个唯一的 $baseRouteName 值:

protected $baseRouteName = 'admin_vendor_bundlename_adminclassname';

protected $baseRoutePattern = 'unique-route-pattern';

你只需要对其中一个类执行此操作,但考虑对两个类执行此操作,以使情况更加清晰明了。


4
当您将此实体添加到另一个管理员时,仍会遇到问题。Sonata会触发错误,告诉您已注册了太多管理员。通过添加'admin_code' => 'sonata.product.admin.product'到add函数中来解决此问题。这将告诉Sonata使用特定的管理员。 - 11mb
1
谢谢!@11mb 我在一个展示中遇到了问题,只需添加->add('someProperty',null, array('admin_code' => 'some.service.admin,id'))即可解决。 - Cassiano

5

Sonata根据您的实体名称自动创建路由。因此,如果您有2个管理类,则会出现冲突。您需要配置不同的路由模式。

将此属性添加到Main\ProgramBundle\Admin\GroupAdmin.php中:

protected $baseRouteName = 'page_group';
protected $baseRoutePattern = 'page-group';

1
我已经尝试过了,现在两个URL都是admin/page-group/list,即使我在PageAdmin和GroupAdmin中分别放置了这些属性(当然是不同的)。 - Zeljko
不要将该属性放到两个类中。 你应该只将此属性放到其中一个管理员类中。如果你把它放在两个类中,你会遇到与之前同样的冲突情况。 - pulzarraider
3
我尝试的第一件事情就是按照你说的做法,把属性只放在一个管理类中。那并没有起作用,只有在那之后我才试了这两种情况。 - Zeljko
为了正常工作,还需要$baseRouteName的保护。 - Srdjan

1
我不知道2012年的情况如何,但在2022年,所有信息都在官方文档的Routing页面中。
可以在每个管理页面中覆盖generateBaseRouteNamegenerateBaseRoutePattern方法,以控制路由的名称(例如用于<a href="{{ path('admin_app_post_list') }}">文章列表</a>)和URL。
// src/Admin/PostAdmin.php
final class PostAdmin extends AbstractAdmin
{
    protected function generateBaseRouteName(bool $isChildAdmin = false): string
    {
        return 'sonata_post';
        // will result in routes named:
        //   sonata_post_list
        //   sonata_post_create
        //   etc
    }

    protected function generateBaseRoutePattern(bool $isChildAdmin = false): string
    {
        return 'Post';
    }
}
Barry的回答似乎仍然有效,但可能会产生不必要的副作用,我不确定。

0
你肯定找到了解决办法,但另一种方法是创建一个父类并使用inheritance mapping进行继承。这样,你就可以拥有不同的仓库,并且Sonata Admin也不会有任何不同之处。

我首先尝试使用一个扩展原始实体的实体 - 但是当你尝试创建两个相同的表时, console doctrine:schema:update 会失败 - 或者更糟糕的是,你最终会在数据库中得到两个表。 - Alister Bulman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接