MediaWiki
REL1_22
|
00001 <?php 00032 abstract class ApiFormatBase extends ApiBase { 00033 00034 private $mIsHtml, $mFormat, $mUnescapeAmps, $mHelp, $mCleared; 00035 private $mBufferResult = false, $mBuffer, $mDisabled = false; 00036 00043 public function __construct( $main, $format ) { 00044 parent::__construct( $main, $format ); 00045 00046 $this->mIsHtml = ( substr( $format, - 2, 2 ) === 'fm' ); // ends with 'fm' 00047 if ( $this->mIsHtml ) { 00048 $this->mFormat = substr( $format, 0, - 2 ); // remove ending 'fm' 00049 } else { 00050 $this->mFormat = $format; 00051 } 00052 $this->mFormat = strtoupper( $this->mFormat ); 00053 $this->mCleared = false; 00054 } 00055 00061 abstract public function getMimeType(); 00062 00067 public function getNeedsRawData() { 00068 return false; 00069 } 00070 00075 public function getFormat() { 00076 return $this->mFormat; 00077 } 00078 00088 public function setUnescapeAmps( $b ) { 00089 $this->mUnescapeAmps = $b; 00090 } 00091 00098 public function getIsHtml() { 00099 return $this->mIsHtml; 00100 } 00101 00108 public function getWantsHelp() { 00109 return $this->getIsHtml(); 00110 } 00111 00116 public function disable() { 00117 $this->mDisabled = true; 00118 } 00119 00120 public function isDisabled() { 00121 return $this->mDisabled; 00122 } 00123 00132 function initPrinter( $isHelpScreen ) { 00133 if ( $this->mDisabled ) { 00134 return; 00135 } 00136 $isHtml = $this->getIsHtml(); 00137 $mime = $isHtml ? 'text/html' : $this->getMimeType(); 00138 $script = wfScript( 'api' ); 00139 00140 // Some printers (ex. Feed) do their own header settings, 00141 // in which case $mime will be set to null 00142 if ( is_null( $mime ) ) { 00143 return; // skip any initialization 00144 } 00145 00146 $this->getMain()->getRequest()->response()->header( "Content-Type: $mime; charset=utf-8" ); 00147 00148 //Set X-Frame-Options API results (bug 39180) 00149 global $wgApiFrameOptions; 00150 if ( $wgApiFrameOptions ) { 00151 $this->getMain()->getRequest()->response()->header( "X-Frame-Options: $wgApiFrameOptions" ); 00152 } 00153 00154 if ( $isHtml ) { 00155 ?> 00156 <!DOCTYPE HTML> 00157 <html> 00158 <head> 00159 <?php if ( $this->mUnescapeAmps ) { 00160 ?> <title>MediaWiki API</title> 00161 <?php } else { 00162 ?> <title>MediaWiki API Result</title> 00163 <?php } ?> 00164 </head> 00165 <body> 00166 <?php 00167 00168 00169 if ( !$isHelpScreen ) { 00170 ?> 00171 <br /> 00172 <small> 00173 You are looking at the HTML representation of the <?php echo $this->mFormat; ?> format.<br /> 00174 HTML is good for debugging, but is unsuitable for application use.<br /> 00175 Specify the format parameter to change the output format.<br /> 00176 To see the non HTML representation of the <?php echo $this->mFormat; ?> format, set format=<?php echo strtolower( $this->mFormat ); ?>.<br /> 00177 See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>, or 00178 <a href='<?php echo $script; ?>'>API help</a> for more information. 00179 </small> 00180 <pre style='white-space: pre-wrap;'> 00181 <?php 00182 00183 00184 } else { // don't wrap the contents of the <pre> for help screens 00185 // because these are actually formatted to rely on 00186 // the monospaced font for layout purposes 00187 ?> 00188 <pre> 00189 <?php 00190 00191 } 00192 } 00193 } 00194 00198 public function closePrinter() { 00199 if ( $this->mDisabled ) { 00200 return; 00201 } 00202 if ( $this->getIsHtml() ) { 00203 ?> 00204 00205 </pre> 00206 </body> 00207 </html> 00208 <?php 00209 00210 00211 } 00212 } 00213 00220 public function printText( $text ) { 00221 if ( $this->mDisabled ) { 00222 return; 00223 } 00224 if ( $this->mBufferResult ) { 00225 $this->mBuffer = $text; 00226 } elseif ( $this->getIsHtml() ) { 00227 echo $this->formatHTML( $text ); 00228 } else { 00229 // For non-HTML output, clear all errors that might have been 00230 // displayed if display_errors=On 00231 // Do this only once, of course 00232 if ( !$this->mCleared ) { 00233 ob_clean(); 00234 $this->mCleared = true; 00235 } 00236 echo $text; 00237 } 00238 } 00239 00243 public function getBuffer() { 00244 return $this->mBuffer; 00245 } 00246 00251 public function setBufferResult( $value ) { 00252 $this->mBufferResult = $value; 00253 } 00254 00259 public function setHelp( $help = true ) { 00260 $this->mHelp = $help; 00261 } 00262 00269 protected function formatHTML( $text ) { 00270 // Escape everything first for full coverage 00271 $text = htmlspecialchars( $text ); 00272 // encode all comments or tags as safe blue strings 00273 $text = str_replace( '<', '<span style="color:blue;"><', $text ); 00274 $text = str_replace( '>', '></span>', $text ); 00275 00276 // identify requests to api.php 00277 $text = preg_replace( '#^(\s*)(api\.php\?[^ <\n\t]+)$#m', '\1<a href="\2">\2</a>', $text ); 00278 if ( $this->mHelp ) { 00279 // make strings inside * bold 00280 $text = preg_replace( "#\\*[^<>\n]+\\*#", '<b>\\0</b>', $text ); 00281 } 00282 00283 // Armor links (bug 61362) 00284 $masked = array(); 00285 $text = preg_replace_callback( '#<a .*?</a>#', function ( $matches ) use ( &$masked ) { 00286 $sha = sha1( $matches[0] ); 00287 $masked[$sha] = $matches[0]; 00288 return "<$sha>"; 00289 }, $text ); 00290 00291 // identify URLs 00292 $protos = wfUrlProtocolsWithoutProtRel(); 00293 // This regex hacks around bug 13218 (" included in the URL) 00294 $text = preg_replace( "#(((?i)$protos).*?)(")?([ \\'\"<>\n]|<|>|")#", '<a href="\\1">\\1</a>\\3\\4', $text ); 00295 00296 // Unarmor links 00297 $text = preg_replace_callback( '#<([0-9a-f]{40})>#', function ( $matches ) use ( &$masked ) { 00298 $sha = $matches[1]; 00299 return isset( $masked[$sha] ) ? $masked[$sha] : $matches[0]; 00300 }, $text ); 00301 00308 if ( $this->mUnescapeAmps ) { 00309 $text = preg_replace( '/&(amp|quot|lt|gt);/', '&\1;', $text ); 00310 } 00311 00312 return $text; 00313 } 00314 00315 public function getExamples() { 00316 return array( 00317 'api.php?action=query&meta=siteinfo&siprop=namespaces&format=' . $this->getModuleName() 00318 => "Format the query result in the {$this->getModuleName()} format", 00319 ); 00320 } 00321 00322 public function getHelpUrls() { 00323 return 'https://www.mediawiki.org/wiki/API:Data_formats'; 00324 } 00325 00326 public function getDescription() { 00327 return $this->getIsHtml() ? ' (pretty-print in HTML)' : ''; 00328 } 00329 } 00330 00335 class ApiFormatFeedWrapper extends ApiFormatBase { 00336 00337 public function __construct( $main ) { 00338 parent::__construct( $main, 'feed' ); 00339 } 00340 00347 public static function setResult( $result, $feed, $feedItems ) { 00348 // Store output in the Result data. 00349 // This way we can check during execution if any error has occurred 00350 // Disable size checking for this because we can't continue 00351 // cleanly; size checking would cause more problems than it'd 00352 // solve 00353 $result->disableSizeCheck(); 00354 $result->addValue( null, '_feed', $feed ); 00355 $result->addValue( null, '_feeditems', $feedItems ); 00356 $result->enableSizeCheck(); 00357 } 00358 00364 public function getMimeType() { 00365 return null; 00366 } 00367 00373 public function getNeedsRawData() { 00374 return true; 00375 } 00376 00382 public function execute() { 00383 $data = $this->getResultData(); 00384 if ( isset( $data['_feed'] ) && isset( $data['_feeditems'] ) ) { 00385 $feed = $data['_feed']; 00386 $items = $data['_feeditems']; 00387 00388 $feed->outHeader(); 00389 foreach ( $items as & $item ) { 00390 $feed->outItem( $item ); 00391 } 00392 $feed->outFooter(); 00393 } else { 00394 // Error has occurred, print something useful 00395 ApiBase::dieDebug( __METHOD__, 'Invalid feed class/item' ); 00396 } 00397 } 00398 }