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