xref: /plugin/diagrams/action/action.php (revision 3039104b0d4959592824d87988b6a7f3e375dae4)
1317bdfc2SAndreas Gohr<?php
2317bdfc2SAndreas Gohr
3317bdfc2SAndreas Gohr/**
4317bdfc2SAndreas Gohr * Action component of diagrams plugin
5317bdfc2SAndreas Gohr *
659e7180eSAndreas Gohr * This handles general operations independent of the configured mode
759e7180eSAndreas Gohr *
859e7180eSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
959e7180eSAndreas Gohr * @author  Innovakom + CosmoCode <dokuwiki@cosmocode.de>
10317bdfc2SAndreas Gohr */
11317bdfc2SAndreas Gohrclass action_plugin_diagrams_action extends DokuWiki_Action_Plugin
12317bdfc2SAndreas Gohr{
132bec1a22SAndreas Gohr    /** @var helper_plugin_diagrams */
142bec1a22SAndreas Gohr    protected $helper;
15317bdfc2SAndreas Gohr
1659e7180eSAndreas Gohr    /**@inheritDoc */
17317bdfc2SAndreas Gohr    public function register(Doku_Event_Handler $controller)
18317bdfc2SAndreas Gohr    {
19317bdfc2SAndreas Gohr        $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'addJsinfo');
20317bdfc2SAndreas Gohr        $controller->register_hook('MEDIAMANAGER_STARTED', 'AFTER', $this, 'addJsinfo');
21317bdfc2SAndreas Gohr        $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'checkConf');
222bec1a22SAndreas Gohr        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleCache');
232bec1a22SAndreas Gohr
242bec1a22SAndreas Gohr        $this->helper = plugin_load('helper', 'diagrams');
25317bdfc2SAndreas Gohr    }
26317bdfc2SAndreas Gohr
27317bdfc2SAndreas Gohr    /**
2859e7180eSAndreas Gohr     * Add data to JSINFO
29317bdfc2SAndreas Gohr     *
3059e7180eSAndreas Gohr     * full service URL
3159e7180eSAndreas Gohr     * digram mode
3259e7180eSAndreas Gohr     * security token used for uploading
3359e7180eSAndreas Gohr     *
3459e7180eSAndreas Gohr     * @param Doku_Event $event DOKUWIKI_STARTED|MEDIAMANAGER_STARTED
35317bdfc2SAndreas Gohr     */
36317bdfc2SAndreas Gohr    public function addJsinfo(Doku_Event $event)
37317bdfc2SAndreas Gohr    {
38317bdfc2SAndreas Gohr        global $JSINFO;
39317bdfc2SAndreas Gohr        $JSINFO['sectok'] = getSecurityToken();
4059e7180eSAndreas Gohr        $JSINFO['plugins']['diagrams'] = [
4159e7180eSAndreas Gohr            'service_url' => $this->getConf('service_url'),
4259e7180eSAndreas Gohr            'mode' => $this->getConf('mode'),
4359e7180eSAndreas Gohr        ];
44317bdfc2SAndreas Gohr    }
45317bdfc2SAndreas Gohr
46317bdfc2SAndreas Gohr    /**
47317bdfc2SAndreas Gohr     * Check if DokuWiki is properly configured to handle SVG diagrams
48317bdfc2SAndreas Gohr     *
4959e7180eSAndreas Gohr     * @param Doku_Event $event DOKUWIKI_STARTED
50317bdfc2SAndreas Gohr     */
51317bdfc2SAndreas Gohr    public function checkConf(Doku_Event $event)
52317bdfc2SAndreas Gohr    {
53317bdfc2SAndreas Gohr        $mime = getMimeTypes();
54317bdfc2SAndreas Gohr        if (!array_key_exists('svg', $mime) || $mime['svg'] !== 'image/svg+xml') {
55317bdfc2SAndreas Gohr            msg($this->getLang('missingConfig'), -1);
56317bdfc2SAndreas Gohr        }
57317bdfc2SAndreas Gohr    }
582bec1a22SAndreas Gohr
592bec1a22SAndreas Gohr    /**
602bec1a22SAndreas Gohr     * Save the PNG cache of a diagram
612bec1a22SAndreas Gohr     *
622bec1a22SAndreas Gohr     * @param Doku_Event $event AJAX_CALL_UNKNOWN
632bec1a22SAndreas Gohr     */
642bec1a22SAndreas Gohr    public function handleCache(Doku_Event $event)
652bec1a22SAndreas Gohr    {
662bec1a22SAndreas Gohr        if ($event->data !== 'plugin_diagrams_savecache') return;
672bec1a22SAndreas Gohr        $event->preventDefault();
682bec1a22SAndreas Gohr        $event->stopPropagation();
692bec1a22SAndreas Gohr
70*3039104bSAndreas Gohr        // to not further complicate the JavaScript and because creating the PNG is essentially free,
71*3039104bSAndreas Gohr        // we always create the PNG but only save it if the cache is enabled
72*3039104bSAndreas Gohr        if (!$this->getConf('pngcache')) {
73*3039104bSAndreas Gohr            echo 'PNG cache disabled, call ignored';
74*3039104bSAndreas Gohr            return;
75*3039104bSAndreas Gohr        }
76*3039104bSAndreas Gohr
772bec1a22SAndreas Gohr        global $INPUT;
782bec1a22SAndreas Gohr
792bec1a22SAndreas Gohr        $svg = $INPUT->str('svg'); // raw svg
802bec1a22SAndreas Gohr        $png = $INPUT->str('png'); // data uri
812bec1a22SAndreas Gohr
822bec1a22SAndreas Gohr        if (!checkSecurityToken()) {
832bec1a22SAndreas Gohr            http_status(403);
842bec1a22SAndreas Gohr            return;
852bec1a22SAndreas Gohr        }
862bec1a22SAndreas Gohr
872bec1a22SAndreas Gohr        if (!$this->helper->isDiagram($svg)) {
882bec1a22SAndreas Gohr            http_status(400);
892bec1a22SAndreas Gohr            return;
902bec1a22SAndreas Gohr        }
912bec1a22SAndreas Gohr
922bec1a22SAndreas Gohr        if (!preg_match('/^data:image\/png;base64,/', $png)) {
932bec1a22SAndreas Gohr            http_status(400);
942bec1a22SAndreas Gohr            return;
952bec1a22SAndreas Gohr        }
962bec1a22SAndreas Gohr        $png = base64_decode(explode(',', $png)[1]);
972bec1a22SAndreas Gohr
982bec1a22SAndreas Gohr        if (substr($png, 1, 3) !== 'PNG') {
992bec1a22SAndreas Gohr            http_status(400);
1002bec1a22SAndreas Gohr            return;
1012bec1a22SAndreas Gohr        }
1022bec1a22SAndreas Gohr
1032bec1a22SAndreas Gohr        $cacheName = getCacheName($svg, '.diagrams.png');
1042bec1a22SAndreas Gohr        if (io_saveFile($cacheName, $png)) {
1052bec1a22SAndreas Gohr            echo 'OK';
1062bec1a22SAndreas Gohr        } else {
1072bec1a22SAndreas Gohr            http_status(500);
1082bec1a22SAndreas Gohr        }
1092bec1a22SAndreas Gohr    }
110317bdfc2SAndreas Gohr}
111