Fatal error: Call to undefined function: drupal_goto()
| Project: | Path redirect |
| Version: | 5.x-1.x-dev |
| Component: | Code |
| Category: | bug report |
| Priority: | critical |
| Assigned: | Unassigned |
| Status: | closed |
Hi all,
I installed Path Redirect about a week ago on my site and today, out of the blue, anonymous users (caching is enabled) started getting this error:
Fatal error: Call to undefined function: drupal_goto() in /home/juice00/public_html/sites/all/modules/contrib/path_redirect/path_redirect.module on line 34
Authenticated users did not get the error.
I used Devel to clear the server cache but that didn't seem to help.
I then disabled path_redirect and cleared the cache again and the problem disappeared.
I love this module and want to continue using it so whatever I can do to help troubleshoot this problem ... I'm ready to help.
The site gets about 10,000 page views a day so it's moderately active.
TIA,
Kevin

#1
Fascinating.
Okay, my hypothesis is that you've got page caching enabled for anonymous users. And because of this, Drupal isn't doing enough of a bootstrap to load the drupal_goto().
I'll bet we should do something along the lines of
<?php
if (function_exists('drupal_goto')) {
// the normal drupal_goto() statement
}
else {
// we do our own redirect
}
?>
#2
...just so I've asked...
on the admin/settings/performance page, you have "Caching mode" set to "Normal" (and not "Aggressive"), right?
You'll be able to alleviate the immediate Fatal Error problem by turning "Caching mode" to "Disabled", by the way.
#3
Thanks Jeff,
Yeah, page caching was on (Normal, not Advanced).
I appreciate you taking a look at this.
Kevin
#4
Where you thinking about something along these lines?
<?phpif (function_exists('drupal_goto')) {
drupal_goto($r->redirect, ($r->query ? $r->query: NULL), ($r->fragment ? $r->fragment : NULL), $r->type);
}
else {
header("Location: $r->redirect");
}
?>
Kevin
#5
Do we need a warning somewhere in the admin interface to explain this to users?
#6
Yes. Pretty much, but I think we can put the redirect code, query, fragment, and redirect type into the non-drupal_goto() version.
#7
I don't know why we'd need to put a warning in. What would the warning say?
#8
Nix that; as long as it works the same way as
drupal_gotothere is no need for a warning. Here is a patch that doesn't work. Let's say I've got a redirect fromfoo/bartobaz/quux. This patch (based on kmillecam's suggestion) will send a location header:Location: baz/quux?query_string#fragmentLooks okay at first, but that's actually going to be treated as relative to the original path
foo/bar, resulting in a request forfoo/baz/quux?q#f.So what's the best way to make
$r->redirectbe relative to the root? Is it safe to callurl($r->redirect,...), or is that just as bad as callingdrupal_goto?Should we wrap this in a
path_redirect_gotofunction?#9
No, we basically just copy the drupal_goto() function into our module. We could even call it path_redirect_goto(). We can slim it down by removing the 'destination' code (the first few lines of the function.
http://api.drupal.org/api/function/drupal_goto/5
The main question that I've got is: if drupal_goto() hasn't been bootstrapped, then I'm guessing most other stuff hasn't been bootstrapped. The function attempts to run
module_invoke_all('exit', $url);and I'm guessing that will bomb out too.We should try to a) look at the bootstrap process and figure out if the modules are loaded enough to run invoke the 'exit' hooks when (not aggressive) page caching is enabled, or b) just drop the code in and see if we get an error! :-)
There are clues here:
http://api.drupal.org/api/function/bootstrap_hooks/5
and here
http://api.drupal.org/api/function/_drupal_cache_init/5
Hmmm... interesting... from _drupal_cache_init():
<?phpelseif (variable_get('cache', CACHE_DISABLED) == CACHE_NORMAL) {
require_once './includes/module.inc';
bootstrap_invoke_all('init');
drupal_page_cache_header($cache);
bootstrap_invoke_all('exit');
exit();
}
?>
It looks like the thing to do is to change drupal_goto()'s
module_invoke_all('exit')tobootstrap_invoke_all('exit');I'll whip up a patch for this as soon as I can.
#10
Okay here's a patch that I've tested and it's working with page caching. I'm going to commit it.
The patch adds a new function called path_redirect_goto(). This function gets called when drupal_goto() is unavailable.
(it also cleans up some extra spaces at the end of lines)
#11
Thanks Jeff!
I'll give it a spin.
Kevin
#12
Committed to dev version.
#13
After installing the latest dev version, I'm getting another error:
Fatal error: Call to undefined function: url() in /home/juice00/public_html/sites/all/modules/contrib/path_redirect/path_redirect.module on line 374
#14
I think this is what I was worried about in #8 above. It looks like
path_redirect_goto()relies onurl(), and I think if you don't havedrupal_goto(), you're not going to haveurl(), either. Sorry, I can't offer a patch at the moment.#15
Just wondering ... if we can't depend on Drupal functions loading, could we capture the base url when path_redirect is installed (or as part of the configuration settings)?
Then if drupal_goto() isn't available, it can fall back on the url from the settings.
Kevin
#16
I can't seem to reproduce the problem, but perhaps something like this will solve it. Maybe this is too simplistic, though;
url()is some 70 lines of code...#17
Status changed.
#18
I had to mangle a bunch of core files to simulate not having
drupal_goto()andurl()available, but once I managed that, this patch worked fine. Tested it with relative and absolute URLs, with and without query strings and fragments.I'd love to get 1.1 out the door once this is fixed!
#19
Committed #18. I'll consider this fixed, but please reopen if further testing reveals problems!
#20
Thanks HorsePunchKid,
I'll load the latest up and give it a try.
Kevin
#21
I've been running this version on a couple of production servers for about a week now. Everything looks good.
Thanks for the work guys.
#22
Automatically closed -- issue fixed for two weeks with no activity.
#23
I think this has been biting us at groups.drupal.org for some time now. I finally dug deep enough to find this error message and see the module has been fixed. Could we please issue a release soon? This was fixed in December.
#24
This is not fully fixed. This init hook is still calling url() even though common.inc is not loaded. See this clause
url($r->redirect) != url($path)
The error that results in my install is
02-May-2008 02:32:46] PHP Fatal error: Call to undefined function url() in /var/www/groups.drupal.org/htdocs/sites/all/modules/path_redirect/path_redirect.module on line 45
#25
what about moving all this code to hook_menu(!$may_cache). is a slight performance hit but at least we are all bootstrapped. this is exactly what the D6 version has chosen to do by implementing hook_init() versus the new hook_boot(). hook_boot() is the one that happens during the bootstrap. hook_init() always runs after full bootstrap in D6.
attached is a patch which implements this and gets rid of our workaround code for hook_init(). this is now running on groups.drupal.org.
#26
Excellent; thank you for digging into this issue. I'll test the patch. We've gotta get this fixed in the next release (1.3).
#27
I checked this patch and some of the above comments... and I'd like to say some things about this change. I learned in global_redirect that hook_init does not provide what you need at this early stage. You need url(), drupal_goto() and some other core functions only available at a later bootstrap. Therefor this should be kept in hook_menu in D5 and in D6 moved to hook_init. hook_init have all functions you need in D6, but not in D5 :-(. It's not optimal, but it works as it should.
I also thought about including all core files and duplicating functions and so on... but there are so many dependencies in path.inc that you will end up with much code and the benefit of duplicating the functions seems no more appropriate.
#28
Fatal error: Call to undefined function url() in ... path_redirect.module on line 45
5.x-1.2 (Latest 5/14/2008 release version) is still suffering from this problem. Any chance of getting a fix into a release in the near term?
#29
Agreement on it needing to be resolved, am experiencing this quite a bit.
Has anyone tried the change suggested by skcombs?
http://drupal.org/node/290221#comment-1155822
#30
I've had a fun time with the hook_menu(!$may_cache) and hook_init() with the 5.x version of my FeedBurner module, so I'm pretty sure I had a good understanding of the problem. I have committed the patch from #25 with a few small modifications. This should now be fixed. Thanks!
#31
Thanks Dave!
#32
Automatically closed -- issue fixed for 2 weeks with no activity.