33 private $mIsHtml, $mFormat;
34 private $mBuffer, $mDisabled =
false;
35 private $mIsWrappedHtml =
false;
36 private $mHttpStatus =
false;
45 parent::__construct( $main, $format );
47 $this->mIsHtml = ( substr( $format, -2, 2 ) ===
'fm' );
48 if ( $this->mIsHtml ) {
49 $this->mFormat = substr( $format, 0, -2 );
50 $this->mIsWrappedHtml = $this->
getMain()->getCheck(
'wrappedhtml' );
52 $this->mFormat = $format;
54 $this->mFormat = strtoupper( $this->mFormat );
76 return 'api-result-wrapped.json';
78 return 'api-result.html';
80 $mimeAnalyzer = MediaWikiServices::getInstance()->getMimeAnalyzer();
81 $ext = $mimeAnalyzer->getExtensionFromMimeTypeOrNull( $this->
getMimeType() )
82 ?? strtolower( $this->mFormat );
83 return "api-result.$ext";
92 return $this->mFormat;
102 return $this->mIsHtml;
111 return $this->mIsWrappedHtml;
120 $this->mDisabled =
true;
128 return $this->mDisabled;
150 $this->mForceDefaultParams =
true;
159 if ( !$this->mForceDefaultParams ) {
160 return parent::getParameterFromSettings( $paramName, $paramSettings, $parseLimit );
163 if ( !is_array( $paramSettings ) ) {
164 return $paramSettings;
167 return $paramSettings[ParamValidator::PARAM_DEFAULT] ??
null;
176 if ( $this->mDisabled ) {
181 $this->mHttpStatus = $code;
183 $this->
getMain()->getRequest()->response()->statusHeader( $code );
192 if ( $this->mDisabled ) {
196 if ( $this->
getIsHtml() && $this->
getMain()->getCacheMode() ===
'public' ) {
198 $this->
getMain()->setCacheMode(
'anon-public-user-private' );
202 ?
'text/mediawiki-api-prettyprint-wrapped'
207 if (
$mime ===
null ) {
211 $this->
getMain()->getRequest()->response()->header(
"Content-Type: $mime; charset=utf-8" );
214 $apiFrameOptions = $this->
getConfig()->get( MainConfigNames::ApiFrameOptions );
215 if ( $apiFrameOptions ) {
216 $this->
getMain()->getRequest()->response()->header(
"X-Frame-Options: $apiFrameOptions" );
221 $header =
'Content-Disposition: inline';
223 $compatFilename = mb_convert_encoding( $filename,
'ISO-8859-1' );
224 if ( preg_match(
'/^[0-9a-zA-Z!#$%&\'*+\-.^_`|~]+$/', $compatFilename ) ) {
225 $header .=
'; filename=' . $compatFilename;
228 . preg_replace(
'/([\0-\x1f"\x5c\x7f])/',
'\\\\$1', $compatFilename ) .
'"';
230 if ( $compatFilename !== $filename ) {
231 $value =
"UTF-8''" . rawurlencode( $filename );
233 $value = strtr( $value, [
234 '%21' =>
'!',
'%23' =>
'#',
'%24' =>
'$',
'%26' =>
'&',
'%2B' =>
'+',
'%5E' =>
'^',
235 '%60' =>
'`',
'%7C' =>
'|',
237 $header .=
'; filename*=' . $value;
246 if ( $this->mDisabled ) {
253 $lcformat = strtolower( $format );
257 $skinFactory = MediaWikiServices::getInstance()->getSkinFactory();
258 $context->setSkin( $skinFactory->makeSkin(
'apioutput' ) );
261 $context->setOutput( $out );
263 $out->setRobotPolicy(
'noindex,nofollow' );
264 $out->addModuleStyles(
'mediawiki.apipretty' );
265 $out->setPageTitle( $context->msg(
'api-format-title' ) );
271 $nonHtmlUrl = strtok( $this->
getRequest()->getFullRequestURL(),
'?' )
272 .
'?' . $this->
getRequest()->appendQueryValue(
'format', $lcformat );
273 $msg = $context->msg(
'api-format-prettyprint-header-hyperlinked' )
274 ->params( $format, $lcformat, $nonHtmlUrl );
276 $msg = $context->msg(
'api-format-prettyprint-header' )->params( $format, $lcformat );
279 $msg = $context->msg(
'api-format-prettyprint-header-only-html' )->params( $format );
282 $header = $msg->parseAsBlock();
284 Html::rawElement(
'div', [
'class' =>
'api-pretty-header' ],
289 if ( $this->mHttpStatus && $this->mHttpStatus !== 200 ) {
291 Html::rawElement(
'div', [
'class' => [
'api-pretty-header',
'api-pretty-status' ] ],
293 'api-format-prettyprint-status',
295 HttpStatus::getMessage( $this->mHttpStatus )
302 if ( $this->
getHookRunner()->onApiFormatHighlight( $context, $result,
$mime, $format ) ) {
304 Html::element(
'pre', [
'class' =>
'api-pretty-content' ], $result )
310 $time = $this->
getMain()->getRequest()->getElapsedTime();
311 echo FormatJson::encode(
313 'status' => (
int)( $this->mHttpStatus ?: 200 ),
314 'statustext' => HttpStatus::getMessage( $this->mHttpStatus ?: 200 ),
315 'html' => $out->getHTML(),
316 'modules' => array_values( array_unique( array_merge(
318 $out->getModuleStyles()
320 'continue' => $this->
getResult()->getResultData(
'continue' ),
321 'time' => round( $time * 1000 ),
323 false, FormatJson::ALL_OK
328 $out->setPreventClickjacking(
false );
345 $this->mBuffer .= $text;
353 return $this->mBuffer;
359 $ret[
'wrappedhtml'] = [
360 ParamValidator::PARAM_DEFAULT =>
false,
369 'action=query&meta=siteinfo&siprop=namespaces&format=' . $this->
getModuleName()
370 => [
'apihelp-format-example-generic', $this->
getFormat() ]
375 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Data_formats';
This abstract class implements many basic API functions, and is the base of all API classes.
getModuleManager()
Get the module manager, or null if this module has no sub-modules.
getMain()
Get the main module.
getResult()
Get the result object.
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
getModuleName()
Get the name of the module being executed by this instance.
getHookRunner()
Get an ApiHookRunner for running core API hooks.
static fixHelpLinks( $html, $helptitle=null, $localModules=[])
Replace Special:ApiHelp links with links to api.php.
This is the main API class, used for both external and internal processing.
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
An IContextSource implementation which will inherit context from another source but allow individual ...
A class containing constants representing the names of configuration variables.
This is one of the Core classes and should be read at least once by any new developers.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
if(!is_readable( $file)) $ext