Added feature #7150: Add pageUnavailable_handling for system problems and maintenance
authorJeff Segars <jsegars@alumni.rice.edu>
Fri, 29 Feb 2008 03:47:31 +0000 (03:47 +0000)
committerJeff Segars <jsegars@alumni.rice.edu>
Fri, 29 Feb 2008 03:47:31 +0000 (03:47 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@3324 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/config_default.php
typo3/sysext/cms/tslib/class.tslib_fe.php
typo3/sysext/cms/tslib/index_ts.php

index c744ae7..ef54feb 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-02-28  Jeff Segars  <jeff@webempoweredchurch.org>
+
+       * Added feature #7150: Add pageUnavailable_handling for system problems and maintenance
+
 2008-02-28  Stanislas Rolland  <stanislas.rolland@fructifor.ca>
 
        * Fixed bug #7684: htmlArea RTE: Cursor positioning when creating new table
index 3ccdc4a..1e6882e 100755 (executable)
@@ -211,6 +211,9 @@ $TYPO3_CONF_VARS = Array(
                '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.
                '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.
+               '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. If the client matches TYPO3_CONF_VARS[SYS][devIPmask], this setting is ignored and the page is shown as normal.
+               '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. If the client matches TYPO3_CONF_VARS[SYS][devIPmask], the page is shown as normal. This is useful during temporary site maintenance. 
                '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.
                'checkFeUserPid' => 1,                                  // Boolean. If set, the pid of fe_user logins must be sent in the form as the field 'pid' and then the user must be located in the pid. If you unset this, you should change the fe_users.username eval-flag 'uniqueInPid' to 'unique' in $TCA. This will do: $TCA['fe_users']['columns']['username']['config']['eval']= 'nospace,lower,required,unique';
index b680586..3910b6a 100755 (executable)
@@ -480,9 +480,13 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
                                        </script>';
                                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->checkPageUnavailableHandler())       {
+                                       $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)  {
@@ -494,9 +498,14 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
                                        </script>';
                                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->checkPageUnavailableHandler())       {
+                               $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;
+                       }
                }
 
 
@@ -912,10 +921,14 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
                                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->checkPageUnavailableHandler())       {
+                                               $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;
+                                       }
                                }
                        }
                }
@@ -1025,10 +1038,14 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
                                $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! <br /><br />('.$this->sys_page->error_getRootLine.')');
-                               exit;
+                               if ($this->checkPageUnavailableHandler())       {
+                                       $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! <br /><br />('.$this->sys_page->error_getRootLine.')');
+                                       exit;
+                               }
                        }
                        $this->fePreview = 1;
                }
@@ -1036,10 +1053,14 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
                        // 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->checkPageUnavailableHandler())       {
+                                       $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'];
@@ -1318,6 +1339,19 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
                        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.
@@ -1331,9 +1365,50 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
                $this->pageNotFoundHandler($this->TYPO3_CONF_VARS['FE']['pageNotFound_handling'], $header, $reason);
                exit;
        }
+       
+       /**
+        * Checks whether the pageUnavailableHandler should be used. To be used, pageUnavailable_handling must be set
+        * and devIPMask must not match the current visitor's IP address.
+        *
+        * @return      boolean         True/false whether the pageUnavailable_handler should be used.
+        */
+       function checkPageUnavailableHandler()  {
+               if($this->TYPO3_CONF_VARS['FE']['pageUnavailable_handling'] &&
+                  !t3lib_div::cmpIP(t3lib_div::getIndpEnv('REMOTE_ADDR'), $this->TYPO3_CONF_VARS['SYS']['devIPmask'])) {
+                       $checkPageUnavailableHandler = TRUE;
+               } else {
+                       $checkPageUnavailableHandler = FALSE;
+               }
+               
+               return $checkPageUnavailableHandler;
+       }
+       
+       /**
+        * 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.
@@ -1341,7 +1416,7 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
         * @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)    {
@@ -1916,10 +1991,14 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
                                $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->checkPageUnavailableHandler())       {
+                                               $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();
 
@@ -1989,10 +2068,14 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
                                }
                                $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->checkPageUnavailableHandler())       {
+                                       $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;
+                               }
                        }
                }
 
@@ -2057,9 +2140,13 @@ require_once (PATH_t3lib.'class.t3lib_lock.php');
                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!<br /><br /><a href="'.htmlspecialchars($redirectUrl).'">Click here to get to the right page.</a>','Error: PATH_INFO not configured');
+                               if ($this->checkPageUnavailableHandler())       {
+                                       $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!<br /><br /><a href="'.htmlspecialchars($redirectUrl).'">Click here to get to the right page.</a>','Error: PATH_INFO not configured');
+                               }
                        } else {
                                header('Location: '.t3lib_div::locationHeaderUrl($redirectUrl));
                        }
index af3a7c8..ca457de 100755 (executable)
@@ -166,6 +166,13 @@ $TSFE = new $temp_TSFEclassName(
                t3lib_div::_GP('MP'),
                t3lib_div::_GP('RDCT')
        );
+
+if($TYPO3_CONF_VARS['FE']['pageUnavailable_force'] && 
+   !t3lib_div::cmpIP(t3lib_div::getIndpEnv('REMOTE_ADDR'), $TYPO3_CONF_VARS['SYS']['devIPmask'])) {
+       $TSFE->pageUnavailableAndExit('This page is temporarily unavailable.');
+}
+       
+       
 $TSFE->connectToDB();
 
        // In case of a keyword-authenticated preview, re-initialize the TSFE object: