1<?php
2
3use dokuwiki\Extension\ActionPlugin;
4use dokuwiki\Extension\EventHandler;
5use dokuwiki\Extension\Event;
6
7/**
8 * DokuWiki Plugin farmer (Action Component)
9 *
10 * Manage AJAX features
11 *
12 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
13 * @author  Michael Große <grosse@cosmocode.de>
14 * @author  Andreas Gohr <gohr@cosmocode.de>
15 */
16class action_plugin_farmer_ajax extends ActionPlugin
17{
18    /**
19     * plugin should use this method to register its handlers with the DokuWiki's event controller
20     *
21     * @param EventHandler $controller DokuWiki's event controller object. Also available as global $EVENT_HANDLER
22     */
23    public function register(EventHandler $controller)
24    {
25        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxCall');
26    }
27
28    /**
29     * handle ajax requests
30     *
31     * @param Event $event
32     * @param $param
33     */
34    public function handleAjaxCall(Event $event, $param)
35    {
36        if (substr($event->data, 0, 13) !== 'plugin_farmer') {
37            return;
38        }
39        //no other ajax call handlers needed
40        $event->stopPropagation();
41        $event->preventDefault();
42
43        if (!auth_isadmin()) die('Only admins allowed');
44
45        if (substr($event->data, 14) === 'getPluginMatrix') {
46            $this->printPluginMatrix($event, $param);
47            return;
48        }
49        if (substr($event->data, 14) === 'modPlugin') {
50            $this->togglePluginState($event, $param);
51            return;
52        }
53        if (substr($event->data, 14, 10) === 'getPlugins') {
54            $this->printAnimalPlugins($event, $param);
55            return;
56        }
57        if (substr($event->data, 14, 10) === 'checkSetup') {
58            $this->checkSetup($event, $param);
59        }
60    }
61
62    /**
63     * Always return an empty response
64     *
65     * This function exists in order to provide a positive (i.e. 200) response
66     * to an ajax request to a non-existing animal.
67     *
68     * @param Event $event
69     * @param $param
70     */
71    public function checkSetup(Event $event, $param)
72    {
73        $data = '';
74        header('Content-Type: application/json');
75        json_encode($data);
76    }
77
78    /**
79     * Turn a plugin on or off
80     *
81     * @param Event $event
82     * @param $param
83     */
84    public function togglePluginState(Event $event, $param)
85    {
86        global $INPUT;
87
88        /** @var helper_plugin_farmer $helper */
89        $helper = plugin_load('helper', 'farmer');
90
91        $pname = $INPUT->str('plugin');
92        $animal = $INPUT->str('ani');
93
94
95        $plugins = $helper->getAnimalPluginRealState($animal);
96        if (!isset($plugins[$pname])) die('no such plugin');
97        $plugin = $plugins[$pname];
98
99        // figure out what to toggle to
100        if ($plugin['isdefault']) {
101            $new = (int) !$plugin['actual'];
102        } else {
103            $new = -1;
104        }
105        $helper->setPluginState($pname, $animal, $new);
106
107        // show new state
108        $plugins = $helper->getAnimalPluginRealState($animal);
109        $plugin = $plugins[$pname];
110        header('Content-Type: text/html; charset=utf-8');
111        echo $this->createPluginMatrixCell($plugin, $animal);
112    }
113
114    /**
115     * Create a matrix of all animals and plugin states
116     *
117     * @param Event $event
118     * @param $param
119     */
120    public function printPluginMatrix(Event $event, $param)
121    {
122        /** @var helper_plugin_farmer $helper */
123        $helper = plugin_load('helper', 'farmer');
124
125        $animals = $helper->getAllAnimals();
126        $plugins = $helper->getAnimalPluginRealState($animals[0]);
127
128        header('Content-Type: text/html; charset=utf-8');
129
130        echo '<div class="table pluginmatrix">';
131        echo '<table>';
132        echo '<thead>';
133        echo '<tr>';
134        echo '<th></th>';
135        foreach ($plugins as $plugin) {
136            echo '<th><div>' . hsc($plugin['name']) . '</div></th>';
137        }
138        echo '</tr>';
139        echo '</thead>';
140
141        echo '<tbody>';
142
143        echo '<tr>';
144        echo '<th>Default</th>';
145        foreach ($plugins as $plugin) {
146            echo $this->createPluginMatrixCell($plugin, $this->getLang('plugin_default'), true);
147        }
148        echo '</tr>';
149
150        foreach ($animals as $animal) {
151            $plugins = $helper->getAnimalPluginRealState($animal);
152            echo '<tr>';
153            echo '<th>' . hsc($animal) . '</th>';
154            foreach ($plugins as $plugin) {
155                echo $this->createPluginMatrixCell($plugin, $animal);
156            }
157            echo '</tr>';
158        }
159        echo '</tbody>';
160        echo '</table>';
161        echo '</div>';
162    }
163
164    /**
165     * create a single cell in the matrix
166     *
167     * @param array $plugin
168     * @param string $animal
169     * @param bool $defaults show the defaults
170     * @return string
171     */
172    protected function createPluginMatrixCell($plugin, $animal, $defaults = false)
173    {
174        if ($defaults) {
175            $current = $plugin['default'];
176            $isdefault = true;
177            $td = 'th';
178        } else {
179            $current = $plugin['actual'];
180            $isdefault = $plugin['isdefault'];
181            $td = 'td';
182        }
183
184        if ($current) {
185            $class = 'on';
186            $lbl = '✓';
187        } else {
188            $class = 'off';
189            $lbl = '✗';
190        }
191        if ($isdefault) $class .= ' default';
192
193
194        $attrs = [
195            'class' => $class,
196            'title' => $animal . ': ' . $plugin['name'],
197            'data-animal' => $animal,
198            'data-plugin' => $plugin['name']
199        ];
200        $attr = buildAttributes($attrs);
201
202        return "<$td $attr>$lbl</$td>";
203    }
204
205    /**
206     * Create an overview on all plugins for a given animal
207     *
208     * @param Event $event
209     * @param $param
210     */
211    public function printAnimalPlugins(Event $event, $param)
212    {
213        $animal = substr($event->data, 25);
214        /** @var helper_plugin_farmer $helper */
215        $helper = plugin_load('helper', 'farmer');
216
217        $plugins = $helper->getAnimalPluginRealState($animal);
218
219        header('Content-Type: text/html; charset=utf-8');
220
221        echo '<table>';
222        echo '<tr>';
223        echo '<th>' . $this->getLang('plugin') . '</th>';
224        echo '<th>' . $this->getLang('plugin_default') . '</th>';
225        echo '<th>' . $this->getLang('plugin_enabled') . '</th>';
226        echo '<th>' . $this->getLang('plugin_disabled') . '</th>';
227        echo '</tr>';
228
229        foreach ($plugins as $plugin) {
230            echo '<tr>';
231            echo '<th>' . hsc($plugin['name']) . '</th>';
232
233            echo '<td>';
234            $attr = [];
235            $attr['type'] = 'radio';
236            $attr['name'] = 'bulk_plugins[' . $plugin['name'] . ']';
237            $attr['value'] = '-1';
238            if ($plugin['isdefault']) {
239                $attr['checked'] = 'checked';
240            }
241            echo '<label>';
242            echo '<input ' . buildAttributes($attr) . ' />';
243            if ($plugin['default']) {
244                echo ' (' . $this->getLang('plugin_on') . ')';
245            } else {
246                echo ' (' . $this->getLang('plugin_off') . ')';
247            }
248            echo '</label>';
249            echo '</td>';
250
251            echo '<td>';
252            $attr = [];
253            $attr['type'] = 'radio';
254            $attr['name'] = 'bulk_plugins[' . $plugin['name'] . ']';
255            $attr['value'] = '1';
256            if (!$plugin['isdefault'] && $plugin['actual']) {
257                $attr['checked'] = 'checked';
258            }
259            echo '<label>';
260            echo '<input ' . buildAttributes($attr) . ' />';
261            echo ' ' . $this->getLang('plugin_on');
262            echo '</label>';
263            echo '</td>';
264
265            echo '<td>';
266            $attr = [];
267            $attr['type'] = 'radio';
268            $attr['name'] = 'bulk_plugins[' . $plugin['name'] . ']';
269            $attr['value'] = '0';
270            if (!$plugin['isdefault'] && !$plugin['actual']) {
271                $attr['checked'] = 'checked';
272            }
273            echo '<label>';
274            echo '<input ' . buildAttributes($attr) . ' />';
275            echo ' ' . $this->getLang('plugin_off');
276            echo '</label>';
277            echo '</td>';
278
279            echo '</tr>';
280        }
281    }
282}
283