5
votes

I'm trying to set up an Admin as a child of an other Admin in Sonata Admin Bundle.

I have 2 Admin classes:

  • CategoryAdmin
    This class contains the following method

    protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null)
    {            
         $id = $this->getRequest()->get('id');
    
         $menu->addChild(
             $this->trans('Projects'),
             array('uri' => $this->getChild('sonata.admin.project')->generateUrl('list', array('id' => $id)))
         );
    }
    
  • ProjectAdmin
    This class contains protected $parentAssociationMapping = 'category';
    category is the property in the model class representing the ManyToOne association.

I added the following lines to my service configuration for CategoryAdmin

calls:
    - [ addChild, ["@sonata.admin.project"]]

The routes for the child Admin are not being generated with this configuration. The link in the SideMenu (top menu) points to /admin/project/list?childId=1&id=1

Here is the output of the children of CategoryAdmin with dump()

array:1 [▼
    "sonata.admin.project" => ProjectAdmin {#406 ▶}
]

This means that the configuration for my child admin seems to be correct. I have no idea, why the routes for the child admin are not being generated.

I hope somebody can give me a hint, what the problem could be.

3

3 Answers

2
votes

Note for next gen sonata coders: If your route is not being generated, first check you didn't do:

protected function configureRoutes(RouteCollection $collection)
{
    //clear all routes except given !!!
    $collection->clearExcept(array('list', 'show'));
}

It costs me two days...

0
votes

Do you have the $baseRouteName and $baseRoutePattern overriden in your admin class ?

If you do, Sonata will generate both child and parent routes with the same name resulting in the parent routes overriding the child ones.

0
votes

I bumped into this issue while solving the problem for myself and decided to share the solution, which costed me several debugging hours...

The only way to generate a proper uri in this case is to use low-level routeGenerator which doesn't make any sonata suggestions, made inside generateMenuUrl method.

First you have to debug the routes, you have in your app (including autogenerated by sonata).

php bin/console debug:router

For example I have 3 nesting levels

hall -> seats scheme -> sector

And my routes are following:

  adminHall_list                             ANY      ANY      ANY    /admin/hall/list
  adminHall_create                           ANY      ANY      ANY    /admin/hall/create
  adminHall_edit                             ANY      ANY      ANY    /admin/hall/{id}/edit
  adminHall_delete                           ANY      ANY      ANY    /admin/hall/{id}/delete
  adminHall_adminScheme_list                 ANY      ANY      ANY    /admin/hall/{id}/scheme/list
  adminHall_adminScheme_create               ANY      ANY      ANY    /admin/hall/{id}/scheme/create
  adminHall_adminScheme_edit                 ANY      ANY      ANY    /admin/hall/{id}/scheme/{childId}/edit
  adminHall_adminScheme_delete               ANY      ANY      ANY    /admin/hall/{id}/scheme/{childId}/delete
  adminHall_adminScheme_adminSector_list     ANY      ANY      ANY    /admin/hall/{id}/scheme/{childId}/sector/list
  adminHall_adminScheme_adminSector_create   ANY      ANY      ANY    /admin/hall/{id}/scheme/{childId}/sector/create
  adminHall_adminScheme_adminSector_edit     ANY      ANY      ANY    /admin/hall/{id}/scheme/{childId}/sector/{childChildId}/edit
  adminHall_adminScheme_adminSector_delete   ANY      ANY      ANY    /admin/hall/{id}/scheme/{childId}/sector/{childChildId}/delete

In admin classes baseRouteName and baseRoutePattern has been overridden.

// HallSchemeAdmin.php
$this->baseRouteName = 'adminScheme';
$this->baseRoutePattern = 'scheme';

To generate a most deep listing url:

$url = $admin->getRouteGenerator()->generate('adminHall_adminScheme_adminSector_list', [
    'id' => $admin->getRequest()->get('id'),
    'childId' => 555, // put required id
]);

It will produce the url like this:

/admin/hall/495/scheme/555/sector/list

If you need edit url, you have to provide childChildId param too:

$url = $admin->getRouteGenerator()->generate('adminHall_adminScheme_adminSector_edit', [
    'id' => $admin->getRequest()->get('id'),
    'childId' => 555, 
    'childChildId' => 12345 
]);

The result is: /admin/hall/495/scheme/555/sector/12345/edit