Yii 1.1: Adding login form to each page

10 followers

After adding proper form to the main layout, like:

...
if(Yii::app()->user->isGuest):
  echo CHtml::beginForm(array('site/login'));
  ...

You may recognize that the user does not get redirected to the previous page correctly.

This is because CWebUser::loginRequired() is not invoked, thus proper states are not saved before the user logs in.

If you want to preserve the referrer you can attach an event handler to your application onEndRequest event with the following content:

$app=Yii::app();
if($app->createUrl($app->user->loginUrl[0])!=$app->request->getUrl())
    $app->user->setReturnUrl($app->request->getUrl());

The above code does the following: if the user is at the login page, the referrer is not saved for future reference (otherwise he will be redirected to the login page right after he logged in, which is, of course, not the desired effect).

In any other cases, the previously viewed page is reloaded if the user logs in with the form in the header.

Make sure your login action makes use of this:

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

Your logout process might also use this feature and not send the user back to the front page.

If you are not sure how to attach an event handler to your application object, open up your config file and insert this function at the head of the code (before returning the array):

function endRequest($event)
{
    $app=Yii::app();
    if($app->createUrl($app->user->loginUrl[0])!=$app->request->getUrl())
        $app->user->setReturnUrl($app->request->getUrl());
}

Attaching could be done in your config:

return array(
...
    'onEndRequest'=>'endRequest',
...

Total 5 comments

#9901 report it
Don Felipe at 2012/09/20 03:50am
@bryglen
!$error instanceof CHttpException

It's much better! Thank you.

#9591 report it
bryglen at 2012/08/27 01:14am
This is a better approach
function endRequest($event)
{
    $app = Yii::app();
    $error = $app->errorHandler->error;
    $loginUrl = $app->createUrl($app->user->loginUrl[0]);
    if(!$error instanceof CHttpException && $loginUrl != $app->request->getUrl())
        $app->user->setReturnUrl($app->request->getUrl());
}

check if error is not an instanceof CHttpException

#6754 report it
Don Felipe at 2012/02/03 02:14am
The 404 problem

This is confusing!

Should Yii::app()->request->getUrl() not return the address/url of the initial page request no matter the HTTP status code? On the other hand, this can easily avoided by adding another condition to check the said status code. However, I doubt it is the right way to do so; but is works for me.

function endRequest($event)
{
    $app = Yii::app();
    $error = $app->errorHandler->error;
    $loginUrl = $app->createUrl($app->user->loginUrl[0]);
 
    if( $error->code===200 && $loginUrl != $app->request->getUrl() )
        $app->user->setReturnUrl($app->request->getUrl());
}
#253 report it
Spear at 2010/07/27 06:44am
Bad idea

the problem with this logic is that user will have 'returnUrl' set to whatever last request page url was. That is, for example, url of ANY element on page that might have had 404 error thrown at it. Say, you have a page with 20 images on it, and one image set '404' error off, so after login you'll be redirected to '/images/something_that_isnt_here.jpg' or, more likely, you'll be returned to '/favicon.ico' which is served by "/site/error" (in case it's missing, of course). Peace out!

#337 report it
kitt at 2010/07/05 09:08pm
another way
CController->refresh()
/**
 * Refreshes the current page.
 * The effect of this method call is the same as user pressing the
 * refresh button on the browser (without post data).
 * @param boolean whether to terminate the current application after calling this method
 * @param string the anchor that should be appended to the redirection URL.
 * Defaults to empty. Make sure the anchor starts with '#' if you want to specify it.
 * The parameter has been available since version 1.0.7.
 **/
public function refresh($terminate=true,$anchor='')
{
    $this->redirect(Yii::app()->getRequest()->getUrl().$anchor,$terminate);
}

Leave a comment

Please to leave your comment.

Write new article
  • Written by: pestaa
  • Updated by: Yang He
  • Category: Tutorials
  • Yii Version: 1.1
  • Votes: +3 / -2
  • Viewed: 32,923 times
  • Created on: Aug 23, 2009
  • Last updated: Jun 29, 2012
  • Tags: Authentication