diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2013-08-12 09:28:15 +0200 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2013-08-12 09:28:15 +0200 |
commit | 08aa4418c30cfc18ccc69a0f0f9cb9e17be6c196 (patch) | |
tree | 577a29fb579188d16003a209ce2a2e9c5b0aa2bd /includes/api/ApiParse.php | |
parent | cacc939b34e315b85e2d72997811eb6677996cc1 (diff) |
Update to MediaWiki 1.21.1
Diffstat (limited to 'includes/api/ApiParse.php')
-rw-r--r-- | includes/api/ApiParse.php | 132 |
1 files changed, 85 insertions, 47 deletions
diff --git a/includes/api/ApiParse.php b/includes/api/ApiParse.php index db6e2bb8..09b7a882 100644 --- a/includes/api/ApiParse.php +++ b/includes/api/ApiParse.php @@ -26,11 +26,15 @@ * @ingroup API */ class ApiParse extends ApiBase { - private $section, $text, $pstText = null; - public function __construct( $main, $action ) { - parent::__construct( $main, $action ); - } + /** @var String $section */ + private $section = null; + + /** @var Content $content */ + private $content = null; + + /** @var Content $pstContent */ + private $pstContent = null; public function execute() { // The data is hot but user-dependent, like page views, so we set vary cookies @@ -44,6 +48,9 @@ class ApiParse extends ApiBase { $pageid = $params['pageid']; $oldid = $params['oldid']; + $model = $params['contentmodel']; + $format = $params['contentformat']; + if ( !is_null( $page ) && ( !is_null( $text ) || $title != 'API' ) ) { $this->dieUsage( 'The page parameter cannot be used together with the text and title parameters', 'params' ); } @@ -61,7 +68,7 @@ class ApiParse extends ApiBase { // TODO: Does this still need $wgTitle? global $wgParser, $wgTitle; - // Currently unnecessary, code to act as a safeguard against any change in current behaviour of uselang breaks + // Currently unnecessary, code to act as a safeguard against any change in current behavior of uselang $oldLang = null; if ( isset( $params['uselang'] ) && $params['uselang'] != $this->getContext()->getLanguage()->getCode() ) { $oldLang = $this->getContext()->getLanguage(); // Backup language @@ -91,19 +98,19 @@ class ApiParse extends ApiBase { $popts->enableLimitReport( !$params['disablepp'] ); // If for some reason the "oldid" is actually the current revision, it may be cached - if ( $titleObj->getLatestRevID() === intval( $oldid ) ) { + if ( $rev->isCurrent() ) { // May get from/save to parser cache - $p_result = $this->getParsedSectionOrText( $pageObj, $popts, $pageid, - isset( $prop['wikitext'] ) ) ; + $p_result = $this->getParsedContent( $pageObj, $popts, + $pageid, isset( $prop['wikitext'] ) ); } else { // This is an old revision, so get the text differently - $this->text = $rev->getText( Revision::FOR_THIS_USER, $this->getUser() ); + $this->content = $rev->getContent( Revision::FOR_THIS_USER, $this->getUser() ); if ( $this->section !== false ) { - $this->text = $this->getSectionText( $this->text, 'r' . $rev->getId() ); + $this->content = $this->getSectionContent( $this->content, 'r' . $rev->getId() ); } // Should we save old revision parses to the parser cache? - $p_result = $wgParser->parse( $this->text, $titleObj, $popts ); + $p_result = $this->content->getParserOutput( $titleObj, $rev->getId(), $popts ); } } else { // Not $oldid, but $pageid or $page if ( $params['redirects'] ) { @@ -136,6 +143,9 @@ class ApiParse extends ApiBase { $pageObj = $this->getTitleOrPageId( $pageParams, 'fromdb' ); $titleObj = $pageObj->getTitle(); + if ( !$titleObj || !$titleObj->exists() ) { + $this->dieUsage( "The page you specified doesn't exist", 'missingtitle' ); + } $wgTitle = $titleObj; if ( isset( $prop['revid'] ) ) { @@ -146,46 +156,59 @@ class ApiParse extends ApiBase { $popts->enableLimitReport( !$params['disablepp'] ); // Potentially cached - $p_result = $this->getParsedSectionOrText( $pageObj, $popts, $pageid, - isset( $prop['wikitext'] ) ) ; + $p_result = $this->getParsedContent( $pageObj, $popts, $pageid, + isset( $prop['wikitext'] ) ); } } else { // Not $oldid, $pageid, $page. Hence based on $text - - if ( is_null( $text ) ) { - $this->dieUsage( 'The text parameter should be passed with the title parameter. Should you be using the "page" parameter instead?', 'params' ); - } - $this->text = $text; $titleObj = Title::newFromText( $title ); - if ( !$titleObj ) { + if ( !$titleObj || $titleObj->isExternal() ) { $this->dieUsageMsg( array( 'invalidtitle', $title ) ); } + if ( !$titleObj->canExist() ) { + $this->dieUsage( "Namespace doesn't allow actual pages", 'pagecannotexist' ); + } $wgTitle = $titleObj; $pageObj = WikiPage::factory( $titleObj ); $popts = $pageObj->makeParserOptions( $this->getContext() ); $popts->enableLimitReport( !$params['disablepp'] ); + if ( is_null( $text ) ) { + $this->dieUsage( 'The text parameter should be passed with the title parameter. Should you be using the "page" parameter instead?', 'params' ); + } + + try { + $this->content = ContentHandler::makeContent( $text, $titleObj, $model, $format ); + } catch ( MWContentSerializationException $ex ) { + $this->dieUsage( $ex->getMessage(), 'parseerror' ); + } + if ( $this->section !== false ) { - $this->text = $this->getSectionText( $this->text, $titleObj->getText() ); + $this->content = $this->getSectionContent( $this->content, $titleObj->getText() ); } if ( $params['pst'] || $params['onlypst'] ) { - $this->pstText = $wgParser->preSaveTransform( $this->text, $titleObj, $this->getUser(), $popts ); + $this->pstContent = $this->content->preSaveTransform( $titleObj, $this->getUser(), $popts ); } if ( $params['onlypst'] ) { // Build a result and bail out $result_array = array(); $result_array['text'] = array(); - $result->setContent( $result_array['text'], $this->pstText ); + $result->setContent( $result_array['text'], $this->pstContent->serialize( $format ) ); if ( isset( $prop['wikitext'] ) ) { $result_array['wikitext'] = array(); - $result->setContent( $result_array['wikitext'], $this->text ); + $result->setContent( $result_array['wikitext'], $this->content->serialize( $format ) ); } $result->addValue( null, $this->getModuleName(), $result_array ); return; } + // Not cached (save or load) - $p_result = $wgParser->parse( $params['pst'] ? $this->pstText : $this->text, $titleObj, $popts ); + if ( $params['pst'] ) { + $p_result = $this->pstContent->getParserOutput( $titleObj, null, $popts ); + } else { + $p_result = $this->content->getParserOutput( $titleObj, null, $popts ); + } } $result_array = array(); @@ -275,10 +298,10 @@ class ApiParse extends ApiBase { if ( isset( $prop['wikitext'] ) ) { $result_array['wikitext'] = array(); - $result->setContent( $result_array['wikitext'], $this->text ); - if ( !is_null( $this->pstText ) ) { + $result->setContent( $result_array['wikitext'], $this->content->serialize( $format ) ); + if ( !is_null( $this->pstContent ) ) { $result_array['psttext'] = array(); - $result->setContent( $result_array['psttext'], $this->pstText ); + $result->setContent( $result_array['psttext'], $this->pstContent->serialize( $format ) ); } } if ( isset( $prop['properties'] ) ) { @@ -286,8 +309,12 @@ class ApiParse extends ApiBase { } if ( $params['generatexml'] ) { + if ( $this->content->getModel() != CONTENT_MODEL_WIKITEXT ) { + $this->dieUsage( "generatexml is only supported for wikitext content", "notwikitext" ); + } + $wgParser->startExternalParse( $titleObj, $popts, OT_PREPROCESS ); - $dom = $wgParser->preprocessToDom( $this->text ); + $dom = $wgParser->preprocessToDom( $this->content->getNativeData() ); if ( is_callable( array( $dom, 'saveXML' ) ) ) { $xml = $dom->saveXML(); } else { @@ -325,15 +352,16 @@ class ApiParse extends ApiBase { * @param $getWikitext Bool * @return ParserOutput */ - private function getParsedSectionOrText( $page, $popts, $pageId = null, $getWikitext = false ) { - global $wgParser; + private function getParsedContent( WikiPage $page, $popts, $pageId = null, $getWikitext = false ) { + $this->content = $page->getContent( Revision::RAW ); //XXX: really raw? - if ( $this->section !== false ) { - $this->text = $this->getSectionText( $page->getRawText(), !is_null( $pageId ) - ? 'page id ' . $pageId : $page->getTitle()->getPrefixedText() ); + if ( $this->section !== false && $this->content !== null ) { + $this->content = $this->getSectionContent( + $this->content, + !is_null( $pageId ) ? 'page id ' . $pageId : $page->getTitle()->getText() ); // Not cached (save or load) - return $wgParser->parse( $this->text, $page->getTitle(), $popts ); + return $this->content->getParserOutput( $page->getTitle(), null, $popts ); } else { // Try the parser cache first // getParserOutput will save to Parser cache if able @@ -342,20 +370,23 @@ class ApiParse extends ApiBase { $this->dieUsage( "There is no revision ID {$page->getLatest()}", 'missingrev' ); } if ( $getWikitext ) { - $this->text = $page->getRawText(); + $this->content = $page->getContent( Revision::RAW ); } return $pout; } } - private function getSectionText( $text, $what ) { - global $wgParser; + private function getSectionContent( Content $content, $what ) { // Not cached (save or load) - $text = $wgParser->getSection( $text, $this->section, false ); - if ( $text === false ) { + $section = $content->getSection( $this->section ); + if ( $section === false ) { $this->dieUsage( "There is no section {$this->section} in " . $what, 'nosuchsection' ); } - return $text; + if ( $section === null ) { + $this->dieUsage( "Sections are not supported by " . $what, 'nosuchsection' ); + $section = false; + } + return $section; } private function formatLangLinks( $links ) { @@ -415,14 +446,14 @@ class ApiParse extends ApiBase { $text = Language::fetchLanguageName( $nt->getInterwiki() ); $langs[] = Html::element( 'a', - array( 'href' => $nt->getFullURL(), 'title' => $nt->getText(), 'class' => "external" ), + array( 'href' => $nt->getFullURL(), 'title' => $nt->getText(), 'class' => 'external' ), $text == '' ? $l : $text ); } $s .= implode( wfMessage( 'pipe-separator' )->escaped(), $langs ); if ( $wgContLang->isRTL() ) { - $s = Html::rawElement( 'span', array( 'dir' => "LTR" ), $s ); + $s = Html::rawElement( 'span', array( 'dir' => 'LTR' ), $s ); } return $s; @@ -548,6 +579,12 @@ class ApiParse extends ApiBase { 'section' => null, 'disablepp' => false, 'generatexml' => false, + 'contentformat' => array( + ApiBase::PARAM_TYPE => ContentHandler::getAllContentFormats(), + ), + 'contentmodel' => array( + ApiBase::PARAM_TYPE => ContentHandler::getContentModels(), + ) ); } @@ -592,7 +629,9 @@ class ApiParse extends ApiBase { 'uselang' => 'Which language to parse the request in', 'section' => 'Only retrieve the content of this section number', 'disablepp' => 'Disable the PP Report from the parser output', - 'generatexml' => 'Generate XML parse tree', + 'generatexml' => 'Generate XML parse tree (requires prop=wikitext)', + 'contentformat' => 'Content serialization format used for the input text', + 'contentmodel' => 'Content model of the new content', ); } @@ -613,6 +652,9 @@ class ApiParse extends ApiBase { array( 'code' => 'nosuchsection', 'info' => 'There is no section sectionnumber in page' ), array( 'nosuchpageid' ), array( 'invalidtitle', 'title' ), + array( 'code' => 'parseerror', 'info' => 'Failed to parse the given text.' ), + array( 'code' => 'notwikitext', 'info' => 'The requested operation is only supported on wikitext content.' ), + array( 'code' => 'pagecannotexist', 'info' => "Namespace doesn't allow actual pages" ), ) ); } @@ -625,8 +667,4 @@ class ApiParse extends ApiBase { public function getHelpUrls() { return 'https://www.mediawiki.org/wiki/API:Parsing_wikitext#parse'; } - - public function getVersion() { - return __CLASS__ . ': $Id$'; - } } |