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?>