source: documentation/trunk/packages/dokuwiki-2011-05-25a/lib/exe/xmlrpc.php@ 30098

Last change on this file since 30098 was 25027, checked in by jmt12, 12 years ago

Adding the packages directory, and within it a configured version of dokuwiki all ready to run

File size: 25.8 KB
Line 
1<?php
2if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
3
4// fix when '< ?xml' isn't on the very first line
5if(isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
6
7/**
8 * Increased whenever the API is changed
9 */
10define('DOKU_XMLRPC_API_VERSION',5);
11
12require_once(DOKU_INC.'inc/init.php');
13session_write_close(); //close session
14
15if(!$conf['xmlrpc']) die('XML-RPC server not enabled.');
16
17/**
18 * Contains needed wrapper functions and registers all available
19 * XMLRPC functions.
20 */
21class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer {
22 var $methods = array();
23 var $public_methods = array();
24
25 /**
26 * Checks if the current user is allowed to execute non anonymous methods
27 */
28 function checkAuth(){
29 global $conf;
30 global $USERINFO;
31
32 if(!$conf['useacl']) return true; //no ACL - then no checks
33
34 $allowed = explode(',',$conf['xmlrpcuser']);
35 $allowed = array_map('trim', $allowed);
36 $allowed = array_unique($allowed);
37 $allowed = array_filter($allowed);
38
39 if(!count($allowed)) return true; //no restrictions
40
41 $user = $_SERVER['REMOTE_USER'];
42 $groups = (array) $USERINFO['grps'];
43
44 if(in_array($user,$allowed)) return true; //user explicitly mentioned
45
46 //check group memberships
47 foreach($groups as $group){
48 if(in_array('@'.$group,$allowed)) return true;
49 }
50
51 //still here? no access!
52 return false;
53 }
54
55 /**
56 * Adds a callback, extends parent method
57 *
58 * add another parameter to define if anonymous access to
59 * this method should be granted.
60 */
61 function addCallback($method, $callback, $args, $help, $public=false){
62 if($public) $this->public_methods[] = $method;
63 return parent::addCallback($method, $callback, $args, $help);
64 }
65
66 /**
67 * Execute a call, extends parent method
68 *
69 * Checks for authentication first
70 */
71 function call($methodname, $args){
72 if(!in_array($methodname,$this->public_methods) && !$this->checkAuth()){
73 return new IXR_Error(-32603, 'server error. not authorized to call method "'.$methodname.'".');
74 }
75 return parent::call($methodname, $args);
76 }
77
78 /**
79 * Constructor. Register methods and run Server
80 */
81 function dokuwiki_xmlrpc_server(){
82 $this->IXR_IntrospectionServer();
83
84 /* DokuWiki's own methods */
85 $this->addCallback(
86 'dokuwiki.getXMLRPCAPIVersion',
87 'this:getAPIVersion',
88 array('integer'),
89 'Returns the XMLRPC API version.',
90 true
91 );
92
93 $this->addCallback(
94 'dokuwiki.getVersion',
95 'getVersion',
96 array('string'),
97 'Returns the running DokuWiki version.',
98 true
99 );
100
101 $this->addCallback(
102 'dokuwiki.login',
103 'this:login',
104 array('integer','string','string'),
105 'Tries to login with the given credentials and sets auth cookies.',
106 true
107 );
108
109 $this->addCallback(
110 'dokuwiki.getPagelist',
111 'this:readNamespace',
112 array('struct','string','struct'),
113 'List all pages within the given namespace.'
114 );
115
116 $this->addCallback(
117 'dokuwiki.search',
118 'this:search',
119 array('struct','string'),
120 'Perform a fulltext search and return a list of matching pages'
121 );
122
123 $this->addCallback(
124 'dokuwiki.getTime',
125 'time',
126 array('int'),
127 'Return the current time at the wiki server.'
128 );
129
130 $this->addCallback(
131 'dokuwiki.setLocks',
132 'this:setLocks',
133 array('struct','struct'),
134 'Lock or unlock pages.'
135 );
136
137
138 $this->addCallback(
139 'dokuwiki.getTitle',
140 'this:getTitle',
141 array('string'),
142 'Returns the wiki title.',
143 true
144 );
145
146 $this->addCallback(
147 'dokuwiki.appendPage',
148 'this:appendPage',
149 array('int', 'string', 'string', 'struct'),
150 'Append text to a wiki page.'
151 );
152
153 /* Wiki API v2 http://www.jspwiki.org/wiki/WikiRPCInterface2 */
154 $this->addCallback(
155 'wiki.getRPCVersionSupported',
156 'this:wiki_RPCVersion',
157 array('int'),
158 'Returns 2 with the supported RPC API version.',
159 true
160 );
161 $this->addCallback(
162 'wiki.getPage',
163 'this:rawPage',
164 array('string','string'),
165 'Get the raw Wiki text of page, latest version.'
166 );
167 $this->addCallback(
168 'wiki.getPageVersion',
169 'this:rawPage',
170 array('string','string','int'),
171 'Get the raw Wiki text of page.'
172 );
173 $this->addCallback(
174 'wiki.getPageHTML',
175 'this:htmlPage',
176 array('string','string'),
177 'Return page in rendered HTML, latest version.'
178 );
179 $this->addCallback(
180 'wiki.getPageHTMLVersion',
181 'this:htmlPage',
182 array('string','string','int'),
183 'Return page in rendered HTML.'
184 );
185 $this->addCallback(
186 'wiki.getAllPages',
187 'this:listPages',
188 array('struct'),
189 'Returns a list of all pages. The result is an array of utf8 pagenames.'
190 );
191 $this->addCallback(
192 'wiki.getAttachments',
193 'this:listAttachments',
194 array('struct', 'string', 'struct'),
195 'Returns a list of all media files.'
196 );
197 $this->addCallback(
198 'wiki.getBackLinks',
199 'this:listBackLinks',
200 array('struct','string'),
201 'Returns the pages that link to this page.'
202 );
203 $this->addCallback(
204 'wiki.getPageInfo',
205 'this:pageInfo',
206 array('struct','string'),
207 'Returns a struct with infos about the page.'
208 );
209 $this->addCallback(
210 'wiki.getPageInfoVersion',
211 'this:pageInfo',
212 array('struct','string','int'),
213 'Returns a struct with infos about the page.'
214 );
215 $this->addCallback(
216 'wiki.getPageVersions',
217 'this:pageVersions',
218 array('struct','string','int'),
219 'Returns the available revisions of the page.'
220 );
221 $this->addCallback(
222 'wiki.putPage',
223 'this:putPage',
224 array('int', 'string', 'string', 'struct'),
225 'Saves a wiki page.'
226 );
227 $this->addCallback(
228 'wiki.listLinks',
229 'this:listLinks',
230 array('struct','string'),
231 'Lists all links contained in a wiki page.'
232 );
233 $this->addCallback(
234 'wiki.getRecentChanges',
235 'this:getRecentChanges',
236 array('struct','int'),
237 'Returns a struct about all recent changes since given timestamp.'
238 );
239 $this->addCallback(
240 'wiki.getRecentMediaChanges',
241 'this:getRecentMediaChanges',
242 array('struct','int'),
243 'Returns a struct about all recent media changes since given timestamp.'
244 );
245 $this->addCallback(
246 'wiki.aclCheck',
247 'this:aclCheck',
248 array('int', 'string'),
249 'Returns the permissions of a given wiki page.'
250 );
251 $this->addCallback(
252 'wiki.putAttachment',
253 'this:putAttachment',
254 array('struct', 'string', 'base64', 'struct'),
255 'Upload a file to the wiki.'
256 );
257 $this->addCallback(
258 'wiki.deleteAttachment',
259 'this:deleteAttachment',
260 array('int', 'string'),
261 'Delete a file from the wiki.'
262 );
263 $this->addCallback(
264 'wiki.getAttachment',
265 'this:getAttachment',
266 array('base64', 'string'),
267 'Download a file from the wiki.'
268 );
269 $this->addCallback(
270 'wiki.getAttachmentInfo',
271 'this:getAttachmentInfo',
272 array('struct', 'string'),
273 'Returns a struct with infos about the attachment.'
274 );
275
276 /**
277 * Trigger XMLRPC_CALLBACK_REGISTER, action plugins can use this event
278 * to extend the XMLRPC interface and register their own callbacks.
279 *
280 * Event data:
281 * The XMLRPC server object:
282 *
283 * $event->data->addCallback() - register a callback, the second
284 * paramter has to be of the form "plugin:<pluginname>:<plugin
285 * method>"
286 *
287 * $event->data->callbacks - an array which holds all awaylable
288 * callbacks
289 */
290 trigger_event('XMLRPC_CALLBACK_REGISTER', $this);
291
292 $this->serve();
293 }
294
295 /**
296 * Return a raw wiki page
297 */
298 function rawPage($id,$rev=''){
299 $id = cleanID($id);
300 if(auth_quickaclcheck($id) < AUTH_READ){
301 return new IXR_Error(1, 'You are not allowed to read this page');
302 }
303 $text = rawWiki($id,$rev);
304 if(!$text) {
305 return pageTemplate($id);
306 } else {
307 return $text;
308 }
309 }
310
311 /**
312 * Return a media file encoded in base64
313 *
314 * @author Gina Haeussge <[email protected]>
315 */
316 function getAttachment($id){
317 $id = cleanID($id);
318 if (auth_quickaclcheck(getNS($id).':*') < AUTH_READ)
319 return new IXR_Error(1, 'You are not allowed to read this file');
320
321 $file = mediaFN($id);
322 if (!@ file_exists($file))
323 return new IXR_Error(1, 'The requested file does not exist');
324
325 $data = io_readFile($file, false);
326 $base64 = base64_encode($data);
327 return $base64;
328 }
329
330 /**
331 * Return info about a media file
332 *
333 * @author Gina Haeussge <[email protected]>
334 */
335 function getAttachmentInfo($id){
336 $id = cleanID($id);
337 $info = array(
338 'lastModified' => 0,
339 'size' => 0,
340 );
341
342 $file = mediaFN($id);
343 if ((auth_quickaclcheck(getNS($id).':*') >= AUTH_READ) && file_exists($file)){
344 $info['lastModified'] = new IXR_Date(filemtime($file));
345 $info['size'] = filesize($file);
346 }
347
348 return $info;
349 }
350
351 /**
352 * Return a wiki page rendered to html
353 */
354 function htmlPage($id,$rev=''){
355 $id = cleanID($id);
356 if(auth_quickaclcheck($id) < AUTH_READ){
357 return new IXR_Error(1, 'You are not allowed to read this page');
358 }
359 return p_wiki_xhtml($id,$rev,false);
360 }
361
362 /**
363 * List all pages - we use the indexer list here
364 */
365 function listPages(){
366 $list = array();
367 $pages = idx_get_indexer()->getPages();
368 $pages = array_filter(array_filter($pages,'isVisiblePage'),'page_exists');
369
370 foreach(array_keys($pages) as $idx) {
371 $perm = auth_quickaclcheck($pages[$idx]);
372 if($perm < AUTH_READ) {
373 continue;
374 }
375 $page = array();
376 $page['id'] = trim($pages[$idx]);
377 $page['perms'] = $perm;
378 $page['size'] = @filesize(wikiFN($pages[$idx]));
379 $page['lastModified'] = new IXR_Date(@filemtime(wikiFN($pages[$idx])));
380 $list[] = $page;
381 }
382
383 return $list;
384 }
385
386 /**
387 * List all pages in the given namespace (and below)
388 */
389 function readNamespace($ns,$opts){
390 global $conf;
391
392 if(!is_array($opts)) $opts=array();
393
394 $ns = cleanID($ns);
395 $dir = utf8_encodeFN(str_replace(':', '/', $ns));
396 $data = array();
397 $opts['skipacl'] = 0; // no ACL skipping for XMLRPC
398 search($data, $conf['datadir'], 'search_allpages', $opts, $dir);
399 return $data;
400 }
401
402 /**
403 * List all pages in the given namespace (and below)
404 */
405 function search($query){
406 require_once(DOKU_INC.'inc/fulltext.php');
407
408 $regex = '';
409 $data = ft_pageSearch($query,$regex);
410 $pages = array();
411
412 // prepare additional data
413 $idx = 0;
414 foreach($data as $id => $score){
415 $file = wikiFN($id);
416
417 if($idx < FT_SNIPPET_NUMBER){
418 $snippet = ft_snippet($id,$regex);
419 $idx++;
420 }else{
421 $snippet = '';
422 }
423
424 $pages[] = array(
425 'id' => $id,
426 'score' => $score,
427 'rev' => filemtime($file),
428 'mtime' => filemtime($file),
429 'size' => filesize($file),
430 'snippet' => $snippet,
431 );
432 }
433 return $pages;
434 }
435
436 /**
437 * Returns the wiki title.
438 */
439 function getTitle(){
440 global $conf;
441 return $conf['title'];
442 }
443
444 /**
445 * List all media files.
446 *
447 * Available options are 'recursive' for also including the subnamespaces
448 * in the listing, and 'pattern' for filtering the returned files against
449 * a regular expression matching their name.
450 *
451 * @author Gina Haeussge <[email protected]>
452 */
453 function listAttachments($ns, $options = array()) {
454 global $conf;
455 global $lang;
456
457 $ns = cleanID($ns);
458
459 if (!is_array($options)) $options = array();
460 $options['skipacl'] = 0; // no ACL skipping for XMLRPC
461
462
463 if(auth_quickaclcheck($ns.':*') >= AUTH_READ) {
464 $dir = utf8_encodeFN(str_replace(':', '/', $ns));
465
466 $data = array();
467 search($data, $conf['mediadir'], 'search_media', $options, $dir);
468 $len = count($data);
469 if(!$len) return array();
470
471 for($i=0; $i<$len; $i++) {
472 unset($data[$i]['meta']);
473 $data[$i]['lastModified'] = new IXR_Date($data[$i]['mtime']);
474 }
475 return $data;
476 } else {
477 return new IXR_Error(1, 'You are not allowed to list media files.');
478 }
479 }
480
481 /**
482 * Return a list of backlinks
483 */
484 function listBackLinks($id){
485 return ft_backlinks(cleanID($id));
486 }
487
488 /**
489 * Return some basic data about a page
490 */
491 function pageInfo($id,$rev=''){
492 $id = cleanID($id);
493 if(auth_quickaclcheck($id) < AUTH_READ){
494 return new IXR_Error(1, 'You are not allowed to read this page');
495 }
496 $file = wikiFN($id,$rev);
497 $time = @filemtime($file);
498 if(!$time){
499 return new IXR_Error(10, 'The requested page does not exist');
500 }
501
502 $info = getRevisionInfo($id, $time, 1024);
503
504 $data = array(
505 'name' => $id,
506 'lastModified' => new IXR_Date($time),
507 'author' => (($info['user']) ? $info['user'] : $info['ip']),
508 'version' => $time
509 );
510
511 return ($data);
512 }
513
514 /**
515 * Save a wiki page
516 *
517 * @author Michael Klier <[email protected]>
518 */
519 function putPage($id, $text, $params) {
520 global $TEXT;
521 global $lang;
522 global $conf;
523
524 $id = cleanID($id);
525 $TEXT = cleanText($text);
526 $sum = $params['sum'];
527 $minor = $params['minor'];
528
529 if(empty($id))
530 return new IXR_Error(1, 'Empty page ID');
531
532 if(!page_exists($id) && trim($TEXT) == '' ) {
533 return new IXR_ERROR(1, 'Refusing to write an empty new wiki page');
534 }
535
536 if(auth_quickaclcheck($id) < AUTH_EDIT)
537 return new IXR_Error(1, 'You are not allowed to edit this page');
538
539 // Check, if page is locked
540 if(checklock($id))
541 return new IXR_Error(1, 'The page is currently locked');
542
543 // SPAM check
544 if(checkwordblock())
545 return new IXR_Error(1, 'Positive wordblock check');
546
547 // autoset summary on new pages
548 if(!page_exists($id) && empty($sum)) {
549 $sum = $lang['created'];
550 }
551
552 // autoset summary on deleted pages
553 if(page_exists($id) && empty($TEXT) && empty($sum)) {
554 $sum = $lang['deleted'];
555 }
556
557 lock($id);
558
559 saveWikiText($id,$TEXT,$sum,$minor);
560
561 unlock($id);
562
563 // run the indexer if page wasn't indexed yet
564 idx_addPage($id);
565
566 return 0;
567 }
568
569 /**
570 * Appends text to a wiki page.
571 */
572 function appendPage($id, $text, $params) {
573 $currentpage = $this->rawPage($id);
574 if (!is_string($currentpage)) {
575 return $currentpage;
576 }
577 return $this->putPage($id, $currentpage.$text, $params);
578 }
579
580 /**
581 * Uploads a file to the wiki.
582 *
583 * Michael Klier <[email protected]>
584 */
585 function putAttachment($id, $file, $params) {
586 $id = cleanID($id);
587 $auth = auth_quickaclcheck(getNS($id).':*');
588
589 if(!isset($id)) {
590 return new IXR_ERROR(1, 'Filename not given.');
591 }
592
593 global $conf;
594
595 $ftmp = $conf['tmpdir'] . '/' . md5($id.clientIP());
596
597 // save temporary file
598 @unlink($ftmp);
599 $buff = base64_decode($file);
600 io_saveFile($ftmp, $buff);
601
602 $res = media_save(array('name' => $ftmp), $id, $params['ow'], $auth, 'rename');
603 if (is_array($res)) {
604 return new IXR_ERROR(-$res[1], $res[0]);
605 } else {
606 return $res;
607 }
608 }
609
610 /**
611 * Deletes a file from the wiki.
612 *
613 * @author Gina Haeussge <[email protected]>
614 */
615 function deleteAttachment($id){
616 $id = cleanID($id);
617 $auth = auth_quickaclcheck(getNS($id).':*');
618 $res = media_delete($id, $auth);
619 if ($res & DOKU_MEDIA_DELETED) {
620 return 0;
621 } elseif ($res & DOKU_MEDIA_NOT_AUTH) {
622 return new IXR_ERROR(1, "You don't have permissions to delete files.");
623 } elseif ($res & DOKU_MEDIA_INUSE) {
624 return new IXR_ERROR(1, 'File is still referenced');
625 } else {
626 return new IXR_ERROR(1, 'Could not delete file');
627 }
628 }
629
630 /**
631 * Returns the permissions of a given wiki page
632 */
633 function aclCheck($id) {
634 $id = cleanID($id);
635 return auth_quickaclcheck($id);
636 }
637
638 /**
639 * Lists all links contained in a wiki page
640 *
641 * @author Michael Klier <[email protected]>
642 */
643 function listLinks($id) {
644 $id = cleanID($id);
645 if(auth_quickaclcheck($id) < AUTH_READ){
646 return new IXR_Error(1, 'You are not allowed to read this page');
647 }
648 $links = array();
649
650 // resolve page instructions
651 $ins = p_cached_instructions(wikiFN($id));
652
653 // instantiate new Renderer - needed for interwiki links
654 include(DOKU_INC.'inc/parser/xhtml.php');
655 $Renderer = new Doku_Renderer_xhtml();
656 $Renderer->interwiki = getInterwiki();
657
658 // parse parse instructions
659 foreach($ins as $in) {
660 $link = array();
661 switch($in[0]) {
662 case 'internallink':
663 $link['type'] = 'local';
664 $link['page'] = $in[1][0];
665 $link['href'] = wl($in[1][0]);
666 array_push($links,$link);
667 break;
668 case 'externallink':
669 $link['type'] = 'extern';
670 $link['page'] = $in[1][0];
671 $link['href'] = $in[1][0];
672 array_push($links,$link);
673 break;
674 case 'interwikilink':
675 $url = $Renderer->_resolveInterWiki($in[1][2],$in[1][3]);
676 $link['type'] = 'extern';
677 $link['page'] = $url;
678 $link['href'] = $url;
679 array_push($links,$link);
680 break;
681 }
682 }
683
684 return ($links);
685 }
686
687 /**
688 * Returns a list of recent changes since give timestamp
689 *
690 * @author Michael Hamann <[email protected]>
691 * @author Michael Klier <[email protected]>
692 */
693 function getRecentChanges($timestamp) {
694 if(strlen($timestamp) != 10)
695 return new IXR_Error(20, 'The provided value is not a valid timestamp');
696
697 $recents = getRecentsSince($timestamp);
698
699 $changes = array();
700
701 foreach ($recents as $recent) {
702 $change = array();
703 $change['name'] = $recent['id'];
704 $change['lastModified'] = new IXR_Date($recent['date']);
705 $change['author'] = $recent['user'];
706 $change['version'] = $recent['date'];
707 $change['perms'] = $recent['perms'];
708 $change['size'] = @filesize(wikiFN($recent['id']));
709 array_push($changes, $change);
710 }
711
712 if (!empty($changes)) {
713 return $changes;
714 } else {
715 // in case we still have nothing at this point
716 return new IXR_Error(30, 'There are no changes in the specified timeframe');
717 }
718 }
719
720 /**
721 * Returns a list of recent media changes since give timestamp
722 *
723 * @author Michael Hamann <[email protected]>
724 * @author Michael Klier <[email protected]>
725 */
726 function getRecentMediaChanges($timestamp) {
727 if(strlen($timestamp) != 10)
728 return new IXR_Error(20, 'The provided value is not a valid timestamp');
729
730 $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES);
731
732 $changes = array();
733
734 foreach ($recents as $recent) {
735 $change = array();
736 $change['name'] = $recent['id'];
737 $change['lastModified'] = new IXR_Date($recent['date']);
738 $change['author'] = $recent['user'];
739 $change['version'] = $recent['date'];
740 $change['perms'] = $recent['perms'];
741 $change['size'] = @filesize(mediaFN($recent['id']));
742 array_push($changes, $change);
743 }
744
745 if (!empty($changes)) {
746 return $changes;
747 } else {
748 // in case we still have nothing at this point
749 return new IXR_Error(30, 'There are no changes in the specified timeframe');
750 }
751 }
752
753 /**
754 * Returns a list of available revisions of a given wiki page
755 *
756 * @author Michael Klier <[email protected]>
757 */
758 function pageVersions($id, $first) {
759 $id = cleanID($id);
760 if(auth_quickaclcheck($id) < AUTH_READ){
761 return new IXR_Error(1, 'You are not allowed to read this page');
762 }
763 global $conf;
764
765 $versions = array();
766
767 if(empty($id))
768 return new IXR_Error(1, 'Empty page ID');
769
770 $revisions = getRevisions($id, $first, $conf['recent']+1);
771
772 if(count($revisions)==0 && $first!=0) {
773 $first=0;
774 $revisions = getRevisions($id, $first, $conf['recent']+1);
775 }
776
777 if(count($revisions)>0 && $first==0) {
778 array_unshift($revisions, ''); // include current revision
779 array_pop($revisions); // remove extra log entry
780 }
781
782 $hasNext = false;
783 if(count($revisions)>$conf['recent']) {
784 $hasNext = true;
785 array_pop($revisions); // remove extra log entry
786 }
787
788 if(!empty($revisions)) {
789 foreach($revisions as $rev) {
790 $file = wikiFN($id,$rev);
791 $time = @filemtime($file);
792 // we check if the page actually exists, if this is not the
793 // case this can lead to less pages being returned than
794 // specified via $conf['recent']
795 if($time){
796 $info = getRevisionInfo($id, $time, 1024);
797 if(!empty($info)) {
798 $data['user'] = $info['user'];
799 $data['ip'] = $info['ip'];
800 $data['type'] = $info['type'];
801 $data['sum'] = $info['sum'];
802 $data['modified'] = new IXR_Date($info['date']);
803 $data['version'] = $info['date'];
804 array_push($versions, $data);
805 }
806 }
807 }
808 return $versions;
809 } else {
810 return array();
811 }
812 }
813
814 /**
815 * The version of Wiki RPC API supported
816 */
817 function wiki_RPCVersion(){
818 return 2;
819 }
820
821
822 /**
823 * Locks or unlocks a given batch of pages
824 *
825 * Give an associative array with two keys: lock and unlock. Both should contain a
826 * list of pages to lock or unlock
827 *
828 * Returns an associative array with the keys locked, lockfail, unlocked and
829 * unlockfail, each containing lists of pages.
830 */
831 function setLocks($set){
832 $locked = array();
833 $lockfail = array();
834 $unlocked = array();
835 $unlockfail = array();
836
837 foreach((array) $set['lock'] as $id){
838 $id = cleanID($id);
839 if(auth_quickaclcheck($id) < AUTH_EDIT || checklock($id)){
840 $lockfail[] = $id;
841 }else{
842 lock($id);
843 $locked[] = $id;
844 }
845 }
846
847 foreach((array) $set['unlock'] as $id){
848 $id = cleanID($id);
849 if(auth_quickaclcheck($id) < AUTH_EDIT || !unlock($id)){
850 $unlockfail[] = $id;
851 }else{
852 $unlocked[] = $id;
853 }
854 }
855
856 return array(
857 'locked' => $locked,
858 'lockfail' => $lockfail,
859 'unlocked' => $unlocked,
860 'unlockfail' => $unlockfail,
861 );
862 }
863
864 function getAPIVersion(){
865 return DOKU_XMLRPC_API_VERSION;
866 }
867
868 function login($user,$pass){
869 global $conf;
870 global $auth;
871 if(!$conf['useacl']) return 0;
872 if(!$auth) return 0;
873 if($auth->canDo('external')){
874 return $auth->trustExternal($user,$pass,false);
875 }else{
876 return auth_login($user,$pass,false,true);
877 }
878 }
879
880
881}
882
883$server = new dokuwiki_xmlrpc_server();
884
885// vim:ts=4:sw=4:et:
Note: See TracBrowser for help on using the repository browser.