wikimedia/mediawiki-core

View on GitHub
includes/OutputTransform/Stages/RenderDebugInfo.php

Summary

Maintainability
B
7 hrs
Test Coverage
<?php

namespace MediaWiki\OutputTransform\Stages;

use MediaWiki\HookContainer\HookContainer;
use MediaWiki\HookContainer\HookRunner;
use MediaWiki\Language\RawMessage;
use MediaWiki\Message\Message;
use MediaWiki\OutputTransform\ContentTextTransformStage;
use MediaWiki\Parser\ParserOutput;
use ParserOptions;

/**
 * Adds debug info to the output
 * @internal
 */
class RenderDebugInfo extends ContentTextTransformStage {

    private HookRunner $hookRunner;

    public function __construct( HookContainer $hookContainer ) {
        $this->hookRunner = new HookRunner( $hookContainer );
    }

    public function shouldRun( ParserOutput $po, ?ParserOptions $popts, array $options = [] ): bool {
        return $options['includeDebugInfo'] ?? false;
    }

    protected function transformText( string $text, ParserOutput $po, ?ParserOptions $popts, array &$options ): string {
        $debugInfo = $this->debugInfo( $po );
        return $text . $debugInfo;
    }

    private function debugInfo( ParserOutput $po ): string {
        $text = '';

        $limitReportData = $po->getLimitReportData();
        // If nothing set it, we can't get it.
        if ( $limitReportData ) {
            $limitReport = "NewPP limit report\n";

            if ( array_key_exists( 'cachereport-origin', $limitReportData ) ) {
                $limitReport .= "Parsed by {$limitReportData['cachereport-origin']}\n";
            }

            if ( array_key_exists( 'cachereport-timestamp', $limitReportData ) ) {
                $limitReport .= "Cached time: {$limitReportData['cachereport-timestamp']}\n";
            }

            if ( array_key_exists( 'cachereport-ttl', $limitReportData ) ) {
                $limitReport .= "Cache expiry: {$limitReportData['cachereport-ttl']}\n";
            }

            if ( array_key_exists( 'cachereport-transientcontent', $limitReportData ) ) {
                $transient = $limitReportData['cachereport-transientcontent'] ? 'true' : 'false';
                $limitReport .= "Reduced expiry: $transient\n";
            }

            // TODO: flags should go into limit report too.
            $limitReport .= 'Complications: [' . implode( ', ', $po->getAllFlags() ) . "]\n";

            foreach ( $limitReportData as $key => $value ) {
                if ( in_array( $key, [
                    'cachereport-origin',
                    'cachereport-timestamp',
                    'cachereport-ttl',
                    'cachereport-transientcontent',
                    'limitreport-timingprofile',
                ] ) ) {
                    // These keys are processed separately.
                    continue;
                }

                // TODO inject MessageFormatter instead of Message::newFromSpecifier
                if ( $this->hookRunner->onParserLimitReportFormat(
                    $key, $value, $limitReport, false, false )
                ) {
                    $keyMsg = Message::newFromSpecifier( $key )->inLanguage( 'en' )->useDatabase( false );
                    $valueMsg = Message::newFallbackSequence( [ "$key-value-text", "$key-value" ] )
                        ->inLanguage( 'en' )->useDatabase( false );
                    if ( !$valueMsg->exists() ) {
                        $valueMsg = new RawMessage( '$1' );
                    }
                    if ( !$keyMsg->isDisabled() && !$valueMsg->isDisabled() ) {
                        $valueMsg->params( $value );
                        $limitReport .= "{$keyMsg->text()}: {$valueMsg->text()}\n";
                    }
                }
            }
            // Since we're not really outputting HTML, decode the entities and
            // then re-encode the things that need hiding inside HTML comments.
            $limitReport = htmlspecialchars_decode( $limitReport );

            // Sanitize for comment. Note '‐' in the replacement is U+2010,
            // which looks much like the problematic '-'.
            $limitReport = str_replace( [ '-', '&' ], [ '‐', '&amp;' ], $limitReport );
            $text = "\n<!-- \n$limitReport-->\n";

            $profileReport = $limitReportData['limitreport-timingprofile'] ?? null;
            if ( $profileReport ) {
                $text .= "<!--\nTransclusion expansion time report (%,ms,calls,template)\n";
                $text .= implode( "\n", $profileReport ) . "\n-->\n";
            }
        }

        if ( $po->getCacheMessage() ) {
            $text .= "\n<!-- " . $po->getCacheMessage() . "\n -->\n";
        }

        $parsoidVersion = $po->getExtensionData( 'core:parsoid-version' );
        if ( $parsoidVersion ) {
            $text .= "\n<!--Parsoid $parsoidVersion-->\n";
        }

        return $text;
    }
}