MediaWiki
REL1_22
|
00001 <?php 00028 class ApiParse extends ApiBase { 00029 00031 private $section = null; 00032 00034 private $content = null; 00035 00037 private $pstContent = null; 00038 00039 public function execute() { 00040 // The data is hot but user-dependent, like page views, so we set vary cookies 00041 $this->getMain()->setCacheMode( 'anon-public-user-private' ); 00042 00043 // Get parameters 00044 $params = $this->extractRequestParams(); 00045 $text = $params['text']; 00046 $title = $params['title']; 00047 if ( $title === null ) { 00048 $titleProvided = false; 00049 // A title is needed for parsing, so arbitrarily choose one 00050 $title = 'API'; 00051 } else { 00052 $titleProvided = true; 00053 } 00054 00055 $page = $params['page']; 00056 $pageid = $params['pageid']; 00057 $oldid = $params['oldid']; 00058 00059 $model = $params['contentmodel']; 00060 $format = $params['contentformat']; 00061 00062 if ( !is_null( $page ) && ( !is_null( $text ) || $titleProvided ) ) { 00063 $this->dieUsage( 'The page parameter cannot be used together with the text and title parameters', 'params' ); 00064 } 00065 00066 $prop = array_flip( $params['prop'] ); 00067 00068 if ( isset( $params['section'] ) ) { 00069 $this->section = $params['section']; 00070 } else { 00071 $this->section = false; 00072 } 00073 00074 // The parser needs $wgTitle to be set, apparently the 00075 // $title parameter in Parser::parse isn't enough *sigh* 00076 // TODO: Does this still need $wgTitle? 00077 global $wgParser, $wgTitle; 00078 00079 // Currently unnecessary, code to act as a safeguard against any change in current behavior of uselang 00080 $oldLang = null; 00081 if ( isset( $params['uselang'] ) && $params['uselang'] != $this->getContext()->getLanguage()->getCode() ) { 00082 $oldLang = $this->getContext()->getLanguage(); // Backup language 00083 $this->getContext()->setLanguage( Language::factory( $params['uselang'] ) ); 00084 } 00085 00086 $redirValues = null; 00087 00088 // Return result 00089 $result = $this->getResult(); 00090 00091 if ( !is_null( $oldid ) || !is_null( $pageid ) || !is_null( $page ) ) { 00092 if ( !is_null( $oldid ) ) { 00093 // Don't use the parser cache 00094 $rev = Revision::newFromID( $oldid ); 00095 if ( !$rev ) { 00096 $this->dieUsage( "There is no revision ID $oldid", 'missingrev' ); 00097 } 00098 if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) { 00099 $this->dieUsage( "You don't have permission to view deleted revisions", 'permissiondenied' ); 00100 } 00101 00102 $titleObj = $rev->getTitle(); 00103 $wgTitle = $titleObj; 00104 $pageObj = WikiPage::factory( $titleObj ); 00105 $popts = $this->makeParserOptions( $pageObj, $params ); 00106 00107 // If for some reason the "oldid" is actually the current revision, it may be cached 00108 if ( $rev->isCurrent() ) { 00109 // May get from/save to parser cache 00110 $p_result = $this->getParsedContent( $pageObj, $popts, 00111 $pageid, isset( $prop['wikitext'] ) ); 00112 } else { // This is an old revision, so get the text differently 00113 $this->content = $rev->getContent( Revision::FOR_THIS_USER, $this->getUser() ); 00114 00115 if ( $this->section !== false ) { 00116 $this->content = $this->getSectionContent( $this->content, 'r' . $rev->getId() ); 00117 } 00118 00119 // Should we save old revision parses to the parser cache? 00120 $p_result = $this->content->getParserOutput( $titleObj, $rev->getId(), $popts ); 00121 } 00122 } else { // Not $oldid, but $pageid or $page 00123 if ( $params['redirects'] ) { 00124 $reqParams = array( 00125 'action' => 'query', 00126 'redirects' => '', 00127 ); 00128 if ( !is_null ( $pageid ) ) { 00129 $reqParams['pageids'] = $pageid; 00130 } else { // $page 00131 $reqParams['titles'] = $page; 00132 } 00133 $req = new FauxRequest( $reqParams ); 00134 $main = new ApiMain( $req ); 00135 $main->execute(); 00136 $data = $main->getResultData(); 00137 $redirValues = isset( $data['query']['redirects'] ) 00138 ? $data['query']['redirects'] 00139 : array(); 00140 $to = $page; 00141 foreach ( (array)$redirValues as $r ) { 00142 $to = $r['to']; 00143 } 00144 $pageParams = array( 'title' => $to ); 00145 } elseif ( !is_null( $pageid ) ) { 00146 $pageParams = array( 'pageid' => $pageid ); 00147 } else { // $page 00148 $pageParams = array( 'title' => $page ); 00149 } 00150 00151 $pageObj = $this->getTitleOrPageId( $pageParams, 'fromdb' ); 00152 $titleObj = $pageObj->getTitle(); 00153 if ( !$titleObj || !$titleObj->exists() ) { 00154 $this->dieUsage( "The page you specified doesn't exist", 'missingtitle' ); 00155 } 00156 $wgTitle = $titleObj; 00157 00158 if ( isset( $prop['revid'] ) ) { 00159 $oldid = $pageObj->getLatest(); 00160 } 00161 00162 $popts = $this->makeParserOptions( $pageObj, $params ); 00163 00164 // Potentially cached 00165 $p_result = $this->getParsedContent( $pageObj, $popts, $pageid, 00166 isset( $prop['wikitext'] ) ); 00167 } 00168 } else { // Not $oldid, $pageid, $page. Hence based on $text 00169 $titleObj = Title::newFromText( $title ); 00170 if ( !$titleObj || $titleObj->isExternal() ) { 00171 $this->dieUsageMsg( array( 'invalidtitle', $title ) ); 00172 } 00173 if ( !$titleObj->canExist() ) { 00174 $this->dieUsage( "Namespace doesn't allow actual pages", 'pagecannotexist' ); 00175 } 00176 $wgTitle = $titleObj; 00177 $pageObj = WikiPage::factory( $titleObj ); 00178 00179 $popts = $this->makeParserOptions( $pageObj, $params ); 00180 00181 if ( is_null( $text ) ) { 00182 if ( $titleProvided && ( $prop || $params['generatexml'] ) ) { 00183 $this->setWarning( 00184 "'title' used without 'text', and parsed page properties were requested " . 00185 "(did you mean to use 'page' instead of 'title'?)" 00186 ); 00187 } 00188 // Prevent warning from ContentHandler::makeContent() 00189 $text = ''; 00190 } 00191 00192 // If we are parsing text, do not use the content model of the default 00193 // API title, but default to wikitext to keep BC. 00194 if ( !$titleProvided && is_null( $model ) ) { 00195 $model = CONTENT_MODEL_WIKITEXT; 00196 $this->setWarning( "No 'title' or 'contentmodel' was given, assuming $model." ); 00197 } 00198 00199 try { 00200 $this->content = ContentHandler::makeContent( $text, $titleObj, $model, $format ); 00201 } catch ( MWContentSerializationException $ex ) { 00202 $this->dieUsage( $ex->getMessage(), 'parseerror' ); 00203 } 00204 00205 if ( $this->section !== false ) { 00206 $this->content = $this->getSectionContent( $this->content, $titleObj->getText() ); 00207 } 00208 00209 if ( $params['pst'] || $params['onlypst'] ) { 00210 $this->pstContent = $this->content->preSaveTransform( $titleObj, $this->getUser(), $popts ); 00211 } 00212 if ( $params['onlypst'] ) { 00213 // Build a result and bail out 00214 $result_array = array(); 00215 $result_array['text'] = array(); 00216 ApiResult::setContent( $result_array['text'], $this->pstContent->serialize( $format ) ); 00217 if ( isset( $prop['wikitext'] ) ) { 00218 $result_array['wikitext'] = array(); 00219 ApiResult::setContent( $result_array['wikitext'], $this->content->serialize( $format ) ); 00220 } 00221 $result->addValue( null, $this->getModuleName(), $result_array ); 00222 return; 00223 } 00224 00225 // Not cached (save or load) 00226 if ( $params['pst'] ) { 00227 $p_result = $this->pstContent->getParserOutput( $titleObj, null, $popts ); 00228 } else { 00229 $p_result = $this->content->getParserOutput( $titleObj, null, $popts ); 00230 } 00231 } 00232 00233 $result_array = array(); 00234 00235 $result_array['title'] = $titleObj->getPrefixedText(); 00236 00237 if ( !is_null( $oldid ) ) { 00238 $result_array['revid'] = intval( $oldid ); 00239 } 00240 00241 if ( $params['redirects'] && !is_null( $redirValues ) ) { 00242 $result_array['redirects'] = $redirValues; 00243 } 00244 00245 if ( isset( $prop['text'] ) ) { 00246 $result_array['text'] = array(); 00247 ApiResult::setContent( $result_array['text'], $p_result->getText() ); 00248 } 00249 00250 if ( !is_null( $params['summary'] ) ) { 00251 $result_array['parsedsummary'] = array(); 00252 ApiResult::setContent( $result_array['parsedsummary'], Linker::formatComment( $params['summary'], $titleObj ) ); 00253 } 00254 00255 if ( isset( $prop['langlinks'] ) || isset( $prop['languageshtml'] ) ) { 00256 $langlinks = $p_result->getLanguageLinks(); 00257 00258 if ( $params['effectivelanglinks'] ) { 00259 // Link flags are ignored for now, but may in the future be 00260 // included in the result. 00261 $linkFlags = array(); 00262 wfRunHooks( 'LanguageLinks', array( $titleObj, &$langlinks, &$linkFlags ) ); 00263 } 00264 } else { 00265 $langlinks = false; 00266 } 00267 00268 if ( isset( $prop['langlinks'] ) ) { 00269 $result_array['langlinks'] = $this->formatLangLinks( $langlinks ); 00270 } 00271 if ( isset( $prop['languageshtml'] ) ) { 00272 $languagesHtml = $this->languagesHtml( $langlinks ); 00273 00274 $result_array['languageshtml'] = array(); 00275 ApiResult::setContent( $result_array['languageshtml'], $languagesHtml ); 00276 } 00277 if ( isset( $prop['categories'] ) ) { 00278 $result_array['categories'] = $this->formatCategoryLinks( $p_result->getCategories() ); 00279 } 00280 if ( isset( $prop['categorieshtml'] ) ) { 00281 $categoriesHtml = $this->categoriesHtml( $p_result->getCategories() ); 00282 $result_array['categorieshtml'] = array(); 00283 ApiResult::setContent( $result_array['categorieshtml'], $categoriesHtml ); 00284 } 00285 if ( isset( $prop['links'] ) ) { 00286 $result_array['links'] = $this->formatLinks( $p_result->getLinks() ); 00287 } 00288 if ( isset( $prop['templates'] ) ) { 00289 $result_array['templates'] = $this->formatLinks( $p_result->getTemplates() ); 00290 } 00291 if ( isset( $prop['images'] ) ) { 00292 $result_array['images'] = array_keys( $p_result->getImages() ); 00293 } 00294 if ( isset( $prop['externallinks'] ) ) { 00295 $result_array['externallinks'] = array_keys( $p_result->getExternalLinks() ); 00296 } 00297 if ( isset( $prop['sections'] ) ) { 00298 $result_array['sections'] = $p_result->getSections(); 00299 } 00300 00301 if ( isset( $prop['displaytitle'] ) ) { 00302 $result_array['displaytitle'] = $p_result->getDisplayTitle() ? 00303 $p_result->getDisplayTitle() : 00304 $titleObj->getPrefixedText(); 00305 } 00306 00307 if ( isset( $prop['headitems'] ) || isset( $prop['headhtml'] ) ) { 00308 $context = $this->getContext(); 00309 $context->setTitle( $titleObj ); 00310 $context->getOutput()->addParserOutputNoText( $p_result ); 00311 00312 if ( isset( $prop['headitems'] ) ) { 00313 $headItems = $this->formatHeadItems( $p_result->getHeadItems() ); 00314 00315 $css = $this->formatCss( $context->getOutput()->buildCssLinksArray() ); 00316 00317 $scripts = array( $context->getOutput()->getHeadScripts() ); 00318 00319 $result_array['headitems'] = array_merge( $headItems, $css, $scripts ); 00320 } 00321 00322 if ( isset( $prop['headhtml'] ) ) { 00323 $result_array['headhtml'] = array(); 00324 ApiResult::setContent( $result_array['headhtml'], $context->getOutput()->headElement( $context->getSkin() ) ); 00325 } 00326 } 00327 00328 if ( isset( $prop['iwlinks'] ) ) { 00329 $result_array['iwlinks'] = $this->formatIWLinks( $p_result->getInterwikiLinks() ); 00330 } 00331 00332 if ( isset( $prop['wikitext'] ) ) { 00333 $result_array['wikitext'] = array(); 00334 ApiResult::setContent( $result_array['wikitext'], $this->content->serialize( $format ) ); 00335 if ( !is_null( $this->pstContent ) ) { 00336 $result_array['psttext'] = array(); 00337 ApiResult::setContent( $result_array['psttext'], $this->pstContent->serialize( $format ) ); 00338 } 00339 } 00340 if ( isset( $prop['properties'] ) ) { 00341 $result_array['properties'] = $this->formatProperties( $p_result->getProperties() ); 00342 } 00343 00344 if ( $params['generatexml'] ) { 00345 if ( $this->content->getModel() != CONTENT_MODEL_WIKITEXT ) { 00346 $this->dieUsage( "generatexml is only supported for wikitext content", "notwikitext" ); 00347 } 00348 00349 $wgParser->startExternalParse( $titleObj, $popts, OT_PREPROCESS ); 00350 $dom = $wgParser->preprocessToDom( $this->content->getNativeData() ); 00351 if ( is_callable( array( $dom, 'saveXML' ) ) ) { 00352 $xml = $dom->saveXML(); 00353 } else { 00354 $xml = $dom->__toString(); 00355 } 00356 $result_array['parsetree'] = array(); 00357 ApiResult::setContent( $result_array['parsetree'], $xml ); 00358 } 00359 00360 $result_mapping = array( 00361 'redirects' => 'r', 00362 'langlinks' => 'll', 00363 'categories' => 'cl', 00364 'links' => 'pl', 00365 'templates' => 'tl', 00366 'images' => 'img', 00367 'externallinks' => 'el', 00368 'iwlinks' => 'iw', 00369 'sections' => 's', 00370 'headitems' => 'hi', 00371 'properties' => 'pp', 00372 ); 00373 $this->setIndexedTagNames( $result_array, $result_mapping ); 00374 $result->addValue( null, $this->getModuleName(), $result_array ); 00375 00376 if ( !is_null( $oldLang ) ) { 00377 $this->getContext()->setLanguage( $oldLang ); // Reset language to $oldLang 00378 } 00379 } 00380 00389 protected function makeParserOptions( WikiPage $pageObj, array $params ) { 00390 wfProfileIn( __METHOD__ ); 00391 00392 $popts = $pageObj->makeParserOptions( $this->getContext() ); 00393 $popts->enableLimitReport( !$params['disablepp'] ); 00394 $popts->setIsPreview( $params['preview'] || $params['sectionpreview'] ); 00395 $popts->setIsSectionPreview( $params['sectionpreview'] ); 00396 00397 wfProfileOut( __METHOD__ ); 00398 return $popts; 00399 } 00400 00408 private function getParsedContent( WikiPage $page, $popts, $pageId = null, $getWikitext = false ) { 00409 $this->content = $page->getContent( Revision::RAW ); //XXX: really raw? 00410 00411 if ( $this->section !== false && $this->content !== null ) { 00412 $this->content = $this->getSectionContent( 00413 $this->content, 00414 !is_null( $pageId ) ? 'page id ' . $pageId : $page->getTitle()->getText() ); 00415 00416 // Not cached (save or load) 00417 return $this->content->getParserOutput( $page->getTitle(), null, $popts ); 00418 } else { 00419 // Try the parser cache first 00420 // getParserOutput will save to Parser cache if able 00421 $pout = $page->getParserOutput( $popts ); 00422 if ( !$pout ) { 00423 $this->dieUsage( "There is no revision ID {$page->getLatest()}", 'missingrev' ); 00424 } 00425 if ( $getWikitext ) { 00426 $this->content = $page->getContent( Revision::RAW ); 00427 } 00428 return $pout; 00429 } 00430 } 00431 00432 private function getSectionContent( Content $content, $what ) { 00433 // Not cached (save or load) 00434 $section = $content->getSection( $this->section ); 00435 if ( $section === false ) { 00436 $this->dieUsage( "There is no section {$this->section} in " . $what, 'nosuchsection' ); 00437 } 00438 if ( $section === null ) { 00439 $this->dieUsage( "Sections are not supported by " . $what, 'nosuchsection' ); 00440 $section = false; 00441 } 00442 return $section; 00443 } 00444 00445 private function formatLangLinks( $links ) { 00446 $result = array(); 00447 foreach ( $links as $link ) { 00448 $entry = array(); 00449 $bits = explode( ':', $link, 2 ); 00450 $title = Title::newFromText( $link ); 00451 00452 $entry['lang'] = $bits[0]; 00453 if ( $title ) { 00454 $entry['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ); 00455 } 00456 ApiResult::setContent( $entry, $bits[1] ); 00457 $result[] = $entry; 00458 } 00459 return $result; 00460 } 00461 00462 private function formatCategoryLinks( $links ) { 00463 $result = array(); 00464 foreach ( $links as $link => $sortkey ) { 00465 $entry = array(); 00466 $entry['sortkey'] = $sortkey; 00467 ApiResult::setContent( $entry, $link ); 00468 $result[] = $entry; 00469 } 00470 return $result; 00471 } 00472 00473 private function categoriesHtml( $categories ) { 00474 $context = $this->getContext(); 00475 $context->getOutput()->addCategoryLinks( $categories ); 00476 return $context->getSkin()->getCategories(); 00477 } 00478 00485 private function languagesHtml( $languages ) { 00486 wfDeprecated( __METHOD__, '1.18' ); 00487 00488 global $wgContLang, $wgHideInterlanguageLinks; 00489 00490 if ( $wgHideInterlanguageLinks || count( $languages ) == 0 ) { 00491 return ''; 00492 } 00493 00494 $s = htmlspecialchars( wfMessage( 'otherlanguages' )->text() . wfMessage( 'colon-separator' )->text() ); 00495 00496 $langs = array(); 00497 foreach ( $languages as $l ) { 00498 $nt = Title::newFromText( $l ); 00499 $text = Language::fetchLanguageName( $nt->getInterwiki() ); 00500 00501 $langs[] = Html::element( 'a', 00502 array( 'href' => $nt->getFullURL(), 'title' => $nt->getText(), 'class' => 'external' ), 00503 $text == '' ? $l : $text ); 00504 } 00505 00506 $s .= implode( wfMessage( 'pipe-separator' )->escaped(), $langs ); 00507 00508 if ( $wgContLang->isRTL() ) { 00509 $s = Html::rawElement( 'span', array( 'dir' => 'LTR' ), $s ); 00510 } 00511 00512 return $s; 00513 } 00514 00515 private function formatLinks( $links ) { 00516 $result = array(); 00517 foreach ( $links as $ns => $nslinks ) { 00518 foreach ( $nslinks as $title => $id ) { 00519 $entry = array(); 00520 $entry['ns'] = $ns; 00521 ApiResult::setContent( $entry, Title::makeTitle( $ns, $title )->getFullText() ); 00522 if ( $id != 0 ) { 00523 $entry['exists'] = ''; 00524 } 00525 $result[] = $entry; 00526 } 00527 } 00528 return $result; 00529 } 00530 00531 private function formatIWLinks( $iw ) { 00532 $result = array(); 00533 foreach ( $iw as $prefix => $titles ) { 00534 foreach ( array_keys( $titles ) as $title ) { 00535 $entry = array(); 00536 $entry['prefix'] = $prefix; 00537 00538 $title = Title::newFromText( "{$prefix}:{$title}" ); 00539 if ( $title ) { 00540 $entry['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ); 00541 } 00542 00543 ApiResult::setContent( $entry, $title->getFullText() ); 00544 $result[] = $entry; 00545 } 00546 } 00547 return $result; 00548 } 00549 00550 private function formatHeadItems( $headItems ) { 00551 $result = array(); 00552 foreach ( $headItems as $tag => $content ) { 00553 $entry = array(); 00554 $entry['tag'] = $tag; 00555 ApiResult::setContent( $entry, $content ); 00556 $result[] = $entry; 00557 } 00558 return $result; 00559 } 00560 00561 private function formatProperties( $properties ) { 00562 $result = array(); 00563 foreach ( $properties as $name => $value ) { 00564 $entry = array(); 00565 $entry['name'] = $name; 00566 ApiResult::setContent( $entry, $value ); 00567 $result[] = $entry; 00568 } 00569 return $result; 00570 } 00571 00572 private function formatCss( $css ) { 00573 $result = array(); 00574 foreach ( $css as $file => $link ) { 00575 $entry = array(); 00576 $entry['file'] = $file; 00577 ApiResult::setContent( $entry, $link ); 00578 $result[] = $entry; 00579 } 00580 return $result; 00581 } 00582 00583 private function setIndexedTagNames( &$array, $mapping ) { 00584 foreach ( $mapping as $key => $name ) { 00585 if ( isset( $array[$key] ) ) { 00586 $this->getResult()->setIndexedTagName( $array[$key], $name ); 00587 } 00588 } 00589 } 00590 00591 public function getAllowedParams() { 00592 return array( 00593 'title' => null, 00594 'text' => null, 00595 'summary' => null, 00596 'page' => null, 00597 'pageid' => array( 00598 ApiBase::PARAM_TYPE => 'integer', 00599 ), 00600 'redirects' => false, 00601 'oldid' => array( 00602 ApiBase::PARAM_TYPE => 'integer', 00603 ), 00604 'prop' => array( 00605 ApiBase::PARAM_DFLT => 'text|langlinks|categories|links|templates|images|externallinks|sections|revid|displaytitle|iwlinks|properties', 00606 ApiBase::PARAM_ISMULTI => true, 00607 ApiBase::PARAM_TYPE => array( 00608 'text', 00609 'langlinks', 00610 'languageshtml', 00611 'categories', 00612 'categorieshtml', 00613 'links', 00614 'templates', 00615 'images', 00616 'externallinks', 00617 'sections', 00618 'revid', 00619 'displaytitle', 00620 'headitems', 00621 'headhtml', 00622 'iwlinks', 00623 'wikitext', 00624 'properties', 00625 ) 00626 ), 00627 'pst' => false, 00628 'onlypst' => false, 00629 'effectivelanglinks' => false, 00630 'uselang' => null, 00631 'section' => null, 00632 'disablepp' => false, 00633 'generatexml' => false, 00634 'preview' => false, 00635 'sectionpreview' => false, 00636 'contentformat' => array( 00637 ApiBase::PARAM_TYPE => ContentHandler::getAllContentFormats(), 00638 ), 00639 'contentmodel' => array( 00640 ApiBase::PARAM_TYPE => ContentHandler::getContentModels(), 00641 ) 00642 ); 00643 } 00644 00645 public function getParamDescription() { 00646 $p = $this->getModulePrefix(); 00647 $wikitext = CONTENT_MODEL_WIKITEXT; 00648 return array( 00649 'text' => "Text to parse. Use {$p}title or {$p}contentmodel to control the content model", 00650 'summary' => 'Summary to parse', 00651 'redirects' => "If the {$p}page or the {$p}pageid parameter is set to a redirect, resolve it", 00652 'title' => "Title of page the text belongs to. " . 00653 "If omitted, \"API\" is used as the title with content model $wikitext", 00654 'page' => "Parse the content of this page. Cannot be used together with {$p}text and {$p}title", 00655 'pageid' => "Parse the content of this page. Overrides {$p}page", 00656 'oldid' => "Parse the content of this revision. Overrides {$p}page and {$p}pageid", 00657 'prop' => array( 00658 'Which pieces of information to get', 00659 ' text - Gives the parsed text of the wikitext', 00660 ' langlinks - Gives the language links in the parsed wikitext', 00661 ' categories - Gives the categories in the parsed wikitext', 00662 ' categorieshtml - Gives the HTML version of the categories', 00663 ' languageshtml - Gives the HTML version of the language links', 00664 ' links - Gives the internal links in the parsed wikitext', 00665 ' templates - Gives the templates in the parsed wikitext', 00666 ' images - Gives the images in the parsed wikitext', 00667 ' externallinks - Gives the external links in the parsed wikitext', 00668 ' sections - Gives the sections in the parsed wikitext', 00669 ' revid - Adds the revision ID of the parsed page', 00670 ' displaytitle - Adds the title of the parsed wikitext', 00671 ' headitems - Gives items to put in the <head> of the page', 00672 ' headhtml - Gives parsed <head> of the page', 00673 ' iwlinks - Gives interwiki links in the parsed wikitext', 00674 ' wikitext - Gives the original wikitext that was parsed', 00675 ' properties - Gives various properties defined in the parsed wikitext', 00676 ), 00677 'effectivelanglinks' => array( 00678 'Includes language links supplied by extensions', 00679 '(for use with prop=langlinks|languageshtml)', 00680 ), 00681 'pst' => array( 00682 'Do a pre-save transform on the input before parsing it', 00683 "Only valid when used with {$p}text", 00684 ), 00685 'onlypst' => array( 00686 'Do a pre-save transform (PST) on the input, but don\'t parse it', 00687 'Returns the same wikitext, after a PST has been applied.', 00688 "Only valid when used with {$p}text", 00689 ), 00690 'uselang' => 'Which language to parse the request in', 00691 'section' => 'Only retrieve the content of this section number', 00692 'disablepp' => 'Disable the PP Report from the parser output', 00693 'generatexml' => "Generate XML parse tree (requires contentmodel=$wikitext)", 00694 'preview' => 'Parse in preview mode', 00695 'sectionpreview' => 'Parse in section preview mode (enables preview mode too)', 00696 'contentformat' => array( 00697 'Content serialization format used for the input text', 00698 "Only valid when used with {$p}text", 00699 ), 00700 'contentmodel' => array( 00701 "Content model of the input text. Default is the model of the " . 00702 "specified ${p}title, or $wikitext if ${p}title is not specified", 00703 "Only valid when used with {$p}text", 00704 ), 00705 ); 00706 } 00707 00708 public function getDescription() { 00709 $p = $this->getModulePrefix(); 00710 return array( 00711 'Parses content and returns parser output', 00712 'See the various prop-Modules of action=query to get information from the current version of a page', 00713 'There are several ways to specify the text to parse:', 00714 "1) Specify a page or revision, using {$p}page, {$p}pageid, or {$p}oldid.", 00715 "2) Specify content explicitly, using {$p}text, {$p}title, and {$p}contentmodel.", 00716 "3) Specify only a summary to parse. {$p}prop should be given an empty value.", 00717 ); 00718 } 00719 00720 public function getPossibleErrors() { 00721 return array_merge( parent::getPossibleErrors(), array( 00722 array( 'code' => 'params', 'info' => 'The page parameter cannot be used together with the text and title parameters' ), 00723 array( 'code' => 'missingrev', 'info' => 'There is no revision ID oldid' ), 00724 array( 'code' => 'permissiondenied', 'info' => 'You don\'t have permission to view deleted revisions' ), 00725 array( 'code' => 'missingtitle', 'info' => 'The page you specified doesn\'t exist' ), 00726 array( 'code' => 'nosuchsection', 'info' => 'There is no section sectionnumber in page' ), 00727 array( 'nosuchpageid' ), 00728 array( 'invalidtitle', 'title' ), 00729 array( 'code' => 'parseerror', 'info' => 'Failed to parse the given text.' ), 00730 array( 'code' => 'notwikitext', 'info' => 'The requested operation is only supported on wikitext content.' ), 00731 array( 'code' => 'pagecannotexist', 'info' => "Namespace doesn't allow actual pages" ), 00732 ) ); 00733 } 00734 00735 public function getExamples() { 00736 return array( 00737 'api.php?action=parse&page=Project:Sandbox' => 'Parse a page', 00738 'api.php?action=parse&text={{Project:Sandbox}}' => 'Parse wikitext', 00739 'api.php?action=parse&text={{PAGENAME}}&title=Test' => 'Parse wikitext, specifying the page title', 00740 'api.php?action=parse&summary=Some+[[link]]&prop=' => 'Parse a summary', 00741 ); 00742 } 00743 00744 public function getHelpUrls() { 00745 return 'https://www.mediawiki.org/wiki/API:Parsing_wikitext#parse'; 00746 } 00747 }