CMultiFileUpload.php 4.05 KB
Newer Older
JULIO JARAMILLO's avatar
JULIO JARAMILLO committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
<?php
/**
 * CMultiFileUpload class file.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link http://www.yiiframework.com/
 * @copyright 2008-2013 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

/**
 * CMultiFileUpload generates a file input that can allow uploading multiple files at a time.
 *
 * This is based on the {@link http://www.fyneworks.com/jquery/multiple-file-upload/ jQuery Multi File Upload plugin}.
 * The uploaded file information can be accessed via $_FILES[widget-name], which gives an array of the uploaded
 * files. Note, you have to set the enclosing form's 'enctype' attribute to be 'multipart/form-data'.
 *
 * Example:
 * <pre>
 * <?php
 *   $this->widget('CMultiFileUpload', array(
 *      'model'=>$model,
 *      'attribute'=>'files',
 *      'accept'=>'jpg|gif',
 *      'options'=>array(
 *         'onFileSelect'=>'function(e, v, m){ alert("onFileSelect - "+v) }',
 *         'afterFileSelect'=>'function(e, v, m){ alert("afterFileSelect - "+v) }',
 *         'onFileAppend'=>'function(e, v, m){ alert("onFileAppend - "+v) }',
 *         'afterFileAppend'=>'function(e, v, m){ alert("afterFileAppend - "+v) }',
 *         'onFileRemove'=>'function(e, v, m){ alert("onFileRemove - "+v) }',
 *         'afterFileRemove'=>'function(e, v, m){ alert("afterFileRemove - "+v) }',
 *      ),
 *   ));
 * ?>
 * </pre>
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @package system.web.widgets
 * @since 1.0
 */
class CMultiFileUpload extends CInputWidget
{
	/**
	 * @var string the file types that are allowed (eg "gif|jpg").
	 * Note, the server side still needs to check if the uploaded files have allowed types.
	 */
	public $accept;
	/**
	 * @var integer the maximum number of files that can be uploaded. If -1, it means no limits. Defaults to -1.
	 */
	public $max=-1;
	/**
	 * @var string the label for the remove button. Defaults to "Remove".
	 */
	public $remove;
	/**
	 * @var string message that is displayed when a file type is not allowed.
	 */
	public $denied;
	/**
	 * @var string message that is displayed when a file is selected.
	 */
	public $selected;
	/**
	 * @var string message that is displayed when a file appears twice.
	 */
	public $duplicate;
	/**
	 * @var string the message template for displaying the uploaded file name
	 * @since 1.1.3
	 */
	public $file;
	/**
	 * @var array additional options that can be passed to the constructor of the multifile js object.
	 * @since 1.1.7
	 */
	public $options=array();


	/**
	 * Runs the widget.
	 * This method registers all needed client scripts and renders
	 * the multiple file uploader.
	 */
	public function run()
	{
		list($name,$id)=$this->resolveNameID();
		if(substr($name,-2)!=='[]')
			$name.='[]';
		if(isset($this->htmlOptions['id']))
			$id=$this->htmlOptions['id'];
		else
			$this->htmlOptions['id']=$id;
		$this->registerClientScript();
		echo CHtml::fileField($name,'',$this->htmlOptions);
	}

	/**
	 * Registers the needed CSS and JavaScript.
	 */
	public function registerClientScript()
	{
		$id=$this->htmlOptions['id'];

		$options=$this->getClientOptions();
		$options=$options===array()? '' : CJavaScript::encode($options);

		$cs=Yii::app()->getClientScript();
		$cs->registerCoreScript('multifile');
		$cs->registerScript('Yii.CMultiFileUpload#'.$id,"jQuery(\"#{$id}\").MultiFile({$options});");
	}

	/**
	 * @return array the javascript options
	 */
	protected function getClientOptions()
	{
		$options=$this->options;
		foreach(array('onFileRemove','afterFileRemove','onFileAppend','afterFileAppend','onFileSelect','afterFileSelect') as $event)
		{
			if(isset($options[$event]) && !($options[$event] instanceof CJavaScriptExpression))
				$options[$event]=new CJavaScriptExpression($options[$event]);
		}

		if($this->accept!==null)
			$options['accept']=$this->accept;
		if($this->max>0)
			$options['max']=$this->max;

		$messages=array();
		foreach(array('remove','denied','selected','duplicate','file') as $messageName)
		{
			if($this->$messageName!==null)
				$messages[$messageName]=$this->$messageName;
		}
		if($messages!==array())
			$options['STRING']=$messages;

		return $options;
	}
}