About redirect and yii-user

Yii-user is an awesome extension.

However, I have some questions about the redirect part.

For example, if i want to create something and I need to login to do that. I can click on “create” and redirect to login page and then redirect back. That works after I changed yii-user’s LoginAction.

But…

My problem is, is there any chance that I can achieve the goal below:

I have a login button on a specific page. I click on that link. it redirects me to the login page and after I login, it takes me back.

(This one is different from the one above because it’s just a link on my page but not a create page with user’s rights).

So all in all…I need a way to redirect me to the PREVIOUS PAGE perfectly after I login… Any ideas about that?

Or any ideas about how to write a small ajax login box on each of my page?? (I really have no idea about how to do that). Or combined fancy box? Or…?

Thanks in advance.

Best,

jimmy.

Hi jiamjing,

I had exactly the same problem before.

As you may already have found, this is the code that redirect the user after successful login.

It’s in LoginController.php of yii-user.




public function LoginController::actionLogin()

{

...

	if($model->validate()) {

		$this->lastViset();

		if (strpos(Yii::app()->user->returnUrl,'/index.php')!==false)

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

		else

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

	}

...



And CWebUser::returnUrl is handled in CWebUser.php of the yii core.

  1. returnUrl is stored in session. (CWebUser::setReturnUrl())

  2. The default returnUrl is the home URL. (CWebUser::getReturnUrl())

  3. It is set to the requested URL if a guest user requested a URL that requires login. (CWebUser::loginRequired())

When we just call login page, the returnUrl defaults to home url, and yii-user will redirect to the module’s returnUrl.

So, if we could have set CWebUser::returnUrl to the current page before calling login page, then we could redirect the user back to the current page after successful login.

What I did to solve the problem was, after all, to modify the yii-user code. :(




public function actionLogin()

{

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

		$model=new UserLogin;


		// if called without specific returnUrl, set it to the previous page

		if (!isset($_POST['UserLogin']) && Yii::app()->user->returnUrl === Yii::app()->request->scriptUrl)

		{

			if (isset($_SERVER['HTTP_REFERER']))

			{

				Yii::app()->user->setReturnUrl($_SERVER['HTTP_REFERER']);

			}

		}


		// collect user input data

		if(isset($_POST['UserLogin']))

		{

			$model->attributes=$_POST['UserLogin'];

			// validate user input and redirect to previous page if valid

			if($model->validate()) {

				$this->lastViset();

				$returnUrl = Yii::app()->user->returnUrl;

				if (strpos($returnUrl,'/index.php')!==false)

					$returnUrl = Yii::app()->controller->module->returnUrl;

				Yii::app()->user->setReturnUrl('');

				$this->redirect($returnUrl);

			}

		}

		// display the login form

		$this->render('/user/login',array('model'=>$model));

	} else

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

}



Someone should have a better idea. ;)

Sorry man… Thanks so much for your help, but this code seems not work for me…

I changed your code and I can’t redirect to my previous page anyway… Included the page"create", “update” and “delete…”

I already actually figured out how to redirect back from these pages(but I can’t redirect back when the user click other ’ login link’ in my page)

That means, for example, I have a comment part in my page. If you want to comment, you have to login. But when the user click /index.php/user/login , it will never redirect the user back to the original page…

Here is my code :(yii-user)


	public function actionLogin()

	{

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

			$model=new UserLogin;

			// collect user input data

			if(isset($_POST['UserLogin']))

			{

				$model->attributes=$_POST['UserLogin'];

				// validate user input and redirect to previous page if valid

				if($model->validate()) {

					$this->lastViset();

/*					

if (preg_match('/index.php$/', Yii::app()->user->returnUrl))

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

else  

*/

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

				}

			}

			// display the login form

			$this->render('/user/login',array('model'=>$model));

		} else

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

	}

Still, Thanks so much man!!!!

I’m sorry, I might have misunderstood your problem.

What I thought was this scenario:

[list=1]

[*]A page named ‘foo’ with a ‘login’ link

[*]Click on ‘login’

[*]Login page

[*]The previous page named ‘foo’ again

[/list]

What is your scenario? I don’t think I understand your problem correctly.

Maybe this is not:

[list=1]

[*]A page named ‘foo’ with a ‘login’ link and ‘comment’ link

[*]Click on ‘comment’

[*]Login page

[*]A page to add a comment

[/list]

Because I think it is already supported by Yii and yii-user.

So, do you want this?

[list=1]

[*]A page named ‘foo’ with a ‘login’ link and ‘comment’ link

[*]Click on ‘login’

[*]Login page

[*]A page to add a comment

[/list]

No, I want exactly what you want.

What my code can do right now is:

A page named foo with a create/update link(generated by crud) and a comment box.(but you need to login to comment, so the comment box is go with a login button)

When you click Create/Update

then i can go to login peg

then I can also redirect back to the page foo.

But if I click on the comment box’s login/ or any other login link (with out create/update which is generated by crud)

Then i go to login page

but I will never come back, instead, i will come to user/profile.

Also…if I use your code. I can’t make either situation above…

Sorry about the trouble i caused.

Again, thanks so much for your help!!!!!

I would really appreciate if you can help me !!!!

Thanks man!

Here is my code:


 public function actionLogin()

        {

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

                        $model=new UserLogin;

                        // collect user input data

                        if(isset($_POST['UserLogin']))

                        {

                                $model->attributes=$_POST['UserLogin'];

                                // validate user input and redirect to previous page if valid

                                if($model->validate()) {

                                        $this->lastViset();

/*                                      

if (preg_match('/index.php$/', Yii::app()->user->returnUrl))

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

else  

*/

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

                                }

                        }

                        // display the login form

                        $this->render('/user/login',array('model'=>$model));

                } else

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

        }

I deleted the code below because they will even stop my first redirection…(that is , if i have these lines, even if i click on create/update. i can’t redirect back. so does the login link)


/*                                      

if (preg_match('/index.php$/', Yii::app()->user->returnUrl))

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

else  

*/

Um, I still don’t understand …

As far as I know, if a guest has clicked on ‘update’ or ‘create’, he will be first redirected to the login page, and then to ‘update’ or ‘create’ page when he has successfully logged in. I mean, not to the original ‘foo’ page. This is the default behavior when you use yii-user as is.

Did you tweak something to touch CWebUser::returnUrl somewhere else?

Well, I’ve noticed that my code (and also the original code) will not work when you are using the ‘get’ format for the URL manager.

The original code in yii-user:




				if (strpos(Yii::app()->user->returnUrl,'/index.php')!==false)

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

				else

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



My code:




                                if (strpos($returnUrl,'/index.php')!==false)

                                        $returnUrl = Yii::app()->controller->module->returnUrl;



If you are using ‘get’ format, then every url you make will contain the string of ‘/index.php’.

So I think the ‘if’ statement should be:




				if (Yii::app()->user->returnUrl !== Yii::app()->request->scriptUrl)



Or




                                if ($returnUrl !== Yii::app()->request->scriptUrl)



But, then again, I don’t know why you had to comment out the lines that you quoted.

It should work as well.

I’m sorry, I’m lost. :(

My url format is "PATH"

Should I change it??

Because if i keep it as path… even i change the code to




                                if ($returnUrl !== Yii::app()->request->scriptUrl)



It still not works…

Thanks so much…

and I think I want exactly what you want…

just the code is not working…

btw, what’s your url manager format?

And again…Thanks for your help.

I want exactly what you want.

That is …from page foo–>login–>page foo.

But those codes just not work…

The reason why i delete some lines is : if i don’t delete them. even when i click create/update , the page will note be redirected back…(that is , always redirect to user/profile after login.)

Thanks!!

Would you please post some codes in your config ? I want the user module part… I’m using yii rights so I’m afraid I did tweak part…but I don’t know where…

any ideas?

Hi jiaming,

I also use ‘path’ format.

And, yes, I’m using yii-user + yii-rights, too. They are both great extensions, I love them.

OK.

Would you please try this once more?




public function actionLogin()

{

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

                $model=new UserLogin;


                // if called without specific returnUrl, set it to the previous page

                if (!isset($_POST['UserLogin']) && Yii::app()->user->returnUrl === Yii::app()->request->scriptUrl)

                {

                        if (isset($_SERVER['HTTP_REFERER']))

                        {

                                Yii::app()->user->setReturnUrl($_SERVER['HTTP_REFERER']);

                        }

                }


                // collect user input data

                if(isset($_POST['UserLogin']))

                {

                        $model->attributes=$_POST['UserLogin'];

                        // validate user input and redirect to previous page if valid

                        if($model->validate()) {

                                $this->lastViset();

                                $returnUrl = Yii::app()->user->returnUrl;

                                /*

                                if (strpos($returnUrl,'/index.php')!==false)

                                        $returnUrl = Yii::app()->controller->module->returnUrl;

                                */

                                Yii::app()->user->setReturnUrl('');

                                $this->redirect($returnUrl);

                        }

                }

                // display the login form

                $this->render('/user/login',array('model'=>$model));

        } else

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

}



I’ve commented out the problematic lines.

I should buy you a dinner dude.

Thanks so much.

That works perfectly.

Thank you so much for your time and help!!!!!

And then, if it doesn’t work, try this:




public function actionLogin()

{

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

                $model=new UserLogin;


Yii::trace('1: retrunUrl = ' . Yii::app()->user->returnUrl);

Yii::trace('2: scriptUrl = ' . Yii::app()->request->scriptUrl);

Yii::trace("3: isset($_POST['UserLogin']) = " . isset($_POST['UserLogin']));

                // if called without specific returnUrl, set it to the previous page

                if (!isset($_POST['UserLogin']) && Yii::app()->user->returnUrl === Yii::app()->request->scriptUrl)

                {

                        if (isset($_SERVER['HTTP_REFERER']))

                        {

                                Yii::app()->user->setReturnUrl($_SERVER['HTTP_REFERER']);

                        }

                }

Yii::trace('4: retrunUrl = ' . Yii::app()->user->returnUrl);


                // collect user input data

                if(isset($_POST['UserLogin']))

                {

                        $model->attributes=$_POST['UserLogin'];

                        // validate user input and redirect to previous page if valid

                        if($model->validate()) {

                                $this->lastViset();

                                $returnUrl = Yii::app()->user->returnUrl;

Yii::trace('5: retrunUrl = ' . $returnUrl);

Yii::trace('6: module_retrunUrl = ' . Yii::app()->controller->module->returnUrl);

                                /*

                                if (strpos($returnUrl,'/index.php')!==false)

                                        $returnUrl = Yii::app()->controller->module->returnUrl;

                                */

                                Yii::app()->user->setReturnUrl('');

Yii::trace('7: redirect to returnUrl');

                                $this->redirect($returnUrl);

                        }

                }

                // display the login form

Yii::trace('8: redirect to login form');

                $this->render('/user/login',array('model'=>$model));

        } else {

Yii::trace('9: redirect to module returnUrl');

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

        }

}



I’ve inserted tracing codes.

In order to log traces, you should configure the log router.




// config/main.php

'log'=>array(

	'class'=>'CLogRouter',

	'routes'=>array(

		array(

			'class'=>'CFileLogRoute',

			'levels'=>'error, warning',

		),

		array(

			'class' => 'CFileLogRoute',

			'logFile' => 'trace.log',

			'levels' => 'trace',

			'categories' => 'application.*',

		),

	),

),



Then you can see the trace log in your ‘protected/runtime/trace.log’.

And examine what’s really happening.

Thanks so much for your help man…!!!

I really appreciate it!!

Thank you!

Thanks. :D

But I’d like to suggest you to examine the reason why you have to comment out the following lines:




/*

if (strpos($returnUrl,'/index.php')!==false)

       $returnUrl = Yii::app()->controller->module->returnUrl;

*/



I don’t think there should be any good reason to avoid these lines.

It might not be a big issue, but you would not want to left something unclear before you proceed.

Yeah, Definitely.

Thanks!

I can’t make it work, some pages are redirected fine, others not, just redirected to /user/profile.

I’ve used the method above, but in redirectUrl I get /index.php for not redirected pages.

Could anyone help me set this up?

Hi EndErr, welcome to the forum.

Er, could you be more specific on your problem?