1<?php
2    /*
3     * plugin should use this method to register its handlers
4     * with the dokuwiki's event controller
5     *
6     * 2025-06-05  axel  replace deprecated JSON object; short array syntax
7     */
8
9    if(!defined('DOKU_INC')) die();
10
11
12    class action_plugin_drawio extends DokuWiki_Action_Plugin {
13
14        public function register(Doku_Event_Handler $controller) {
15            $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'addjsinfo');
16            $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this,'_ajax_call');
17            // $controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'insert_button', array ());
18        }
19
20        // function insert_button(Doku_Event $event, $param) {
21        //     $event->data[] = array (
22        //         'type' => 'format',
23        //         'title' => $this->getLang('abutton'),
24        //         'icon' => '../../plugins/drawio/icon.png',
25        //         'open' => '<abutton>',
26        //         'close' => '',
27        //         'block' => false,
28        //     );
29        // }
30
31        /**
32         *  add drawio config options to jsinfo
33         */
34
35	    function addjsinfo($event, $params){
36            global $JSINFO;
37	        $JSINFO['plugin_drawio'] = [
38                'zIndex' => $this->getConf('zIndex'),
39                'url' => $this->getConf('url'),
40                'toolbar_possible_extension' => array_map('trim', explode(",",$this->getConf('toolbar_possible_extension')))
41            ];
42	    }
43
44        /**
45         * handle ajax requests
46         */
47        function _ajax_call(Doku_Event $event, $param) {
48            if ($event->data !== 'plugin_drawio') {
49                return;
50            }
51            //no other ajax call handlers needed
52            $event->stopPropagation();
53            $event->preventDefault();
54
55            //e.g. access additional request variables
56            global $conf, $lang;
57            global $INPUT; //available since release 2012-10-13 "Adora Belle"
58            $name = $INPUT->str('imageName');
59            $action = $INPUT->str('action');
60
61            $suffix = strpos($action, "draft_") === 0 ? '.draft':'';
62            $media_id = $name . $suffix;
63			$media_id = cleanID($media_id);
64			$fl = mediaFN($media_id);
65
66			// Get user info
67			global $USERINFO;
68			global $INPUT;
69			global $INFO;
70
71			$user = $INPUT->server->str('REMOTE_USER');
72			$groups = (array) $USERINFO['grps'];
73			$auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE);
74			$id = cleanID($name);
75
76			// Check ACL
77			$auth = auth_aclcheck($id, $user, $groups);
78			$access_granted = ($auth >= $auth_ow);
79
80			// AJAX request
81			if ($action == 'get_auth')
82            {
83				echo json_encode($access_granted);
84				return;
85            }
86						;
87			if (!$access_granted)
88				return [$lang['media_perm_upload'], 0];
89
90			io_makeFileDir($fl);
91		    if($action == 'save'){
92
93				$old = @filemtime($fl);
94				if(!file_exists(mediaFN($media_id, $old)) && file_exists($fl)) {
95					// add old revision to the attic if missing
96					media_saveOldRevision($media_id);
97				}
98				$filesize_old = file_exists($fl) ? filesize($fl) : 0;
99
100				// prepare directory
101				io_createNamespace($media_id, 'media');
102
103                // Write content to file
104                $content = $INPUT->str('content');
105                $base64data = explode(",", $content)[1];
106                //$whandle = fopen($file_path,'w');
107                $whandle = fopen($fl, 'w');
108                fwrite($whandle,base64_decode($base64data));
109                fclose($whandle);
110
111				@clearstatcache(true, $fl);
112				$new = @filemtime($fl);
113				chmod($fl, $conf['fmode']);
114
115				// Add to log
116				$filesize_new = filesize($fl);
117				$sizechange = $filesize_new - $filesize_old;
118				if ($filesize_old != 0) {
119				    addMediaLogEntry($new, $media_id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange);
120				} else {
121					addMediaLogEntry($new, $media_id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange);
122                }
123            }
124            if($action == 'get_png'){
125				if (!file_exists($fl)) return;
126                // Return image in the base64 for draw.io
127                header('Content-Type: application/json');
128                //$fc = file_get_contents($file_path);
129                $fc = file_get_contents($fl);
130				echo json_encode(["content" => "data:image/png;base64,".base64_encode($fc)]);
131            }
132            if($action == 'get_svg'){
133				if (!file_exists($fl)) return;
134                // Return image in the base64 for draw.io
135                header('Content-Type: application/json');
136                //$fc = file_get_contents($file_path);
137                $fc = file_get_contents($fl);
138				echo json_encode(["content" => "data:image/svg+xml;base64,".base64_encode($fc)]);
139            }
140
141            // Draft section
142            if($action == 'draft_save'){
143                // prepare directory
144                io_createNamespace($media_id, 'media');
145
146                // Format content of draft file
147                $content = $INPUT->str('content');
148
149                // Write content to file
150                $whandle = fopen($fl, 'w');
151                fwrite($whandle, $content);
152                fclose($whandle);
153            }
154            if($action == 'draft_rm'){
155                unlink($fl);
156            }
157            if($action == 'draft_get'){
158                header('Content-Type: application/json');
159                if (file_exists($fl)){
160                    echo file_get_contents($fl);
161                }else {
162                    echo json_encode(["content" => "NaN"]);
163                }
164            }
165        }
166    }
167