Overview

Packages

  • Mime

Classes

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