/lib/Zend/Validate/File/MimeType.php

https://github.com/adrienne/Readability · PHP · 283 lines · 138 code · 32 blank · 113 comment · 24 complexity · a0952e3201043d714dd728a81acae9d4 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Validate
  17. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: $
  20. */
  21. /**
  22. * @see Zend_Validate_Abstract
  23. */
  24. require_once 'Zend/Validate/Abstract.php';
  25. /**
  26. * Validator for the mime type of a file
  27. *
  28. * @category Zend
  29. * @package Zend_Validate
  30. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  31. * @license http://framework.zend.com/license/new-bsd New BSD License
  32. */
  33. class Zend_Validate_File_MimeType extends Zend_Validate_Abstract
  34. {
  35. /**#@+
  36. * @const Error type constants
  37. */
  38. const FALSE_TYPE = 'fileMimeTypeFalse';
  39. const NOT_DETECTED = 'fileMimeTypeNotDetected';
  40. const NOT_READABLE = 'fileMimeTypeNotReadable';
  41. /**#@-*/
  42. /**
  43. * @var array Error message templates
  44. */
  45. protected $_messageTemplates = array(
  46. self::FALSE_TYPE => "The file '%value%' has a false mimetype of '%type%'",
  47. self::NOT_DETECTED => "The mimetype of file '%value%' could not been detected",
  48. self::NOT_READABLE => "The file '%value%' can not be read"
  49. );
  50. /**
  51. * @var array
  52. */
  53. protected $_messageVariables = array(
  54. 'type' => '_type'
  55. );
  56. /**
  57. * @var string
  58. */
  59. protected $_type;
  60. /**
  61. * Mimetypes
  62. *
  63. * If null, there is no mimetype
  64. *
  65. * @var string|null
  66. */
  67. protected $_mimetype;
  68. /**
  69. * Magicfile to use
  70. *
  71. * @var string|null
  72. */
  73. protected $_magicfile;
  74. /**
  75. * Sets validator options
  76. *
  77. * Mimetype to accept
  78. *
  79. * @param string|array $mimetype MimeType
  80. * @return void
  81. */
  82. public function __construct($mimetype)
  83. {
  84. if ($mimetype instanceof Zend_Config) {
  85. $mimetype = $mimetype->toArray();
  86. } elseif (is_string($mimetype)) {
  87. $mimetype = explode(',', $mimetype);
  88. } elseif (!is_array($mimetype)) {
  89. require_once 'Zend/Validate/Exception.php';
  90. throw new Zend_Validate_Exception("Invalid options to validator provided");
  91. }
  92. if (isset($mimetype['magicfile'])) {
  93. $this->setMagicFile($mimetype['magicfile']);
  94. }
  95. $this->setMimeType($mimetype);
  96. }
  97. /**
  98. * Returna the actual set magicfile
  99. *
  100. * @return string
  101. */
  102. public function getMagicFile()
  103. {
  104. return $this->_magicfile;
  105. }
  106. /**
  107. * Sets the magicfile to use
  108. * if null, the MAGIC constant from php is used
  109. *
  110. * @param string $file
  111. * @return Zend_Validate_File_MimeType Provides fluid interface
  112. */
  113. public function setMagicFile($file)
  114. {
  115. if (empty($file)) {
  116. $this->_magicfile = null;
  117. } else if (!is_readable($file)) {
  118. require_once 'Zend/Validate/Exception.php';
  119. throw new Zend_Validate_Exception('The given magicfile can not be read');
  120. } else {
  121. $this->_magicfile = (string) $file;
  122. }
  123. return $this;
  124. }
  125. /**
  126. * Returns the set mimetypes
  127. *
  128. * @param boolean $asArray Returns the values as array, when false an concated string is returned
  129. * @return string|array
  130. */
  131. public function getMimeType($asArray = false)
  132. {
  133. $asArray = (bool) $asArray;
  134. $mimetype = (string) $this->_mimetype;
  135. if ($asArray) {
  136. $mimetype = explode(',', $mimetype);
  137. }
  138. return $mimetype;
  139. }
  140. /**
  141. * Sets the mimetypes
  142. *
  143. * @param string|array $mimetype The mimetypes to validate
  144. * @return Zend_Validate_File_Extension Provides a fluent interface
  145. */
  146. public function setMimeType($mimetype)
  147. {
  148. $this->_mimetype = null;
  149. $this->addMimeType($mimetype);
  150. return $this;
  151. }
  152. /**
  153. * Adds the mimetypes
  154. *
  155. * @param string|array $mimetype The mimetypes to add for validation
  156. * @return Zend_Validate_File_Extension Provides a fluent interface
  157. */
  158. public function addMimeType($mimetype)
  159. {
  160. $mimetypes = $this->getMimeType(true);
  161. if (is_string($mimetype)) {
  162. $mimetype = explode(',', $mimetype);
  163. } elseif (!is_array($mimetype)) {
  164. require_once 'Zend/Validate/Exception.php';
  165. throw new Zend_Validate_Exception("Invalid options to validator provided");
  166. }
  167. if (isset($mimetype['magicfile'])) {
  168. unset($mimetype['magicfile']);
  169. }
  170. foreach ($mimetype as $content) {
  171. if (empty($content) || !is_string($content)) {
  172. continue;
  173. }
  174. $mimetypes[] = trim($content);
  175. }
  176. $mimetypes = array_unique($mimetypes);
  177. // Sanity check to ensure no empty values
  178. foreach ($mimetypes as $key => $mt) {
  179. if (empty($mt)) {
  180. unset($mimetypes[$key]);
  181. }
  182. }
  183. $this->_mimetype = implode(',', $mimetypes);
  184. return $this;
  185. }
  186. /**
  187. * Defined by Zend_Validate_Interface
  188. *
  189. * Returns true if the mimetype of the file matches the given ones. Also parts
  190. * of mimetypes can be checked. If you give for example "image" all image
  191. * mime types will be accepted like "image/gif", "image/jpeg" and so on.
  192. *
  193. * @param string $value Real file to check for mimetype
  194. * @param array $file File data from Zend_File_Transfer
  195. * @return boolean
  196. */
  197. public function isValid($value, $file = null)
  198. {
  199. // Is file readable ?
  200. require_once 'Zend/Loader.php';
  201. if (!Zend_Loader::isReadable($value)) {
  202. return $this->_throw($file, self::NOT_READABLE);
  203. }
  204. if ($file !== null) {
  205. $mimefile = $this->getMagicFile();
  206. if (class_exists('finfo', false) && ((!empty($mimefile)) or (defined('MAGIC')))) {
  207. if (!empty($mimefile)) {
  208. $mime = new finfo(FILEINFO_MIME, $mimefile);
  209. } else {
  210. $mime = new finfo(FILEINFO_MIME);
  211. }
  212. $this->_type = $mime->file($value);
  213. unset($mime);
  214. } elseif (function_exists('mime_content_type') && ini_get('mime_magic.magicfile')) {
  215. $this->_type = mime_content_type($value);
  216. } else {
  217. $this->_type = $file['type'];
  218. }
  219. }
  220. if (empty($this->_type)) {
  221. return $this->_throw($file, self::NOT_DETECTED);
  222. }
  223. $mimetype = $this->getMimeType(true);
  224. if (in_array($this->_type, $mimetype)) {
  225. return true;
  226. }
  227. $types = explode('/', $this->_type);
  228. $types = array_merge($types, explode('-', $this->_type));
  229. foreach($mimetype as $mime) {
  230. if (in_array($mime, $types)) {
  231. return true;
  232. }
  233. }
  234. return $this->_throw($file, self::FALSE_TYPE);
  235. }
  236. /**
  237. * Throws an error of the given type
  238. *
  239. * @param string $file
  240. * @param string $errorType
  241. * @return false
  242. */
  243. protected function _throw($file, $errorType)
  244. {
  245. if ($file !== null) {
  246. $this->_value = $file['name'];
  247. }
  248. $this->_error($errorType);
  249. return false;
  250. }
  251. }