diff --git a/includes/mime_detect.inc b/includes/mime_detect.inc index 0914f62b..5c4fe681 100644 --- a/includes/mime_detect.inc +++ b/includes/mime_detect.inc @@ -1,369 +1,135 @@ mime). - * While I don't have a specific use case for a mime->extension lookup, I think - * it's good to have in here. - * - * Drupal 7 will have better mime handlers. See: - * http://api.drupal.org/api/function/file_default_mimetype_mapping/7 + * A nice added bonus is that this new class will put a note in watchdog when + * it encounters a filetype it doesnt know. */ class MimeDetect { - protected $protectedMimeTypes = array( - /* - * This is a shortlist of mimetypes which should catch most - * mimetype<-->extension lookups in the context of Islandora collections. - * - * It has been cut from a much longer list. - * - * Two types of mimetypes should be put in this list: - * 1) Special emerging formats which may not yet be expressed in the system - * mime.types file. - * 2) Heavily used mimetypes of particular importance to the Islandora - * project, as lookups against this list will be quicker and less - * resource intensive than other methods. - * - * Lookups are first checked against this short list. If no results are - * found, then the lookup function may move on to check other sources, - * namely the system's mime.types file. - * - * In most cases though, this short list should suffice. - * - * If modifying this list, please note that for promiscuous mimetypes - * (those which map to multiple extensions, such as text/plain) - * The function get_extension will always return the *LAST* extension in - * this list, so you should put your preferred extension *LAST*. - * - * e.g... - * "jpeg" => "image/jpeg", - * "jpe" => "image/jpeg", - * "jpg" => "image/jpeg", - * - * $this->get_extension('image/jpeg') will always return 'jpg'. - * - */ - // Openoffice: - 'odb' => 'application/vnd.oasis.opendocument.database', - 'odc' => 'application/vnd.oasis.opendocument.chart', - 'odf' => 'application/vnd.oasis.opendocument.formula', - 'odg' => 'application/vnd.oasis.opendocument.graphics', - 'odi' => 'application/vnd.oasis.opendocument.image', - 'odm' => 'application/vnd.oasis.opendocument.text-master', - 'odp' => 'application/vnd.oasis.opendocument.presentation', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', - 'odt' => 'application/vnd.oasis.opendocument.text', - 'otg' => 'application/vnd.oasis.opendocument.graphics-template', - 'oth' => 'application/vnd.oasis.opendocument.text-web', - 'otp' => 'application/vnd.oasis.opendocument.presentation-template', - 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', - 'ott' => 'application/vnd.oasis.opendocument.text-template', - // Staroffice: - 'stc' => 'application/vnd.sun.xml.calc.template', - 'std' => 'application/vnd.sun.xml.draw.template', - 'sti' => 'application/vnd.sun.xml.impress.template', - 'stw' => 'application/vnd.sun.xml.writer.template', - 'sxc' => 'application/vnd.sun.xml.calc', - 'sxd' => 'application/vnd.sun.xml.draw', - 'sxg' => 'application/vnd.sun.xml.writer.global', - 'sxi' => 'application/vnd.sun.xml.impress', - 'sxm' => 'application/vnd.sun.xml.math', - 'sxw' => 'application/vnd.sun.xml.writer', - // K-office: - 'kil' => 'application/x-killustrator', - 'kpt' => 'application/x-kpresenter', - 'kpr' => 'application/x-kpresenter', - 'ksp' => 'application/x-kspread', - 'kwt' => 'application/x-kword', - 'kwd' => 'application/x-kword', - // Ms office 97: - 'doc' => 'application/msword', - 'xls' => 'application/vnd.ms-excel', - 'ppt' => 'application/vnd.ms-powerpoint', - // Office2007: - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'docm' => 'application/vnd.ms-word.document.macroEnabled.12', - 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', - 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', - 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', - 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', - 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', - 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', - 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', - 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', - 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', - 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', - 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', - 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', - 'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12', - // Wordperfect (who cares?): - 'wpd' => 'application/wordperfect', - // Common and generic containers: - 'pdf' => 'application/pdf', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - 'rtf' => 'text/rtf', - 'rtx' => 'text/richtext', - 'latex' => 'application/x-latex', - 'tex' => 'application/x-tex', - 'texi' => 'application/x-texinfo', - 'texinfo' => 'application/x-texinfo', - // *ml: - 'css' => 'text/css', - 'htm' => 'text/html', - 'html' => 'text/html', - 'wbxml' => 'application/vnd.wap.wbxml', - 'xht' => 'application/xhtml+xml', - 'xhtml' => 'application/xhtml+xml', - 'xsl' => 'text/xml', - 'xml' => 'text/xml', - 'csv' => 'text/csv', - 'tsv' => 'text/tab-separated-values', - 'txt' => 'text/plain', - // images: - "bmp" => "image/bmp", - 'dng' => 'image/x-adobe-dng', - "gif" => "image/gif", - "ief" => "image/ief", - "jpeg" => "image/jpeg", - "jpe" => "image/jpeg", - "jpg" => "image/jpeg", - "jp2" => "image/jp2", - "png" => "image/png", - "tiff" => "image/tiff", - "tif" => "image/tif", - "djvu" => "image/vnd.djvu", - "djv" => "image/vnd.djvu", - "wbmp" => "image/vnd.wap.wbmp", - "ras" => "image/x-cmu-raster", - "pnm" => "image/x-portable-anymap", - "pbm" => "image/x-portable-bitmap", - "pgm" => "image/x-portable-graymap", - "ppm" => "image/x-portable-pixmap", - "rgb" => "image/x-rgb", - "xbm" => "image/x-xbitmap", - "xpm" => "image/x-xpixmap", - "xwd" => "image/x-windowdump", - // videos: - "mpeg" => "video/mpeg", - "mpe" => "video/mpeg", - "mpg" => "video/mpeg", - "m4v" => "video/mp4", - "mp4" => "video/mp4", - "ogv" => "video/ogg", - "qt" => "video/quicktime", - "mov" => "video/quicktime", - "mxu" => "video/vnd.mpegurl", - "avi" => "video/x-msvideo", - "movie" => "video/x-sgi-movie", - "flv" => "video/x-flv", - "swf" => "application/x-shockwave-flash", - // Audio: - "mp3" => "audio/mpeg", - "mp4a" => "audio/mp4", - "m4a" => "audio/mp4", - "oga" => "audio/ogg", - "ogg" => "audio/ogg", - "flac" => "audio/x-flac", - "wav" => "audio/vnd.wave", - // Compressed formats: - // (note: http://svn.cleancode.org/svn/email/trunk/mime.types) - "tgz" => "application/x-gzip", - "gz" => "application/x-gzip", - "tar" => "application/x-tar", - "gtar" => "application/x-gtar", - "zip" => "application/x-zip", - // others: - 'bin' => 'application/octet-stream', - ); - protected $protectedFileExtensions; - protected $systemTypes; - protected $systemExts; - protected $etcMimeTypes = '/etc/mime.types'; + const DEFAULT_MIMETYPE = 'application/octet-stream'; + const DEFAULT_EXTENSION = 'bin'; + + protected $mimeTypes; + protected $extTypes; /** * Construtor. */ public function __construct() { + // Mimetype list returned as a double assoc array with two entries: + // Mimetypes: Integer array of mimetypes + // Extensions: Assoc array of extensions + // + // Extension array can be used as a key to get mimetypes + // Example if $extensions['png'] == 5, then + // $mimetypes[5] = 'image/png' + // We want to combine this into 1 array for easy access. + $temp = file_mimetype_mapping(); + + $temp_mime_types = $temp['mimetypes']; + $temp_mime_ext = $temp['extensions']; + + // Free the memory in temp since we don't need it anymore. + unset($temp); + + // Combine the two arrays into one. + foreach ($temp_mime_ext as $key => $val) { + $this->mime_types[$key] = $temp_mime_types[$val]; + } - // Populate the reverse shortlist: - $this->protectedFileExtensions = array_flip($this->protectedMimeTypes); + // Flip the mime_type array to make the ext array. + $this->ext_types = array_flip($this->mime_types); + } - // Pick up a local mime.types file if it is available. - if (is_readable('mime.types')) { - $this->etcMimeTypes = 'mime.types'; - } + /** + * For backwards-compatibility with our old mimetype class. + * + * @param string $filename + * Filename to convert to mimetype. + * + * @return data + * Returns a string with the mimetype for the file. + */ + public function getType($filename) { + return $this->getMimetype($filename); } /** - * Gets MIME type associated with the give file's extension. + * Returns a mimetype associated with the file extension of $filename. * * @param string $filename - * The filename - * @param bool $debug - * Returns a debug array. + * The filename we want the mime type of. * - * @return mixed - * string or an array + * @param bool $debug + * Enable or disable debug output mode. + * + * @return string + * Mimetype associated with the file extension of $filename. */ public function getMimetype($filename, $debug = FALSE) { + // The file extension will be the last index in the exploded string. + $ext = @end(explode('.', $filename)); + $ext = strtolower($ext); - $file_name_and_extension = explode('.', $filename); - $ext = drupal_strtolower(array_pop($file_name_and_extension)); - - if (!empty($this->protectedMimeTypes[$ext])) { + // Check the array for a predetermined mime type. + // If type not found, add a warning to watchdog. + if (!empty($this->mime_types[$ext])) { if (TRUE === $debug) { - return array('mime_type' => $this->protectedMimeTypes[$ext], 'method' => 'from_array'); - } - return $this->protectedMimeTypes[$ext]; - } - - if (function_exists('file_get_mimetype')) { - $drupal_mimetype = file_get_mimetype($filename); - if ('application/octet-stream' != $drupal_mimetype) { - if (TRUE == $debug) { - return array('mime_type' => $drupal_mimetype, 'method' => 'file_get_mimetype'); - } - return $drupal_mimetype; + $return_type = $this->mime_types[$ext]; + return array('mime_type' => $return_type, 'method' => 'from_array'); } - } - if (!isset($this->systemTypes)) { - $this->systemTypes = $this->systemExtensionMimetypes(); + return $this->mime_types[$ext]; } - if (isset($this->systemTypes[$ext])) { - if (TRUE == $debug) { - return array('mime_type' => $this->systemTypes[$ext], 'method' => 'mime.types'); - } - return $this->systemTypes[$ext]; + else { + // This file was not in the drupal mime system. + // Add a line to the watchdog informing us of this incident. + $err_msg = 'Found a file extension not covered in the drupal mime func:'; + watchdog('MimeClass', $err_msg . $ext); } - if (TRUE === $debug) { + // By default return application octet stream. + if (TRUE == $debug) { return array('mime_type' => 'application/octet-stream', 'method' => 'last_resort'); } + return 'application/octet-stream'; } /** - * Gets one valid file extension for a given MIME type. + * Returns *one* valid file extension for a given $mime_type. + * + * @param string $type + * String containing the mimetype * - * @param string $mime_type - * The MIME type. * @param bool $debug - * Generated debug information? + * Toggle debug mode on/off * * @return string - * The file extensions associated with the given MIME type. + * Return the file extension */ - public function getExtension($mime_type, $debug = FALSE) { + public function getExtension($type, $debug = FALSE) { - if (!empty($this->protectedFileExtensions[$mime_type])) { + if (!empty($this->ext_types[$type])) { if (TRUE == $debug) { - return array('extension' => $this->protectedFileExtensions[$mime_type], 'method' => 'from_array'); + return array('extension' => $this->ext_types[$type], 'method' => 'from_array'); } - return $this->protectedFileExtensions[$mime_type]; - } - - if (!isset($this->systemExts)) { - $this->systemExts = $this->systemMimetypeExtensions(); + return $this->ext_types[$type]; } - if (isset($this->systemExts[$mime_type])) { + else { + // Return bin by default. This could cause errors. + // Function should return false or -1 or something to be handled. + // Client side. if (TRUE == $debug) { - return array('extension' => $this->systemExts[$mime_type], 'method' => 'mime.types'); - } - return $this->systemExts[$mime_type]; - } - - if (TRUE == $debug) { - return array('extension' => 'bin', 'method' => 'last_resort'); - } - return 'bin'; - } - - /** - * Gets an associative array of MIME type and extension associations. - * - * Users the system mime.types file, or a local mime.types if one is found - * @see MIMEDetect::__constuctor() - * - * @return array - * An associative array where the keys are MIME types and the values - * extensions. - */ - protected function systemMimetypeExtensions() { - $out = array(); - if (file_exists($this->etcMimeTypes)) { - $file = fopen($this->etcMimeTypes, 'r'); - while (($line = fgets($file)) !== FALSE) { - $line = trim(preg_replace('/#.*/', '', $line)); - if (!$line) { - continue; - } - $parts = preg_split('/\s+/', $line); - if (count($parts) == 1) { - continue; - } - // A single part means a mimetype without extensions, which we ignore. - $type = array_shift($parts); - if (!isset($out[$type])) { - $out[$type] = array_shift($parts); - } - // We take the first ext from the line if many are present. - } - fclose($file); - } - return $out; - } - - /** - * Gets a associative array of extensions and MIME types. - * - * Users the system mime.types file, or a local mime.types if one is found - * @see MIMEDetect::__constuctor() - * - * @return array - * An associative array where the keys are extensions and the values - * MIME types. - */ - protected function systemExtensionMimetypes() { - $out = array(); - if (file_exists($this->etcMimeTypes)) { - $file = fopen($this->etcMimeTypes, 'r'); - while (($line = fgets($file)) !== FALSE) { - $line = trim(preg_replace('/#.*/', '', $line)); - if (!$line) { - continue; - } - $parts = preg_split('/\s+/', $line); - if (count($parts) == 1) { - continue; - } - // A single part means a mimetype without extensions, which we ignore. - $type = array_shift($parts); - foreach ($parts as $part) { - $out[$part] = $type; - } + return array('extension' => 'bin', 'method' => 'last_resort'); } - fclose($file); + return 'bin'; } - return $out; } } diff --git a/islandora.info b/islandora.info index 54f62c05..8b3b9a8e 100644 --- a/islandora.info +++ b/islandora.info @@ -15,4 +15,5 @@ files[] = tests/islandora_web_test_case.inc files[] = tests/authtokens.test files[] = tests/hooks.test files[] = tests/islandora_manage_permissions.test +files[] = tests/MimeClass.test php = 5.3 diff --git a/tests/MimeClass.test b/tests/MimeClass.test new file mode 100644 index 00000000..b76ca5da --- /dev/null +++ b/tests/MimeClass.test @@ -0,0 +1,405 @@ + 'MimeDetect Test', + 'description' => 'Ensure that the class MimeDetect works as expected', + 'group' => 'Islandora', + ); + } + + /** + * Call the parent setup function for the test. + */ + public function setUp() { + parent::setUp(array('islandora')); + } + + /** + * Test all mime and extension types. + */ + public function testMimeTypes() { + // Create a mime array to assert against the MimeDetect Class. + $mime_type_list = array( + 'ez' => 'application/andrew-inset' , + 'atom' => 'application/atom' , + 'atomcat' => 'application/atomcat+xml' , + 'atomsrv' => 'application/atomserv+xml' , + 'pcap' => 'application/cap' , + 'cu' => 'application/cu-seeme' , + 'tsp' => 'application/dsptype' , + 'hta' => 'application/hta' , + 'jar' => 'application/java-archive' , + 'ser' => 'application/java-serialized-object' , + 'class' => 'application/java-vm' , + 'hqx' => 'application/mac-binhex40' , + 'nb' => 'application/mathematica' , + 'mdb' => 'application/msaccess' , + 'doc' => 'application/msword' , + 'bin' => 'application/octet-stream' , + 'oda' => 'application/oda' , + 'ogx' => 'application/ogg' , + 'pdf' => 'application/pdf' , + 'key' => 'application/pgp-keys' , + 'pgp' => 'application/pgp-signature' , + 'prf' => 'application/pics-rules' , + 'ps' => 'application/postscript' , + 'rar' => 'application/rar' , + 'rdf' => 'application/rdf+xml' , + 'rss' => 'application/rss+xml' , + 'rtf' => 'application/rtf' , + 'smil' => 'application/smil' , + 'cdy' => 'application/vnd.cinderella' , + 'kml' => 'application/vnd.google-earth.kml+xml' , + 'kmz' => 'application/vnd.google-earth.kmz' , + 'xul' => 'application/vnd.mozilla.xul+xml' , + 'xls' => 'application/vnd.ms-excel' , + 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12' , + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12' , + 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12' , + 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12' , + 'cat' => 'application/vnd.ms-pki.seccat' , + 'stl' => 'application/vnd.ms-pki.stl' , + 'ppt' => 'application/vnd.ms-powerpoint' , + 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12' , + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12' , + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' , + 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12' , + 'docm' => 'application/vnd.ms-word.document.macroEnabled.12' , + 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12' , + 'xps' => 'application/vnd.ms-xpsdocument' , + 'odc' => 'application/vnd.oasis.opendocument.chart' , + 'odb' => 'application/vnd.oasis.opendocument.database' , + 'odf' => 'application/vnd.oasis.opendocument.formula' , + 'odg' => 'application/vnd.oasis.opendocument.graphics' , + 'otg' => 'application/vnd.oasis.opendocument.graphics-template' , + 'odi' => 'application/vnd.oasis.opendocument.image' , + 'odp' => 'application/vnd.oasis.opendocument.presentation' , + 'otp' => 'application/vnd.oasis.opendocument.presentation-template' , + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet' , + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template' , + 'odt' => 'application/vnd.oasis.opendocument.text' , + 'odm' => 'application/vnd.oasis.opendocument.text-master' , + 'ott' => 'application/vnd.oasis.opendocument.text-template' , + 'oth' => 'application/vnd.oasis.opendocument.text-web' , + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation' , + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' , + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template' , + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' , + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' , + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' , + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' , + 'cod' => 'application/vnd.rim.cod' , + 'mmf' => 'application/vnd.smaf' , + 'sdc' => 'application/vnd.stardivision.calc' , + 'sds' => 'application/vnd.stardivision.chart' , + 'sda' => 'application/vnd.stardivision.draw' , + 'sdd' => 'application/vnd.stardivision.impress' , + 'sdw' => 'application/vnd.stardivision.writer' , + 'sgl' => 'application/vnd.stardivision.writer-global' , + 'sxc' => 'application/vnd.sun.xml.calc' , + 'stc' => 'application/vnd.sun.xml.calc.template' , + 'sxd' => 'application/vnd.sun.xml.draw' , + 'std' => 'application/vnd.sun.xml.draw.template' , + 'sxi' => 'application/vnd.sun.xml.impress' , + 'sti' => 'application/vnd.sun.xml.impress.template' , + 'sxm' => 'application/vnd.sun.xml.math' , + 'sxw' => 'application/vnd.sun.xml.writer' , + 'sxg' => 'application/vnd.sun.xml.writer.global' , + 'stw' => 'application/vnd.sun.xml.writer.template' , + 'sis' => 'application/vnd.symbian.install' , + 'vsd' => 'application/vnd.visio' , + 'wbxml' => 'application/vnd.wap.wbxml' , + 'wmlc' => 'application/vnd.wap.wmlc' , + 'wmlsc' => 'application/vnd.wap.wmlscriptc' , + 'wpd' => 'application/wordperfect' , + 'wp5' => 'application/wordperfect5.1' , + 'wk' => 'application/x-123' , + '7z' => 'application/x-7z-compressed' , + 'abw' => 'application/x-abiword' , + 'dmg' => 'application/x-apple-diskimage' , + 'bcpio' => 'application/x-bcpio' , + 'torrent' => 'application/x-bittorrent' , + 'cab' => 'application/x-cab' , + 'cbr' => 'application/x-cbr' , + 'cbz' => 'application/x-cbz' , + 'cdf' => 'application/x-cdf' , + 'vcd' => 'application/x-cdlink' , + 'pgn' => 'application/x-chess-pgn' , + 'cpio' => 'application/x-cpio' , + 'deb' => 'application/x-debian-package' , + 'dcr' => 'application/x-director' , + 'dms' => 'application/x-dms' , + 'wad' => 'application/x-doom' , + 'dvi' => 'application/x-dvi' , + 'flac' => 'application/x-flac' , + 'mm' => 'application/x-freemind' , + 'spl' => 'application/x-futuresplash' , + 'gnumeric' => 'application/x-gnumeric' , + 'sgf' => 'application/x-go-sgf' , + 'gcf' => 'application/x-graphing-calculator' , + 'tgz' => 'application/x-gtar' , + 'hdf' => 'application/x-hdf' , + 'rhtml' => 'application/x-httpd-eruby' , + 'php' => 'application/x-httpd-php' , + 'phps' => 'application/x-httpd-php-source' , + 'php3' => 'application/x-httpd-php3' , + 'php3p' => 'application/x-httpd-php3-preprocessed' , + 'php4' => 'application/x-httpd-php4' , + 'ica' => 'application/x-ica' , + 'isp' => 'application/x-internet-signup' , + 'iii' => 'application/x-iphone' , + 'iso' => 'application/x-iso9660-image' , + 'jnlp' => 'application/x-java-jnlp-file' , + 'js' => 'application/x-javascript' , + 'jmz' => 'application/x-jmol' , + 'chrt' => 'application/x-kchart' , + 'kil' => 'application/x-killustrator' , + 'skt' => 'application/x-koan' , + 'kpt' => 'application/x-kpresenter' , + 'ksp' => 'application/x-kspread' , + 'kwt' => 'application/x-kword' , + 'latex' => 'application/x-latex' , + 'lha' => 'application/x-lha' , + 'lyx' => 'application/x-lyx' , + 'lzh' => 'application/x-lzh' , + 'lzx' => 'application/x-lzx' , + 'fbdoc' => 'application/x-maker' , + 'mif' => 'application/x-mif' , + 'wmd' => 'application/x-ms-wmd' , + 'wmz' => 'application/x-ms-wmz' , + 'com' => 'application/x-msdos-program' , + 'msi' => 'application/x-msi' , + 'nc' => 'application/x-netcdf' , + 'pac' => 'application/x-ns-proxy-autoconfig' , + 'nwc' => 'application/x-nwc' , + 'o' => 'application/x-object' , + 'oza' => 'application/x-oz-application' , + 'p7r' => 'application/x-pkcs7-certreqresp' , + 'crl' => 'application/x-pkcs7-crl' , + 'pyc' => 'application/x-python-code' , + 'qtl' => 'application/x-quicktimeplayer' , + 'rpm' => 'application/x-redhat-package-manager' , + 'shar' => 'application/x-shar' , + 'swfl' => 'application/x-shockwave-flash' , + 'sit' => 'application/x-stuffit' , + 'sv4cpio' => 'application/x-sv4cpio' , + 'sv4crc' => 'application/x-sv4crc' , + 'tar' => 'application/x-tar' , + 'gf' => 'application/x-tex-gf' , + 'pk' => 'application/x-tex-pk' , + 'texinfo' => 'application/x-texinfo' , + 'old' => 'application/x-trash' , + 'tr' => 'application/x-troff' , + 'man' => 'application/x-troff-man' , + 'me' => 'application/x-troff-me' , + 'ms' => 'application/x-troff-ms' , + 'ustar' => 'application/x-ustar' , + 'src' => 'application/x-wais-source' , + 'wz' => 'application/x-wingz' , + 'crt' => 'application/x-x509-ca-cert' , + 'xcf' => 'application/x-xcf' , + 'fig' => 'application/x-xfig' , + 'xpi' => 'application/x-xpinstall' , + 'xhtml' => 'application/xhtml+xml' , + 'xsl' => 'application/xml' , + 'zip' => 'application/zip' , + 'snd' => 'audio/basic' , + 'kar' => 'audio/midi' , + 'mp2' => 'audio/mpeg' , + 'spx' => 'audio/ogg' , + 'sid' => 'audio/prs.sid' , + 'aifc' => 'audio/x-aiff' , + 'gsm' => 'audio/x-gsm' , + 'm3u' => 'audio/x-mpegurl' , + 'wax' => 'audio/x-ms-wax' , + 'wma' => 'audio/x-ms-wma' , + 'ram' => 'audio/x-pn-realaudio' , + 'ra' => 'audio/x-realaudio' , + 'pls' => 'audio/x-scpls' , + 'sd2' => 'audio/x-sd2' , + 'wav' => 'audio/x-wav' , + 'alc' => 'chemical/x-alchemy' , + 'cache' => 'chemical/x-cache' , + 'csf' => 'chemical/x-cache-csf' , + 'ctab' => 'chemical/x-cactvs-binary' , + 'cdx' => 'chemical/x-cdx' , + 'cer' => 'chemical/x-cerius' , + 'c3d' => 'chemical/x-chem3d' , + 'chm' => 'chemical/x-chemdraw' , + 'cif' => 'chemical/x-cif' , + 'cmdf' => 'chemical/x-cmdf' , + 'cml' => 'chemical/x-cml' , + 'cpa' => 'chemical/x-compass' , + 'bsd' => 'chemical/x-crossfire' , + 'csm' => 'chemical/x-csml' , + 'ctx' => 'chemical/x-ctx' , + 'cef' => 'chemical/x-cxf' , + 'embl' => 'chemical/x-embl-dl-nucleotide' , + 'spc' => 'chemical/x-galactic-spc' , + 'gamin' => 'chemical/x-gamess-input' , + 'fch' => 'chemical/x-gaussian-checkpoint' , + 'cub' => 'chemical/x-gaussian-cube' , + 'gjc' => 'chemical/x-gaussian-input' , + 'gal' => 'chemical/x-gaussian-log' , + 'gcg' => 'chemical/x-gcg8-sequence' , + 'gen' => 'chemical/x-genbank' , + 'hin' => 'chemical/x-hin' , + 'ist' => 'chemical/x-isostar' , + 'jdx' => 'chemical/x-jcamp-dx' , + 'kin' => 'chemical/x-kinemage' , + 'mcm' => 'chemical/x-macmolecule' , + 'mmod' => 'chemical/x-macromodel-input' , + 'mol' => 'chemical/x-mdl-molfile' , + 'rd' => 'chemical/x-mdl-rdfile' , + 'rxn' => 'chemical/x-mdl-rxnfile' , + 'sd' => 'chemical/x-mdl-sdfile' , + 'tgf' => 'chemical/x-mdl-tgf' , + 'mcif' => 'chemical/x-mmcif' , + 'mol2' => 'chemical/x-mol2' , + 'b' => 'chemical/x-molconn-Z' , + 'mop' => 'chemical/x-mopac-input' , + 'moo' => 'chemical/x-mopac-out' , + 'mvb' => 'chemical/x-mopac-vib' , + 'prt' => 'chemical/x-ncbi-asn1-ascii' , + 'val' => 'chemical/x-ncbi-asn1-binary' , + 'asn' => 'chemical/x-ncbi-asn1-spec' , + 'pdb' => 'chemical/x-pdb' , + 'ros' => 'chemical/x-rosdal' , + 'sw' => 'chemical/x-swissprot' , + 'vms' => 'chemical/x-vamas-iso14976' , + 'vmd' => 'chemical/x-vmd' , + 'xtel' => 'chemical/x-xtel' , + 'xyz' => 'chemical/x-xyz' , + 'gif' => 'image/gif' , + 'ief' => 'image/ief' , + 'jpg' => 'image/jpeg' , + 'pcx' => 'image/pcx' , + 'png' => 'image/png' , + 'svg' => 'image/svg+xml' , + 'tiff' => 'image/tiff' , + 'djv' => 'image/vnd.djvu' , + 'ico' => 'image/vnd.microsoft.icon' , + 'wbmp' => 'image/vnd.wap.wbmp' , + 'ras' => 'image/x-cmu-raster' , + 'cdr' => 'image/x-coreldraw' , + 'pat' => 'image/x-coreldrawpattern' , + 'cdt' => 'image/x-coreldrawtemplate' , + 'cpt' => 'image/x-corelphotopaint' , + 'art' => 'image/x-jg' , + 'jng' => 'image/x-jng' , + 'bmp' => 'image/x-ms-bmp' , + 'psd' => 'image/x-photoshop' , + 'pnm' => 'image/x-portable-anymap' , + 'pbm' => 'image/x-portable-bitmap' , + 'pgm' => 'image/x-portable-graymap' , + 'ppm' => 'image/x-portable-pixmap' , + 'rgb' => 'image/x-rgb' , + 'xbm' => 'image/x-xbitmap' , + 'xpm' => 'image/x-xpixmap' , + 'xwd' => 'image/x-xwindowdump' , + 'eml' => 'message/rfc822' , + 'iges' => 'model/iges' , + 'mesh' => 'model/mesh' , + 'ics' => 'text/calendar' , + 'css' => 'text/css' , + 'csv' => 'text/csv' , + '323' => 'text/h323' , + 'shtml' => 'text/html' , + 'uls' => 'text/iuls' , + 'mml' => 'text/mathml' , + 'asc' => 'text/plain' , + 'rtx' => 'text/richtext' , + 'sct' => 'text/scriptlet' , + 'tsv' => 'text/tab-separated-values' , + 'tm' => 'text/texmacs' , + 'jad' => 'text/vnd.sun.j2me.app-descriptor' , + 'wml' => 'text/vnd.wap.wml' , + 'wmls' => 'text/vnd.wap.wmlscript' , + 'bib' => 'text/x-bibtex' , + 'boo' => 'text/x-boo' , + 'hxx' => 'text/x-c++hdr' , + 'c++' => 'text/x-c++src' , + 'h' => 'text/x-chdr' , + 'htc' => 'text/x-component' , + 'csh' => 'text/x-csh' , + 'c' => 'text/x-csrc' , + 'diff' => 'text/x-diff' , + 'd' => 'text/x-dsrc' , + 'hs' => 'text/x-haskell' , + 'java' => 'text/x-java' , + 'lhs' => 'text/x-literate-haskell' , + 'moc' => 'text/x-moc' , + 'p' => 'text/x-pascal' , + 'gcd' => 'text/x-pcs-gcd' , + 'pl' => 'text/x-perl' , + 'py' => 'text/x-python' , + 'etx' => 'text/x-setext' , + 'sh' => 'text/x-sh' , + 'tcl' => 'text/x-tcl' , + 'tex' => 'text/x-tex' , + 'vcs' => 'text/x-vcalendar' , + 'vcf' => 'text/x-vcard' , + '3gp' => 'video/3gpp' , + 'dl' => 'video/dl' , + 'dv' => 'video/dv' , + 'fli' => 'video/fli' , + 'gl' => 'video/gl' , + 'f4p' => 'video/mp4' , + 'mpg' => 'video/mpeg' , + 'ogv' => 'video/ogg' , + 'mov' => 'video/quicktime' , + 'mxu' => 'video/vnd.mpegurl' , + 'lsx' => 'video/x-la-asf' , + 'mng' => 'video/x-mng' , + 'asf' => 'video/x-ms-asf' , + 'wm' => 'video/x-ms-wm' , + 'wmv' => 'video/x-ms-wmv' , + 'wmx' => 'video/x-ms-wmx' , + 'wvx' => 'video/x-ms-wvx' , + 'avi' => 'video/x-msvideo' , + 'movie' => 'video/x-sgi-movie' , + 'ice' => 'x-conference/x-cooltalk' , + 'sisx' => 'x-epoc/x-sisx-app' , + 'vrml' => 'x-world/x-vrml' , + 'f4b' => 'audio/mp4' , + 'flv' => 'video/x-flv' , + 'm4v' => 'video/x-m4v'); + + // Insantiate the mime class. + $mime_detect = new MimeDetect(); + + // Test the mapping list. + foreach ($mime_type_list as $ext => $type) { + $detected_ext = $mime_detect->getExtension($type); + $detected_mimetype = $mime_detect->getMimetype($ext); + $this->assertEqual($detected_ext, $ext, "The detected extension:$detected_ext matched the expected extension:$ext"); + $this->assertEqual($detected_mimetype, $type, "The detected mimetype:$detected_mimetype, matched the expected mimetype:$type."); + } + + // Test invalid mime type. + $result = $mime_detect->getExtension("obviously_not_a_valid_mimetype"); + $default = MimeDetect::DEFAULT_EXTENSION; + $this->assertEqual($result, $default, "MimeDetect returned:$result which should match generic mimetype:$default when an invalid extension was given."); + // Test invalid extension. + $result = $mime_detect->getMimetype("banana.aqswswswerawerqfasdzc"); + $default = MimeDetect::DEFAULT_MIMETYPE; + $this->assertEqual($result, $default, "MimeDetect returned:$result a generic extension which should match:$default."); + } +}