xref: /plugin/diagrams/action/action.php (revision 3039104b0d4959592824d87988b6a7f3e375dae4)
1<?php
2
3/**
4 * Action component of diagrams plugin
5 *
6 * This handles general operations independent of the configured mode
7 *
8 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
9 * @author  Innovakom + CosmoCode <dokuwiki@cosmocode.de>
10 */
11class action_plugin_diagrams_action extends DokuWiki_Action_Plugin
12{
13    /** @var helper_plugin_diagrams */
14    protected $helper;
15
16    /**@inheritDoc */
17    public function register(Doku_Event_Handler $controller)
18    {
19        $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'addJsinfo');
20        $controller->register_hook('MEDIAMANAGER_STARTED', 'AFTER', $this, 'addJsinfo');
21        $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'checkConf');
22        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleCache');
23
24        $this->helper = plugin_load('helper', 'diagrams');
25    }
26
27    /**
28     * Add data to JSINFO
29     *
30     * full service URL
31     * digram mode
32     * security token used for uploading
33     *
34     * @param Doku_Event $event DOKUWIKI_STARTED|MEDIAMANAGER_STARTED
35     */
36    public function addJsinfo(Doku_Event $event)
37    {
38        global $JSINFO;
39        $JSINFO['sectok'] = getSecurityToken();
40        $JSINFO['plugins']['diagrams'] = [
41            'service_url' => $this->getConf('service_url'),
42            'mode' => $this->getConf('mode'),
43        ];
44    }
45
46    /**
47     * Check if DokuWiki is properly configured to handle SVG diagrams
48     *
49     * @param Doku_Event $event DOKUWIKI_STARTED
50     */
51    public function checkConf(Doku_Event $event)
52    {
53        $mime = getMimeTypes();
54        if (!array_key_exists('svg', $mime) || $mime['svg'] !== 'image/svg+xml') {
55            msg($this->getLang('missingConfig'), -1);
56        }
57    }
58
59    /**
60     * Save the PNG cache of a diagram
61     *
62     * @param Doku_Event $event AJAX_CALL_UNKNOWN
63     */
64    public function handleCache(Doku_Event $event)
65    {
66        if ($event->data !== 'plugin_diagrams_savecache') return;
67        $event->preventDefault();
68        $event->stopPropagation();
69
70        // to not further complicate the JavaScript and because creating the PNG is essentially free,
71        // we always create the PNG but only save it if the cache is enabled
72        if (!$this->getConf('pngcache')) {
73            echo 'PNG cache disabled, call ignored';
74            return;
75        }
76
77        global $INPUT;
78
79        $svg = $INPUT->str('svg'); // raw svg
80        $png = $INPUT->str('png'); // data uri
81
82        if (!checkSecurityToken()) {
83            http_status(403);
84            return;
85        }
86
87        if (!$this->helper->isDiagram($svg)) {
88            http_status(400);
89            return;
90        }
91
92        if (!preg_match('/^data:image\/png;base64,/', $png)) {
93            http_status(400);
94            return;
95        }
96        $png = base64_decode(explode(',', $png)[1]);
97
98        if (substr($png, 1, 3) !== 'PNG') {
99            http_status(400);
100            return;
101        }
102
103        $cacheName = getCacheName($svg, '.diagrams.png');
104        if (io_saveFile($cacheName, $png)) {
105            echo 'OK';
106        } else {
107            http_status(500);
108        }
109    }
110}
111