MediaWiki  REL1_21
ApiFormatBase.php
Go to the documentation of this file.
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( '&lt;', '<span style="color:blue;">&lt;', $text );
00274                 $text = str_replace( '&gt;', '&gt;</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 (&quot; included in the URL)
00294                 $text = preg_replace( "#(((?i)$protos).*?)(&quot;)?([ \\'\"<>\n]|&lt;|&gt;|&quot;)#", '<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;(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 }