]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - RPC2.php
Convert to unix line endings (newline instead of carriage-return).
[SourceForge/phpwiki.git] / RPC2.php
1 <?php 
2 // $Id: RPC2.php,v 1.2 2002-09-04 19:33:36 dairiki Exp $
3 /* Copyright (C) 2002, Lawrence Akka <lakka@users.sourceforge.net>
4  *
5  * LICENCE
6  * =======
7  * This file is part of PhpWiki.
8  * 
9  * PhpWiki is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * PhpWiki is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with PhpWiki; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  * LIBRARY USED - POSSIBLE PROBLEMS
24  * ================================
25  * 
26  * This file provides an XML-RPC interface for PhpWiki.  It uses the XML-RPC 
27  * library for PHP by Edd Dumbill - see http://xmlrpc.usefulinc.com/php.html 
28  * for details.
29  *
30  * PHP >= 4.1.0 includes experimental support for the xmlrpc-epi c library 
31  * written by Dan Libby (see http://uk2.php.net/manual/en/ref.xmlrpc.php).  This
32  * is not compiled into PHP by default.  If it *is* compiled into your installation
33  * (ie you have --with-xmlrpc) there may well be namespace conflicts with the xml-rpc
34  * library used by this code, and you will get errors.
35  * 
36  * INTERFACE SPECIFICTION
37  * ======================
38  *  
39  * The interface specification is that discussed at 
40  * http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=WikiRPCInterface
41  * 
42  * See also http://www.usemod.com/cgi-bin/mb.pl?XmlRpc
43  * 
44  * NB:  All XMLRPC methods should be prefixed with "wiki."
45  * eg  wiki.getAllPages
46  * 
47  
48 */
49
50 // ToDo:  
51 //        Remove all warnings from xmlrpc.inc 
52 //        Return list of external links in listLinks
53  
54
55 // Intercept GET requests from confused users.  Only POST is allowed here!
56 // There is some indication that $HTTP_SERVER_VARS is deprecated in php > 4.1.0
57 // in favour of $_Server, but as far as I know, it still works.
58 if ($HTTP_SERVER_VARS['REQUEST_METHOD'] != "POST")  
59 {
60     die('This is the address of the XML-RPC interface.' .
61         '  You must use XML-RPC calls to access information here');
62 }
63
64 // Include the php XML-RPC library
65 include("lib/XMLRPC/xmlrpc.inc");
66 include("lib/XMLRPC/xmlrpcs.inc");
67
68 // Constant defined to indicate to phpwiki that it is being accessed via XML-RPC
69 define ("WIKI_XMLRPC", "true");
70 //  API version
71 define ("WIKI_XMLRPC_VERSION", 1);
72 // Start up the main code
73 include_once("index.php");
74 include_once("lib/main.php");
75
76 /**
77  * Helper function:  Looks up a page revision (most recent by default) in the wiki database
78  * 
79  * @param xmlrpcmsg $params :  string pagename [int version]
80  * @return WikiDB _PageRevision object, or false if no such page
81  */
82
83 function _getPageRevision ($params)
84 {
85     global $request;
86     $ParamPageName = $params->getParam(0);
87     $ParamVersion = $params->getParam(1);
88         // ?? really need utf8_decode here?
89     $pagename = utf8_decode($ParamPageName->scalarval());
90     $version =  ($ParamVersion) ? ($ParamVersion->scalarval()):(0);
91     // FIXME:  test for version <=0 ??
92     $dbh = $request->getDbh();
93     if ($dbh->isWikiPage($pagename)) {
94         $page = $dbh->getPage($pagename);
95         if (!$version) {
96             $revision = $page->getCurrentRevision();
97         } else {
98             $revision = $page->getRevision($version);
99         } 
100         return $revision;
101     } 
102     return false;
103
104
105 // ****************************************************************************
106 // Main API functions follow
107 // ****************************************************************************
108
109
110 /**
111  * int getRPCVersionSupported(): Returns 1 for this version of the API 
112  */
113
114 // Method signature:  An array of possible signatures.  Each signature is
115 // an array of types. The first entry is the return type.  The other 
116 // entries (if any) are the parameter types
117 $getRPCVersionSupported_sig = array(array($xmlrpcInt));
118 // Doc string:  A string containing documentation for the method. The 
119 // documentation may contain HTML markup
120 $getRPCVersionSupported_doc = 'Get the version of the wiki API';
121
122 // The function must be a function in the global scope which services the XML-RPC
123 // method.
124 function getRPCVersionSupported($params)
125 {
126     return new xmlrpcresp(new xmlrpcval(WIKI_XMLRPC_VERSION, "int"));
127 }
128
129 /**
130  * array getRecentChanges(Date timestamp) : Get list of changed pages since 
131  * timestamp, which should be in UTC. The result is an array, where each element
132  * is a struct: 
133  *     name (string) : Name of the page. The name is UTF-8 with URL encoding to make it ASCII. 
134  *     lastModified (date) : Date of last modification, in UTC. 
135  *     author (string) : Name of the author (if available). Again, name is UTF-8 with URL encoding. 
136  *         version (int) : Current version. 
137  * A page MAY be specified multiple times. A page MAY NOT be specified multiple 
138  * times with the same modification date.
139  */
140 $getRecentChanges_sig = array(array($xmlrpcArray, $xmlrpcDateTime));
141 $getRecentChanges_doc = 'Get a list of changed pages since [timestamp]';
142
143 function getRecentChanges($params)
144 {
145     global $request, $xmlrpcerruser;
146     // Get the first parameter as an ISO 8601 date.  Assume UTC
147     $encoded_date = $params->getParam(0);
148     $datetime = iso8601_decode($encoded_date->scalarval(), 1);
149     $dbh = $request->getDbh();
150     $pages = array();
151     $iterator = $dbh->mostRecent(array('since' => $datetime));
152     while ($page = $iterator->next()) {
153         // $page contains a WikiDB_PageRevision object
154         // no need to url encode $name, because it is already stored in that format ???
155         $name = new xmlrpcval(utf8_encode($page->getPageName())); 
156         $lastmodified = new xmlrpcval(iso8601_encode($page->get('mtime')), "dateTime.iso8601");
157         $author = new xmlrpcval(utf8_encode($page->get('author')));
158         $version = new xmlrpcval($page->getVersion, 'int');
159
160         // Build an array of xmlrpc structs
161         $pages[] = new xmlrpcval(array('name'=>$name, 
162                                        'lastModified'=>$lastmodified,
163                                        'author'=>$author,
164                                        'version'=>$version),
165                                  'struct');
166     } 
167     return new xmlrpcresp(new xmlrpcval($pages, "array"));
168
169
170
171 /**
172  * base64 getPage( String pagename ): Get the raw Wiki text of page, latest version. 
173  * Page name must be UTF-8, with URL encoding. Returned value is a binary object,
174  * with UTF-8 encoded page data.
175  */
176
177 $getPage_sig = array(array($xmlrpcBase64, $xmlrpcString));
178 $getPage_doc = 'Get the raw Wiki text of the current version of a page';
179
180 function getPage($params)
181 {
182     global $request, $xmlrpcerruser;
183     $revision = _getPageRevision($params);
184
185     if ($revision) {
186         // fixme : need urlencoding here?
187         $content = ($revision->getPackedContent());
188         return new xmlrpcresp(new xmlrpcval($content, "base64"));
189     }
190     else {
191         // return an errror response
192         return new xmlrpcresp(0, $xmlrpcerruser + 1, "No such page");
193     }
194 }
195
196  
197
198 /**
199  * base64 getPageVersion( String pagename, int version ): Get the raw Wiki text of page.
200  * Returns UTF-8, expects UTF-8 with URL encoding.
201  */
202
203 $getPageVersion_sig = array(array($xmlrpcBase64, $xmlrpcString, $xmlrpcInt));
204 $getPageVersion_doc = 'Get the raw Wiki text of a page version';
205
206 function getPageVersion($params)
207 {
208     global $request, $xmlrpcerruser;
209     return getPage($params);
210     // error checking is done in getPage
211
212
213 /**
214  * base64 getPageHTML( String pagename ): Return page in rendered HTML. 
215  * Returns UTF-8, expects UTF-8 with URL encoding.
216  */
217
218 $getPageHTML_sig = array(array($xmlrpcString, $xmlrpcString));
219 $getPageHTML_doc = 'Get the current version of a page rendered in HTML';
220
221 function getPageHTML($params)
222 {
223     global $request, $xmlrpcerruser;
224     $revision = _getPageRevision($params);
225     if ($revision) {
226         include_once('lib/display.php');
227         // This is a bit hacky.  Start output buffering, fake a request, and get phpWiki
228         // to render the page.  Then return it via XMLRPC.
229         $request->setArg('pagename',$revision->getPageName());
230         $request->setArg('version',$revision->getVersion());
231         ob_start();
232         displayPage($request);
233         $output = ob_get_contents();
234         ob_end_clean();
235         //        xmlrpc_debugmsg("$output");
236         return new xmlrpcresp(new xmlrpcval(utf8_encode($output), "string"));
237     }
238     else {
239         return new xmlrpcresp(0, $xmlrpcerruser + 1, "No such page");
240     }
241
242
243 /**
244  * base64 getPageHTMLVersion( String pagename, int version ): Return page in rendered HTML, UTF-8.
245  */
246
247 $getPageHTMLVersion_sig = array(array($xmlrpcBase64, $xmlrpcString, $xmlrpcInt));
248 $getPageHTMLVersion_doc = 'Get a version of a page rendered in HTML';
249
250 function getPageHTMLVersion($params)
251 {
252     global $request, $xmlrpcerruser;
253     return getPageHTML($params);
254
255
256 /**
257  * getAllPages(): Returns a list of all pages. The result is an array of strings.
258  */
259
260 $getAllPages_sig = array(array($xmlrpcArray));
261 $getAllPages_doc = 'Returns a list of all pages as an array of strings'; 
262  
263 function getAllPages($params)
264 {
265     global $request, $xmlrpcerruser;
266     $dbh = $request->getDbh();
267     $iterator = $dbh->getAllPages();
268     $pages = array();
269     while ($page = $iterator->next()) {
270         $pages[] = new xmlrpcval($page->getName());
271     } 
272     return new xmlrpcresp(new xmlrpcval($pages, "array"));
273
274
275 /**
276  * struct getPageInfo( string pagename ) : returns a struct with elements: 
277  *   name (string): the canonical page name 
278  *   lastModified (date): Last modification date 
279  *   version (int): current version 
280  *       author (string): author name 
281  */
282
283 $getPageInfo_sig = array(array($xmlrpcStruct, $xmlrpcString));
284 $getPageInfo_doc = 'Gets info about the current version of a page';
285
286 function getPageInfo($params)
287 {
288     global $xmlrpcerruser;
289     $revision = _getPageRevision($params);
290     if ($revision) {
291         $name = new xmlrpcval($params->getParam(0));
292         $version = new xmlrpcval ($revision->getVersion(), "int");
293         $lastmodified = new xmlrpcval(iso8601_encode($revision->get('mtime'), 0), "dateTime.iso8601");
294         $author = new xmlrpcval($revision->get('author'));
295
296         return new xmlrpcresp(new xmlrpcval(array('name' => $name, 
297                                                   'lastModified' => $lastmodified,
298                                                   'version' => $version, 
299                                                   'author' => $author), 
300                                             "struct"));
301     }
302     else {
303         return new xmlrpcresp(0, $xmlrpcerruser + 1, "No such page");
304     }
305
306
307 /**
308  * struct getPageInfoVersion( string pagename, int version ) : returns a struct just like plain getPageInfo(), 
309  *      but this time for a specific version.
310  */
311
312 $getPageInfoVersion_sig = array(array($xmlrpcStruct, $xmlrpcString, $xmlrpcInt));
313 $getPageInfoVersion_doc = 'Gets info about a page version';
314
315 function getPageInfoVersion($params)
316 {
317     global $request, $xmlrpcerruser;
318     return getPageInfo($params);
319 }
320
321  
322 /*  array listLinks( string pagename ): Lists all links for a given page. The
323  *  returned array contains structs, with the following elements: 
324  *       name (string) : The page name or URL the link is to. 
325  *       type (int) : The link type. Zero (0) for internal Wiki link,
326  *         one (1) for external link (URL - image link, whatever).
327  */
328
329 $listLinks_sig = array(array($xmlrpcArray, $xmlrpcString));
330 $listLinks_doc = 'Lists all links for a given page';
331
332 function listLinks($params)
333 {
334     global $request, $xmlrpcerruser;
335     $ParamPageName = $params->getParam(0);
336     // ?? really need utf8_decode here?
337     $pagename = utf8_decode($ParamPageName->scalarval());
338     $dbh = $request->getDbh();
339     if ($dbh->isWikiPage($pagename)) {
340         $page = $dbh->getPage($pagename);
341         $linkiterator = $page->getLinks();
342         $linkstruct = array();
343         while ($currentpage = $linkiterator->next()) {
344             $currentname = $currentpage->getName();
345             $name = new xmlrpcval($currentname, "string");    
346             // NB no clean way to extract a list of external links yet, so
347             // only internal links returned.  ie all type 0.
348             $type = new xmlrpcval(0, "int");
349             $linkstruct[] = new xmlrpcval(array('name'=> $name,
350                                                 'type'=> $type
351                                                 ), "struct");
352         }
353             return new xmlrpcresp(new xmlrpcval ($linkstruct, "array"));
354     } else
355         return new xmlrpcresp(0, $xmlrpcerruser + 1, "No such page");
356
357  
358 // Construct the server instance, and set up the despatch map, which maps
359 // the XML-RPC methods onto the wiki functions
360 $s = new xmlrpc_server(array("wiki.getRPCVersionSupported" =>
361                              array("function" => "getRPCVersionSupported",
362                                    "signature" => $getRPCVersionSupported_sig,
363                                    "docstring" => $getRPCVersionSupported_doc),
364                              "wiki.getRecentChanges" =>
365                              array("function" => "getRecentChanges",
366                                    "signature" => $getRecentChanges_sig,
367                                    "docstring" => $getRecentChanges_doc),
368                              "wiki.getPage" =>
369                              array("function" => "getPage",
370                                    "signature" => $getPage_sig,
371                                    "docstring" => $getPage_doc),
372                              "wiki.getPageVersion" =>
373                              array("function" => "getPageVersion",
374                                    "signature" => $getPageVersion_sig,
375                                    "docstring" => $getPageVersion_doc),
376                              "wiki.getPageHTML" =>
377                              array("function" => "getPageHTML",
378                                    "signature" => $getPageHTML_sig,
379                                    "docstring" => $getPageHTML_doc),
380                              "wiki.getPageHTMLVersion" =>
381                              array("function" => "getPageHTMLVersion",
382                                    "signature" => $getPageHTMLVersion_sig,
383                                    "docstring" => $getPageHTMLVersion_doc),
384                              "wiki.getAllPages" =>
385                              array("function" => "getAllPages",
386                                    "signature" => $getAllPages_sig,
387                                    "docstring" => $getAllPages_doc),
388                              "wiki.getPageInfo" =>
389                              array("function" => "getPageInfo",
390                                    "signature" => $getPageInfo_sig,
391                                    "docstring" => $getPageInfo_doc),
392                              "wiki.getPageInfoVersion" =>
393                              array("function" => "getPageInfoVersion",
394                                    "signature" => $getPageInfoVersion_sig,
395                                    "docstring" => $getPageInfoVersion_doc),
396                              "wiki.listLinks" =>
397                              array("function" => "listLinks",
398                                    "signature" => $listLinks_sig,
399                                    "docstring" => $listLinks_doc)
400                              ));
401                              
402 // (c-file-style: "gnu")
403 // Local Variables:
404 // mode: php
405 // tab-width: 8
406 // c-basic-offset: 4
407 // c-hanging-comment-ender-p: nil
408 // indent-tabs-mode: nil
409 // End:   
410 ?>