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