1<?php
2
3use dokuwiki\plugin\diagrams\Diagrams;
4
5/**
6 * Action component of diagrams plugin
7 *
8 * This handles operations related to mediafile based 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_mediafile extends DokuWiki_Action_Plugin
14{
15
16    /** @var helper_plugin_diagrams */
17    protected $helper;
18
19    /** @inheritDoc */
20    public function register(Doku_Event_Handler $controller)
21    {
22        // only register if mediafile mode is enabled
23        if (!($this->getConf('mode') & Diagrams::MODE_MEDIA)) return;
24
25        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleEditCheck');
26        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleNamespaceCheck');
27        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleExistsCheck');
28        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleIsDiagramCheck');
29        $controller->register_hook('MEDIA_SENDFILE', 'BEFORE', $this, 'handleCSP');
30        $controller->register_hook('PLUGIN_MOVE_HANDLERS_REGISTER', 'BEFORE', $this, 'registerMoveHandler');
31
32        $this->helper = plugin_load('helper', 'diagrams');
33    }
34
35    public function handleExistsCheck(Doku_Event $event)
36    {
37        if ($event->data !== 'plugin_diagrams_mediafile_existscheck') return;
38        $event->preventDefault();
39        $event->stopPropagation();
40
41        global $INPUT;
42        $mediaId = $INPUT->str('mediaId');
43
44        $file = mediaFN($mediaId);
45
46        echo json_encode(file_exists($file));
47    }
48
49    /**
50     * Check all supplied diagrams and return only editable diagrams
51     *
52     * @param Doku_Event $event AJAX_CALL_UNKNOWN
53     */
54    public function handleEditCheck(Doku_Event $event)
55    {
56        if ($event->data !== 'plugin_diagrams_mediafile_editcheck') return;
57        $event->preventDefault();
58        $event->stopPropagation();
59
60        global $INPUT;
61        $diagrams = (array)json_decode($INPUT->str('diagrams'));
62
63        $editable = [];
64        foreach ($diagrams as $image) {
65            $image = cleanID($image);
66            $file = mediaFN($image);
67
68            if (
69                file_exists($file) &&
70                auth_quickaclcheck($image) >= AUTH_UPLOAD &&
71                $this->helper->isDiagramFile($file)
72            ) {
73                $editable[] = $image;
74            }
75        }
76
77        echo json_encode($editable);
78    }
79
80    /**
81     * Check if the given media ID is a diagram
82     *
83     * @param Doku_Event $event AJAX_CALL_UNKNOWN
84     */
85    public function handleIsDiagramCheck(Doku_Event $event)
86    {
87        if ($event->data !== 'plugin_diagrams_mediafile_isdiagramcheck') return;
88        $event->preventDefault();
89        $event->stopPropagation();
90
91        global $INPUT;
92        $diagram = $INPUT->str('diagram');
93
94        $file = mediaFN(cleanID($diagram));
95        if (!file_exists($file)) {
96            http_status(404);
97            echo 0;
98            return;
99        }
100
101        if (!$this->helper->isDiagramFile($file)) {
102            http_status(403);
103            echo 0;
104        }
105
106        echo 1;
107    }
108
109    /**
110     * Check ACL for supplied namespace
111     *
112     * @param Doku_Event $event AJAX_CALL_UNKNOWN
113     */
114    public function handleNamespaceCheck(Doku_Event $event)
115    {
116        if ($event->data !== 'plugin_diagrams_mediafile_nscheck') return;
117        $event->preventDefault();
118        $event->stopPropagation();
119
120        global $INPUT;
121        $ns = $INPUT->str('ns');
122
123        echo json_encode(auth_quickaclcheck($ns . ':*') >= AUTH_UPLOAD);
124    }
125
126    /**
127     * Set custom CSP for SVG diagrams
128     *
129     * @param Doku_Event $event MEDIA_SENDFILE
130     */
131    public function handleCSP(Doku_Event $event)
132    {
133        if ($event->data['ext'] === 'svg' && $this->helper->isDiagramFile($event->data['file'])) {
134            $event->data['csp'] = Diagrams::CSP;
135        }
136    }
137
138    /**
139     * Registers our handler with the move plugin
140     *
141     * @param Doku_Event $event
142     * @return void
143     */
144    public function registerMoveHandler(Doku_Event $event)
145    {
146        $event->data['handlers']['diagrams_mediafile'] = [new \syntax_plugin_diagrams_mediafile(), 'handleMove'];
147    }
148}
149