Sonata admin - child admin class

I have an Order object that can have several related LineItem objects.

I created the Admin class for Order and the Admin class for LineItem. But I need the AdminItem Admin class to be a child of the order admin class.

In the LineItemAdmin class, I set protected $parentAssociationMapping = 'order'; .

In addition, in the OrderAdmin method of configureFormFields I added ->add('lineItems', 'sonata_type_model') .

However, it still does not work. The list of positions on the order form is not accessible for clicks, so I don’t see how to get from the order administrator form to say the page of the LineItem administrators list.

Are there any routes that need to be configured? Are there any changes to the lineItems form field that I need to make?

It was very difficult to find any good documentation on the Sonata Admin package, so any help would be appreciated.

PS. Even if you go through the SonataAdminBundle code, this does not help, since it is very difficult to execute the code because of its complexity.

+7
source share
2 answers

After going through only the same problems with undocumented functions, the only steps you skipped call addChild and configureSideMenu in the parent class OrderAdmin.

This solution will create a separate page with sidemenu that will contain lineItems, they will not be embedded in the OrderAdmin form (I'm not sure if this is possible).

There are no routes to configure as SonataAdmin handles this for you.

Here is an example parent admin class using annotations:

 namespace YourVendor\YourBundle\Admin; use JMS\DiExtraBundle\Annotation\Service; use JMS\DiExtraBundle\Annotation\Tag; use JMS\DiExtraBundle\Annotation\Inject; use JMS\DiExtraBundle\Annotation\InjectParams; use Knp\Menu\ItemInterface as MenuItemInterface; use Sonata\AdminBundle\Admin\Admin; use Sonata\AdminBundle\Admin\AdminInterface; /** * @Service("sonata.admin.order") * @Tag("sonata.admin", attributes={"manager_type"="orm", "group"="Orders", "label"="Orders"}) */ class OrderAdmin extends Admin { /** * @InjectParams({ * "code" = @Inject("%your.parameters.code%"), * "class" = @Inject("%your.parameters.class%"), * "baseControllerName" = @Inject("%your.parameters.controller%"), * "lineItems" = @Inject("sonata.admin.line_item") * }) */ public function __construct($code, $class, $baseControllerName, $lineItems) { parent::__construct($code, $class, $baseControllerName); $this->addChild($lineItems); } protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null) { if (!$childAdmin && !in_array($action, array('edit', 'show'))) { return; } $admin = $this->isChild() ? $this->getParent() : $this; $id = $admin->getRequest()->get('id'); $menu->addChild('Show Order', array('uri' => $admin->generateUrl('show', array('id' => $id)))); $menu->addChild('Edit Order', array('uri' => $admin->generateUrl('edit', array('id' => $id)))); $menu->addChild('Line items', array('uri' => $admin->generateUrl('sonata.admin.line_item.list', array('id' => $id)))); } } 

If you use XML or YML for your services, you probably will not need the __construct method, as addChild calls can go into the service definition.

At the time of writing, there is an open problem with the JMS DiExtra Bundle with a pull request for the selected @Admin annotation, which can also avoid this requirement. It was quiet for a couple of weeks.

+4
source

You can:

 // Order Entity /** * @ORM\OneToMany(targetEntity="OrderItem", mappedBy="invoice", cascade={"persist", "remove"}, orphanRemoval=true) * */ protected $items; ... // OrderAdmin.php protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('Order Items') ->add('items', 'sonata_type_collection', array('required' => true, 'by_reference' => false, ), array('edit' => 'inline', 'inline' => 'table',)) .... 

Make sure you also have an OrderItem administrator. What is needed due to sonata_type_collection needs an admin class to work.

This solution is great for my invoice package with many invoice items.

+1
source

All Articles