00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 if ( !defined( 'MEDIAWIKI' ) ) {
00027
00028 require_once ( "ApiBase.php" );
00029 }
00030
00034 class ApiParse extends ApiBase {
00035
00036 public function __construct( $main, $action ) {
00037 parent :: __construct( $main, $action );
00038 }
00039
00040 public function execute() {
00041
00042 $this->getMain()->setCacheMode( 'anon-public-user-private' );
00043
00044
00045 $params = $this->extractRequestParams();
00046 $text = $params['text'];
00047 $title = $params['title'];
00048 $page = $params['page'];
00049 $oldid = $params['oldid'];
00050 if ( !is_null( $page ) && ( !is_null( $text ) || $title != "API" ) )
00051 $this->dieUsage( "The page parameter cannot be used together with the text and title parameters", 'params' );
00052 $prop = array_flip( $params['prop'] );
00053 $revid = false;
00054
00055
00056
00057 global $wgParser, $wgUser, $wgTitle, $wgEnableParserCache;
00058 $popts = new ParserOptions();
00059 $popts->setTidy( true );
00060 $popts->enableLimitReport();
00061 $redirValues = null;
00062 if ( !is_null( $oldid ) || !is_null( $page ) )
00063 {
00064 if ( !is_null( $oldid ) )
00065 {
00066
00067 $rev = Revision::newFromID( $oldid );
00068 if ( !$rev )
00069 $this->dieUsage( "There is no revision ID $oldid", 'missingrev' );
00070 if ( !$rev->userCan( Revision::DELETED_TEXT ) )
00071 $this->dieUsage( "You don't have permission to view deleted revisions", 'permissiondenied' );
00072
00073 $text = $rev->getText( Revision::FOR_THIS_USER );
00074 $titleObj = $rev->getTitle();
00075 $wgTitle = $titleObj;
00076 $p_result = $wgParser->parse( $text, $titleObj, $popts );
00077 }
00078 else
00079 {
00080 if ( $params['redirects'] )
00081 {
00082 $req = new FauxRequest( array(
00083 'action' => 'query',
00084 'redirects' => '',
00085 'titles' => $page
00086 ) );
00087 $main = new ApiMain( $req );
00088 $main->execute();
00089 $data = $main->getResultData();
00090 $redirValues = @$data['query']['redirects'];
00091 $to = $page;
00092 foreach ( (array)$redirValues as $r )
00093 $to = $r['to'];
00094 }
00095 else
00096 $to = $page;
00097 $titleObj = Title::newFromText( $to );
00098 if ( !$titleObj )
00099 $this->dieUsage( "The page you specified doesn't exist", 'missingtitle' );
00100
00101 $articleObj = new Article( $titleObj );
00102 if ( isset( $prop['revid'] ) )
00103 $oldid = $articleObj->getRevIdFetched();
00104
00105 $p_result = false;
00106 $pcache = ParserCache::singleton();
00107 if ( $wgEnableParserCache )
00108 $p_result = $pcache->get( $articleObj, $wgUser );
00109 if ( !$p_result )
00110 {
00111 $p_result = $wgParser->parse( $articleObj->getContent(), $titleObj, $popts );
00112
00113 if ( $wgEnableParserCache )
00114 $pcache->save( $p_result, $articleObj, $popts );
00115 }
00116 }
00117 }
00118 else
00119 {
00120 $titleObj = Title::newFromText( $title );
00121 if ( !$titleObj )
00122 $titleObj = Title::newFromText( "API" );
00123 $wgTitle = $titleObj;
00124 if ( $params['pst'] || $params['onlypst'] )
00125 $text = $wgParser->preSaveTransform( $text, $titleObj, $wgUser, $popts );
00126 if ( $params['onlypst'] )
00127 {
00128
00129 $result_array['text'] = array();
00130 $this->getResult()->setContent( $result_array['text'], $text );
00131 $this->getResult()->addValue( null, $this->getModuleName(), $result_array );
00132 return;
00133 }
00134 $p_result = $wgParser->parse( $text, $titleObj, $popts );
00135 }
00136
00137
00138 $result = $this->getResult();
00139 $result_array = array();
00140 if ( $params['redirects'] && !is_null( $redirValues ) )
00141 $result_array['redirects'] = $redirValues;
00142
00143 if ( isset( $prop['text'] ) ) {
00144 $result_array['text'] = array();
00145 $result->setContent( $result_array['text'], $p_result->getText() );
00146 }
00147
00148 if ( !is_null( $params['summary'] ) ) {
00149 $result_array['parsedsummary'] = array();
00150 $result->setContent( $result_array['parsedsummary'], $wgUser->getSkin()->formatComment( $params['summary'], $titleObj ) );
00151 }
00152
00153 if ( isset( $prop['langlinks'] ) )
00154 $result_array['langlinks'] = $this->formatLangLinks( $p_result->getLanguageLinks() );
00155 if ( isset( $prop['categories'] ) )
00156 $result_array['categories'] = $this->formatCategoryLinks( $p_result->getCategories() );
00157 if ( isset( $prop['links'] ) )
00158 $result_array['links'] = $this->formatLinks( $p_result->getLinks() );
00159 if ( isset( $prop['templates'] ) )
00160 $result_array['templates'] = $this->formatLinks( $p_result->getTemplates() );
00161 if ( isset( $prop['images'] ) )
00162 $result_array['images'] = array_keys( $p_result->getImages() );
00163 if ( isset( $prop['externallinks'] ) )
00164 $result_array['externallinks'] = array_keys( $p_result->getExternalLinks() );
00165 if ( isset( $prop['sections'] ) )
00166 $result_array['sections'] = $p_result->getSections();
00167 if ( isset( $prop['displaytitle'] ) )
00168 $result_array['displaytitle'] = $p_result->getDisplayTitle() ?
00169 $p_result->getDisplayTitle() :
00170 $titleObj->getPrefixedText();
00171
00172 if ( isset( $prop['headitems'] ) )
00173 $result_array['headitems'] = $this->formatHeadItems( $p_result->getHeadItems() );
00174
00175 if ( isset( $prop['headhtml'] ) ) {
00176 $out = new OutputPage;
00177 $out->addParserOutputNoText( $p_result );
00178 $result_array['headhtml'] = array();
00179 $result->setContent( $result_array['headhtml'], $out->headElement( $wgUser->getSkin() ) );
00180 }
00181
00182 if ( !is_null( $oldid ) )
00183 $result_array['revid'] = intval( $oldid );
00184
00185 $result_mapping = array(
00186 'redirects' => 'r',
00187 'langlinks' => 'll',
00188 'categories' => 'cl',
00189 'links' => 'pl',
00190 'templates' => 'tl',
00191 'images' => 'img',
00192 'externallinks' => 'el',
00193 'sections' => 's',
00194 'headitems' => 'hi'
00195 );
00196 $this->setIndexedTagNames( $result_array, $result_mapping );
00197 $result->addValue( null, $this->getModuleName(), $result_array );
00198 }
00199
00200 private function formatLangLinks( $links ) {
00201 $result = array();
00202 foreach ( $links as $link ) {
00203 $entry = array();
00204 $bits = explode( ':', $link, 2 );
00205 $entry['lang'] = $bits[0];
00206 $this->getResult()->setContent( $entry, $bits[1] );
00207 $result[] = $entry;
00208 }
00209 return $result;
00210 }
00211
00212 private function formatCategoryLinks( $links ) {
00213 $result = array();
00214 foreach ( $links as $link => $sortkey ) {
00215 $entry = array();
00216 $entry['sortkey'] = $sortkey;
00217 $this->getResult()->setContent( $entry, $link );
00218 $result[] = $entry;
00219 }
00220 return $result;
00221 }
00222
00223 private function formatLinks( $links ) {
00224 $result = array();
00225 foreach ( $links as $ns => $nslinks ) {
00226 foreach ( $nslinks as $title => $id ) {
00227 $entry = array();
00228 $entry['ns'] = $ns;
00229 $this->getResult()->setContent( $entry, Title::makeTitle( $ns, $title )->getFullText() );
00230 if ( $id != 0 )
00231 $entry['exists'] = '';
00232 $result[] = $entry;
00233 }
00234 }
00235 return $result;
00236 }
00237
00238 private function formatHeadItems( $headItems ) {
00239 $result = array();
00240 foreach ( $headItems as $tag => $content ) {
00241 $entry = array();
00242 $entry['tag'] = $tag;
00243 $this->getResult()->setContent( $entry, $content );
00244 $result[] = $entry;
00245 }
00246 return $result;
00247 }
00248
00249 private function setIndexedTagNames( &$array, $mapping ) {
00250 foreach ( $mapping as $key => $name ) {
00251 if ( isset( $array[$key] ) )
00252 $this->getResult()->setIndexedTagName( $array[$key], $name );
00253 }
00254 }
00255
00256 public function getAllowedParams() {
00257 return array (
00258 'title' => array(
00259 ApiBase :: PARAM_DFLT => 'API',
00260 ),
00261 'text' => null,
00262 'summary' => null,
00263 'page' => null,
00264 'redirects' => false,
00265 'oldid' => null,
00266 'prop' => array(
00267 ApiBase :: PARAM_DFLT => 'text|langlinks|categories|links|templates|images|externallinks|sections|revid|displaytitle',
00268 ApiBase :: PARAM_ISMULTI => true,
00269 ApiBase :: PARAM_TYPE => array(
00270 'text',
00271 'langlinks',
00272 'categories',
00273 'links',
00274 'templates',
00275 'images',
00276 'externallinks',
00277 'sections',
00278 'revid',
00279 'displaytitle',
00280 'headitems',
00281 'headhtml'
00282 )
00283 ),
00284 'pst' => false,
00285 'onlypst' => false,
00286 );
00287 }
00288
00289 public function getParamDescription() {
00290 return array (
00291 'text' => 'Wikitext to parse',
00292 'summary' => 'Summary to parse',
00293 'redirects' => 'If the page parameter is set to a redirect, resolve it',
00294 'title' => 'Title of page the text belongs to',
00295 'page' => 'Parse the content of this page. Cannot be used together with text and title',
00296 'oldid' => 'Parse the content of this revision. Overrides page',
00297 'prop' => array( 'Which pieces of information to get.',
00298 'NOTE: Section tree is only generated if there are more than 4 sections, or if the __TOC__ keyword is present'
00299 ),
00300 'pst' => array( 'Do a pre-save transform on the input before parsing it.',
00301 'Ignored if page or oldid is used.'
00302 ),
00303 'onlypst' => array( 'Do a PST on the input, but don\'t parse it.',
00304 'Returns PSTed wikitext. Ignored if page or oldid is used.'
00305 ),
00306 );
00307 }
00308
00309 public function getDescription() {
00310 return 'This module parses wikitext and returns parser output';
00311 }
00312
00313 public function getPossibleErrors() {
00314 return array_merge( parent::getPossibleErrors(), array(
00315 array( 'code' => 'params', 'info' => 'The page parameter cannot be used together with the text and title parameters' ),
00316 array( 'code' => 'missingrev', 'info' => 'There is no revision ID oldid' ),
00317 array( 'code' => 'permissiondenied', 'info' => 'You don\'t have permission to view deleted revisions' ),
00318 array( 'code' => 'missingtitle', 'info' => 'The page you specified doesn\'t exist' ),
00319 ) );
00320 }
00321
00322 protected function getExamples() {
00323 return array (
00324 'api.php?action=parse&text={{Project:Sandbox}}'
00325 );
00326 }
00327
00328 public function getVersion() {
00329 return __CLASS__ . ': $Id: ApiParse.php 69932 2010-07-26 08:03:21Z tstarling $';
00330 }
00331 }