00001 <?php
00025 require_once 'Zend/Validate/Abstract.php';
00026
00035 class Zend_Validate_File_MimeType extends Zend_Validate_Abstract
00036 {
00040 const FALSE_TYPE = 'fileMimeTypeFalse';
00041 const NOT_DETECTED = 'fileMimeTypeNotDetected';
00042 const NOT_READABLE = 'fileMimeTypeNotReadable';
00048 protected $_messageTemplates = array(
00049 self::FALSE_TYPE => "The file '%value%' has a false mimetype of '%type%'",
00050 self::NOT_DETECTED => "The mimetype of file '%value%' could not been detected",
00051 self::NOT_READABLE => "The file '%value%' can not be read"
00052 );
00053
00057 protected $_messageVariables = array(
00058 'type' => '_type'
00059 );
00060
00064 protected $_type;
00065
00073 protected $_mimetype;
00074
00080 protected $_magicfile;
00081
00086 protected $_magicFiles = array(
00087 '/usr/share/misc/magic',
00088 '/usr/share/misc/magic.mime',
00089 '/usr/share/misc/magic.mgc',
00090 '/usr/share/mime/magic',
00091 '/usr/share/mime/magic.mime',
00092 '/usr/share/mime/magic.mgc',
00093 '/usr/share/file/magic',
00094 '/usr/share/file/magic.mime',
00095 '/usr/share/file/magic.mgc',
00096 );
00097
00103 protected $_headerCheck = false;
00104
00113 public function __construct($mimetype)
00114 {
00115 if ($mimetype instanceof Zend_Config) {
00116 $mimetype = $mimetype->toArray();
00117 } elseif (is_string($mimetype)) {
00118 $mimetype = explode(',', $mimetype);
00119 } elseif (!is_array($mimetype)) {
00120 require_once 'Zend/Validate/Exception.php';
00121 throw new Zend_Validate_Exception("Invalid options to validator provided");
00122 }
00123
00124 if (isset($mimetype['magicfile'])) {
00125 $this->setMagicFile($mimetype['magicfile']);
00126 }
00127
00128 if (isset($mimetype['headerCheck'])) {
00129 $this->enableHeaderCheck(true);
00130 }
00131
00132 $this->setMimeType($mimetype);
00133 }
00134
00140 public function getMagicFile()
00141 {
00142 if (null === $this->_magicfile && empty($_ENV['MAGIC'])) {
00143 foreach ($this->_magicFiles as $file) {
00144 if (file_exists($file)) {
00145 $this->setMagicFile($file);
00146 break;
00147 }
00148 }
00149 }
00150 return $this->_magicfile;
00151 }
00152
00160 public function setMagicFile($file)
00161 {
00162 if (empty($file)) {
00163 $this->_magicfile = null;
00164 } else if (!is_readable($file)) {
00165 require_once 'Zend/Validate/Exception.php';
00166 throw new Zend_Validate_Exception('The given magicfile can not be read');
00167 } else {
00168 $this->_magicfile = (string) $file;
00169 }
00170
00171 return $this;
00172 }
00173
00179 public function getHeaderCheck()
00180 {
00181 return $this->_headerCheck;
00182 }
00183
00191 public function enableHeaderCheck($headerCheck = true)
00192 {
00193 $this->_headerCheck = (boolean) $headerCheck;
00194 return $this;
00195 }
00196
00203 public function getMimeType($asArray = false)
00204 {
00205 $asArray = (bool) $asArray;
00206 $mimetype = (string) $this->_mimetype;
00207 if ($asArray) {
00208 $mimetype = explode(',', $mimetype);
00209 }
00210
00211 return $mimetype;
00212 }
00213
00220 public function setMimeType($mimetype)
00221 {
00222 $this->_mimetype = null;
00223 $this->addMimeType($mimetype);
00224 return $this;
00225 }
00226
00233 public function addMimeType($mimetype)
00234 {
00235 $mimetypes = $this->getMimeType(true);
00236
00237 if (is_string($mimetype)) {
00238 $mimetype = explode(',', $mimetype);
00239 } elseif (!is_array($mimetype)) {
00240 require_once 'Zend/Validate/Exception.php';
00241 throw new Zend_Validate_Exception("Invalid options to validator provided");
00242 }
00243
00244 if (isset($mimetype['magicfile'])) {
00245 unset($mimetype['magicfile']);
00246 }
00247
00248 foreach ($mimetype as $content) {
00249 if (empty($content) || !is_string($content)) {
00250 continue;
00251 }
00252 $mimetypes[] = trim($content);
00253 }
00254 $mimetypes = array_unique($mimetypes);
00255
00256
00257 foreach ($mimetypes as $key => $mt) {
00258 if (empty($mt)) {
00259 unset($mimetypes[$key]);
00260 }
00261 }
00262
00263 $this->_mimetype = implode(',', $mimetypes);
00264
00265 return $this;
00266 }
00267
00279 public function isValid($value, $file = null)
00280 {
00281 if ($file === null) {
00282 $file = array(
00283 'type' => null,
00284 'name' => $value
00285 );
00286 }
00287
00288
00289 require_once 'Zend/Loader.php';
00290 if (!Zend_Loader::isReadable($value)) {
00291 return $this->_throw($file, self::NOT_READABLE);
00292 }
00293
00294 $mimefile = $this->getMagicFile();
00295 if (class_exists('finfo', false)) {
00296 $const = defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME;
00297 if (!empty($mimefile)) {
00298 $mime = new finfo($const, $mimefile);
00299 } else {
00300 $mime = new finfo($const);
00301 }
00302
00303 if ($mime !== false) {
00304 $this->_type = $mime->file($value);
00305 }
00306 unset($mime);
00307 }
00308
00309 if (empty($this->_type)) {
00310 if (function_exists('mime_content_type') && ini_get('mime_magic.magicfile')) {
00311 $this->_type = mime_content_type($value);
00312 } elseif ($this->_headerCheck) {
00313 $this->_type = $file['type'];
00314 }
00315 }
00316
00317 if (empty($this->_type)) {
00318 return $this->_throw($file, self::NOT_DETECTED);
00319 }
00320
00321 $mimetype = $this->getMimeType(true);
00322 if (in_array($this->_type, $mimetype)) {
00323 return true;
00324 }
00325
00326 $types = explode('/', $this->_type);
00327 $types = array_merge($types, explode('-', $this->_type));
00328 foreach($mimetype as $mime) {
00329 if (in_array($mime, $types)) {
00330 return true;
00331 }
00332 }
00333
00334 return $this->_throw($file, self::FALSE_TYPE);
00335 }
00336
00344 protected function _throw($file, $errorType)
00345 {
00346 $this->_value = $file['name'];
00347 $this->_error($errorType);
00348 return false;
00349 }
00350 }