1<?php
2
3if (!defined('DOKU_INC')) die();
4
5/**
6 * Class action_plugin_api
7 * Implements a rest api wrapper around XML rpc
8 *
9 * https://www.dokuwiki.org/devel:xmlrpc
10 *
11 * Test:
12 * http://localhost:81/lib/exe/ajax.php?call=api
13 *
14 * @see RemoteAPI for the entry point
15 * @see RemoteAPICore for the implementation of each functions
16 */
17class  action_plugin_api extends DokuWiki_Action_Plugin
18{
19
20    const PLUGIN_NAME = 'api';
21
22    function register(Doku_Event_Handler $controller)
23    {
24        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, '_ajax_call');
25    }
26
27    /**
28     * handle ajax requests
29     * @param $event Doku_Event
30     */
31    function _ajax_call(&$event)
32    {
33        $info = confToHash(__DIR__ . '/plugin.info.txt');
34
35        if ($event->data !== self::getPluginName()) {
36            return;
37        }
38        //no other ajax call handlers needed
39        $event->stopPropagation();
40        $event->preventDefault();
41
42        global $conf;
43        $conf['remote'] = true;
44        $conf['remoteuser'] = '@ALL';
45        $response_code = 200;
46
47        global $INPUT;
48        $fn = $INPUT->str('fn');
49
50        $remote = new RemoteAPI();
51        switch ($fn) {
52            case '':
53                $data = array(
54                    "api" => self::PLUGIN_NAME,
55                    "version" => $info['date']
56                );
57                break;
58            case 'version':
59                $wikiVersion = $remote->call('dokuwiki.getVersion');
60                $rpcVersion = $remote->call('wiki.getRPCVersionSupported');
61                $pluginApiVersion = $info['date'];
62                $data = array(
63                    'wiki' => $wikiVersion,
64                    self::PLUGIN_NAME => $pluginApiVersion,
65                    'rpc' => $rpcVersion,
66                );
67                break;
68            case 'wiki':
69                $wikiTitle = $remote->call('dokuwiki.getTitle');
70                $wikiVersion = $remote->call('dokuwiki.getVersion');
71                $data = array(
72                    'version' => $wikiVersion,
73                    'title' => $wikiTitle,
74                );
75                break;
76            case 'pages':
77                $allPages = $remote->call('wiki.getAllPages');
78                $data = array();
79                $limit = $INPUT->str('limit');
80                if (!$limit){
81                    $limit = PHP_INT_MAX;
82                }
83                foreach ($allPages as $key => $pages) {
84                    $pageData = array();
85                    $pageData['id'] = $pages['id'];
86                    $pageData['title'] = tpl_pagetitle($pages['id'], true);
87                    $data[] = $pageData;
88                    if ($key >= $limit - 1) {
89                        break;
90                    }
91                }
92                break;
93            case 'page':
94                $id = $INPUT->str('id');
95                if ($id == '') {
96                    $response_code = 400;
97                    $data = array(
98                        'error' => 'The id query parameters is mandatory when asking data of a page'
99                    );
100                    break;
101                }
102                $data['title'] = tpl_pagetitle($id, true);
103                $data['html'] = $remote->call('wiki.getPageHTML', array("pagename" => $id));
104                $data['backlinks'] = $remote->call('wiki.getBackLinks', array("pagename" => $id));
105                $allLinks = $remote->call('wiki.listLinks', array("pagename" => $id));
106                $links = array();
107                $externalLinks = array();
108                foreach ($allLinks as $link) {
109                    if ($link['type'] == 'local') {
110                        $links[] = $link['page'];
111                    } else {
112                        $externalLinks[] = $link['href'];
113                    }
114                }
115                $data['links'] = $links;
116                $data['external_links'] = $externalLinks;
117                break;
118            default:
119                $data = 'Function (' . $fn . ') was not found';
120                $response_code = 404;
121        }
122
123
124        // Return
125        require_once DOKU_INC . 'inc/JSON.php';
126        $json = new JSON();
127        header('Content-Type: application/json');
128        http_response_code($response_code);
129        if ($_GET["callback"]) {
130            echo $_GET["callback"] . "(" . $json->encode($data) . ")";
131        } else {
132            echo $json->encode($data);
133        }
134    }
135
136
137}