diff --git a/boost.api.inc b/boost.api.inc index 2313a24c63efbaf468b647d310d2c10a87ee00c7..5fd192537a5694b3ad7848dbd8603148bd1aa411 100644 --- a/boost.api.inc +++ b/boost.api.inc @@ -43,6 +43,18 @@ function boost_is_cacheable($path) { return !(BOOST_CACHEABILITY_OPTION xor preg_match($regexp, $alias)); } +/** + * Determines whether a given Drupal page is currently cached or not. + */ +function boost_is_cached($path) { + $path = (empty($path) ? BOOST_FRONTPAGE : $path); + $alias = drupal_get_path_alias($path); + $path = drupal_get_normal_path($path); // normalize path + + // TODO: also determine if alias/symlink exists? + return file_exists(boost_file_path($path)); +} + /** * Deletes all static files currently in the cache. */ diff --git a/boost.module b/boost.module index 0c13cb73e3da4bb7ee861a6e307c7e20bce46ec9..68998ceb6ef8e3f0b314d17f6e6239035ae84ad3 100644 --- a/boost.module +++ b/boost.module @@ -114,6 +114,47 @@ function boost_init() { } } +/** + * Implementation of hook_exit(). Performs cleanup tasks. + * + * For POST requests by anonymous visitors, this adds a dummy query string + * to any URL being redirected to using drupal_goto(). + * + * This is pretty much a hack that assumes a bit too much familiarity with + * what happens under the hood of the Drupal core function drupal_goto(). + * + * It's necessary, though, in order for any session messages set on form + * submission to actually show up on the next page if that page has been + * cached by Boost. + */ +function boost_exit($destination = NULL) { + // Check that hook_exit() was invoked by drupal_goto() for a POST request: + if (!empty($destination) && $_SERVER['REQUEST_METHOD'] == 'POST') { + + // Check that we're dealing with an anonymous visitor. and that some + // session messages have actually been set during this page request: + global $user; + if (empty($user->uid) && ($messages = drupal_set_message())) { + + // Check that the page we're redirecting to has been cached by Boost + // and really necessitates special handling: + extract(parse_url($destination)); + $path = ($path == base_path() ? '' : substr($path, strlen(base_path()))); + if (boost_is_cached($path) && empty($query)) { + // FIXME: call any remaining exit hooks since we're about to terminate. + + // Add a query string to ensure we don't serve a static copy of + // the page we're redirecting to, which would prevent the session + // messages from showing up: + $destination = url($path, 't=' . time(), $fragment, TRUE); + + // Do what drupal_goto() would do if we were to return to it: + exit(header('Location: ' . $destination)); + } + } + } +} + /** * Implementation of hook_form_alter(). Performs alterations before a form * is rendered.