xref: /dokuwiki/lib/exe/xmlrpc.php (revision 3f3bb97fcdd30282632d96a5bb19d2ea61c01504)
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 */
1080d6fbc3SAdrian Langdefine('DOKU_XMLRPC_API_VERSION', 6);
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();
24*3f3bb97fSDominik Eckelmann    var $remote;
253ee5b583SAndreas Gohr
263ee5b583SAndreas Gohr    /**
273ee5b583SAndreas Gohr     * Checks if the current user is allowed to execute non anonymous methods
283ee5b583SAndreas Gohr     */
293ee5b583SAndreas Gohr    function checkAuth(){
303ee5b583SAndreas Gohr        global $conf;
313ee5b583SAndreas Gohr        global $USERINFO;
323ee5b583SAndreas Gohr
333ee5b583SAndreas Gohr        if(!$conf['useacl']) return true; //no ACL - then no checks
34992ded5aSAndreas Gohr        if(trim($conf['xmlrpcuser']) == '') return true; //no restrictions
353ee5b583SAndreas Gohr
36992ded5aSAndreas Gohr        return auth_isMember($conf['xmlrpcuser'],$_SERVER['REMOTE_USER'],(array) $USERINFO['grps']);
373ee5b583SAndreas Gohr    }
383ee5b583SAndreas Gohr
393ee5b583SAndreas Gohr    /**
403ee5b583SAndreas Gohr     * Adds a callback, extends parent method
413ee5b583SAndreas Gohr     *
423ee5b583SAndreas Gohr     * add another parameter to define if anonymous access to
433ee5b583SAndreas Gohr     * this method should be granted.
443ee5b583SAndreas Gohr     */
453ee5b583SAndreas Gohr    function addCallback($method, $callback, $args, $help, $public=false){
463ee5b583SAndreas Gohr        if($public) $this->public_methods[] = $method;
473ee5b583SAndreas Gohr        return parent::addCallback($method, $callback, $args, $help);
483ee5b583SAndreas Gohr    }
493ee5b583SAndreas Gohr
503ee5b583SAndreas Gohr    /**
513ee5b583SAndreas Gohr     * Execute a call, extends parent method
523ee5b583SAndreas Gohr     *
533ee5b583SAndreas Gohr     * Checks for authentication first
543ee5b583SAndreas Gohr     */
553ee5b583SAndreas Gohr    function call($methodname, $args){
563ee5b583SAndreas Gohr        if(!in_array($methodname,$this->public_methods) && !$this->checkAuth()){
57794fc9dbSMichael Hamann            if (!isset($_SERVER['REMOTE_USER'])) {
58b760af94SMichael Hamann                header('HTTP/1.1 401 Unauthorized');
59794fc9dbSMichael Hamann            } else {
60794fc9dbSMichael Hamann                header('HTTP/1.1 403 Forbidden');
61794fc9dbSMichael Hamann            }
623ee5b583SAndreas Gohr            return new IXR_Error(-32603, 'server error. not authorized to call method "'.$methodname.'".');
633ee5b583SAndreas Gohr        }
643ee5b583SAndreas Gohr        return parent::call($methodname, $args);
653ee5b583SAndreas Gohr    }
66797c0d11SAndreas Gohr
67797c0d11SAndreas Gohr    /**
68797c0d11SAndreas Gohr     * Constructor. Register methods and run Server
69797c0d11SAndreas Gohr     */
70797c0d11SAndreas Gohr    function dokuwiki_xmlrpc_server(){
71*3f3bb97fSDominik Eckelmann        $this->remote = new RemoteAPI();
72797c0d11SAndreas Gohr        $this->IXR_IntrospectionServer();
73797c0d11SAndreas Gohr
74797c0d11SAndreas Gohr        /* DokuWiki's own methods */
75797c0d11SAndreas Gohr        $this->addCallback(
76445e8084SAndreas Gohr            'dokuwiki.getXMLRPCAPIVersion',
77445e8084SAndreas Gohr            'this:getAPIVersion',
78445e8084SAndreas Gohr            array('integer'),
793ee5b583SAndreas Gohr            'Returns the XMLRPC API version.',
803ee5b583SAndreas Gohr            true
81445e8084SAndreas Gohr        );
82445e8084SAndreas Gohr
83445e8084SAndreas Gohr        $this->addCallback(
84797c0d11SAndreas Gohr            'dokuwiki.getVersion',
85797c0d11SAndreas Gohr            'getVersion',
86797c0d11SAndreas Gohr            array('string'),
873ee5b583SAndreas Gohr            'Returns the running DokuWiki version.',
883ee5b583SAndreas Gohr            true
89797c0d11SAndreas Gohr        );
90797c0d11SAndreas Gohr
911b11c097SAndreas Gohr        $this->addCallback(
92445e8084SAndreas Gohr            'dokuwiki.login',
93445e8084SAndreas Gohr            'this:login',
94445e8084SAndreas Gohr            array('integer','string','string'),
953ee5b583SAndreas Gohr            'Tries to login with the given credentials and sets auth cookies.',
963ee5b583SAndreas Gohr            true
97445e8084SAndreas Gohr        );
98445e8084SAndreas Gohr
99445e8084SAndreas Gohr        $this->addCallback(
1001b11c097SAndreas Gohr            'dokuwiki.getPagelist',
1011b11c097SAndreas Gohr            'this:readNamespace',
1021b11c097SAndreas Gohr            array('struct','string','struct'),
1031b11c097SAndreas Gohr            'List all pages within the given namespace.'
1041b11c097SAndreas Gohr        );
1051b11c097SAndreas Gohr
1061b11c097SAndreas Gohr        $this->addCallback(
107f71f4f53SAndreas Gohr            'dokuwiki.search',
108f71f4f53SAndreas Gohr            'this:search',
109f71f4f53SAndreas Gohr            array('struct','string'),
110f71f4f53SAndreas Gohr            'Perform a fulltext search and return a list of matching pages'
111f71f4f53SAndreas Gohr        );
112f71f4f53SAndreas Gohr
113f71f4f53SAndreas Gohr        $this->addCallback(
1141b11c097SAndreas Gohr            'dokuwiki.getTime',
1151b11c097SAndreas Gohr            'time',
1161b11c097SAndreas Gohr            array('int'),
1171b11c097SAndreas Gohr            'Return the current time at the wiki server.'
1181b11c097SAndreas Gohr        );
1191b11c097SAndreas Gohr
12028ec3c76SAndreas Gohr        $this->addCallback(
12128ec3c76SAndreas Gohr            'dokuwiki.setLocks',
12228ec3c76SAndreas Gohr            'this:setLocks',
12328ec3c76SAndreas Gohr            array('struct','struct'),
12428ec3c76SAndreas Gohr            'Lock or unlock pages.'
12528ec3c76SAndreas Gohr        );
12628ec3c76SAndreas Gohr
127e6f4c9d4SGeorges-Etienne Legendre
128e6f4c9d4SGeorges-Etienne Legendre        $this->addCallback(
129e6f4c9d4SGeorges-Etienne Legendre            'dokuwiki.getTitle',
130e6f4c9d4SGeorges-Etienne Legendre            'this:getTitle',
131e6f4c9d4SGeorges-Etienne Legendre            array('string'),
132e6f4c9d4SGeorges-Etienne Legendre            'Returns the wiki title.',
133e6f4c9d4SGeorges-Etienne Legendre            true
134e6f4c9d4SGeorges-Etienne Legendre        );
135e6f4c9d4SGeorges-Etienne Legendre
136ba9418bcSHakan Sandell        $this->addCallback(
137ba9418bcSHakan Sandell            'dokuwiki.appendPage',
138ba9418bcSHakan Sandell            'this:appendPage',
139ba9418bcSHakan Sandell            array('int', 'string', 'string', 'struct'),
140ba9418bcSHakan Sandell            'Append text to a wiki page.'
141ba9418bcSHakan Sandell        );
142ba9418bcSHakan Sandell
143797c0d11SAndreas Gohr        /* Wiki API v2 http://www.jspwiki.org/wiki/WikiRPCInterface2 */
144797c0d11SAndreas Gohr        $this->addCallback(
145797c0d11SAndreas Gohr            'wiki.getRPCVersionSupported',
146797c0d11SAndreas Gohr            'this:wiki_RPCVersion',
147797c0d11SAndreas Gohr            array('int'),
1483ee5b583SAndreas Gohr            'Returns 2 with the supported RPC API version.',
1493ee5b583SAndreas Gohr            true
150797c0d11SAndreas Gohr        );
151797c0d11SAndreas Gohr        $this->addCallback(
152797c0d11SAndreas Gohr            'wiki.getPage',
153797c0d11SAndreas Gohr            'this:rawPage',
154797c0d11SAndreas Gohr            array('string','string'),
155797c0d11SAndreas Gohr            'Get the raw Wiki text of page, latest version.'
156797c0d11SAndreas Gohr        );
157797c0d11SAndreas Gohr        $this->addCallback(
158797c0d11SAndreas Gohr            'wiki.getPageVersion',
159797c0d11SAndreas Gohr            'this:rawPage',
160797c0d11SAndreas Gohr            array('string','string','int'),
161797c0d11SAndreas Gohr            'Get the raw Wiki text of page.'
162797c0d11SAndreas Gohr        );
163797c0d11SAndreas Gohr        $this->addCallback(
164797c0d11SAndreas Gohr            'wiki.getPageHTML',
165797c0d11SAndreas Gohr            'this:htmlPage',
166797c0d11SAndreas Gohr            array('string','string'),
167797c0d11SAndreas Gohr            'Return page in rendered HTML, latest version.'
168797c0d11SAndreas Gohr        );
169797c0d11SAndreas Gohr        $this->addCallback(
170797c0d11SAndreas Gohr            'wiki.getPageHTMLVersion',
171797c0d11SAndreas Gohr            'this:htmlPage',
172797c0d11SAndreas Gohr            array('string','string','int'),
173797c0d11SAndreas Gohr            'Return page in rendered HTML.'
174797c0d11SAndreas Gohr        );
175797c0d11SAndreas Gohr        $this->addCallback(
176797c0d11SAndreas Gohr            'wiki.getAllPages',
177797c0d11SAndreas Gohr            'this:listPages',
178797c0d11SAndreas Gohr            array('struct'),
179797c0d11SAndreas Gohr            'Returns a list of all pages. The result is an array of utf8 pagenames.'
180797c0d11SAndreas Gohr        );
181797c0d11SAndreas Gohr        $this->addCallback(
18226bec61eSMichael Klier            'wiki.getAttachments',
18326bec61eSMichael Klier            'this:listAttachments',
184c63d1645SGina Haeussge            array('struct', 'string', 'struct'),
18526bec61eSMichael Klier            'Returns a list of all media files.'
18626bec61eSMichael Klier        );
18726bec61eSMichael Klier        $this->addCallback(
188797c0d11SAndreas Gohr            'wiki.getBackLinks',
189797c0d11SAndreas Gohr            'this:listBackLinks',
190797c0d11SAndreas Gohr            array('struct','string'),
191797c0d11SAndreas Gohr            'Returns the pages that link to this page.'
192797c0d11SAndreas Gohr        );
193797c0d11SAndreas Gohr        $this->addCallback(
194797c0d11SAndreas Gohr            'wiki.getPageInfo',
195797c0d11SAndreas Gohr            'this:pageInfo',
196797c0d11SAndreas Gohr            array('struct','string'),
197797c0d11SAndreas Gohr            'Returns a struct with infos about the page.'
198797c0d11SAndreas Gohr        );
199797c0d11SAndreas Gohr        $this->addCallback(
200797c0d11SAndreas Gohr            'wiki.getPageInfoVersion',
201797c0d11SAndreas Gohr            'this:pageInfo',
202797c0d11SAndreas Gohr            array('struct','string','int'),
203797c0d11SAndreas Gohr            'Returns a struct with infos about the page.'
204797c0d11SAndreas Gohr        );
2053a1dad2dSDennis Ploeger        $this->addCallback(
20673056168SMichael Klier            'wiki.getPageVersions',
20773056168SMichael Klier            'this:pageVersions',
20873056168SMichael Klier            array('struct','string','int'),
20973056168SMichael Klier            'Returns the available revisions of the page.'
21073056168SMichael Klier        );
21173056168SMichael Klier        $this->addCallback(
2123a1dad2dSDennis Ploeger            'wiki.putPage',
2133a1dad2dSDennis Ploeger            'this:putPage',
214222572bfSMichael Klier            array('int', 'string', 'string', 'struct'),
215fdd2e9d6SMichael Klier            'Saves a wiki page.'
2163a1dad2dSDennis Ploeger        );
217beccd742SMichael Klier        $this->addCallback(
218beccd742SMichael Klier            'wiki.listLinks',
219beccd742SMichael Klier            'this:listLinks',
220beccd742SMichael Klier            array('struct','string'),
221fdd2e9d6SMichael Klier            'Lists all links contained in a wiki page.'
222beccd742SMichael Klier        );
22363dd0d58SMichael Klier        $this->addCallback(
22463dd0d58SMichael Klier            'wiki.getRecentChanges',
22563dd0d58SMichael Klier            'this:getRecentChanges',
22663dd0d58SMichael Klier            array('struct','int'),
22799c8d7f2Smichael            'Returns a struct about all recent changes since given timestamp.'
22899c8d7f2Smichael        );
22999c8d7f2Smichael        $this->addCallback(
23099c8d7f2Smichael            'wiki.getRecentMediaChanges',
23199c8d7f2Smichael            'this:getRecentMediaChanges',
23299c8d7f2Smichael            array('struct','int'),
23399c8d7f2Smichael            'Returns a struct about all recent media changes since given timestamp.'
23463dd0d58SMichael Klier        );
235e62b9ea5SMichael Klier        $this->addCallback(
236e62b9ea5SMichael Klier            'wiki.aclCheck',
237e62b9ea5SMichael Klier            'this:aclCheck',
238c63d1645SGina Haeussge            array('int', 'string'),
239e62b9ea5SMichael Klier            'Returns the permissions of a given wiki page.'
240e62b9ea5SMichael Klier        );
2412aca132fSMichael Klier        $this->addCallback(
2422aca132fSMichael Klier            'wiki.putAttachment',
2432aca132fSMichael Klier            'this:putAttachment',
2442aca132fSMichael Klier            array('struct', 'string', 'base64', 'struct'),
2452aca132fSMichael Klier            'Upload a file to the wiki.'
2462aca132fSMichael Klier        );
247cfef3001SGina Haeussge        $this->addCallback(
248f01ff8c1SGina Haeussge            'wiki.deleteAttachment',
249f01ff8c1SGina Haeussge            'this:deleteAttachment',
250f01ff8c1SGina Haeussge            array('int', 'string'),
251f01ff8c1SGina Haeussge            'Delete a file from the wiki.'
252f01ff8c1SGina Haeussge        );
253f01ff8c1SGina Haeussge        $this->addCallback(
254cfef3001SGina Haeussge            'wiki.getAttachment',
255cfef3001SGina Haeussge            'this:getAttachment',
256c63d1645SGina Haeussge            array('base64', 'string'),
257cfef3001SGina Haeussge            'Download a file from the wiki.'
258cfef3001SGina Haeussge        );
2595672e868SGina Haeussge        $this->addCallback(
2605672e868SGina Haeussge            'wiki.getAttachmentInfo',
2615672e868SGina Haeussge            'this:getAttachmentInfo',
262c63d1645SGina Haeussge            array('struct', 'string'),
2635672e868SGina Haeussge            'Returns a struct with infos about the attachment.'
2645672e868SGina Haeussge        );
265797c0d11SAndreas Gohr
266bb32615dSMichael Klier        /**
267bb32615dSMichael Klier         * Trigger XMLRPC_CALLBACK_REGISTER, action plugins can use this event
268bb32615dSMichael Klier         * to extend the XMLRPC interface and register their own callbacks.
269bb32615dSMichael Klier         *
270bb32615dSMichael Klier         * Event data:
271bb32615dSMichael Klier         *  The XMLRPC server object:
272bb32615dSMichael Klier         *
273bb32615dSMichael Klier         *  $event->data->addCallback() - register a callback, the second
274bb32615dSMichael Klier         *  paramter has to be of the form "plugin:<pluginname>:<plugin
275bb32615dSMichael Klier         *  method>"
276bb32615dSMichael Klier         *
277bb32615dSMichael Klier         *  $event->data->callbacks - an array which holds all awaylable
278bb32615dSMichael Klier         *  callbacks
279bb32615dSMichael Klier         */
280bb32615dSMichael Klier        trigger_event('XMLRPC_CALLBACK_REGISTER', $this);
281bb32615dSMichael Klier
282797c0d11SAndreas Gohr        $this->serve();
283797c0d11SAndreas Gohr    }
284797c0d11SAndreas Gohr
285797c0d11SAndreas Gohr    /**
286797c0d11SAndreas Gohr     * Return a raw wiki page
287797c0d11SAndreas Gohr     */
288797c0d11SAndreas Gohr    function rawPage($id,$rev=''){
289*3f3bb97fSDominik Eckelmann        try {
290*3f3bb97fSDominik Eckelmann            return $this->remote->rawPage($id, $rev);
291*3f3bb97fSDominik Eckelmann        } catch(RemoteAccessDenied $e) {
292797c0d11SAndreas Gohr            return new IXR_Error(1, 'You are not allowed to read this page');
293797c0d11SAndreas Gohr        }
294797c0d11SAndreas Gohr    }
295797c0d11SAndreas Gohr
296797c0d11SAndreas Gohr    /**
297cfef3001SGina Haeussge     * Return a media file encoded in base64
298c63d1645SGina Haeussge     *
299c63d1645SGina Haeussge     * @author Gina Haeussge <osd@foosel.net>
300cfef3001SGina Haeussge     */
301cfef3001SGina Haeussge    function getAttachment($id){
302c63d1645SGina Haeussge        $id = cleanID($id);
303cfef3001SGina Haeussge        if (auth_quickaclcheck(getNS($id).':*') < AUTH_READ)
304cfef3001SGina Haeussge            return new IXR_Error(1, 'You are not allowed to read this file');
305cfef3001SGina Haeussge
306cfef3001SGina Haeussge        $file = mediaFN($id);
307cfef3001SGina Haeussge        if (!@ file_exists($file))
308cfef3001SGina Haeussge            return new IXR_Error(1, 'The requested file does not exist');
309cfef3001SGina Haeussge
310cfef3001SGina Haeussge        $data = io_readFile($file, false);
311cfef3001SGina Haeussge        $base64 = base64_encode($data);
312cfef3001SGina Haeussge        return $base64;
313cfef3001SGina Haeussge    }
314cfef3001SGina Haeussge
315cfef3001SGina Haeussge    /**
3165672e868SGina Haeussge     * Return info about a media file
3175672e868SGina Haeussge     *
3185672e868SGina Haeussge     * @author Gina Haeussge <osd@foosel.net>
3195672e868SGina Haeussge     */
3205672e868SGina Haeussge    function getAttachmentInfo($id){
3215672e868SGina Haeussge        $id = cleanID($id);
3225672e868SGina Haeussge        $info = array(
3235672e868SGina Haeussge            'lastModified' => 0,
3245672e868SGina Haeussge            'size' => 0,
3255672e868SGina Haeussge        );
3265672e868SGina Haeussge
3275672e868SGina Haeussge        $file = mediaFN($id);
3285672e868SGina Haeussge        if ((auth_quickaclcheck(getNS($id).':*') >= AUTH_READ) && file_exists($file)){
3295672e868SGina Haeussge            $info['lastModified'] = new IXR_Date(filemtime($file));
3305672e868SGina Haeussge            $info['size'] = filesize($file);
3315672e868SGina Haeussge        }
3325672e868SGina Haeussge
3335672e868SGina Haeussge        return $info;
3345672e868SGina Haeussge    }
3355672e868SGina Haeussge
3365672e868SGina Haeussge    /**
337797c0d11SAndreas Gohr     * Return a wiki page rendered to html
338797c0d11SAndreas Gohr     */
339797c0d11SAndreas Gohr    function htmlPage($id,$rev=''){
340eff795acSMichael Hamann        $id = cleanID($id);
341797c0d11SAndreas Gohr        if(auth_quickaclcheck($id) < AUTH_READ){
342797c0d11SAndreas Gohr            return new IXR_Error(1, 'You are not allowed to read this page');
343797c0d11SAndreas Gohr        }
344797c0d11SAndreas Gohr        return p_wiki_xhtml($id,$rev,false);
345797c0d11SAndreas Gohr    }
346797c0d11SAndreas Gohr
347797c0d11SAndreas Gohr    /**
348797c0d11SAndreas Gohr     * List all pages - we use the indexer list here
349797c0d11SAndreas Gohr     */
350797c0d11SAndreas Gohr    function listPages(){
351dfd13e55SMichael Klier        $list  = array();
3529b41be24STom N Harris        $pages = idx_get_indexer()->getPages();
3539b41be24STom N Harris        $pages = array_filter(array_filter($pages,'isVisiblePage'),'page_exists');
354dfd13e55SMichael Klier
355dfd13e55SMichael Klier        foreach(array_keys($pages) as $idx) {
356dfd13e55SMichael Klier            $perm = auth_quickaclcheck($pages[$idx]);
357a0070b52SAdrian Lang            if($perm < AUTH_READ) {
358a0070b52SAdrian Lang                continue;
359a0070b52SAdrian Lang            }
360dfd13e55SMichael Klier            $page = array();
361dfd13e55SMichael Klier            $page['id'] = trim($pages[$idx]);
362dfd13e55SMichael Klier            $page['perms'] = $perm;
363dfd13e55SMichael Klier            $page['size'] = @filesize(wikiFN($pages[$idx]));
364e070c6f3SGina Haeussge            $page['lastModified'] = new IXR_Date(@filemtime(wikiFN($pages[$idx])));
365dfd13e55SMichael Klier            $list[] = $page;
366dfd13e55SMichael Klier        }
367dfd13e55SMichael Klier
368dfd13e55SMichael Klier        return $list;
369797c0d11SAndreas Gohr    }
370797c0d11SAndreas Gohr
371797c0d11SAndreas Gohr    /**
3721b11c097SAndreas Gohr     * List all pages in the given namespace (and below)
3731b11c097SAndreas Gohr     */
3741b11c097SAndreas Gohr    function readNamespace($ns,$opts){
3751b11c097SAndreas Gohr        global $conf;
3761b11c097SAndreas Gohr
3771b11c097SAndreas Gohr        if(!is_array($opts)) $opts=array();
3781b11c097SAndreas Gohr
3791b11c097SAndreas Gohr        $ns = cleanID($ns);
3801b11c097SAndreas Gohr        $dir = utf8_encodeFN(str_replace(':', '/', $ns));
3811b11c097SAndreas Gohr        $data = array();
3826fc3aa1aSAndreas Gohr        $opts['skipacl'] = 0; // no ACL skipping for XMLRPC
3831b11c097SAndreas Gohr        search($data, $conf['datadir'], 'search_allpages', $opts, $dir);
3841b11c097SAndreas Gohr        return $data;
3851b11c097SAndreas Gohr    }
3861b11c097SAndreas Gohr
3871b11c097SAndreas Gohr    /**
388f71f4f53SAndreas Gohr     * List all pages in the given namespace (and below)
389f71f4f53SAndreas Gohr     */
390f71f4f53SAndreas Gohr    function search($query){
391f71f4f53SAndreas Gohr        require_once(DOKU_INC.'inc/fulltext.php');
392f71f4f53SAndreas Gohr
393f71f4f53SAndreas Gohr        $regex = '';
394f71f4f53SAndreas Gohr        $data  = ft_pageSearch($query,$regex);
395f71f4f53SAndreas Gohr        $pages = array();
396f71f4f53SAndreas Gohr
397f71f4f53SAndreas Gohr        // prepare additional data
398f71f4f53SAndreas Gohr        $idx = 0;
399f71f4f53SAndreas Gohr        foreach($data as $id => $score){
400f71f4f53SAndreas Gohr            $file = wikiFN($id);
401f71f4f53SAndreas Gohr
402f71f4f53SAndreas Gohr            if($idx < FT_SNIPPET_NUMBER){
403f71f4f53SAndreas Gohr                $snippet = ft_snippet($id,$regex);
404f71f4f53SAndreas Gohr                $idx++;
405f71f4f53SAndreas Gohr            }else{
406f71f4f53SAndreas Gohr                $snippet = '';
407f71f4f53SAndreas Gohr            }
408f71f4f53SAndreas Gohr
409f71f4f53SAndreas Gohr            $pages[] = array(
410f71f4f53SAndreas Gohr                'id'      => $id,
411f71f4f53SAndreas Gohr                'score'   => $score,
412f71f4f53SAndreas Gohr                'rev'     => filemtime($file),
413f71f4f53SAndreas Gohr                'mtime'   => filemtime($file),
414f71f4f53SAndreas Gohr                'size'    => filesize($file),
415f71f4f53SAndreas Gohr                'snippet' => $snippet,
416f71f4f53SAndreas Gohr            );
417f71f4f53SAndreas Gohr        }
418ac1ffddeSGeorges-Etienne Legendre        return $pages;
419f71f4f53SAndreas Gohr    }
420f71f4f53SAndreas Gohr
421e6f4c9d4SGeorges-Etienne Legendre    /**
422e6f4c9d4SGeorges-Etienne Legendre     * Returns the wiki title.
423e6f4c9d4SGeorges-Etienne Legendre     */
424e6f4c9d4SGeorges-Etienne Legendre    function getTitle(){
425e6f4c9d4SGeorges-Etienne Legendre        global $conf;
426e6f4c9d4SGeorges-Etienne Legendre        return $conf['title'];
427e6f4c9d4SGeorges-Etienne Legendre    }
428f71f4f53SAndreas Gohr
429f71f4f53SAndreas Gohr    /**
43026bec61eSMichael Klier     * List all media files.
4313275953aSGina Haeussge     *
4323275953aSGina Haeussge     * Available options are 'recursive' for also including the subnamespaces
4333275953aSGina Haeussge     * in the listing, and 'pattern' for filtering the returned files against
4343275953aSGina Haeussge     * a regular expression matching their name.
4353275953aSGina Haeussge     *
4363275953aSGina Haeussge     * @author Gina Haeussge <osd@foosel.net>
43726bec61eSMichael Klier     */
4383275953aSGina Haeussge    function listAttachments($ns, $options = array()) {
43926bec61eSMichael Klier        global $conf;
44026bec61eSMichael Klier        global $lang;
44126bec61eSMichael Klier
44226bec61eSMichael Klier        $ns = cleanID($ns);
44326bec61eSMichael Klier
4446fc3aa1aSAndreas Gohr        if (!is_array($options)) $options = array();
4456fc3aa1aSAndreas Gohr        $options['skipacl'] = 0; // no ACL skipping for XMLRPC
4463275953aSGina Haeussge
4473275953aSGina Haeussge
44826bec61eSMichael Klier        if(auth_quickaclcheck($ns.':*') >= AUTH_READ) {
44926bec61eSMichael Klier            $dir = utf8_encodeFN(str_replace(':', '/', $ns));
45026bec61eSMichael Klier
45126bec61eSMichael Klier            $data = array();
452224122cfSAndreas Gohr            search($data, $conf['mediadir'], 'search_media', $options, $dir);
453224122cfSAndreas Gohr            $len = count($data);
454224122cfSAndreas Gohr            if(!$len) return array();
45526bec61eSMichael Klier
456224122cfSAndreas Gohr            for($i=0; $i<$len; $i++) {
457224122cfSAndreas Gohr                unset($data[$i]['meta']);
458224122cfSAndreas Gohr                $data[$i]['lastModified'] = new IXR_Date($data[$i]['mtime']);
45926bec61eSMichael Klier            }
460224122cfSAndreas Gohr            return $data;
46126bec61eSMichael Klier        } else {
46226bec61eSMichael Klier            return new IXR_Error(1, 'You are not allowed to list media files.');
46326bec61eSMichael Klier        }
46426bec61eSMichael Klier    }
46526bec61eSMichael Klier
46626bec61eSMichael Klier    /**
467797c0d11SAndreas Gohr     * Return a list of backlinks
468797c0d11SAndreas Gohr     */
469beccd742SMichael Klier    function listBackLinks($id){
47086228f10SDominik Eckelmann        return ft_backlinks(cleanID($id));
471797c0d11SAndreas Gohr    }
472797c0d11SAndreas Gohr
473797c0d11SAndreas Gohr    /**
47463dd0d58SMichael Klier     * Return some basic data about a page
475797c0d11SAndreas Gohr     */
476797c0d11SAndreas Gohr    function pageInfo($id,$rev=''){
477eff795acSMichael Hamann        $id = cleanID($id);
478797c0d11SAndreas Gohr        if(auth_quickaclcheck($id) < AUTH_READ){
479797c0d11SAndreas Gohr            return new IXR_Error(1, 'You are not allowed to read this page');
480797c0d11SAndreas Gohr        }
481797c0d11SAndreas Gohr        $file = wikiFN($id,$rev);
482797c0d11SAndreas Gohr        $time = @filemtime($file);
483797c0d11SAndreas Gohr        if(!$time){
484797c0d11SAndreas Gohr            return new IXR_Error(10, 'The requested page does not exist');
485797c0d11SAndreas Gohr        }
486797c0d11SAndreas Gohr
487797c0d11SAndreas Gohr        $info = getRevisionInfo($id, $time, 1024);
488797c0d11SAndreas Gohr
489797c0d11SAndreas Gohr        $data = array(
490797c0d11SAndreas Gohr            'name'         => $id,
491797c0d11SAndreas Gohr            'lastModified' => new IXR_Date($time),
492797c0d11SAndreas Gohr            'author'       => (($info['user']) ? $info['user'] : $info['ip']),
493797c0d11SAndreas Gohr            'version'      => $time
494797c0d11SAndreas Gohr        );
49563dd0d58SMichael Klier
49663dd0d58SMichael Klier        return ($data);
497797c0d11SAndreas Gohr    }
498797c0d11SAndreas Gohr
499797c0d11SAndreas Gohr    /**
5003a1dad2dSDennis Ploeger     * Save a wiki page
501222572bfSMichael Klier     *
502222572bfSMichael Klier     * @author Michael Klier <chi@chimeric.de>
5033a1dad2dSDennis Ploeger     */
504222572bfSMichael Klier    function putPage($id, $text, $params) {
5053a1dad2dSDennis Ploeger        global $TEXT;
506a6a229ceSMichael Klier        global $lang;
507593bf8f6SMichael Klier        global $conf;
5083a1dad2dSDennis Ploeger
509222572bfSMichael Klier        $id    = cleanID($id);
51056523eecSAndreas Gohr        $TEXT  = cleanText($text);
511222572bfSMichael Klier        $sum   = $params['sum'];
512222572bfSMichael Klier        $minor = $params['minor'];
513222572bfSMichael Klier
514222572bfSMichael Klier        if(empty($id))
515fdd2e9d6SMichael Klier            return new IXR_Error(1, 'Empty page ID');
516222572bfSMichael Klier
51756523eecSAndreas Gohr        if(!page_exists($id) && trim($TEXT) == '' ) {
51851597811SMichael Klier            return new IXR_ERROR(1, 'Refusing to write an empty new wiki page');
51951597811SMichael Klier        }
52051597811SMichael Klier
521055b0144SChris Smith        if(auth_quickaclcheck($id) < AUTH_EDIT)
522222572bfSMichael Klier            return new IXR_Error(1, 'You are not allowed to edit this page');
5233a1dad2dSDennis Ploeger
5243a1dad2dSDennis Ploeger        // Check, if page is locked
525222572bfSMichael Klier        if(checklock($id))
526222572bfSMichael Klier            return new IXR_Error(1, 'The page is currently locked');
527222572bfSMichael Klier
528a6a229ceSMichael Klier        // SPAM check
5293a1dad2dSDennis Ploeger        if(checkwordblock())
530222572bfSMichael Klier            return new IXR_Error(1, 'Positive wordblock check');
5313a1dad2dSDennis Ploeger
532a6a229ceSMichael Klier        // autoset summary on new pages
533a6a229ceSMichael Klier        if(!page_exists($id) && empty($sum)) {
534a6a229ceSMichael Klier            $sum = $lang['created'];
535a6a229ceSMichael Klier        }
536a6a229ceSMichael Klier
537a6a229ceSMichael Klier        // autoset summary on deleted pages
538a6a229ceSMichael Klier        if(page_exists($id) && empty($TEXT) && empty($sum)) {
539a6a229ceSMichael Klier            $sum = $lang['deleted'];
540a6a229ceSMichael Klier        }
541a6a229ceSMichael Klier
542222572bfSMichael Klier        lock($id);
5433a1dad2dSDennis Ploeger
544222572bfSMichael Klier        saveWikiText($id,$TEXT,$sum,$minor);
5453a1dad2dSDennis Ploeger
546222572bfSMichael Klier        unlock($id);
5473a1dad2dSDennis Ploeger
548593bf8f6SMichael Klier        // run the indexer if page wasn't indexed yet
549593bf8f6SMichael Klier        idx_addPage($id);
550593bf8f6SMichael Klier
5513a1dad2dSDennis Ploeger        return 0;
552beccd742SMichael Klier    }
5533a1dad2dSDennis Ploeger
554beccd742SMichael Klier    /**
555ba9418bcSHakan Sandell     * Appends text to a wiki page.
556ba9418bcSHakan Sandell     */
557ba9418bcSHakan Sandell    function appendPage($id, $text, $params) {
558ba9418bcSHakan Sandell        $currentpage = $this->rawPage($id);
559ba9418bcSHakan Sandell        if (!is_string($currentpage)) {
560ba9418bcSHakan Sandell            return $currentpage;
561ba9418bcSHakan Sandell        }
562ba9418bcSHakan Sandell        return $this->putPage($id, $currentpage.$text, $params);
563ba9418bcSHakan Sandell    }
564ba9418bcSHakan Sandell
565ba9418bcSHakan Sandell    /**
5662aca132fSMichael Klier     * Uploads a file to the wiki.
5672aca132fSMichael Klier     *
5682aca132fSMichael Klier     * Michael Klier <chi@chimeric.de>
5692aca132fSMichael Klier     */
570f01ff8c1SGina Haeussge    function putAttachment($id, $file, $params) {
571eff795acSMichael Hamann        $id = cleanID($id);
572f01ff8c1SGina Haeussge        $auth = auth_quickaclcheck(getNS($id).':*');
573ffb291f2SAdrian Lang
574f01ff8c1SGina Haeussge        if(!isset($id)) {
5752aca132fSMichael Klier            return new IXR_ERROR(1, 'Filename not given.');
5762aca132fSMichael Klier        }
5772aca132fSMichael Klier
578ffb291f2SAdrian Lang        global $conf;
579ffb291f2SAdrian Lang
580c77fa67bSMichael Hamann        $ftmp = $conf['tmpdir'] . '/' . md5($id.clientIP());
5812aca132fSMichael Klier
5822aca132fSMichael Klier        // save temporary file
5832aca132fSMichael Klier        @unlink($ftmp);
58480d6fbc3SAdrian Lang        if (preg_match('/^[A-Za-z0-9\+\/]*={0,2}$/', $file) === 1) {
58580d6fbc3SAdrian Lang            // DEPRECATED: Double-decode file if it still looks like base64
58680d6fbc3SAdrian Lang            // after first decoding (which is done by the library)
58780d6fbc3SAdrian Lang            $file = base64_decode($file);
58880d6fbc3SAdrian Lang        }
58980d6fbc3SAdrian Lang        io_saveFile($ftmp, $file);
5902aca132fSMichael Klier
591ffb291f2SAdrian Lang        $res = media_save(array('name' => $ftmp), $id, $params['ow'], $auth, 'rename');
592ffb291f2SAdrian Lang        if (is_array($res)) {
593ffb291f2SAdrian Lang            return new IXR_ERROR(-$res[1], $res[0]);
5942aca132fSMichael Klier        } else {
595ffb291f2SAdrian Lang            return $res;
5962aca132fSMichael Klier        }
5972aca132fSMichael Klier    }
5982aca132fSMichael Klier
5992aca132fSMichael Klier    /**
600f01ff8c1SGina Haeussge     * Deletes a file from the wiki.
601f01ff8c1SGina Haeussge     *
602f01ff8c1SGina Haeussge     * @author Gina Haeussge <osd@foosel.net>
603f01ff8c1SGina Haeussge     */
604f01ff8c1SGina Haeussge    function deleteAttachment($id){
605eff795acSMichael Hamann        $id = cleanID($id);
606f01ff8c1SGina Haeussge        $auth = auth_quickaclcheck(getNS($id).':*');
60787229c84SAdrian Lang        $res = media_delete($id, $auth);
60887229c84SAdrian Lang        if ($res & DOKU_MEDIA_DELETED) {
609f01ff8c1SGina Haeussge            return 0;
61087229c84SAdrian Lang        } elseif ($res & DOKU_MEDIA_NOT_AUTH) {
61187229c84SAdrian Lang            return new IXR_ERROR(1, "You don't have permissions to delete files.");
61287229c84SAdrian Lang        } elseif ($res & DOKU_MEDIA_INUSE) {
613f01ff8c1SGina Haeussge            return new IXR_ERROR(1, 'File is still referenced');
61499c8d7f2Smichael        } else {
61587229c84SAdrian Lang            return new IXR_ERROR(1, 'Could not delete file');
6162aca132fSMichael Klier        }
6172aca132fSMichael Klier    }
6182aca132fSMichael Klier
6192aca132fSMichael Klier    /**
620e62b9ea5SMichael Klier    * Returns the permissions of a given wiki page
621e62b9ea5SMichael Klier    */
622e62b9ea5SMichael Klier    function aclCheck($id) {
623eff795acSMichael Hamann        $id = cleanID($id);
624e62b9ea5SMichael Klier        return auth_quickaclcheck($id);
625e62b9ea5SMichael Klier    }
626e62b9ea5SMichael Klier
627e62b9ea5SMichael Klier    /**
628beccd742SMichael Klier     * Lists all links contained in a wiki page
62963dd0d58SMichael Klier     *
63063dd0d58SMichael Klier     * @author Michael Klier <chi@chimeric.de>
631beccd742SMichael Klier     */
632beccd742SMichael Klier    function listLinks($id) {
633eff795acSMichael Hamann        $id = cleanID($id);
634beccd742SMichael Klier        if(auth_quickaclcheck($id) < AUTH_READ){
635beccd742SMichael Klier            return new IXR_Error(1, 'You are not allowed to read this page');
636beccd742SMichael Klier        }
637beccd742SMichael Klier        $links = array();
638beccd742SMichael Klier
639beccd742SMichael Klier        // resolve page instructions
640eff795acSMichael Hamann        $ins   = p_cached_instructions(wikiFN($id));
641beccd742SMichael Klier
642beccd742SMichael Klier        // instantiate new Renderer - needed for interwiki links
643beccd742SMichael Klier        include(DOKU_INC.'inc/parser/xhtml.php');
644beccd742SMichael Klier        $Renderer = new Doku_Renderer_xhtml();
645beccd742SMichael Klier        $Renderer->interwiki = getInterwiki();
646beccd742SMichael Klier
647beccd742SMichael Klier        // parse parse instructions
648beccd742SMichael Klier        foreach($ins as $in) {
649beccd742SMichael Klier            $link = array();
650beccd742SMichael Klier            switch($in[0]) {
651beccd742SMichael Klier                case 'internallink':
652beccd742SMichael Klier                    $link['type'] = 'local';
653beccd742SMichael Klier                    $link['page'] = $in[1][0];
654beccd742SMichael Klier                    $link['href'] = wl($in[1][0]);
655beccd742SMichael Klier                    array_push($links,$link);
656beccd742SMichael Klier                    break;
657beccd742SMichael Klier                case 'externallink':
658beccd742SMichael Klier                    $link['type'] = 'extern';
659beccd742SMichael Klier                    $link['page'] = $in[1][0];
660beccd742SMichael Klier                    $link['href'] = $in[1][0];
661beccd742SMichael Klier                    array_push($links,$link);
662beccd742SMichael Klier                    break;
663beccd742SMichael Klier                case 'interwikilink':
664beccd742SMichael Klier                    $url = $Renderer->_resolveInterWiki($in[1][2],$in[1][3]);
665beccd742SMichael Klier                    $link['type'] = 'extern';
666beccd742SMichael Klier                    $link['page'] = $url;
667beccd742SMichael Klier                    $link['href'] = $url;
668beccd742SMichael Klier                    array_push($links,$link);
669beccd742SMichael Klier                    break;
670beccd742SMichael Klier            }
671beccd742SMichael Klier        }
672beccd742SMichael Klier
67363dd0d58SMichael Klier        return ($links);
67463dd0d58SMichael Klier    }
67563dd0d58SMichael Klier
67663dd0d58SMichael Klier    /**
67763dd0d58SMichael Klier     * Returns a list of recent changes since give timestamp
67863dd0d58SMichael Klier     *
67999c8d7f2Smichael     * @author Michael Hamann <michael@content-space.de>
68063dd0d58SMichael Klier     * @author Michael Klier <chi@chimeric.de>
68163dd0d58SMichael Klier     */
68263dd0d58SMichael Klier    function getRecentChanges($timestamp) {
68363dd0d58SMichael Klier        if(strlen($timestamp) != 10)
68463dd0d58SMichael Klier            return new IXR_Error(20, 'The provided value is not a valid timestamp');
68563dd0d58SMichael Klier
68699c8d7f2Smichael        $recents = getRecentsSince($timestamp);
68763dd0d58SMichael Klier
68899c8d7f2Smichael        $changes = array();
68963dd0d58SMichael Klier
69099c8d7f2Smichael        foreach ($recents as $recent) {
69199c8d7f2Smichael            $change = array();
69299c8d7f2Smichael            $change['name']         = $recent['id'];
69399c8d7f2Smichael            $change['lastModified'] = new IXR_Date($recent['date']);
69499c8d7f2Smichael            $change['author']       = $recent['user'];
69599c8d7f2Smichael            $change['version']      = $recent['date'];
69699c8d7f2Smichael            $change['perms']        = $recent['perms'];
69799c8d7f2Smichael            $change['size']         = @filesize(wikiFN($recent['id']));
69863dd0d58SMichael Klier            array_push($changes, $change);
69999c8d7f2Smichael        }
70099c8d7f2Smichael
70199c8d7f2Smichael        if (!empty($changes)) {
70299c8d7f2Smichael            return $changes;
70363dd0d58SMichael Klier        } else {
70463dd0d58SMichael Klier            // in case we still have nothing at this point
70563dd0d58SMichael Klier            return new IXR_Error(30, 'There are no changes in the specified timeframe');
7063a1dad2dSDennis Ploeger        }
70799c8d7f2Smichael    }
70899c8d7f2Smichael
70999c8d7f2Smichael    /**
71099c8d7f2Smichael     * Returns a list of recent media changes since give timestamp
71199c8d7f2Smichael     *
71299c8d7f2Smichael     * @author Michael Hamann <michael@content-space.de>
71399c8d7f2Smichael     * @author Michael Klier <chi@chimeric.de>
71499c8d7f2Smichael     */
71599c8d7f2Smichael    function getRecentMediaChanges($timestamp) {
71699c8d7f2Smichael        if(strlen($timestamp) != 10)
71799c8d7f2Smichael            return new IXR_Error(20, 'The provided value is not a valid timestamp');
71899c8d7f2Smichael
71999c8d7f2Smichael        $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES);
72099c8d7f2Smichael
72199c8d7f2Smichael        $changes = array();
72299c8d7f2Smichael
72399c8d7f2Smichael        foreach ($recents as $recent) {
72499c8d7f2Smichael            $change = array();
72599c8d7f2Smichael            $change['name']         = $recent['id'];
72699c8d7f2Smichael            $change['lastModified'] = new IXR_Date($recent['date']);
72799c8d7f2Smichael            $change['author']       = $recent['user'];
72899c8d7f2Smichael            $change['version']      = $recent['date'];
72999c8d7f2Smichael            $change['perms']        = $recent['perms'];
730a4da2756Smichael            $change['size']         = @filesize(mediaFN($recent['id']));
73199c8d7f2Smichael            array_push($changes, $change);
73299c8d7f2Smichael        }
73399c8d7f2Smichael
73499c8d7f2Smichael        if (!empty($changes)) {
73599c8d7f2Smichael            return $changes;
73699c8d7f2Smichael        } else {
73799c8d7f2Smichael            // in case we still have nothing at this point
73899c8d7f2Smichael            return new IXR_Error(30, 'There are no changes in the specified timeframe');
73999c8d7f2Smichael        }
74099c8d7f2Smichael    }
7413a1dad2dSDennis Ploeger
7423a1dad2dSDennis Ploeger    /**
74373056168SMichael Klier     * Returns a list of available revisions of a given wiki page
74473056168SMichael Klier     *
74573056168SMichael Klier     * @author Michael Klier <chi@chimeric.de>
74673056168SMichael Klier     */
74773056168SMichael Klier    function pageVersions($id, $first) {
748eff795acSMichael Hamann        $id = cleanID($id);
749eff795acSMichael Hamann        if(auth_quickaclcheck($id) < AUTH_READ){
750eff795acSMichael Hamann            return new IXR_Error(1, 'You are not allowed to read this page');
751eff795acSMichael Hamann        }
75273056168SMichael Klier        global $conf;
75373056168SMichael Klier
75473056168SMichael Klier        $versions = array();
75573056168SMichael Klier
75673056168SMichael Klier        if(empty($id))
75773056168SMichael Klier            return new IXR_Error(1, 'Empty page ID');
75873056168SMichael Klier
75973056168SMichael Klier        $revisions = getRevisions($id, $first, $conf['recent']+1);
76073056168SMichael Klier
76173056168SMichael Klier        if(count($revisions)==0 && $first!=0) {
76273056168SMichael Klier            $first=0;
76373056168SMichael Klier            $revisions = getRevisions($id, $first, $conf['recent']+1);
76473056168SMichael Klier        }
76573056168SMichael Klier
76645c63471SMichael Klier        if(count($revisions)>0 && $first==0) {
76745c63471SMichael Klier            array_unshift($revisions, '');  // include current revision
76845c63471SMichael Klier            array_pop($revisions);          // remove extra log entry
76945c63471SMichael Klier        }
77045c63471SMichael Klier
77173056168SMichael Klier        $hasNext = false;
77273056168SMichael Klier        if(count($revisions)>$conf['recent']) {
77373056168SMichael Klier            $hasNext = true;
77473056168SMichael Klier            array_pop($revisions); // remove extra log entry
77573056168SMichael Klier        }
77673056168SMichael Klier
77773056168SMichael Klier        if(!empty($revisions)) {
77873056168SMichael Klier            foreach($revisions as $rev) {
77973056168SMichael Klier                $file = wikiFN($id,$rev);
78073056168SMichael Klier                $time = @filemtime($file);
78145c63471SMichael Klier                // we check if the page actually exists, if this is not the
78245c63471SMichael Klier                // case this can lead to less pages being returned than
78345c63471SMichael Klier                // specified via $conf['recent']
78473056168SMichael Klier                if($time){
78573056168SMichael Klier                    $info = getRevisionInfo($id, $time, 1024);
78673056168SMichael Klier                    if(!empty($info)) {
78773056168SMichael Klier                        $data['user'] = $info['user'];
78873056168SMichael Klier                        $data['ip']   = $info['ip'];
78973056168SMichael Klier                        $data['type'] = $info['type'];
79073056168SMichael Klier                        $data['sum']  = $info['sum'];
79173056168SMichael Klier                        $data['modified'] = new IXR_Date($info['date']);
79273056168SMichael Klier                        $data['version'] = $info['date'];
79373056168SMichael Klier                        array_push($versions, $data);
79473056168SMichael Klier                    }
79573056168SMichael Klier                }
79673056168SMichael Klier            }
79773056168SMichael Klier            return $versions;
79873056168SMichael Klier        } else {
79973056168SMichael Klier            return array();
80073056168SMichael Klier        }
80173056168SMichael Klier    }
80273056168SMichael Klier
80373056168SMichael Klier    /**
804797c0d11SAndreas Gohr     * The version of Wiki RPC API supported
805797c0d11SAndreas Gohr     */
806797c0d11SAndreas Gohr    function wiki_RPCVersion(){
807797c0d11SAndreas Gohr        return 2;
808797c0d11SAndreas Gohr    }
8091b11c097SAndreas Gohr
81028ec3c76SAndreas Gohr
81128ec3c76SAndreas Gohr    /**
81228ec3c76SAndreas Gohr     * Locks or unlocks a given batch of pages
81328ec3c76SAndreas Gohr     *
81428ec3c76SAndreas Gohr     * Give an associative array with two keys: lock and unlock. Both should contain a
81528ec3c76SAndreas Gohr     * list of pages to lock or unlock
81628ec3c76SAndreas Gohr     *
81728ec3c76SAndreas Gohr     * Returns an associative array with the keys locked, lockfail, unlocked and
81828ec3c76SAndreas Gohr     * unlockfail, each containing lists of pages.
81928ec3c76SAndreas Gohr     */
82028ec3c76SAndreas Gohr    function setLocks($set){
82128ec3c76SAndreas Gohr        $locked     = array();
82228ec3c76SAndreas Gohr        $lockfail   = array();
82328ec3c76SAndreas Gohr        $unlocked   = array();
82428ec3c76SAndreas Gohr        $unlockfail = array();
82528ec3c76SAndreas Gohr
82628ec3c76SAndreas Gohr        foreach((array) $set['lock'] as $id){
827eff795acSMichael Hamann            $id = cleanID($id);
828eff795acSMichael Hamann            if(auth_quickaclcheck($id) < AUTH_EDIT || checklock($id)){
82928ec3c76SAndreas Gohr                $lockfail[] = $id;
83028ec3c76SAndreas Gohr            }else{
83128ec3c76SAndreas Gohr                lock($id);
83228ec3c76SAndreas Gohr                $locked[] = $id;
83328ec3c76SAndreas Gohr            }
83428ec3c76SAndreas Gohr        }
83528ec3c76SAndreas Gohr
83628ec3c76SAndreas Gohr        foreach((array) $set['unlock'] as $id){
837eff795acSMichael Hamann            $id = cleanID($id);
838eff795acSMichael Hamann            if(auth_quickaclcheck($id) < AUTH_EDIT || !unlock($id)){
83928ec3c76SAndreas Gohr                $unlockfail[] = $id;
840eff795acSMichael Hamann            }else{
841eff795acSMichael Hamann                $unlocked[] = $id;
84228ec3c76SAndreas Gohr            }
84328ec3c76SAndreas Gohr        }
84428ec3c76SAndreas Gohr
84528ec3c76SAndreas Gohr        return array(
84628ec3c76SAndreas Gohr            'locked'     => $locked,
84728ec3c76SAndreas Gohr            'lockfail'   => $lockfail,
84828ec3c76SAndreas Gohr            'unlocked'   => $unlocked,
84928ec3c76SAndreas Gohr            'unlockfail' => $unlockfail,
85028ec3c76SAndreas Gohr        );
85128ec3c76SAndreas Gohr    }
85228ec3c76SAndreas Gohr
853445e8084SAndreas Gohr    function getAPIVersion(){
854445e8084SAndreas Gohr        return DOKU_XMLRPC_API_VERSION;
855445e8084SAndreas Gohr    }
856445e8084SAndreas Gohr
857445e8084SAndreas Gohr    function login($user,$pass){
858445e8084SAndreas Gohr        global $conf;
859445e8084SAndreas Gohr        global $auth;
860445e8084SAndreas Gohr        if(!$conf['useacl']) return 0;
861445e8084SAndreas Gohr        if(!$auth) return 0;
862fe13bd81SAndreas Gohr
863fe13bd81SAndreas Gohr        @session_start(); // reopen session for login
864445e8084SAndreas Gohr        if($auth->canDo('external')){
865fe13bd81SAndreas Gohr            $ok = $auth->trustExternal($user,$pass,false);
866445e8084SAndreas Gohr        }else{
867fe13bd81SAndreas Gohr            $evdata = array(
868fe13bd81SAndreas Gohr                'user'     => $user,
869fe13bd81SAndreas Gohr                'password' => $pass,
870fe13bd81SAndreas Gohr                'sticky'   => false,
871fe13bd81SAndreas Gohr                'silent'   => true,
872fe13bd81SAndreas Gohr            );
873fe13bd81SAndreas Gohr            $ok = trigger_event('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper');
874445e8084SAndreas Gohr        }
875fe13bd81SAndreas Gohr        session_write_close(); // we're done with the session
876fe13bd81SAndreas Gohr
877fe13bd81SAndreas Gohr        return $ok;
878445e8084SAndreas Gohr    }
8793ee5b583SAndreas Gohr
8803ee5b583SAndreas Gohr
881797c0d11SAndreas Gohr}
882797c0d11SAndreas Gohr
883797c0d11SAndreas Gohr$server = new dokuwiki_xmlrpc_server();
884797c0d11SAndreas Gohr
885e3776c06SMichael Hamann// vim:ts=4:sw=4:et:
886