45 $this->
getMain()->setCacheMode(
'anon-public-user-private' );
56 $text = $params[
'text'];
59 $titleProvided =
false;
63 $titleProvided =
true;
66 $page = $params[
'page'];
67 $pageid = $params[
'pageid'];
68 $oldid = $params[
'oldid'];
70 $model = $params[
'contentmodel'];
71 $format = $params[
'contentformat'];
73 $prop = array_flip( $params[
'prop'] );
75 if ( isset( $params[
'section'] ) ) {
76 $this->section = $params[
'section'];
77 if ( !preg_match(
'/^((T-)?\d+|new)$/', $this->section ) ) {
81 $this->section =
false;
91 $needContent = isset( $prop[
'wikitext'] ) ||
92 isset( $prop[
'parsetree'] ) || $params[
'generatexml'];
97 if ( !is_null( $oldid ) || !is_null( $pageid ) || !is_null( $page ) ) {
98 if ( $this->section ===
'new' ) {
99 $this->
dieWithError(
'apierror-invalidparammix-parse-new-section',
'invalidparammix' );
101 if ( !is_null( $oldid ) ) {
105 $this->
dieWithError( [
'apierror-nosuchrevid', $oldid ] );
109 if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() ) ) {
111 [
'apierror-permissiondenied', $this->
msg(
'action-deletedtext' ) ]
115 $titleObj = $rev->getTitle();
117 $pageObj = WikiPage::factory( $titleObj );
118 list( $popts, $reset, $suppressCache ) = $this->
makeParserOptions( $pageObj, $params );
120 $pageObj, $popts, $suppressCache, $pageid, $rev, $needContent
123 if ( $params[
'redirects'] ) {
127 if ( !is_null( $pageid ) ) {
128 $reqParams[
'pageids'] = $pageid;
130 $reqParams[
'titles'] = $page;
136 $redirValues = $pageSet->getRedirectTitlesAsResult( $this->
getResult() );
139 foreach ( $pageSet->getRedirectTitles() as
$title ) {
140 $to =
$title->getFullText();
142 $pageParams = [
'title' => $to ];
143 } elseif ( !is_null( $pageid ) ) {
144 $pageParams = [
'pageid' => $pageid ];
146 $pageParams = [
'title' => $page ];
150 $titleObj = $pageObj->getTitle();
151 if ( !$titleObj || !$titleObj->exists() ) {
158 if ( isset( $prop[
'revid'] ) ) {
159 $oldid = $pageObj->getLatest();
162 list( $popts, $reset, $suppressCache ) = $this->
makeParserOptions( $pageObj, $params );
164 $pageObj, $popts, $suppressCache, $pageid,
null, $needContent
168 $titleObj = Title::newFromText(
$title );
169 if ( !$titleObj || $titleObj->isExternal() ) {
172 $revid = $params[
'revid'];
173 if ( $revid !==
null ) {
176 $this->
dieWithError( [
'apierror-nosuchrevid', $revid ] );
178 $pTitleObj = $titleObj;
179 $titleObj = $rev->getTitle();
180 if ( $titleProvided ) {
181 if ( !$titleObj->equals( $pTitleObj ) ) {
182 $this->
addWarning( [
'apierror-revwrongpage', $rev->getId(),
188 $titleProvided =
true;
192 if ( $titleObj->canExist() ) {
193 $pageObj = WikiPage::factory( $titleObj );
197 $pageObj = $article->getPage();
201 $textProvided = !is_null( $text );
203 if ( !$textProvided ) {
204 if ( $titleProvided && ( $prop || $params[
'generatexml'] ) ) {
205 if ( $revid !==
null ) {
206 $this->
addWarning(
'apiwarn-parse-revidwithouttext' );
208 $this->
addWarning(
'apiwarn-parse-titlewithouttext' );
217 if ( $textProvided && !$titleProvided && is_null( $model ) ) {
219 $this->
addWarning( [
'apiwarn-parse-nocontentmodel', $model ] );
223 $this->content = ContentHandler::makeContent( $text, $titleObj, $model, $format );
226 'wrap' =>
ApiMessage::create(
'apierror-contentserializationexception',
'parseerror' )
230 if ( $this->section !==
false ) {
231 if ( $this->section ===
'new' ) {
233 if ( !is_null( $params[
'sectiontitle'] ) && $params[
'sectiontitle'] !==
'' ) {
234 $this->content = $this->content->addSectionHeader( $params[
'sectiontitle'] );
237 $this->content = $this->
getSectionContent( $this->content, $titleObj->getPrefixedText() );
241 if ( $params[
'pst'] || $params[
'onlypst'] ) {
242 $this->pstContent = $this->content->preSaveTransform( $titleObj, $this->
getUser(), $popts );
244 if ( $params[
'onlypst'] ) {
247 $result_array[
'text'] = $this->pstContent->serialize( $format );
249 if ( isset( $prop[
'wikitext'] ) ) {
250 $result_array[
'wikitext'] = $this->content->serialize( $format );
253 if ( !is_null( $params[
'summary'] ) ||
254 ( !is_null( $params[
'sectiontitle'] ) && $this->section ===
'new' )
256 $result_array[
'parsedsummary'] = $this->
formatSummary( $titleObj, $params );
260 $result->addValue(
null, $this->
getModuleName(), $result_array );
266 if ( $params[
'pst'] ) {
267 $p_result = $this->pstContent->getParserOutput( $titleObj, $revid, $popts );
269 $p_result = $this->content->getParserOutput( $titleObj, $revid, $popts );
275 $result_array[
'title'] = $titleObj->getPrefixedText();
276 $result_array[
'pageid'] = $pageid ?: $pageObj->getId();
277 if ( $this->contentIsDeleted ) {
278 $result_array[
'textdeleted'] =
true;
280 if ( $this->contentIsSuppressed ) {
281 $result_array[
'textsuppressed'] =
true;
284 if ( isset( $params[
'useskin'] ) ) {
285 $factory = MediaWikiServices::getInstance()->getSkinFactory();
286 $skin = $factory->makeSkin( Skin::normalizeKey( $params[
'useskin'] ) );
292 if ( $skin || isset( $prop[
'headhtml'] ) || isset( $prop[
'categorieshtml'] ) ) {
317 $outputPage->addParserOutputMetadata( $p_result );
318 if ( $this->content ) {
319 $outputPage->addContentOverride( $titleObj, $this->content );
325 $skin->setupSkinUserCss( $outputPage );
327 $outputPage->loadSkinModules( $skin );
330 Hooks::run(
'ApiParseMakeOutputPage', [ $this, $outputPage ] );
333 if ( !is_null( $oldid ) ) {
334 $result_array[
'revid'] = (int)$oldid;
337 if ( $params[
'redirects'] && !is_null( $redirValues ) ) {
338 $result_array[
'redirects'] = $redirValues;
341 if ( isset( $prop[
'text'] ) ) {
342 $result_array[
'text'] = $p_result->getText( [
343 'allowTOC' => !$params[
'disabletoc'],
344 'enableSectionEditLinks' => !$params[
'disableeditsection'],
345 'wrapperDivClass' => $params[
'wrapoutputclass'],
346 'deduplicateStyles' => !$params[
'disablestylededuplication'],
351 if ( !is_null( $params[
'summary'] ) ||
352 ( !is_null( $params[
'sectiontitle'] ) && $this->section ===
'new' )
354 $result_array[
'parsedsummary'] = $this->
formatSummary( $titleObj, $params );
358 if ( isset( $prop[
'langlinks'] ) ) {
360 $langlinks = $outputPage->getLanguageLinks();
362 $langlinks = $p_result->getLanguageLinks();
366 if ( $params[
'effectivelanglinks'] ) {
368 Hooks::run(
'LanguageLinks', [ $titleObj, &$langlinks, &$linkFlags ] );
374 if ( isset( $prop[
'categories'] ) ) {
377 if ( isset( $prop[
'categorieshtml'] ) ) {
378 $result_array[
'categorieshtml'] = $outputPage->getSkin()->getCategories();
381 if ( isset( $prop[
'links'] ) ) {
382 $result_array[
'links'] = $this->
formatLinks( $p_result->getLinks() );
384 if ( isset( $prop[
'templates'] ) ) {
385 $result_array[
'templates'] = $this->
formatLinks( $p_result->getTemplates() );
387 if ( isset( $prop[
'images'] ) ) {
388 $result_array[
'images'] = array_keys( $p_result->getImages() );
390 if ( isset( $prop[
'externallinks'] ) ) {
391 $result_array[
'externallinks'] = array_keys( $p_result->getExternalLinks() );
393 if ( isset( $prop[
'sections'] ) ) {
394 $result_array[
'sections'] = $p_result->getSections();
396 if ( isset( $prop[
'parsewarnings'] ) ) {
397 $result_array[
'parsewarnings'] = $p_result->getWarnings();
400 if ( isset( $prop[
'displaytitle'] ) ) {
401 $result_array[
'displaytitle'] = $p_result->getDisplayTitle() !==
false
402 ? $p_result->getDisplayTitle() : $titleObj->getPrefixedText();
405 if ( isset( $prop[
'headitems'] ) ) {
407 $result_array[
'headitems'] = $this->
formatHeadItems( $outputPage->getHeadItemsArray() );
409 $result_array[
'headitems'] = $this->
formatHeadItems( $p_result->getHeadItems() );
413 if ( isset( $prop[
'headhtml'] ) ) {
414 $result_array[
'headhtml'] = $outputPage->headElement(
$context->
getSkin() );
418 if ( isset( $prop[
'modules'] ) ) {
420 $result_array[
'modules'] = $outputPage->getModules();
422 $result_array[
'modulescripts'] = [];
423 $result_array[
'modulestyles'] = $outputPage->getModuleStyles();
425 $result_array[
'modules'] = array_values( array_unique( $p_result->getModules() ) );
427 $result_array[
'modulescripts'] = [];
428 $result_array[
'modulestyles'] = array_values( array_unique( $p_result->getModuleStyles() ) );
432 if ( isset( $prop[
'jsconfigvars'] ) ) {
433 $jsconfigvars = $skin ? $outputPage->getJsConfigVars() : $p_result->getJsConfigVars();
437 if ( isset( $prop[
'encodedjsconfigvars'] ) ) {
438 $jsconfigvars = $skin ? $outputPage->getJsConfigVars() : $p_result->getJsConfigVars();
439 $result_array[
'encodedjsconfigvars'] = FormatJson::encode(
447 if ( isset( $prop[
'modules'] ) &&
448 !isset( $prop[
'jsconfigvars'] ) && !isset( $prop[
'encodedjsconfigvars'] ) ) {
449 $this->
addWarning(
'apiwarn-moduleswithoutvars' );
452 if ( isset( $prop[
'indicators'] ) ) {
454 $result_array[
'indicators'] = (array)$outputPage->getIndicators();
456 $result_array[
'indicators'] = (array)$p_result->getIndicators();
461 if ( isset( $prop[
'iwlinks'] ) ) {
462 $result_array[
'iwlinks'] = $this->
formatIWLinks( $p_result->getInterwikiLinks() );
465 if ( isset( $prop[
'wikitext'] ) ) {
466 $result_array[
'wikitext'] = $this->content->serialize( $format );
468 if ( !is_null( $this->pstContent ) ) {
469 $result_array[
'psttext'] = $this->pstContent->serialize( $format );
473 if ( isset( $prop[
'properties'] ) ) {
474 $result_array[
'properties'] = (array)$p_result->getProperties();
478 if ( isset( $prop[
'limitreportdata'] ) ) {
479 $result_array[
'limitreportdata'] =
482 if ( isset( $prop[
'limitreporthtml'] ) ) {
487 if ( isset( $prop[
'parsetree'] ) || $params[
'generatexml'] ) {
489 $this->
dieWithError(
'apierror-parsetree-notwikitext',
'notwikitext' );
492 $parser = MediaWikiServices::getInstance()->getParser();
493 $parser->startExternalParse( $titleObj, $popts, Parser::OT_PREPROCESS );
495 $xml = $parser->preprocessToDom( $this->content->getText() )->__toString();
496 $result_array[
'parsetree'] = $xml;
503 'categories' =>
'cl',
507 'externallinks' =>
'el',
512 'indicators' =>
'ind',
513 'modulescripts' =>
'm',
514 'modulestyles' =>
'm',
515 'properties' =>
'pp',
516 'limitreportdata' =>
'lr',
517 'parsewarnings' =>
'pw'
520 $result->addValue(
null, $this->
getModuleName(), $result_array );
533 $popts->enableLimitReport( !$params[
'disablepp'] && !$params[
'disablelimitreport'] );
534 $popts->setIsPreview( $params[
'preview'] || $params[
'sectionpreview'] );
535 $popts->setIsSectionPreview( $params[
'sectionpreview'] );
536 if ( $params[
'disabletidy'] ) {
537 $popts->setTidy(
false );
539 if ( $params[
'wrapoutputclass'] !==
'' ) {
540 $popts->setWrapOutputClass( $params[
'wrapoutputclass'] );
544 $suppressCache =
false;
545 Hooks::run(
'ApiMakeParserOptions',
546 [ $popts, $pageObj->
getTitle(), $params, $this, &$reset, &$suppressCache ] );
549 $suppressCache = $suppressCache || !$popts->isSafeToCache();
551 return [ $popts, $reset, $suppressCache ];
564 WikiPage $page, $popts, $suppressCache, $pageId, $rev, $getContent
566 $revId = $rev ? $rev->getId() :
null;
567 $isDeleted = $rev && $rev->isDeleted( RevisionRecord::DELETED_TEXT );
569 if ( $getContent || $this->section !==
false || $isDeleted ) {
571 $this->content = $rev->getContent( RevisionRecord::FOR_THIS_USER, $this->
getUser() );
572 if ( !$this->content ) {
573 $this->
dieWithError( [
'apierror-missingcontent-revid', $revId ] );
576 $this->content = $page->
getContent( RevisionRecord::FOR_THIS_USER, $this->
getUser() );
577 if ( !$this->content ) {
581 $this->contentIsDeleted = $isDeleted;
582 $this->contentIsSuppressed = $rev &&
583 $rev->isDeleted( RevisionRecord::DELETED_TEXT | RevisionRecord::DELETED_RESTRICTED );
586 if ( $this->section !==
false ) {
589 $pageId ===
null ? $page->
getTitle()->getPrefixedText() : $this->
msg(
'pageid', $pageId )
591 return $this->content->getParserOutput( $page->
getTitle(), $revId, $popts );
596 $pout = $this->content->getParserOutput( $page->
getTitle(), $revId, $popts );
621 $this->
dieWithError( [
'apierror-nosuchsection-what', $this->section, $what ],
'nosuchsection' );
624 $this->
dieWithError( [
'apierror-sectionsnotsupported-what', $what ],
'nosuchsection' );
639 $summary = $params[
'summary'] ??
'';
640 $sectionTitle = $params[
'sectiontitle'] ??
'';
642 if ( $this->section ===
'new' && ( $sectionTitle ===
'' || $summary ===
'' ) ) {
643 if ( $sectionTitle !==
'' ) {
644 $summary = $params[
'sectiontitle'];
646 if ( $summary !==
'' ) {
647 $summary =
wfMessage(
'newsectionsummary' )
648 ->rawParams( MediaWikiServices::getInstance()->getParser()
649 ->stripSectionName( $summary ) )
650 ->inContentLanguage()->text();
658 foreach ( $links as $link ) {
660 $bits = explode(
':', $link, 2 );
661 $title = Title::newFromText( $link );
663 $entry[
'lang'] = $bits[0];
667 $entry[
'langname'] = Language::fetchLanguageName(
669 $this->getLanguage()->getCode()
673 $entry[
'autonym'] = Language::fetchLanguageName(
$title->getInterwiki() );
692 $db = $this->
getDB();
693 $res = $db->select( [
'page',
'page_props' ],
694 [
'page_title',
'pp_propname' ],
695 $lb->constructSet(
'page', $db ),
699 'LEFT JOIN', [
'pp_propname' =>
'hiddencat',
'pp_page = page_id' ]
703 foreach (
$res as $row ) {
704 $hiddencats[$row->page_title] = isset( $row->pp_propname );
707 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
709 foreach ( $links as $link => $sortkey ) {
711 $entry[
'sortkey'] = $sortkey;
714 if ( !isset( $hiddencats[$link] ) ) {
715 $entry[
'missing'] =
true;
720 $linkCache->addBadLinkObj(
$title );
721 if (
$title->isKnown() ) {
722 $entry[
'known'] =
true;
724 } elseif ( $hiddencats[$link] ) {
725 $entry[
'hidden'] =
true;
735 foreach ( $links as $ns => $nslinks ) {
736 foreach ( $nslinks as
$title => $id ) {
740 $entry[
'exists'] = $id != 0;
750 foreach ( $iw as $prefix => $titles ) {
751 foreach ( array_keys( $titles ) as
$title ) {
753 $entry[
'prefix'] = $prefix;
755 $title = Title::newFromText(
"{$prefix}:{$title}" );
770 foreach ( $headItems as $tag =>
$content ) {
772 $entry[
'tag'] = $tag;
783 foreach ( $limitReportData as $name => $value ) {
785 $entry[
'name'] = $name;
786 if ( !is_array( $value ) ) {
790 $entry = array_merge( $entry, $value );
798 foreach ( $mapping as $key => $name ) {
799 if ( isset( $array[$key] ) ) {
819 'redirects' =>
false,
825 'images|externallinks|sections|revid|displaytitle|iwlinks|' .
826 'properties|parsewarnings',
843 'encodedjsconfigvars',
858 'headitems' =>
'apiwarn-deprecation-parse-headitems',
861 'wrapoutputclass' =>
'mw-parser-output',
864 'effectivelanglinks' => [
876 'disablelimitreport' =>
false,
877 'disableeditsection' =>
false,
882 'disablestylededuplication' =>
false,
891 'sectionpreview' =>
false,
892 'disabletoc' =>
false,
907 'action=parse&page=Project:Sandbox'
908 =>
'apihelp-parse-example-page',
909 'action=parse&text={{Project:Sandbox}}&contentmodel=wikitext'
910 =>
'apihelp-parse-example-text',
911 'action=parse&text={{PAGENAME}}&title=Test'
912 =>
'apihelp-parse-example-texttitle',
913 'action=parse&summary=Some+[[link]]&prop='
914 =>
'apihelp-parse-example-summary',
919 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Parsing_wikitext#parse';
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
if(! $wgRequest->checkUrlExtension()) if(isset( $_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] !='') $wgTitle
This abstract class implements many basic API functions, and is the base of all API classes.
const PARAM_DEPRECATED
(boolean) Is the parameter deprecated (will show a warning)?
getDB()
Gets a default replica DB connection object.
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
checkTitleUserPermissions(LinkTarget $linkTarget, $actions, $options=[])
Helper function for permission-denied errors.
const PARAM_DEPRECATED_VALUES
(array) When PARAM_TYPE is an array, this indicates which of the values are deprecated.
getMain()
Get the main module.
const PARAM_TYPE
(string|string[]) Either an array of allowed value strings, or a string type as described below.
const PARAM_DFLT
(null|boolean|integer|string) Default value of the parameter.
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
getResult()
Get the result object.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
requireMaxOneParameter( $params, $required)
Die if more than one of a certain set of parameters is set and not false.
dieWithException( $exception, array $options=[])
Abort execution with an error derived from an exception.
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
getModuleName()
Get the name of the module being executed by this instance.
getTitleOrPageId( $params, $load=false)
Get a WikiPage object from a title or pageid param, if possible.
const PARAM_ISMULTI
(boolean) Accept multiple pipe-separated values for this parameter (e.g.
This is the main API class, used for both external and internal processing.
static create( $msg, $code=null, array $data=null)
Create an IApiMessage for the message.
This class contains a list of pages that the client has requested.
formatSummary( $title, $params)
This mimicks the behavior of EditPage in formatting a summary.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
getParsedContent(WikiPage $page, $popts, $suppressCache, $pageId, $rev, $getContent)
formatHeadItems( $headItems)
getExamplesMessages()
Returns usage examples for this module.
formatCategoryLinks( $links)
formatLimitReportData( $limitReportData)
makeParserOptions(WikiPage $pageObj, array $params)
Constructs a ParserOptions object.
bool $contentIsSuppressed
getSectionContent(Content $content, $what)
Extract the requested section from the given Content.
getHelpUrls()
Return links to more detailed help pages about the module.
setIndexedTagNames(&$array, $mapping)
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
static addMetadataToResultVars( $vars, $forceHash=true)
Add the correct metadata to an array of vars we want to export through the API.
const META_SUBELEMENTS
Key for the 'subelements' metadata item.
const META_BC_SUBELEMENTS
Key for the 'BC subelements' metadata item.
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
static setContentValue(array &$arr, $name, $value, $flags=0)
Add an output value to the array by name and mark as META_CONTENT.
static setIndexedTagNameRecursive(array &$arr, $tag)
Set indexed tag name on $arr and all subarrays.
static newFromTitle( $title, IContextSource $context)
Create an Article object of the appropriate class for the given page.
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
getContext()
Get the base IContextSource object.
An IContextSource implementation which will inherit context from another source but allow individual ...
static getPreviewLimitReport(ParserOutput $output=null)
Get the Limit report for page previews.
WebRequest clone which takes values from a provided array.
Class representing a list of titles The execute() method checks them all for existence and adds them ...
setArray( $array)
Set the link list to a given 2-d array First key is the namespace, second is the DB key,...
static formatComment( $comment, $title=null, $local=false, $wikiId=null)
This function is called by all recent changes variants, by the page history, and by the user contribu...
Exception representing a failure to serialize or unserialize a content object.
This is one of the Core classes and should be read at least once by any new developers.
static newFromId( $id, $flags=0)
Load a page revision from a given revision ID number.
Class representing a MediaWiki article and history.
getContent( $audience=RevisionRecord::FOR_PUBLIC, User $user=null)
Get the content of the current revision.
getLatest()
Get the page_latest field.
makeParserOptions( $context)
Get parser options suitable for rendering the primary article wikitext.
getParserOutput(ParserOptions $parserOptions, $oldid=null, $forceParse=false)
Get a ParserOutput for the given ParserOptions and revision ID.
getTitle()
Get the title object of the article.
const CONTENT_MODEL_WIKITEXT
Base interface for content objects.