Merge "Remove not used private member variable mParserWarnings from OutputPage"
[mediawiki.git] / includes / api / ApiParse.php
blob5754c2368dab8b3d5d302651517d84dbba86bb2e
1 <?php
2 /**
3 * Created on Dec 01, 2007
5 * Copyright © 2007 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * http://www.gnu.org/copyleft/gpl.html
22 * @file
25 /**
26 * @ingroup API
28 class ApiParse extends ApiBase {
30 /** @var string $section */
31 private $section = null;
33 /** @var Content $content */
34 private $content = null;
36 /** @var Content $pstContent */
37 private $pstContent = null;
39 public function execute() {
40 // The data is hot but user-dependent, like page views, so we set vary cookies
41 $this->getMain()->setCacheMode( 'anon-public-user-private' );
43 // Get parameters
44 $params = $this->extractRequestParams();
45 $text = $params['text'];
46 $title = $params['title'];
47 if ( $title === null ) {
48 $titleProvided = false;
49 // A title is needed for parsing, so arbitrarily choose one
50 $title = 'API';
51 } else {
52 $titleProvided = true;
55 $page = $params['page'];
56 $pageid = $params['pageid'];
57 $oldid = $params['oldid'];
59 $model = $params['contentmodel'];
60 $format = $params['contentformat'];
62 if ( !is_null( $page ) && ( !is_null( $text ) || $titleProvided ) ) {
63 $this->dieUsage(
64 'The page parameter cannot be used together with the text and title parameters',
65 'params'
69 $prop = array_flip( $params['prop'] );
71 if ( isset( $params['section'] ) ) {
72 $this->section = $params['section'];
73 if ( !preg_match( '/^((T-)?\d+|new)$/', $this->section ) ) {
74 $this->dieUsage(
75 "The section parameter must be a valid section id or 'new'", "invalidsection"
78 } else {
79 $this->section = false;
82 // The parser needs $wgTitle to be set, apparently the
83 // $title parameter in Parser::parse isn't enough *sigh*
84 // TODO: Does this still need $wgTitle?
85 global $wgParser, $wgTitle;
87 $redirValues = null;
89 // Return result
90 $result = $this->getResult();
92 if ( !is_null( $oldid ) || !is_null( $pageid ) || !is_null( $page ) ) {
93 if ( $this->section === 'new' ) {
94 $this->dieUsage(
95 'section=new cannot be combined with oldid, pageid or page parameters. ' .
96 'Please use text', 'params'
99 if ( !is_null( $oldid ) ) {
100 // Don't use the parser cache
101 $rev = Revision::newFromId( $oldid );
102 if ( !$rev ) {
103 $this->dieUsage( "There is no revision ID $oldid", 'missingrev' );
105 if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
106 $this->dieUsage( "You don't have permission to view deleted revisions", 'permissiondenied' );
109 $titleObj = $rev->getTitle();
110 $wgTitle = $titleObj;
111 $pageObj = WikiPage::factory( $titleObj );
112 $popts = $this->makeParserOptions( $pageObj, $params );
114 // If for some reason the "oldid" is actually the current revision, it may be cached
115 // Deliberately comparing $pageObj->getLatest() with $rev->getId(), rather than
116 // checking $rev->isCurrent(), because $pageObj is what actually ends up being used,
117 // and if its ->getLatest() is outdated, $rev->isCurrent() won't tell us that.
118 if ( $rev->getId() == $pageObj->getLatest() ) {
119 // May get from/save to parser cache
120 $p_result = $this->getParsedContent( $pageObj, $popts,
121 $pageid, isset( $prop['wikitext'] ) );
122 } else { // This is an old revision, so get the text differently
123 $this->content = $rev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
125 if ( $this->section !== false ) {
126 $this->content = $this->getSectionContent( $this->content, 'r' . $rev->getId() );
129 // Should we save old revision parses to the parser cache?
130 $p_result = $this->content->getParserOutput( $titleObj, $rev->getId(), $popts );
132 } else { // Not $oldid, but $pageid or $page
133 if ( $params['redirects'] ) {
134 $reqParams = array(
135 'redirects' => '',
137 if ( !is_null( $pageid ) ) {
138 $reqParams['pageids'] = $pageid;
139 } else { // $page
140 $reqParams['titles'] = $page;
142 $req = new FauxRequest( $reqParams );
143 $main = new ApiMain( $req );
144 $pageSet = new ApiPageSet( $main );
145 $pageSet->execute();
146 $redirValues = $pageSet->getRedirectTitlesAsResult( $this->getResult() );
148 $to = $page;
149 foreach ( $pageSet->getRedirectTitles() as $title ) {
150 $to = $title->getFullText();
152 $pageParams = array( 'title' => $to );
153 } elseif ( !is_null( $pageid ) ) {
154 $pageParams = array( 'pageid' => $pageid );
155 } else { // $page
156 $pageParams = array( 'title' => $page );
159 $pageObj = $this->getTitleOrPageId( $pageParams, 'fromdb' );
160 $titleObj = $pageObj->getTitle();
161 if ( !$titleObj || !$titleObj->exists() ) {
162 $this->dieUsage( "The page you specified doesn't exist", 'missingtitle' );
164 $wgTitle = $titleObj;
166 if ( isset( $prop['revid'] ) ) {
167 $oldid = $pageObj->getLatest();
170 $popts = $this->makeParserOptions( $pageObj, $params );
172 // Don't pollute the parser cache when setting options that aren't
173 // in ParserOptions::optionsHash()
174 /// @todo: This should be handled closer to the actual cache instead of here, see T110269
175 $suppressCache =
176 $params['disablepp'] ||
177 $params['disablelimitreport'] ||
178 $params['preview'] ||
179 $params['sectionpreview'] ||
180 $params['disabletidy'];
182 if ( $suppressCache ) {
183 $this->content = $this->getContent( $pageObj, $pageid );
184 $p_result = $this->content->getParserOutput( $titleObj, null, $popts );
185 } else {
186 // Potentially cached
187 $p_result = $this->getParsedContent( $pageObj, $popts, $pageid,
188 isset( $prop['wikitext'] ) );
191 } else { // Not $oldid, $pageid, $page. Hence based on $text
192 $titleObj = Title::newFromText( $title );
193 if ( !$titleObj || $titleObj->isExternal() ) {
194 $this->dieUsageMsg( array( 'invalidtitle', $title ) );
196 $wgTitle = $titleObj;
197 if ( $titleObj->canExist() ) {
198 $pageObj = WikiPage::factory( $titleObj );
199 } else {
200 // Do like MediaWiki::initializeArticle()
201 $article = Article::newFromTitle( $titleObj, $this->getContext() );
202 $pageObj = $article->getPage();
205 $popts = $this->makeParserOptions( $pageObj, $params );
206 $textProvided = !is_null( $text );
208 if ( !$textProvided ) {
209 if ( $titleProvided && ( $prop || $params['generatexml'] ) ) {
210 $this->setWarning(
211 "'title' used without 'text', and parsed page properties were requested " .
212 "(did you mean to use 'page' instead of 'title'?)"
215 // Prevent warning from ContentHandler::makeContent()
216 $text = '';
219 // If we are parsing text, do not use the content model of the default
220 // API title, but default to wikitext to keep BC.
221 if ( $textProvided && !$titleProvided && is_null( $model ) ) {
222 $model = CONTENT_MODEL_WIKITEXT;
223 $this->setWarning( "No 'title' or 'contentmodel' was given, assuming $model." );
226 try {
227 $this->content = ContentHandler::makeContent( $text, $titleObj, $model, $format );
228 } catch ( MWContentSerializationException $ex ) {
229 $this->dieUsage( $ex->getMessage(), 'parseerror' );
232 if ( $this->section !== false ) {
233 if ( $this->section === 'new' ) {
234 // Insert the section title above the content.
235 if ( !is_null( $params['sectiontitle'] ) && $params['sectiontitle'] !== '' ) {
236 $this->content = $this->content->addSectionHeader( $params['sectiontitle'] );
238 } else {
239 $this->content = $this->getSectionContent( $this->content, $titleObj->getPrefixedText() );
243 if ( $params['pst'] || $params['onlypst'] ) {
244 $this->pstContent = $this->content->preSaveTransform( $titleObj, $this->getUser(), $popts );
246 if ( $params['onlypst'] ) {
247 // Build a result and bail out
248 $result_array = array();
249 $result_array['text'] = $this->pstContent->serialize( $format );
250 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
251 if ( isset( $prop['wikitext'] ) ) {
252 $result_array['wikitext'] = $this->content->serialize( $format );
253 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'wikitext';
255 if ( !is_null( $params['summary'] ) ||
256 ( !is_null( $params['sectiontitle'] ) && $this->section === 'new' )
258 $result_array['parsedsummary'] = $this->formatSummary( $titleObj, $params );
259 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsedsummary';
262 $result->addValue( null, $this->getModuleName(), $result_array );
264 return;
267 // Not cached (save or load)
268 if ( $params['pst'] ) {
269 $p_result = $this->pstContent->getParserOutput( $titleObj, null, $popts );
270 } else {
271 $p_result = $this->content->getParserOutput( $titleObj, null, $popts );
275 $result_array = array();
277 $result_array['title'] = $titleObj->getPrefixedText();
278 $result_array['pageid'] = $pageid ? $pageid : $pageObj->getId();
280 if ( !is_null( $oldid ) ) {
281 $result_array['revid'] = intval( $oldid );
284 if ( $params['redirects'] && !is_null( $redirValues ) ) {
285 $result_array['redirects'] = $redirValues;
288 if ( $params['disabletoc'] ) {
289 $p_result->setTOCEnabled( false );
292 if ( isset( $prop['text'] ) ) {
293 $result_array['text'] = $p_result->getText();
294 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
297 if ( !is_null( $params['summary'] ) ||
298 ( !is_null( $params['sectiontitle'] ) && $this->section === 'new' )
300 $result_array['parsedsummary'] = $this->formatSummary( $titleObj, $params );
301 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsedsummary';
304 if ( isset( $prop['langlinks'] ) ) {
305 $langlinks = $p_result->getLanguageLinks();
307 if ( $params['effectivelanglinks'] ) {
308 // Link flags are ignored for now, but may in the future be
309 // included in the result.
310 $linkFlags = array();
311 Hooks::run( 'LanguageLinks', array( $titleObj, &$langlinks, &$linkFlags ) );
313 } else {
314 $langlinks = false;
317 if ( isset( $prop['langlinks'] ) ) {
318 $result_array['langlinks'] = $this->formatLangLinks( $langlinks );
320 if ( isset( $prop['categories'] ) ) {
321 $result_array['categories'] = $this->formatCategoryLinks( $p_result->getCategories() );
323 if ( isset( $prop['categorieshtml'] ) ) {
324 $result_array['categorieshtml'] = $this->categoriesHtml( $p_result->getCategories() );
325 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'categorieshtml';
327 if ( isset( $prop['links'] ) ) {
328 $result_array['links'] = $this->formatLinks( $p_result->getLinks() );
330 if ( isset( $prop['templates'] ) ) {
331 $result_array['templates'] = $this->formatLinks( $p_result->getTemplates() );
333 if ( isset( $prop['images'] ) ) {
334 $result_array['images'] = array_keys( $p_result->getImages() );
336 if ( isset( $prop['externallinks'] ) ) {
337 $result_array['externallinks'] = array_keys( $p_result->getExternalLinks() );
339 if ( isset( $prop['sections'] ) ) {
340 $result_array['sections'] = $p_result->getSections();
343 if ( isset( $prop['displaytitle'] ) ) {
344 $result_array['displaytitle'] = $p_result->getDisplayTitle() ?
345 $p_result->getDisplayTitle() :
346 $titleObj->getPrefixedText();
349 if ( isset( $prop['headitems'] ) || isset( $prop['headhtml'] ) ) {
350 $context = $this->getContext();
351 $context->setTitle( $titleObj );
352 $context->getOutput()->addParserOutputMetadata( $p_result );
354 if ( isset( $prop['headitems'] ) ) {
355 $headItems = $this->formatHeadItems( $p_result->getHeadItems() );
357 $css = $this->formatCss( $context->getOutput()->buildCssLinksArray() );
359 $scripts = array( $context->getOutput()->getHeadScripts() );
361 $result_array['headitems'] = array_merge( $headItems, $css, $scripts );
364 if ( isset( $prop['headhtml'] ) ) {
365 $result_array['headhtml'] = $context->getOutput()->headElement( $context->getSkin() );
366 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'headhtml';
370 if ( isset( $prop['modules'] ) ) {
371 $result_array['modules'] = array_values( array_unique( $p_result->getModules() ) );
372 $result_array['modulescripts'] = array_values( array_unique( $p_result->getModuleScripts() ) );
373 $result_array['modulestyles'] = array_values( array_unique( $p_result->getModuleStyles() ) );
374 // To be removed in 1.27
375 $result_array['modulemessages'] = array();
376 $this->setWarning( 'modulemessages is deprecated since MediaWiki 1.26' );
379 if ( isset( $prop['jsconfigvars'] ) ) {
380 $result_array['jsconfigvars'] =
381 ApiResult::addMetadataToResultVars( $p_result->getJsConfigVars() );
384 if ( isset( $prop['encodedjsconfigvars'] ) ) {
385 $result_array['encodedjsconfigvars'] = FormatJson::encode(
386 $p_result->getJsConfigVars(), false, FormatJson::ALL_OK
388 $result_array[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
391 if ( isset( $prop['modules'] ) &&
392 !isset( $prop['jsconfigvars'] ) && !isset( $prop['encodedjsconfigvars'] ) ) {
393 $this->setWarning( "Property 'modules' was set but not 'jsconfigvars' " .
394 "or 'encodedjsconfigvars'. Configuration variables are necessary " .
395 "for proper module usage." );
398 if ( isset( $prop['indicators'] ) ) {
399 $result_array['indicators'] = (array)$p_result->getIndicators();
400 ApiResult::setArrayType( $result_array['indicators'], 'BCkvp', 'name' );
403 if ( isset( $prop['iwlinks'] ) ) {
404 $result_array['iwlinks'] = $this->formatIWLinks( $p_result->getInterwikiLinks() );
407 if ( isset( $prop['wikitext'] ) ) {
408 $result_array['wikitext'] = $this->content->serialize( $format );
409 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'wikitext';
410 if ( !is_null( $this->pstContent ) ) {
411 $result_array['psttext'] = $this->pstContent->serialize( $format );
412 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'psttext';
415 if ( isset( $prop['properties'] ) ) {
416 $result_array['properties'] = (array)$p_result->getProperties();
417 ApiResult::setArrayType( $result_array['properties'], 'BCkvp', 'name' );
420 if ( isset( $prop['limitreportdata'] ) ) {
421 $result_array['limitreportdata'] =
422 $this->formatLimitReportData( $p_result->getLimitReportData() );
424 if ( isset( $prop['limitreporthtml'] ) ) {
425 $result_array['limitreporthtml'] = EditPage::getPreviewLimitReport( $p_result );
426 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'limitreporthtml';
429 if ( isset( $prop['parsetree'] ) || $params['generatexml'] ) {
430 if ( $this->content->getModel() != CONTENT_MODEL_WIKITEXT ) {
431 $this->dieUsage( "parsetree is only supported for wikitext content", "notwikitext" );
434 $wgParser->startExternalParse( $titleObj, $popts, Parser::OT_PREPROCESS );
435 $dom = $wgParser->preprocessToDom( $this->content->getNativeData() );
436 if ( is_callable( array( $dom, 'saveXML' ) ) ) {
437 $xml = $dom->saveXML();
438 } else {
439 $xml = $dom->__toString();
441 $result_array['parsetree'] = $xml;
442 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsetree';
445 $result_mapping = array(
446 'redirects' => 'r',
447 'langlinks' => 'll',
448 'categories' => 'cl',
449 'links' => 'pl',
450 'templates' => 'tl',
451 'images' => 'img',
452 'externallinks' => 'el',
453 'iwlinks' => 'iw',
454 'sections' => 's',
455 'headitems' => 'hi',
456 'modules' => 'm',
457 'indicators' => 'ind',
458 'modulescripts' => 'm',
459 'modulestyles' => 'm',
460 'modulemessages' => 'm',
461 'properties' => 'pp',
462 'limitreportdata' => 'lr',
464 $this->setIndexedTagNames( $result_array, $result_mapping );
465 $result->addValue( null, $this->getModuleName(), $result_array );
469 * Constructs a ParserOptions object
471 * @param WikiPage $pageObj
472 * @param array $params
474 * @return ParserOptions
476 protected function makeParserOptions( WikiPage $pageObj, array $params ) {
478 $popts = $pageObj->makeParserOptions( $this->getContext() );
479 $popts->enableLimitReport( !$params['disablepp'] && !$params['disablelimitreport'] );
480 $popts->setIsPreview( $params['preview'] || $params['sectionpreview'] );
481 $popts->setIsSectionPreview( $params['sectionpreview'] );
482 $popts->setEditSection( !$params['disableeditsection'] );
483 if ( $params['disabletidy'] ) {
484 $popts->setTidy( false );
487 return $popts;
491 * @param WikiPage $page
492 * @param ParserOptions $popts
493 * @param int $pageId
494 * @param bool $getWikitext
495 * @return ParserOutput
497 private function getParsedContent( WikiPage $page, $popts, $pageId = null, $getWikitext = false ) {
498 $this->content = $this->getContent( $page, $pageId );
500 if ( $this->section !== false && $this->content !== null ) {
501 // Not cached (save or load)
502 return $this->content->getParserOutput( $page->getTitle(), null, $popts );
505 // Try the parser cache first
506 // getParserOutput will save to Parser cache if able
507 $pout = $page->getParserOutput( $popts );
508 if ( !$pout ) {
509 $this->dieUsage( "There is no revision ID {$page->getLatest()}", 'missingrev' );
511 if ( $getWikitext ) {
512 $this->content = $page->getContent( Revision::RAW );
515 return $pout;
519 * Get the content for the given page and the requested section.
521 * @param WikiPage $page
522 * @param int $pageId
523 * @return Content
525 private function getContent( WikiPage $page, $pageId = null ) {
526 $content = $page->getContent( Revision::RAW ); // XXX: really raw?
528 if ( $this->section !== false && $content !== null ) {
529 $content = $this->getSectionContent(
530 $content,
531 !is_null( $pageId ) ? 'page id ' . $pageId : $page->getTitle()->getPrefixedText()
534 return $content;
538 * Extract the requested section from the given Content
540 * @param Content $content
541 * @param string $what Identifies the content in error messages, e.g. page title.
542 * @return Content|bool
544 private function getSectionContent( Content $content, $what ) {
545 // Not cached (save or load)
546 $section = $content->getSection( $this->section );
547 if ( $section === false ) {
548 $this->dieUsage( "There is no section {$this->section} in " . $what, 'nosuchsection' );
550 if ( $section === null ) {
551 $this->dieUsage( "Sections are not supported by " . $what, 'nosuchsection' );
552 $section = false;
555 return $section;
559 * This mimicks the behavior of EditPage in formatting a summary
561 * @param Title $title of the page being parsed
562 * @param Array $params the API parameters of the request
563 * @return Content|bool
565 private function formatSummary( $title, $params ) {
566 global $wgParser;
567 $summary = !is_null( $params['summary'] ) ? $params['summary'] : '';
568 $sectionTitle = !is_null( $params['sectiontitle'] ) ? $params['sectiontitle'] : '';
570 if ( $this->section === 'new' && ( $sectionTitle === '' || $summary === '' ) ) {
571 if ( $sectionTitle !== '' ) {
572 $summary = $params['sectiontitle'];
574 if ( $summary !== '' ) {
575 $summary = wfMessage( 'newsectionsummary' )
576 ->rawParams( $wgParser->stripSectionName( $summary ) )
577 ->inContentLanguage()->text();
580 return Linker::formatComment( $summary, $title, $this->section === 'new' );
583 private function formatLangLinks( $links ) {
584 $result = array();
585 foreach ( $links as $link ) {
586 $entry = array();
587 $bits = explode( ':', $link, 2 );
588 $title = Title::newFromText( $link );
590 $entry['lang'] = $bits[0];
591 if ( $title ) {
592 $entry['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
593 // localised language name in 'uselang' language
594 $entry['langname'] = Language::fetchLanguageName(
595 $title->getInterwiki(),
596 $this->getLanguage()->getCode()
599 // native language name
600 $entry['autonym'] = Language::fetchLanguageName( $title->getInterwiki() );
602 ApiResult::setContentValue( $entry, 'title', $bits[1] );
603 $result[] = $entry;
606 return $result;
609 private function formatCategoryLinks( $links ) {
610 $result = array();
612 if ( !$links ) {
613 return $result;
616 // Fetch hiddencat property
617 $lb = new LinkBatch;
618 $lb->setArray( array( NS_CATEGORY => $links ) );
619 $db = $this->getDB();
620 $res = $db->select( array( 'page', 'page_props' ),
621 array( 'page_title', 'pp_propname' ),
622 $lb->constructSet( 'page', $db ),
623 __METHOD__,
624 array(),
625 array( 'page_props' => array(
626 'LEFT JOIN', array( 'pp_propname' => 'hiddencat', 'pp_page = page_id' )
629 $hiddencats = array();
630 foreach ( $res as $row ) {
631 $hiddencats[$row->page_title] = isset( $row->pp_propname );
634 foreach ( $links as $link => $sortkey ) {
635 $entry = array();
636 $entry['sortkey'] = $sortkey;
637 // array keys will cast numeric category names to ints, so cast back to string
638 ApiResult::setContentValue( $entry, 'category', (string)$link );
639 if ( !isset( $hiddencats[$link] ) ) {
640 $entry['missing'] = true;
641 } elseif ( $hiddencats[$link] ) {
642 $entry['hidden'] = true;
644 $result[] = $entry;
647 return $result;
650 private function categoriesHtml( $categories ) {
651 $context = $this->getContext();
652 $context->getOutput()->addCategoryLinks( $categories );
654 return $context->getSkin()->getCategories();
657 private function formatLinks( $links ) {
658 $result = array();
659 foreach ( $links as $ns => $nslinks ) {
660 foreach ( $nslinks as $title => $id ) {
661 $entry = array();
662 $entry['ns'] = $ns;
663 ApiResult::setContentValue( $entry, 'title', Title::makeTitle( $ns, $title )->getFullText() );
664 $entry['exists'] = $id != 0;
665 $result[] = $entry;
669 return $result;
672 private function formatIWLinks( $iw ) {
673 $result = array();
674 foreach ( $iw as $prefix => $titles ) {
675 foreach ( array_keys( $titles ) as $title ) {
676 $entry = array();
677 $entry['prefix'] = $prefix;
679 $title = Title::newFromText( "{$prefix}:{$title}" );
680 if ( $title ) {
681 $entry['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
684 ApiResult::setContentValue( $entry, 'title', $title->getFullText() );
685 $result[] = $entry;
689 return $result;
692 private function formatHeadItems( $headItems ) {
693 $result = array();
694 foreach ( $headItems as $tag => $content ) {
695 $entry = array();
696 $entry['tag'] = $tag;
697 ApiResult::setContentValue( $entry, 'content', $content );
698 $result[] = $entry;
701 return $result;
704 private function formatCss( $css ) {
705 $result = array();
706 foreach ( $css as $file => $link ) {
707 $entry = array();
708 $entry['file'] = $file;
709 ApiResult::setContentValue( $entry, 'link', $link );
710 $result[] = $entry;
713 return $result;
716 private function formatLimitReportData( $limitReportData ) {
717 $result = array();
719 foreach ( $limitReportData as $name => $value ) {
720 $entry = array();
721 $entry['name'] = $name;
722 if ( !is_array( $value ) ) {
723 $value = array( $value );
725 ApiResult::setIndexedTagNameRecursive( $value, 'param' );
726 $entry = array_merge( $entry, $value );
727 $result[] = $entry;
730 return $result;
733 private function setIndexedTagNames( &$array, $mapping ) {
734 foreach ( $mapping as $key => $name ) {
735 if ( isset( $array[$key] ) ) {
736 ApiResult::setIndexedTagName( $array[$key], $name );
741 public function getAllowedParams() {
742 return array(
743 'title' => null,
744 'text' => array(
745 ApiBase::PARAM_TYPE => 'text',
747 'summary' => null,
748 'page' => null,
749 'pageid' => array(
750 ApiBase::PARAM_TYPE => 'integer',
752 'redirects' => false,
753 'oldid' => array(
754 ApiBase::PARAM_TYPE => 'integer',
756 'prop' => array(
757 ApiBase::PARAM_DFLT => 'text|langlinks|categories|links|templates|' .
758 'images|externallinks|sections|revid|displaytitle|iwlinks|properties',
759 ApiBase::PARAM_ISMULTI => true,
760 ApiBase::PARAM_TYPE => array(
761 'text',
762 'langlinks',
763 'categories',
764 'categorieshtml',
765 'links',
766 'templates',
767 'images',
768 'externallinks',
769 'sections',
770 'revid',
771 'displaytitle',
772 'headitems',
773 'headhtml',
774 'modules',
775 'jsconfigvars',
776 'encodedjsconfigvars',
777 'indicators',
778 'iwlinks',
779 'wikitext',
780 'properties',
781 'limitreportdata',
782 'limitreporthtml',
783 'parsetree',
785 ApiBase::PARAM_HELP_MSG_PER_VALUE => array(
786 'parsetree' => array( 'apihelp-parse-paramvalue-prop-parsetree', CONTENT_MODEL_WIKITEXT ),
789 'pst' => false,
790 'onlypst' => false,
791 'effectivelanglinks' => false,
792 'section' => null,
793 'sectiontitle' => array(
794 ApiBase::PARAM_TYPE => 'string',
796 'disablepp' => array(
797 ApiBase::PARAM_DFLT => false,
798 ApiBase::PARAM_DEPRECATED => true,
800 'disablelimitreport' => false,
801 'disableeditsection' => false,
802 'disabletidy' => false,
803 'generatexml' => array(
804 ApiBase::PARAM_DFLT => false,
805 ApiBase::PARAM_HELP_MSG => array(
806 'apihelp-parse-param-generatexml', CONTENT_MODEL_WIKITEXT
808 ApiBase::PARAM_DEPRECATED => true,
810 'preview' => false,
811 'sectionpreview' => false,
812 'disabletoc' => false,
813 'contentformat' => array(
814 ApiBase::PARAM_TYPE => ContentHandler::getAllContentFormats(),
816 'contentmodel' => array(
817 ApiBase::PARAM_TYPE => ContentHandler::getContentModels(),
822 protected function getExamplesMessages() {
823 return array(
824 'action=parse&page=Project:Sandbox'
825 => 'apihelp-parse-example-page',
826 'action=parse&text={{Project:Sandbox}}&contentmodel=wikitext'
827 => 'apihelp-parse-example-text',
828 'action=parse&text={{PAGENAME}}&title=Test'
829 => 'apihelp-parse-example-texttitle',
830 'action=parse&summary=Some+[[link]]&prop='
831 => 'apihelp-parse-example-summary',
835 public function getHelpUrls() {
836 return 'https://www.mediawiki.org/wiki/API:Parsing_wikitext#parse';