]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - SOAP.php
Check it is really a _WikiUser
[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         return $page->save($content, $version + 1, $meta);
87     }
88
89     // require 'view' access
90     function getPageContent($pagename, $credentials = false)
91     {
92         global $server;
93         checkCredentials($server, $credentials, 'view', $pagename);
94         $dbi = WikiDB::open($GLOBALS['DBParams']);
95         $page = $dbi->getPage($pagename);
96         $rev = $page->getCurrentRevision();
97         $text = $rev->getPackedContent();
98         return $text;
99     }
100
101     // require 'view' access
102     function getPageRevision($pagename, $revision, $credentials = false)
103     {
104         global $server;
105         checkCredentials($server, $credentials, 'view', $pagename);
106         $dbi = WikiDB::open($GLOBALS['DBParams']);
107         $page = $dbi->getPage($pagename);
108         $rev = $page->getRevision($revision);
109         $text = $rev->getPackedContent();
110         return $text;
111     }
112
113     // require 'view' access
114     function getCurrentRevision($pagename, $credentials = false)
115     {
116         global $server;
117         checkCredentials($server, $credentials, 'view', $pagename);
118         // if (!mayAccessPage('view', $pagename))
119         //     $server->fault(401, '', "no permission");
120         $dbi = WikiDB::open($GLOBALS['DBParams']);
121         $page = $dbi->getPage($pagename);
122         // $rev = $page->getCurrentRevision();
123         $version = $page->getVersion();
124         return (double)$version;
125     }
126
127     // require 'change' or 'view' access ?
128     function getPageMeta($pagename, $credentials = false)
129     {
130         global $server;
131         checkCredentials($server, $credentials, 'view', $pagename);
132         $dbi = WikiDB::open($GLOBALS['DBParams']);
133         $page = $dbi->getPage($pagename);
134         return $page->getMetaData();
135     }
136
137     // require 'view' access to AllPages
138     function getAllPagenames($credentials = false)
139     {
140         global $server;
141         checkCredentials($server, $credentials, 'view', _("AllPages"));
142         $dbi = WikiDB::open($GLOBALS['DBParams']);
143         $page_iter = $dbi->getAllPages();
144         $pages = array();
145         while ($page = $page_iter->next()) {
146             $pages[] = array('pagename' => $page->_pagename);
147         }
148         sort($pages);
149         return $pages;
150     }
151
152     // require 'view' access
153     function getBacklinks($pagename, $credentials = false)
154     {
155         global $server;
156         checkCredentials($server, $credentials, 'view', $pagename);
157         $dbi = WikiDB::open($GLOBALS['DBParams']);
158         $backend = &$dbi->_backend;
159         $result = $backend->get_links($pagename);
160         $page_iter = new WikiDB_PageIterator($dbi, $result);
161         $pages = array();
162         while ($page = $page_iter->next()) {
163             $pages[] = array('pagename' => $page->getName());
164         }
165         return $pages;
166     }
167
168     // require 'view' access to TitleSearch
169     function doTitleSearch($s, $credentials = false)
170     {
171         require_once 'lib/TextSearchQuery.php';
172
173         global $server;
174         checkCredentials($server, $credentials, 'view', _("TitleSearch"));
175         $dbi = WikiDB::open($GLOBALS['DBParams']);
176         $query = new TextSearchQuery($s);
177         $page_iter = $dbi->titleSearch($query);
178         $pages = array();
179         while ($page = $page_iter->next()) {
180             $pages[] = array('pagename' => $page->getName());
181         }
182         return $pages;
183     }
184
185     // require 'view' access to FullTextSearch
186     function doFullTextSearch($s, $credentials = false)
187     {
188         require_once 'lib/TextSearchQuery.php';
189
190         global $server;
191         checkCredentials($server, $credentials, 'view', _("FullTextSearch"));
192         $dbi = WikiDB::open($GLOBALS['DBParams']);
193         $query = new TextSearchQuery($s);
194         $page_iter = $dbi->fullSearch($query);
195         $pages = array();
196         while ($page = $page_iter->next()) {
197             $pages[] = array('pagename' => $page->getName());
198         }
199         return $pages;
200     }
201
202     // require 'view' access to RecentChanges
203     function getRecentChanges($limit = false, $since = false, $include_minor = false, $credentials = false)
204     {
205         global $server;
206         checkCredentials($server, $credentials, 'view', _("RecentChanges"));
207         $dbi = WikiDB::open($GLOBALS['DBParams']);
208         $params = array('limit' => $limit, 'since' => $since,
209             'include_minor_revisions' => $include_minor);
210         $page_iter = $dbi->mostRecent($params);
211         $pages = array();
212         while ($page = $page_iter->next()) {
213             $pages[] = array('pagename' => $page->getName(),
214                 'lastModified' => $page->get('mtime'),
215                 'author' => $page->get('author'),
216                 'summary' => $page->get('summary'), // added with 1.3.13
217                 'version' => $page->getVersion()
218             );
219         }
220         return $pages;
221     }
222
223     // require 'view' access
224     function listLinks($pagename, $credentials = false)
225     {
226         global $server;
227         checkCredentials($server, $credentials, 'view', $pagename);
228         $dbi = WikiDB::open($GLOBALS['DBParams']);
229         $page = $dbi->getPage($pagename);
230         $linkiterator = $page->getPageLinks();
231         $links = array();
232         while ($currentpage = $linkiterator->next()) {
233             if ($currentpage->exists())
234                 $links[] = array('pagename' => $currentpage->getName());
235         }
236         return $links;
237     }
238
239     function listPlugins($credentials = false)
240     {
241         global $server;
242         checkCredentials($server, $credentials, 'change', _("HomePage"));
243         $plugin_dir = 'lib/plugin';
244         if (defined('PHPWIKI_DIR'))
245             $plugin_dir = PHPWIKI_DIR . "/$plugin_dir";
246         $pd = new fileSet($plugin_dir, '*.php');
247         $plugins = $pd->getFiles();
248         unset($pd);
249         sort($plugins);
250         $RetArray = array();
251         if (!empty($plugins)) {
252             require_once 'lib/WikiPlugin.php';
253             $w = new WikiPluginLoader();
254             foreach ($plugins as $plugin) {
255                 $pluginName = str_replace(".php", "", $plugin);
256                 $p = $w->getPlugin($pluginName, false); // second arg?
257                 // trap php files which aren't WikiPlugin~s: wikiplugin + wikiplugin_cached only
258                 if (strtolower(substr(get_parent_class($p), 0, 10)) == 'wikiplugin') {
259                     $RetArray[] = $pluginName;
260                 }
261             }
262         }
263         return $RetArray;
264     }
265
266     function getPluginSynopsis($pluginname, $credentials = false)
267     {
268         global $server;
269         checkCredentials($server, $credentials, 'change', "Help/" . $pluginname . "Plugin");
270         require_once 'lib/WikiPlugin.php';
271         $w = new WikiPluginLoader();
272         $synopsis = '';
273         $p = $w->getPlugin($pluginname, false); // second arg?
274         // trap php files which aren't WikiPlugin~s: wikiplugin + wikiplugin_cached only
275         if (strtolower(substr(get_parent_class($p), 0, 10)) == 'wikiplugin') {
276             $plugin_args = '';
277             $desc = $p->getArgumentsDescription();
278             $src = array("\n", '"', "'", '|', '[', ']', '\\');
279             $replace = array('%0A', '%22', '%27', '%7C', '%5B', '%5D', '%5C');
280             $desc = str_replace("<br />", ' ', $desc->asXML());
281             if ($desc)
282                 $plugin_args = '\n' . str_replace($src, $replace, $desc);
283             $synopsis = "<?plugin " . $pluginname . $plugin_args . "?>"; // 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         return $dbi->listRelations($also_attributes,
330             $only_attributes,
331             $sorted);
332     }
333
334     // some basic semantic search
335     function linkSearch($linktype, $search, $pages = "*", $relation = "*", $credentials = false)
336     {
337         global $server;
338         checkCredentials($server, $credentials, 'view', _("HomePage"));
339         $dbi = WikiDB::open($GLOBALS['DBParams']);
340         require_once 'lib/TextSearchQuery.php';
341         $pagequery = new TextSearchQuery($pages);
342         $linkquery = new TextSearchQuery($search);
343         if ($linktype == 'relation') {
344             $relquery = new TextSearchQuery($relation);
345             $links = $dbi->_backend->link_search($pagequery, $linkquery, $linktype, $relquery);
346         } elseif ($linktype == 'attribute') { // only numeric search with attributes!
347             $relquery = new TextSearchQuery($relation);
348             require_once 'lib/SemanticWeb.php';
349             // search: "population > 1 million and area < 200 km^2" relation="*" pages="*"
350             $linkquery = new SemanticAttributeSearchQuery($search, $relation);
351             $links = $dbi->_backend->link_search($pagequery, $linkquery, $linktype, $relquery);
352         } else {
353             // we already do have forward and backlinks as SOAP
354             $links = $dbi->_backend->link_search($pagequery, $linkquery, $linktype);
355         }
356         return $links->asArray();
357     }
358 }
359
360 $server = new SoapServer('PhpWiki.wsdl');
361 $server->setClass('PhpWikiSoapServer');
362
363 if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD']=='POST') {
364     $server->handle();
365 } elseif (isset($_SERVER['QUERY_STRING'])) {
366     // Return the WSDL
367     $wsdl = @implode('', @file('PhpWiki.wsdl'));
368     if (strlen($wsdl) > 1) {
369         header("Content-type: text/xml");
370         echo $wsdl;
371     } else {
372         header("Status: 500 Internal Server Error");
373         header("Content-type: text/plain");
374         echo "HTTP/1.0 500 Internal Server Error";
375     }
376 }
377
378 // Local Variables:
379 // mode: php
380 // tab-width: 8
381 // c-basic-offset: 4
382 // c-hanging-comment-ender-p: nil
383 // indent-tabs-mode: nil
384 // End: