the ability to specify a path for handling 'access denied' pages is nice. it would be helpful if this handler could learn the path which was originally requested by the user. currently, $_GET['q'] is overwritten with the path of the handler and thus the handler is ignorant.

Comments

moshe weitzman’s picture

for now, i work around this limitation by stashing the path in my own var using the following line of code which executes in hook_menu(!$may_cache)

$_GET['q_original'] = $_GET['q'];

jsloan’s picture

This same situation occurs when a node is a member of a book. Via the _nodeapi hook in the book module eventually the function menu_set_active_item() will execute the following statement:

if (empty($path)) {
      $path = $_GET['q'];
    }
    else {
      $_GET['q'] = $path;
    }

... which sets the superglobal $_GET to the callback path of the menu item.

Like Moshe, I had to store the original contents in another variable. I need to use the full value of the $path in a module that extends the node to accept "full directory paths" and this works fine when the node is just a node, it breaks only when it is part of a book.

I guess what I am asking is "can we find another approach to menu/callback $path setting. Perhaps declare a variable for menu in the bootstrap and then leave the $_GET alone. It would be much more intuitive for module/theme developers to depend on the content of $_GET as reflecting what they see in the URL.

Richard Archer’s picture

Priority: Normal » Minor

I'm changing this to CVS because:

- I think it's worth looking into further
but
- any solution will not likely be back-ported.

dublin drupaller’s picture

Worth noting that Kbahey has already posted a patch for common.inc that maybe useful in this situation.

http://drupal.org/node/35687

The patch was intended for his customerrror.module, but, I'm guessing that it maybe aapplied to common.inc across the board.

Dub

kbahey’s picture

Status: Active » Needs review
StatusFileSize
new684 bytes

Here is the patch to common.inc for HEAD.

It is one line, and just stores the destination in the session. Any other module or function can check if destination is set and act accordingly.

For example, customerror traps the user hook, checks if it is a login, unsets the destination in the session, and redirects to the original page the user tried to access

If we get this in, modules can act on this in many ways.

moshe weitzman’s picture

session is for data that needs to persist across page views. $_GET[q] doesn't need this. i don't really like this solution.

moshe weitzman’s picture

Status: Needs review » Needs work
markus_petrux’s picture

I would say "won't fix" 'cause why would you preserve the original value of $_GET['q']? I believe the core doesn't need this and if it is need by a contrib module, the original value could be capture from the init or menu hooks.

Someone that could benefit from this approach would be the statistics module, when it saves the path in the log, instead of $_GET['q'], it could use $original_path. Say $original_path was saved in the menu hook like this:

  ...
  if ($may_cache) {
    ...
  }
  else {
    global $original_path;
    $original_path = $_GET['q'];
    ...
  }
  ...

In statistics_exit, after this:

  drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH);

it could do this:

  global $original_path;
  if (!isset($original_path)) {
    $original_path = $_GET['q'];
  }

And use $original_path instead of $_GET['q'] in the INSERT statement.

It works. ;-)

moshe weitzman’s picture

the use case is to put a login form on the accedss denied page ()assuming anonymous user). that login form ought to know the destination where the user was headed.

markus_petrux’s picture

so you could save the original init path by drupal core itself and provide a normalized method to get its value. Say drupal_init_path() is modified like this:

function drupal_init_path() {
  global $drupal_init_path;
  if (!empty($_GET['q'])) {
    $_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/'));
  }
  else {
    $_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node'));
  }
  $drupal_init_path = $_GET['q'];
}

The normalized method to get the original path could like:

/**
 * Get the original init path.
 */
function drupal_get_init_path() {
  global $drupal_init_path;
  return $drupal_init_path;
}

So you could set destination based on drupal_get_init_path() for a login form (or anything else) defined inside the 403/404 handlers.

markus_petrux’s picture

Then the example I posted above, related to the statistics module, would be much simpler. The exit hook could use drupal_get_init_path() rather than $_GET['q'] to save the path in the access_log table.

moshe weitzman’s picture

yes, thats the right idea. perhaps we change to two functions get_initial_path and set_initial_path. the set_initial_path will be called by the menu system whenever it first figures out $_GET['q'] ... lets not abbreviate init instead of initial. dries no like that.

moshe weitzman’s picture

forget my last comment. i didn't realized we already had that init_path function. markus' proposal looks good to me.

markus_petrux’s picture

Status: Needs work » Needs review
StatusFileSize
new1.51 KB

Do you mean this? (see patch)

markus_petrux’s picture

StatusFileSize
new1.48 KB

rerolled (affected line in statistics module was changed)

markus_petrux’s picture

Status: Needs review » Reviewed & tested by the community

This is so simple that I believe it is RTC. Please, correct me if I'm wrong.

moshe weitzman’s picture

I suspect that http://drupal.org/node/13621 is a bug that depends on the patch here

moshe weitzman’s picture

killes@www.drop.org’s picture

Status: Reviewed & tested by the community » Needs work

using a get_foo function with a global variable doesn't make much sense. There should be a set_foo function and a static var.

Steven’s picture

This issue offers a much simpler solution to this (and another) issue:
http://drupal.org/node/55869

moshe weitzman’s picture

Status: Needs work » Fixed

tentatively marking this as fixed based on the patch that steven points to. please reopen with some detail if that solution isn't workable. it persists the original path in the $_REQUEST['destination'] element

Anonymous’s picture

Status: Fixed » Closed (fixed)