Redirect user after login in Drupal

Redirecting users in Drupal is not easy as it seems to be. In this 6.19 version of Drupal, there are some gotchas to have in mind to make a succesfull redirection

The Direct Path : Hooking form_alter
Like the title say, what we need to do is create a hook for the form_alter hook. This hook is usefull for modifyng the form before rendering it (and for a lot of other interesting stuff), and because Mr. login block and Ms. login page (sitemap.com/user) are also forms, we are going to have fun with the hook(er) (bazinga? well, thats a sick joke). Here are the steps for ultimate redirection control:
  1. Create a module: Create two files yeah.info and yeah.module (change yeah for whatever you wish but make sure to remember that key word) and put them inside sites/all/modules/yeah.
  2. Fill yeah.info with this generic code:
    ;
    $Id$
    name = Yeah Redirect
    description = "Redirect your users at login"
    core = 6.x
    package = "Yeah"

    This is just a required file the module need to exist.

  3. Fill yeah.module with this code

    function yeah_form_alter(&$form, $form_state, $form_id){
    if ($form_id == 'user_login' || $form_id == 'user_login_block') {
    $form['#redirect']=array('thepath/you/want.php');}
    }

    Now, let me explain how this works:
    • The first line tell you that you're hooking the hook_form_alter hook (sic). What does this means is that before any form is rendered this function is being called. Notice the three parameters, first one is the variable that hold the form, its an reference (& anyone?) so the changes you make to &form will exist outside this function. Dont worry too much about $form_state. The third one is the id of the form.
    • The second line is an if that we use to capture only the user_login page form (user_login) and the user_login block form.
    • If the form currently on form_alter is a login form, then we are going to modified it, giving the #redirect property the url that we want to go. If you need to pass parameters then use an array, the first one is the path, and the next ones are the parameters



This code should work for all the user login pages. But it will not work for user login blocks...

What the..

Yes, that code will not work for the login block of Drupal. Why? well because, redirect calls the function drupal_goto($url) an that function is going to ignore you if $_REQUEST['destination'] and/or $_REQUEST['edit']['destination'] exist. Why? I dont have a clue, maybe someone in Drupal wants us to be slapped in the face as a price for using this awesome piece of framework ( no sarcasm here, really!, i luuuuuuuuuve Drupal, well except the drupal_goto function).

The Solution
unset($_REQUEST['destination'], $_REQUEST['edit']['destination']);
Insert this after form redirect and youre ready to go!.

Dude, its not working
Well here are some hints if you need more help:
  1. Make sure you activate the module . Duh!
  2. Check that others noncore modules are not using drupal_goto. Drupal_goto is like a header('Location:....) , it will redirect you to another page, and if there is more code to process after calling drupal_goto, it would not be use.
  3. Clear your theme_cache. Even if you have the 'Rebuild the theme registry on every page load.' on, hell just clear all the cache just in case.
Maybe im missing something here but with this easy explanation i think i have covered all that is need to know for redirecting users at login state. Happy Hooking

2 comments:

Anonymous said...

Hello Jeeba!

I have one remark about "destination" request parameter, for D7 at least.

You have to do next thing:

unset($_GET['destination']);

because drupal_goto() function does next verification:

if (isset($_GET['destination']) && !url_is_external($_GET['destination']))

and unset $_REQUEST["destination"] doesn't work.

Jose Carlos Tamayo said...

Thanks anon!. Didnt know about this in Drupal 7.