xref: /plugin/combo/action/svg.php (revision c3437056399326d621a01da73b649707fbb0ae69)
1<?php
2
3
4require_once(__DIR__ . '/../ComboStrap/PluginUtility.php');
5
6use ComboStrap\Dimension;
7use ComboStrap\Identity;
8use ComboStrap\CacheMedia;
9use ComboStrap\DokuPath;
10use ComboStrap\ImageSvg;
11use ComboStrap\MediaLink;
12use ComboStrap\LogUtility;
13use ComboStrap\PluginUtility;
14use ComboStrap\Resources;
15use ComboStrap\SvgImageLink;
16use ComboStrap\TagAttributes;
17
18if (!defined('DOKU_INC')) exit;
19if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
20
21/**
22 * Class action_plugin_combo_svg
23 * Returned an svg optimized version
24 */
25class action_plugin_combo_svg extends DokuWiki_Action_Plugin
26{
27
28
29    const CONF_SVG_UPLOAD_GROUP_NAME = "svgUploadGroupName";
30
31    public function register(Doku_Event_Handler $controller)
32    {
33
34        $controller->register_hook('FETCH_MEDIA_STATUS', 'BEFORE', $this, 'svg_optimization');
35
36
37        /**
38         * Hack the upload is done via the ajax.php file
39         * {@link media_upload()}
40         */
41        $controller->register_hook('AUTH_ACL_CHECK', 'BEFORE', $this, 'svg_mime');
42
43        /**
44         * When the parsing of a page starts
45         */
46        $controller->register_hook('PARSER_WIKITEXT_PREPROCESS', 'BEFORE', $this, 'svg_mime');
47
48    }
49
50    /**
51     * @param Doku_Event $event
52     * https://www.dokuwiki.org/devel:event:fetch_media_status
53     */
54    public function svg_optimization(Doku_Event &$event)
55    {
56
57        if ($event->data['ext'] != 'svg') return;
58        if ($event->data['status'] >= 400) return; // ACLs and precondition checks
59
60
61        $tagAttributes = TagAttributes::createEmpty(ImageSvg::CANONICAL);
62        $width = $event->data['width'];
63        if ($width != 0) {
64            $tagAttributes->addComponentAttributeValue(Dimension::WIDTH_KEY, $width);
65        }
66        $height = $event->data['height'];
67        if ($height != 0) {
68            $tagAttributes->addComponentAttributeValue(Dimension::HEIGHT_KEY, $height);
69        }
70        $tagAttributes->addComponentAttributeValue(CacheMedia::CACHE_KEY, $event->data['cache']);
71
72        $mime = "image/svg+xml";
73        $event->data["mime"] = $mime;
74        $tagAttributes->setMime($mime);
75
76        /**
77         * Add the extra attributes
78         */
79        $rev = null;
80        foreach ($_REQUEST as $name => $value) {
81            switch ($name) {
82                case "media":
83                case "w":
84                case "h":
85                case "cache":
86                case CacheMedia::CACHE_BUSTER_KEY:
87                case "tok": // A checker
88                    // Nothing to do, we take them
89                    break;
90                case "rev":
91                    $rev = $value;
92                    break;
93                case "u":
94                case "p":
95                case "http_credentials":
96                    // Credentials data
97                    break;
98                default:
99                    if (!empty($value)) {
100                        if (!in_array(strtolower($name), MediaLink::NON_URL_ATTRIBUTES)) {
101                            $tagAttributes->addComponentAttributeValue($name, $value);
102                        } else {
103                            LogUtility::msg("The attribute ($name) is not a valid fetch image URL attribute and was not added", LogUtility::LVL_MSG_WARNING, SvgImageLink::CANONICAL);
104                        }
105                    } else {
106                        LogUtility::msg("Internal Error: the value of the query name ($name) is empty", LogUtility::LVL_MSG_WARNING, SvgImageLink::CANONICAL);
107                    }
108            }
109        }
110
111
112        $id = $event->data["media"];
113
114        $dokuPath = DokuPath::createMediaPathFromId($id,$rev);
115
116        $svgImage = new ImageSvg($dokuPath,  $tagAttributes);
117        try {
118            $event->data['file'] =  $svgImage->getSvgFile()->toAbsolutePath()->toString();
119        } catch (RuntimeException $e) {
120
121            $event->data['file'] = PluginUtility::getResourceBaseUrl()."/images/error-bad-format.svg";
122            $event->data['status'] = 422;
123
124        }
125
126
127    }
128
129    /**
130     * @param Doku_Event $event
131     * {@link media_save} is checking the authorized mime type
132     * Svg is not by default, we add it here if the user is admin or
133     * in a specified group
134     */
135    public function svg_mime(Doku_Event &$event)
136    {
137
138        self::allowSvgIfAuthorized();
139
140    }
141
142    /**
143     *
144     */
145    public static function allowSvgIfAuthorized()
146    {
147        $isAdmin = Identity::isAdmin();
148        $isMember = Identity::isMember("@" . self::CONF_SVG_UPLOAD_GROUP_NAME);
149
150        if ($isAdmin || $isMember) {
151            /**
152             * Enhance the svg mime type
153             * {@link getMimeTypes()}
154             */
155            global $config_cascade;
156            $svgMimeConf = Resources::getConfResourceDirectory() . "/svg.mime.conf";
157            $config_cascade['mime']['local'][] = $svgMimeConf;
158        }
159
160    }
161
162
163}
164