Merge "Mostly revert "Verify parameter for MapCacheLRU::has() can be passed to array_...
[lhc/web/wiklou.git] / includes / api / ApiParse.php
1 <?php
2 /**
3 * Created on Dec 01, 2007
4 *
5 * Copyright © 2007 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
6 *
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.
11 *
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.
16 *
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
21 *
22 * @file
23 */
24
25 /**
26 * @ingroup API
27 */
28 class ApiParse extends ApiBase {
29
30 /** @var string $section */
31 private $section = null;
32
33 /** @var Content $content */
34 private $content = null;
35
36 /** @var Content $pstContent */
37 private $pstContent = null;
38
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' );
42
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;
53 }
54
55 $page = $params['page'];
56 $pageid = $params['pageid'];
57 $oldid = $params['oldid'];
58
59 $model = $params['contentmodel'];
60 $format = $params['contentformat'];
61
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'
66 );
67 }
68
69 $prop = array_flip( $params['prop'] );
70
71 if ( isset( $params['section'] ) ) {
72 $this->section = $params['section'];
73 if ( !preg_match( '/^((T-)?\d+|new)$/', $this->section ) ) {
74 $this->dieUsage( "The section parameter must be a valid section id or 'new'", "invalidsection" );
75 }
76 } else {
77 $this->section = false;
78 }
79
80 // The parser needs $wgTitle to be set, apparently the
81 // $title parameter in Parser::parse isn't enough *sigh*
82 // TODO: Does this still need $wgTitle?
83 global $wgParser, $wgTitle;
84
85 $redirValues = null;
86
87 // Return result
88 $result = $this->getResult();
89
90 if ( !is_null( $oldid ) || !is_null( $pageid ) || !is_null( $page ) ) {
91 if ( $this->section === 'new' ) {
92 $this->dieUsage( 'section=new cannot be combined with oldid, pageid or page parameters. Please use text', 'params' );
93 }
94 if ( !is_null( $oldid ) ) {
95 // Don't use the parser cache
96 $rev = Revision::newFromId( $oldid );
97 if ( !$rev ) {
98 $this->dieUsage( "There is no revision ID $oldid", 'missingrev' );
99 }
100 if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
101 $this->dieUsage( "You don't have permission to view deleted revisions", 'permissiondenied' );
102 }
103
104 $titleObj = $rev->getTitle();
105 $wgTitle = $titleObj;
106 $pageObj = WikiPage::factory( $titleObj );
107 $popts = $this->makeParserOptions( $pageObj, $params );
108
109 // If for some reason the "oldid" is actually the current revision, it may be cached
110 if ( $rev->isCurrent() ) {
111 // May get from/save to parser cache
112 $p_result = $this->getParsedContent( $pageObj, $popts,
113 $pageid, isset( $prop['wikitext'] ) );
114 } else { // This is an old revision, so get the text differently
115 $this->content = $rev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
116
117 if ( $this->section !== false ) {
118 $this->content = $this->getSectionContent( $this->content, 'r' . $rev->getId() );
119 }
120
121 // Should we save old revision parses to the parser cache?
122 $p_result = $this->content->getParserOutput( $titleObj, $rev->getId(), $popts );
123 }
124 } else { // Not $oldid, but $pageid or $page
125 if ( $params['redirects'] ) {
126 $reqParams = array(
127 'action' => 'query',
128 'redirects' => '',
129 );
130 if ( !is_null( $pageid ) ) {
131 $reqParams['pageids'] = $pageid;
132 } else { // $page
133 $reqParams['titles'] = $page;
134 }
135 $req = new FauxRequest( $reqParams );
136 $main = new ApiMain( $req );
137 $main->execute();
138 $data = $main->getResultData();
139 $redirValues = isset( $data['query']['redirects'] )
140 ? $data['query']['redirects']
141 : array();
142 $to = $page;
143 foreach ( (array)$redirValues as $r ) {
144 $to = $r['to'];
145 }
146 $pageParams = array( 'title' => $to );
147 } elseif ( !is_null( $pageid ) ) {
148 $pageParams = array( 'pageid' => $pageid );
149 } else { // $page
150 $pageParams = array( 'title' => $page );
151 }
152
153 $pageObj = $this->getTitleOrPageId( $pageParams, 'fromdb' );
154 $titleObj = $pageObj->getTitle();
155 if ( !$titleObj || !$titleObj->exists() ) {
156 $this->dieUsage( "The page you specified doesn't exist", 'missingtitle' );
157 }
158 $wgTitle = $titleObj;
159
160 if ( isset( $prop['revid'] ) ) {
161 $oldid = $pageObj->getLatest();
162 }
163
164 $popts = $this->makeParserOptions( $pageObj, $params );
165
166 // Potentially cached
167 $p_result = $this->getParsedContent( $pageObj, $popts, $pageid,
168 isset( $prop['wikitext'] ) );
169 }
170 } else { // Not $oldid, $pageid, $page. Hence based on $text
171 $titleObj = Title::newFromText( $title );
172 if ( !$titleObj || $titleObj->isExternal() ) {
173 $this->dieUsageMsg( array( 'invalidtitle', $title ) );
174 }
175 $wgTitle = $titleObj;
176 if ( $titleObj->canExist() ) {
177 $pageObj = WikiPage::factory( $titleObj );
178 } else {
179 // Do like MediaWiki::initializeArticle()
180 $article = Article::newFromTitle( $titleObj, $this->getContext() );
181 $pageObj = $article->getPage();
182 }
183
184 $popts = $this->makeParserOptions( $pageObj, $params );
185 $textProvided = !is_null( $text );
186
187 if ( !$textProvided ) {
188 if ( $titleProvided && ( $prop || $params['generatexml'] ) ) {
189 $this->setWarning(
190 "'title' used without 'text', and parsed page properties were requested " .
191 "(did you mean to use 'page' instead of 'title'?)"
192 );
193 }
194 // Prevent warning from ContentHandler::makeContent()
195 $text = '';
196 }
197
198 // If we are parsing text, do not use the content model of the default
199 // API title, but default to wikitext to keep BC.
200 if ( $textProvided && !$titleProvided && is_null( $model ) ) {
201 $model = CONTENT_MODEL_WIKITEXT;
202 $this->setWarning( "No 'title' or 'contentmodel' was given, assuming $model." );
203 }
204
205 try {
206 $this->content = ContentHandler::makeContent( $text, $titleObj, $model, $format );
207 } catch ( MWContentSerializationException $ex ) {
208 $this->dieUsage( $ex->getMessage(), 'parseerror' );
209 }
210
211 if ( $this->section !== false ) {
212 if ( $this->section === 'new' ) {
213 // Insert the section title above the content.
214 if ( !is_null( $params['sectiontitle'] ) && $params['sectiontitle'] !== '' ) {
215 $this->content = $this->content->addSectionHeader( $params['sectiontitle'] );
216 }
217 } else {
218 $this->content = $this->getSectionContent( $this->content, $titleObj->getPrefixedText() );
219 }
220 }
221
222 if ( $params['pst'] || $params['onlypst'] ) {
223 $this->pstContent = $this->content->preSaveTransform( $titleObj, $this->getUser(), $popts );
224 }
225 if ( $params['onlypst'] ) {
226 // Build a result and bail out
227 $result_array = array();
228 $result_array['text'] = array();
229 ApiResult::setContent( $result_array['text'], $this->pstContent->serialize( $format ) );
230 if ( isset( $prop['wikitext'] ) ) {
231 $result_array['wikitext'] = array();
232 ApiResult::setContent( $result_array['wikitext'], $this->content->serialize( $format ) );
233 }
234 if ( !is_null( $params['summary'] ) ||
235 ( !is_null( $params['sectiontitle'] ) && $this->section === 'new' )
236 ) {
237 $result_array['parsedsummary'] = array();
238 ApiResult::setContent( $result_array['parsedsummary'], $this->formatSummary( $titleObj, $params ) );
239 }
240
241 $result->addValue( null, $this->getModuleName(), $result_array );
242
243 return;
244 }
245
246 // Not cached (save or load)
247 if ( $params['pst'] ) {
248 $p_result = $this->pstContent->getParserOutput( $titleObj, null, $popts );
249 } else {
250 $p_result = $this->content->getParserOutput( $titleObj, null, $popts );
251 }
252 }
253
254 $result_array = array();
255
256 $result_array['title'] = $titleObj->getPrefixedText();
257
258 if ( !is_null( $oldid ) ) {
259 $result_array['revid'] = intval( $oldid );
260 }
261
262 if ( $params['redirects'] && !is_null( $redirValues ) ) {
263 $result_array['redirects'] = $redirValues;
264 }
265
266 if ( $params['disabletoc'] ) {
267 $p_result->setTOCEnabled( false );
268 }
269
270 if ( isset( $prop['text'] ) ) {
271 $result_array['text'] = array();
272 ApiResult::setContent( $result_array['text'], $p_result->getText() );
273 }
274
275 if ( !is_null( $params['summary'] ) ||
276 ( !is_null( $params['sectiontitle'] ) && $this->section === 'new' )
277 ) {
278 $result_array['parsedsummary'] = array();
279 ApiResult::setContent( $result_array['parsedsummary'], $this->formatSummary( $titleObj, $params ) );
280 }
281
282 if ( isset( $prop['langlinks'] ) ) {
283 $langlinks = $p_result->getLanguageLinks();
284
285 if ( $params['effectivelanglinks'] ) {
286 // Link flags are ignored for now, but may in the future be
287 // included in the result.
288 $linkFlags = array();
289 Hooks::run( 'LanguageLinks', array( $titleObj, &$langlinks, &$linkFlags ) );
290 }
291 } else {
292 $langlinks = false;
293 }
294
295 if ( isset( $prop['langlinks'] ) ) {
296 $result_array['langlinks'] = $this->formatLangLinks( $langlinks );
297 }
298 if ( isset( $prop['categories'] ) ) {
299 $result_array['categories'] = $this->formatCategoryLinks( $p_result->getCategories() );
300 }
301 if ( isset( $prop['categorieshtml'] ) ) {
302 $categoriesHtml = $this->categoriesHtml( $p_result->getCategories() );
303 $result_array['categorieshtml'] = array();
304 ApiResult::setContent( $result_array['categorieshtml'], $categoriesHtml );
305 }
306 if ( isset( $prop['links'] ) ) {
307 $result_array['links'] = $this->formatLinks( $p_result->getLinks() );
308 }
309 if ( isset( $prop['templates'] ) ) {
310 $result_array['templates'] = $this->formatLinks( $p_result->getTemplates() );
311 }
312 if ( isset( $prop['images'] ) ) {
313 $result_array['images'] = array_keys( $p_result->getImages() );
314 }
315 if ( isset( $prop['externallinks'] ) ) {
316 $result_array['externallinks'] = array_keys( $p_result->getExternalLinks() );
317 }
318 if ( isset( $prop['sections'] ) ) {
319 $result_array['sections'] = $p_result->getSections();
320 }
321
322 if ( isset( $prop['displaytitle'] ) ) {
323 $result_array['displaytitle'] = $p_result->getDisplayTitle() ?
324 $p_result->getDisplayTitle() :
325 $titleObj->getPrefixedText();
326 }
327
328 if ( isset( $prop['headitems'] ) || isset( $prop['headhtml'] ) ) {
329 $context = $this->getContext();
330 $context->setTitle( $titleObj );
331 $context->getOutput()->addParserOutputMetadata( $p_result );
332
333 if ( isset( $prop['headitems'] ) ) {
334 $headItems = $this->formatHeadItems( $p_result->getHeadItems() );
335
336 $css = $this->formatCss( $context->getOutput()->buildCssLinksArray() );
337
338 $scripts = array( $context->getOutput()->getHeadScripts() );
339
340 $result_array['headitems'] = array_merge( $headItems, $css, $scripts );
341 }
342
343 if ( isset( $prop['headhtml'] ) ) {
344 $result_array['headhtml'] = array();
345 ApiResult::setContent(
346 $result_array['headhtml'],
347 $context->getOutput()->headElement( $context->getSkin() )
348 );
349 }
350 }
351
352 if ( isset( $prop['modules'] ) ) {
353 $result_array['modules'] = array_values( array_unique( $p_result->getModules() ) );
354 $result_array['modulescripts'] = array_values( array_unique( $p_result->getModuleScripts() ) );
355 $result_array['modulestyles'] = array_values( array_unique( $p_result->getModuleStyles() ) );
356 $result_array['modulemessages'] = array_values( array_unique( $p_result->getModuleMessages() ) );
357 }
358
359 if ( isset( $prop['indicators'] ) ) {
360 foreach ( $p_result->getIndicators() as $name => $content ) {
361 $indicator = array( 'name' => $name );
362 ApiResult::setContent( $indicator, $content );
363 $result_array['indicators'][] = $indicator;
364 }
365 }
366
367 if ( isset( $prop['iwlinks'] ) ) {
368 $result_array['iwlinks'] = $this->formatIWLinks( $p_result->getInterwikiLinks() );
369 }
370
371 if ( isset( $prop['wikitext'] ) ) {
372 $result_array['wikitext'] = array();
373 ApiResult::setContent( $result_array['wikitext'], $this->content->serialize( $format ) );
374 if ( !is_null( $this->pstContent ) ) {
375 $result_array['psttext'] = array();
376 ApiResult::setContent( $result_array['psttext'], $this->pstContent->serialize( $format ) );
377 }
378 }
379 if ( isset( $prop['properties'] ) ) {
380 $result_array['properties'] = $this->formatProperties( $p_result->getProperties() );
381 }
382
383 if ( isset( $prop['limitreportdata'] ) ) {
384 $result_array['limitreportdata'] =
385 $this->formatLimitReportData( $p_result->getLimitReportData() );
386 }
387 if ( isset( $prop['limitreporthtml'] ) ) {
388 $limitreportHtml = EditPage::getPreviewLimitReport( $p_result );
389 $result_array['limitreporthtml'] = array();
390 ApiResult::setContent( $result_array['limitreporthtml'], $limitreportHtml );
391 }
392
393 if ( $params['generatexml'] ) {
394 if ( $this->content->getModel() != CONTENT_MODEL_WIKITEXT ) {
395 $this->dieUsage( "generatexml is only supported for wikitext content", "notwikitext" );
396 }
397
398 $wgParser->startExternalParse( $titleObj, $popts, Parser::OT_PREPROCESS );
399 $dom = $wgParser->preprocessToDom( $this->content->getNativeData() );
400 if ( is_callable( array( $dom, 'saveXML' ) ) ) {
401 $xml = $dom->saveXML();
402 } else {
403 $xml = $dom->__toString();
404 }
405 $result_array['parsetree'] = array();
406 ApiResult::setContent( $result_array['parsetree'], $xml );
407 }
408
409 $result_mapping = array(
410 'redirects' => 'r',
411 'langlinks' => 'll',
412 'categories' => 'cl',
413 'links' => 'pl',
414 'templates' => 'tl',
415 'images' => 'img',
416 'externallinks' => 'el',
417 'iwlinks' => 'iw',
418 'sections' => 's',
419 'headitems' => 'hi',
420 'modules' => 'm',
421 'indicators' => 'ind',
422 'modulescripts' => 'm',
423 'modulestyles' => 'm',
424 'modulemessages' => 'm',
425 'properties' => 'pp',
426 'limitreportdata' => 'lr',
427 );
428 $this->setIndexedTagNames( $result_array, $result_mapping );
429 $result->addValue( null, $this->getModuleName(), $result_array );
430 }
431
432 /**
433 * Constructs a ParserOptions object
434 *
435 * @param WikiPage $pageObj
436 * @param array $params
437 *
438 * @return ParserOptions
439 */
440 protected function makeParserOptions( WikiPage $pageObj, array $params ) {
441
442 $popts = $pageObj->makeParserOptions( $this->getContext() );
443 $popts->enableLimitReport( !$params['disablepp'] );
444 $popts->setIsPreview( $params['preview'] || $params['sectionpreview'] );
445 $popts->setIsSectionPreview( $params['sectionpreview'] );
446 $popts->setEditSection( !$params['disableeditsection'] );
447
448 return $popts;
449 }
450
451 /**
452 * @param WikiPage $page
453 * @param ParserOptions $popts
454 * @param int $pageId
455 * @param bool $getWikitext
456 * @return ParserOutput
457 */
458 private function getParsedContent( WikiPage $page, $popts, $pageId = null, $getWikitext = false ) {
459 $this->content = $page->getContent( Revision::RAW ); //XXX: really raw?
460
461 if ( $this->section !== false && $this->content !== null ) {
462 $this->content = $this->getSectionContent(
463 $this->content,
464 !is_null( $pageId ) ? 'page id ' . $pageId : $page->getTitle()->getPrefixedText()
465 );
466
467 // Not cached (save or load)
468 return $this->content->getParserOutput( $page->getTitle(), null, $popts );
469 }
470
471 // Try the parser cache first
472 // getParserOutput will save to Parser cache if able
473 $pout = $page->getParserOutput( $popts );
474 if ( !$pout ) {
475 $this->dieUsage( "There is no revision ID {$page->getLatest()}", 'missingrev' );
476 }
477 if ( $getWikitext ) {
478 $this->content = $page->getContent( Revision::RAW );
479 }
480
481 return $pout;
482 }
483
484 /**
485 * @param Content $content
486 * @param string $what Identifies the content in error messages, e.g. page title.
487 * @return Content|bool
488 */
489 private function getSectionContent( Content $content, $what ) {
490 // Not cached (save or load)
491 $section = $content->getSection( $this->section );
492 if ( $section === false ) {
493 $this->dieUsage( "There is no section {$this->section} in " . $what, 'nosuchsection' );
494 }
495 if ( $section === null ) {
496 $this->dieUsage( "Sections are not supported by " . $what, 'nosuchsection' );
497 $section = false;
498 }
499
500 return $section;
501 }
502
503 /**
504 * This mimicks the behavior of EditPage in formatting a summary
505 *
506 * @param Title $title of the page being parsed
507 * @param Array $params the API parameters of the request
508 * @return Content|bool
509 */
510 private function formatSummary( $title, $params ) {
511 global $wgParser;
512 $summary = !is_null( $params['summary'] ) ? $params['summary'] : '';
513 $sectionTitle = !is_null( $params['sectiontitle'] ) ? $params['sectiontitle'] : '';
514
515 if ( $this->section === 'new' && ( $sectionTitle === '' || $summary === '' ) ) {
516 if( $sectionTitle !== '' ) {
517 $summary = $params['sectiontitle'];
518 }
519 if ( $summary !== '' ) {
520 $summary = wfMessage( 'newsectionsummary' )->rawParams( $wgParser->stripSectionName( $summary ) )
521 ->inContentLanguage()->text();
522 }
523 }
524 return Linker::formatComment( $summary, $title, $this->section === 'new' );
525 }
526
527 private function formatLangLinks( $links ) {
528 $result = array();
529 foreach ( $links as $link ) {
530 $entry = array();
531 $bits = explode( ':', $link, 2 );
532 $title = Title::newFromText( $link );
533
534 $entry['lang'] = $bits[0];
535 if ( $title ) {
536 $entry['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
537 // localised language name in 'uselang' language
538 $entry['langname'] = Language::fetchLanguageName(
539 $title->getInterwiki(),
540 $this->getLanguage()->getCode()
541 );
542
543 // native language name
544 $entry['autonym'] = Language::fetchLanguageName( $title->getInterwiki() );
545 }
546 ApiResult::setContent( $entry, $bits[1] );
547 $result[] = $entry;
548 }
549
550 return $result;
551 }
552
553 private function formatCategoryLinks( $links ) {
554 $result = array();
555
556 if ( !$links ) {
557 return $result;
558 }
559
560 // Fetch hiddencat property
561 $lb = new LinkBatch;
562 $lb->setArray( array( NS_CATEGORY => $links ) );
563 $db = $this->getDB();
564 $res = $db->select( array( 'page', 'page_props' ),
565 array( 'page_title', 'pp_propname' ),
566 $lb->constructSet( 'page', $db ),
567 __METHOD__,
568 array(),
569 array( 'page_props' => array(
570 'LEFT JOIN', array( 'pp_propname' => 'hiddencat', 'pp_page = page_id' )
571 ) )
572 );
573 $hiddencats = array();
574 foreach ( $res as $row ) {
575 $hiddencats[$row->page_title] = isset( $row->pp_propname );
576 }
577
578 foreach ( $links as $link => $sortkey ) {
579 $entry = array();
580 $entry['sortkey'] = $sortkey;
581 ApiResult::setContent( $entry, $link );
582 if ( !isset( $hiddencats[$link] ) ) {
583 $entry['missing'] = '';
584 } elseif ( $hiddencats[$link] ) {
585 $entry['hidden'] = '';
586 }
587 $result[] = $entry;
588 }
589
590 return $result;
591 }
592
593 private function categoriesHtml( $categories ) {
594 $context = $this->getContext();
595 $context->getOutput()->addCategoryLinks( $categories );
596
597 return $context->getSkin()->getCategories();
598 }
599
600 private function formatLinks( $links ) {
601 $result = array();
602 foreach ( $links as $ns => $nslinks ) {
603 foreach ( $nslinks as $title => $id ) {
604 $entry = array();
605 $entry['ns'] = $ns;
606 ApiResult::setContent( $entry, Title::makeTitle( $ns, $title )->getFullText() );
607 if ( $id != 0 ) {
608 $entry['exists'] = '';
609 }
610 $result[] = $entry;
611 }
612 }
613
614 return $result;
615 }
616
617 private function formatIWLinks( $iw ) {
618 $result = array();
619 foreach ( $iw as $prefix => $titles ) {
620 foreach ( array_keys( $titles ) as $title ) {
621 $entry = array();
622 $entry['prefix'] = $prefix;
623
624 $title = Title::newFromText( "{$prefix}:{$title}" );
625 if ( $title ) {
626 $entry['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
627 }
628
629 ApiResult::setContent( $entry, $title->getFullText() );
630 $result[] = $entry;
631 }
632 }
633
634 return $result;
635 }
636
637 private function formatHeadItems( $headItems ) {
638 $result = array();
639 foreach ( $headItems as $tag => $content ) {
640 $entry = array();
641 $entry['tag'] = $tag;
642 ApiResult::setContent( $entry, $content );
643 $result[] = $entry;
644 }
645
646 return $result;
647 }
648
649 private function formatProperties( $properties ) {
650 $result = array();
651 foreach ( $properties as $name => $value ) {
652 $entry = array();
653 $entry['name'] = $name;
654 ApiResult::setContent( $entry, $value );
655 $result[] = $entry;
656 }
657
658 return $result;
659 }
660
661 private function formatCss( $css ) {
662 $result = array();
663 foreach ( $css as $file => $link ) {
664 $entry = array();
665 $entry['file'] = $file;
666 ApiResult::setContent( $entry, $link );
667 $result[] = $entry;
668 }
669
670 return $result;
671 }
672
673 private function formatLimitReportData( $limitReportData ) {
674 $result = array();
675 $apiResult = $this->getResult();
676
677 foreach ( $limitReportData as $name => $value ) {
678 $entry = array();
679 $entry['name'] = $name;
680 if ( !is_array( $value ) ) {
681 $value = array( $value );
682 }
683 $apiResult->setIndexedTagName( $value, 'param' );
684 $apiResult->setIndexedTagName_recursive( $value, 'param' );
685 $entry = array_merge( $entry, $value );
686 $result[] = $entry;
687 }
688
689 return $result;
690 }
691
692 private function setIndexedTagNames( &$array, $mapping ) {
693 foreach ( $mapping as $key => $name ) {
694 if ( isset( $array[$key] ) ) {
695 $this->getResult()->setIndexedTagName( $array[$key], $name );
696 }
697 }
698 }
699
700 public function getAllowedParams() {
701 return array(
702 'title' => null,
703 'text' => null,
704 'summary' => null,
705 'page' => null,
706 'pageid' => array(
707 ApiBase::PARAM_TYPE => 'integer',
708 ),
709 'redirects' => false,
710 'oldid' => array(
711 ApiBase::PARAM_TYPE => 'integer',
712 ),
713 'prop' => array(
714 ApiBase::PARAM_DFLT => 'text|langlinks|categories|links|templates|' .
715 'images|externallinks|sections|revid|displaytitle|iwlinks|properties',
716 ApiBase::PARAM_ISMULTI => true,
717 ApiBase::PARAM_TYPE => array(
718 'text',
719 'langlinks',
720 'categories',
721 'categorieshtml',
722 'links',
723 'templates',
724 'images',
725 'externallinks',
726 'sections',
727 'revid',
728 'displaytitle',
729 'headitems',
730 'headhtml',
731 'modules',
732 'indicators',
733 'iwlinks',
734 'wikitext',
735 'properties',
736 'limitreportdata',
737 'limitreporthtml',
738 )
739 ),
740 'pst' => false,
741 'onlypst' => false,
742 'effectivelanglinks' => false,
743 'section' => null,
744 'sectiontitle' => array(
745 ApiBase::PARAM_TYPE => 'string',
746 ),
747 'disablepp' => false,
748 'disableeditsection' => false,
749 'generatexml' => array(
750 ApiBase::PARAM_DFLT => false,
751 ApiBase::PARAM_HELP_MSG => array(
752 'apihelp-parse-param-generatexml', CONTENT_MODEL_WIKITEXT
753 ),
754 ),
755 'preview' => false,
756 'sectionpreview' => false,
757 'disabletoc' => false,
758 'contentformat' => array(
759 ApiBase::PARAM_TYPE => ContentHandler::getAllContentFormats(),
760 ),
761 'contentmodel' => array(
762 ApiBase::PARAM_TYPE => ContentHandler::getContentModels(),
763 )
764 );
765 }
766
767 protected function getExamplesMessages() {
768 return array(
769 'action=parse&page=Project:Sandbox'
770 => 'apihelp-parse-example-page',
771 'action=parse&text={{Project:Sandbox}}&contentmodel=wikitext'
772 => 'apihelp-parse-example-text',
773 'action=parse&text={{PAGENAME}}&title=Test'
774 => 'apihelp-parse-example-texttitle',
775 'action=parse&summary=Some+[[link]]&prop='
776 => 'apihelp-parse-example-summary',
777 );
778 }
779
780 public function getHelpUrls() {
781 return 'https://www.mediawiki.org/wiki/API:Parsing_wikitext#parse';
782 }
783 }