1 <?php 2 /** 3 * Copyright 1999-2017 Horde LLC (http://www.horde.org/) 4 * 5 * See the enclosed file LICENSE for license information (LGPL). If you 6 * did not receive this file, see http://www.horde.org/licenses/lgpl21. 7 * 8 * @category Horde 9 * @copyright 1999-2017 Horde LLC 10 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 11 * @package Mime 12 */ 13 14 /** 15 * Utilities to determine MIME content-types of unknown content. 16 * 17 * @author Anil Madhavapeddy <anil@recoil.org> 18 * @author Michael Slusarz <slusarz@horde.org> 19 * @category Horde 20 * @copyright 1999-2017 Horde LLC 21 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 22 * @package Mime 23 */ 24 class Horde_Mime_Magic 25 { 26 /** 27 * The MIME extension map. 28 * 29 * @var array 30 */ 31 protected static $_map = null; 32 33 /** 34 * Returns a copy of the MIME extension map. 35 * 36 * @return array The MIME extension map. 37 */ 38 protected static function _getMimeExtensionMap() 39 { 40 if (is_null(self::$_map)) { 41 require __DIR__ . '/mime.mapping.php'; 42 self::$_map = $mime_extension_map; 43 } 44 45 return self::$_map; 46 } 47 48 /** 49 * Attempt to convert a file extension to a MIME type, based 50 * on the global Horde and application specific config files. 51 * 52 * If we cannot map the file extension to a specific type, then 53 * we fall back to a custom MIME handler 'x-extension/$ext', which 54 * can be used as a normal MIME type internally throughout Horde. 55 * 56 * @param string $ext The file extension to be mapped to a MIME type. 57 * 58 * @return string The MIME type of the file extension. 59 */ 60 public static function extToMime($ext) 61 { 62 if (empty($ext)) { 63 return 'application/octet-stream'; 64 } 65 66 $ext = Horde_String::lower($ext); 67 $map = self::_getMimeExtensionMap(); 68 $pos = 0; 69 70 while (!isset($map[$ext])) { 71 if (($pos = strpos($ext, '.')) === false) { 72 break; 73 } 74 $ext = substr($ext, $pos + 1); 75 } 76 77 return isset($map[$ext]) 78 ? $map[$ext] 79 : 'x-extension/' . $ext; 80 } 81 82 /** 83 * Attempt to convert a filename to a MIME type, based on the global Horde 84 * and application specific config files. 85 * 86 * @param string $filename The filename to be mapped to a MIME type. 87 * @param boolean $unknown How should unknown extensions be handled? If 88 * true, will return 'x-extension/*' types. If 89 * false, will return 'application/octet-stream'. 90 * 91 * @return string The MIME type of the filename. 92 */ 93 public static function filenameToMime($filename, $unknown = true) 94 { 95 $pos = strlen($filename) + 1; 96 $type = ''; 97 98 $map = self::_getMimeExtensionMap(); 99 for ($i = 0; $i <= $map['__MAXPERIOD__']; ++$i) { 100 $npos = strrpos(substr($filename, 0, $pos - 1), '.'); 101 if ($npos === false) { 102 break; 103 } 104 $pos = $npos + 1; 105 } 106 107 $type = ($pos === false) ? '' : self::extToMime(substr($filename, $pos)); 108 109 return (empty($type) || (!$unknown && (strpos($type, 'x-extension') !== false))) 110 ? 'application/octet-stream' 111 : $type; 112 } 113 114 /** 115 * Attempt to convert a MIME type to a file extension, based 116 * on the global Horde and application specific config files. 117 * 118 * If we cannot map the type to a file extension, we return false. 119 * 120 * @param string $type The MIME type to be mapped to a file extension. 121 * 122 * @return string The file extension of the MIME type. 123 */ 124 public static function mimeToExt($type) 125 { 126 if (empty($type)) { 127 return false; 128 } 129 130 if (($key = array_search($type, self::_getMimeExtensionMap())) === false) { 131 list($major, $minor) = explode('/', $type); 132 if ($major == 'x-extension') { 133 return $minor; 134 } 135 if (strpos($minor, 'x-') === 0) { 136 return substr($minor, 2); 137 } 138 return false; 139 } 140 141 return $key; 142 } 143 144 /** 145 * Attempt to determine the MIME type of an unknown file. 146 * 147 * @param string $path The path to the file to analyze. 148 * @param string $magic_db Path to the mime magic database. 149 * @param array $opts Additional options: 150 * - nostrip: (boolean) Don't strip parameter information from MIME 151 * type string. 152 * DEFAULT: false 153 * 154 * @return mixed The MIME type of the file. Returns false if the file 155 * type can not be determined. 156 */ 157 public static function analyzeFile($path, $magic_db = null, 158 $opts = array()) 159 { 160 if (Horde_Util::extensionExists('fileinfo')) { 161 $res = empty($magic_db) 162 ? finfo_open(FILEINFO_MIME) 163 : finfo_open(FILEINFO_MIME, $magic_db); 164 165 if ($res) { 166 $type = trim(finfo_file($res, $path)); 167 finfo_close($res); 168 169 /* Remove any additional information. */ 170 if (empty($opts['nostrip'])) { 171 foreach (array(';', ',', '\\0') as $separator) { 172 if (($pos = strpos($type, $separator)) !== false) { 173 $type = rtrim(substr($type, 0, $pos)); 174 } 175 } 176 177 if (preg_match('|^[a-z0-9]+/[.-a-z0-9]+$|i', $type)) { 178 return $type; 179 } 180 } else { 181 return $type; 182 } 183 } 184 } 185 186 return false; 187 } 188 189 /** 190 * Attempt to determine the MIME type of an unknown byte stream. 191 * 192 * @param string $data The file data to analyze. 193 * @param string $magic_db Path to the mime magic database. 194 * @param array $opts Additional options: 195 * - nostrip: (boolean) Don't strip parameter information from MIME 196 * type string. 197 * DEFAULT: false 198 * 199 * @return mixed The MIME type of the file. Returns false if the file 200 * type can not be determined. 201 */ 202 public static function analyzeData($data, $magic_db = null, 203 $opts = array()) 204 { 205 /* If the PHP Mimetype extension is available, use that. */ 206 if (Horde_Util::extensionExists('fileinfo')) { 207 $res = empty($magic_db) 208 ? @finfo_open(FILEINFO_MIME) 209 : @finfo_open(FILEINFO_MIME, $magic_db); 210 211 if (!$res) { 212 return false; 213 } 214 215 $type = trim(finfo_buffer($res, $data)); 216 finfo_close($res); 217 218 /* Remove any additional information. */ 219 if (empty($opts['nostrip'])) { 220 if (($pos = strpos($type, ';')) !== false) { 221 $type = rtrim(substr($type, 0, $pos)); 222 } 223 224 if (($pos = strpos($type, ',')) !== false) { 225 $type = rtrim(substr($type, 0, $pos)); 226 } 227 } 228 229 return $type; 230 } 231 232 return false; 233 } 234 235 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body