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;
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 # Don't use the parser cache
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 $text = $rev->getText( Revision::FOR_THIS_USER );
00073 $titleObj = $rev->getTitle();
00074 $wgTitle = $titleObj;
00075 $p_result = $wgParser->parse($text, $titleObj, $popts);
00076 }
00077 else
00078 {
00079 if($params['redirects'])
00080 {
00081 $req = new FauxRequest(array(
00082 'action' => 'query',
00083 'redirects' => '',
00084 'titles' => $page
00085 ));
00086 $main = new ApiMain($req);
00087 $main->execute();
00088 $data = $main->getResultData();
00089 $redirValues = @$data['query']['redirects'];
00090 $to = $page;
00091 foreach((array)$redirValues as $r)
00092 $to = $r['to'];
00093 }
00094 else
00095 $to = $page;
00096 $titleObj = Title::newFromText($to);
00097 if(!$titleObj)
00098 $this->dieUsage("The page you specified doesn't exist", 'missingtitle');
00099
00100 $articleObj = new Article($titleObj);
00101 if(isset($prop['revid']))
00102 $oldid = $articleObj->getRevIdFetched();
00103
00104 $pcache = ParserCache::singleton();
00105 $p_result = $pcache->get($articleObj, $wgUser);
00106 if(!$p_result)
00107 {
00108 $p_result = $wgParser->parse($articleObj->getContent(), $titleObj, $popts);
00109 global $wgUseParserCache;
00110 if($wgUseParserCache)
00111 $pcache->save($p_result, $articleObj, $popts);
00112 }
00113 }
00114 }
00115 else
00116 {
00117 $titleObj = Title::newFromText($title);
00118 if(!$titleObj)
00119 $titleObj = Title::newFromText("API");
00120 $wgTitle = $titleObj;
00121 if($params['pst'] || $params['onlypst'])
00122 $text = $wgParser->preSaveTransform($text, $titleObj, $wgUser, $popts);
00123 if($params['onlypst'])
00124 {
00125
00126 $result_array['text'] = array();
00127 $this->getResult()->setContent($result_array['text'], $text);
00128 $this->getResult()->addValue(null, $this->getModuleName(), $result_array);
00129 return;
00130 }
00131 $p_result = $wgParser->parse($text, $titleObj, $popts);
00132 }
00133
00134
00135 $result = $this->getResult();
00136 $result_array = array();
00137 if($params['redirects'] && !is_null($redirValues))
00138 $result_array['redirects'] = $redirValues;
00139 if(isset($prop['text'])) {
00140 $result_array['text'] = array();
00141 $result->setContent($result_array['text'], $p_result->getText());
00142 }
00143 if(isset($prop['langlinks']))
00144 $result_array['langlinks'] = $this->formatLangLinks($p_result->getLanguageLinks());
00145 if(isset($prop['categories']))
00146 $result_array['categories'] = $this->formatCategoryLinks($p_result->getCategories());
00147 if(isset($prop['links']))
00148 $result_array['links'] = $this->formatLinks($p_result->getLinks());
00149 if(isset($prop['templates']))
00150 $result_array['templates'] = $this->formatLinks($p_result->getTemplates());
00151 if(isset($prop['images']))
00152 $result_array['images'] = array_keys($p_result->getImages());
00153 if(isset($prop['externallinks']))
00154 $result_array['externallinks'] = array_keys($p_result->getExternalLinks());
00155 if(isset($prop['sections']))
00156 $result_array['sections'] = $p_result->getSections();
00157 if(isset($prop['displaytitle']))
00158 $result_array['displaytitle'] = $p_result->getDisplayTitle() ?
00159 $p_result->getDisplayTitle() :
00160 $titleObj->getPrefixedText();
00161 if(!is_null($oldid))
00162 $result_array['revid'] = intval($oldid);
00163
00164 $result_mapping = array(
00165 'redirects' => 'r',
00166 'langlinks' => 'll',
00167 'categories' => 'cl',
00168 'links' => 'pl',
00169 'templates' => 'tl',
00170 'images' => 'img',
00171 'externallinks' => 'el',
00172 'sections' => 's',
00173 );
00174 $this->setIndexedTagNames( $result_array, $result_mapping );
00175 $result->addValue( null, $this->getModuleName(), $result_array );
00176 }
00177
00178 private function formatLangLinks( $links ) {
00179 $result = array();
00180 foreach( $links as $link ) {
00181 $entry = array();
00182 $bits = split( ':', $link, 2 );
00183 $entry['lang'] = $bits[0];
00184 $this->getResult()->setContent( $entry, $bits[1] );
00185 $result[] = $entry;
00186 }
00187 return $result;
00188 }
00189
00190 private function formatCategoryLinks( $links ) {
00191 $result = array();
00192 foreach( $links as $link => $sortkey ) {
00193 $entry = array();
00194 $entry['sortkey'] = $sortkey;
00195 $this->getResult()->setContent( $entry, $link );
00196 $result[] = $entry;
00197 }
00198 return $result;
00199 }
00200
00201 private function formatLinks( $links ) {
00202 $result = array();
00203 foreach( $links as $ns => $nslinks ) {
00204 foreach( $nslinks as $title => $id ) {
00205 $entry = array();
00206 $entry['ns'] = $ns;
00207 $this->getResult()->setContent( $entry, Title::makeTitle( $ns, $title )->getFullText() );
00208 if( $id != 0 )
00209 $entry['exists'] = '';
00210 $result[] = $entry;
00211 }
00212 }
00213 return $result;
00214 }
00215
00216 private function setIndexedTagNames( &$array, $mapping ) {
00217 foreach( $mapping as $key => $name ) {
00218 if( isset( $array[$key] ) )
00219 $this->getResult()->setIndexedTagName( $array[$key], $name );
00220 }
00221 }
00222
00223 public function getAllowedParams() {
00224 return array (
00225 'title' => array(
00226 ApiBase :: PARAM_DFLT => 'API',
00227 ),
00228 'text' => null,
00229 'page' => null,
00230 'redirects' => false,
00231 'oldid' => null,
00232 'prop' => array(
00233 ApiBase :: PARAM_DFLT => 'text|langlinks|categories|links|templates|images|externallinks|sections|revid|displaytitle',
00234 ApiBase :: PARAM_ISMULTI => true,
00235 ApiBase :: PARAM_TYPE => array(
00236 'text',
00237 'langlinks',
00238 'categories',
00239 'links',
00240 'templates',
00241 'images',
00242 'externallinks',
00243 'sections',
00244 'revid',
00245 'displaytitle',
00246 )
00247 ),
00248 'pst' => false,
00249 'onlypst' => false,
00250 );
00251 }
00252
00253 public function getParamDescription() {
00254 return array (
00255 'text' => 'Wikitext to parse',
00256 'redirects' => 'If the page parameter is set to a redirect, resolve it',
00257 'title' => 'Title of page the text belongs to',
00258 'page' => 'Parse the content of this page. Cannot be used together with text and title',
00259 'oldid' => 'Parse the content of this revision. Overrides page',
00260 'prop' => array('Which pieces of information to get.',
00261 'NOTE: Section tree is only generated if there are more than 4 sections, or if the __TOC__ keyword is present'
00262 ),
00263 'pst' => array( 'Do a pre-save transform on the input before parsing it.',
00264 'Ignored if page or oldid is used.'
00265 ),
00266 'onlypst' => array('Do a PST on the input, but don\'t parse it.',
00267 'Returns PSTed wikitext. Ignored if page or oldid is used.'
00268 ),
00269 );
00270 }
00271
00272 public function getDescription() {
00273 return 'This module parses wikitext and returns parser output';
00274 }
00275
00276 protected function getExamples() {
00277 return array (
00278 'api.php?action=parse&text={{Project:Sandbox}}'
00279 );
00280 }
00281
00282 public function getVersion() {
00283 return __CLASS__ . ': $Id: ApiParse.php 69986 2010-07-27 03:57:39Z tstarling $';
00284 }
00285 }