1: <?php
2: /**
3: * CMultiFileUpload 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: * CMultiFileUpload generates a file input that can allow uploading multiple files at a time.
13: *
14: * This is based on the {@link http://www.fyneworks.com/jquery/multiple-file-upload/ jQuery Multi File Upload plugin}.
15: * The uploaded file information can be accessed via $_FILES[widget-name], which gives an array of the uploaded
16: * files. Note, you have to set the enclosing form's 'enctype' attribute to be 'multipart/form-data'.
17: *
18: * Example:
19: * <pre>
20: * <?php
21: * $this->widget('CMultiFileUpload', array(
22: * 'model'=>$model,
23: * 'attribute'=>'files',
24: * 'accept'=>'jpg|gif',
25: * 'options'=>array(
26: * 'onFileSelect'=>'function(e, v, m){ alert("onFileSelect - "+v) }',
27: * 'afterFileSelect'=>'function(e, v, m){ alert("afterFileSelect - "+v) }',
28: * 'onFileAppend'=>'function(e, v, m){ alert("onFileAppend - "+v) }',
29: * 'afterFileAppend'=>'function(e, v, m){ alert("afterFileAppend - "+v) }',
30: * 'onFileRemove'=>'function(e, v, m){ alert("onFileRemove - "+v) }',
31: * 'afterFileRemove'=>'function(e, v, m){ alert("afterFileRemove - "+v) }',
32: * ),
33: * ));
34: * ?>
35: * </pre>
36: *
37: * @author Qiang Xue <qiang.xue@gmail.com>
38: * @package system.web.widgets
39: * @since 1.0
40: */
41: class CMultiFileUpload extends CInputWidget
42: {
43: /**
44: * @var string the file types that are allowed (eg "gif|jpg").
45: * Note, the server side still needs to check if the uploaded files have allowed types.
46: */
47: public $accept;
48: /**
49: * @var integer the maximum number of files that can be uploaded. If -1, it means no limits. Defaults to -1.
50: */
51: public $max=-1;
52: /**
53: * @var string the label for the remove button. Defaults to "Remove".
54: */
55: public $remove;
56: /**
57: * @var string message that is displayed when a file type is not allowed.
58: */
59: public $denied;
60: /**
61: * @var string message that is displayed when a file is selected.
62: */
63: public $selected;
64: /**
65: * @var string message that is displayed when a file appears twice.
66: */
67: public $duplicate;
68: /**
69: * @var string the message template for displaying the uploaded file name
70: * @since 1.1.3
71: */
72: public $file;
73: /**
74: * @var array additional options that can be passed to the constructor of the multifile js object.
75: * @since 1.1.7
76: */
77: public $options=array();
78:
79:
80: /**
81: * Runs the widget.
82: * This method registers all needed client scripts and renders
83: * the multiple file uploader.
84: */
85: public function run()
86: {
87: list($name,$id)=$this->resolveNameID();
88: if(substr($name,-2)!=='[]')
89: $name.='[]';
90: if(isset($this->htmlOptions['id']))
91: $id=$this->htmlOptions['id'];
92: else
93: $this->htmlOptions['id']=$id;
94: $this->registerClientScript();
95: echo CHtml::fileField($name,'',$this->htmlOptions);
96: }
97:
98: /**
99: * Registers the needed CSS and JavaScript.
100: */
101: public function registerClientScript()
102: {
103: $id=$this->htmlOptions['id'];
104:
105: $options=$this->getClientOptions();
106: $options=$options===array()? '' : CJavaScript::encode($options);
107:
108: $cs=Yii::app()->getClientScript();
109: $cs->registerCoreScript('multifile');
110: $cs->registerScript('Yii.CMultiFileUpload#'.$id,"jQuery(\"#{$id}\").MultiFile({$options});");
111: }
112:
113: /**
114: * @return array the javascript options
115: */
116: protected function getClientOptions()
117: {
118: $options=$this->options;
119: foreach(array('onFileRemove','afterFileRemove','onFileAppend','afterFileAppend','onFileSelect','afterFileSelect') as $event)
120: {
121: if(isset($options[$event]) && !($options[$event] instanceof CJavaScriptExpression))
122: $options[$event]=new CJavaScriptExpression($options[$event]);
123: }
124:
125: if($this->accept!==null)
126: $options['accept']=$this->accept;
127: if($this->max>0)
128: $options['max']=$this->max;
129:
130: $messages=array();
131: foreach(array('remove','denied','selected','duplicate','file') as $messageName)
132: {
133: if($this->$messageName!==null)
134: $messages[$messageName]=$this->$messageName;
135: }
136: if($messages!==array())
137: $options['STRING']=$messages;
138:
139: return $options;
140: }
141: }
142: