Module login link on Home page

I have two modules in my Yii app - Admin and Member. Both have separate logins, so I have done the following in my MemberModule.php file:


'user'=>array(

	'class'=>'CWebUser',

	'stateKeyPrefix'=>'member',

	'loginUrl'=>Yii::app()->createUrl('member/default/login'),

),

On my main site layout I have the following:


array('label'=>'Login', 'url'=>array('/member'), 'visible'=>Yii::app()->user->isGuest),

Now even when the user is logged in to the Member Module, the Login link still gets displayed on the main home page. I assume this is because Yii::app()->user->isGuest does not check the member module. How to fix this?

What do you mean by module? CWebModule?

Do you login the user? - http://www.yiiframework.com/doc/api/CWebUser#login-detail

Yes:


if($model->validate() && $model->login())

	$this->redirect(Yii::app()->user->returnUrl);

To login a user you must have something like…


Yii::app()->user->login($this->_identity,$duration);

Yes, I have that in my LoginForm model.

\protected\modules\member\controllers\DefaultController.php has actionLogin which references to $model=new LoginForm

You can access the WebUser object of the member module this way:




// Within a controller

$this->module->user


// Globally

Yii::app()->getModule('member')->user



Property "MemberModule.user" is not defined.

In main config:




'modules' => array(

   'member' => array(

      'components' => array(

         'user' => array(

            ...

         ),

      ),

   ),

),



I see. So in other words I can actually take out my custom config from MemberModule.php file and put it all in the main.php config file?

Yes, how did you do it in MemberModule.php?

I did it like this in MemberModule.php:


Yii::app()->setComponents(array(

	'errorHandler'=>array(

		'errorAction'=>'member/default/error',

	),

	'user'=>array(

		'class'=>'CWebUser',

		'stateKeyPrefix'=>'member',

		'loginUrl'=>Yii::app()->createUrl('member/default/login'),

	),

));

So can all this just go in main.php?

Ahh I see, you have to realize Yii::app() is a module itself. If you do Yii::app()->setComponents(), your original components defined in the main config under the base componenents array get overwritten.

This could lead to the following:




echo Yii::app()->user->id; // 1

$module = Yii::app()->getModule('member'); // init method of MemberModule get called and user component get changed

echo Yii::app()->user->id; // 2



If you don’t mixup the different modules (access one module in another), you don’t run in any problems with your approach though.

I think the right solution in your case is to define the user component in the main config (like explained) and the errorHandler component in the beforeControllerAction method of the MemberModule:




public function beforeControllerAction($controller, $action)

{


   if (parent::beforeControllerAction($controller, $action))

   {


      Yii::app()->setComponents(array(

         'errorHandler'=>array(

            'errorAction'=>'member/default/error',

        ),

      ));


     return true;


   }


}



This way, the errorHandler gets overwritten only when a actual member module controller is running.

// Note that within the member module, you should not access the user object via Yii::app()->user. See my first post in this thread. Though if you don’t like that, you are free to overwrite the user object in the beforeControllerAction method as well.

Cheers. It also seems that loginUrl needs to be specified in the Module config. So a user component is still required in the Module.

Yes like explained. If you would overwrite the user component in the init() method of MemberModule, at this point you would change the user object:


array('label'=>'Login', 'url'=>array('/member'), 'visible'=>Yii::app()->user->isGuest),

Means if you access Yii::app()->user below this line, you would access the user object defined in init() method, not the one in the main config under the base components array.

I don’t really understand though. How come I can’t just put loginUrl in the module’s user component in main.php?

You can do that. But you may need to put the loginUrl in both user component configurations. If you only set it for the user component of the member module, you will get something different when doing this within a controller which is not part of the member module:




var_dump(Yii::app()->user->loginUrl);



Yeh that’s what I mean, if I can just put it in main.php then I don’t need to create a user component in MemberModule.php.

At the moment, both ‘class’ and ‘stateKeyPrefix’ can be declared in main.php but ‘loginUrl’ has to be declared in MemberModule.php:

main.php:


'member'=>array(

	'components'=>array(

		'user'=>array(

			'class'=>'CWebUser',

			'stateKeyPrefix'=>'member',

		),

	),

),

MemberModule.php:




Yii::app()->setComponents(array(

	'errorHandler'=>array(

		'errorAction'=>'member/default/error',

	),

	'user'=>array(

		'loginUrl'=>Yii::app()->createUrl('member/default/login'),

	),

));



Well in main config, just put the loginUrl 2 times. First time for the main user component and the seconds the for the member module user component. Otherwise you may run into problems.