<?php
+/**
+ * Debug toolbar related code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* New debugger system that outputs a toolbar on page view
*
+ * By default, most methods do nothing ( self::$enabled = false ). You have
+ * to explicitly call MWDebug::init() to enabled them.
+ *
* @todo Profiler support
+ *
+ * @since 1.19
*/
class MWDebug {
*/
protected static $query = array();
- /**
- * Request information
- *
- * @var array
- */
- protected static $request = array();
-
/**
* Is the debugger enabled?
*
* @var bool
*/
- protected static $enabled = true;
+ protected static $enabled = false;
/**
* Array of functions that have already been warned, formatted
protected static $deprecationWarnings = array();
/**
- * Called in Setup.php, initializes the debugger if it is enabled with
- * $wgDebugToolbar
+ * Enabled the debugger and load resource module.
+ * This is called by Setup.php when $wgDebugToolbar is true.
+ *
+ * @since 1.19
*/
public static function init() {
- global $wgDebugToolbar;
+ self::$enabled = true;
+ }
- if ( !$wgDebugToolbar ) {
- self::$enabled = false;
- return;
+ /**
+ * Add ResourceLoader modules to the OutputPage object if debugging is
+ * enabled.
+ *
+ * @since 1.19
+ * @param $out OutputPage
+ */
+ public static function addModules( OutputPage $out ) {
+ if ( self::$enabled ) {
+ $out->addModules( 'mediawiki.debug.init' );
}
-
- RequestContext::getMain()->getOutput()->addModules( 'mediawiki.debug' );
}
/**
*
* @todo Add support for passing objects
*
+ * @since 1.19
* @param $str string
*/
public static function log( $str ) {
);
}
+ /**
+ * Returns internal log array
+ * @since 1.19
+ * @return array
+ */
+ public static function getLog() {
+ return self::$log;
+ }
+
+ /**
+ * Clears internal log array and deprecation tracking
+ * @since 1.19
+ */
+ public static function clearLog() {
+ self::$log = array();
+ self::$deprecationWarnings = array();
+ }
+
/**
* Adds a warning entry to the log
*
+ * @since 1.19
* @param $msg
* @param int $callerOffset
* @return mixed
// Check to see if there was already a deprecation notice, so not to
// get a duplicate warning
- $lastLog = self::$log[ count( self::$log ) - 1 ];
- if ( $lastLog['type'] == 'deprecated' && $lastLog['caller'] == wfGetCaller( $callerOffset + 1 ) ) {
- return;
+ $logCount = count( self::$log );
+ $caller = wfGetCaller( $callerOffset + 1 );
+ if ( $logCount ) {
+ $lastLog = self::$log[ $logCount - 1 ];
+ if ( $lastLog['type'] == 'deprecated' && $lastLog['caller'] == $caller ) {
+ return;
+ }
}
self::$log[] = array(
'msg' => htmlspecialchars( $msg ),
'type' => 'warn',
- 'caller' => wfGetCaller( $callerOffset ),
+ 'caller' => $caller,
);
}
/**
* Adds a depreciation entry to the log, along with a backtrace
*
+ * @since 1.19
* @param $function
* @param $version
* @param $component
* This is a method to pass messages from wfDebug to the pretty debugger.
* Do NOT use this method, use MWDebug::log or wfDebug()
*
+ * @since 1.19
* @param $str string
*/
public static function debugMsg( $str ) {
/**
* Begins profiling on a database query
*
+ * @since 1.19
* @param $sql string
* @param $function string
* @param $isMaster bool
'sql' => $sql,
'function' => $function,
'master' => (bool) $isMaster,
- 'time' > 0.0,
- '_start' => wfTime(),
+ 'time' => 0.0,
+ '_start' => microtime( true ),
);
return count( self::$query ) - 1;
/**
* Calculates how long a query took.
*
+ * @since 1.19
* @param $id int
*/
public static function queryTime( $id ) {
return;
}
- self::$query[$id]['time'] = wfTime() - self::$query[$id]['_start'];
+ self::$query[$id]['time'] = microtime( true ) - self::$query[$id]['_start'];
unset( self::$query[$id]['_start'] );
}
- /**
- * Processes a WebRequest object
- *
- * @param $request WebRequest
- */
- public static function processRequest( WebRequest $request ) {
- if ( !self::$enabled ) {
- return;
- }
-
- self::$request = array(
- 'method' => $_SERVER['REQUEST_METHOD'],
- 'url' => $request->getRequestURL(),
- 'headers' => $request->getAllHeaders(),
- 'params' => $request->getValues(),
- );
- }
-
/**
* Returns a list of files included, along with their size
*
/**
* Returns the HTML to add to the page for the toolbar
*
+ * @since 1.19
* @param $context IContextSource
* @return string
*/
return '';
}
- global $wgVersion, $wgRequestTime;
MWDebug::log( 'MWDebug output complete' );
- $debugInfo = array(
+ $debugInfo = self::getDebugInfo( $context );
+
+ // Cannot use OutputPage::addJsConfigVars because those are already outputted
+ // by the time this method is called.
+ $html = Html::inlineScript(
+ ResourceLoader::makeLoaderConditionalScript(
+ ResourceLoader::makeConfigSetScript( array( 'debugInfo' => $debugInfo ) )
+ )
+ );
+
+ return $html;
+ }
+
+ /**
+ * Append the debug info to given ApiResult
+ *
+ * @param $context IContextSource
+ * @param $result ApiResult
+ */
+ public static function appendDebugInfoToApiResult( IContextSource $context, ApiResult $result ) {
+ if ( !self::$enabled ) {
+ return;
+ }
+
+ MWDebug::log( 'MWDebug output complete' );
+ $debugInfo = self::getDebugInfo( $context );
+
+ $result->setIndexedTagName( $debugInfo, 'debuginfo' );
+ $result->setIndexedTagName( $debugInfo['log'], 'line' );
+ foreach( $debugInfo['debugLog'] as $index => $debugLogText ) {
+ $vals = array();
+ ApiResult::setContent( $vals, $debugLogText );
+ $debugInfo['debugLog'][$index] = $vals; //replace
+ }
+ $result->setIndexedTagName( $debugInfo['debugLog'], 'msg' );
+ $result->setIndexedTagName( $debugInfo['queries'], 'query' );
+ $result->setIndexedTagName( $debugInfo['includes'], 'queries' );
+ $result->addValue( array(), 'debuginfo', $debugInfo );
+ }
+
+ /**
+ * Returns the HTML to add to the page for the toolbar
+ *
+ * @param $context IContextSource
+ * @return array
+ */
+ public static function getDebugInfo( IContextSource $context ) {
+ if ( !self::$enabled ) {
+ return array();
+ }
+
+ global $wgVersion, $wgRequestTime;
+ $request = $context->getRequest();
+ return array(
'mwVersion' => $wgVersion,
'phpVersion' => PHP_VERSION,
- 'time' => wfTime() - $wgRequestTime,
+ 'gitRevision' => GitInfo::headSHA1(),
+ 'gitBranch' => GitInfo::currentBranch(),
+ 'gitViewUrl' => GitInfo::headViewUrl(),
+ 'time' => microtime( true ) - $wgRequestTime,
'log' => self::$log,
'debugLog' => self::$debug,
'queries' => self::$query,
- 'request' => self::$request,
+ 'request' => array(
+ 'method' => $_SERVER['REQUEST_METHOD'],
+ 'url' => $request->getRequestURL(),
+ 'headers' => $request->getAllHeaders(),
+ 'params' => $request->getValues(),
+ ),
'memory' => $context->getLanguage()->formatSize( memory_get_usage() ),
'memoryPeak' => $context->getLanguage()->formatSize( memory_get_peak_usage() ),
'includes' => self::getFilesIncluded( $context ),
);
- // TODO: Clean this up
- $html = Html::openElement( 'script' );
- $html .= 'var debugInfo = ' . Xml::encodeJsVar( $debugInfo ) . ';';
- $html .= " $(function() { mw.loader.using( 'mediawiki.debug', function() { mw.Debug.init( debugInfo ) } ); }); ";
- $html .= Html::closeElement( 'script' );
-
- return $html;
}
-}
\ No newline at end of file
+}