Closed benrcole closed 7 years ago
Can you var_dump
$item
in a sonata menu, to see if there is anything specific to sonata we could use to do the restriction suggested by stof?
object(Knp\Menu\MenuItem)[2325]
protected 'name' => string 'TournamentParticipant' (length=21)
protected 'label' => null
protected 'linkAttributes' =>
array (size=0)
empty
protected 'childrenAttributes' =>
array (size=0)
empty
protected 'labelAttributes' =>
array (size=0)
empty
protected 'uri' => string '{}' (length=62)
protected 'attributes' =>
array (size=0)
empty
protected 'extras' =>
array (size=3)
'translation_domain' => string 'messages' (length=8)
'admin' =>
object(EventBundle\Admin\TournamentParticipantAdmin)[2329]
protected 'listFieldDescriptions' =>
array (size=0)
...
protected 'showFieldDescriptions' =>
array (size=0)
...
protected 'formFieldDescriptions' =>
array (size=0)
...
protected 'filterFieldDescriptions' =>
array (size=0)
...
protected 'maxPerPage' => int 32
protected 'maxPageLinks' => int 25
protected 'baseRouteName' => null
protected 'baseRoutePattern' => null
protected 'baseControllerName' => string 'SonataAdminBundle:CRUD' (length=22)
protected 'classnameLabel' => string 'TournamentParticipant' (length=21)
protected 'translationDomain' => string 'messages' (length=8)
protected 'formOptions' =>
array (size=0)
...
protected 'datagridValues' =>
array (size=2)
...
protected 'perPageOptions' =>
array (size=5)
...
protected 'pagerType' => string 'default' (length=7)
protected 'code' => string 'event.admin.tournament_participant' (length=34)
protected 'label' => string 'TournamentParticipant' (length=21)
protected 'persistFilters' => boolean false
protected 'routes' => null
protected 'subject' => null
protected 'children' =>
array (size=0)
...
protected 'parent' => null
protected 'baseCodeRoute' => string 'event.admin.tournament_participant' (length=34)
protected 'parentAssociationMapping' => null
protected 'parentFieldDescription' => null
protected 'currentChild' => boolean false
protected 'uniqid' => null
protected 'modelManager' =>
object(Sonata\DoctrineORMAdminBundle\Model\ModelManager)[2614]
...
protected 'request' => null
protected 'translator' =>
object(Symfony\Bundle\FrameworkBundle\Translation\Translator)[63]
...
protected 'formContractor' =>
object(Sonata\DoctrineORMAdminBundle\Builder\FormContractor)[2613]
...
protected 'listBuilder' =>
object(Sonata\DoctrineORMAdminBundle\Builder\ListBuilder)[2599]
...
protected 'showBuilder' =>
object(Sonata\DoctrineORMAdminBundle\Builder\ShowBuilder)[2547]
...
protected 'datagridBuilder' =>
object(Sonata\DoctrineORMAdminBundle\Builder\DatagridBuilder)[2592]
...
protected 'routeBuilder' =>
object(Sonata\AdminBundle\Route\PathInfoBuilder)[2562]
...
protected 'datagrid' => null
protected 'routeGenerator' =>
object(Sonata\AdminBundle\Route\DefaultRouteGenerator)[2589]
...
protected 'breadcrumbs' =>
array (size=0)
...
protected 'securityHandler' =>
object(Sonata\AdminBundle\Security\Handler\NoopSecurityHandler)[2564]
...
protected 'validator' =>
object(Symfony\Component\Validator\Validator\RecursiveValidator)[2563]
...
protected 'configurationPool' =>
object(Sonata\AdminBundle\Admin\Pool)[1017]
...
protected 'menu' => null
protected 'menuFactory' =>
object(Knp\Menu\MenuFactory)[1009]
...
protected 'loaded' =>
array (size=4)
...
protected 'formTheme' =>
array (size=1)
...
protected 'filterTheme' =>
array (size=1)
...
protected 'templates' =>
array (size=39)
...
protected 'extensions' =>
array (size=1)
...
protected 'labelTranslatorStrategy' =>
object(Sonata\AdminBundle\Translator\NativeLabelTranslatorStrategy)[2560]
...
protected 'supportsPreviewMode' => boolean false
protected 'securityInformation' =>
array (size=0)
...
protected 'cacheIsGranted' =>
array (size=1)
...
protected 'searchResultActions' =>
array (size=2)
...
protected 'listModes' =>
array (size=2)
...
protected 'accessMapping' =>
array (size=0)
...
private 'class' (Sonata\AdminBundle\Admin\AbstractAdmin) => string 'EventBundle\Entity\TournamentParticipant' (length=40)
private 'subClasses' (Sonata\AdminBundle\Admin\AbstractAdmin) =>
array (size=0)
...
private 'list' (Sonata\AdminBundle\Admin\AbstractAdmin) => null
private 'show' (Sonata\AdminBundle\Admin\AbstractAdmin) => null
private 'form' (Sonata\AdminBundle\Admin\AbstractAdmin) => null
private 'filter' (Sonata\AdminBundle\Admin\AbstractAdmin) => null
private 'cachedBaseRouteName' (Sonata\AdminBundle\Admin\AbstractAdmin) => null
private 'cachedBaseRoutePattern' (Sonata\AdminBundle\Admin\AbstractAdmin) => null
private 'formGroups' (Sonata\AdminBundle\Admin\AbstractAdmin) => boolean false
private 'formTabs' (Sonata\AdminBundle\Admin\AbstractAdmin) => boolean false
private 'showGroups' (Sonata\AdminBundle\Admin\AbstractAdmin) => boolean false
private 'showTabs' (Sonata\AdminBundle\Admin\AbstractAdmin) => boolean false
private 'managerType' (Sonata\AdminBundle\Admin\AbstractAdmin) => string 'orm' (length=3)
private 'breadcrumbsBuilder' (Sonata\AdminBundle\Admin\AbstractAdmin) => null
'routes' =>
array (size=1)
0 =>
array (size=2)
...
protected 'display' => boolean true
protected 'displayChildren' => boolean true
protected 'children' =>
array (size=0)
empty
protected 'parent' =>
object(Knp\Menu\MenuItem)[2364]
protected 'name' => string 'Events' (length=6)
protected 'label' => string 'Events' (length=6)
protected 'linkAttributes' =>
array (size=0)
empty
protected 'childrenAttributes' =>
array (size=1)
'class' => string 'active treeview-menu' (length=20)
protected 'labelAttributes' =>
array (size=0)
empty
protected 'uri' => null
protected 'attributes' =>
array (size=0)
empty
protected 'extras' =>
array (size=3)
'icon' => string '<i class='fa fa-plus'></i>' (length=26)
'label_catalogue' => string 'SonataAdminBundle' (length=17)
'roles' =>
array (size=0)
...
protected 'display' => boolean true
protected 'displayChildren' => boolean true
protected 'children' =>
array (size=2)
'Tournament' =>
object(Knp\Menu\MenuItem)[2328]
...
'TournamentParticipant' =>
&object(Knp\Menu\MenuItem)[2325]
protected 'parent' =>
object(Knp\Menu\MenuItem)[2366]
protected 'name' => string 'root' (length=4)
protected 'label' => null
protected 'linkAttributes' =>
array (size=0)
...
protected 'childrenAttributes' =>
array (size=0)
...
protected 'labelAttributes' =>
array (size=0)
...
protected 'uri' => null
protected 'attributes' =>
array (size=0)
...
protected 'extras' =>
array (size=0)
...
protected 'display' => boolean true
protected 'displayChildren' => boolean true
protected 'children' =>
array (size=4)
...
protected 'parent' => null
protected 'isCurrent' => null
protected 'factory' =>
object(Knp\Menu\MenuFactory)[1009]
...
protected 'isCurrent' => null
protected 'factory' =>
object(Knp\Menu\MenuFactory)[1009]
private 'extensions' =>
array (size=2)
...
private 'sorted' =>
array (size=2)
...
protected 'isCurrent' => null
protected 'factory' =>
object(Knp\Menu\MenuFactory)[1009]
private 'extensions' =>
array (size=2)
0 =>
array (size=1)
...
-10 =>
array (size=1)
...
private 'sorted' =>
array (size=2)
0 =>
object(Knp\Menu\Integration\Symfony\RoutingExtension)[1011]
...
1 =>
object(Knp\Menu\Factory\CoreExtension)[1010]
...
Well, for one, the extras
array is full of Sonata-specific things… could you make a PR doing the restriction based on it?
...
use Sonata\AdminBundle\Admin\AbstractAdmin;
...
public function matchItem(ItemInterface $item)
{
$children = $item->getChildren();
$match = null;
foreach ($children as $child) {
if ($this->matcher->isCurrent($child) && $child->getExtra('admin') instanceof AbstractAdmin) {
$match = true;
break;
}
}
return $match;
}
The above seems to work although it's premised on every relevant current
node having an attached Admin
class.
Looking at the MenuBuilder it looks like some Items
may not. In that case we only currently have translation_domain
that could be matched and that can be overridden by users.
Alternatively we could add something else to each MenuItem
that's created by the AdminBundle
but that feels a little messy.
To be honest, I think this is a flaw in the design of the global nature of the Matcher
setup and I'm reluctant to hack anything else into the otherwise clean nature of the AdminBundle
.
Thoughts?
I think adding something else, like a marker, just for that would be the way to go. But you're right, it would be great to have a dedicated thing for that.
The best course of action IMO would be to hack something, raise an issue in knp/menu, and mark the hack for "removal when the issue is solved".
OK - happy to do this. Will submit a PR later - am hacking on a VPS at the moment
I dealed with this exact same issue last week. I found the same hack as commented by @benrcole but as said before for now we don't a clear way to identify each MenuItem for sure.
I was on my way to create a PR (#4272) to simplify to overriding of Menu Voter shipped with Sonata by exposing classnames as parameters in the DIC config.
I will try to find the time to create a PR to add a marker on each MenuItem of Sonata Menu to be sure those voters have no side effect.
For the history, these voters were added to simplify twig logic in PR https://github.com/sonata-project/SonataAdminBundle/pull/3577/files#diff-7aad62c164c47d66f90ce813f6f91c49
Environment
Sonata packages
Symfony packages
Other
Subject
The
ChildrenVoter
included as part ofSonataAdminBundle
is affecting otherKnpMenus
in different parts of applications.Building a breadcrumb as per the
KnpMenuBundle
documentation relies on which returnstrue
for the root node based on theChildrenVoter
result.As per the response from https://github.com/KnpLabs/KnpMenuBundle/issues/331 there doesnt seem to be a way to remove a
Voter
from a specifcMenu
so is it possible to restrict theChildrenVoter
to onlySonataAdmin
Menus?More info http://stackoverflow.com/questions/41304270/can-you-make-knpmenu-voters-private
Steps to reproduce
Call
isCurrent
on aKnpMenu
root node where the current page is a child node of the root.Expected results
Any parent returns true for
isCurrent
if theChildrenVoter
is loaded.This is correct behavior for
SonataAdmin
menu links but shouldnt be applied to nonSonataAdmin
menus.Actual results
Only the current item returns true for non
SonataAdmin
menus.