1<?php 2 3 4namespace ComboStrap; 5 6 7use renderer_plugin_combo_analytics; 8 9class Mime 10{ 11 12 public const JSON = "application/json"; 13 public const HTML = "text/html"; 14 public const XHTML = "text/xhtml"; 15 const PLAIN_TEXT = "text/plain"; 16 public const SVG = "image/svg+xml"; 17 public const JAVASCRIPT = "text/javascript"; 18 const PNG = "image/png"; 19 const GIF = "image/gif"; 20 const JPEG = "image/jpeg"; 21 const BMP = "image/bmp"; 22 const WEBP = "image/webp"; 23 const CSS = "text/css"; 24 const MARKDOWN = "text/markdown"; 25 const PDF = "application/pdf"; 26 const BINARY_MIME = "application/octet-stream"; 27 public const RASTER_MIMES = [ 28 Mime::BMP, 29 Mime::WEBP, 30 Mime::JPEG, 31 Mime::GIF, 32 MIME::PNG 33 ]; 34 35 const XML = "text/xml"; 36 const INSTRUCTIONS = "text/i"; 37 const META = "text/meta"; 38 const HANDLEBARS = "text/hbs"; 39 40 /** 41 * @var array|null 42 */ 43 private static ?array $knownTypes; 44 45 /** 46 * @var string 47 */ 48 private $mime; 49 50 /** 51 * Mime constructor. 52 */ 53 public function __construct(string $mime) 54 { 55 if (trim($mime) === "") { 56 LogUtility::msg("The mime should not be an empty string"); 57 } 58 $this->mime = $mime; 59 } 60 61 public static function create(string $mime): Mime 62 { 63 return new Mime($mime); 64 } 65 66 /** 67 * @throws ExceptionNotFound 68 */ 69 public static function createFromExtension($extension): Mime 70 { 71 switch ($extension) { 72 case FetcherSvg::EXTENSION: 73 /** 74 * Svg is authorized when viewing but is not part 75 * of the {@link File::getKnownMime()} 76 */ 77 return new Mime(Mime::SVG); 78 case "js": 79 return new Mime(Mime::JAVASCRIPT); 80 case renderer_plugin_combo_analytics::RENDERER_NAME_MODE: 81 case Json::EXTENSION: 82 return new Mime(Mime::JSON); 83 case "md": 84 return new Mime(Mime::MARKDOWN); 85 case "txt": 86 return new Mime(Mime::PLAIN_TEXT); 87 case "xhtml": 88 return new Mime(Mime::XHTML); 89 case "html": 90 return new Mime(Mime::HTML); 91 case "png": 92 return new Mime(Mime::PNG); 93 case "css": 94 return new Mime(Mime::CSS); 95 case "jpg": 96 case "jpeg": 97 return new Mime(Mime::JPEG); 98 case "webp": 99 return new Mime(Mime::WEBP); 100 case "bmp": 101 return new Mime(Mime::BMP); 102 case "gif": 103 return new Mime(Mime::GIF); 104 case "pdf": 105 return new Mime(Mime::PDF); 106 case MarkupRenderer::INSTRUCTION_EXTENSION: 107 // text storage, array memory 108 return new Mime(self::INSTRUCTIONS); 109 case MarkupRenderer::METADATA_EXTENSION: 110 // text storage, array memory 111 return new Mime(self::META); 112 case TemplateEngine::EXTENSION_HBS: 113 // handlebars 114 return new Mime(self::HANDLEBARS); 115 default: 116 $mtypes = getMimeTypes(); 117 $mimeString = $mtypes[$extension] ?? null; 118 if ($mimeString === null) { 119 throw new ExceptionNotFound("No mime was found for the extension ($extension)"); 120 } else { 121 /** 122 * Delete the special dokuwiki character `!` 123 * that means that the media should be downloaded 124 */ 125 if ($mimeString[0] === "!") { 126 $mimeString = substr($mimeString, 1); 127 } 128 return new Mime($mimeString); 129 } 130 131 } 132 } 133 134 public static function getJson(): Mime 135 { 136 try { 137 return Mime::createFromExtension("json"); 138 } catch (ExceptionNotFound $e) { 139 throw new ExceptionRuntime("Json is a known extension and should not throw. Error :{$e->getMessage()}"); 140 } 141 } 142 143 public static function getHtml(): Mime 144 { 145 try { 146 return Mime::createFromExtension("html"); 147 } catch (ExceptionNotFound $e) { 148 throw new ExceptionRuntime("Html is a known extension and should not throw. Error :{$e->getMessage()}"); 149 } 150 } 151 152 public static function getText(): Mime 153 { 154 try { 155 return Mime::createFromExtension("txt"); 156 } catch (ExceptionNotFound $e) { 157 throw new ExceptionRuntime("Txt is a known extension and should not throw. Error :{$e->getMessage()}"); 158 } 159 } 160 161 public static function getBinary(): Mime 162 { 163 return new Mime(self::BINARY_MIME); 164 } 165 166 public static function getXml() 167 { 168 return new Mime(self::XML); 169 } 170 171 public function __toString() 172 { 173 return $this->mime; 174 } 175 176 public function isKnown(): bool 177 { 178 179 if (self::$knownTypes === null) { 180 self::$knownTypes = getMimeTypes(); 181 } 182 return array_search($this->mime, self::$knownTypes) !== false; 183 184 } 185 186 public function isTextBased(): bool 187 { 188 if ($this->getFirstPart() === "text") { 189 return true; 190 } 191 if (in_array($this->mime, [self::SVG, self::JSON])) { 192 return true; 193 } 194 return false; 195 } 196 197 private function getFirstPart() 198 { 199 return explode("/", $this->mime)[0]; 200 } 201 202 public function isImage(): bool 203 { 204 return substr($this->mime, 0, 5) === 'image'; 205 } 206 207 public function toString(): string 208 { 209 return $this->__toString(); 210 } 211 212 public function getExtension() 213 { 214 215 $secondPart = explode("/", $this->mime)[1]; 216 // case such as "image/svg+xml"; 217 return explode("+", $secondPart)[0]; 218 219 } 220 221 public function isSupportedRasterImage(): bool 222 { 223 return in_array($this->mime, Mime::RASTER_MIMES); 224 } 225 226 227} 228