Skip to content

Instantly share code, notes, and snippets.

@fullpipe
Last active November 8, 2018 13:55
Show Gist options
  • Save fullpipe/d11f1ca1538e4b220ea6 to your computer and use it in GitHub Desktop.
Save fullpipe/d11f1ca1538e4b220ea6 to your computer and use it in GitHub Desktop.
sonata admin child admin

from smlr

First, create your AAdmin, ABAdmin and BAdmin Classes like you would, if those Classes wouldn't share any relation. After this, add to your sonata.admin.A service a Child sonata.admin.AB (Admin.yml or Admin.xml).

Than you can use the configureSideMenu() method in AAdmin to create a sidemenu and generate a link to ABAdmin.

It's important to add $parentAssociationMapping to your ABAdmin Class and adding some if-statements to improve the usability, if list and form is in a A-context.

If you know the mechanism, it's quite easy. Hope my example works for you..

#   Admin.yml
#   Add a Child in the Service of A

services:
    sonata.admin.A:
        class: Path\toBundle\Admin\AAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: YourGroup, label: "label.A" }
        arguments:
            - ~
            - Path\toBundle\Entity\A
            - 'SonataAdminBundle:CRUD'
        calls:
            - [ setTranslationDomain, [toBundle]]
            - [ addChild, [@sonata.admin.AB]]
class AAdmin extends Admin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->with('General')
                ->add('name')
                ->add('data')
                /* No add('AB') here.. as you see in my screenshot, I added it inline before. */
            ->end()
         ;
    }

    // ...
    
    protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null)
    {
        if (!$childAdmin && !in_array($action, array('edit'))) {
            return;
        }

        $admin = $this->isChild() ? $this->getParent() : $this;

        $id = $admin->getRequest()->get('id');

        $menu->addChild(
            $this->trans('admin.sidemenu.link_view_A'),
            array('uri' => $admin->generateUrl('edit', array('id' => $id)))
        );

        $menu->addChild(
            $this->trans('admin.sidemenu.link_view_AB'),
            array('uri' => $admin->generateUrl('sonata.admin.AB.list', array('id' => $id)))
        );   
    } 
}
class ABAdmin extends Admin
{
    protected $parentAssociationMapping = 'A'; // This does the trick..
    
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('B')
            ->add('AB_Data')
        ;
        
        if (!$this->isChild()) 
            $formMapper->add('A'); // Just add the A dropdown, if you are NOT in A-context
    }

    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('AB_Data')
            ->add('B')
        ;
    }

    protected function configureListFields(ListMapper $listMapper)
    {
        if (!$this->isChild())
            $listMapper->addIdentifier('id')->addIdentifier('A');
            
        $listMapper
            ->addIdentifier('B')
            ->addIdentifier('AB_Data');
    }
}

The relations in the AB Entity are defined as the following (I added a surrogate key Id)

class AB
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
    protected $id;
    
/**
* @ORM\ManyToOne(targetEntity="B", inversedBy="ABs")
* @ORM\JoinColumn(name="B_id", referencedColumnName="id", nullable=false)
*/
    protected $B;
    
/**
* @ORM\ManyToOne(targetEntity="A", inversedBy="As")
* @ORM\JoinColumn(name="A_id", referencedColumnName="id", nullable=false)
*/
    protected $A;

/**
* @ORM\Column(type="string", length=10, nullable=true)
*/
    protected $AB_Data;
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment