Index: t3lib/config_default.php =================================================================== --- t3lib/config_default.php (revision 2939) +++ t3lib/config_default.php (working copy) @@ -202,6 +202,9 @@ 'compressionDebugInfo' => 0, // Boolean. If set, then in the end of the pages, the sizes of the compressed and non-compressed document is output. This should be used ONLY as a test, because the content is compressed twice in order to output this statistics! 'pageNotFound_handling' => '', // How TYPO3 should handle requests for non-existing/accessible pages. false (default): The 'nearest' page is shown. TRUE or '1': An TYPO3 error box is displayed. Strings: page to show (reads content and outputs with correct headers), eg. 'notfound.html' or 'http://www.domain.org/errors/notfound.html'. If prefixed "REDIRECT:" it will redirect to the URL/script after the prefix (original behaviour). If prefixed with "READFILE:" then it will expect the remaining string to be a HTML file which will be read and outputted directly after having the marker "###CURRENT_URL###" substituted with REQUEST_URI and ###REASON### with reason text, for example: "READFILE:fileadmin/notfound.html". Another option is the prefix "USER_FUNCTION:" which will call a user function, eg. "USER_FUNCTION:typo3conf/pageNotFoundHandling.php:user_pageNotFound->pageNotFound" where the file must contain a class "user_pageNotFound" with a method "pageNotFound" inside with two parameters, $param and $ref 'pageNotFound_handling_statheader' => 'HTTP/1.0 404 Not Found', // If 'pageNotFound_handling' is enabled, this string will always be sent as header before the actual handling. + 'pageUnavailable_handling' => '', // How TYPO3 should handle requests when pages are unavailable due to system problems. false (default): A static error message is displayed. Strings: page to show (reads content and outputs with correct headers), eg. 'unavailable.html' or 'http://www.domain.org/errors/unavailable.html'. If prefixed "REDIRECT:" it will redirect to the URL/script after the prefix (original behaviour). If prefixed with "READFILE:" then it will expect the remaining string to be a HTML file which will be read and outputted directly after having the marker "###CURRENT_URL###" substituted with REQUEST_URI and ###REASON### with reason text, for example: "READFILE:fileadmin/unavailable.html". Another option is the prefix "USER_FUNCTION:" which will call a user function, eg. "USER_FUNCTION:typo3conf/pageUnavailableHandling.php:user_pageUnavailable->pageUnavailable" where the file must contain a class "user_pageUnavailable" with a method "pageUnavailable" inside with two parameters, $param and $ref + 'pageUnavailable_handling_statheader' => 'HTTP/1.0 503 Service Temporarily Unavailable', // If 'pageUnavailable_handling' is enabled, this string will always be sent as header before the actual handling. + 'pageUnavailable_force' => 0, // Boolean. If true, pageUnavailable_handling is used for every frontend page. This is useful during temporary site maintenance. 'pageNotFoundOnCHashError' => 0, // Boolean. If true, a page not found call is made when cHash evaluation error occurs. By default they will just disable caching but still display page output. 'userFuncClassPrefix' => 'user_', // This prefix must be the first part of any function or class name called from TypoScript, for instance in the stdWrap function. 'addRootLineFields' => '', // Comma-list of fields from the 'pages'-table. These fields are added to the select query for fields in the rootline. Index: typo3/sysext/cms/tslib/class.tslib_fe.php =================================================================== --- typo3/sysext/cms/tslib/class.tslib_fe.php (revision 2939) +++ typo3/sysext/cms/tslib/class.tslib_fe.php (working copy) @@ -467,9 +467,13 @@ '; exit; } elseif (!$GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) { - header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); - $this->printError('Cannot connect to the current database, "'.TYPO3_db.'"','Database Error'); - exit; + if ($this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling']) { + $this->pageUnavailableAndExit('Cannot connect to the current database, "'.TYPO3_db.'"'); + } else { + header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); + $this->printError('Cannot connect to the current database, "'.TYPO3_db.'"','Database Error'); + exit; + } } } else { if (!TYPO3_db) { @@ -481,9 +485,14 @@ '; exit; } - header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); - $this->printError('The current username, password or host was not accepted when the connection to the database was attempted to be established!','Database Error'); - exit; + + if ($this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling']) { + $this->pageUnavailableAndExit('The current username, password or host was not accepted when the connection to the database was attempted to be established!'); + } else { + header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); + $this->printError('The current username, password or host was not accepted when the connection to the database was attempted to be established!','Database Error'); + exit; + } } @@ -895,10 +904,14 @@ if ($theFirstPage) { $this->id = $theFirstPage['uid']; } else { - header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); - t3lib_div::sysLog('No pages are found on the rootlevel!', 'cms', 3); - $this->printError('No pages are found on the rootlevel!'); - exit; + if ($this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling']) { + $this->pageUnavailableAndExit('No pages are found on the rootlevel!'); + } else { + header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); + t3lib_div::sysLog('No pages are found on the rootlevel!', 'cms', 3); + $this->printError('No pages are found on the rootlevel!'); + exit; + } } } } @@ -1008,10 +1021,14 @@ $this->rootLine = $this->sys_page->getRootLine($this->id,$this->MP); } if (!count($this->rootLine)) { - header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); - t3lib_div::sysLog('The requested page didn\'t have a proper connection to the tree-root! ('.$this->sys_page->error_getRootLine.')', 'cms', 3); - $this->printError('The requested page didn\'t have a proper connection to the tree-root!

('.$this->sys_page->error_getRootLine.')'); - exit; + if ($this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling']) { + $this->pageUnavailableAndExit('The requested page didn\'t have a proper connection to the tree-root!'); + } else { + header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); + t3lib_div::sysLog('The requested page didn\'t have a proper connection to the tree-root! ('.$this->sys_page->error_getRootLine.')', 'cms', 3); + $this->printError('The requested page didn\'t have a proper connection to the tree-root!

('.$this->sys_page->error_getRootLine.')'); + exit; + } } $this->fePreview = 1; } @@ -1019,10 +1036,14 @@ // Checking for include section regarding the hidden/starttime/endtime/fe_user (that is access control of a whole subbranch!) if ($this->checkRootlineForIncludeSection()) { if (!count($this->rootLine)) { - header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); - t3lib_div::sysLog('The requested page was not accessible!', 'cms', 3); - $this->printError('The requested page was not accessible!'); - exit; + if ($this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling']) { + $this->pageUnavailableAndExit('The requested page was not accesible!'); + } else { + header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); + t3lib_div::sysLog('The requested page was not accessible!', 'cms', 3); + $this->printError('The requested page was not accessible!'); + exit; + } } else { $el = reset($this->rootLine); $this->id = $el['uid']; @@ -1301,6 +1322,19 @@ return $this->sys_page->getDomainStartPage(t3lib_div::getIndpEnv('HTTP_HOST'),t3lib_div::getIndpEnv('SCRIPT_NAME'),t3lib_div::getIndpEnv('REQUEST_URI')); } } + + /** + * Page unavailable handler for use in frontend plugins from extensions. + * + * @param string Reason text + * @param string HTTP header to send + * @return void Function exits. + */ + function pageUnavailableAndExit($reason='', $header='') { + $header = $header ? $header : $this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling_statheader']; + $this->pageUnavailableHandler($this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling'], $header, $reason); + exit; + } /** * Page-not-found handler for use in frontend plugins from extensions. @@ -1314,9 +1348,33 @@ $this->pageNotFoundHandler($this->TYPO3_CONF_VARS['FE']['pageNotFound_handling'], $header, $reason); exit; } + + /** + * Page unavailable handler. Acts a wrapper for the pageErrorHandler method. + * + * @param mixed Which type of handling; If a true PHP-boolean or TRUE then a ->printError message is outputted. If integer an error message with that number is shown. Otherwise the $code value is expected to be a "Location:" header value. + * @param string If set, this is passed directly to the PHP function, header() + * @param string If set, error messages will also mention this as the reason for the page-not-found. + * @return void (The function exits!) + */ + function pageUnavailableHandler($code, $header, $reason) { + $this->pageErrorHandler($code, $header, $reason); + } + + /** + * Page not found handler. Acts a wrapper for the pageErrorHandler method. + * + * @param mixed Which type of handling; If a true PHP-boolean or TRUE then a ->printError message is outputted. If integer an error message with that number is shown. Otherwise the $code value is expected to be a "Location:" header value. + * @param string If set, this is passed directly to the PHP function, header() + * @param string If set, error messages will also mention this as the reason for the page-not-found. + * @return void (The function exits!) + */ + function pageNotFoundHandler($code, $header='', $reason='') { + $this->pageErrorHandler($code, $header, $reason); + } /** - * Page not found handler. + * Generic error page handler. * Exits. * * @param mixed Which type of handling; If a true PHP-boolean or TRUE then a ->printError message is outputted. If integer an error message with that number is shown. Otherwise the $code value is expected to be a "Location:" header value. @@ -1324,7 +1382,7 @@ * @param string If set, error messages will also mention this as the reason for the page-not-found. * @return void (The function exits!) */ - function pageNotFoundHandler($code, $header='', $reason='') { + function pageErrorHandler($code, $header='', $reason='') { // Issue header in any case: if ($header) { @@ -1842,10 +1900,14 @@ $this->pSetup = $this->tmpl->setup[$this->sPre.'.']; if (!is_array($this->pSetup)) { - header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); - t3lib_div::sysLog('The page is not configured! [type= '.$this->type.']['.$this->sPre.']', 'cms', 3); - $this->printError('The page is not configured! [type= '.$this->type.']['.$this->sPre.']'); - exit; + if ($this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling']) { + $this->pageUnavailableAndExit('The page is not configured! [type= '.$this->type.']['.$this->sPre.']'); + } else { + header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); + t3lib_div::sysLog('The page is not configured! [type= '.$this->type.']['.$this->sPre.']', 'cms', 3); + $this->printError('The page is not configured! [type= '.$this->type.']['.$this->sPre.']'); + exit; + } } else { $this->config['config']=Array(); @@ -1911,10 +1973,14 @@ } $GLOBALS['TT']->pull(); } else { - header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); - t3lib_div::sysLog('No template found!', 'cms', 3); - $this->printError('No template found!'); - exit; + if ($this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling']) { + $this->pageUnavailableAndExit('No template found!'); + } else { + header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); + t3lib_div::sysLog('No template found!', 'cms', 3); + $this->printError('No template found!'); + exit; + } } } @@ -1979,9 +2045,13 @@ if ($this->absRefPrefix_force && strcmp($this->config['config']['simulateStaticDocuments'],'PATH_INFO')) { $redirectUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_DIR').'index.php?id='.$this->id.'&type='.$this->type; if ($this->config['config']['simulateStaticDocuments_dontRedirectPathInfoError']) { - header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); - t3lib_div::sysLog('PATH_INFO was not configured for this website, and the URL tries to find the page by PATH_INFO!', 'cms', 3); - $this->printError('PATH_INFO was not configured for this website, and the URL tries to find the page by PATH_INFO!

Click here to get to the right page.','Error: PATH_INFO not configured'); + if ($this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling']) { + $this->pageUnavailableAndExit('PATH_INFO was not configured for this website, and the URL tries to find the page by PATH_INFO!'); + } else { + header( 'HTTP/1.0 503 Service Temporarily Unavailable' ); + t3lib_div::sysLog('PATH_INFO was not configured for this website, and the URL tries to find the page by PATH_INFO!', 'cms', 3); + $this->printError('PATH_INFO was not configured for this website, and the URL tries to find the page by PATH_INFO!

Click here to get to the right page.','Error: PATH_INFO not configured'); + } } else { header('Location: '.t3lib_div::locationHeaderUrl($redirectUrl)); } Index: typo3/sysext/cms/tslib/index_ts.php =================================================================== --- typo3/sysext/cms/tslib/index_ts.php (revision 2939) +++ typo3/sysext/cms/tslib/index_ts.php (working copy) @@ -163,6 +163,12 @@ t3lib_div::_GP('MP'), t3lib_div::_GP('RDCT') ); + +if($TYPO3_CONF_VARS['FE']['pageUnavailable_force']) { + $TSFE->pageUnavailableAndExit('This page is temporarily unavailable.'); +} + + $TSFE->connectToDB(); // In case of a keyword-authenticated preview, re-initialize the TSFE object: