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