]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - SOAP.php
Update translations
[SourceForge/phpwiki.git] / SOAP.php
1 <?php
2 /**
3  * SOAP server
4  * Taken from http://www.wlug.org.nz/archive/
5  * Please see http://phpwiki.sourceforge.net/phpwiki/PhpWiki.wdsl
6  * for the wdsl discussion.
7  *
8  * Todo:
9  * checkCredentials: set the $GLOBALS['request']->_user object for
10  *                   mayAccessPage
11  * server url:
12  *   Installer helper which changes server url of the default PhpWiki.wdsl
13  *   Or do it dynamically in the soap class? No, the client must connect to us.
14  *
15  * @author: Reini Urban
16  * @author: Marc-Etienne Vargenau
17  *          Rewrite with native PHP 5 SOAP
18  */
19 define ("WIKI_SOAP", true);
20 define ("PHPWIKI_NOMAIN", true);
21
22 require_once 'lib/prepend.php';
23 require_once 'lib/IniConfig.php';
24 IniConfig('config/config.ini');
25 require_once 'lib/main.php';
26
27 function checkCredentials(&$server, &$credentials, $access, $pagename)
28 {
29     // check the "Authorization: Basic '.base64_encode("$this->username:$this->password").'\r\n'" header
30     if (isset($server->header['Authorization'])) {
31         $line = base64_decode(str_replace("Basic ", "", trim($server->header['Authorization'])));
32         list($username, $password) = explode(':', $line);
33     } elseif ($credentials && is_string($credentials) && base64_decode($credentials, true)) {
34         list($username, $password) = explode(':', base64_decode($credentials));
35     } else {
36         if (!isset($_SERVER))
37             $_SERVER =& $GLOBALS['HTTP_SERVER_VARS'];
38             // TODO: where in the header is the client IP
39             if (!isset($username)) {
40                 if (isset($_SERVER['REMOTE_ADDR']))
41                     $username = $_SERVER['REMOTE_ADDR'];
42                 elseif (isset($GLOBALS['REMOTE_ADDR']))
43                     $username = $GLOBALS['REMOTE_ADDR'];
44                 else
45                     $username = $server->host;
46             }
47     }
48     if (!isset($password))
49         $password = '';
50
51     global $request;
52     $request->_user = WikiUser($username);
53     $request->_user->AuthCheck(array('userid' => $username, 'passwd' => $password));
54
55     if (!mayAccessPage($access, $pagename)) {
56         $server->fault(401, "no permission, "
57                           . "access=$access, "
58                           . "pagename=$pagename, "
59                           . "username=$username"
60                           );
61     }
62     $credentials = array('username' => $username, 'password' => $password);
63 }
64
65 class PhpWikiSoapServer
66 {
67     //todo: check and set credentials
68     // requiredAuthorityForPage($action);
69     // require 'edit' access
70     function doSavePage($pagename, $content, $credentials = false)
71     {
72         global $server;
73         checkCredentials($server, $credentials, 'edit', $pagename);
74         $dbi = WikiDB::open($GLOBALS['DBParams']);
75         $page = $dbi->getPage($pagename);
76         $current = $page->getCurrentRevision();
77         $version = $current->getVersion();
78         $userid = $credentials['username'];
79         $summary = sprintf(_("SOAP Request by %s"), $userid);
80         $meta = array('author' => $userid,
81                       'author_id' => $userid,
82                       'summary' => $summary,
83                       'mtime' => time(),
84                       'pagetype' => 'wikitext'
85                      );
86         $ret = $page->save($content, $version + 1, $meta);
87         if ($ret === false) {
88             return "Failed";
89         } else {
90             return "Done";
91         }
92     }
93
94     // require 'view' access
95     function getPageContent($pagename, $credentials = false)
96     {
97         global $server;
98         checkCredentials($server, $credentials, 'view', $pagename);
99         $dbi = WikiDB::open($GLOBALS['DBParams']);
100         $page = $dbi->getPage($pagename);
101         $rev = $page->getCurrentRevision();
102         $text = $rev->getPackedContent();
103         return $text;
104     }
105
106     // require 'view' access
107     function getPageRevision($pagename, $revision, $credentials = false)
108     {
109         global $server;
110         checkCredentials($server, $credentials, 'view', $pagename);
111         $dbi = WikiDB::open($GLOBALS['DBParams']);
112         $page = $dbi->getPage($pagename);
113         $rev = $page->getRevision($revision);
114         $text = $rev->getPackedContent();
115         return $text;
116     }
117
118     // require 'view' access
119     function getCurrentRevision($pagename, $credentials = false)
120     {
121         global $server;
122         checkCredentials($server, $credentials, 'view', $pagename);
123         $dbi = WikiDB::open($GLOBALS['DBParams']);
124         $page = $dbi->getPage($pagename);
125         $version = $page->getVersion();
126         return (double)$version;
127     }
128
129     // require 'change' or 'view' access ?
130     function getPageMeta($pagename, $credentials = false)
131     {
132         global $server;
133         checkCredentials($server, $credentials, 'view', $pagename);
134         $dbi = WikiDB::open($GLOBALS['DBParams']);
135         $page = $dbi->getPage($pagename);
136         return $page->getMetaData();
137     }
138
139     // require 'view' access to AllPages
140     function getAllPagenames($credentials = false)
141     {
142         global $server;
143         checkCredentials($server, $credentials, 'view', _("AllPages"));
144         $dbi = WikiDB::open($GLOBALS['DBParams']);
145         $page_iter = $dbi->getAllPages();
146         $pages = array();
147         while ($page = $page_iter->next()) {
148             $pages[] = array('pagename' => $page->_pagename);
149         }
150         sort($pages);
151         return $pages;
152     }
153
154     // require 'view' access
155     function getBacklinks($pagename, $credentials = false)
156     {
157         global $server;
158         checkCredentials($server, $credentials, 'view', $pagename);
159         $dbi = WikiDB::open($GLOBALS['DBParams']);
160         $backend = &$dbi->_backend;
161         $result = $backend->get_links($pagename);
162         $page_iter = new WikiDB_PageIterator($dbi, $result);
163         $pages = array();
164         while ($page = $page_iter->next()) {
165             $pages[] = array('pagename' => $page->getName());
166         }
167         return $pages;
168     }
169
170     // require 'view' access to TitleSearch
171     function doTitleSearch($s, $credentials = false)
172     {
173         require_once 'lib/TextSearchQuery.php';
174
175         global $server;
176         checkCredentials($server, $credentials, 'view', _("TitleSearch"));
177         $dbi = WikiDB::open($GLOBALS['DBParams']);
178         $query = new TextSearchQuery($s);
179         $page_iter = $dbi->titleSearch($query);
180         $pages = array();
181         while ($page = $page_iter->next()) {
182             $pages[] = array('pagename' => $page->getName());
183         }
184         return $pages;
185     }
186
187     // require 'view' access to FullTextSearch
188     function doFullTextSearch($s, $credentials = false)
189     {
190         require_once 'lib/TextSearchQuery.php';
191
192         global $server;
193         checkCredentials($server, $credentials, 'view', _("FullTextSearch"));
194         $dbi = WikiDB::open($GLOBALS['DBParams']);
195         $query = new TextSearchQuery($s);
196         $page_iter = $dbi->fullSearch($query);
197         $pages = array();
198         while ($page = $page_iter->next()) {
199             $pages[] = array('pagename' => $page->getName());
200         }
201         return $pages;
202     }
203
204     // require 'view' access to RecentChanges
205     function getRecentChanges($limit = false, $since = false, $include_minor = false, $credentials = false)
206     {
207         global $server;
208         checkCredentials($server, $credentials, 'view', _("RecentChanges"));
209         $dbi = WikiDB::open($GLOBALS['DBParams']);
210         $params = array('limit' => $limit, 'since' => $since,
211             'include_minor_revisions' => $include_minor);
212         $page_iter = $dbi->mostRecent($params);
213         $pages = array();
214         while ($page = $page_iter->next()) {
215             $pages[] = array('pagename' => $page->getName(),
216                 'lastModified' => $page->get('mtime'),
217                 'author' => $page->get('author'),
218                 'summary' => $page->get('summary'), // added with 1.3.13
219                 'version' => $page->getVersion()
220             );
221         }
222         return $pages;
223     }
224
225     // require 'view' access
226     function listLinks($pagename, $credentials = false)
227     {
228         global $server;
229         checkCredentials($server, $credentials, 'view', $pagename);
230         $dbi = WikiDB::open($GLOBALS['DBParams']);
231         $page = $dbi->getPage($pagename);
232         $linkiterator = $page->getPageLinks();
233         $links = array();
234         while ($currentpage = $linkiterator->next()) {
235             if ($currentpage->exists())
236                 $links[] = array('pagename' => $currentpage->getName());
237         }
238         return $links;
239     }
240
241     function listPlugins($credentials = false)
242     {
243         global $server;
244         checkCredentials($server, $credentials, 'change', _("HomePage"));
245         $plugin_dir = 'lib/plugin';
246         if (defined('PHPWIKI_DIR'))
247             $plugin_dir = PHPWIKI_DIR . "/$plugin_dir";
248         $pd = new fileSet($plugin_dir, '*.php');
249         $plugins = $pd->getFiles();
250         unset($pd);
251         sort($plugins);
252         $RetArray = array();
253         if (!empty($plugins)) {
254             require_once 'lib/WikiPlugin.php';
255             $w = new WikiPluginLoader();
256             foreach ($plugins as $plugin) {
257                 $pluginName = str_replace(".php", "", $plugin);
258                 $p = $w->getPlugin($pluginName, false); // second arg?
259                 // trap php files which aren't WikiPlugin~s: wikiplugin + wikiplugin_cached only
260                 if (strtolower(substr(get_parent_class($p), 0, 10)) == 'wikiplugin') {
261                     $RetArray[] = $pluginName;
262                 }
263             }
264         }
265         return $RetArray;
266     }
267
268     function getPluginSynopsis($pluginname, $credentials = false)
269     {
270         global $server;
271         checkCredentials($server, $credentials, 'change', "Help/" . $pluginname . "Plugin");
272         require_once 'lib/WikiPlugin.php';
273         $w = new WikiPluginLoader();
274         $synopsis = '';
275         $p = $w->getPlugin($pluginname, false); // second arg?
276         // trap php files which aren't WikiPlugin~s: wikiplugin + wikiplugin_cached only
277         if (strtolower(substr(get_parent_class($p), 0, 10)) == 'wikiplugin') {
278             $plugin_args = '';
279             $desc = $p->getArgumentsDescription();
280             $desc = str_replace("<br />", ' ', $desc->asXML());
281             if ($desc)
282                 $plugin_args = ' ' . $desc;
283             $synopsis = "<<" . $pluginname . $plugin_args . ">>";
284         }
285         return $synopsis;
286     }
287
288     // only plugins returning pagelists will return something useful. so omit the html output
289     function callPlugin($pluginname, $plugin_args, $credentials = false)
290     {
291         global $request;
292         global $server;
293         checkCredentials($server, $credentials, 'change', "Help/" . $pluginname . "Plugin");
294
295         $dbi = WikiDB::open($GLOBALS['DBParams']);
296         $basepage = '';
297         require_once 'lib/WikiPlugin.php';
298         $w = new WikiPluginLoader();
299         $p = $w->getPlugin($pluginname, false); // second arg?
300         $pagelist = $p->run($dbi, $plugin_args, $request, $basepage);
301         $pages = array();
302         if (is_object($pagelist) and is_a($pagelist, 'PageList')) {
303             foreach ($pagelist->pageNames() as $name)
304                 $pages[] = array('pagename' => $name);
305         }
306         return $pages;
307     }
308
309     /**
310      * array listRelations([ Integer option = 1 ])
311      *
312      * Returns an array of all available relation names.
313      *   option: 1 relations only ( with 0 also )
314      *   option: 2 attributes only
315      *   option: 3 both, all names of relations and attributes
316      *   option: 4 unsorted, this might be added as bitvalue: 7 = 4+3. default: sorted
317      * For some semanticweb autofill methods.
318      *
319      * @author: Reini Urban
320      */
321     function listRelations($option = 1, $credentials = false)
322     {
323         global $server;
324         checkCredentials($server, $credentials, 'view', _("HomePage"));
325         $dbi = WikiDB::open($GLOBALS['DBParams']);
326         $also_attributes = $option & 2;
327         $only_attributes = $option & 2 and !($option & 1);
328         $sorted = !($option & 4);
329         $relations = $dbi->listRelations($also_attributes,
330             $only_attributes,
331             $sorted);
332         return array_keys(array_flip($relations)); // Remove duplicates
333     }
334
335     // some basic semantic search
336     function linkSearch($linktype, $search, $pages = "*", $relation = "*", $credentials = false)
337     {
338         global $server;
339         checkCredentials($server, $credentials, 'view', _("HomePage"));
340         $dbi = WikiDB::open($GLOBALS['DBParams']);
341         require_once 'lib/TextSearchQuery.php';
342         $pagequery = new TextSearchQuery($pages);
343         $linkquery = new TextSearchQuery($search);
344         if ($linktype == 'relation') {
345             $relquery = new TextSearchQuery($relation);
346             $links = $dbi->_backend->link_search($pagequery, $linkquery, $linktype, $relquery);
347         } elseif ($linktype == 'attribute') { // only numeric search with attributes!
348             $relquery = new TextSearchQuery($relation);
349             require_once 'lib/SemanticWeb.php';
350             // search: "population > 1 million and area < 200 km^2" relation="*" pages="*"
351             $linkquery = new SemanticAttributeSearchQuery($search, $relation);
352             $links = $dbi->_backend->link_search($pagequery, $linkquery, $linktype, $relquery);
353         } else {
354             // we already do have forward and backlinks as SOAP
355             $links = $dbi->_backend->link_search($pagequery, $linkquery, $linktype);
356         }
357         return $links->asArray();
358     }
359 }
360
361 $server = new SoapServer('PhpWiki.wsdl');
362 $server->setClass('PhpWikiSoapServer');
363
364 if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD']=='POST') {
365     $server->handle();
366 } elseif (isset($_SERVER['QUERY_STRING'])) {
367     // Return the WSDL
368     $wsdl = @implode('', @file('PhpWiki.wsdl'));
369     if (strlen($wsdl) > 1) {
370         header("Content-type: text/xml");
371         echo $wsdl;
372     } else {
373         header("Status: 500 Internal Server Error");
374         header("Content-type: text/plain");
375         echo "HTTP/1.0 500 Internal Server Error";
376     }
377 }