How to have a defaultAction controller depending of the user status ?

Hi,

I just begin with Yii, and today I get a small problem…

Indeed, on my webApp, I want that all the unlogged users are redirected on my login page, and all the others (logged users) are redirected to the first page of my webApp (for example : index.php/MyFirstPage).

So, I have added on my SiteController the defaultAction :


public $defaultAction='login';

It is ok for unlogged users, but not for logged user :(

I think that I have to put the following code somewhere, but I don’t find where…I 've tried to put it on the actionIndex() function but it doesn’t work…




if (!Yii::app()->user->isGuest) {

   $defaultAction='index.php/MyFirstPage';

} else {

   $defaultAction='login';

}



Have you an idea or a better way for resolve my problem ?

Thanks in advance.

try the following

in your configuration file ( usually configs/main.php) add the following line in its first level:




'basePath'=>__DIR__.DIRECTORY_SEPARATOR.'..',

	'name'=>'My app',

	//....

	//action that will be executed before any other action

	'onBeginRequest' => array('Bootstrap', 'beginRequest'),//this line



and then create a class Bootstrap in your components folder and do something like the following:




class Bootstrap

{

   //method that will be executed before any other application action and defined above

	public function beginRequest($event){

    	if(Yii::app()->user->isGuest())

     		$_SERVER['REQUEST_URI']='/user/login';//this is the easiest way, its not totally right tho

	}

}



as you see, you just replaced the requested uri, the next step Yii will run the application and CHttpRequest will check for $_SERVER[‘REQUEST_URI’] to route the application

I created a BaseController class and extend all my other classes from it.

In BaseController, I have a beforeAction function that tests the status of a user and redirects them to where they should go.

The key for me is to only test for exceptions to the normal app flow. For instance, I check if their subscription has expired then redirect to a profile page. If the subscription is still active, I just return ‘true’ so the child class functions normally, as written.





class BaseController extends CController

{

	protected function beforeAction()

	{			

		if(Yii::app()->user->IsGuest)

			Yii::app()->user->loginRequired();

		

		if(!Yii::app()->user->isGuest)

		{			

			if(strtotime(Yii::app()->user->subscriptionEnd) < strtotime(date('Y-m-d')))

				// Redirect somewhere

			else					

				return true;

		}

	}

}



  • Well, not ALL my classes get extended from BaseController…only those that need the additional checks. Otherwise, there are unnecessary performance hits…

Thanks for your answers.

It seems that the


 $_SERVER['REQUEST_URI']='/user/login';

cause some problems with redirections.

Next, i’ve tried the beforeAction solution, but the function


Yii::app()->user->loginRequired();

doesn’t work, I don’t understand why…

:frowning:

I contninue to search a solution…

Hum, I think that i’ve found a solution…

I’ve created a BaseController class (as required previously), and then all my controllers extend this class instead of Controller.

Here my BaseControllerClass :




class BaseController extends CController

{

	

	/**

	 * @var string the default layout for the controller view. Defaults to '//layouts/column1',

	 * meaning using a single column layout. See 'protected/views/layouts/column1.php'.

	 */

	public $layout='//layouts/column1';

	/**

	 * @var array context menu items. This property will be assigned to {@link CMenu::items}.

	 */

	public $menu=array();

	/**

	 * @var array the breadcrumbs of the current page. The value of this property will

	 * be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links}

	 * for more details on how to specify this property.

	 */

	public $breadcrumbs=array();	

	

  protected function beforeAction($action)


  {


    if(Yii::app()->user->isGuest && $this->id.'/'.$action->id!=='site/login')


    {


       Yii::app()->user->loginRequired();


    }


    return true;


  } 

}



I don’t know if it is the best way to solve this “issue” but it seems ok…

drech’s solution works like a charm…and there’s a need to include gui’s “&& $this->id.’/’.$action->id!==‘site/login’” to avoid infinite loop when accessing ‘site/login’ in guest role.

My solution, in SiteController.php




public function actionIndex()

{

	if (Yii::app()->user->isGuest)

		$this->redirect(array('site/login'));

	else

		$this->render('index');

}



Simple is better.