Explorar o código

Display sidebar menu as active on child admin routes. (#4546)

Every element of the sidebar menu is displayed as active when
the current route is a child admin of the menu element's admin.
Jules Lamur %!s(int64=7) %!d(string=hai) anos
pai
achega
39bdd5f69a

+ 15 - 5
Menu/Matcher/Voter/AdminVoter.php

@@ -46,19 +46,29 @@ class AdminVoter implements VoterInterface
     public function matchItem(ItemInterface $item)
     {
         $admin = $item->getExtra('admin');
-        $match = null;
+
         if ($admin instanceof AdminInterface
             && $admin->hasRoute('list') && $admin->hasAccess('list')
-            && $this->request && $this->request->get('_sonata_admin') == $admin->getCode()
+            && $this->request
         ) {
-            $match = true;
+            $requestCode = $this->request->get('_sonata_admin');
+
+            if ($admin->getCode() === $requestCode) {
+                return true;
+            }
+
+            foreach ($admin->getChildren() as $child) {
+                if ($child->getBaseCodeRoute() === $requestCode) {
+                    return true;
+                }
+            }
         }
 
         $route = $item->getExtra('route');
         if ($route && $this->request && $route == $this->request->get('_route')) {
-            $match = true;
+            return true;
         }
 
-        return $match;
+        return null;
     }
 }

+ 47 - 0
Tests/Menu/Matcher/Voter/AdminVoterTest.php

@@ -29,6 +29,8 @@ class AdminVoterTest extends AbstractVoterTest
             'no code request' => array($this->getAdmin('_sonata_admin', true, true), '_sonata_admin_unexpected', null, null),
             'no route' => array($this->getAdmin('_sonata_admin', false, true), '_sonata_admin', null, null),
             'has admin' => array($this->getAdmin('_sonata_admin', true, true), '_sonata_admin', null, true),
+            'has child admin' => array($this->getChildAdmin('_sonata_admin', '_sonata_child_admin', true, true), '_sonata_admin|_sonata_child_admin', null, true),
+            'has bad child admin' => array($this->getChildAdmin('_sonata_admin', '_sonata_child_admin', true, true), '_sonata_admin|_sonata_child_admin_unexpected', null, null),
             'direct link' => array('admin_post', null, 'admin_post', true),
             'no direct link' => array('admin_post', null, 'admin_blog', null),
         );
@@ -89,7 +91,52 @@ class AdminVoterTest extends AbstractVoterTest
             ->method('getCode')
             ->will($this->returnValue($code))
         ;
+        $admin
+            ->expects($this->any())
+            ->method('getChildren')
+            ->will($this->returnValue(array()))
+        ;
 
         return $admin;
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    private function getChildAdmin($parentCode, $childCode, $list = false, $granted = false)
+    {
+        $parentAdmin = $this->createMock('Sonata\AdminBundle\Admin\AbstractAdmin');
+        $parentAdmin
+            ->expects($this->any())
+            ->method('hasRoute')
+            ->with('list')
+            ->will($this->returnValue($list))
+        ;
+        $parentAdmin
+            ->expects($this->any())
+            ->method('hasAccess')
+            ->with('list')
+            ->will($this->returnValue($granted))
+        ;
+        $parentAdmin
+            ->expects($this->any())
+            ->method('getCode')
+            ->will($this->returnValue($parentCode))
+        ;
+
+        $childAdmin = $this->createMock('Sonata\AdminBundle\Admin\AbstractAdmin');
+        $childAdmin
+            ->expects($this->any())
+            ->method('getBaseCodeRoute')
+            ->will($this->returnValue($parentCode.'|'.$childCode))
+        ;
+
+        $parentAdmin
+            ->expects($this->any())
+            ->method('getChildren')
+            ->will($this->returnValue(array($childAdmin)))
+        ;
+
+        return $parentAdmin;
+    }
 }