From e8775320553b0431826910ff5f645a07a6cd742f Mon Sep 17 00:00:00 2001
From: samhemelryk
" . $message; + } + } + + switch ($this->page->state) { + case moodle_page::STATE_BEFORE_HEADER : + // No output yet it is safe to delivery the full arsenol of redirect methods + if (!$disableredirect) { + @header($_SERVER['SERVER_PROTOCOL'] . ' 303 See Other'); //302 might not work for POST requests, 303 is ignored by obsolete clients + @header('Location: '.$url); + $this->metarefreshtag = ''."\n"; + $this->page->requires->js_function_call('document.location.replace', array($url))->after_delay($delay+3); + } + $output = $this->header(); + $output .= $this->notification($message, $messageclass); + $output .= $this->footer(); + break; + case moodle_page::STATE_PRINTING_HEADER : + // We should hopefully never get here + throw new coding_exception('You cannot redirect while printing the page header'); + break; + case moodle_page::STATE_IN_BODY : + // We really shouldn't be here but we can deal with this + debugging("You should really redirect before you start page output"); + if (!$disableredirect) { + $this->page->requires->js_function_call('document.location.replace', array($url))->after_delay($delay+3); + } + $output = $this->opencontainers->pop_all_but_last(); + $output .= $this->notification($message, $messageclass); + $output .= $this->footer(); + break; + case moodle_page::STATE_DONE : + // Too late to be calling redirect now + throw new coding_exception('You cannot redirect after the entire page has been generated'); + break; + } + return $output; + } + // TODO remove $navigation and $menu arguments - replace with $PAGE->navigation public function header($navigation = '', $menu='') { global $USER, $CFG; @@ -1170,13 +1232,13 @@ class moodle_core_renderer extends moodle_renderer_base { $output = ''; - if ($this->opencontainers->count() == 0) { + if ($this->has_started()) { + $output .= $this->opencontainers->pop_all_but_last(); + } else { // Header not yet printed @header('HTTP/1.0 404 Not Found'); $this->page->set_title(get_string('error')); $output .= $this->header(); - } else { - $output .= $this->opencontainers->pop_all_but_last(); } $message = '
'. diff --git a/lib/weblib.php b/lib/weblib.php index 4aa9b3c5f2..689a193a4b 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -5654,61 +5654,40 @@ function notice_yesno ($message, $linkyes, $linkno, $optionsyes=NULL, $optionsno /** * Redirects the user to another page, after printing a notice * - * @todo '&' needs to be encoded into '&' for XHTML compliance, - * however, this is not true for javascript. Therefore we - * first decode all entities in $url (since we cannot rely on) - * the correct input) and then encode for where it's needed - * echo ""; + * This function calls the OUTPUT redirect method, echo's the output + * and then dies to ensure nothing else happens. + * + * Good practice: You should call this method before starting page + * output by using any of the OUTPUT methods. * - * @global object * @global object * @global object * @global object * @uses $_COOKIE * @uses DEBUG_DEVELOPER * @uses DEBUG_ALL - * @param string $url The url to take the user to - * @param string $message The text message to display to the user about the redirect, if any - * @param string $delay How long before refreshing to the new page at $url? - * @return void Dies + * @param string $url The URL to redirect to + * @param string $message The message to display to the user + * @param int $delay The delay before redirecting + * @return void */ function redirect($url, $message='', $delay=-1) { - global $CFG, $THEME, $SESSION, $PAGE; + global $OUTPUT, $SESSION, $CFG; if (!empty($CFG->usesid) && !isset($_COOKIE[session_name()])) { $url = $SESSION->sid_process_url($url); } - $message = clean_text($message); - - $encodedurl = preg_replace("/\&(?![a-zA-Z0-9#]{1,8};)/", "&", $url); - $encodedurl = preg_replace('/^.*href="([^"]*)".*$/', "\\1", clean_text('')); - $url = str_replace('&', '&', $encodedurl); - -/// At developer debug level. Don't redirect if errors have been printed on screen. -/// Currenly only works in PHP 5.2+; we do not want strict PHP5 errors - $lasterror = error_get_last(); - $error = defined('DEBUGGING_PRINTED') or (!empty($lasterror) && ($lasterror['type'] & DEBUG_DEVELOPER)); - $errorprinted = debugging('', DEBUG_ALL) && $CFG->debugdisplay && $error; - if ($errorprinted) { - $message = "Error output, so disabling automatic redirect." . $message; - } - - $performanceinfo = ''; - if (defined('MDL_PERF') || (!empty($CFG->perfdebug) and $CFG->perfdebug > 7)) { - if (defined('MDL_PERFTOLOG') && !function_exists('register_shutdown_function')) { - $perf = get_performance_info(); - error_log("PERF: " . $perf['txt']); + $usingmsg = false; + if ($message!=='') { + $usingmsg = true; + if ($delay===-1 || !is_numeric($delay)) { + $delay = 3; } - } - -/// when no message and header printed yet, try to redirect - if (empty($message) and !$PAGE->headerprinted) { - - // Technically, HTTP/1.1 requires Location: header to contain - // the absolute path. (In practice browsers accept relative - // paths - but still, might as well do it properly.) - // This code turns relative into absolute. + $message = clean_text($message); + } else { + $message = 'This page should redirect. If nothing is happening please click the continue button below.'; + $delay = 0; if (!preg_match('|^[a-z]+:|', $url)) { // Get host name http://www.wherever.com $hostpart = preg_replace('|^(.*?[^:/])/.*$|', '$1', $CFG->wwwroot); @@ -5728,39 +5707,24 @@ function redirect($url, $message='', $delay=-1) { $url = $newurl; } } - - $delay = 0; - //try header redirection first - @header($_SERVER['SERVER_PROTOCOL'] . ' 303 See Other'); //302 might not work for POST requests, 303 is ignored by obsolete clients - @header('Location: '.$url); - //another way for older browsers and already sent headers (eg trailing whitespace in config.php) - echo ''; - echo $PAGE->requires->js_function_call('document.location.replace', array($url))->asap(); - die; } - if ($delay == -1) { - $delay = 3; // if no delay specified wait 3 seconds - } - if (!$PAGE->headerprinted) { - // this type of redirect might not be working in some browsers - such as lynx :-( - print_header('', '', '', '', $errorprinted ? '' : ('')); - $delay += 3; // double redirect prevention, it was sometimes breaking upgrades before 1.7 - } else { - print_container_end_all(false, $THEME->open_header_containers); + $performanceinfo = ''; + if (defined('MDL_PERF') || (!empty($CFG->perfdebug) and $CFG->perfdebug > 7)) { + if (defined('MDL_PERFTOLOG') && !function_exists('register_shutdown_function')) { + $perf = get_performance_info(); + error_log("PERF: " . $perf['txt']); + } } - echo '