I’m scratching my head on this one. Right now I’m expanding my app to dynamically build a top level menu from menu items provided by application modules. My authorizations are calculated based upon some data that is contained within a custom User class. I have a custom user class configured in my app:
When I access Yii::app()->user within most parts of the application, I get MyCustomUserClass. I am building out that module’s menu structure within the module’s init() function. However, I found that Yii::app()->user returns a CWebUser when used within an init(), instead of the expected MyCustomUserClass.
Is this a bug, or am I going about this the wrong way?
Okay, so it turns out that it’s kind of a bug, but probably expected behavior. After a lot of research and tracing the code, I narrowed it down to gii. When gii is loaded, it actually overrides the global user class and sets it to CWebUser - regardless of what you have in the config. This is hardcoded. There’s been some debate on changing this behavior but the Yii devs have stood their ground.
GiiModules.php, line 118:
Yii::app()->setComponents(array(
'errorHandler'=>array(
'class'=>'CErrorHandler',
'errorAction'=>$this->getId().'/default/error',
),
'user'=>array(
'class'=>'CWebUser', // THIS IS THE PROBLEM LINE
'stateKeyPrefix'=>'gii',
'loginUrl'=>Yii::app()->createUrl($this->getId().'/default/login'),
),
'widgetFactory' => array(
'class'=>'CWidgetFactory',
'widgets' => array()
)
), false);
The devs have stated that this is required to ensure gii works properly, but I might recommend a patch that allows gii to proceed with the app’s custom class if it’s derived from a base CWebUser class.
The reason why I ran in to this problem is because I loop through each module to query it for potential menu items - and in the process of doing do I’m calling Yii::app()->getModule(), which kicks off the module’s init().
I was able to resolve this issue for now by ensuring that I don’t call getModule on gii, and in production gii is disabled so it’s a non-issue there.