X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiFormatBase.php;h=c826bbad9569cd8a924b2c95f81e0a94ae581611;hb=88f73a5d6567c1f7df53d498be4d0c63b431b881;hp=be683105ffb442420bc5e2a0ff6fc07638dffed4;hpb=8df1bb7951c4adcfcc4540c00e70080220b03099;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiFormatBase.php b/includes/api/ApiFormatBase.php index be683105ff..c826bbad95 100644 --- a/includes/api/ApiFormatBase.php +++ b/includes/api/ApiFormatBase.php @@ -32,6 +32,7 @@ abstract class ApiFormatBase extends ApiBase { private $mIsHtml, $mFormat, $mUnescapeAmps, $mHelp; private $mBuffer, $mDisabled = false; + private $mIsWrappedHtml = false; protected $mForceDefaultParams = false; /** @@ -45,6 +46,7 @@ abstract class ApiFormatBase extends ApiBase { $this->mIsHtml = ( substr( $format, -2, 2 ) === 'fm' ); // ends with 'fm' if ( $this->mIsHtml ) { $this->mFormat = substr( $format, 0, -2 ); // remove ending 'fm' + $this->mIsWrappedHtml = $this->getMain()->getCheck( 'wrappedhtml' ); } else { $this->mFormat = $format; } @@ -79,6 +81,15 @@ abstract class ApiFormatBase extends ApiBase { return $this->mIsHtml; } + /** + * Returns true when the special wrapped mode is enabled. + * @since 1.27 + * @return bool + */ + protected function getIsWrappedHtml() { + return $this->mIsWrappedHtml; + } + /** * Disable the formatter. * @@ -140,12 +151,14 @@ abstract class ApiFormatBase extends ApiBase { * Initialize the printer function and prepare the output headers. * @param bool $unused Always false since 1.25 */ - function initPrinter( $unused = false ) { + public function initPrinter( $unused = false ) { if ( $this->mDisabled ) { return; } - $mime = $this->getIsHtml() ? 'text/html' : $this->getMimeType(); + $mime = $this->getIsWrappedHtml() + ? 'text/mediawiki-api-prettyprint-wrapped' + : ( $this->getIsHtml() ? 'text/html' : $this->getMimeType() ); // Some printers (ex. Feed) do their own header settings, // in which case $mime will be set to null @@ -185,30 +198,60 @@ abstract class ApiFormatBase extends ApiBase { $out->addModuleStyles( 'mediawiki.apipretty' ); $out->setPageTitle( $context->msg( 'api-format-title' ) ); - // When the format without suffix 'fm' is defined, there is a non-html version - if ( $this->getMain()->getModuleManager()->isDefined( $lcformat, 'format' ) ) { - $msg = $context->msg( 'api-format-prettyprint-header' )->params( $format, $lcformat ); - } else { - $msg = $context->msg( 'api-format-prettyprint-header-only-html' )->params( $format ); - } + if ( !$this->getIsWrappedHtml() ) { + // When the format without suffix 'fm' is defined, there is a non-html version + if ( $this->getMain()->getModuleManager()->isDefined( $lcformat, 'format' ) ) { + $msg = $context->msg( 'api-format-prettyprint-header' )->params( $format, $lcformat ); + } else { + $msg = $context->msg( 'api-format-prettyprint-header-only-html' )->params( $format ); + } - $header = $msg->parseAsBlock(); - $out->addHTML( - Html::rawElement( 'div', array( 'class' => 'api-pretty-header' ), - ApiHelp::fixHelpLinks( $header ) - ) - ); + $header = $msg->parseAsBlock(); + $out->addHTML( + Html::rawElement( 'div', [ 'class' => 'api-pretty-header' ], + ApiHelp::fixHelpLinks( $header ) + ) + ); + } - if ( Hooks::run( 'ApiFormatHighlight', array( $context, $result, $mime, $format ) ) ) { + if ( Hooks::run( 'ApiFormatHighlight', [ $context, $result, $mime, $format ] ) ) { $out->addHTML( - Html::element( 'pre', array( 'class' => 'api-pretty-content' ), $result ) + Html::element( 'pre', [ 'class' => 'api-pretty-content' ], $result ) ); } - // API handles its own clickjacking protection. - // Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode. - $out->allowClickjacking(); - $out->output(); + if ( $this->getIsWrappedHtml() ) { + // This is a special output mode mainly intended for ApiSandbox use + $time = microtime( true ) - $this->getConfig()->get( 'RequestTime' ); + $json = FormatJson::encode( + [ + 'html' => $out->getHTML(), + 'modules' => array_values( array_unique( array_merge( + $out->getModules(), + $out->getModuleScripts(), + $out->getModuleStyles() + ) ) ), + 'time' => round( $time * 1000 ), + ], + false, FormatJson::ALL_OK + ); + + // Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in + // Flash, but what it does isn't friendly for the API, so we need to + // work around it. + if ( preg_match( '/\<\s*cross-domain-policy\s*\>/i', $json ) ) { + $json = preg_replace( + '/\<(\s*cross-domain-policy\s*)\>/i', '\\u003C$1\\u003E', $json + ); + } + + echo $json; + } else { + // API handles its own clickjacking protection. + // Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode. + $out->allowClickjacking(); + $out->output(); + } } else { // For non-HTML output, clear all errors that might have been // displayed if display_errors=On @@ -234,11 +277,23 @@ abstract class ApiFormatBase extends ApiBase { return $this->mBuffer; } + public function getAllowedParams() { + $ret = []; + if ( $this->getIsHtml() ) { + $ret['wrappedhtml'] = [ + ApiBase::PARAM_DFLT => false, + ApiBase::PARAM_HELP_MSG => 'apihelp-format-param-wrappedhtml', + + ]; + } + return $ret; + } + protected function getExamplesMessages() { - return array( + return [ 'action=query&meta=siteinfo&siprop=namespaces&format=' . $this->getModuleName() - => array( 'apihelp-format-example-generic', $this->getFormat() ) - ); + => [ 'apihelp-format-example-generic', $this->getFormat() ] + ]; } public function getHelpUrls() { @@ -314,7 +369,7 @@ abstract class ApiFormatBase extends ApiBase { } // Armor links (bug 61362) - $masked = array(); + $masked = []; $text = preg_replace_callback( '##', function ( $matches ) use ( &$masked ) { $sha = sha1( $matches[0] ); $masked[$sha] = $matches[0];