YiiSmartMenu auto checks permissions to define visibility of any menu item. It can be used with any authManager component since that one has configured to use the Yii::app()->user->checkAccess() authorization method.
YiiSmartMenu can work out-of-the-box with the Rights.
This is how YiiSmartMenu works: it iterates through the received items and turns its visibility true or false depending on result of checkAccess() function to that specific menu item. If you prefer, you can define the auth item name to be checked for yourself but if you don't, YiiSmartMenu will auto compound it by concatenating the module (whether any), the controller and the action defined in url or submit options of your menu's items.
It could be use, for example, in //layouts/main or //layouts/column2 menus:
$this->widget('application.components.YiiSmartMenu',array( //No required init options 'partItemSeparator'=>'.', 'upperCaseFirstLetter'=>true, //Same options used in CMenu 'items'=>array( array( 'label'=>'Home Page', 'url'=>array('/site/index', ), array( 'label'=>'Other Page', 'url'=>array('something/other'), //optional, if not set, YSM will controll visibility; 'visible'=>{your own rule, YSM will not touch this}, //optional, params to be sent to checkAccess() function; //if not set, YSM will use params from url/submit options //or $_GET. 'authParams'=>array('myParam'=>'myValue', ...), //optional, auth item name to be used in checkAccess() function; //if not set, YSM will auto generate this. 'authItemName'=>'myAuthItemName', ), ... ), ...
In the first menu item above, YiiSmartMeny would use the property url ('/site/index') to generate and execute the following checkAccess() function:
Yii::app()->user->checkAccess("Site.Index", $_GET)';
Setting 'partItemSeparator'=>'' (empty string) makes YSM generate:
Yii::app()->user->checkAccess("SiteIndex", $_GET)';
And if you also has set 'upperCaseFirstLetter'=>false YSM would generate:
Yii::app()->user->checkAccess("siteindex", $_GET)';
This way, the menu item 'Home Page' would only be visible if the current logged user had access privilegies to an auth item named 'Site.Index' (or 'siteindex' if init options was set like in the example). Note that $_GET is passed as $params to checkAccess() if you do not define 'authParams' option of your menu item or if the "url" or "submit" options has no additional params.
If you have trace logs enabled you can check traces messages to view why each menu item was turned visible or not. The template of the showed trace messages is:
Item {MenuItemName} is [*not*] visible. You have [no] permissions to [ModuleW.]ControllerX.ActionY with params:paramX=valX ...
$this->widget('zii.widgets.CMenu', ... to $this->widget('application.components.YiiSmartMenu',... (Please, see the examples above);Version 0.3.0
Version 0.2.1
Version 0.1.0 First Version;
Total 12 comments
Hello Sidtj,
Thank you for this extention! It has been a great start for what I need.
I'm working with Rights too, and I've been bothered by the fact that when a user has access to, let's say, User.Admin.*, the visibility check for User.Admin.View doesn't work. And if the link is something like User/Admin and going for the default controller, then I wanted it to check User.Admin.*
So here is it, very dirty and quick. Basically I create the .* item and check both.
What do you think? Any idea of how to make it better, if not irrelevant?
I dont know emenu, but I could see it extends CMenu. So, you could just change emenu class making it to extend YiiSmartMenu.
Change this...
to...
Can I integrate this extension with emenu? yiismartmenu will check permissions and emenu will render it...
When your link has no controller (eg. 'url'=>'actionX'), ysm uses the current controller. Probably it was your case.
By the way, thanks for sharing this:
I had removed it when used YSM in a specific project cause I was having problemas with 'ControllerX.*' of Rights. I will put it again in the next version.
Hi
I had to change YiiSmartMenu.php as follows (code between RCH 20120130 comments)
Thanks sidtj
Get closer to having this working using the 'url'=>'#' workaround.
Additonally I'm close to having this working with the MbMenu extension (http://www.yiiframework.com/extension/mbmenu/ "(MbMenu)")...in YiiSmartMenu.php just extend as follows:
Thank you, mhorrocks!
This is a good extension, easy to implement and pretty effective.
Yeah, it seems a bug. Thanks for let me know. Will be fixed in the next version.
Workaround: set 'url'=>'#'.
Thank you.
Hi
RE: v0.3.0 YiiSMartMenu
My menu starts like this:
The incoming menu has child items, but no URL.
So I'm getting the error: "Undefined index: url" on line 95 of YiiSmartMenu.php:
Any ideas what I'm doing wrong?
Thanks in advance Russell
Very happy that it was useful for you! Thanks for let me know.
Thanks, this is just what the doctor ordered, installed the file, called it, works perfectly. Literally 2 minutes to get it working.
Leave a comment
Please login to leave your comment.