xref: /dokuwiki/lib/exe/xmlrpc.php (revision 992ded5a7e2cbd2c8092ded03d035d0cbeade327)
1797c0d11SAndreas Gohr<?php
27aec69d1SGuy Brandif(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
3797c0d11SAndreas Gohr
4797c0d11SAndreas Gohr// fix when '< ?xml' isn't on the very first line
5797c0d11SAndreas Gohrif(isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
6797c0d11SAndreas Gohr
7445e8084SAndreas Gohr/**
8445e8084SAndreas Gohr * Increased whenever the API is changed
9445e8084SAndreas Gohr */
10ba9418bcSHakan Sandelldefine('DOKU_XMLRPC_API_VERSION',5);
11797c0d11SAndreas Gohr
12797c0d11SAndreas Gohrrequire_once(DOKU_INC.'inc/init.php');
13797c0d11SAndreas Gohrsession_write_close();  //close session
14593bf8f6SMichael Klier
153ee5b583SAndreas Gohrif(!$conf['xmlrpc']) die('XML-RPC server not enabled.');
16593bf8f6SMichael Klier
17797c0d11SAndreas Gohr/**
18797c0d11SAndreas Gohr * Contains needed wrapper functions and registers all available
19797c0d11SAndreas Gohr * XMLRPC functions.
20797c0d11SAndreas Gohr */
21797c0d11SAndreas Gohrclass dokuwiki_xmlrpc_server extends IXR_IntrospectionServer {
22797c0d11SAndreas Gohr    var $methods       = array();
233ee5b583SAndreas Gohr    var $public_methods = array();
243ee5b583SAndreas Gohr
253ee5b583SAndreas Gohr    /**
263ee5b583SAndreas Gohr     * Checks if the current user is allowed to execute non anonymous methods
273ee5b583SAndreas Gohr     */
283ee5b583SAndreas Gohr    function checkAuth(){
293ee5b583SAndreas Gohr        global $conf;
303ee5b583SAndreas Gohr        global $USERINFO;
313ee5b583SAndreas Gohr
323ee5b583SAndreas Gohr        if(!$conf['useacl']) return true; //no ACL - then no checks
33*992ded5aSAndreas Gohr        if(trim($conf['xmlrpcuser']) == '') return true; //no restrictions
343ee5b583SAndreas Gohr
35*992ded5aSAndreas Gohr        return auth_isMember($conf['xmlrpcuser'],$_SERVER['REMOTE_USER'],(array) $USERINFO['grps']);
363ee5b583SAndreas Gohr    }
373ee5b583SAndreas Gohr
383ee5b583SAndreas Gohr    /**
393ee5b583SAndreas Gohr     * Adds a callback, extends parent method
403ee5b583SAndreas Gohr     *
413ee5b583SAndreas Gohr     * add another parameter to define if anonymous access to
423ee5b583SAndreas Gohr     * this method should be granted.
433ee5b583SAndreas Gohr     */
443ee5b583SAndreas Gohr    function addCallback($method, $callback, $args, $help, $public=false){
453ee5b583SAndreas Gohr        if($public) $this->public_methods[] = $method;
463ee5b583SAndreas Gohr        return parent::addCallback($method, $callback, $args, $help);
473ee5b583SAndreas Gohr    }
483ee5b583SAndreas Gohr
493ee5b583SAndreas Gohr    /**
503ee5b583SAndreas Gohr     * Execute a call, extends parent method
513ee5b583SAndreas Gohr     *
523ee5b583SAndreas Gohr     * Checks for authentication first
533ee5b583SAndreas Gohr     */
543ee5b583SAndreas Gohr    function call($methodname, $args){
553ee5b583SAndreas Gohr        if(!in_array($methodname,$this->public_methods) && !$this->checkAuth()){
563ee5b583SAndreas Gohr            return new IXR_Error(-32603, 'server error. not authorized to call method "'.$methodname.'".');
573ee5b583SAndreas Gohr        }
583ee5b583SAndreas Gohr        return parent::call($methodname, $args);
593ee5b583SAndreas Gohr    }
60797c0d11SAndreas Gohr
61797c0d11SAndreas Gohr    /**
62797c0d11SAndreas Gohr     * Constructor. Register methods and run Server
63797c0d11SAndreas Gohr     */
64797c0d11SAndreas Gohr    function dokuwiki_xmlrpc_server(){
65797c0d11SAndreas Gohr        $this->IXR_IntrospectionServer();
66797c0d11SAndreas Gohr
67797c0d11SAndreas Gohr        /* DokuWiki's own methods */
68797c0d11SAndreas Gohr        $this->addCallback(
69445e8084SAndreas Gohr            'dokuwiki.getXMLRPCAPIVersion',
70445e8084SAndreas Gohr            'this:getAPIVersion',
71445e8084SAndreas Gohr            array('integer'),
723ee5b583SAndreas Gohr            'Returns the XMLRPC API version.',
733ee5b583SAndreas Gohr            true
74445e8084SAndreas Gohr        );
75445e8084SAndreas Gohr
76445e8084SAndreas Gohr        $this->addCallback(
77797c0d11SAndreas Gohr            'dokuwiki.getVersion',
78797c0d11SAndreas Gohr            'getVersion',
79797c0d11SAndreas Gohr            array('string'),
803ee5b583SAndreas Gohr            'Returns the running DokuWiki version.',
813ee5b583SAndreas Gohr            true
82797c0d11SAndreas Gohr        );
83797c0d11SAndreas Gohr
841b11c097SAndreas Gohr        $this->addCallback(
85445e8084SAndreas Gohr            'dokuwiki.login',
86445e8084SAndreas Gohr            'this:login',
87445e8084SAndreas Gohr            array('integer','string','string'),
883ee5b583SAndreas Gohr            'Tries to login with the given credentials and sets auth cookies.',
893ee5b583SAndreas Gohr            true
90445e8084SAndreas Gohr        );
91445e8084SAndreas Gohr
92445e8084SAndreas Gohr        $this->addCallback(
931b11c097SAndreas Gohr            'dokuwiki.getPagelist',
941b11c097SAndreas Gohr            'this:readNamespace',
951b11c097SAndreas Gohr            array('struct','string','struct'),
961b11c097SAndreas Gohr            'List all pages within the given namespace.'
971b11c097SAndreas Gohr        );
981b11c097SAndreas Gohr
991b11c097SAndreas Gohr        $this->addCallback(
100f71f4f53SAndreas Gohr            'dokuwiki.search',
101f71f4f53SAndreas Gohr            'this:search',
102f71f4f53SAndreas Gohr            array('struct','string'),
103f71f4f53SAndreas Gohr            'Perform a fulltext search and return a list of matching pages'
104f71f4f53SAndreas Gohr        );
105f71f4f53SAndreas Gohr
106f71f4f53SAndreas Gohr        $this->addCallback(
1071b11c097SAndreas Gohr            'dokuwiki.getTime',
1081b11c097SAndreas Gohr            'time',
1091b11c097SAndreas Gohr            array('int'),
1101b11c097SAndreas Gohr            'Return the current time at the wiki server.'
1111b11c097SAndreas Gohr        );
1121b11c097SAndreas Gohr
11328ec3c76SAndreas Gohr        $this->addCallback(
11428ec3c76SAndreas Gohr            'dokuwiki.setLocks',
11528ec3c76SAndreas Gohr            'this:setLocks',
11628ec3c76SAndreas Gohr            array('struct','struct'),
11728ec3c76SAndreas Gohr            'Lock or unlock pages.'
11828ec3c76SAndreas Gohr        );
11928ec3c76SAndreas Gohr
120e6f4c9d4SGeorges-Etienne Legendre
121e6f4c9d4SGeorges-Etienne Legendre        $this->addCallback(
122e6f4c9d4SGeorges-Etienne Legendre            'dokuwiki.getTitle',
123e6f4c9d4SGeorges-Etienne Legendre            'this:getTitle',
124e6f4c9d4SGeorges-Etienne Legendre            array('string'),
125e6f4c9d4SGeorges-Etienne Legendre            'Returns the wiki title.',
126e6f4c9d4SGeorges-Etienne Legendre            true
127e6f4c9d4SGeorges-Etienne Legendre        );
128e6f4c9d4SGeorges-Etienne Legendre
129ba9418bcSHakan Sandell        $this->addCallback(
130ba9418bcSHakan Sandell            'dokuwiki.appendPage',
131ba9418bcSHakan Sandell            'this:appendPage',
132ba9418bcSHakan Sandell            array('int', 'string', 'string', 'struct'),
133ba9418bcSHakan Sandell            'Append text to a wiki page.'
134ba9418bcSHakan Sandell        );
135ba9418bcSHakan Sandell
136797c0d11SAndreas Gohr        /* Wiki API v2 http://www.jspwiki.org/wiki/WikiRPCInterface2 */
137797c0d11SAndreas Gohr        $this->addCallback(
138797c0d11SAndreas Gohr            'wiki.getRPCVersionSupported',
139797c0d11SAndreas Gohr            'this:wiki_RPCVersion',
140797c0d11SAndreas Gohr            array('int'),
1413ee5b583SAndreas Gohr            'Returns 2 with the supported RPC API version.',
1423ee5b583SAndreas Gohr            true
143797c0d11SAndreas Gohr        );
144797c0d11SAndreas Gohr        $this->addCallback(
145797c0d11SAndreas Gohr            'wiki.getPage',
146797c0d11SAndreas Gohr            'this:rawPage',
147797c0d11SAndreas Gohr            array('string','string'),
148797c0d11SAndreas Gohr            'Get the raw Wiki text of page, latest version.'
149797c0d11SAndreas Gohr        );
150797c0d11SAndreas Gohr        $this->addCallback(
151797c0d11SAndreas Gohr            'wiki.getPageVersion',
152797c0d11SAndreas Gohr            'this:rawPage',
153797c0d11SAndreas Gohr            array('string','string','int'),
154797c0d11SAndreas Gohr            'Get the raw Wiki text of page.'
155797c0d11SAndreas Gohr        );
156797c0d11SAndreas Gohr        $this->addCallback(
157797c0d11SAndreas Gohr            'wiki.getPageHTML',
158797c0d11SAndreas Gohr            'this:htmlPage',
159797c0d11SAndreas Gohr            array('string','string'),
160797c0d11SAndreas Gohr            'Return page in rendered HTML, latest version.'
161797c0d11SAndreas Gohr        );
162797c0d11SAndreas Gohr        $this->addCallback(
163797c0d11SAndreas Gohr            'wiki.getPageHTMLVersion',
164797c0d11SAndreas Gohr            'this:htmlPage',
165797c0d11SAndreas Gohr            array('string','string','int'),
166797c0d11SAndreas Gohr            'Return page in rendered HTML.'
167797c0d11SAndreas Gohr        );
168797c0d11SAndreas Gohr        $this->addCallback(
169797c0d11SAndreas Gohr            'wiki.getAllPages',
170797c0d11SAndreas Gohr            'this:listPages',
171797c0d11SAndreas Gohr            array('struct'),
172797c0d11SAndreas Gohr            'Returns a list of all pages. The result is an array of utf8 pagenames.'
173797c0d11SAndreas Gohr        );
174797c0d11SAndreas Gohr        $this->addCallback(
17526bec61eSMichael Klier            'wiki.getAttachments',
17626bec61eSMichael Klier            'this:listAttachments',
177c63d1645SGina Haeussge            array('struct', 'string', 'struct'),
17826bec61eSMichael Klier            'Returns a list of all media files.'
17926bec61eSMichael Klier        );
18026bec61eSMichael Klier        $this->addCallback(
181797c0d11SAndreas Gohr            'wiki.getBackLinks',
182797c0d11SAndreas Gohr            'this:listBackLinks',
183797c0d11SAndreas Gohr            array('struct','string'),
184797c0d11SAndreas Gohr            'Returns the pages that link to this page.'
185797c0d11SAndreas Gohr        );
186797c0d11SAndreas Gohr        $this->addCallback(
187797c0d11SAndreas Gohr            'wiki.getPageInfo',
188797c0d11SAndreas Gohr            'this:pageInfo',
189797c0d11SAndreas Gohr            array('struct','string'),
190797c0d11SAndreas Gohr            'Returns a struct with infos about the page.'
191797c0d11SAndreas Gohr        );
192797c0d11SAndreas Gohr        $this->addCallback(
193797c0d11SAndreas Gohr            'wiki.getPageInfoVersion',
194797c0d11SAndreas Gohr            'this:pageInfo',
195797c0d11SAndreas Gohr            array('struct','string','int'),
196797c0d11SAndreas Gohr            'Returns a struct with infos about the page.'
197797c0d11SAndreas Gohr        );
1983a1dad2dSDennis Ploeger        $this->addCallback(
19973056168SMichael Klier            'wiki.getPageVersions',
20073056168SMichael Klier            'this:pageVersions',
20173056168SMichael Klier            array('struct','string','int'),
20273056168SMichael Klier            'Returns the available revisions of the page.'
20373056168SMichael Klier        );
20473056168SMichael Klier        $this->addCallback(
2053a1dad2dSDennis Ploeger            'wiki.putPage',
2063a1dad2dSDennis Ploeger            'this:putPage',
207222572bfSMichael Klier            array('int', 'string', 'string', 'struct'),
208fdd2e9d6SMichael Klier            'Saves a wiki page.'
2093a1dad2dSDennis Ploeger        );
210beccd742SMichael Klier        $this->addCallback(
211beccd742SMichael Klier            'wiki.listLinks',
212beccd742SMichael Klier            'this:listLinks',
213beccd742SMichael Klier            array('struct','string'),
214fdd2e9d6SMichael Klier            'Lists all links contained in a wiki page.'
215beccd742SMichael Klier        );
21663dd0d58SMichael Klier        $this->addCallback(
21763dd0d58SMichael Klier            'wiki.getRecentChanges',
21863dd0d58SMichael Klier            'this:getRecentChanges',
21963dd0d58SMichael Klier            array('struct','int'),
22099c8d7f2Smichael            'Returns a struct about all recent changes since given timestamp.'
22199c8d7f2Smichael        );
22299c8d7f2Smichael        $this->addCallback(
22399c8d7f2Smichael            'wiki.getRecentMediaChanges',
22499c8d7f2Smichael            'this:getRecentMediaChanges',
22599c8d7f2Smichael            array('struct','int'),
22699c8d7f2Smichael            'Returns a struct about all recent media changes since given timestamp.'
22763dd0d58SMichael Klier        );
228e62b9ea5SMichael Klier        $this->addCallback(
229e62b9ea5SMichael Klier            'wiki.aclCheck',
230e62b9ea5SMichael Klier            'this:aclCheck',
231c63d1645SGina Haeussge            array('int', 'string'),
232e62b9ea5SMichael Klier            'Returns the permissions of a given wiki page.'
233e62b9ea5SMichael Klier        );
2342aca132fSMichael Klier        $this->addCallback(
2352aca132fSMichael Klier            'wiki.putAttachment',
2362aca132fSMichael Klier            'this:putAttachment',
2372aca132fSMichael Klier            array('struct', 'string', 'base64', 'struct'),
2382aca132fSMichael Klier            'Upload a file to the wiki.'
2392aca132fSMichael Klier        );
240cfef3001SGina Haeussge        $this->addCallback(
241f01ff8c1SGina Haeussge            'wiki.deleteAttachment',
242f01ff8c1SGina Haeussge            'this:deleteAttachment',
243f01ff8c1SGina Haeussge            array('int', 'string'),
244f01ff8c1SGina Haeussge            'Delete a file from the wiki.'
245f01ff8c1SGina Haeussge        );
246f01ff8c1SGina Haeussge        $this->addCallback(
247cfef3001SGina Haeussge            'wiki.getAttachment',
248cfef3001SGina Haeussge            'this:getAttachment',
249c63d1645SGina Haeussge            array('base64', 'string'),
250cfef3001SGina Haeussge            'Download a file from the wiki.'
251cfef3001SGina Haeussge        );
2525672e868SGina Haeussge        $this->addCallback(
2535672e868SGina Haeussge            'wiki.getAttachmentInfo',
2545672e868SGina Haeussge            'this:getAttachmentInfo',
255c63d1645SGina Haeussge            array('struct', 'string'),
2565672e868SGina Haeussge            'Returns a struct with infos about the attachment.'
2575672e868SGina Haeussge        );
258797c0d11SAndreas Gohr
259bb32615dSMichael Klier        /**
260bb32615dSMichael Klier         * Trigger XMLRPC_CALLBACK_REGISTER, action plugins can use this event
261bb32615dSMichael Klier         * to extend the XMLRPC interface and register their own callbacks.
262bb32615dSMichael Klier         *
263bb32615dSMichael Klier         * Event data:
264bb32615dSMichael Klier         *  The XMLRPC server object:
265bb32615dSMichael Klier         *
266bb32615dSMichael Klier         *  $event->data->addCallback() - register a callback, the second
267bb32615dSMichael Klier         *  paramter has to be of the form "plugin:<pluginname>:<plugin
268bb32615dSMichael Klier         *  method>"
269bb32615dSMichael Klier         *
270bb32615dSMichael Klier         *  $event->data->callbacks - an array which holds all awaylable
271bb32615dSMichael Klier         *  callbacks
272bb32615dSMichael Klier         */
273bb32615dSMichael Klier        trigger_event('XMLRPC_CALLBACK_REGISTER', $this);
274bb32615dSMichael Klier
275797c0d11SAndreas Gohr        $this->serve();
276797c0d11SAndreas Gohr    }
277797c0d11SAndreas Gohr
278797c0d11SAndreas Gohr    /**
279797c0d11SAndreas Gohr     * Return a raw wiki page
280797c0d11SAndreas Gohr     */
281797c0d11SAndreas Gohr    function rawPage($id,$rev=''){
282eff795acSMichael Hamann        $id = cleanID($id);
283797c0d11SAndreas Gohr        if(auth_quickaclcheck($id) < AUTH_READ){
284797c0d11SAndreas Gohr            return new IXR_Error(1, 'You are not allowed to read this page');
285797c0d11SAndreas Gohr        }
2862c176304SMichael Klier        $text = rawWiki($id,$rev);
2872c176304SMichael Klier        if(!$text) {
288fe17917eSAdrian Lang            return pageTemplate($id);
2892c176304SMichael Klier        } else {
2902c176304SMichael Klier            return $text;
2912c176304SMichael Klier        }
292797c0d11SAndreas Gohr    }
293797c0d11SAndreas Gohr
294797c0d11SAndreas Gohr    /**
295cfef3001SGina Haeussge     * Return a media file encoded in base64
296c63d1645SGina Haeussge     *
297c63d1645SGina Haeussge     * @author Gina Haeussge <osd@foosel.net>
298cfef3001SGina Haeussge     */
299cfef3001SGina Haeussge    function getAttachment($id){
300c63d1645SGina Haeussge        $id = cleanID($id);
301cfef3001SGina Haeussge        if (auth_quickaclcheck(getNS($id).':*') < AUTH_READ)
302cfef3001SGina Haeussge            return new IXR_Error(1, 'You are not allowed to read this file');
303cfef3001SGina Haeussge
304cfef3001SGina Haeussge        $file = mediaFN($id);
305cfef3001SGina Haeussge        if (!@ file_exists($file))
306cfef3001SGina Haeussge            return new IXR_Error(1, 'The requested file does not exist');
307cfef3001SGina Haeussge
308cfef3001SGina Haeussge        $data = io_readFile($file, false);
309cfef3001SGina Haeussge        $base64 = base64_encode($data);
310cfef3001SGina Haeussge        return $base64;
311cfef3001SGina Haeussge    }
312cfef3001SGina Haeussge
313cfef3001SGina Haeussge    /**
3145672e868SGina Haeussge     * Return info about a media file
3155672e868SGina Haeussge     *
3165672e868SGina Haeussge     * @author Gina Haeussge <osd@foosel.net>
3175672e868SGina Haeussge     */
3185672e868SGina Haeussge    function getAttachmentInfo($id){
3195672e868SGina Haeussge        $id = cleanID($id);
3205672e868SGina Haeussge        $info = array(
3215672e868SGina Haeussge            'lastModified' => 0,
3225672e868SGina Haeussge            'size' => 0,
3235672e868SGina Haeussge        );
3245672e868SGina Haeussge
3255672e868SGina Haeussge        $file = mediaFN($id);
3265672e868SGina Haeussge        if ((auth_quickaclcheck(getNS($id).':*') >= AUTH_READ) && file_exists($file)){
3275672e868SGina Haeussge            $info['lastModified'] = new IXR_Date(filemtime($file));
3285672e868SGina Haeussge            $info['size'] = filesize($file);
3295672e868SGina Haeussge        }
3305672e868SGina Haeussge
3315672e868SGina Haeussge        return $info;
3325672e868SGina Haeussge    }
3335672e868SGina Haeussge
3345672e868SGina Haeussge    /**
335797c0d11SAndreas Gohr     * Return a wiki page rendered to html
336797c0d11SAndreas Gohr     */
337797c0d11SAndreas Gohr    function htmlPage($id,$rev=''){
338eff795acSMichael Hamann        $id = cleanID($id);
339797c0d11SAndreas Gohr        if(auth_quickaclcheck($id) < AUTH_READ){
340797c0d11SAndreas Gohr            return new IXR_Error(1, 'You are not allowed to read this page');
341797c0d11SAndreas Gohr        }
342797c0d11SAndreas Gohr        return p_wiki_xhtml($id,$rev,false);
343797c0d11SAndreas Gohr    }
344797c0d11SAndreas Gohr
345797c0d11SAndreas Gohr    /**
346797c0d11SAndreas Gohr     * List all pages - we use the indexer list here
347797c0d11SAndreas Gohr     */
348797c0d11SAndreas Gohr    function listPages(){
349dfd13e55SMichael Klier        $list  = array();
3509b41be24STom N Harris        $pages = idx_get_indexer()->getPages();
3519b41be24STom N Harris        $pages = array_filter(array_filter($pages,'isVisiblePage'),'page_exists');
352dfd13e55SMichael Klier
353dfd13e55SMichael Klier        foreach(array_keys($pages) as $idx) {
354dfd13e55SMichael Klier            $perm = auth_quickaclcheck($pages[$idx]);
355a0070b52SAdrian Lang            if($perm < AUTH_READ) {
356a0070b52SAdrian Lang                continue;
357a0070b52SAdrian Lang            }
358dfd13e55SMichael Klier            $page = array();
359dfd13e55SMichael Klier            $page['id'] = trim($pages[$idx]);
360dfd13e55SMichael Klier            $page['perms'] = $perm;
361dfd13e55SMichael Klier            $page['size'] = @filesize(wikiFN($pages[$idx]));
362e070c6f3SGina Haeussge            $page['lastModified'] = new IXR_Date(@filemtime(wikiFN($pages[$idx])));
363dfd13e55SMichael Klier            $list[] = $page;
364dfd13e55SMichael Klier        }
365dfd13e55SMichael Klier
366dfd13e55SMichael Klier        return $list;
367797c0d11SAndreas Gohr    }
368797c0d11SAndreas Gohr
369797c0d11SAndreas Gohr    /**
3701b11c097SAndreas Gohr     * List all pages in the given namespace (and below)
3711b11c097SAndreas Gohr     */
3721b11c097SAndreas Gohr    function readNamespace($ns,$opts){
3731b11c097SAndreas Gohr        global $conf;
3741b11c097SAndreas Gohr
3751b11c097SAndreas Gohr        if(!is_array($opts)) $opts=array();
3761b11c097SAndreas Gohr
3771b11c097SAndreas Gohr        $ns = cleanID($ns);
3781b11c097SAndreas Gohr        $dir = utf8_encodeFN(str_replace(':', '/', $ns));
3791b11c097SAndreas Gohr        $data = array();
3806fc3aa1aSAndreas Gohr        $opts['skipacl'] = 0; // no ACL skipping for XMLRPC
3811b11c097SAndreas Gohr        search($data, $conf['datadir'], 'search_allpages', $opts, $dir);
3821b11c097SAndreas Gohr        return $data;
3831b11c097SAndreas Gohr    }
3841b11c097SAndreas Gohr
3851b11c097SAndreas Gohr    /**
386f71f4f53SAndreas Gohr     * List all pages in the given namespace (and below)
387f71f4f53SAndreas Gohr     */
388f71f4f53SAndreas Gohr    function search($query){
389f71f4f53SAndreas Gohr        require_once(DOKU_INC.'inc/fulltext.php');
390f71f4f53SAndreas Gohr
391f71f4f53SAndreas Gohr        $regex = '';
392f71f4f53SAndreas Gohr        $data  = ft_pageSearch($query,$regex);
393f71f4f53SAndreas Gohr        $pages = array();
394f71f4f53SAndreas Gohr
395f71f4f53SAndreas Gohr        // prepare additional data
396f71f4f53SAndreas Gohr        $idx = 0;
397f71f4f53SAndreas Gohr        foreach($data as $id => $score){
398f71f4f53SAndreas Gohr            $file = wikiFN($id);
399f71f4f53SAndreas Gohr
400f71f4f53SAndreas Gohr            if($idx < FT_SNIPPET_NUMBER){
401f71f4f53SAndreas Gohr                $snippet = ft_snippet($id,$regex);
402f71f4f53SAndreas Gohr                $idx++;
403f71f4f53SAndreas Gohr            }else{
404f71f4f53SAndreas Gohr                $snippet = '';
405f71f4f53SAndreas Gohr            }
406f71f4f53SAndreas Gohr
407f71f4f53SAndreas Gohr            $pages[] = array(
408f71f4f53SAndreas Gohr                'id'      => $id,
409f71f4f53SAndreas Gohr                'score'   => $score,
410f71f4f53SAndreas Gohr                'rev'     => filemtime($file),
411f71f4f53SAndreas Gohr                'mtime'   => filemtime($file),
412f71f4f53SAndreas Gohr                'size'    => filesize($file),
413f71f4f53SAndreas Gohr                'snippet' => $snippet,
414f71f4f53SAndreas Gohr            );
415f71f4f53SAndreas Gohr        }
416ac1ffddeSGeorges-Etienne Legendre        return $pages;
417f71f4f53SAndreas Gohr    }
418f71f4f53SAndreas Gohr
419e6f4c9d4SGeorges-Etienne Legendre    /**
420e6f4c9d4SGeorges-Etienne Legendre     * Returns the wiki title.
421e6f4c9d4SGeorges-Etienne Legendre     */
422e6f4c9d4SGeorges-Etienne Legendre    function getTitle(){
423e6f4c9d4SGeorges-Etienne Legendre        global $conf;
424e6f4c9d4SGeorges-Etienne Legendre        return $conf['title'];
425e6f4c9d4SGeorges-Etienne Legendre    }
426f71f4f53SAndreas Gohr
427f71f4f53SAndreas Gohr    /**
42826bec61eSMichael Klier     * List all media files.
4293275953aSGina Haeussge     *
4303275953aSGina Haeussge     * Available options are 'recursive' for also including the subnamespaces
4313275953aSGina Haeussge     * in the listing, and 'pattern' for filtering the returned files against
4323275953aSGina Haeussge     * a regular expression matching their name.
4333275953aSGina Haeussge     *
4343275953aSGina Haeussge     * @author Gina Haeussge <osd@foosel.net>
43526bec61eSMichael Klier     */
4363275953aSGina Haeussge    function listAttachments($ns, $options = array()) {
43726bec61eSMichael Klier        global $conf;
43826bec61eSMichael Klier        global $lang;
43926bec61eSMichael Klier
44026bec61eSMichael Klier        $ns = cleanID($ns);
44126bec61eSMichael Klier
4426fc3aa1aSAndreas Gohr        if (!is_array($options)) $options = array();
4436fc3aa1aSAndreas Gohr        $options['skipacl'] = 0; // no ACL skipping for XMLRPC
4443275953aSGina Haeussge
4453275953aSGina Haeussge
44626bec61eSMichael Klier        if(auth_quickaclcheck($ns.':*') >= AUTH_READ) {
44726bec61eSMichael Klier            $dir = utf8_encodeFN(str_replace(':', '/', $ns));
44826bec61eSMichael Klier
44926bec61eSMichael Klier            $data = array();
450224122cfSAndreas Gohr            search($data, $conf['mediadir'], 'search_media', $options, $dir);
451224122cfSAndreas Gohr            $len = count($data);
452224122cfSAndreas Gohr            if(!$len) return array();
45326bec61eSMichael Klier
454224122cfSAndreas Gohr            for($i=0; $i<$len; $i++) {
455224122cfSAndreas Gohr                unset($data[$i]['meta']);
456224122cfSAndreas Gohr                $data[$i]['lastModified'] = new IXR_Date($data[$i]['mtime']);
45726bec61eSMichael Klier            }
458224122cfSAndreas Gohr            return $data;
45926bec61eSMichael Klier        } else {
46026bec61eSMichael Klier            return new IXR_Error(1, 'You are not allowed to list media files.');
46126bec61eSMichael Klier        }
46226bec61eSMichael Klier    }
46326bec61eSMichael Klier
46426bec61eSMichael Klier    /**
465797c0d11SAndreas Gohr     * Return a list of backlinks
466797c0d11SAndreas Gohr     */
467beccd742SMichael Klier    function listBackLinks($id){
46886228f10SDominik Eckelmann        return ft_backlinks(cleanID($id));
469797c0d11SAndreas Gohr    }
470797c0d11SAndreas Gohr
471797c0d11SAndreas Gohr    /**
47263dd0d58SMichael Klier     * Return some basic data about a page
473797c0d11SAndreas Gohr     */
474797c0d11SAndreas Gohr    function pageInfo($id,$rev=''){
475eff795acSMichael Hamann        $id = cleanID($id);
476797c0d11SAndreas Gohr        if(auth_quickaclcheck($id) < AUTH_READ){
477797c0d11SAndreas Gohr            return new IXR_Error(1, 'You are not allowed to read this page');
478797c0d11SAndreas Gohr        }
479797c0d11SAndreas Gohr        $file = wikiFN($id,$rev);
480797c0d11SAndreas Gohr        $time = @filemtime($file);
481797c0d11SAndreas Gohr        if(!$time){
482797c0d11SAndreas Gohr            return new IXR_Error(10, 'The requested page does not exist');
483797c0d11SAndreas Gohr        }
484797c0d11SAndreas Gohr
485797c0d11SAndreas Gohr        $info = getRevisionInfo($id, $time, 1024);
486797c0d11SAndreas Gohr
487797c0d11SAndreas Gohr        $data = array(
488797c0d11SAndreas Gohr            'name'         => $id,
489797c0d11SAndreas Gohr            'lastModified' => new IXR_Date($time),
490797c0d11SAndreas Gohr            'author'       => (($info['user']) ? $info['user'] : $info['ip']),
491797c0d11SAndreas Gohr            'version'      => $time
492797c0d11SAndreas Gohr        );
49363dd0d58SMichael Klier
49463dd0d58SMichael Klier        return ($data);
495797c0d11SAndreas Gohr    }
496797c0d11SAndreas Gohr
497797c0d11SAndreas Gohr    /**
4983a1dad2dSDennis Ploeger     * Save a wiki page
499222572bfSMichael Klier     *
500222572bfSMichael Klier     * @author Michael Klier <chi@chimeric.de>
5013a1dad2dSDennis Ploeger     */
502222572bfSMichael Klier    function putPage($id, $text, $params) {
5033a1dad2dSDennis Ploeger        global $TEXT;
504a6a229ceSMichael Klier        global $lang;
505593bf8f6SMichael Klier        global $conf;
5063a1dad2dSDennis Ploeger
507222572bfSMichael Klier        $id    = cleanID($id);
50856523eecSAndreas Gohr        $TEXT  = cleanText($text);
509222572bfSMichael Klier        $sum   = $params['sum'];
510222572bfSMichael Klier        $minor = $params['minor'];
511222572bfSMichael Klier
512222572bfSMichael Klier        if(empty($id))
513fdd2e9d6SMichael Klier            return new IXR_Error(1, 'Empty page ID');
514222572bfSMichael Klier
51556523eecSAndreas Gohr        if(!page_exists($id) && trim($TEXT) == '' ) {
51651597811SMichael Klier            return new IXR_ERROR(1, 'Refusing to write an empty new wiki page');
51751597811SMichael Klier        }
51851597811SMichael Klier
519055b0144SChris Smith        if(auth_quickaclcheck($id) < AUTH_EDIT)
520222572bfSMichael Klier            return new IXR_Error(1, 'You are not allowed to edit this page');
5213a1dad2dSDennis Ploeger
5223a1dad2dSDennis Ploeger        // Check, if page is locked
523222572bfSMichael Klier        if(checklock($id))
524222572bfSMichael Klier            return new IXR_Error(1, 'The page is currently locked');
525222572bfSMichael Klier
526a6a229ceSMichael Klier        // SPAM check
5273a1dad2dSDennis Ploeger        if(checkwordblock())
528222572bfSMichael Klier            return new IXR_Error(1, 'Positive wordblock check');
5293a1dad2dSDennis Ploeger
530a6a229ceSMichael Klier        // autoset summary on new pages
531a6a229ceSMichael Klier        if(!page_exists($id) && empty($sum)) {
532a6a229ceSMichael Klier            $sum = $lang['created'];
533a6a229ceSMichael Klier        }
534a6a229ceSMichael Klier
535a6a229ceSMichael Klier        // autoset summary on deleted pages
536a6a229ceSMichael Klier        if(page_exists($id) && empty($TEXT) && empty($sum)) {
537a6a229ceSMichael Klier            $sum = $lang['deleted'];
538a6a229ceSMichael Klier        }
539a6a229ceSMichael Klier
540222572bfSMichael Klier        lock($id);
5413a1dad2dSDennis Ploeger
542222572bfSMichael Klier        saveWikiText($id,$TEXT,$sum,$minor);
5433a1dad2dSDennis Ploeger
544222572bfSMichael Klier        unlock($id);
5453a1dad2dSDennis Ploeger
546593bf8f6SMichael Klier        // run the indexer if page wasn't indexed yet
547593bf8f6SMichael Klier        idx_addPage($id);
548593bf8f6SMichael Klier
5493a1dad2dSDennis Ploeger        return 0;
550beccd742SMichael Klier    }
5513a1dad2dSDennis Ploeger
552beccd742SMichael Klier    /**
553ba9418bcSHakan Sandell     * Appends text to a wiki page.
554ba9418bcSHakan Sandell     */
555ba9418bcSHakan Sandell    function appendPage($id, $text, $params) {
556ba9418bcSHakan Sandell        $currentpage = $this->rawPage($id);
557ba9418bcSHakan Sandell        if (!is_string($currentpage)) {
558ba9418bcSHakan Sandell            return $currentpage;
559ba9418bcSHakan Sandell        }
560ba9418bcSHakan Sandell        return $this->putPage($id, $currentpage.$text, $params);
561ba9418bcSHakan Sandell    }
562ba9418bcSHakan Sandell
563ba9418bcSHakan Sandell    /**
5642aca132fSMichael Klier     * Uploads a file to the wiki.
5652aca132fSMichael Klier     *
5662aca132fSMichael Klier     * Michael Klier <chi@chimeric.de>
5672aca132fSMichael Klier     */
568f01ff8c1SGina Haeussge    function putAttachment($id, $file, $params) {
569eff795acSMichael Hamann        $id = cleanID($id);
570f01ff8c1SGina Haeussge        $auth = auth_quickaclcheck(getNS($id).':*');
571ffb291f2SAdrian Lang
572f01ff8c1SGina Haeussge        if(!isset($id)) {
5732aca132fSMichael Klier            return new IXR_ERROR(1, 'Filename not given.');
5742aca132fSMichael Klier        }
5752aca132fSMichael Klier
576ffb291f2SAdrian Lang        global $conf;
577ffb291f2SAdrian Lang
578c77fa67bSMichael Hamann        $ftmp = $conf['tmpdir'] . '/' . md5($id.clientIP());
5792aca132fSMichael Klier
5802aca132fSMichael Klier        // save temporary file
5812aca132fSMichael Klier        @unlink($ftmp);
5822aca132fSMichael Klier        $buff = base64_decode($file);
5832aca132fSMichael Klier        io_saveFile($ftmp, $buff);
5842aca132fSMichael Klier
585ffb291f2SAdrian Lang        $res = media_save(array('name' => $ftmp), $id, $params['ow'], $auth, 'rename');
586ffb291f2SAdrian Lang        if (is_array($res)) {
587ffb291f2SAdrian Lang            return new IXR_ERROR(-$res[1], $res[0]);
5882aca132fSMichael Klier        } else {
589ffb291f2SAdrian Lang            return $res;
5902aca132fSMichael Klier        }
5912aca132fSMichael Klier    }
5922aca132fSMichael Klier
5932aca132fSMichael Klier    /**
594f01ff8c1SGina Haeussge     * Deletes a file from the wiki.
595f01ff8c1SGina Haeussge     *
596f01ff8c1SGina Haeussge     * @author Gina Haeussge <osd@foosel.net>
597f01ff8c1SGina Haeussge     */
598f01ff8c1SGina Haeussge    function deleteAttachment($id){
599eff795acSMichael Hamann        $id = cleanID($id);
600f01ff8c1SGina Haeussge        $auth = auth_quickaclcheck(getNS($id).':*');
60187229c84SAdrian Lang        $res = media_delete($id, $auth);
60287229c84SAdrian Lang        if ($res & DOKU_MEDIA_DELETED) {
603f01ff8c1SGina Haeussge            return 0;
60487229c84SAdrian Lang        } elseif ($res & DOKU_MEDIA_NOT_AUTH) {
60587229c84SAdrian Lang            return new IXR_ERROR(1, "You don't have permissions to delete files.");
60687229c84SAdrian Lang        } elseif ($res & DOKU_MEDIA_INUSE) {
607f01ff8c1SGina Haeussge            return new IXR_ERROR(1, 'File is still referenced');
60899c8d7f2Smichael        } else {
60987229c84SAdrian Lang            return new IXR_ERROR(1, 'Could not delete file');
6102aca132fSMichael Klier        }
6112aca132fSMichael Klier    }
6122aca132fSMichael Klier
6132aca132fSMichael Klier    /**
614e62b9ea5SMichael Klier    * Returns the permissions of a given wiki page
615e62b9ea5SMichael Klier    */
616e62b9ea5SMichael Klier    function aclCheck($id) {
617eff795acSMichael Hamann        $id = cleanID($id);
618e62b9ea5SMichael Klier        return auth_quickaclcheck($id);
619e62b9ea5SMichael Klier    }
620e62b9ea5SMichael Klier
621e62b9ea5SMichael Klier    /**
622beccd742SMichael Klier     * Lists all links contained in a wiki page
62363dd0d58SMichael Klier     *
62463dd0d58SMichael Klier     * @author Michael Klier <chi@chimeric.de>
625beccd742SMichael Klier     */
626beccd742SMichael Klier    function listLinks($id) {
627eff795acSMichael Hamann        $id = cleanID($id);
628beccd742SMichael Klier        if(auth_quickaclcheck($id) < AUTH_READ){
629beccd742SMichael Klier            return new IXR_Error(1, 'You are not allowed to read this page');
630beccd742SMichael Klier        }
631beccd742SMichael Klier        $links = array();
632beccd742SMichael Klier
633beccd742SMichael Klier        // resolve page instructions
634eff795acSMichael Hamann        $ins   = p_cached_instructions(wikiFN($id));
635beccd742SMichael Klier
636beccd742SMichael Klier        // instantiate new Renderer - needed for interwiki links
637beccd742SMichael Klier        include(DOKU_INC.'inc/parser/xhtml.php');
638beccd742SMichael Klier        $Renderer = new Doku_Renderer_xhtml();
639beccd742SMichael Klier        $Renderer->interwiki = getInterwiki();
640beccd742SMichael Klier
641beccd742SMichael Klier        // parse parse instructions
642beccd742SMichael Klier        foreach($ins as $in) {
643beccd742SMichael Klier            $link = array();
644beccd742SMichael Klier            switch($in[0]) {
645beccd742SMichael Klier                case 'internallink':
646beccd742SMichael Klier                    $link['type'] = 'local';
647beccd742SMichael Klier                    $link['page'] = $in[1][0];
648beccd742SMichael Klier                    $link['href'] = wl($in[1][0]);
649beccd742SMichael Klier                    array_push($links,$link);
650beccd742SMichael Klier                    break;
651beccd742SMichael Klier                case 'externallink':
652beccd742SMichael Klier                    $link['type'] = 'extern';
653beccd742SMichael Klier                    $link['page'] = $in[1][0];
654beccd742SMichael Klier                    $link['href'] = $in[1][0];
655beccd742SMichael Klier                    array_push($links,$link);
656beccd742SMichael Klier                    break;
657beccd742SMichael Klier                case 'interwikilink':
658beccd742SMichael Klier                    $url = $Renderer->_resolveInterWiki($in[1][2],$in[1][3]);
659beccd742SMichael Klier                    $link['type'] = 'extern';
660beccd742SMichael Klier                    $link['page'] = $url;
661beccd742SMichael Klier                    $link['href'] = $url;
662beccd742SMichael Klier                    array_push($links,$link);
663beccd742SMichael Klier                    break;
664beccd742SMichael Klier            }
665beccd742SMichael Klier        }
666beccd742SMichael Klier
66763dd0d58SMichael Klier        return ($links);
66863dd0d58SMichael Klier    }
66963dd0d58SMichael Klier
67063dd0d58SMichael Klier    /**
67163dd0d58SMichael Klier     * Returns a list of recent changes since give timestamp
67263dd0d58SMichael Klier     *
67399c8d7f2Smichael     * @author Michael Hamann <michael@content-space.de>
67463dd0d58SMichael Klier     * @author Michael Klier <chi@chimeric.de>
67563dd0d58SMichael Klier     */
67663dd0d58SMichael Klier    function getRecentChanges($timestamp) {
67763dd0d58SMichael Klier        if(strlen($timestamp) != 10)
67863dd0d58SMichael Klier            return new IXR_Error(20, 'The provided value is not a valid timestamp');
67963dd0d58SMichael Klier
68099c8d7f2Smichael        $recents = getRecentsSince($timestamp);
68163dd0d58SMichael Klier
68299c8d7f2Smichael        $changes = array();
68363dd0d58SMichael Klier
68499c8d7f2Smichael        foreach ($recents as $recent) {
68599c8d7f2Smichael            $change = array();
68699c8d7f2Smichael            $change['name']         = $recent['id'];
68799c8d7f2Smichael            $change['lastModified'] = new IXR_Date($recent['date']);
68899c8d7f2Smichael            $change['author']       = $recent['user'];
68999c8d7f2Smichael            $change['version']      = $recent['date'];
69099c8d7f2Smichael            $change['perms']        = $recent['perms'];
69199c8d7f2Smichael            $change['size']         = @filesize(wikiFN($recent['id']));
69263dd0d58SMichael Klier            array_push($changes, $change);
69399c8d7f2Smichael        }
69499c8d7f2Smichael
69599c8d7f2Smichael        if (!empty($changes)) {
69699c8d7f2Smichael            return $changes;
69763dd0d58SMichael Klier        } else {
69863dd0d58SMichael Klier            // in case we still have nothing at this point
69963dd0d58SMichael Klier            return new IXR_Error(30, 'There are no changes in the specified timeframe');
7003a1dad2dSDennis Ploeger        }
70199c8d7f2Smichael    }
70299c8d7f2Smichael
70399c8d7f2Smichael    /**
70499c8d7f2Smichael     * Returns a list of recent media changes since give timestamp
70599c8d7f2Smichael     *
70699c8d7f2Smichael     * @author Michael Hamann <michael@content-space.de>
70799c8d7f2Smichael     * @author Michael Klier <chi@chimeric.de>
70899c8d7f2Smichael     */
70999c8d7f2Smichael    function getRecentMediaChanges($timestamp) {
71099c8d7f2Smichael        if(strlen($timestamp) != 10)
71199c8d7f2Smichael            return new IXR_Error(20, 'The provided value is not a valid timestamp');
71299c8d7f2Smichael
71399c8d7f2Smichael        $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES);
71499c8d7f2Smichael
71599c8d7f2Smichael        $changes = array();
71699c8d7f2Smichael
71799c8d7f2Smichael        foreach ($recents as $recent) {
71899c8d7f2Smichael            $change = array();
71999c8d7f2Smichael            $change['name']         = $recent['id'];
72099c8d7f2Smichael            $change['lastModified'] = new IXR_Date($recent['date']);
72199c8d7f2Smichael            $change['author']       = $recent['user'];
72299c8d7f2Smichael            $change['version']      = $recent['date'];
72399c8d7f2Smichael            $change['perms']        = $recent['perms'];
724a4da2756Smichael            $change['size']         = @filesize(mediaFN($recent['id']));
72599c8d7f2Smichael            array_push($changes, $change);
72699c8d7f2Smichael        }
72799c8d7f2Smichael
72899c8d7f2Smichael        if (!empty($changes)) {
72999c8d7f2Smichael            return $changes;
73099c8d7f2Smichael        } else {
73199c8d7f2Smichael            // in case we still have nothing at this point
73299c8d7f2Smichael            return new IXR_Error(30, 'There are no changes in the specified timeframe');
73399c8d7f2Smichael        }
73499c8d7f2Smichael    }
7353a1dad2dSDennis Ploeger
7363a1dad2dSDennis Ploeger    /**
73773056168SMichael Klier     * Returns a list of available revisions of a given wiki page
73873056168SMichael Klier     *
73973056168SMichael Klier     * @author Michael Klier <chi@chimeric.de>
74073056168SMichael Klier     */
74173056168SMichael Klier    function pageVersions($id, $first) {
742eff795acSMichael Hamann        $id = cleanID($id);
743eff795acSMichael Hamann        if(auth_quickaclcheck($id) < AUTH_READ){
744eff795acSMichael Hamann            return new IXR_Error(1, 'You are not allowed to read this page');
745eff795acSMichael Hamann        }
74673056168SMichael Klier        global $conf;
74773056168SMichael Klier
74873056168SMichael Klier        $versions = array();
74973056168SMichael Klier
75073056168SMichael Klier        if(empty($id))
75173056168SMichael Klier            return new IXR_Error(1, 'Empty page ID');
75273056168SMichael Klier
75373056168SMichael Klier        $revisions = getRevisions($id, $first, $conf['recent']+1);
75473056168SMichael Klier
75573056168SMichael Klier        if(count($revisions)==0 && $first!=0) {
75673056168SMichael Klier            $first=0;
75773056168SMichael Klier            $revisions = getRevisions($id, $first, $conf['recent']+1);
75873056168SMichael Klier        }
75973056168SMichael Klier
76045c63471SMichael Klier        if(count($revisions)>0 && $first==0) {
76145c63471SMichael Klier            array_unshift($revisions, '');  // include current revision
76245c63471SMichael Klier            array_pop($revisions);          // remove extra log entry
76345c63471SMichael Klier        }
76445c63471SMichael Klier
76573056168SMichael Klier        $hasNext = false;
76673056168SMichael Klier        if(count($revisions)>$conf['recent']) {
76773056168SMichael Klier            $hasNext = true;
76873056168SMichael Klier            array_pop($revisions); // remove extra log entry
76973056168SMichael Klier        }
77073056168SMichael Klier
77173056168SMichael Klier        if(!empty($revisions)) {
77273056168SMichael Klier            foreach($revisions as $rev) {
77373056168SMichael Klier                $file = wikiFN($id,$rev);
77473056168SMichael Klier                $time = @filemtime($file);
77545c63471SMichael Klier                // we check if the page actually exists, if this is not the
77645c63471SMichael Klier                // case this can lead to less pages being returned than
77745c63471SMichael Klier                // specified via $conf['recent']
77873056168SMichael Klier                if($time){
77973056168SMichael Klier                    $info = getRevisionInfo($id, $time, 1024);
78073056168SMichael Klier                    if(!empty($info)) {
78173056168SMichael Klier                        $data['user'] = $info['user'];
78273056168SMichael Klier                        $data['ip']   = $info['ip'];
78373056168SMichael Klier                        $data['type'] = $info['type'];
78473056168SMichael Klier                        $data['sum']  = $info['sum'];
78573056168SMichael Klier                        $data['modified'] = new IXR_Date($info['date']);
78673056168SMichael Klier                        $data['version'] = $info['date'];
78773056168SMichael Klier                        array_push($versions, $data);
78873056168SMichael Klier                    }
78973056168SMichael Klier                }
79073056168SMichael Klier            }
79173056168SMichael Klier            return $versions;
79273056168SMichael Klier        } else {
79373056168SMichael Klier            return array();
79473056168SMichael Klier        }
79573056168SMichael Klier    }
79673056168SMichael Klier
79773056168SMichael Klier    /**
798797c0d11SAndreas Gohr     * The version of Wiki RPC API supported
799797c0d11SAndreas Gohr     */
800797c0d11SAndreas Gohr    function wiki_RPCVersion(){
801797c0d11SAndreas Gohr        return 2;
802797c0d11SAndreas Gohr    }
8031b11c097SAndreas Gohr
80428ec3c76SAndreas Gohr
80528ec3c76SAndreas Gohr    /**
80628ec3c76SAndreas Gohr     * Locks or unlocks a given batch of pages
80728ec3c76SAndreas Gohr     *
80828ec3c76SAndreas Gohr     * Give an associative array with two keys: lock and unlock. Both should contain a
80928ec3c76SAndreas Gohr     * list of pages to lock or unlock
81028ec3c76SAndreas Gohr     *
81128ec3c76SAndreas Gohr     * Returns an associative array with the keys locked, lockfail, unlocked and
81228ec3c76SAndreas Gohr     * unlockfail, each containing lists of pages.
81328ec3c76SAndreas Gohr     */
81428ec3c76SAndreas Gohr    function setLocks($set){
81528ec3c76SAndreas Gohr        $locked     = array();
81628ec3c76SAndreas Gohr        $lockfail   = array();
81728ec3c76SAndreas Gohr        $unlocked   = array();
81828ec3c76SAndreas Gohr        $unlockfail = array();
81928ec3c76SAndreas Gohr
82028ec3c76SAndreas Gohr        foreach((array) $set['lock'] as $id){
821eff795acSMichael Hamann            $id = cleanID($id);
822eff795acSMichael Hamann            if(auth_quickaclcheck($id) < AUTH_EDIT || checklock($id)){
82328ec3c76SAndreas Gohr                $lockfail[] = $id;
82428ec3c76SAndreas Gohr            }else{
82528ec3c76SAndreas Gohr                lock($id);
82628ec3c76SAndreas Gohr                $locked[] = $id;
82728ec3c76SAndreas Gohr            }
82828ec3c76SAndreas Gohr        }
82928ec3c76SAndreas Gohr
83028ec3c76SAndreas Gohr        foreach((array) $set['unlock'] as $id){
831eff795acSMichael Hamann            $id = cleanID($id);
832eff795acSMichael Hamann            if(auth_quickaclcheck($id) < AUTH_EDIT || !unlock($id)){
83328ec3c76SAndreas Gohr                $unlockfail[] = $id;
834eff795acSMichael Hamann            }else{
835eff795acSMichael Hamann                $unlocked[] = $id;
83628ec3c76SAndreas Gohr            }
83728ec3c76SAndreas Gohr        }
83828ec3c76SAndreas Gohr
83928ec3c76SAndreas Gohr        return array(
84028ec3c76SAndreas Gohr            'locked'     => $locked,
84128ec3c76SAndreas Gohr            'lockfail'   => $lockfail,
84228ec3c76SAndreas Gohr            'unlocked'   => $unlocked,
84328ec3c76SAndreas Gohr            'unlockfail' => $unlockfail,
84428ec3c76SAndreas Gohr        );
84528ec3c76SAndreas Gohr    }
84628ec3c76SAndreas Gohr
847445e8084SAndreas Gohr    function getAPIVersion(){
848445e8084SAndreas Gohr        return DOKU_XMLRPC_API_VERSION;
849445e8084SAndreas Gohr    }
850445e8084SAndreas Gohr
851445e8084SAndreas Gohr    function login($user,$pass){
852445e8084SAndreas Gohr        global $conf;
853445e8084SAndreas Gohr        global $auth;
854445e8084SAndreas Gohr        if(!$conf['useacl']) return 0;
855445e8084SAndreas Gohr        if(!$auth) return 0;
856445e8084SAndreas Gohr        if($auth->canDo('external')){
857445e8084SAndreas Gohr            return $auth->trustExternal($user,$pass,false);
858445e8084SAndreas Gohr        }else{
859445e8084SAndreas Gohr            return auth_login($user,$pass,false,true);
860445e8084SAndreas Gohr        }
861445e8084SAndreas Gohr    }
8623ee5b583SAndreas Gohr
8633ee5b583SAndreas Gohr
864797c0d11SAndreas Gohr}
865797c0d11SAndreas Gohr
866797c0d11SAndreas Gohr$server = new dokuwiki_xmlrpc_server();
867797c0d11SAndreas Gohr
868e3776c06SMichael Hamann// vim:ts=4:sw=4:et:
869