MediaWiki
REL1_23
|
00001 <?php 00032 abstract class ApiFormatBase extends ApiBase { 00033 private $mIsHtml, $mFormat, $mUnescapeAmps, $mHelp, $mCleared; 00034 private $mBufferResult = false, $mBuffer, $mDisabled = false; 00035 00042 public function __construct( $main, $format ) { 00043 parent::__construct( $main, $format ); 00044 00045 $this->mIsHtml = ( substr( $format, -2, 2 ) === 'fm' ); // ends with 'fm' 00046 if ( $this->mIsHtml ) { 00047 $this->mFormat = substr( $format, 0, -2 ); // remove ending 'fm' 00048 } else { 00049 $this->mFormat = $format; 00050 } 00051 $this->mFormat = strtoupper( $this->mFormat ); 00052 $this->mCleared = false; 00053 } 00054 00060 abstract public function getMimeType(); 00061 00066 public function getNeedsRawData() { 00067 return false; 00068 } 00069 00074 public function getFormat() { 00075 return $this->mFormat; 00076 } 00077 00087 public function setUnescapeAmps( $b ) { 00088 $this->mUnescapeAmps = $b; 00089 } 00090 00097 public function getIsHtml() { 00098 return $this->mIsHtml; 00099 } 00100 00107 public function getWantsHelp() { 00108 return $this->getIsHtml(); 00109 } 00110 00115 public function disable() { 00116 $this->mDisabled = true; 00117 } 00118 00119 public function isDisabled() { 00120 return $this->mDisabled; 00121 } 00122 00129 public function canPrintErrors() { 00130 return true; 00131 } 00132 00141 function initPrinter( $isHelpScreen ) { 00142 if ( $this->mDisabled ) { 00143 return; 00144 } 00145 $isHtml = $this->getIsHtml(); 00146 $mime = $isHtml ? 'text/html' : $this->getMimeType(); 00147 $script = wfScript( 'api' ); 00148 00149 // Some printers (ex. Feed) do their own header settings, 00150 // in which case $mime will be set to null 00151 if ( is_null( $mime ) ) { 00152 return; // skip any initialization 00153 } 00154 00155 $this->getMain()->getRequest()->response()->header( "Content-Type: $mime; charset=utf-8" ); 00156 00157 //Set X-Frame-Options API results (bug 39180) 00158 global $wgApiFrameOptions; 00159 if ( $wgApiFrameOptions ) { 00160 $this->getMain()->getRequest()->response()->header( "X-Frame-Options: $wgApiFrameOptions" ); 00161 } 00162 00163 if ( $isHtml ) { 00164 ?> 00165 <!DOCTYPE HTML> 00166 <html> 00167 <head> 00168 <?php 00169 if ( $this->mUnescapeAmps ) { 00170 ?> <title>MediaWiki API</title> 00171 <?php 00172 } else { 00173 ?> <title>MediaWiki API Result</title> 00174 <?php 00175 } 00176 ?> 00177 </head> 00178 <body> 00179 <?php 00180 if ( !$isHelpScreen ) { 00181 // @codingStandardsIgnoreStart Exclude long line from CodeSniffer checks 00182 ?> 00183 <br /> 00184 <small> 00185 You are looking at the HTML representation of the <?php echo $this->mFormat; ?> format.<br /> 00186 HTML is good for debugging, but is unsuitable for application use.<br /> 00187 Specify the format parameter to change the output format.<br /> 00188 To see the non HTML representation of the <?php echo $this->mFormat; ?> format, set format=<?php echo strtolower( $this->mFormat ); ?>.<br /> 00189 See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>, or 00190 <a href='<?php echo $script; ?>'>API help</a> for more information. 00191 </small> 00192 <pre style='white-space: pre-wrap;'> 00193 <?php 00194 // @codingStandardsIgnoreEnd 00195 // don't wrap the contents of the <pre> for help screens 00196 // because these are actually formatted to rely on 00197 // the monospaced font for layout purposes 00198 } else { 00199 ?> 00200 <pre> 00201 <?php 00202 } 00203 } 00204 } 00205 00209 public function closePrinter() { 00210 if ( $this->mDisabled ) { 00211 return; 00212 } 00213 if ( $this->getIsHtml() ) { 00214 ?> 00215 00216 </pre> 00217 </body> 00218 </html> 00219 <?php 00220 } 00221 } 00222 00229 public function printText( $text ) { 00230 if ( $this->mDisabled ) { 00231 return; 00232 } 00233 if ( $this->mBufferResult ) { 00234 $this->mBuffer = $text; 00235 } elseif ( $this->getIsHtml() ) { 00236 echo $this->formatHTML( $text ); 00237 } else { 00238 // For non-HTML output, clear all errors that might have been 00239 // displayed if display_errors=On 00240 // Do this only once, of course 00241 if ( !$this->mCleared ) { 00242 ob_clean(); 00243 $this->mCleared = true; 00244 } 00245 echo $text; 00246 } 00247 } 00248 00252 public function getBuffer() { 00253 return $this->mBuffer; 00254 } 00255 00260 public function setBufferResult( $value ) { 00261 $this->mBufferResult = $value; 00262 } 00263 00268 public function setHelp( $help = true ) { 00269 $this->mHelp = $help; 00270 } 00271 00278 protected function formatHTML( $text ) { 00279 // Escape everything first for full coverage 00280 $text = htmlspecialchars( $text ); 00281 // encode all comments or tags as safe blue strings 00282 $text = str_replace( '<', '<span style="color:blue;"><', $text ); 00283 $text = str_replace( '>', '></span>', $text ); 00284 00285 // identify requests to api.php 00286 $text = preg_replace( '#^(\s*)(api\.php\?[^ <\n\t]+)$#m', '\1<a href="\2">\2</a>', $text ); 00287 if ( $this->mHelp ) { 00288 // make lines inside * bold 00289 $text = preg_replace( '#^(\s*)(\*[^<>\n]+\*)(\s*)$#m', '$1<b>$2</b>$3', $text ); 00290 } 00291 00292 // Armor links (bug 61362) 00293 $masked = array(); 00294 $text = preg_replace_callback( '#<a .*?</a>#', function ( $matches ) use ( &$masked ) { 00295 $sha = sha1( $matches[0] ); 00296 $masked[$sha] = $matches[0]; 00297 return "<$sha>"; 00298 }, $text ); 00299 00300 // identify URLs 00301 $protos = wfUrlProtocolsWithoutProtRel(); 00302 // This regex hacks around bug 13218 (" included in the URL) 00303 $text = preg_replace( 00304 "#(((?i)$protos).*?)(")?([ \\'\"<>\n]|<|>|")#", 00305 '<a href="\\1">\\1</a>\\3\\4', 00306 $text 00307 ); 00308 00309 // Unarmor links 00310 $text = preg_replace_callback( '#<([0-9a-f]{40})>#', function ( $matches ) use ( &$masked ) { 00311 $sha = $matches[1]; 00312 return isset( $masked[$sha] ) ? $masked[$sha] : $matches[0]; 00313 }, $text ); 00314 00321 if ( $this->mUnescapeAmps ) { 00322 $text = preg_replace( '/&(amp|quot|lt|gt);/', '&\1;', $text ); 00323 } 00324 00325 return $text; 00326 } 00327 00328 public function getExamples() { 00329 return array( 00330 'api.php?action=query&meta=siteinfo&siprop=namespaces&format=' . $this->getModuleName() 00331 => "Format the query result in the {$this->getModuleName()} format", 00332 ); 00333 } 00334 00335 public function getHelpUrls() { 00336 return 'https://www.mediawiki.org/wiki/API:Data_formats'; 00337 } 00338 00339 public function getDescription() { 00340 return $this->getIsHtml() ? ' (pretty-print in HTML)' : ''; 00341 } 00342 } 00343 00348 class ApiFormatFeedWrapper extends ApiFormatBase { 00349 00350 public function __construct( $main ) { 00351 parent::__construct( $main, 'feed' ); 00352 } 00353 00360 public static function setResult( $result, $feed, $feedItems ) { 00361 // Store output in the Result data. 00362 // This way we can check during execution if any error has occurred 00363 // Disable size checking for this because we can't continue 00364 // cleanly; size checking would cause more problems than it'd 00365 // solve 00366 $result->disableSizeCheck(); 00367 $result->addValue( null, '_feed', $feed ); 00368 $result->addValue( null, '_feeditems', $feedItems ); 00369 $result->enableSizeCheck(); 00370 } 00371 00377 public function getMimeType() { 00378 return null; 00379 } 00380 00386 public function getNeedsRawData() { 00387 return true; 00388 } 00389 00395 public function canPrintErrors() { 00396 return false; 00397 } 00398 00404 public function execute() { 00405 $data = $this->getResultData(); 00406 if ( isset( $data['_feed'] ) && isset( $data['_feeditems'] ) ) { 00407 $feed = $data['_feed']; 00408 $items = $data['_feeditems']; 00409 00410 $feed->outHeader(); 00411 foreach ( $items as & $item ) { 00412 $feed->outItem( $item ); 00413 } 00414 $feed->outFooter(); 00415 } else { 00416 // Error has occurred, print something useful 00417 ApiBase::dieDebug( __METHOD__, 'Invalid feed class/item' ); 00418 } 00419 } 00420 }