| Index: trunk/phase3/includes/DefaultSettings.php |
| — | — | @@ -2854,3 +2854,13 @@ |
| 2855 | 2855 | $wgParserConf = array( |
| 2856 | 2856 | 'class' => 'Parser', |
| 2857 | 2857 | ); |
| | 2858 | + |
| | 2859 | +/** |
| | 2860 | + * Hooks that are used for outputting exceptions |
| | 2861 | + * Format is: |
| | 2862 | + * $wgExceptionHooks[] = $funcname |
| | 2863 | + * or: |
| | 2864 | + * $wgExceptionHooks[] = array( $class, $funcname ) |
| | 2865 | + * Hooks should return strings or false |
| | 2866 | + */ |
| | 2867 | +$wgExceptionHooks = array(); |
| \ No newline at end of file |
| Index: trunk/phase3/includes/Exception.php |
| — | — | @@ -16,6 +16,26 @@ |
| 17 | 17 | return is_object( $wgLang ); |
| 18 | 18 | } |
| 19 | 19 | |
| | 20 | + function runHooks( $name, $args = array() ) { |
| | 21 | + global $wgExceptionHooks; |
| | 22 | + if( !isset( $wgExceptionHooks ) || !is_array( $wgExceptionHooks ) ) |
| | 23 | + return; // Just silently ignore |
| | 24 | + if( !array_key_exists( $name, $wgExceptionHooks ) || !is_array( $wgExceptionHooks[ $name ] ) ) |
| | 25 | + return; |
| | 26 | + $hooks = $wgExceptionHooks[ $name ]; |
| | 27 | + $callargs = array_merge( array( $this ), $args ); |
| | 28 | + |
| | 29 | + foreach( $hooks as $hook ) { |
| | 30 | + if( is_string( $hook ) || ( is_array( $hook ) && count( $hook ) >= 2 && is_string( $hook[0] ) ) ) { //'function' or array( 'class', hook' ) |
| | 31 | + $result = call_user_func_array( $hook, $callargs ); |
| | 32 | + } else { |
| | 33 | + $result = null; |
| | 34 | + } |
| | 35 | + if( is_string( $result ) ) |
| | 36 | + return $result; |
| | 37 | + } |
| | 38 | + } |
| | 39 | + |
| 20 | 40 | /** Get a message from i18n */ |
| 21 | 41 | function msg( $key, $fallback /*[, params...] */ ) { |
| 22 | 42 | $args = array_slice( func_get_args(), 2 ); |
| — | — | @@ -83,9 +103,16 @@ |
| 84 | 104 | $wgOut->enableClientCache( false ); |
| 85 | 105 | $wgOut->redirect( '' ); |
| 86 | 106 | $wgOut->clearHTML(); |
| 87 | | - $wgOut->addHTML( $this->getHTML() ); |
| | 107 | + if( $hookResult = $this->runHooks( get_class( $this ) ) ) { |
| | 108 | + $wgOut->addHTML( $hookResult ); |
| | 109 | + } else { |
| | 110 | + $wgOut->addHTML( $this->getHTML() ); |
| | 111 | + } |
| 88 | 112 | $wgOut->output(); |
| 89 | 113 | } else { |
| | 114 | + if( $hookResult = $this->runHooks( get_class( $this ) . "Raw" ) ) { |
| | 115 | + die( $hookResult ); |
| | 116 | + } |
| 90 | 117 | echo $this->htmlHeader(); |
| 91 | 118 | echo $this->getHTML(); |
| 92 | 119 | echo $this->htmlFooter(); |
| — | — | @@ -131,7 +158,6 @@ |
| 132 | 159 | function htmlFooter() { |
| 133 | 160 | echo "</body></html>"; |
| 134 | 161 | } |
| 135 | | - |
| 136 | 162 | } |
| 137 | 163 | |
| 138 | 164 | /** |
| Index: trunk/phase3/RELEASE-NOTES |
| — | — | @@ -121,6 +121,7 @@ |
| 122 | 122 | * Allow subpage syntax for Special:Userrights, i.e., Special:Userrights/Name. |
| 123 | 123 | * When submitting changes on Special:Userrights, show the full form again, not |
| 124 | 124 | just the search box. |
| | 125 | +* Added exception hooks |
| 125 | 126 | |
| 126 | 127 | |
| 127 | 128 | === Bug fixes in 1.12 === |
| Index: trunk/extensions/examples/ErrorPage/dberr.html |
| — | — | @@ -0,0 +1,40 @@ |
| | 2 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| | 3 | +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> |
| | 4 | + <head> |
| | 5 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
| | 6 | + <title>Database error</title> |
| | 7 | + <style type="text/css" media="screen, projection">/*<![CDATA[*/ |
| | 8 | + @import "{{skins}}/common/shared.css?104"; |
| | 9 | + @import "{{skins}}/monobook/main.css?104"; |
| | 10 | + /*]]>*/</style> |
| | 11 | + </head> |
| | 12 | + <body class="mediawiki"> |
| | 13 | + <div id="globalWrapper"> |
| | 14 | + <div id="column-content"> |
| | 15 | + <div id="content"> |
| | 16 | + <h1> |
| | 17 | + Database error |
| | 18 | + </h1> |
| | 19 | + <div id="bodyContent"> |
| | 20 | + <p><strong>Database error was happend</strong></P> |
| | 21 | + <p>Last database query: <code>{{sql}}</code></p> |
| | 22 | + <p>Function: <code>{{function}}</code></p> |
| | 23 | + <p>MySQL error: <code>{{errno}}: {{error}}</code></p> |
| | 24 | + </div> |
| | 25 | + </div> |
| | 26 | + </div> |
| | 27 | + <div id="column-one"> |
| | 28 | + <div class="portlet" id="p-logo"> |
| | 29 | + <img src="{{logo}}" alt="{{sitename}} logo" style="float:left;margin-right:1em" /> |
| | 30 | + </div> |
| | 31 | + </div> |
| | 32 | + <div class="visualClear"></div> |
| | 33 | + <div id="footer"> |
| | 34 | + <div id="f-poweredbyico"> |
| | 35 | + <a href="http://www.mediawiki.org/"><img src="{{skins}}/common/images/poweredby_mediawiki_88x31.png" alt="Powered by MediaWiki" /></a> |
| | 36 | + </div> |
| | 37 | + <p>Generated on {{now}} — <a href="irc://irc.freenode.net/#wikimedia-tech" class="link-irc">Technical IRC channel</a></p> |
| | 38 | + </div> |
| | 39 | + </div> |
| | 40 | + </body> |
| | 41 | +</html> |
| \ No newline at end of file |
| Index: trunk/extensions/examples/ErrorPage/dbconn.html |
| — | — | @@ -0,0 +1,40 @@ |
| | 2 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| | 3 | +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> |
| | 4 | + <head> |
| | 5 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
| | 6 | + <title>Wikimedia has some problems with database servers</title> |
| | 7 | + <style type="text/css" media="screen, projection">/*<![CDATA[*/ |
| | 8 | + @import "{{skins}}/common/shared.css?104"; |
| | 9 | + @import "{{skins}}/monobook/main.css?104"; |
| | 10 | + /*]]>*/</style> |
| | 11 | + </head> |
| | 12 | + <body class="mediawiki"> |
| | 13 | + <div id="globalWrapper"> |
| | 14 | + <div id="column-content"> |
| | 15 | + <div id="content"> |
| | 16 | + <h1> |
| | 17 | + Wikimedia has some problems with database servers |
| | 18 | + </h1> |
| | 19 | + <div id="bodyContent"> |
| | 20 | + <p style="font-weight: bold; font-size: 15px">Sorry! This site is experiencing technical difficulties.</p> |
| | 21 | + <p>Try waiting a few minutes and reloading.</p> |
| | 22 | + <p>If you report us about this error, please provide following information:</p> |
| | 23 | + <p><code>Error: {{dberror}}</code></p> |
| | 24 | + </div> |
| | 25 | + </div> |
| | 26 | + </div> |
| | 27 | + <div id="column-one"> |
| | 28 | + <div class="portlet" id="p-logo"> |
| | 29 | + <img src="{{logo}}" alt="{{sitename}} logo" style="float:left;margin-right:1em" /> |
| | 30 | + </div> |
| | 31 | + </div> |
| | 32 | + <div class="visualClear"></div> |
| | 33 | + <div id="footer"> |
| | 34 | + <div id="f-poweredbyico"> |
| | 35 | + <a href="http://www.mediawiki.org/"><img src="{{skins}}/common/images/poweredby_mediawiki_88x31.png" alt="Powered by MediaWiki" /></a> |
| | 36 | + </div> |
| | 37 | + <p>Generated on {{now}} — <a href="http://wikimediafoundation.org/wiki/Donate/en">Donate</a> — <a href="irc://irc.freenode.net/#wikimedia-tech" class="link-irc">Technical IRC channel</a></p> |
| | 38 | + </div> |
| | 39 | + </div> |
| | 40 | + </body> |
| | 41 | +</html> |
| \ No newline at end of file |
| Index: trunk/extensions/examples/ErrorPage/NiceErrorPage.php |
| — | — | @@ -0,0 +1,60 @@ |
| | 2 | +<?php |
| | 3 | + |
| | 4 | +/** |
| | 5 | + * Example of the page that uses extensions hooks for |
| | 6 | + * making nice error page. |
| | 7 | + * |
| | 8 | + * @author VasilievVV |
| | 9 | + * @license GNU GPL 2 or later |
| | 10 | + */ |
| | 11 | + |
| | 12 | +//$wgExceptionHooks['DBConnectionErrorRaw'][] = array( 'NiceErrorPage', 'dbConnectionOP' ); |
| | 13 | +$wgExceptionHooks['DBConnectionErrorRaw'][] = array( 'NiceErrorPage', 'dbConnection' ); |
| | 14 | +$wgExceptionHooks['DBQueryErrorRaw'][] = array( 'NiceErrorPage', 'dbQueryError' ); |
| | 15 | + |
| | 16 | +$wgNiceErrorPagePath = "{$wgServer}{$wgScriptPath}/extensions/examples/ErrorPage"; |
| | 17 | + |
| | 18 | +class NiceErrorPage { |
| | 19 | + static function dbConnection( $error ) { |
| | 20 | + if ( trim( $error->error ) == '' ) { |
| | 21 | + $error->error = $error->db->getProperty('mServer'); |
| | 22 | + } |
| | 23 | + return self::preprocessPage( 'dbconn', array( 'dberror' => $error->error ) ); |
| | 24 | + } |
| | 25 | + |
| | 26 | + static function dbQueryError( $error ) { |
| | 27 | + $args = array( |
| | 28 | + 'sql' => $error->getSQL(), |
| | 29 | + 'function' => $error->fname, |
| | 30 | + 'errno' => $error->errno, |
| | 31 | + 'error' => $error->error, |
| | 32 | + ); |
| | 33 | + return self::preprocessPage( 'dberr', $args ); |
| | 34 | + } |
| | 35 | + |
| | 36 | + static function preprocessPage( $name, $args = array() ) { |
| | 37 | + $page = file_get_contents( dirname( __FILE__ ) . "/{$name}.html" ); |
| | 38 | + $args = array_merge( self::commonArgs(), $args ); |
| | 39 | + foreach( $args as $aname => $aval ) { |
| | 40 | + $page = preg_replace( '/{{' . $aname . '}}/i', $aval, $page ); |
| | 41 | + } |
| | 42 | + return $page; |
| | 43 | + } |
| | 44 | + |
| | 45 | + static function commonArgs() { |
| | 46 | + global $wgNiceErrorPagePath, $wgLogo, $wgSitename, $wgServer, $wgScriptPath; |
| | 47 | + $a = array( |
| | 48 | + 'basepath' => $wgNiceErrorPagePath, |
| | 49 | + 'logo' => $wgLogo, |
| | 50 | + 'now' => wfTimestamp( TS_RFC2822 ), |
| | 51 | + 'sitename' => $wgSitename, |
| | 52 | + 'skins' => "{$wgServer}{$wgScriptPath}/skins", |
| | 53 | + ); |
| | 54 | + return $a; |
| | 55 | + } |
| | 56 | + |
| | 57 | + static function __call( $method, $args ) { |
| | 58 | + $name = str_replace( 'OP', '', $method ); |
| | 59 | + return $this->$name( $args[0] ); |
| | 60 | + } |
| | 61 | +} |
| \ No newline at end of file |
| Property changes on: trunk/extensions/examples/ErrorPage/NiceErrorPage.php |
| ___________________________________________________________________ |
| Name: svn:eol-style |
| 1 | 62 | + native |