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