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