xref: /plugin/diagrams/action/embed.php (revision 317bdfc2bd4bf051cf5d349bd5d8d27dc2a0b6c5)
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    /** @var helper_plugin_diagrams */
16    protected $helper;
17
18    /** @inheritDoc */
19    public function register(Doku_Event_Handler $controller)
20    {
21        // only register if embed mode is enabled
22        if (!$this->getConf('mode') & Diagrams::MODE_EMBED) return;
23
24        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleLoad');
25        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleSave');
26
27        $this->helper = plugin_load('helper', 'diagrams');
28    }
29
30    /**
31     * Load the SVG for an embedded diagram
32     *
33     * This locks the page for editing
34     *
35     * @see https://www.dokuwiki.org/devel:events:AJAX_CALL_UNKNOWN
36     * @param Doku_Event $event Event object
37     * @param mixed $param optional parameter passed when event was registered
38     * @return void
39     */
40    public function handleLoad(Doku_Event $event, $param)
41    {
42        if ($event->data !== 'plugin_diagrams_embed_load') return;
43        $event->preventDefault();
44        $event->stopPropagation();
45
46        global $INPUT;
47
48        $id = $INPUT->str('id');
49        $pos = $INPUT->int('pos');
50        $len = $INPUT->int('len');
51
52        if (auth_quickaclcheck($id) < AUTH_READ) { // FIXME should we check for EDIT perms on read as well?
53            http_status(403);
54            return;
55        }
56
57        if (!page_exists($id)) {
58            http_status(404);
59            return;
60        }
61
62        if (checklock($id)) {
63            http_status(423, 'Page Locked');
64            return;
65        }
66
67        $svg = rawWiki($id);
68        if(!$this->helper->isDiagram($svg)) {
69            http_status(400);
70            return;
71        }
72
73        lock($id); // FIXME we probably need some periodic lock renewal while editing?
74        header('Content-Type: image/svg+xml');
75        echo substr($svg, $pos, $len);
76    }
77
78    /**
79     * Save a new embedded diagram
80     *
81     * @see https://www.dokuwiki.org/devel:events:AJAX_CALL_UNKNOWN
82     * @param Doku_Event $event Event object
83     * @param mixed $param optional parameter passed when event was registered
84     * @return void
85     */
86    public function handleSave(Doku_Event $event, $param)
87    {
88        if ($event->data !== 'plugin_diagrams_embed_save') return;
89        $event->preventDefault();
90        $event->stopPropagation();
91
92        global $INPUT;
93
94        $id = $INPUT->str('id');
95        $svg = $INPUT->str('svg');
96        $pos = $INPUT->int('pos');
97        $len = $INPUT->int('len');
98
99
100        if (auth_quickaclcheck($id) < AUTH_EDIT) {
101            http_status(403);
102            return;
103        }
104
105        if (!page_exists($id)) {
106            http_status(404);
107            return;
108        }
109
110        if (!checkSecurityToken()) {
111            http_status(403);
112            return;
113        }
114
115        if (empty($svg) || substr($svg, 0, 4) !== '<svg') {
116            http_status(400);
117            return;
118        }
119
120        if(!$this->helper->isDiagram($svg)) {
121            http_status(400);
122            return;
123        }
124
125        $original = rawWiki($id);
126        $new = substr($original, 0, $pos) . $svg . substr($original, $pos + $len);
127        saveWikiText($id, $new, $this->getLang('embedSaveSummary'));
128        unlock($id);
129        echo 'OK';
130    }
131
132}
133
134