MediaWiki  REL1_19
Debug.php
Go to the documentation of this file.
00001 <?php
00002 
00011 class MWDebug {
00012 
00018         protected static $log = array();
00019 
00025         protected static $debug = array();
00026 
00032         protected static $query = array();
00033 
00039         protected static $enabled = false;
00040 
00047         protected static $deprecationWarnings = array();
00048 
00053         public static function init() {
00054                 self::$enabled = true;
00055         }
00056 
00063         public static function addModules( OutputPage $out ) {
00064                 if ( self::$enabled ) {
00065                         $out->addModules( 'mediawiki.debug.init' );
00066                 }
00067         }
00068 
00076         public static function log( $str ) {
00077                 if ( !self::$enabled ) {
00078                         return;
00079                 }
00080 
00081                 self::$log[] = array(
00082                         'msg' => htmlspecialchars( $str ),
00083                         'type' => 'log',
00084                         'caller' => wfGetCaller(),
00085                 );
00086         }
00087 
00091         public static function getLog() {
00092                 return self::$log;
00093         }
00094 
00098         public static function clearLog() {
00099                 self::$log = array();
00100                 self::$deprecationWarnings = array();
00101         }
00102 
00110         public static function warning( $msg, $callerOffset = 1 ) {
00111                 if ( !self::$enabled ) {
00112                         return;
00113                 }
00114 
00115                 // Check to see if there was already a deprecation notice, so not to
00116                 // get a duplicate warning
00117                 $logCount = count( self::$log );
00118                 if ( $logCount ) {
00119                         $lastLog = self::$log[ $logCount - 1 ];
00120                         if ( $lastLog['type'] == 'deprecated' && $lastLog['caller'] == wfGetCaller( $callerOffset + 1 ) ) {
00121                                 return;
00122                         }
00123                 }
00124 
00125                 self::$log[] = array(
00126                         'msg' => htmlspecialchars( $msg ),
00127                         'type' => 'warn',
00128                         'caller' => wfGetCaller( $callerOffset ),
00129                 );
00130         }
00131 
00140         public static function deprecated( $function, $version, $component ) {
00141                 if ( !self::$enabled ) {
00142                         return;
00143                 }
00144 
00145                 // Chain: This function -> wfDeprecated -> deprecatedFunction -> caller
00146                 $caller = wfGetCaller( 4 );
00147 
00148                 // Check to see if there already was a warning about this function
00149                 $functionString = "$function-$caller";
00150                 if ( in_array( $functionString, self::$deprecationWarnings ) ) {
00151                         return;
00152                 }
00153 
00154                 $version = $version === false ? '(unknown version)' : $version;
00155                 $component = $component === false ? 'MediaWiki' : $component;
00156                 $msg = htmlspecialchars( "Use of function $function was deprecated in $component $version" );
00157                 $msg .= Html::rawElement( 'div', array( 'class' => 'mw-debug-backtrace' ),
00158                         Html::element( 'span', array(), 'Backtrace:' )
00159                          . wfBacktrace()
00160                 );
00161 
00162                 self::$deprecationWarnings[] = $functionString;
00163                 self::$log[] = array(
00164                         'msg' => $msg,
00165                         'type' => 'deprecated',
00166                         'caller' => $caller,
00167                 );
00168         }
00169 
00176         public static function debugMsg( $str ) {
00177                 if ( !self::$enabled ) {
00178                         return;
00179                 }
00180 
00181                 self::$debug[] = trim( $str );
00182         }
00183 
00193         public static function query( $sql, $function, $isMaster ) {
00194                 if ( !self::$enabled ) {
00195                         return -1;
00196                 }
00197 
00198                 self::$query[] = array(
00199                         'sql' => $sql,
00200                         'function' => $function,
00201                         'master' => (bool) $isMaster,
00202                         'time' => 0.0,
00203                         '_start' => microtime( true ),
00204                 );
00205 
00206                 return count( self::$query ) - 1;
00207         }
00208 
00214         public static function queryTime( $id ) {
00215                 if ( $id === -1 || !self::$enabled ) {
00216                         return;
00217                 }
00218 
00219                 self::$query[$id]['time'] = microtime( true ) - self::$query[$id]['_start'];
00220                 unset( self::$query[$id]['_start'] );
00221         }
00222 
00229         protected static function getFilesIncluded( IContextSource $context ) {
00230                 $files = get_included_files();
00231                 $fileList = array();
00232                 foreach ( $files as $file ) {
00233                         $size = filesize( $file );
00234                         $fileList[] = array(
00235                                 'name' => $file,
00236                                 'size' => $context->getLanguage()->formatSize( $size ),
00237                         );
00238                 }
00239 
00240                 return $fileList;
00241         }
00242 
00249         public static function getDebugHTML( IContextSource $context ) {
00250                 if ( !self::$enabled ) {
00251                         return '';
00252                 }
00253 
00254                 global $wgVersion, $wgRequestTime;
00255                 MWDebug::log( 'MWDebug output complete' );
00256                 $request = $context->getRequest();
00257                 $debugInfo = array(
00258                         'mwVersion' => $wgVersion,
00259                         'phpVersion' => PHP_VERSION,
00260                         'time' => microtime( true ) - $wgRequestTime,
00261                         'log' => self::$log,
00262                         'debugLog' => self::$debug,
00263                         'queries' => self::$query,
00264                         'request' => array(
00265                                 'method' => $_SERVER['REQUEST_METHOD'],
00266                                 'url' => $request->getRequestURL(),
00267                                 'headers' => $request->getAllHeaders(),
00268                                 'params' => $request->getValues(),
00269                         ),
00270                         'memory' => $context->getLanguage()->formatSize( memory_get_usage() ),
00271                         'memoryPeak' => $context->getLanguage()->formatSize( memory_get_peak_usage() ),
00272                         'includes' => self::getFilesIncluded( $context ),
00273                 );
00274 
00275                 // Cannot use OutputPage::addJsConfigVars because those are already outputted
00276                 // by the time this method is called.
00277                 $html = Html::inlineScript(
00278                         ResourceLoader::makeLoaderConditionalScript(
00279                                 ResourceLoader::makeConfigSetScript( array( 'debugInfo' => $debugInfo ) )
00280                         )
00281                 );
00282 
00283                 return $html;
00284         }
00285 }