Hi,

I am quite new to Drupal module development...and this particular issue is doing me in :) What I am trying to do is apply a redirect when a user logs in. I can get this to work properly from the "user_login" form (www.mysite.com/user), but not from the "user_login_block" - this always redirects to www.mysite.com/node. Below, I have simplified the problem - I want to redirect to www.mysite.com/node/1 and the info and module files are:

testredirect.info

name = testredirect
description = Test redirect
package = Redirect test
core = 7.x
files[] = testredirect.module

testredirect.module

function testredirect_form_alter(&$form, &$form_state, $form_id) {
  switch ($form_id) {
    case 'user_login':       // user login page
    case 'user_login_block': // user login block
      $form['#submit'][] = 'testredirect_submit';
      break;
  }
}

function testredirect_submit($form, &$form_state) {
  $form_state['redirect'] = 'node/1';
}

I have searched the forum and have found some posts where similar issues are reported. Some suggested using drupal_goto() but I believe this is not a particularly good idea. Others suggested 'unsetting' $_REQUEST['destination']. I have inspected this variable and can see it has been set to "node" but I have failed to 'unset' it (using unset($_REQUEST['destination']);). Can anyone explain why the redirect works for the 'user_login' form but not the 'user_login_block'?

Note, I am aware of the login_destination module. However I would still like to know what's happening with the above.

Thanks.

Comments

Ellen Dee’s picture

Have you considered using actions/triggers? It's what I use to handle redirects after login in 6.x. Haven't yet implemented it in 7.x.

http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hoo...

davbre87’s picture

Thanks for the response. Although this is not reflected in my initial post, I want to redirect only on certain conditions, e.g. I want to check what roles the user has been assigned and whether or not they have certain profile information.

In any case, I did try actions and triggers. That is, I created an advanced action "Redirect to Url" and then the trigger for when a user logs in. The exact same thing happens, i.e. it works when logging in from the /user page but not from the user login block.

Can anyone explain what's going on?

davbre87’s picture

EDIT:
I had posted what I thought was a solution, but it's not. I've tried programming a module, have used actions and triggers and also the rules module, but no joy. Could this be a bug in core?

Ellen Dee’s picture

Here's a pared-down version of what I have, which works fine from the login block:

function mymodule_login_redirect(&$object, $context = array()) {
  if (user_access('access administration pages')) {
    drupal_goto('admin');
  }
}

function mymodule_action_info() {
  return array(
    'mymodule_login_redirect' => array(
      'description' => t('Custom redirect on login'),
      'type' => 'mymodule',
      'configurable' => FALSE,
      'hooks' => array(
        'user' => array('login'),
      )
    ),
}

Of course you then have to enable it at Site building > Triggers (Task: Users).

mikeyg’s picture

I am working on my first Drupal site and I have been unable to find a workable solution to the login redirect either. After a user has logged in, I want to redirect the user to a specific node (node/11). I'm working with Drupal 7 and have tried a variety of approaches - nothing has worked. The approach presented here by Lara D looks promising but I'm not sure how to modify it for my needs.

In addition to what seem to be the obvious changes:
- Change "mymodule" to my module
- Change the Drupal goto destination to my node

I suspect that the argument of user_access('access administration pages') needs to be changed but I haven't found documentation on this

Any help would be greatly appreciated.

mesch’s picture

If you inspect the user module .module file , you'll see there's documentation (in Drupal 6) beginning line 1411 stating that setting the destination in the query string (as done by the user login block) inteferes with the redirect. There is no url parameter with the user_login block, and that's why the redirect works there. You can see the form actions are different by inspecting the source of each form.

One solution would be to simply remove the $form['#action']. I just threw together this code and it does the trick.

/**
 * Implement of hook_form_FORM_ID_alter()
 */
function myModule_form_user_login_block_alter(&$form, &$form_state)
{
   unset($form['#action']);
   $form['#submit'][] = 'redirect_submit';
}

Let me know if that does the job.

mikeyg’s picture

Thank you for your suggestion. I have a few questions on how to implement. Your approach removes the form action and then sets the submit function to 'redirect_submit'.

Is this code to work in conjunction with the approach of Lana's or is it required to make the trigger/action configuration work correctly with the action "Redirect URL"?

mikeyg’s picture

I forgot to ask ... where is 'redirect_submit' defined?

Thanks again for your help.

mesch’s picture

Unsetting the #action element should be sufficient. It's generally best to avoid using drupal_goto in submit handlers. To see why, consider what happens when you have multiple submit handlers. If you execute drupal_goto in the first submit handler, the other submit handlers are not executed. This isn't a problem if you have just the one handler, but you never know when you'll need another one in future, by which point you may have forgotten about the drupal_goto.

The 'redirect_submit' isn't defined, it's just function name I created for the example. It would look something like this:

function redirect_submit($form, &$form_state)
{
  $form_state['redirect'] = 'the_url_you_wish_to_redirect_to'
}
mesch’s picture

BTW, I'm not suggesting this is the only or even best way of doing redirects on login. Lara's approach using triggers/actions is another possibility. I was just responding to the original poster's question as to why the redirect wasn't working.

mikeyg’s picture

Login redirect now working. I used a variation of your suggestion and it seems to be working fine. Using hook_form_alter I changed the login 'action' property. Instead of unsetting it, I changed it to the desired path. The original property value was 'node/1?destination=node/1'. I changed it to the desired value:

if ($form_id == 'user_login_block' || $form_id == 'user_login') {
$form['#action'] = 'node/1?destination=node/11';
}

Thanks again for your help.

wei.2k’s picture

Just setting the form['#action'] doesn't work for me to alter the redirection url for user_login form on D7.

it does however redirect the page, but my user wasn't logged in during the process and it end up with permission denied error (since the redirected url required certain permission set).

the solutions provided by MEsch above work for me.
this is how it look like on my code


function yourmodule_form_alter(&$form, &$form_state, $form_id){
	if ($form_id == 'user_login' || $form_id == 'user_login_block') {
             unset($form['#action']);
             $form['#submit'][] = 'yourmodule_redirect_submit';
	}
}

function yourmodule_redirect_submit($form, &$form_state)
{
  $form_state['redirect'] = 'path_to_redirect_here';
}

alternatively, for anyone who don't want to code anything at all, this module work as well....
http://drupal.org/project/login_destination

tvn’s picture

This works perfectly on D7.9. Thanks!

ziccidus’s picture

If you use the Trigger module, you can simply unset the default action, and the Trigger action will work on the login-block as well:

<?php
/*
 * Implements hook_form_alter()
 */
function MODULENAME_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_login_block') {
    unset($form['#action']);
  }
}
?>