xref: /plugin/diagrams/action/embed.php (revision 146e874b1a88e6d45cbffef54a860c0c8fcec462)
1<?php
2
3use dokuwiki\plugin\diagrams\Diagrams;
4
5/**
6 * DokuWiki Plugin diagrams (Action Component)
7 *
8 * This handles loading and saving embedded diagrams
9 *
10 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
11 * @author  Innovakom + CosmoCode <dokuwiki@cosmocode.de>
12 */
13class action_plugin_diagrams_embed extends \dokuwiki\Extension\ActionPlugin
14{
15
16    /** @inheritDoc */
17    public function register(Doku_Event_Handler $controller)
18    {
19        // only register if embed mode is enabled
20        if (!$this->getConf('mode') & Diagrams::MODE_EMBED) return;
21
22        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleLoad');
23        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleSave');
24    }
25
26    /**
27     * Load the SVG for an embedded diagram
28     *
29     * This locks the page for editing
30     *
31     * @see https://www.dokuwiki.org/devel:events:AJAX_CALL_UNKNOWN
32     * @param Doku_Event $event Event object
33     * @param mixed $param optional parameter passed when event was registered
34     * @return void
35     */
36    public function handleLoad(Doku_Event $event, $param)
37    {
38        if ($event->data !== 'plugin_diagrams_embed_load') return;
39        $event->preventDefault();
40        $event->stopPropagation();
41
42        global $INPUT;
43
44        $id = $INPUT->str('id');
45        $pos = $INPUT->int('pos');
46        $len = $INPUT->int('len');
47
48        if (auth_quickaclcheck($id) < AUTH_READ) { // FIXME should we check for EDIT perms on read as well?
49            http_status(403);
50            return;
51        }
52
53        if (!page_exists($id)) {
54            http_status(404);
55            return;
56        }
57
58        if (checklock($id)) {
59            http_status(423, 'Page Locked');
60            return;
61        }
62        lock($id); // FIXME we probably need some periodic lock renewal while editing?
63
64        header('Content-Type: image/svg+xml');
65        $svg = rawWiki($id);
66        echo substr($svg, $pos, $len);
67    }
68
69    /**
70     * Save a new embedded diagram
71     *
72     * @see https://www.dokuwiki.org/devel:events:AJAX_CALL_UNKNOWN
73     * @param Doku_Event $event Event object
74     * @param mixed $param optional parameter passed when event was registered
75     * @return void
76     */
77    public function handleSave(Doku_Event $event, $param)
78    {
79        if ($event->data !== 'plugin_diagrams_embed_load') return;
80        $event->preventDefault();
81        $event->stopPropagation();
82
83        global $INPUT;
84
85        $id = $INPUT->str('id');
86        $svg = $INPUT->str('svg'); // FIXME do we want to do any sanity checks on this?
87        $pos = $INPUT->int('pos');
88        $len = $INPUT->int('len');
89
90
91        if (auth_quickaclcheck($id) < AUTH_EDIT) {
92            http_status(403);
93            return;
94        }
95
96        if (!page_exists($id)) {
97            http_status(404);
98            return;
99        }
100
101        if (!checkSecurityToken()) {
102            http_status(403);
103            return;
104        }
105
106        if (empty($svg) || substr($svg, 0, 4) !== '<svg') {
107            http_status(400);
108            return;
109        }
110
111        $original = rawWiki($id);
112        $new = substr($original, 0, $pos) . $svg . substr($original, $pos + $len);
113        saveWikiText($id, $new, $this->getLang('embedSaveSummary'));
114        unlock($id);
115        echo 'OK';
116    }
117
118}
119
120