I have read through a number of forum threads about redirecting a user to the page from which he came after he logs in. These threads talk about different possible solutions. See http://drupal.org/node/5066 and http://drupal.org/node/41151 and http://drupal.org/node/30052 and http://drupal.org/node/18253. However, I don't believe that any of the threads actually provides a solution, or at least, I didn't understand the solution if it was presented. I simply want the login page (/user) to remember the referrer page and send the user back to the referrer page after the user logs in. Is this possible? Thanks.

Comments

Amstercad’s picture

Have a look at this section of code.

http://drupal.org/node/39818#comment-73521

Notice how the session variable $destbefore403 is used at the beginning and end of the login form.

FWIW, also look at the new functions the Login Toboggan module brings to the party; it isn't what you're asking for, but I think you might want to consider what it does if you haven't already.

Please let others know what you manage to get working..

jacobson’s picture

This thread really helps show how to do what I want with one exception. I want to also have the ability to put a login link on my site header and after the user clicks on the link and logs in, I want to return them to the page from which they clicked the link. So, somehow I need to set the value of $destbefore403 before the login link is clicked. Could I just have a global that gets set on EVERY page that stores the url of the current page?

Thanks for the quick response.

HAJ

Amstercad’s picture

I think the answer is there in that code, but you aren't seeing it just yet.

Consider the function $destbefore403, look what it does: it calls an API function:

http://drupaldocs.org/api/4.6/function/drupal_get_destination

which is directly related to:

http://drupaldocs.org/api/4.6/function/drupal_goto

Budrick’s picture

How do you catch login event for redirect?
My hook_user is not invoked on load...
My original post in module development forum:
http://drupal.org/node/54480

dayre’s picture

Finding out how to simply redirect a user after login took way too much time. This solution i found from the login_destination module in CVS, worked for me, hope this helps.

  1. create your own module and enable it
  2. override the form_alter function and catch the user_login_block and user_login form ids. These are the two forms from where a user can log in. (replace "mymodulename" with the name of your module)
  3. set the $form #action value to a new url location.

The following example tests for the user role and redirects to different locations based on that.

/**
 * Implementation of hook_form_alter().
 */
function mymodulename_form_alter($form_id, &$form) {
  if ($form_id == 'user_login_block' || $form_id == 'user_login') {
    $form['#action'] = mymodulename_get_destination();
  }
}

/** 
 * Change the $path to the node location you want the user to
 * go to after logging in.
 */
function mymodulename_get_destination() {
  global $user;
  if (in_array('admin user',$user->roles)) {
     $path = 'node/11';  # admin area
  }
  else {
     $path = 'node/12';  # user area
  }
  return url('', "destination=$path");
}
trailerparkopera’s picture

Ran into this problem today and this took minutes to address. Thanks!

ecuguru’s picture

I tried your code, and it's exactly what I'm looking for, but I keep getting NULL for $user with:

function login_destination_get_destination() {
	global $user;
	$username = $user->uid;

Can you tell me what I should be looking for, or why I can't globally call $user->id?

thanks!

greggles’s picture

This is basically the login destionation module. And you rsolution (of using the $user prior to login) will never work - this issue explains why not and shows how to resolve it.

--
Knaddison Family | mmm Beta Burritos

MattClare’s picture

I've tried to implement this feature so that I can have the same functionality experienced on this very web page when you login to post a response.

If it makes any difference I've got a customized imap_auth in use for authentication.

Thanks in advance for any help anyone can offer.

jlieberman’s picture

It's probably not the best solution, but it's a simple solution.

modules\user.module

- return array(t('History') => form_item(t('Member for'), format_interval(time() - $user->created)));
+ print "<script language='JavaScript'>\n";
+ print "history.go(-2)";
+ print "</script>\n";
+ // return array(t('History') => form_item(t('Member for'), format_interval(time() - $user->created)));


themes\yourtheme\page.tpl.php

After the meta tags:

+ <?php 
+ header('Cache-Control: no-store, no-cache, must-revalidate'); 
+ Header('Pragma: no-cache');
+ ?>
lamb0176 at umn dot edu’s picture

I like this method a lot. However, my theme is a ".theme" and the output is all HTML, so the php doesn't work. I tried turning off caching in HTML using the 2 common META tag methods but it didn't work.

I also tried refreshing the page in user.module after the history.go(-2) command. However, this refreshes the page to the drupal user/login page instead of where I want.

Any ideas on turning off caching or using java to refresh correctly within user.module? Thanks ahead of time.

greggles’s picture

You can use the login destination module: http://drupal.org/node/69051

and specifically this modification to it: http://drupal.org/node/88258

Generally speaking, you should almost never modify the user.module code directly.

--
Knaddison Family | mmm Beta Burritos

ardas’s picture

I would like to propose one more interesting modification which is here http://drupal.org/node/98836
There is an ability to put the URL or PHP snippet to build URL you need right in a settings page - very convenient and no need to patch sources. This version also fixes the issue with global $user; mentioned before.

----------------
Regards,
Dmitry Kresin, ARDAS group (www.ardas.dp.ua)

mlncn’s picture

benjamin, Agaric

beautifulmind’s picture

To dayre,
Co-incidentally, I wrote the same code, but the problem is, how Drupal could decide whether the current user is logged in or not, when altering the login form!!

Beautiful mind
Know more

Regards.
🪷 Beautifulmind

f1vlad’s picture

Thank you guys for some ideas, your solution inspired me to create my own solution. In my case it's essential that each group is forwarded to their own page right after login. So what I did was this:

/**
* Implementation of hook_form_alter(). Redirecting all loging to one file where figure out where to forward further
*/

function variousoverride_form_alter($form_id, &$form) {
  if ($form_id == 'user_login_block' || $form_id == 'user_login') {
    $form['#action'] = variousoverride_get_destination();
  }
}

function variousoverride_get_destination() {
  $path = 'misc/loginprocessor.php';  # user area
  return url('', "destination=$path");
}

In few words, what I am doing is I am forwarding every login to misc/loginprocessor.php, there, I am doing a full bootstrap, then my script forwards (eg: <? header("Location:node/12") ) each user based on his group membership to appropriate page.

trying’s picture

The simplest way to redirect i found was to use the logintoboggan module. It has a redirect option and you just choose the page you want them to be redirected to.

beautifulmind’s picture

I found the login destination module to redirect the user based on the roles assigned to them.
This is a very easy way to redirect the user to their respective page.
Try it and feel better.

Beautifulmind
Know more

Regards.
🪷 Beautifulmind

bboldi’s picture

...that doesn't require manipulating the login form... it can be useful in some cases


	global $user;

	$last_user_id = $_SESSION['last_user_id'];
	
	$_SESSION['last_user_id'] = $user->uid;

	if(!($last_user_id>0) && $user->uid > 0)
	{
		// USER JUST LOGGED IN ... DO SOMETHING
	}

----------------------------------------
Boldizsár Bednárik ing.
http://www.bboldi.com

drahman’s picture

Can you elaborate?

This is exactly what I am trying to do: Redirect users based upon their assigned role. So role "tall people" will be redirected to the page "tall people" and everyone else are not affected.

I am a novice and much of this code talk is over my head. I would greatly appreciate any instructions you could give me in (layman's terms) to use login_destination to achieve this.

beautifulmind’s picture

kaptron’s picture

So, I was looking for 2 things:

1) a customized login form that was small and compact so it could be used in a configurable block.

2) Redirecting / keeping the user on their current page after login.

I took this customized login form from another thread, and all I had to do was grab "drupal_get_destination();" and pass that as a parameter after "user/login?", which automatically redirects the user to their current page.

This is the code I'm using in my block, pretty easy to modify and it does the trick:

<?php  global $user;  $redirect = drupal_get_destination(); ?>
<?php if ($user->uid) : ?>
  <span class="login_text">Logged in as: </span> <?php print l($user->name,'user/'.$user->uid); ?> |
  <?php print l("logout","logout"); ?>
    <?php else : ?>
<form action="user/login?<?php print $redirect; ?>" method="post" id="user-login">
      <label for="edit-name"><span class="login_text">Username:</span>
      <input type="text" maxlength="60" name="name" id="edit-name"  size="5" value="" tabindex="1" class="form-text required" /></label>
      <label for="edit-pass"><span class="login_text">Password:</span>
      <input type="password" maxlength="" name="pass" id="edit-pass"  size="5"  tabindex="2" class="form-text required" /></label>
      <input type="hidden" name="form_id" id="edit-user-login" value="user_login"  />
     <input type="submit" name="op" value="Log in"  tabindex="3" id="edit-submit" class="form-submit" /></form>
      <?php endif; ?>
kaptron’s picture

ah, I should mention that my solution requires the login toboggan module... I didn't realize that the module was affecting this code snippet until I disabled it, hehe.

rimian’s picture

I was using drupal_goto('user') to redirect to the login form which I altered to

if(!myaccessdeniedfunction()){
drupal_set_message('Access Denied. Please login to view this page.');
drupal_goto('user','destination=node/'.$node->nid);
}

Of course that's just a snip of code in my module.

If you're not logged into this page take a look at the link to reply to the comment. You'll see the destination in the query string.

http://www.rimian.com.au
http://www.freelancewebdeveloper.net.au

cglusky’s picture

This is a simple way to print a link that will redirect to the referring page.

  $destination = drupal_get_destination();
    print l('Login', 'user/login', array('query' => $destination));

After following that link and logging in the user will be sent back to the page where they clicked the link.

I happen to use it in page.tpl.php

R,
Coby

petrovichby’s picture

Coby, thanks. That's what I was looking for.

Pogle’s picture

Perfect. Wish I'd read that first. I put the following in user.module function user_login_block() .

  $destination = drupal_get_destination();
    $items[] = l(t('Login'), 'user/login', array('attributes' => array('title' => t('Login for existing customers.')),'query' => $destination));
jmather’s picture

Say I want to limit access to a particular page (with redirect after login) based on being authenticated easy enough...could be like so:

global $user;
if($user->uid <= 0) {
   drupal_goto('user','destination=node/'.$node->nid); 
}

What if I want to restrict a download of a file though while ensuring authentication...

In other words:

1) User requests to download a file
2) Check Authentication
3) User is not authenticated redirect to login
4) User logs in/registers

How do I prompt them for the file download and then redirect back to the page they came from?

ajross’s picture

This is just an extension of Coby's tip. I had my login link in my secondary menu and I wanted to keep the link as part of that menu instead of manually adding a link to the page template somewhere. So I modified the secondary links variable by adding the following code to the MYTHEME_preprocess_page() function in template.php. Seems to be working for me so far (for 6.x), and could easily be done with primary links or other menus:

  $destination = drupal_get_destination();
  foreach ($vars['secondary_links'] as &$value){
      if($value['href'] == 'user/login'){
          $value['query'] = $destination;
      }
  }
mpaler’s picture

If your login link isn't in primary or secondary links and rather in some other menu, you can use hook_menu_item_link to achieve the same effect by putting this into your template.php:

function your_theme_menu_item_link($link) {
  if (empty($link['localized_options'])) {
    $link['localized_options'] = array();
  }
  if ($link['title'] == "Login"){ // redirect after login to the page user was on. Change to match your login link text
    $destination = drupal_get_destination();
    $link['localized_options']['query'] = $destination;
     return l($link['title'], $link['href'], $link['localized_options']);
   } else {
      return l($link['title'], $link['href'], $link['localized_options']);		
   }
}
paul.dambra’s picture

Stumbled on this today and it immediately solved a gripe and taught me a couple of things.

P

Chaz Cheadle’s picture

That was what I was looking for, and was suprised that the login module didn't provide the facility.

-Chaz

boltforge’s picture

This requires almost no modification or modules. But really all it accomplishes is getting you back to the page you were on.

Just add <form action="/user?destination=<?php print $_REQUEST['q'] ?>">

Logs you in and redirects you to the page you were on :)

emorling’s picture

Folks, this method works.

nonrate’s picture

A bit off topic, but relevant as google led me here when searching for how to do this.

function hook_user ( $op ){

    if ( $op == "login" ){
        drupal_goto( "http://" . $_SERVER['HTTP_HOST'] . url( 'path/to/page' ) );
    }
}

Where hook is the name of your module. You must put this in a module that you created (or that already exists if you're a hacker) as it will not work in template.php. By default, I always have a generic functions module in my Drupal deployments (thus this becomes myfunctions_user) for performing actions that I need globally, or that can not be done in template.php, like this type of redirect.

So if you create a basic, basic module by following the module tuorial, and just have this function in there, you can rather easily control redirects. Note, the drupal_goto() function wants a complete URL, so that's why I am getting $_SERVER['HTTP_HOST'].

Another benefit, you should be able to global the $user variable and access what roles or other specifics you need to redirect to the right location. Let me know if this is not clear and I will try to clarify. Good luck.

stoptime’s picture

Actually, you only need a full path if you're going to an external site. Otherwise, it'll take an internal Drupal path ('node/6').
http://api.drupal.org/api/function/drupal_goto/6

I don't think you need to use the url() function either, as it's already used in drupal_goto()

Cheers.

abhax’s picture

i tried to redirect the user to a page after the user log's in with the help of the triggers n even rules but nothing seems to work here as even after i created the trigger to redirect the user after he's login to another page the drupal still redirects me to the default front page that i have assigned in the site information -> default front page....

Moreover i came to know that the triggers n rules wont help me to get redirected to the page i want after the user has logged in... coz drupal dun allow that and it uses the default front page only to redirect the user after the user has logged in.....

The solution i came to know is the FRONT PAGE module that can define differnt Front page after logging as per the roles assigned to them......
but again it wont redirect to the url i used in the FRONT PAGe :P

msti’s picture

I also tried the code from nonrate and was not working for me either. Probably you are right about drupal using the default redirect to the front page only. It turns out that drupal holds the value of the next url in the $_REQUEST['destination'] string. So I edited the code and came with the solution:


function hook_user ( $op ){
    if ( $op == "login" ){
	$_REQUEST['destination'] = 'node/XXX';
    }
}

Hope this helps,
Mike

Drupal developer and consultant
http://www.mikestiv.com

duckzland’s picture

have you try custom destination module?

--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com

modir’s picture

liaolliso’s picture

This is my solution. It works for me.

1. implement the hook_user and case 'login': do you stuff after login( eg: if(user is admin) drupal_goto(...) else if(...)... )

2. implement hook_form_alter: set the login form $form['#action'] = ''

Then it's ok without any other module's help

phoang’s picture

My solution for return to current node after login. If anyone has better ideas, please write your...Thx

/*
 * Implementation of hook_user() 
 */

function mymodule_user($op){
    $alias = drupal_get_path_alias($_GET['q']);
    if ( $op == "login" ){
       drupal_goto( "http://" . $_SERVER['HTTP_HOST'].'/'.$alias );
    }
}

Contact me for Drupal web development or outsource your projects...

irohit786’s picture

@dayre: Thanx.. I was able to move forward,
however i could not get this code to work could somebody please help me on this? sorry if there is a silly mistake in there, I'm a newb, and i'm using drupal 7.14, I have stumbled upon login destinatination module but i'd be more than happy if can get it to work this way.Thanx.

<?php
function my_module_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'user_login_block' || $form_id == 'user_login') {
   $form['#action'] = my_module_get_destination();
 }
 
}

function my_module_get_destination() {
  global $user;
  $latest_team = db_query("SELECT field_user_team_nid FROM field_data_field_user_team where entity_id = '".$user->uid."'ORDER BY delta DESC LIMIT 1 ")->fetchField();

  if (in_array('administrator',$user->roles)) {
     drupal_goto('');  // redirects to home page
  }
  elseif($latest_team == ''){
  drupal_goto('user');//redirects to profile page
  }
  else{
    drupal_goto( 'node/'.$latest_team);//redirects user to his latest team
	}
  }
?>
leymannx’s picture

/**
 * Implements hook_user_login().
 */
function MYMODULE_user_login(&$edit, $account) {
	$edit['redirect'] = 'node/123';
	// $edit['redirect'] = '<front>';
	// works fine as well
}