-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Best practice: multiple voters for different items #146
Comments
Voters are iterated over in the order they are supplied to Additionally the default foreach ($this->voters as $voter) {
$current = $voter->matchItem($item);
if (null !== $current) {
break;
}
} The default Voters are just for the most simplistic use cases, and handles the bulk of how menus are generally handled. For my purposes I created my own The end result of my specific needs was to match, Sidebar, Footer and Boilerplate current menu links, while displaying the MenuItems that match the user's permissions. Since Guest users do not have permissions, the User Voter checked to see if the user permissions was empty and simply returned null to allow for the next Voter to execute. Example class UserVoter implements VoterInterface
{
private $permissions;
public function __construct($permissions = null)
{
$this->permissions = $permissions;
}
public function matchItem(ItemInterface $item)
{
if (null !== $this->permissions && null !== $item->getExtra('permission')) {
$item->setDisplay(isset($this->permissions[$item->getExtra('permission')]));
}
return null;
}
}
$matcher->addVoter(new UserVoter($userPermissions)); //executes first
$matcher->addVoter(new UriVoter($_SERVER['REQUEST_URI'])); //executes second |
The RouteVoter will only perform positive matching, never negative matching (it abstains instead, letting next voters decide). And btw, it already handles checking multiple routes. Regarding user permissions, this is not really a job for the voters. It should belong to the builder (or to a factory extension), as you want to hide the item entirely from the menu, not just mark it as not being the current item. Regarding the priority, the library assumes that the code registering voters can control the order in which it registers them, rather than implementing a sorting system internally. When using the Symfony bundle, it uses a priority mechanism (during the compile-time of the container, so there is no performance impact at runtime) to build this order. |
I have a general question regarding the new matcher/voter system: what if I need a more complex voting mechanism for some items, but not for all of them?
Imagine having some items that need both a route check (as done by the current
RouteVoter
) and then look up something in the database and thus decide if the item is current or not. Since theRouteVoter
would returntrue
orfalse
for any item that is tested, there would be no chance for other voters to check anything at all.Voters also seem not to provide any specific order as the extensions do, so if I don't add them all at the same time I won't know which one comes first.
It seems to me that at the moment there is no other way than to check these things while creating the menu items in the first place. I would love to give the items or the menu system in general some more "intelligence", because this would allow for faster and simpler menu definitions (e.g. in a YAML file) with specific runtime details figured out later.
Is there anything I have missed?
The text was updated successfully, but these errors were encountered: