]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - RPC2.php
Renamed from WikiXMLRPC.php for consistency with other servers. A few comments added
[SourceForge/phpwiki.git] / RPC2.php
1 <?php \r// $Id: RPC2.php,v 1.1 2002-09-02 08:13:51 lakka Exp $\r/* Copyright (C) 2002, Lawrence Akka <lakka@users.sourceforge.net>\r *\r * LICENCE\r * =======\r * This file is part of PhpWiki.\r * \r * PhpWiki is free software; you can redistribute it and/or modify\r * it under the terms of the GNU General Public License as published by\r * the Free Software Foundation; either version 2 of the License, or\r * (at your option) any later version.\r * \r * PhpWiki is distributed in the hope that it will be useful,\r * but WITHOUT ANY WARRANTY; without even the implied warranty of\r * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r * GNU General Public License for more details.\r * \r * You should have received a copy of the GNU General Public License\r * along with PhpWiki; if not, write to the Free Software\r * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r *\r * LIBRARY USED - POSSIBLE PROBLEMS\r * ================================\r * \r * This file provides an XML-RPC interface for PhpWiki.  It uses the XML-RPC \r * library for PHP by Edd Dumbill - see http://xmlrpc.usefulinc.com/php.html \r * for details.\r *\r * PHP >= 4.1.0 includes experimental support for the xmlrpc-epi c library \r * written by Dan Libby (see http://uk2.php.net/manual/en/ref.xmlrpc.php).  This\r * is not compiled into PHP by default.  If it *is* compiled into your installation\r * (ie you have --with-xmlrpc) there may well be namespace conflicts with the xml-rpc\r * library used by this code, and you will get errors.\r * \r * INTERFACE SPECIFICTION\r * ======================\r *  \r * The interface specification is that discussed at \r * http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=WikiRPCInterface\r * \r * See also http://www.usemod.com/cgi-bin/mb.pl?XmlRpc\r * \r * NB:  All XMLRPC methods should be prefixed with "wiki."\r * eg  wiki.getAllPages\r * \r \r*/\r\r// ToDo:  \r//        Remove all warnings from xmlrpc.inc \r//        Return list of external links in listLinks\r \r\r// Intercept GET requests from confused users.  Only POST is allowed here!\r// There is some indication that $HTTP_SERVER_VARS is deprecated in php > 4.1.0\r// in favour of $_Server, but as far as I know, it still works.\rif ($HTTP_SERVER_VARS['REQUEST_METHOD'] != "POST")  \r{\r    die('This is the address of the XML-RPC interface.  You must use XML-RPC calls to access information here');\r}\r\r// Include the php XML-RPC library\rinclude("lib/XMLRPC/xmlrpc.inc");\rinclude("lib/XMLRPC/xmlrpcs.inc");\r\r// Constant defined to indicate to phpwiki that it is being accessed via XML-RPC\rdefine ("WIKI_XMLRPC", "true");\r//  API version\rdefine ("WIKI_XMLRPC_VERSION", 1);\r// Start up the main code\rinclude_once("index.php");\rinclude_once("lib/main.php");\r\r/**\r * Helper function:  Looks up a page revision (most recent by default) in the wiki database\r * \r * @param xmlrpcmsg $params :  string pagename [int version]\r * @return WikiDB _PageRevision object, or false if no such page\r */\r\rfunction _getPageRevision ($params)\r{\r    global $request;\r    $ParamPageName = $params->getParam(0);\r    $ParamVersion = $params->getParam(1);\r    // ?? really need utf8_decode here?\r    $pagename = utf8_decode($ParamPageName->scalarval());\r    $version =  ($ParamVersion) ? ($ParamVersion->scalarval()):(0);\r    // FIXME:  test for version <=0 ??\r    $dbh = $request->getDbh();\r    if ($dbh->isWikiPage($pagename)) {\r        $page = $dbh->getPage($pagename);\r        if (!$version) {\r            $revision = $page->getCurrentRevision();\r        } else {\r            $revision = $page->getRevision($version);\r        } \r        return $revision;\r    } \r    return false;\r\r\r// ****************************************************************************\r// Main API functions follow\r// ****************************************************************************\r\r\r/**\r * int getRPCVersionSupported(): Returns 1 for this version of the API \r*/\r\r// Method signature:  An array of possible signatures.  Each signature is\r// an array of types. The first entry is the return type.  The other \r// entries (if any) are the parameter types\r$getRPCVersionSupported_sig = array(array($xmlrpcInt));\r// Doc string:  A string containing documentation for the method. The \r// documentation may contain HTML markup\r$getRPCVersionSupported_doc = 'Get the version of the wiki API';\r\r// The function must be a function in the global scope which services the XML-RPC\r// method.\rfunction getRPCVersionSupported($params)\r{\r   return new xmlrpcresp(new xmlrpcval(WIKI_XMLRPC_VERSION, "int"));\r}\r\r/**\r * array getRecentChanges(Date timestamp) : Get list of changed pages since \r * timestamp, which should be in UTC. The result is an array, where each element\r * is a struct: \r *     name (string) : Name of the page. The name is UTF-8 with URL encoding to make it ASCII. \r *     lastModified (date) : Date of last modification, in UTC. \r *     author (string) : Name of the author (if available). Again, name is UTF-8 with URL encoding. \r *           version (int) : Current version. \r * A page MAY be specified multiple times. A page MAY NOT be specified multiple \r * times with the same modification date.\r */\r$getRecentChanges_sig = array(array($xmlrpcArray, $xmlrpcDateTime));\r$getRecentChanges_doc = 'Get a list of changed pages since [timestamp]';\r\rfunction getRecentChanges($params)\r{\r    global $request, $xmlrpcerruser;\r    $err = "";\r//    $retval = new xmlrpcval();\r    // Get the first parameter as an ISO 8601 date.  Assume UTC\r    $encoded_date = $params->getParam(0);\r $datetime = iso8601_decode($encoded_date->scalarval(), 1);\r     $dbh = $request->getDbh();\r    $pages = array();\r    $iterator = $dbh->mostRecent(array('since' => $datetime));\r    while ($page = $iterator->next()) {\r                // $page contains a WikiDB_PageRevision object\r        // no need to url encode $name, because it is already stored in that format ???\r        $name = new xmlrpcval(utf8_encode($page->getPageName())); \r              $lastmodified = new xmlrpcval(iso8601_encode($page->get('mtime')), "dateTime.iso8601");\r                $author = new xmlrpcval(utf8_encode($page->get('author')));\r            $version = new xmlrpcval($page->getVersion, 'int');\r\r           // Build an array of xmlrpc structs\r        $pages[] = new xmlrpcval(array('name'=>$name, \r                                                                        'lastModified'=>$lastmodified,\r                                                                         'author'=>$author,\r                                                                     'version'=>$version),\r                                                                'struct');\r    } \r    return new xmlrpcresp(new xmlrpcval($pages, "array"));\r\r\r\r/**\r * base64 getPage( String pagename ): Get the raw Wiki text of page, latest version. \r * Page name must be UTF-8, with URL encoding. Returned value is a binary object,\r * with UTF-8 encoded page data.\r */\r\r$getPage_sig = array(array($xmlrpcBase64, $xmlrpcString));\r$getPage_doc = 'Get the raw Wiki text of the current version of a page';\r\rfunction getPage($params)\r{\r   global $request, $xmlrpcerruser;\r   $revision = _getPageRevision($params);\r\r    if ($revision) {\r        // fixme : need urlencoding here?\r        $content = ($revision->getPackedContent());\r        return new xmlrpcresp(new xmlrpcval($content, "base64"));\r    } else\r       // return an errror response\r        return new xmlrpcresp(0, $xmlrpcerruser + 1, "No such page");\r}\r \r\r/**\r * base64 getPageVersion( String pagename, int version ): Get the raw Wiki text of page.\r * Returns UTF-8, expects UTF-8 with URL encoding.\r */\r\r$getPageVersion_sig = array(array($xmlrpcBase64, $xmlrpcString, $xmlrpcInt));\r$getPageVersion_doc = 'Get the raw Wiki text of a page version';\r\rfunction getPageVersion($params)\r{\r    global $request, $xmlrpcerruser;\r    return getPage($params);\r  // error checking is done in getPage\r\r\r/**\r * base64 getPageHTML( String pagename ): Return page in rendered HTML. \r * Returns UTF-8, expects UTF-8 with URL encoding.\r */\r\r$getPageHTML_sig = array(array($xmlrpcString, $xmlrpcString));\r$getPageHTML_doc = 'Get the current version of a page rendered in HTML';\r\rfunction getPageHTML($params)\r{\r    global $request, $xmlrpcerruser;\r    $revision = _getPageRevision($params);\r    if ($revision) {\r        include_once('lib/display.php');\r        // This is a bit hacky.  Start output buffering, fake a request, and get phpWiki\r          // to render the page.  Then return it via XMLRPC.\r        $request->setArg('pagename',$revision->getPageName());\r        $request->setArg('version',$revision->getVersion());\r         ob_start();\r        displayPage($request);\r        $output = ob_get_contents();\r        ob_end_clean();\r//        xmlrpc_debugmsg("$output");\r        return new xmlrpcresp(new xmlrpcval(utf8_encode($output), "string"));\r    } else\r        return new xmlrpcresp(0, $xmlrpcerruser + 1, "No such page");\r\r\r/**\r * base64 getPageHTMLVersion( String pagename, int version ): Return page in rendered HTML, UTF-8.\r */\r\r$getPageHTMLVersion_sig = array(array($xmlrpcBase64, $xmlrpcString, $xmlrpcInt));\r$getPageHTMLVersion_doc = 'Get a version of a page rendered in HTML';\r\rfunction getPageHTMLVersion($params)\r{\r    global $request, $xmlrpcerruser;\r    return getPageHTML($params);\r\r\r/**\r * getAllPages(): Returns a list of all pages. The result is an array of strings.\r */\r\r$getAllPages_sig = array(array($xmlrpcArray));\r$getAllPages_doc = 'Returns a list of all pages as an array of strings'; \r \rfunction getAllPages($params)\r{\r    global $request, $xmlrpcerruser;\r    $dbh = $request->getDbh();\r    $iterator = $dbh->getAllPages();\r    $pages = array();\r    while ($page = $iterator->next()) {\r        $pages[] = new xmlrpcval($page->getName());\r    } \r    return new xmlrpcresp(new xmlrpcval($pages, "array"));\r\r\r/**\r * struct getPageInfo( string pagename ) : returns a struct with elements: \r *   name (string): the canonical page name \r *   lastModified (date): Last modification date \r *   version (int): current version \r *     author (string): author name \r */\r\r$getPageInfo_sig = array(array($xmlrpcStruct, $xmlrpcString));\r$getPageInfo_doc = 'Gets info about the current version of a page';\r\rfunction getPageInfo($params)\r{\r   global $xmlrpcerruser;\r   $revision = _getPageRevision($params);\r   if ($revision) {\r        $name = new xmlrpcval($params->getParam(0));\r        $version = new xmlrpcval ($revision->getVersion(), "int");\r        $lastmodified = new xmlrpcval(iso8601_encode($revision->get('mtime'), 0), "dateTime.iso8601");\r        $author = new xmlrpcval($revision->get('author'));\r\r        return new xmlrpcresp(new xmlrpcval(array('name' => $name, \r                                                   'lastModified' => $lastmodified,\r                                                  'version' => $version, \r                                                                                             'author' => $author), \r                                                                                   "struct"));\r    } else\r        return new xmlrpcresp(0, $xmlrpcerruser + 1, "No such page");\r\r\r/**\r * struct getPageInfoVersion( string pagename, int version ) : returns a struct just like plain getPageInfo(), \r *     but this time for a specific version.\r */\r\r$getPageInfoVersion_sig = array(array($xmlrpcStruct, $xmlrpcString, $xmlrpcInt));\r$getPageInfoVersion_doc = 'Gets info about a page version';\r\rfunction getPageInfoVersion($params)\r{\r    global $request, $xmlrpcerruser;\r    return getPageInfo($params);\r}\r\r \r/*  array listLinks( string pagename ): Lists all links for a given page. The\r *  returned array contains structs, with the following elements: \r *          name (string) : The page name or URL the link is to. \r *       type (int) : The link type. Zero (0) for internal Wiki link,\r *         one (1) for external link (URL - image link, whatever).\r */\r\r$listLinks_sig = array(array($xmlrpcArray, $xmlrpcString));\r$listLinks_doc = 'Lists all links for a given page';\r\rfunction listLinks($params)\r{\r    global $request, $xmlrpcerruser;\r    $ParamPageName = $params->getParam(0);\r   // ?? really need utf8_decode here?\r    $pagename = utf8_decode($ParamPageName->scalarval());\r          $dbh = $request->getDbh();\r    if ($dbh->isWikiPage($pagename)) {\r        $page = $dbh->getPage($pagename);\r            $linkiterator = $page->getLinks();\r        $linkstruct = array();\r        while ($currentpage = $linkiterator->next()) {\r            $currentname = $currentpage->getName();\r            $name = new xmlrpcval($currentname, "string");    \r// NB no clean way to extract a list of external links yet, so\r// only internal links returned.  ie all type 0.\r                    $type = new xmlrpcval(0, "int");\r                   $linkstruct[] = new xmlrpcval(array('name'=> $name,\r                                                        'type'=> $type\r                                                                           ), "struct");\r        }\r          return new xmlrpcresp(new xmlrpcval ($linkstruct, "array"));\r    } else\r        return new xmlrpcresp(0, $xmlrpcerruser + 1, "No such page");\r\r \r// Construct the server instance, and set up the despatch map, which maps\r// the XML-RPC methods onto the wiki functions\r$s = new xmlrpc_server(array("wiki.getRPCVersionSupported" =>\r                             array("function" => "getRPCVersionSupported",\r                                   "signature" => $getRPCVersionSupported_sig,\r                                   "docstring" => $getRPCVersionSupported_doc),\r                             "wiki.getRecentChanges" =>\r                             array("function" => "getRecentChanges",\r                                   "signature" => $getRecentChanges_sig,\r                                   "docstring" => $getRecentChanges_doc),\r                             "wiki.getPage" =>\r                             array("function" => "getPage",\r                                   "signature" => $getPage_sig,\r                                   "docstring" => $getPage_doc),\r                             "wiki.getPageVersion" =>\r                             array("function" => "getPageVersion",\r                                   "signature" => $getPageVersion_sig,\r                                   "docstring" => $getPageVersion_doc),\r                             "wiki.getPageHTML" =>\r                             array("function" => "getPageHTML",\r                                   "signature" => $getPageHTML_sig,\r                                   "docstring" => $getPageHTML_doc),\r                             "wiki.getPageHTMLVersion" =>\r                             array("function" => "getPageHTMLVersion",\r                                   "signature" => $getPageHTMLVersion_sig,\r                                   "docstring" => $getPageHTMLVersion_doc),\r                             "wiki.getAllPages" =>\r                             array("function" => "getAllPages",\r                                   "signature" => $getAllPages_sig,\r                                   "docstring" => $getAllPages_doc),\r                             "wiki.getPageInfo" =>\r                             array("function" => "getPageInfo",\r                                   "signature" => $getPageInfo_sig,\r                                   "docstring" => $getPageInfo_doc),\r                             "wiki.getPageInfoVersion" =>\r                             array("function" => "getPageInfoVersion",\r                                   "signature" => $getPageInfoVersion_sig,\r                                   "docstring" => $getPageInfoVersion_doc),\r                             "wiki.listLinks" =>\r                             array("function" => "listLinks",\r                                   "signature" => $listLinks_sig,\r                                   "docstring" => $listLinks_doc)\r        ));\r\r?>