APIEDIT BRANCH MERGE:
[lhc/web/wiklou.git] / includes / api / ApiFormatBase.php
index 3075fbc..5bfbd9e 100644 (file)
@@ -1,12 +1,11 @@
 <?php
 
-
 /*
  * Created on Sep 19, 2006
  *
  * API for MediaWiki 1.8+
  *
- * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,12 +28,18 @@ if (!defined('MEDIAWIKI')) {
        require_once ('ApiBase.php');
 }
 
+/**
+ * This is the abstract base class for API formatters.
+ * 
+ * @addtogroup API
+ */
 abstract class ApiFormatBase extends ApiBase {
 
-       private $mIsHtml, $mFormat;
+       private $mIsHtml, $mFormat, $mUnescapeAmps;
 
        /**
-       * Constructor
+       * Create a new instance of the formatter.
+       * If the format name ends with 'fm', wrap its output in the proper HTML.
        */
        public function __construct($main, $format) {
                parent :: __construct($main, $format);
@@ -54,10 +59,27 @@ abstract class ApiFormatBase extends ApiBase {
         */
        public abstract function getMimeType();
 
+       /**
+        * If formatter outputs data results as is, the results must first be sanitized.
+        * An XML formatter on the other hand uses special tags, such as "_element" for special handling,
+        * and thus needs to override this function to return true.  
+        */
        public function getNeedsRawData() {
                return false;
        }
 
+       /**
+        * Specify whether or not ampersands should be escaped to '&amp;' when rendering. This
+        * should only be set to true for the help message when rendered in the default (xmlfm)
+        * format. This is a temporary special-case fix that should be removed once the help
+        * has been reworked to use a fully html interface.
+        *
+        * @param boolean Whether or not ampersands should be escaped.
+        */
+       public function setUnescapeAmps ( $b ) {
+               $this->mUnescapeAmps = $b;
+       }
+
        /**
         * Returns true when an HTML filtering printer should be used.
         * The default implementation assumes that formats ending with 'fm' 
@@ -75,40 +97,45 @@ abstract class ApiFormatBase extends ApiBase {
        function initPrinter($isError) {
                $isHtml = $this->getIsHtml();
                $mime = $isHtml ? 'text/html' : $this->getMimeType();
-               
+               $script = wfScript( 'api' );
+
                // Some printers (ex. Feed) do their own header settings,
                // in which case $mime will be set to null
                if (is_null($mime))
-                       return; // skip any initialization
-                       
-               header("Content-Type: $mime; charset=utf-8;");
-               header("Cache-Control: private, s-maxage=0, max-age=0");
-               
+                       return; // skip any initialization
+
+               header("Content-Type: $mime; charset=utf-8");
+
                if ($isHtml) {
 ?>
-               <html>
-               <head>
-                       <title>MediaWiki API</title>
-               </head>
-               <body>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<?php if ($this->mUnescapeAmps) { 
+?>     <title>MediaWiki API</title>
+<?php } else {
+?>     <title>MediaWiki API Result</title>
+<?php } ?>
+</head>
+<body>
 <?php
 
 
-                       if (!$isError) {
+                       if( !$isError ) {
 ?>
-                       <br/>
-                       <small>
-                       You are looking at the HTML representation of the <?=$this->mFormat?> format.<br/>
-                       HTML is good for debugging, but probably not suitable for your application.<br/>
-                       Please see "format" parameter documentation at the <a href='api.php'>API help</a>
-                       for more information.<br/>
-                       </small>
+<br/>
+<small>
+You are looking at the HTML representation of the <?php echo( $this->mFormat ); ?> format.<br/>
+HTML is good for debugging, but probably is not suitable for your application.<br/>
+See <a href='http://www.mediawiki.org/wiki/API'>complete documentation</a>, or 
+<a href='<?php echo( $script ); ?>'>API help</a> for more information.
+</small>
 <?php
 
 
                        }
 ?>
-               <pre>
+<pre>
 <?php
 
 
@@ -121,14 +148,20 @@ abstract class ApiFormatBase extends ApiBase {
        public function closePrinter() {
                if ($this->getIsHtml()) {
 ?>
-               </pre>
-               </body>
+
+</pre>
+</body>
+</html>
 <?php
 
 
                }
        }
 
+       /**
+        * The main format printing function. Call it to output the result string to the user.
+        * This function will automatically output HTML when format name ends in 'fm'.
+        */
        public function printText($text) {
                if ($this->getIsHtml())
                        echo $this->formatHTML($text);
@@ -141,16 +174,27 @@ abstract class ApiFormatBase extends ApiBase {
        * This method also replaces any '<' with &lt;
        */
        protected function formatHTML($text) {
-               // encode all tags as safe blue strings
-               $text = ereg_replace('\<([^>]+)\>', '<font color=blue>&lt;\1&gt;</font>', $text);
+               // Escape everything first for full coverage
+               $text = htmlspecialchars($text);
+
+               // encode all comments or tags as safe blue strings
+               $text = preg_replace('/\&lt;(!--.*?--|.*?)\&gt;/', '<span style="color:blue;">&lt;\1&gt;</span>', $text);
                // identify URLs
-               $text = ereg_replace("[a-zA-Z]+://[^ '\"()<\n]+", '<a href="\\0">\\0</a>', $text);
+               $protos = "http|https|ftp|gopher";
+               $text = ereg_replace("($protos)://[^ \\'\"()<\n]+", '<a href="\\0">\\0</a>', $text);
                // identify requests to api.php
-               $text = ereg_replace("api\\.php\\?[^ ()<\n\t]+", '<a href="\\0">\\0</a>', $text);
+               $text = ereg_replace("api\\.php\\?[^ \\()<\n\t]+", '<a href="\\0">\\0</a>', $text);
                // make strings inside * bold
                $text = ereg_replace("\\*[^<>\n]+\\*", '<b>\\0</b>', $text);
                // make strings inside $ italic
                $text = ereg_replace("\\$[^<>\n]+\\$", '<b><i>\\0</i></b>', $text);
+               
+               /* Temporary fix for bad links in help messages. As a special case,
+                * XML-escaped metachars are de-escaped one level in the help message
+                * for legibility. Should be removed once we have completed a fully-html
+                * version of the help message. */
+               if ( $this->mUnescapeAmps )
+                       $text = preg_replace( '/&amp;(amp|quot|lt|gt);/', '&\1;', $text );
 
                return $text;
        }
@@ -159,7 +203,11 @@ abstract class ApiFormatBase extends ApiBase {
         * Returns usage examples for this format.
         */
        protected function getExamples() {
-               return 'api.php?action=query&meta=siteinfo&si=namespaces&format=' . $this->getModuleName();
+               return 'api.php?action=query&meta=siteinfo&siprop=namespaces&format=' . $this->getModuleName();
+       }
+
+       protected function getDescription() {
+               return $this->getIsHtml() ? ' (pretty-print in HTML)' : '';
        }
 
        public static function getBaseVersion() {
@@ -169,6 +217,7 @@ abstract class ApiFormatBase extends ApiBase {
 
 /**
  * This printer is used to wrap an instance of the Feed class 
+ * @addtogroup API
  */
 class ApiFormatFeedWrapper extends ApiFormatBase {
 
@@ -177,12 +226,12 @@ class ApiFormatFeedWrapper extends ApiFormatBase {
        }
 
        /**
-        * Call this method to initialize output data
+        * Call this method to initialize output data. See self::execute()
         */
        public static function setResult($result, $feed, $feedItems) {
                // Store output in the Result data.
                // This way we can check during execution if any error has occured
-               $data =& $result->getData();
+               $data = & $result->getData();
                $data['_feed'] = $feed;
                $data['_feeditems'] = $feedItems;
        }
@@ -200,26 +249,30 @@ class ApiFormatFeedWrapper extends ApiFormatBase {
        public function getNeedsRawData() {
                return true;
        }
-       
+
+       /**
+        * This class expects the result data to be in a custom format set by self::setResult()
+        * $result['_feed']              - an instance of one of the $wgFeedClasses classes
+        * $result['_feeditems'] - an array of FeedItem instances
+        */
        public function execute() {
-               $data =& $this->getResultData();
-               if (isset($data['_feed']) && isset($data['_feeditems'])) {
-                       $feed =& $data['_feed'];
-                       $items =& $data['_feeditems'];
+               $data = $this->getResultData();
+               if (isset ($data['_feed']) && isset ($data['_feeditems'])) {
+                       $feed = $data['_feed'];
+                       $items = $data['_feeditems'];
 
                        $feed->outHeader();
-                       foreach($items as &$item)
+                       foreach ($items as & $item)
                                $feed->outItem($item);
                        $feed->outFooter();
                } else {
                        // Error has occured, print something usefull
-                       // TODO: make this error more informative using $this->dieDebug() or similar
+                       // TODO: make this error more informative using ApiBase :: dieDebug() or similar
                        wfHttpError(500, 'Internal Server Error', '');
                }
        }
-
+       
        public function getVersion() {
                return __CLASS__ . ': $Id$';
        }
 }
-?>
\ No newline at end of file