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