File indexing completed on 2024-12-22 05:37:11
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Validate 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 /** 0023 * @see Zend_Validate_Abstract 0024 */ 0025 // require_once 'Zend/Validate/Abstract.php'; 0026 0027 /** 0028 * Validator for the file extension of a file 0029 * 0030 * @category Zend 0031 * @package Zend_Validate 0032 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0033 * @license http://framework.zend.com/license/new-bsd New BSD License 0034 */ 0035 class Zend_Validate_File_Extension extends Zend_Validate_Abstract 0036 { 0037 /** 0038 * @const string Error constants 0039 */ 0040 const FALSE_EXTENSION = 'fileExtensionFalse'; 0041 const NOT_FOUND = 'fileExtensionNotFound'; 0042 0043 /** 0044 * @var array Error message templates 0045 */ 0046 protected $_messageTemplates = array( 0047 self::FALSE_EXTENSION => "File '%value%' has a false extension", 0048 self::NOT_FOUND => "File '%value%' is not readable or does not exist", 0049 ); 0050 0051 /** 0052 * Internal list of extensions 0053 * @var string 0054 */ 0055 protected $_extension = ''; 0056 0057 /** 0058 * Validate case sensitive 0059 * 0060 * @var boolean 0061 */ 0062 protected $_case = false; 0063 0064 /** 0065 * @var array Error message template variables 0066 */ 0067 protected $_messageVariables = array( 0068 'extension' => '_extension' 0069 ); 0070 0071 /** 0072 * Sets validator options 0073 * 0074 * @param string|array|Zend_Config $options 0075 */ 0076 public function __construct($options) 0077 { 0078 if ($options instanceof Zend_Config) { 0079 $options = $options->toArray(); 0080 } 0081 0082 if (1 < func_num_args()) { 0083 $case = func_get_arg(1); 0084 $this->setCase($case); 0085 } 0086 0087 if (is_array($options) and isset($options['case'])) { 0088 $this->setCase($options['case']); 0089 unset($options['case']); 0090 } 0091 0092 $this->setExtension($options); 0093 } 0094 0095 /** 0096 * Returns the case option 0097 * 0098 * @return boolean 0099 */ 0100 public function getCase() 0101 { 0102 return $this->_case; 0103 } 0104 0105 /** 0106 * Sets the case to use 0107 * 0108 * @param boolean $case 0109 * @return Zend_Validate_File_Extension Provides a fluent interface 0110 */ 0111 public function setCase($case) 0112 { 0113 $this->_case = (boolean) $case; 0114 return $this; 0115 } 0116 0117 /** 0118 * Returns the set file extension 0119 * 0120 * @return array 0121 */ 0122 public function getExtension() 0123 { 0124 $extension = explode(',', $this->_extension); 0125 0126 return $extension; 0127 } 0128 0129 /** 0130 * Sets the file extensions 0131 * 0132 * @param string|array $extension The extensions to validate 0133 * @return Zend_Validate_File_Extension Provides a fluent interface 0134 */ 0135 public function setExtension($extension) 0136 { 0137 $this->_extension = null; 0138 $this->addExtension($extension); 0139 return $this; 0140 } 0141 0142 /** 0143 * Adds the file extensions 0144 * 0145 * @param string|array $extension The extensions to add for validation 0146 * @return Zend_Validate_File_Extension Provides a fluent interface 0147 */ 0148 public function addExtension($extension) 0149 { 0150 $extensions = $this->getExtension(); 0151 if (is_string($extension)) { 0152 $extension = explode(',', $extension); 0153 } 0154 0155 foreach ($extension as $content) { 0156 if (empty($content) || !is_string($content)) { 0157 continue; 0158 } 0159 0160 $extensions[] = trim($content); 0161 } 0162 $extensions = array_unique($extensions); 0163 0164 // Sanity check to ensure no empty values 0165 foreach ($extensions as $key => $ext) { 0166 if (empty($ext)) { 0167 unset($extensions[$key]); 0168 } 0169 } 0170 0171 $this->_extension = implode(',', $extensions); 0172 0173 return $this; 0174 } 0175 0176 /** 0177 * Defined by Zend_Validate_Interface 0178 * 0179 * Returns true if and only if the fileextension of $value is included in the 0180 * set extension list 0181 * 0182 * @param string $value Real file to check for extension 0183 * @param array $file File data from Zend_File_Transfer 0184 * @return boolean 0185 */ 0186 public function isValid($value, $file = null) 0187 { 0188 // Is file readable ? 0189 // require_once 'Zend/Loader.php'; 0190 if (!Zend_Loader::isReadable($value)) { 0191 return $this->_throw($file, self::NOT_FOUND); 0192 } 0193 0194 if ($file !== null) { 0195 $info['extension'] = substr($file['name'], strrpos($file['name'], '.') + 1); 0196 } else { 0197 $info = pathinfo($value); 0198 if (!array_key_exists('extension', $info)) { 0199 // From the manual at http://php.net/pathinfo: 0200 // "If the path does not have an extension, no extension element 0201 // will be returned (see second example below)." 0202 return false; 0203 } 0204 } 0205 0206 $extensions = $this->getExtension(); 0207 0208 if ($this->_case && (in_array($info['extension'], $extensions))) { 0209 return true; 0210 } else if (!$this->getCase()) { 0211 foreach ($extensions as $extension) { 0212 if (strtolower($extension) == strtolower($info['extension'])) { 0213 return true; 0214 } 0215 } 0216 } 0217 0218 return $this->_throw($file, self::FALSE_EXTENSION); 0219 } 0220 0221 /** 0222 * Throws an error of the given type 0223 * 0224 * @param string $file 0225 * @param string $errorType 0226 * @return false 0227 */ 0228 protected function _throw($file, $errorType) 0229 { 0230 if (null !== $file) { 0231 $this->_value = $file['name']; 0232 } 0233 0234 $this->_error($errorType); 0235 return false; 0236 } 0237 }