2012-01-12 3 views
7

У меня есть объект Order, который может иметь несколько связанных объектов LineItem.Sonata admin - child admin class

Я создал класс администратора для Order и класс Admin для LineItem. Но мне нужно, чтобы класс AdminItem Admin был дочерним по классу Order Admin.

В классе LineItemAdmin я установил protected $parentAssociationMapping = 'order';.

Кроме того, в методе OrderAdmin configureFormFields я добавил ->add('lineItems', 'sonata_type_model').

Однако все еще не работает. Список позиций в форме заказа не доступен для кликов, поэтому я не вижу, как получить из формы администратора заказа, чтобы сказать страницу списка администрирования LineItem.

Есть ли маршруты, которые необходимо настроить? Есть ли изменения в поле формы lineItems, которое мне нужно сделать?

Было очень сложно найти какую-либо хорошую документацию по пакету администрирования Sonata, поэтому любая помощь будет оценена по достоинству.

PS. Даже переход через код SonataAdminBundle не помог, так как очень сложно выполнить код из-за его сложности.

ответ

4

Пройдя те же проблемы с недокументированными функциями, единственные шаги, которые вы пропустили, вызывают addChild и configureSideMenu в родительском классе OrderAdmin.

Это решение создаст отдельную страницу с sidemenu, которая будет содержать элементы lineItems, они не будут внедрены в форму OrderAdmin (я не уверен, что это возможно).

Нет никаких маршрутов, которые необходимо настроить, так как SonataAdmin обрабатывает это для вас.

Вот пример класса родительского администратора, с помощью аннотаций:

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

Если вы используете XML или YML для услуг, которые вы, вероятно, не будет нужен метод __construct как addChild вызовы могут перейти в определении сервиса.

На момент написания статьи есть an open issue с JMS DiExtra Bundle с запросом на растяжение для выделенной аннотации @Admin, которая также может избежать этого требования. Хотя было спокойнее на пару недель.

1

Вы можете на следующее:

// 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',)) 
.... 

Убедитесь, что у вас есть также OrderItem Admin. То, что необходимо из-за sonata_type_collection, нуждается в классе администратора для работы.

Это решение отлично подходит для моего счета-фактуры со многими счетами.