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