Overview

Packages

  • application
    • commands
    • components
      • actions
      • filters
      • leftWidget
      • permissions
      • sortableWidget
      • util
      • webupdater
      • x2flow
        • actions
        • triggers
      • X2GridView
      • X2Settings
    • controllers
    • models
      • embedded
    • modules
      • accounts
        • controllers
        • models
      • actions
        • controllers
        • models
      • calendar
        • controllers
        • models
      • charts
        • models
      • contacts
        • controllers
        • models
      • docs
        • components
        • controllers
        • models
      • groups
        • controllers
        • models
      • marketing
        • components
        • controllers
        • models
      • media
        • controllers
        • models
      • mobile
        • components
      • opportunities
        • controllers
        • models
      • products
        • controllers
        • models
      • quotes
        • controllers
        • models
      • services
        • controllers
        • models
      • template
        • models
      • users
        • controllers
        • models
      • workflow
        • controllers
        • models
      • x2Leads
        • controllers
        • models
  • Net
  • None
  • PHP
  • system
    • base
    • caching
      • dependencies
    • collections
    • console
    • db
      • ar
      • schema
        • cubrid
        • mssql
        • mysql
        • oci
        • pgsql
        • sqlite
    • i18n
      • gettext
    • logging
    • test
    • utils
    • validators
    • web
      • actions
      • auth
      • filters
      • form
      • helpers
      • renderers
      • services
      • widgets
        • captcha
        • pagers
  • Text
    • Highlighter
  • zii
    • behaviors
    • widgets
      • grid
      • jui

Classes

  • CBooleanValidator
  • CCaptchaValidator
  • CCompareValidator
  • CDateValidator
  • CDefaultValueValidator
  • CEmailValidator
  • CExistValidator
  • CFileValidator
  • CFilterValidator
  • CInlineValidator
  • CNumberValidator
  • CRangeValidator
  • CRegularExpressionValidator
  • CRequiredValidator
  • CSafeValidator
  • CStringValidator
  • CTypeValidator
  • CUniqueValidator
  • CUnsafeValidator
  • CUrlValidator
  • CValidator
  • X2UrlValidator
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * CFileValidator class file.
  4:  *
  5:  * @author Qiang Xue <qiang.xue@gmail.com>
  6:  * @link http://www.yiiframework.com/
  7:  * @copyright 2008-2013 Yii Software LLC
  8:  * @license http://www.yiiframework.com/license/
  9:  */
 10: 
 11: /**
 12:  * CFileValidator verifies if an attribute is receiving a valid uploaded file.
 13:  *
 14:  * It uses the model class and attribute name to retrieve the information
 15:  * about the uploaded file. It then checks if a file is uploaded successfully,
 16:  * if the file size is within the limit and if the file type is allowed.
 17:  *
 18:  * This validator will attempt to fetch uploaded data if attribute is not
 19:  * previously set. Please note that this cannot be done if input is tabular:
 20:  * <pre>
 21:  *  foreach($models as $i=>$model)
 22:  *     $model->attribute = CUploadedFile::getInstance($model, "[$i]attribute");
 23:  * </pre>
 24:  * Please note that you must use {@link CUploadedFile::getInstances} for multiple
 25:  * file uploads.
 26:  *
 27:  * When using CFileValidator with an active record, the following code is often used:
 28:  * <pre>
 29:  *  $model->attribute = CUploadedFile::getInstance($model, "attribute");
 30:  *  if($model->save())
 31:  *  {
 32:  *     // single upload
 33:  *     $model->attribute->saveAs($path);
 34:  *     // multiple upload
 35:  *     foreach($model->attribute as $file)
 36:  *        $file->saveAs($path);
 37:  *  }
 38:  * </pre>
 39:  *
 40:  * You can use {@link CFileValidator} to validate the file attribute.
 41:  *
 42:  * In addition to the {@link message} property for setting a custom error message,
 43:  * CFileValidator has a few custom error messages you can set that correspond to different
 44:  * validation scenarios. When the file is too large, you may use the {@link tooLarge} property
 45:  * to define a custom error message. Similarly for {@link tooSmall}, {@link wrongType} and
 46:  * {@link tooMany}. The messages may contain additional placeholders that will be replaced
 47:  * with the actual content. In addition to the "{attribute}" placeholder, recognized by all
 48:  * validators (see {@link CValidator}), CFileValidator allows for the following placeholders
 49:  * to be specified:
 50:  * <ul>
 51:  * <li>{file}: replaced with the name of the file.</li>
 52:  * <li>{limit}: when using {@link tooLarge}, replaced with {@link maxSize};
 53:  * when using {@link tooSmall}, replaced with {@link minSize}; and when using {@link tooMany}
 54:  * replaced with {@link maxFiles}.</li>
 55:  * <li>{extensions}: when using {@link wrongType}, it will be replaced with the allowed extensions.</li>
 56:  * </ul>
 57:  *
 58:  * @author Qiang Xue <qiang.xue@gmail.com>
 59:  * @package system.validators
 60:  * @since 1.0
 61:  */
 62: class CFileValidator extends CValidator
 63: {
 64:     /**
 65:      * @var boolean whether the attribute requires a file to be uploaded or not.
 66:      * Defaults to false, meaning a file is required to be uploaded.
 67:      * When no file is uploaded, the owner attribute is set to null to prevent
 68:      * setting arbitrary values.
 69:      */
 70:     public $allowEmpty=false;
 71:     /**
 72:      * @var mixed a list of file name extensions that are allowed to be uploaded.
 73:      * This can be either an array or a string consisting of file extension names
 74:      * separated by space or comma (e.g. "gif, jpg").
 75:      * Extension names are case-insensitive. Defaults to null, meaning all file name
 76:      * extensions are allowed.
 77:      */
 78:     public $types;
 79:     /**
 80:      * @var mixed a list of MIME-types of the file that are allowed to be uploaded.
 81:      * This can be either an array or a string consisting of MIME-types separated
 82:      * by space or comma (e.g. "image/gif, image/jpeg"). MIME-types are
 83:      * case-insensitive. Defaults to null, meaning all MIME-types are allowed.
 84:      * In order to use this property fileinfo PECL extension should be installed.
 85:      * @since 1.1.11
 86:      */
 87:     public $mimeTypes;
 88:     /**
 89:      * @var integer the minimum number of bytes required for the uploaded file.
 90:      * Defaults to null, meaning no limit.
 91:      * @see tooSmall
 92:      */
 93:     public $minSize;
 94:     /**
 95:      * @var integer the maximum number of bytes required for the uploaded file.
 96:      * Defaults to null, meaning no limit.
 97:      * Note, the size limit is also affected by 'upload_max_filesize' INI setting
 98:      * and the 'MAX_FILE_SIZE' hidden field value.
 99:      * @see tooLarge
100:      */
101:     public $maxSize;
102:     /**
103:      * @var string the error message used when the uploaded file is too large.
104:      * @see maxSize
105:      */
106:     public $tooLarge;
107:     /**
108:      * @var string the error message used when the uploaded file is too small.
109:      * @see minSize
110:      */
111:     public $tooSmall;
112:     /**
113:      * @var string the error message used when the uploaded file has an extension name
114:      * that is not listed among {@link types}.
115:      */
116:     public $wrongType;
117:     /**
118:      * @var string the error message used when the uploaded file has a MIME-type
119:      * that is not listed among {@link mimeTypes}. In order to use this property
120:      * fileinfo PECL extension should be installed.
121:      * @since 1.1.11
122:      */
123:     public $wrongMimeType;
124:     /**
125:      * @var integer the maximum file count the given attribute can hold.
126:      * It defaults to 1, meaning single file upload. By defining a higher number,
127:      * multiple uploads become possible.
128:      */
129:     public $maxFiles=1;
130:     /**
131:      * @var string the error message used if the count of multiple uploads exceeds
132:      * limit.
133:      */
134:     public $tooMany;
135: 
136:     /**
137:      * Set the attribute and then validates using {@link validateFile}.
138:      * If there is any error, the error message is added to the object.
139:      * @param CModel $object the object being validated
140:      * @param string $attribute the attribute being validated
141:      */
142:     protected function validateAttribute($object, $attribute)
143:     {
144:         $files=$object->$attribute;
145:         if($this->maxFiles > 1)
146:         {
147:             if(!is_array($files) || !isset($files[0]) || !$files[0] instanceof CUploadedFile)
148:                 $files = CUploadedFile::getInstances($object, $attribute);
149:             if(array()===$files)
150:                 return $this->emptyAttribute($object, $attribute);
151:             if(count($files) > $this->maxFiles)
152:             {
153:                 $message=$this->tooMany!==null?$this->tooMany : Yii::t('yii', '{attribute} cannot accept more than {limit} files.');
154:                 $this->addError($object, $attribute, $message, array('{attribute}'=>$attribute, '{limit}'=>$this->maxFiles));
155:             }
156:             else
157:                 foreach($files as $file)
158:                     $this->validateFile($object, $attribute, $file);
159:         }
160:         else
161:         {
162:             if (is_array($files))
163:             {
164:                 if (count($files) > 1)
165:                 {
166:                     $message=$this->tooMany!==null?$this->tooMany : Yii::t('yii', '{attribute} cannot accept more than {limit} files.');
167:                     $this->addError($object, $attribute, $message, array('{attribute}'=>$attribute, '{limit}'=>$this->maxFiles));
168:                     return;
169:                 }
170:                 else
171:                     $file = empty($files) ? null : reset($files);
172:             }
173:             else
174:                 $file = $files;
175:             if(!$file instanceof CUploadedFile)
176:             {
177:                 $file = CUploadedFile::getInstance($object, $attribute);
178:                 if(null===$file)
179:                     return $this->emptyAttribute($object, $attribute);
180:             }
181:             $this->validateFile($object, $attribute, $file);
182:         }
183:     }
184: 
185:     /**
186:      * Internally validates a file object.
187:      * @param CModel $object the object being validated
188:      * @param string $attribute the attribute being validated
189:      * @param CUploadedFile $file uploaded file passed to check against a set of rules
190:      * @throws CException if failed to upload the file
191:      */
192:     protected function validateFile($object, $attribute, $file)
193:     {
194:         $error=(null===$file ? null : $file->getError());
195:         if($error==UPLOAD_ERR_INI_SIZE || $error==UPLOAD_ERR_FORM_SIZE || $this->maxSize!==null && $file->getSize()>$this->maxSize)
196:         {
197:             $message=$this->tooLarge!==null?$this->tooLarge : Yii::t('yii','The file "{file}" is too large. Its size cannot exceed {limit} bytes.');
198:             $this->addError($object,$attribute,$message,array('{file}'=>CHtml::encode($file->getName()), '{limit}'=>$this->getSizeLimit()));
199:             if($error!==UPLOAD_ERR_OK)
200:                 return;
201:         }
202:         elseif($error!==UPLOAD_ERR_OK)
203:         {
204:             if($error==UPLOAD_ERR_NO_FILE)
205:                 return $this->emptyAttribute($object, $attribute);
206:             elseif($error==UPLOAD_ERR_PARTIAL)
207:                 throw new CException(Yii::t('yii','The file "{file}" was only partially uploaded.',array('{file}'=>CHtml::encode($file->getName()))));
208:             elseif($error==UPLOAD_ERR_NO_TMP_DIR)
209:                 throw new CException(Yii::t('yii','Missing the temporary folder to store the uploaded file "{file}".',array('{file}'=>CHtml::encode($file->getName()))));
210:             elseif($error==UPLOAD_ERR_CANT_WRITE)
211:                 throw new CException(Yii::t('yii','Failed to write the uploaded file "{file}" to disk.',array('{file}'=>CHtml::encode($file->getName()))));
212:             elseif(defined('UPLOAD_ERR_EXTENSION') && $error==UPLOAD_ERR_EXTENSION)  // available for PHP 5.2.0 or above
213:                 throw new CException(Yii::t('yii','A PHP extension stopped the file upload.'));
214:             else
215:                 throw new CException(Yii::t('yii','Unable to upload the file "{file}" because of an unrecognized error.',array('{file}'=>CHtml::encode($file->getName()))));
216:         }
217: 
218:         if($this->minSize!==null && $file->getSize()<$this->minSize)
219:         {
220:             $message=$this->tooSmall!==null?$this->tooSmall : Yii::t('yii','The file "{file}" is too small. Its size cannot be smaller than {limit} bytes.');
221:             $this->addError($object,$attribute,$message,array('{file}'=>CHtml::encode($file->getName()), '{limit}'=>$this->minSize));
222:         }
223: 
224:         if($this->types!==null)
225:         {
226:             if(is_string($this->types))
227:                 $types=preg_split('/[\s,]+/',strtolower($this->types),-1,PREG_SPLIT_NO_EMPTY);
228:             else
229:                 $types=$this->types;
230:             if(!in_array(strtolower($file->getExtensionName()),$types))
231:             {
232:                 $message=$this->wrongType!==null?$this->wrongType : Yii::t('yii','The file "{file}" cannot be uploaded. Only files with these extensions are allowed: {extensions}.');
233:                 $this->addError($object,$attribute,$message,array('{file}'=>CHtml::encode($file->getName()), '{extensions}'=>implode(', ',$types)));
234:             }
235:         }
236: 
237:         if($this->mimeTypes!==null && !empty($file->tempName))
238:         {
239:             if(function_exists('finfo_open'))
240:             {
241:                 $mimeType=false;
242:                 if($info=finfo_open(defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME))
243:                     $mimeType=finfo_file($info,$file->getTempName());
244:             }
245:             elseif(function_exists('mime_content_type'))
246:                 $mimeType=mime_content_type($file->getTempName());
247:             else
248:                 throw new CException(Yii::t('yii','In order to use MIME-type validation provided by CFileValidator fileinfo PECL extension should be installed.'));
249: 
250:             if(is_string($this->mimeTypes))
251:                 $mimeTypes=preg_split('/[\s,]+/',strtolower($this->mimeTypes),-1,PREG_SPLIT_NO_EMPTY);
252:             else
253:                 $mimeTypes=$this->mimeTypes;
254: 
255:             if($mimeType===false || !in_array(strtolower($mimeType),$mimeTypes))
256:             {
257:                 $message=$this->wrongMimeType!==null?$this->wrongMimeType : Yii::t('yii','The file "{file}" cannot be uploaded. Only files of these MIME-types are allowed: {mimeTypes}.');
258:                 $this->addError($object,$attribute,$message,array('{file}'=>CHtml::encode($file->getName()), '{mimeTypes}'=>implode(', ',$mimeTypes)));
259:             }
260:         }
261:     }
262: 
263:     /**
264:      * Raises an error to inform end user about blank attribute.
265:      * Sets the owner attribute to null to prevent setting arbitrary values.
266:      * @param CModel $object the object being validated
267:      * @param string $attribute the attribute being validated
268:      */
269:     protected function emptyAttribute($object, $attribute)
270:     {
271:         if($this->safe) 
272:             $object->$attribute=null;
273: 
274:         if(!$this->allowEmpty)
275:         {
276:             $message=$this->message!==null?$this->message : Yii::t('yii','{attribute} cannot be blank.');
277:             $this->addError($object,$attribute,$message);
278:         }
279:     }
280: 
281:     /**
282:      * Returns the maximum size allowed for uploaded files.
283:      * This is determined based on three factors:
284:      * <ul>
285:      * <li>'upload_max_filesize' in php.ini</li>
286:      * <li>'MAX_FILE_SIZE' hidden field</li>
287:      * <li>{@link maxSize}</li>
288:      * </ul>
289:      *
290:      * @return integer the size limit for uploaded files.
291:      */
292:     protected function getSizeLimit()
293:     {
294:         $limit=ini_get('upload_max_filesize');
295:         $limit=$this->sizeToBytes($limit);
296:         if($this->maxSize!==null && $limit>0 && $this->maxSize<$limit)
297:             $limit=$this->maxSize;
298:         if(isset($_POST['MAX_FILE_SIZE']) && $_POST['MAX_FILE_SIZE']>0 && $_POST['MAX_FILE_SIZE']<$limit)
299:             $limit=$_POST['MAX_FILE_SIZE'];
300:         return $limit;
301:     }
302: 
303:     /**
304:      * Converts php.ini style size to bytes. Examples of size strings are: 150, 1g, 500k, 5M (size suffix
305:      * is case insensitive). If you pass here the number with a fractional part, then everything after
306:      * the decimal point will be ignored (php.ini values common behavior). For example 1.5G value would be
307:      * treated as 1G and 1073741824 number will be returned as a result. This method is public
308:      * (was private before) since 1.1.11.
309:      *
310:      * @param string $sizeStr the size string to convert.
311:      * @return integer the byte count in the given size string.
312:      * @since 1.1.11
313:      */
314:     public function sizeToBytes($sizeStr)
315:     {
316:         // get the latest character
317:         switch (strtolower(substr($sizeStr, -1)))
318:         {
319:             case 'm': return (int)$sizeStr * 1048576; // 1024 * 1024
320:             case 'k': return (int)$sizeStr * 1024; // 1024
321:             case 'g': return (int)$sizeStr * 1073741824; // 1024 * 1024 * 1024
322:             default: return (int)$sizeStr; // do nothing
323:         }
324:     }
325: }
326: 
API documentation generated by ApiGen 2.8.0