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