*/
function wfDeprecated( $function, $version = false, $component = false ) {
static $functionsWarned = array();
-
+
+ MWDebug::deprecated( $function, $version, $component );
+
if ( !in_array( $function, $GLOBALS['wgDeprecationWhitelist'] ) && !isset( $functionsWarned[$function] ) ) {
$functionsWarned[$function] = true;
function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
global $wgDevelopmentWarnings;
+ MWDebug::warning( $msg, $callerOffset + 2 );
+
$callers = wfDebugBacktrace();
if ( isset( $callers[$callerOffset + 1] ) ) {
$callerfunc = $callers[$callerOffset + 1];
*/
protected static $enabled = true;
+ /**
+ * Array of functions that have already been warned, formatted
+ * function-caller to prevent a buttload of warnings
+ *
+ * @var array
+ */
+ protected static $deprecationWarnings = array();
+
/**
* Called in Setup.php, initializes the debugger if it is enabled with
* $wgDebugToolbar
/**
* Adds a line to the log
*
- * This does nothing atm, there's not frontend for it
- *
- * @todo Add error and warning log type
* @todo Add support for passing objects
*
* @param $str string
return;
}
- self::$log[] = $str;
+ self::$log[] = array(
+ 'msg' => htmlspecialchars( $str ),
+ 'type' => 'log',
+ 'caller' => wfGetCaller(),
+ );
+ }
+
+ /**
+ * Adds a warning entry to the log
+ *
+ * @param $msg
+ * @param int $callerOffset
+ * @return mixed
+ */
+ public static function warning( $msg, $callerOffset = 1 ) {
+ if ( !self::$enabled ) {
+ return;
+ }
+
+ // 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;
+ }
+
+ self::$log[] = array(
+ 'msg' => htmlspecialchars( $msg ),
+ 'type' => 'warn',
+ 'caller' => wfGetCaller( $callerOffset ),
+ );
+ }
+
+ /**
+ * Adds a depreciation entry to the log, along with a backtrace
+ *
+ * @param $function
+ * @param $version
+ * @param $component
+ * @return mixed
+ */
+ public static function deprecated( $function, $version, $component ) {
+ if ( !self::$enabled ) {
+ return;
+ }
+
+ // Chain: This function -> wfDeprecated -> deprecatedFunction -> caller
+ $caller = wfGetCaller( 4 );
+
+ // Check to see if there already was a warning about this function
+ $functionString = "$function-$caller";
+ if ( in_array( $functionString, self::$deprecationWarnings ) ) {
+ return;
+ }
+
+ $version = $version === false ? '(unknown version)' : $version;
+ $component = $component === false ? 'MediaWiki' : $component;
+ $msg = htmlspecialchars( "Use of function $function was deprecated in $component $version" );
+ $msg .= Html::rawElement( 'div', array( 'class' => 'mw-debug-backtrace' ),
+ Html::element( 'span', array(), 'Backtrace:' )
+ . wfBacktrace()
+ );
+
+ self::$deprecationWarnings[] = $functionString;
+ self::$log[] = array(
+ 'msg' => $msg,
+ 'type' => 'deprecated',
+ 'caller' => $caller,
+ );
}
/**
}
global $wgVersion, $wgRequestTime;
+ MWDebug::log( 'MWDebug output complete' );
$debugInfo = array(
'mwVersion' => $wgVersion,
'phpVersion' => PHP_VERSION,
}
.mw-debug-pane {
- max-height: 300px;
+ height: 300px;
overflow: scroll;
display: none;
font-size: 11px;
#mw-debug-pane-request td {
background-color: white;
}
+
+#mw-debug-console tr td:first-child {
+ font-weight: bold;
+ vertical-align: top;
+}
+
+.mw-debug-console-log {
+ background-color: #add8e6;
+}
+
+.mw-debug-console-warn {
+ background-color: #ffa07a;
+}
+
+.mw-debug-console-deprecated {
+ background-color: #ffb6c1;
+}
+
+.mw-debug-backtrace {
+ padding: 5px 10px;
+ margin: 5px;
+ background-color: #dedede;
+}
+
+.mw-debug-backtrace span {
+ font-weight: bold;
+ color: #111;
+}
+
+.mw-debug-backtrace ul {
+ padding-left: 10px;
+}
+
+.mw-debug-backtrace li {
+ width: auto;
+ padding: 0;
+ color: #333;
+ font-size: 10px;
+ margin-bottom: 0;
+ line-height: 1em;
+}
+
+/* Cheapo hack to hide the first 3 lines of the backtrace */
+.mw-debug-backtrace li:nth-child(-n+3) {
+ display: none;
+}
\ No newline at end of file
.appendTo( $bits );
}
+ paneTriggerBitDiv( 'console', 'Console (' + this.data.log.length + ')' );
+
paneTriggerBitDiv( 'querylist', 'Queries: ' + this.data.queries.length );
paneTriggerBitDiv( 'debuglog', 'Debug Log (' + this.data.debugLog.length + ' lines)' );
$bits.appendTo( $container );
panes = {
+ console: this.buildConsoleTable(),
querylist: this.buildQueryTable(),
debuglog: this.buildDebugLogTable(),
request: this.buildRequestPane(),
this.$container = $container;
},
+ /**
+ * Builds the console panel
+ */
+ buildConsoleTable: function () {
+ var $table, entryTypeText, i, length, entry;
+
+ $table = $( '<table id="mw-debug-console">' );
+
+ $('<colgroup>').css( 'width', /*padding=*/20 + ( 10*/*fontSize*/11 ) ).appendTo( $table );
+ $('<colgroup>').appendTo( $table );
+ $('<colgroup>').css( 'width', 350 ).appendTo( $table );
+
+
+ entryTypeText = function( entryType ) {
+ switch ( entryType ) {
+ case 'log':
+ return 'Log';
+ case 'warn':
+ return 'Warning';
+ case 'deprecated':
+ return 'Deprecated';
+ default:
+ return 'Unknown';
+ }
+ };
+
+ for ( i = 0, length = this.data.log.length; i < length; i += 1 ) {
+ entry = this.data.log[i];
+ entry.typeText = entryTypeText( entry.type );
+
+ $( '<tr>' )
+ .append( $( '<td>' )
+ .text( entry.typeText )
+ .attr( 'class', 'mw-debug-console-' + entry.type )
+ )
+ .append( $( '<td>' ).html( entry.msg ) )
+ .append( $( '<td>' ).text( entry.caller ) )
+ .appendTo( $table );
+ }
+
+ return $table;
+ },
+
/**
* Query list pane
*/