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