From 3e0c291810d23bb54c337c0fe95c1ba441459c4c Mon Sep 17 00:00:00 2001 From: Robin Millette Date: Sun, 31 May 2009 16:42:29 -0400 Subject: Added configurable options for attachments: supported mimetypes and quotas for uploads. --- extlib/MIME/Type.php | 523 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 523 insertions(+) create mode 100644 extlib/MIME/Type.php (limited to 'extlib/MIME/Type.php') diff --git a/extlib/MIME/Type.php b/extlib/MIME/Type.php new file mode 100644 index 000000000..c335f8d92 --- /dev/null +++ b/extlib/MIME/Type.php @@ -0,0 +1,523 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Type.php,v 1.6 2009/01/16 11:49:45 cweiske Exp $ + +require_once 'PEAR.php'; + +$_fileCmd = &PEAR::getStaticProperty('MIME_Type', 'fileCmd'); +$_fileCmd = 'file'; + +/** + * Class for working with MIME types + * + * @category MIME + * @package MIME_Type + * @license PHP License 3.0 + * @version 1.2.0 + * @link http://pear.php.net/package/MIME_Type + * @author Ian Eure + */ +class MIME_Type +{ + /** + * The MIME media type + * + * @var string + */ + var $media = ''; + + /** + * The MIME media sub-type + * + * @var string + */ + var $subType = ''; + + /** + * Optional MIME parameters + * + * @var array + */ + var $parameters = array(); + + /** + * List of valid media types. + * A media type is the string in front of the slash. + * The media type of "text/xml" would be "text". + * + * @var array + */ + var $validMediaTypes = array( + 'text', + 'image', + 'audio', + 'video', + 'application', + 'multipart', + 'message' + ); + + + /** + * Constructor. + * + * If $type is set, if will be parsed and the appropriate class vars set. + * If not, you get an empty class. + * This is useful, but not quite as useful as parsing a type. + * + * @param string $type MIME type + * + * @return void + */ + function MIME_Type($type = false) + { + if ($type) { + $this->parse($type); + } + } + + + /** + * Parse a mime-type and set the class variables. + * + * @param string $type MIME type to parse + * + * @return void + */ + function parse($type) + { + $this->media = $this->getMedia($type); + $this->subType = $this->getSubType($type); + $this->parameters = array(); + if (MIME_Type::hasParameters($type)) { + require_once 'MIME/Type/Parameter.php'; + foreach (MIME_Type::getParameters($type) as $param) { + $param = new MIME_Type_Parameter($param); + $this->parameters[$param->name] = $param; + } + } + } + + + /** + * Does this type have any parameters? + * + * @param string $type MIME type to check + * + * @return boolean true if $type has parameters, false otherwise + * @static + */ + function hasParameters($type) + { + if (strstr($type, ';')) { + return true; + } + return false; + } + + + /** + * Get a MIME type's parameters + * + * @param string $type MIME type to get parameters of + * + * @return array $type's parameters + * @static + */ + function getParameters($type) + { + $params = array(); + $tmp = explode(';', $type); + for ($i = 1; $i < count($tmp); $i++) { + $params[] = trim($tmp[$i]); + } + return $params; + } + + + /** + * Strip parameters from a MIME type string. + * + * @param string $type MIME type string + * + * @return string MIME type with parameters removed + * @static + */ + function stripParameters($type) + { + if (strstr($type, ';')) { + return substr($type, 0, strpos($type, ';')); + } + return $type; + } + + + /** + * Removes comments from a media type, subtype or parameter. + * + * @param string $string String to strip comments from + * @param string &$comment Comment is stored in there. + * + * @return string String without comments + * @static + */ + function stripComments($string, &$comment) + { + if (strpos($string, '(') === false) { + return $string; + } + + $inquote = false; + $quoting = false; + $incomment = 0; + $newstring = ''; + + for ($n = 0; $n < strlen($string); $n++) { + if ($quoting) { + if ($incomment == 0) { + $newstring .= $string[$n]; + } else if ($comment !== null) { + $comment .= $string[$n]; + } + $quoting = false; + } else if ($string[$n] == '\\') { + $quoting = true; + } else if (!$inquote && $incomment > 0 && $string[$n] == ')') { + $incomment--; + if ($incomment == 0 && $comment !== null) { + $comment .= ' '; + } + } else if (!$inquote && $string[$n] == '(') { + $incomment++; + } else if ($string[$n] == '"') { + if ($inquote) { + $inquote = false; + } else { + $inquote = true; + } + } else if ($incomment == 0) { + $newstring .= $string[$n]; + } else if ($comment !== null) { + $comment .= $string[$n]; + } + } + + if ($comment !== null) { + $comment = trim($comment); + } + + return $newstring; + } + + + /** + * Get a MIME type's media + * + * @note 'media' refers to the portion before the first slash + * + * @param string $type MIME type to get media of + * + * @return string $type's media + * @static + */ + function getMedia($type) + { + $tmp = explode('/', $type); + return strtolower(trim(MIME_Type::stripComments($tmp[0], $null))); + } + + + /** + * Get a MIME type's subtype + * + * @param string $type MIME type to get subtype of + * + * @return string $type's subtype, null if invalid mime type + * @static + */ + function getSubType($type) + { + $tmp = explode('/', $type); + if (!isset($tmp[1])) { + return null; + } + $tmp = explode(';', $tmp[1]); + return strtolower(trim(MIME_Type::stripComments($tmp[0], $null))); + } + + + /** + * Create a textual MIME type from object values + * + * This function performs the opposite function of parse(). + * + * @return string MIME type string + */ + function get() + { + $type = strtolower($this->media . '/' . $this->subType); + if (count($this->parameters)) { + foreach ($this->parameters as $key => $null) { + $type .= '; ' . $this->parameters[$key]->get(); + } + } + return $type; + } + + + /** + * Is this type experimental? + * + * @note Experimental types are denoted by a leading 'x-' in the media or + * subtype, e.g. text/x-vcard or x-world/x-vrml. + * + * @param string $type MIME type to check + * + * @return boolean true if $type is experimental, false otherwise + * @static + */ + function isExperimental($type) + { + if (substr(MIME_Type::getMedia($type), 0, 2) == 'x-' || + substr(MIME_Type::getSubType($type), 0, 2) == 'x-') { + return true; + } + return false; + } + + + /** + * Is this a vendor MIME type? + * + * @note Vendor types are denoted with a leading 'vnd. in the subtype. + * + * @param string $type MIME type to check + * + * @return boolean true if $type is a vendor type, false otherwise + * @static + */ + function isVendor($type) + { + if (substr(MIME_Type::getSubType($type), 0, 4) == 'vnd.') { + return true; + } + return false; + } + + + /** + * Is this a wildcard type? + * + * @param string $type MIME type to check + * + * @return boolean true if $type is a wildcard, false otherwise + * @static + */ + function isWildcard($type) + { + if ($type == '*/*' || MIME_Type::getSubtype($type) == '*') { + return true; + } + return false; + } + + + /** + * Perform a wildcard match on a MIME type + * + * Example: + * MIME_Type::wildcardMatch('image/*', 'image/png') + * + * @param string $card Wildcard to check against + * @param string $type MIME type to check + * + * @return boolean true if there was a match, false otherwise + * @static + */ + function wildcardMatch($card, $type) + { + if (!MIME_Type::isWildcard($card)) { + return false; + } + + if ($card == '*/*') { + return true; + } + + if (MIME_Type::getMedia($card) == MIME_Type::getMedia($type)) { + return true; + } + + return false; + } + + + /** + * Add a parameter to this type + * + * @param string $name Attribute name + * @param string $value Attribute value + * @param string $comment Comment for this parameter + * + * @return void + */ + function addParameter($name, $value, $comment = false) + { + $tmp = new MIME_Type_Parameter(); + + $tmp->name = $name; + $tmp->value = $value; + $tmp->comment = $comment; + $this->parameters[$name] = $tmp; + } + + + /** + * Remove a parameter from this type + * + * @param string $name Parameter name + * + * @return void + */ + function removeParameter($name) + { + unset($this->parameters[$name]); + } + + + /** + * Autodetect a file's MIME-type + * + * This function may be called staticly. + * + * @internal Tries to use fileinfo extension at first. If that + * does not work, mime_magic is used. If this is also not available + * or does not succeed, "file" command is tried to be executed with + * System_Command. When that fails, too, then we use our in-built + * extension-to-mimetype-mapping list. + * + * @param string $file Path to the file to get the type of + * @param bool $params Append MIME parameters if true + * + * @return string $file's MIME-type on success, PEAR_Error otherwise + * + * @since 1.0.0beta1 + * @static + */ + function autoDetect($file, $params = false) + { + // Sanity checks + if (!file_exists($file)) { + return PEAR::raiseError("File \"$file\" doesn't exist"); + } + + if (!is_readable($file)) { + return PEAR::raiseError("File \"$file\" is not readable"); + } + + if (function_exists('finfo_file')) { + $finfo = finfo_open(FILEINFO_MIME); + $type = finfo_file($finfo, $file); + finfo_close($finfo); + if ($type !== false && $type !== '') { + return MIME_Type::_handleDetection($type, $params); + } + } + + if (function_exists('mime_content_type')) { + $type = mime_content_type($file); + if ($type !== false && $type !== '') { + return MIME_Type::_handleDetection($type, $params); + } + } + + @include_once 'System/Command.php'; + if (class_exists('System_Command')) { + return MIME_Type::_handleDetection( + MIME_Type::_fileAutoDetect($file), + $params + ); + } + + require_once 'MIME/Type/Extension.php'; + $mte = new MIME_Type_Extension(); + return $mte->getMIMEType($file); + } + + + /** + * Handles a detected MIME type and modifies it if necessary. + * + * @param string $type MIME Type of a file + * @param bool $params Append MIME parameters if true + * + * @return string $file's MIME-type on success, PEAR_Error otherwise + */ + function _handleDetection($type, $params) + { + // _fileAutoDetect() may have returned an error. + if (PEAR::isError($type)) { + return $type; + } + + // Don't return an empty string + if (!$type || !strlen($type)) { + return PEAR::raiseError("Sorry, couldn't determine file type."); + } + + // Strip parameters if present & requested + if (MIME_Type::hasParameters($type) && !$params) { + $type = MIME_Type::stripParameters($type); + } + + return $type; + } + + + /** + * Autodetect a file's MIME-type with 'file' and System_Command + * + * This function may be called staticly. + * + * @param string $file Path to the file to get the type of + * + * @return string $file's MIME-type + * + * @since 1.0.0beta1 + * @static + */ + function _fileAutoDetect($file) + { + $cmd = new System_Command(); + + // Make sure we have the 'file' command. + $fileCmd = PEAR::getStaticProperty('MIME_Type', 'fileCmd'); + if (!$cmd->which($fileCmd)) { + unset($cmd); + return PEAR::raiseError("Can't find file command \"{$fileCmd}\""); + } + + $cmd->pushCommand($fileCmd, "-bi " . escapeshellarg($file)); + $res = $cmd->execute(); + unset($cmd); + + return $res; + } +} + -- cgit v1.2.3-54-g00ecf