├── .gitignore ├── README.md ├── UploadAction.php ├── Uploadify.php ├── UploadifyAsset.php ├── assets ├── jquery.uploadify.js ├── uploadify-cancel.png ├── uploadify.css └── uploadify.swf └── composer.json /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | /debug/ 3 | composer.lock -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # yii2-uploadify-widget 2 | === 3 | 4 | ## composer.json 5 | --- 6 | ```json 7 | "require": { 8 | "xj/yii2-uploadify-widget": "~2.0.0" 9 | }, 10 | 11 | "require": { 12 | "xj/yii2-uploadify-widget": "~1.0.0" 13 | }, 14 | ``` 15 | 16 | ## example: 17 | ### version 2.0 18 | --- 19 | ```php 20 | //Remove Events Auto Convert 21 | 22 | use yii\web\JsExpression; 23 | 24 | //外部TAG 25 | echo Html::fileInput('test', NULL, ['id' => 'test']); 26 | echo Uploadify::widget([ 27 | 'url' => yii\helpers\Url::to(['s-upload']), 28 | 'id' => 'test', 29 | 'csrf' => true, 30 | 'renderTag' => false, 31 | 'jsOptions' => [ 32 | 'width' => 120, 33 | 'height' => 40, 34 | 'onUploadError' => new JsExpression(<< new JsExpression(<< 'test']); 60 | echo Uploadify::widget([ 61 | 'url' => yii\helpers\Url::to(['s-upload']), 62 | 'id' => 'test', 63 | 'csrf' => true, 64 | 'renderTag' => false, 65 | 'jsOptions' => [ 66 | 'width' => 120, 67 | 'height' => 40, 68 | 'onUploadError' => "function(file, errorCode, errorMsg, errorString) { 69 | console.log('The file ' + file.name + ' could not be uploaded: ' + errorString + errorCode + errorMsg); 70 | }", 71 | 'onUploadSuccess' => "function(file, data, response) { 72 | data = JSON.parse(data); 73 | if (data.error) { 74 | console.log(data.msg); 75 | } else { 76 | console.log(data.fileUrl); 77 | } 78 | }" 79 | ] 80 | ]); 81 | 82 | //直接渲染 83 | echo Html::activeLabel($model, 'file'); 84 | echo Uploadify::widget([ 85 | 'url' => yii\helpers\Url::to(['s-upload']), 86 | 'attribute' => 'file', 87 | 'model' => $model, 88 | 'csrf' => true, 89 | 'jsOptions' => [ 90 | 'width' => 120, 91 | 'height' => 40, 92 | 'onUploadError' => "function(file, errorCode, errorMsg, errorString) { 93 | console.log('The file ' + file.name + ' could not be uploaded: ' + errorString + errorCode + errorMsg); 94 | }", 95 | 'onUploadSuccess' => "function(file, data, response) { 96 | console.log('The file ' + file.name + ' was successfully uploaded with a response of ' + response + ':' + data); 97 | }" 98 | ] 99 | ]); 100 | ``` 101 | 102 | Action: 103 | --- 104 | ### version 2.0 105 | ---- 106 | ```php 107 | use xj\uploadify\UploadAction; 108 | 109 | public function actions() { 110 | return [ 111 | 's-upload' => [ 112 | 'class' => UploadAction::className(), 113 | 'basePath' => '@webroot/upload', 114 | 'baseUrl' => '@web/upload', 115 | 'enableCsrf' => true, // default 116 | 'postFieldName' => 'Filedata', // default 117 | //BEGIN METHOD 118 | 'format' => [$this, 'methodName'], 119 | //END METHOD 120 | //BEGIN CLOSURE BY-HASH 121 | 'overwriteIfExist' => true, 122 | 'format' => function (UploadAction $action) { 123 | $fileext = $action->uploadfile->getExtension(); 124 | $filename = sha1_file($action->uploadfile->tempName); 125 | return "{$filename}.{$fileext}"; 126 | }, 127 | //END CLOSURE BY-HASH 128 | //BEGIN CLOSURE BY TIME 129 | 'format' => function (UploadAction $action) { 130 | $fileext = $action->uploadfile->getExtension(); 131 | $filehash = sha1(uniqid() . time()); 132 | $p1 = substr($filehash, 0, 2); 133 | $p2 = substr($filehash, 2, 2); 134 | return "{$p1}/{$p2}/{$filehash}.{$fileext}"; 135 | }, 136 | //END CLOSURE BY TIME 137 | 'validateOptions' => [ 138 | 'extensions' => ['jpg', 'png'], 139 | 'maxSize' => 1 * 1024 * 1024, //file size 140 | ], 141 | 'beforeValidate' => function (UploadAction $action) { 142 | //throw new Exception('test error'); 143 | }, 144 | 'afterValidate' => function (UploadAction $action) {}, 145 | 'beforeSave' => function (UploadAction $action) {}, 146 | 'afterSave' => function (UploadAction $action) { 147 | $action->output['fileUrl'] = $action->getWebUrl(); 148 | $action->getFilename(); // "image/yyyymmddtimerand.jpg" 149 | $action->getWebUrl(); // "baseUrl + filename, /upload/image/yyyymmddtimerand.jpg" 150 | $action->getSavePath(); // "/var/www/htdocs/upload/image/yyyymmddtimerand.jpg" 151 | }, 152 | ], 153 | ]; 154 | } 155 | ``` 156 | 157 | 158 | ### version 1.0 159 | ---- 160 | ```php 161 | use xj\uploadify\UploadAction; 162 | 163 | public function actions() { 164 | return [ 165 | 's-upload' => [ 166 | 'class' => UploadAction::className(), 167 | 'uploadBasePath' => '@webroot/upload', //file system path 168 | 'uploadBaseUrl' => '@web/upload', //web path 169 | 'csrf' => true, 170 | // 'format' => 'image/{yyyy}{mm}{dd}/{time}{rand:6}', // OR Closure 171 | 'format' => function(UploadAction $action) { 172 | $fileext = $action->uploadFileInstance->getExtension(); 173 | $filehash = sha1(uniqid() . time()); 174 | $p1 = substr($filehash, 0, 2); 175 | $p2 = substr($filehash, 2, 2); 176 | return "{$p1}/{$p2}/{$filehash}.{$fileext}"; 177 | }, 178 | 'validateOptions' => [ 179 | 'extensions' => ['jpg', 'png'], 180 | 'maxSize' => 1 * 1024 * 1024, //file size 181 | ], 182 | 'beforeValidate' => function(UploadAction $action) {}, 183 | 'afterValidate' => function(UploadAction $action) {}, 184 | 'beforeSave' => function(UploadAction $action) {}, 185 | 'afterSave' => function(UploadAction $action) { 186 | //$action->filename; // image/yyyymmdd/xxx.jpg 187 | //$action->$fullFilename // /var/www/htdocs/image/yyyymmddtimerand.jpg 188 | }, 189 | ], 190 | ]; 191 | } 192 | ``` 193 | -------------------------------------------------------------------------------- /UploadAction.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class UploadAction extends Action 18 | { 19 | 20 | /** 21 | * SavePath 22 | * @var string 23 | */ 24 | public $basePath = '@webroot/upload'; 25 | 26 | /** 27 | * WebUrl 28 | * @var string 29 | */ 30 | public $baseUrl = '@web/upload'; 31 | 32 | /** 33 | * @var bool 34 | */ 35 | public $enableCsrf = true; 36 | 37 | /** 38 | * @var array | Closure 39 | * @example 40 | * // [$object, 'methodName'] 41 | * // function(){} 42 | */ 43 | public $format; 44 | 45 | /** 46 | * file validator options 47 | * @var [] 48 | * @see http://stuff.cebe.cc/yii2docs/yii-validators-filevalidator.html 49 | * @example 50 | * [ 51 | * 'maxSize' => 1000, 52 | * 'extensions' => ['jpg', 'png'] 53 | * ] 54 | */ 55 | public $validateOptions; 56 | 57 | /** 58 | * @var string 59 | */ 60 | public $postFieldName = 'Filedata'; 61 | 62 | /** 63 | * @var UploadedFile 64 | */ 65 | public $uploadfile; 66 | 67 | /** 68 | * Save Relative File Name 69 | * image/yyyymmdd/xxx.jpg 70 | * @var string 71 | */ 72 | public $filename; 73 | 74 | /** 75 | * @var bool 76 | */ 77 | public $overwriteIfExist = false; 78 | 79 | /** 80 | * @var int 81 | */ 82 | public $fileChmod = 0644; 83 | 84 | /** 85 | * @var int 86 | */ 87 | public $dirChmod = 0755; 88 | 89 | /** 90 | * throw yii\base\Exception will break 91 | * @var Closure 92 | * beforeValidate($UploadAction) 93 | */ 94 | public $beforeValidate; 95 | 96 | /** 97 | * throw yii\base\Exception will break 98 | * @var Closure 99 | * afterValidate($UploadAction) 100 | */ 101 | public $afterValidate; 102 | 103 | /** 104 | * throw yii\base\Exception will break 105 | * @var Closure 106 | * beforeSave($UploadAction) 107 | */ 108 | public $beforeSave; 109 | 110 | /** 111 | * throw yii\base\Exception will break 112 | * @var Closure 113 | * afterSave($filename, $fullFilename, $UploadAction) 114 | */ 115 | public $afterSave; 116 | 117 | /** 118 | * OutputBuffer 119 | * @var [] 120 | */ 121 | public $output = ['error' => false]; 122 | 123 | 124 | public function init() 125 | { 126 | $this->initCsrf(); 127 | 128 | if (empty($this->basePath)) { 129 | throw new Exception('basePath not exist'); 130 | } 131 | $this->basePath = Yii::getAlias($this->basePath); 132 | 133 | if (empty($this->baseUrl)) { 134 | throw new Exception('baseUrl not exist'); 135 | } 136 | $this->baseUrl = Yii::getAlias($this->baseUrl); 137 | 138 | if (false === is_callable($this->format) && false === is_array($this->format)) { 139 | throw new Exception('format is invalid'); 140 | } 141 | 142 | return parent::init(); 143 | } 144 | 145 | public function run() 146 | { 147 | try { 148 | //instance uploadfile 149 | $this->uploadfile = UploadedFile::getInstanceByName($this->postFieldName); 150 | if (null === $this->uploadfile) { 151 | throw new Exception("uploadfile {$this->postFieldName} not exist"); 152 | } 153 | 154 | if (null !== $this->beforeValidate) { 155 | call_user_func($this->beforeValidate, $this); 156 | } 157 | $this->validate(); 158 | if (null !== $this->afterValidate) { 159 | call_user_func($this->afterValidate, $this); 160 | } 161 | if (null !== $this->beforeSave) { 162 | call_user_func($this->beforeSave, $this); 163 | } 164 | $this->save(); 165 | if ($this->afterSave !== null) { 166 | call_user_func($this->afterSave, $this); 167 | } 168 | } catch (Exception $e) { 169 | $this->output['error'] = true; 170 | $this->output['msg'] = $e->getMessage(); 171 | } 172 | Yii::$app->response->format = 'json'; 173 | return $this->output; 174 | } 175 | 176 | /** 177 | * @throws Exception 178 | */ 179 | protected function save() 180 | { 181 | $filename = $this->getFilename(); 182 | $basePath = $this->basePath; 183 | $saveFilename = $basePath . '/' . $filename; 184 | $dirPath = dirname($saveFilename); 185 | if (false === is_dir($dirPath) && false === file_exists($dirPath)) { 186 | if (false === mkdir($dirPath, $this->dirChmod, true)) { 187 | throw new Exception("Create Directory Fail: {$dirPath}"); 188 | } 189 | } 190 | $saveResult = $this->uploadfile->saveAs($saveFilename); 191 | if (true === $saveResult) { 192 | if (false === chmod($saveFilename, $this->fileChmod)) { 193 | throw new Exception("SetChmod Fail: {$this->fileChmod} {$saveFilename}"); 194 | } 195 | } else { 196 | throw new Exception("SaveAsFile Fail: {$saveFilename}"); 197 | } 198 | } 199 | 200 | /** 201 | * 取得没有碰撞的FileName 202 | * @return string 203 | * @throws Exception 204 | */ 205 | protected function getSaveFileNameWithNotExist() 206 | { 207 | $retryCount = 10; 208 | $currentCount = 0; 209 | $basePath = $this->basePath; 210 | $filename = ''; 211 | do { 212 | ++$currentCount; 213 | $filename = $this->getSaveFileName(); 214 | $filepath = $basePath . DIRECTORY_SEPARATOR . $filename; 215 | } while ($currentCount < $retryCount && file_exists($filepath)); 216 | if ($currentCount == $retryCount) { 217 | throw new Exception(__FUNCTION__ . " try {$currentCount} times"); 218 | } 219 | return $filename; 220 | } 221 | 222 | /** 223 | * @return string 224 | * @throws Exception 225 | */ 226 | protected function getSaveFileName() 227 | { 228 | return call_user_func($this->format, $this); 229 | } 230 | 231 | /** 232 | * @throws Exception 233 | */ 234 | protected function validate() 235 | { 236 | if (empty($this->validateOptions)) { 237 | return; 238 | } 239 | $file = $this->uploadfile; 240 | $error = []; 241 | $validator = new FileValidator($this->validateOptions); 242 | if (!$validator->validate($file, $error)) { 243 | throw new Exception($error); 244 | } 245 | } 246 | 247 | protected function initCsrf() 248 | { 249 | $session = Yii::$app->getSession(); 250 | $request = Yii::$app->getRequest(); 251 | if (false === $this->enableCsrf) { 252 | return; 253 | } 254 | $request->enableCsrfValidation = true; 255 | $request->enableCsrfCookie = false; //verify with session 256 | $sessionName = $session->getName(); 257 | $postSessionId = $request->post($sessionName); 258 | if ($postSessionId != $session->getId()) { 259 | $session->destroy(); 260 | $session->setId($postSessionId); 261 | $session->open(); 262 | } 263 | } 264 | 265 | /** 266 | * @return string 267 | * @throws Exception 268 | */ 269 | public function getFilename() 270 | { 271 | if (null === $this->filename) { 272 | if ($this->overwriteIfExist) { 273 | $this->filename = $this->getSaveFileName(); 274 | } else { 275 | $this->filename = $this->getSaveFileNameWithNotExist(); 276 | } 277 | } 278 | return $this->filename; 279 | } 280 | 281 | /** 282 | * @return string 283 | */ 284 | public function getSavePath() 285 | { 286 | return rtrim($this->basePath, '\\/') . '/' . $this->filename; 287 | } 288 | 289 | /** 290 | * @return string 291 | */ 292 | public function getWebUrl() 293 | { 294 | return rtrim($this->baseUrl, '\\/') . '/' . $this->filename; 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /Uploadify.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Uploadify extends InputWidget 18 | { 19 | 20 | /** 21 | * upload file to URL 22 | * @var string 23 | * @example 24 | * http://xxxxx/upload.php 25 | * ['article/upload'] 26 | * ['upload'] 27 | */ 28 | public $url; 29 | 30 | /** 31 | * @var bool 32 | */ 33 | public $csrf = true; 34 | 35 | /** 36 | * 是否渲染Tag 37 | * @var bool 38 | */ 39 | public $renderTag = true; 40 | 41 | /** 42 | * uploadify js options 43 | * @var array 44 | * @example 45 | * [ 46 | * 'height' => 30, 47 | * 'width' => 120, 48 | * 'swf' => '/uploadify/uploadify.swf', 49 | * 'uploader' => '/uploadify/uploadify.php', 50 | * ] 51 | * @see http://www.uploadify.com/documentation/ 52 | */ 53 | public $jsOptions = []; 54 | 55 | /** 56 | * @var int 57 | */ 58 | public $registerJsPos = View::POS_LOAD; 59 | 60 | /** 61 | * Initializes the widget. 62 | */ 63 | public function init() 64 | { 65 | //init var 66 | if (empty($this->url)) { 67 | throw new InvalidConfigException('Url must be set'); 68 | } 69 | if (empty($this->id)) { 70 | $this->id = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId(); 71 | } 72 | $this->options['id'] = $this->id; 73 | if (empty($this->name)) { 74 | $this->name = $this->hasModel() ? Html::getInputName($this->model, $this->attribute) : $this->id; 75 | } 76 | 77 | //register Assets 78 | $assets = UploadifyAsset::register($this->view); 79 | 80 | $this->initOptions($assets); 81 | $this->initCsrfOption(); 82 | 83 | parent::init(); 84 | } 85 | 86 | /** 87 | * Renders the widget. 88 | */ 89 | public function run() 90 | { 91 | $this->registerScripts(); 92 | if ($this->renderTag === true) { 93 | echo $this->renderTag(); 94 | } 95 | } 96 | 97 | /** 98 | * init Uploadify options 99 | * @param [] $assets 100 | * @return void 101 | */ 102 | protected function initOptions($assets) 103 | { 104 | $baseUrl = $assets->baseUrl; 105 | 106 | $this->jsOptions['uploader'] = $this->url; 107 | $this->jsOptions['swf'] = $baseUrl . '/uploadify.swf'; 108 | 109 | } 110 | 111 | /** 112 | * @return void 113 | */ 114 | protected function initCsrfOption() 115 | { 116 | if (false === $this->csrf) { 117 | return; 118 | } 119 | $request = Yii::$app->request; 120 | $request->enableCsrfValidation = true; 121 | $csrfParam = $request->csrfParam; 122 | $csrfValue = $request->getCsrfToken(); 123 | $session = Yii::$app->session; 124 | $session->open(); 125 | 126 | //write csrfValue to session 127 | if ($request->enableCookieValidation) { 128 | $cookieCsrfValue = Yii::$app->getRequest()->getCookies()->getValue($csrfParam); 129 | if (null === $cookieCsrfValue) { 130 | $cookieCsrfValue = Yii::$app->getResponse()->getCookies()->getValue($csrfParam); 131 | } 132 | $session->set($csrfParam, $cookieCsrfValue); 133 | } 134 | 135 | $sessionIdName = $session->getName(); 136 | $sessionIdValue = $session->getId(); 137 | $this->jsOptions = ArrayHelper::merge($this->jsOptions, [ 138 | 'formData' => [ 139 | $sessionIdName => $sessionIdValue, 140 | $csrfParam => $csrfValue, 141 | ] 142 | ]); 143 | } 144 | 145 | /** 146 | * render file input tag 147 | * @return string 148 | */ 149 | protected function renderTag() 150 | { 151 | return Html::fileInput($this->name, null, $this->options); 152 | } 153 | 154 | /** 155 | * register script 156 | */ 157 | protected function registerScripts() 158 | { 159 | $jsonOptions = Json::encode($this->jsOptions); 160 | $script = <<id}').uploadify({$jsonOptions}); 162 | EOF; 163 | $this->view->registerJs($script, $this->registerJsPos); 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /UploadifyAsset.php: -------------------------------------------------------------------------------- 1 | 3 | is released under the MIT License 4 | */ 5 | ;var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null; 6 | if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true; 7 | X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10); 8 | ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0;}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version"); 9 | if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)];}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}; 10 | }(),k=function(){if(!M.w3){return;}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f(); 11 | }if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false);}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee); 12 | f();}});if(O==top){(function(){if(J){return;}try{j.documentElement.doScroll("left");}catch(X){setTimeout(arguments.callee,0);return;}f();})();}}if(M.wk){(function(){if(J){return; 13 | }if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return;}f();})();}s(f);}}();function f(){if(J){return;}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span")); 14 | Z.parentNode.removeChild(Z);}catch(aa){return;}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y); 20 | if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa);}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall; 21 | ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class");}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align"); 22 | }var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'; 35 | }}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id);}else{var Z=C(r);Z.setAttribute("type",q); 36 | for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac]);}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac]); 37 | }}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab]);}}aa.parentNode.replaceChild(Z,aa);X=Z;}}return X;}function e(Z,X,Y){var aa=C("param"); 38 | aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa);}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none"; 39 | (function(){if(X.readyState==4){b(Y);}else{setTimeout(arguments.callee,10);}})();}else{X.parentNode.removeChild(X);}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null; 40 | }}Y.parentNode.removeChild(Y);}}function c(Z){var X=null;try{X=j.getElementById(Z);}catch(Y){}return X;}function C(X){return j.createElement(X);}function i(Z,X,Y){Z.attachEvent(X,Y); 41 | I[I.length]=[Z,X,Y];}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false; 42 | }function v(ac,Y,ad,ab){if(M.ie&&M.mac){return;}var aa=j.getElementsByTagName("head")[0];if(!aa){return;}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null; 43 | G=null;}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]; 44 | }G=X;}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y);}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}")); 45 | }}}function w(Z,X){if(!m){return;}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y;}else{v("#"+Z,"visibility:"+Y);}}function L(Y){var Z=/[\\\"<>\.;]/; 46 | var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y;}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length; 47 | for(var ab=0;ab','','','','','','',""].join("")};SWFUpload.prototype.getFlashVars=function(){var b=this.buildParamString();var a=this.settings.http_success.join(",");return["movieName=",encodeURIComponent(this.movieName),"&uploadURL=",encodeURIComponent(this.settings.upload_url),"&useQueryString=",encodeURIComponent(this.settings.use_query_string),"&requeueOnError=",encodeURIComponent(this.settings.requeue_on_error),"&httpSuccess=",encodeURIComponent(a),"&assumeSuccessTimeout=",encodeURIComponent(this.settings.assume_success_timeout),"&params=",encodeURIComponent(b),"&filePostName=",encodeURIComponent(this.settings.file_post_name),"&fileTypes=",encodeURIComponent(this.settings.file_types),"&fileTypesDescription=",encodeURIComponent(this.settings.file_types_description),"&fileSizeLimit=",encodeURIComponent(this.settings.file_size_limit),"&fileUploadLimit=",encodeURIComponent(this.settings.file_upload_limit),"&fileQueueLimit=",encodeURIComponent(this.settings.file_queue_limit),"&debugEnabled=",encodeURIComponent(this.settings.debug_enabled),"&buttonImageURL=",encodeURIComponent(this.settings.button_image_url),"&buttonWidth=",encodeURIComponent(this.settings.button_width),"&buttonHeight=",encodeURIComponent(this.settings.button_height),"&buttonText=",encodeURIComponent(this.settings.button_text),"&buttonTextTopPadding=",encodeURIComponent(this.settings.button_text_top_padding),"&buttonTextLeftPadding=",encodeURIComponent(this.settings.button_text_left_padding),"&buttonTextStyle=",encodeURIComponent(this.settings.button_text_style),"&buttonAction=",encodeURIComponent(this.settings.button_action),"&buttonDisabled=",encodeURIComponent(this.settings.button_disabled),"&buttonCursor=",encodeURIComponent(this.settings.button_cursor)].join("")};SWFUpload.prototype.getMovieElement=function(){if(this.movieElement==undefined){this.movieElement=document.getElementById(this.movieName)}if(this.movieElement===null){throw"Could not find Flash element"}return this.movieElement};SWFUpload.prototype.buildParamString=function(){var c=this.settings.post_params;var b=[];if(typeof(c)==="object"){for(var a in c){if(c.hasOwnProperty(a)){b.push(encodeURIComponent(a.toString())+"="+encodeURIComponent(c[a].toString()))}}}return b.join("&")};SWFUpload.prototype.destroy=function(){try{this.cancelUpload(null,false);var a=null;a=this.getMovieElement();if(a&&typeof(a.CallFunction)==="unknown"){for(var c in a){try{if(typeof(a[c])==="function"){a[c]=null}}catch(e){}}try{a.parentNode.removeChild(a)}catch(b){}}window[this.movieName]=null;SWFUpload.instances[this.movieName]=null;delete SWFUpload.instances[this.movieName];this.movieElement=null;this.settings=null;this.customSettings=null;this.eventQueue=null;this.movieName=null;return true}catch(d){return false}};SWFUpload.prototype.displayDebugInfo=function(){this.debug(["---SWFUpload Instance Info---\n","Version: ",SWFUpload.version,"\n","Movie Name: ",this.movieName,"\n","Settings:\n","\t","upload_url: ",this.settings.upload_url,"\n","\t","flash_url: ",this.settings.flash_url,"\n","\t","use_query_string: ",this.settings.use_query_string.toString(),"\n","\t","requeue_on_error: ",this.settings.requeue_on_error.toString(),"\n","\t","http_success: ",this.settings.http_success.join(", "),"\n","\t","assume_success_timeout: ",this.settings.assume_success_timeout,"\n","\t","file_post_name: ",this.settings.file_post_name,"\n","\t","post_params: ",this.settings.post_params.toString(),"\n","\t","file_types: ",this.settings.file_types,"\n","\t","file_types_description: ",this.settings.file_types_description,"\n","\t","file_size_limit: ",this.settings.file_size_limit,"\n","\t","file_upload_limit: ",this.settings.file_upload_limit,"\n","\t","file_queue_limit: ",this.settings.file_queue_limit,"\n","\t","debug: ",this.settings.debug.toString(),"\n","\t","prevent_swf_caching: ",this.settings.prevent_swf_caching.toString(),"\n","\t","button_placeholder_id: ",this.settings.button_placeholder_id.toString(),"\n","\t","button_placeholder: ",(this.settings.button_placeholder?"Set":"Not Set"),"\n","\t","button_image_url: ",this.settings.button_image_url.toString(),"\n","\t","button_width: ",this.settings.button_width.toString(),"\n","\t","button_height: ",this.settings.button_height.toString(),"\n","\t","button_text: ",this.settings.button_text.toString(),"\n","\t","button_text_style: ",this.settings.button_text_style.toString(),"\n","\t","button_text_top_padding: ",this.settings.button_text_top_padding.toString(),"\n","\t","button_text_left_padding: ",this.settings.button_text_left_padding.toString(),"\n","\t","button_action: ",this.settings.button_action.toString(),"\n","\t","button_disabled: ",this.settings.button_disabled.toString(),"\n","\t","custom_settings: ",this.settings.custom_settings.toString(),"\n","Event Handlers:\n","\t","swfupload_loaded_handler assigned: ",(typeof this.settings.swfupload_loaded_handler==="function").toString(),"\n","\t","file_dialog_start_handler assigned: ",(typeof this.settings.file_dialog_start_handler==="function").toString(),"\n","\t","file_queued_handler assigned: ",(typeof this.settings.file_queued_handler==="function").toString(),"\n","\t","file_queue_error_handler assigned: ",(typeof this.settings.file_queue_error_handler==="function").toString(),"\n","\t","upload_start_handler assigned: ",(typeof this.settings.upload_start_handler==="function").toString(),"\n","\t","upload_progress_handler assigned: ",(typeof this.settings.upload_progress_handler==="function").toString(),"\n","\t","upload_error_handler assigned: ",(typeof this.settings.upload_error_handler==="function").toString(),"\n","\t","upload_success_handler assigned: ",(typeof this.settings.upload_success_handler==="function").toString(),"\n","\t","upload_complete_handler assigned: ",(typeof this.settings.upload_complete_handler==="function").toString(),"\n","\t","debug_handler assigned: ",(typeof this.settings.debug_handler==="function").toString(),"\n"].join(""))};SWFUpload.prototype.addSetting=function(b,c,a){if(c==undefined){return(this.settings[b]=a)}else{return(this.settings[b]=c)}};SWFUpload.prototype.getSetting=function(a){if(this.settings[a]!=undefined){return this.settings[a]}return""};SWFUpload.prototype.callFlash=function(functionName,argumentArray){argumentArray=argumentArray||[];var movieElement=this.getMovieElement();var returnValue,returnString;try{returnString=movieElement.CallFunction(''+__flash__argumentsToXML(argumentArray,0)+"");returnValue=eval(returnString)}catch(ex){throw"Call to "+functionName+" failed"}if(returnValue!=undefined&&typeof returnValue.post==="object"){returnValue=this.unescapeFilePostParams(returnValue)}return returnValue};SWFUpload.prototype.selectFile=function(){this.callFlash("SelectFile")};SWFUpload.prototype.selectFiles=function(){this.callFlash("SelectFiles")};SWFUpload.prototype.startUpload=function(a){this.callFlash("StartUpload",[a])};SWFUpload.prototype.cancelUpload=function(a,b){if(b!==false){b=true}this.callFlash("CancelUpload",[a,b])};SWFUpload.prototype.stopUpload=function(){this.callFlash("StopUpload")};SWFUpload.prototype.getStats=function(){return this.callFlash("GetStats")};SWFUpload.prototype.setStats=function(a){this.callFlash("SetStats",[a])};SWFUpload.prototype.getFile=function(a){if(typeof(a)==="number"){return this.callFlash("GetFileByIndex",[a])}else{return this.callFlash("GetFile",[a])}};SWFUpload.prototype.addFileParam=function(a,b,c){return this.callFlash("AddFileParam",[a,b,c])};SWFUpload.prototype.removeFileParam=function(a,b){this.callFlash("RemoveFileParam",[a,b])};SWFUpload.prototype.setUploadURL=function(a){this.settings.upload_url=a.toString();this.callFlash("SetUploadURL",[a])};SWFUpload.prototype.setPostParams=function(a){this.settings.post_params=a;this.callFlash("SetPostParams",[a])};SWFUpload.prototype.addPostParam=function(a,b){this.settings.post_params[a]=b;this.callFlash("SetPostParams",[this.settings.post_params])};SWFUpload.prototype.removePostParam=function(a){delete this.settings.post_params[a];this.callFlash("SetPostParams",[this.settings.post_params])};SWFUpload.prototype.setFileTypes=function(a,b){this.settings.file_types=a;this.settings.file_types_description=b;this.callFlash("SetFileTypes",[a,b])};SWFUpload.prototype.setFileSizeLimit=function(a){this.settings.file_size_limit=a;this.callFlash("SetFileSizeLimit",[a])};SWFUpload.prototype.setFileUploadLimit=function(a){this.settings.file_upload_limit=a;this.callFlash("SetFileUploadLimit",[a])};SWFUpload.prototype.setFileQueueLimit=function(a){this.settings.file_queue_limit=a;this.callFlash("SetFileQueueLimit",[a])};SWFUpload.prototype.setFilePostName=function(a){this.settings.file_post_name=a;this.callFlash("SetFilePostName",[a])};SWFUpload.prototype.setUseQueryString=function(a){this.settings.use_query_string=a;this.callFlash("SetUseQueryString",[a])};SWFUpload.prototype.setRequeueOnError=function(a){this.settings.requeue_on_error=a;this.callFlash("SetRequeueOnError",[a])};SWFUpload.prototype.setHTTPSuccess=function(a){if(typeof a==="string"){a=a.replace(" ","").split(",")}this.settings.http_success=a;this.callFlash("SetHTTPSuccess",[a])};SWFUpload.prototype.setAssumeSuccessTimeout=function(a){this.settings.assume_success_timeout=a;this.callFlash("SetAssumeSuccessTimeout",[a])};SWFUpload.prototype.setDebugEnabled=function(a){this.settings.debug_enabled=a;this.callFlash("SetDebugEnabled",[a])};SWFUpload.prototype.setButtonImageURL=function(a){if(a==undefined){a=""}this.settings.button_image_url=a;this.callFlash("SetButtonImageURL",[a])};SWFUpload.prototype.setButtonDimensions=function(c,a){this.settings.button_width=c;this.settings.button_height=a;var b=this.getMovieElement();if(b!=undefined){b.style.width=c+"px";b.style.height=a+"px"}this.callFlash("SetButtonDimensions",[c,a])};SWFUpload.prototype.setButtonText=function(a){this.settings.button_text=a;this.callFlash("SetButtonText",[a])};SWFUpload.prototype.setButtonTextPadding=function(b,a){this.settings.button_text_top_padding=a;this.settings.button_text_left_padding=b;this.callFlash("SetButtonTextPadding",[b,a])};SWFUpload.prototype.setButtonTextStyle=function(a){this.settings.button_text_style=a;this.callFlash("SetButtonTextStyle",[a])};SWFUpload.prototype.setButtonDisabled=function(a){this.settings.button_disabled=a;this.callFlash("SetButtonDisabled",[a])};SWFUpload.prototype.setButtonAction=function(a){this.settings.button_action=a;this.callFlash("SetButtonAction",[a])};SWFUpload.prototype.setButtonCursor=function(a){this.settings.button_cursor=a;this.callFlash("SetButtonCursor",[a])};SWFUpload.prototype.queueEvent=function(b,c){if(c==undefined){c=[]}else{if(!(c instanceof Array)){c=[c]}}var a=this;if(typeof this.settings[b]==="function"){this.eventQueue.push(function(){this.settings[b].apply(this,c)});setTimeout(function(){a.executeNextEvent()},0)}else{if(this.settings[b]!==null){throw"Event handler "+b+" is unknown or is not a function"}}};SWFUpload.prototype.executeNextEvent=function(){var a=this.eventQueue?this.eventQueue.shift():null;if(typeof(a)==="function"){a.apply(this)}};SWFUpload.prototype.unescapeFilePostParams=function(c){var e=/[$]([0-9a-f]{4})/i;var f={};var d;if(c!=undefined){for(var a in c.post){if(c.post.hasOwnProperty(a)){d=a;var b;while((b=e.exec(d))!==null){d=d.replace(b[0],String.fromCharCode(parseInt("0x"+b[1],16)))}f[d]=c.post[a]}}c.post=f}return c};SWFUpload.prototype.testExternalInterface=function(){try{return this.callFlash("TestExternalInterface")}catch(a){return false}};SWFUpload.prototype.flashReady=function(){var a=this.getMovieElement();if(!a){this.debug("Flash called back ready but the flash movie can't be found.");return}this.cleanUp(a);this.queueEvent("swfupload_loaded_handler")};SWFUpload.prototype.cleanUp=function(a){try{if(this.movieElement&&typeof(a.CallFunction)==="unknown"){this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");for(var c in a){try{if(typeof(a[c])==="function"){a[c]=null}}catch(b){}}}}catch(d){}window.__flash__removeCallback=function(e,f){try{if(e){e[f]=null}}catch(g){}}};SWFUpload.prototype.fileDialogStart=function(){this.queueEvent("file_dialog_start_handler")};SWFUpload.prototype.fileQueued=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("file_queued_handler",a)};SWFUpload.prototype.fileQueueError=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("file_queue_error_handler",[a,c,b])};SWFUpload.prototype.fileDialogComplete=function(b,c,a){this.queueEvent("file_dialog_complete_handler",[b,c,a])};SWFUpload.prototype.uploadStart=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("return_upload_start_handler",a)};SWFUpload.prototype.returnUploadStart=function(a){var b;if(typeof this.settings.upload_start_handler==="function"){a=this.unescapeFilePostParams(a);b=this.settings.upload_start_handler.call(this,a)}else{if(this.settings.upload_start_handler!=undefined){throw"upload_start_handler must be a function"}}if(b===undefined){b=true}b=!!b;this.callFlash("ReturnUploadStart",[b])};SWFUpload.prototype.uploadProgress=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("upload_progress_handler",[a,c,b])};SWFUpload.prototype.uploadError=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("upload_error_handler",[a,c,b])};SWFUpload.prototype.uploadSuccess=function(b,a,c){b=this.unescapeFilePostParams(b);this.queueEvent("upload_success_handler",[b,a,c])};SWFUpload.prototype.uploadComplete=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("upload_complete_handler",a)};SWFUpload.prototype.debug=function(a){this.queueEvent("debug_handler",a)};SWFUpload.prototype.debugMessage=function(c){if(this.settings.debug){var a,d=[];if(typeof c==="object"&&typeof c.name==="string"&&typeof c.message==="string"){for(var b in c){if(c.hasOwnProperty(b)){d.push(b+": "+c[b])}}a=d.join("\n")||"";d=a.split("\n");a="EXCEPTION: "+d.join("\nEXCEPTION: ");SWFUpload.Console.writeLine(a)}else{SWFUpload.Console.writeLine(c)}}};SWFUpload.Console={};SWFUpload.Console.writeLine=function(d){var b,a;try{b=document.getElementById("SWFUpload_Console");if(!b){a=document.createElement("form");document.getElementsByTagName("body")[0].appendChild(a);b=document.createElement("textarea");b.id="SWFUpload_Console";b.style.fontFamily="monospace";b.setAttribute("wrap","off");b.wrap="off";b.style.overflow="auto";b.style.width="700px";b.style.height="350px";b.style.margin="5px";a.appendChild(b)}b.value+=d+"\n";b.scrollTop=b.scrollHeight-b.clientHeight}catch(c){alert("Exception: "+c.name+" Message: "+c.message)}}; 73 | 74 | /* 75 | Uploadify v3.2.1 76 | Copyright (c) 2012 Reactive Apps, Ronnie Garcia 77 | Released under the MIT License 78 | */ 79 | 80 | (function($) { 81 | 82 | // These methods can be called by adding them as the first argument in the uploadify plugin call 83 | var methods = { 84 | 85 | init : function(options, swfUploadOptions) { 86 | 87 | return this.each(function() { 88 | 89 | // Create a reference to the jQuery DOM object 90 | var $this = $(this); 91 | 92 | // Clone the original DOM object 93 | var $clone = $this.clone(); 94 | 95 | // Setup the default options 96 | var settings = $.extend({ 97 | // Required Settings 98 | id : $this.attr('id'), // The ID of the DOM object 99 | swf : 'uploadify.swf', // The path to the uploadify SWF file 100 | uploader : 'uploadify.php', // The path to the server-side upload script 101 | 102 | // Options 103 | auto : true, // Automatically upload files when added to the queue 104 | buttonClass : '', // A class name to add to the browse button DOM object 105 | buttonCursor : 'hand', // The cursor to use with the browse button 106 | buttonImage : null, // (String or null) The path to an image to use for the Flash browse button if not using CSS to style the button 107 | buttonText : 'SELECT FILES', // The text to use for the browse button 108 | checkExisting : false, // The path to a server-side script that checks for existing files on the server 109 | debug : false, // Turn on swfUpload debugging mode 110 | fileObjName : 'Filedata', // The name of the file object to use in your server-side script 111 | fileSizeLimit : 0, // The maximum size of an uploadable file in KB (Accepts units B KB MB GB if string, 0 for no limit) 112 | fileTypeDesc : 'All Files', // The description for file types in the browse dialog 113 | fileTypeExts : '*.*', // Allowed extensions in the browse dialog (server-side validation should also be used) 114 | height : 30, // The height of the browse button 115 | itemTemplate : false, // The template for the file item in the queue 116 | method : 'post', // The method to use when sending files to the server-side upload script 117 | multi : true, // Allow multiple file selection in the browse dialog 118 | formData : {}, // An object with additional data to send to the server-side upload script with every file upload 119 | preventCaching : true, // Adds a random value to the Flash URL to prevent caching of it (conflicts with existing parameters) 120 | progressData : 'percentage', // ('percentage' or 'speed') Data to show in the queue item during a file upload 121 | queueID : false, // The ID of the DOM object to use as a file queue (without the #) 122 | queueSizeLimit : 999, // The maximum number of files that can be in the queue at one time 123 | removeCompleted : true, // Remove queue items from the queue when they are done uploading 124 | removeTimeout : 3, // The delay in seconds before removing a queue item if removeCompleted is set to true 125 | requeueErrors : false, // Keep errored files in the queue and keep trying to upload them 126 | successTimeout : 30, // The number of seconds to wait for Flash to detect the server's response after the file has finished uploading 127 | uploadLimit : 0, // The maximum number of files you can upload 128 | width : 120, // The width of the browse button 129 | 130 | // Events 131 | overrideEvents : [] // (Array) A list of default event handlers to skip 132 | /* 133 | onCancel // Triggered when a file is cancelled from the queue 134 | onClearQueue // Triggered during the 'clear queue' method 135 | onDestroy // Triggered when the uploadify object is destroyed 136 | onDialogClose // Triggered when the browse dialog is closed 137 | onDialogOpen // Triggered when the browse dialog is opened 138 | onDisable // Triggered when the browse button gets disabled 139 | onEnable // Triggered when the browse button gets enabled 140 | onFallback // Triggered is Flash is not detected 141 | onInit // Triggered when Uploadify is initialized 142 | onQueueComplete // Triggered when all files in the queue have been uploaded 143 | onSelectError // Triggered when an error occurs while selecting a file (file size, queue size limit, etc.) 144 | onSelect // Triggered for each file that is selected 145 | onSWFReady // Triggered when the SWF button is loaded 146 | onUploadComplete // Triggered when a file upload completes (success or error) 147 | onUploadError // Triggered when a file upload returns an error 148 | onUploadSuccess // Triggered when a file is uploaded successfully 149 | onUploadProgress // Triggered every time a file progress is updated 150 | onUploadStart // Triggered immediately before a file upload starts 151 | */ 152 | }, options); 153 | 154 | // Prepare settings for SWFUpload 155 | var swfUploadSettings = { 156 | assume_success_timeout : settings.successTimeout, 157 | button_placeholder_id : settings.id, 158 | button_width : settings.width, 159 | button_height : settings.height, 160 | button_text : null, 161 | button_text_style : null, 162 | button_text_top_padding : 0, 163 | button_text_left_padding : 0, 164 | button_action : (settings.multi ? SWFUpload.BUTTON_ACTION.SELECT_FILES : SWFUpload.BUTTON_ACTION.SELECT_FILE), 165 | button_disabled : false, 166 | button_cursor : (settings.buttonCursor == 'arrow' ? SWFUpload.CURSOR.ARROW : SWFUpload.CURSOR.HAND), 167 | button_window_mode : SWFUpload.WINDOW_MODE.TRANSPARENT, 168 | debug : settings.debug, 169 | requeue_on_error : settings.requeueErrors, 170 | file_post_name : settings.fileObjName, 171 | file_size_limit : settings.fileSizeLimit, 172 | file_types : settings.fileTypeExts, 173 | file_types_description : settings.fileTypeDesc, 174 | file_queue_limit : settings.queueSizeLimit, 175 | file_upload_limit : settings.uploadLimit, 176 | flash_url : settings.swf, 177 | prevent_swf_caching : settings.preventCaching, 178 | post_params : settings.formData, 179 | upload_url : settings.uploader, 180 | use_query_string : (settings.method == 'get'), 181 | 182 | // Event Handlers 183 | file_dialog_complete_handler : handlers.onDialogClose, 184 | file_dialog_start_handler : handlers.onDialogOpen, 185 | file_queued_handler : handlers.onSelect, 186 | file_queue_error_handler : handlers.onSelectError, 187 | swfupload_loaded_handler : settings.onSWFReady, 188 | upload_complete_handler : handlers.onUploadComplete, 189 | upload_error_handler : handlers.onUploadError, 190 | upload_progress_handler : handlers.onUploadProgress, 191 | upload_start_handler : handlers.onUploadStart, 192 | upload_success_handler : handlers.onUploadSuccess 193 | } 194 | 195 | // Merge the user-defined options with the defaults 196 | if (swfUploadOptions) { 197 | swfUploadSettings = $.extend(swfUploadSettings, swfUploadOptions); 198 | } 199 | // Add the user-defined settings to the swfupload object 200 | swfUploadSettings = $.extend(swfUploadSettings, settings); 201 | 202 | // Detect if Flash is available 203 | var playerVersion = swfobject.getFlashPlayerVersion(); 204 | var flashInstalled = (playerVersion.major >= 9); 205 | 206 | if (flashInstalled) { 207 | // Create the swfUpload instance 208 | window['uploadify_' + settings.id] = new SWFUpload(swfUploadSettings); 209 | var swfuploadify = window['uploadify_' + settings.id]; 210 | 211 | // Add the SWFUpload object to the elements data object 212 | $this.data('uploadify', swfuploadify); 213 | 214 | // Wrap the instance 215 | var $wrapper = $('
', { 216 | 'id' : settings.id, 217 | 'class' : 'uploadify', 218 | 'css' : { 219 | 'height' : settings.height + 'px', 220 | 'width' : settings.width + 'px' 221 | } 222 | }); 223 | $('#' + swfuploadify.movieName).wrap($wrapper); 224 | // Recreate the reference to wrapper 225 | $wrapper = $('#' + settings.id); 226 | // Add the data object to the wrapper 227 | $wrapper.data('uploadify', swfuploadify); 228 | 229 | // Create the button 230 | var $button = $('
', { 231 | 'id' : settings.id + '-button', 232 | 'class' : 'uploadify-button ' + settings.buttonClass 233 | }); 234 | if (settings.buttonImage) { 235 | $button.css({ 236 | 'background-image' : "url('" + settings.buttonImage + "')", 237 | 'text-indent' : '-9999px' 238 | }); 239 | } 240 | $button.html('' + settings.buttonText + '') 241 | .css({ 242 | 'height' : settings.height + 'px', 243 | 'line-height' : settings.height + 'px', 244 | 'width' : settings.width + 'px' 245 | }); 246 | // Append the button to the wrapper 247 | $wrapper.append($button); 248 | 249 | // Adjust the styles of the movie 250 | $('#' + swfuploadify.movieName).css({ 251 | 'position' : 'absolute', 252 | 'z-index' : 1 253 | }); 254 | 255 | // Create the file queue 256 | if (!settings.queueID) { 257 | var $queue = $('
', { 258 | 'id' : settings.id + '-queue', 259 | 'class' : 'uploadify-queue' 260 | }); 261 | $wrapper.after($queue); 262 | swfuploadify.settings.queueID = settings.id + '-queue'; 263 | swfuploadify.settings.defaultQueue = true; 264 | } 265 | 266 | // Create some queue related objects and variables 267 | swfuploadify.queueData = { 268 | files : {}, // The files in the queue 269 | filesSelected : 0, // The number of files selected in the last select operation 270 | filesQueued : 0, // The number of files added to the queue in the last select operation 271 | filesReplaced : 0, // The number of files replaced in the last select operation 272 | filesCancelled : 0, // The number of files that were cancelled instead of replaced 273 | filesErrored : 0, // The number of files that caused error in the last select operation 274 | uploadsSuccessful : 0, // The number of files that were successfully uploaded 275 | uploadsErrored : 0, // The number of files that returned errors during upload 276 | averageSpeed : 0, // The average speed of the uploads in KB 277 | queueLength : 0, // The number of files in the queue 278 | queueSize : 0, // The size in bytes of the entire queue 279 | uploadSize : 0, // The size in bytes of the upload queue 280 | queueBytesUploaded : 0, // The size in bytes that have been uploaded for the current upload queue 281 | uploadQueue : [], // The files currently to be uploaded 282 | errorMsg : 'Some files were not added to the queue:' 283 | }; 284 | 285 | // Save references to all the objects 286 | swfuploadify.original = $clone; 287 | swfuploadify.wrapper = $wrapper; 288 | swfuploadify.button = $button; 289 | swfuploadify.queue = $queue; 290 | 291 | // Call the user-defined init event handler 292 | if (settings.onInit) settings.onInit.call($this, swfuploadify); 293 | 294 | } else { 295 | 296 | // Call the fallback function 297 | if (settings.onFallback) settings.onFallback.call($this); 298 | 299 | } 300 | }); 301 | 302 | }, 303 | 304 | // Stop a file upload and remove it from the queue 305 | cancel : function(fileID, supressEvent) { 306 | 307 | var args = arguments; 308 | 309 | this.each(function() { 310 | // Create a reference to the jQuery DOM object 311 | var $this = $(this), 312 | swfuploadify = $this.data('uploadify'), 313 | settings = swfuploadify.settings, 314 | delay = -1; 315 | 316 | if (args[0]) { 317 | // Clear the queue 318 | if (args[0] == '*') { 319 | var queueItemCount = swfuploadify.queueData.queueLength; 320 | $('#' + settings.queueID).find('.uploadify-queue-item').each(function() { 321 | delay++; 322 | if (args[1] === true) { 323 | swfuploadify.cancelUpload($(this).attr('id'), false); 324 | } else { 325 | swfuploadify.cancelUpload($(this).attr('id')); 326 | } 327 | $(this).find('.data').removeClass('data').html(' - Cancelled'); 328 | $(this).find('.uploadify-progress-bar').remove(); 329 | $(this).delay(1000 + 100 * delay).fadeOut(500, function() { 330 | $(this).remove(); 331 | }); 332 | }); 333 | swfuploadify.queueData.queueSize = 0; 334 | swfuploadify.queueData.queueLength = 0; 335 | // Trigger the onClearQueue event 336 | if (settings.onClearQueue) settings.onClearQueue.call($this, queueItemCount); 337 | } else { 338 | for (var n = 0; n < args.length; n++) { 339 | swfuploadify.cancelUpload(args[n]); 340 | $('#' + args[n]).find('.data').removeClass('data').html(' - Cancelled'); 341 | $('#' + args[n]).find('.uploadify-progress-bar').remove(); 342 | $('#' + args[n]).delay(1000 + 100 * n).fadeOut(500, function() { 343 | $(this).remove(); 344 | }); 345 | } 346 | } 347 | } else { 348 | var item = $('#' + settings.queueID).find('.uploadify-queue-item').get(0); 349 | $item = $(item); 350 | swfuploadify.cancelUpload($item.attr('id')); 351 | $item.find('.data').removeClass('data').html(' - Cancelled'); 352 | $item.find('.uploadify-progress-bar').remove(); 353 | $item.delay(1000).fadeOut(500, function() { 354 | $(this).remove(); 355 | }); 356 | } 357 | }); 358 | 359 | }, 360 | 361 | // Revert the DOM object back to its original state 362 | destroy : function() { 363 | 364 | this.each(function() { 365 | // Create a reference to the jQuery DOM object 366 | var $this = $(this), 367 | swfuploadify = $this.data('uploadify'), 368 | settings = swfuploadify.settings; 369 | 370 | // Destroy the SWF object and 371 | swfuploadify.destroy(); 372 | 373 | // Destroy the queue 374 | if (settings.defaultQueue) { 375 | $('#' + settings.queueID).remove(); 376 | } 377 | 378 | // Reload the original DOM element 379 | $('#' + settings.id).replaceWith(swfuploadify.original); 380 | 381 | // Call the user-defined event handler 382 | if (settings.onDestroy) settings.onDestroy.call(this); 383 | 384 | delete swfuploadify; 385 | }); 386 | 387 | }, 388 | 389 | // Disable the select button 390 | disable : function(isDisabled) { 391 | 392 | this.each(function() { 393 | // Create a reference to the jQuery DOM object 394 | var $this = $(this), 395 | swfuploadify = $this.data('uploadify'), 396 | settings = swfuploadify.settings; 397 | 398 | // Call the user-defined event handlers 399 | if (isDisabled) { 400 | swfuploadify.button.addClass('disabled'); 401 | if (settings.onDisable) settings.onDisable.call(this); 402 | } else { 403 | swfuploadify.button.removeClass('disabled'); 404 | if (settings.onEnable) settings.onEnable.call(this); 405 | } 406 | 407 | // Enable/disable the browse button 408 | swfuploadify.setButtonDisabled(isDisabled); 409 | }); 410 | 411 | }, 412 | 413 | // Get or set the settings data 414 | settings : function(name, value, resetObjects) { 415 | 416 | var args = arguments; 417 | var returnValue = value; 418 | 419 | this.each(function() { 420 | // Create a reference to the jQuery DOM object 421 | var $this = $(this), 422 | swfuploadify = $this.data('uploadify'), 423 | settings = swfuploadify.settings; 424 | 425 | if (typeof(args[0]) == 'object') { 426 | for (var n in value) { 427 | setData(n,value[n]); 428 | } 429 | } 430 | if (args.length === 1) { 431 | returnValue = settings[name]; 432 | } else { 433 | switch (name) { 434 | case 'uploader': 435 | swfuploadify.setUploadURL(value); 436 | break; 437 | case 'formData': 438 | if (!resetObjects) { 439 | value = $.extend(settings.formData, value); 440 | } 441 | swfuploadify.setPostParams(settings.formData); 442 | break; 443 | case 'method': 444 | if (value == 'get') { 445 | swfuploadify.setUseQueryString(true); 446 | } else { 447 | swfuploadify.setUseQueryString(false); 448 | } 449 | break; 450 | case 'fileObjName': 451 | swfuploadify.setFilePostName(value); 452 | break; 453 | case 'fileTypeExts': 454 | swfuploadify.setFileTypes(value, settings.fileTypeDesc); 455 | break; 456 | case 'fileTypeDesc': 457 | swfuploadify.setFileTypes(settings.fileTypeExts, value); 458 | break; 459 | case 'fileSizeLimit': 460 | swfuploadify.setFileSizeLimit(value); 461 | break; 462 | case 'uploadLimit': 463 | swfuploadify.setFileUploadLimit(value); 464 | break; 465 | case 'queueSizeLimit': 466 | swfuploadify.setFileQueueLimit(value); 467 | break; 468 | case 'buttonImage': 469 | swfuploadify.button.css('background-image', settingValue); 470 | break; 471 | case 'buttonCursor': 472 | if (value == 'arrow') { 473 | swfuploadify.setButtonCursor(SWFUpload.CURSOR.ARROW); 474 | } else { 475 | swfuploadify.setButtonCursor(SWFUpload.CURSOR.HAND); 476 | } 477 | break; 478 | case 'buttonText': 479 | $('#' + settings.id + '-button').find('.uploadify-button-text').html(value); 480 | break; 481 | case 'width': 482 | swfuploadify.setButtonDimensions(value, settings.height); 483 | break; 484 | case 'height': 485 | swfuploadify.setButtonDimensions(settings.width, value); 486 | break; 487 | case 'multi': 488 | if (value) { 489 | swfuploadify.setButtonAction(SWFUpload.BUTTON_ACTION.SELECT_FILES); 490 | } else { 491 | swfuploadify.setButtonAction(SWFUpload.BUTTON_ACTION.SELECT_FILE); 492 | } 493 | break; 494 | } 495 | settings[name] = value; 496 | } 497 | }); 498 | 499 | if (args.length === 1) { 500 | return returnValue; 501 | } 502 | 503 | }, 504 | 505 | // Stop the current uploads and requeue what is in progress 506 | stop : function() { 507 | 508 | this.each(function() { 509 | // Create a reference to the jQuery DOM object 510 | var $this = $(this), 511 | swfuploadify = $this.data('uploadify'); 512 | 513 | // Reset the queue information 514 | swfuploadify.queueData.averageSpeed = 0; 515 | swfuploadify.queueData.uploadSize = 0; 516 | swfuploadify.queueData.bytesUploaded = 0; 517 | swfuploadify.queueData.uploadQueue = []; 518 | 519 | swfuploadify.stopUpload(); 520 | }); 521 | 522 | }, 523 | 524 | // Start uploading files in the queue 525 | upload : function() { 526 | 527 | var args = arguments; 528 | 529 | this.each(function() { 530 | // Create a reference to the jQuery DOM object 531 | var $this = $(this), 532 | swfuploadify = $this.data('uploadify'); 533 | 534 | // Reset the queue information 535 | swfuploadify.queueData.averageSpeed = 0; 536 | swfuploadify.queueData.uploadSize = 0; 537 | swfuploadify.queueData.bytesUploaded = 0; 538 | swfuploadify.queueData.uploadQueue = []; 539 | 540 | // Upload the files 541 | if (args[0]) { 542 | if (args[0] == '*') { 543 | swfuploadify.queueData.uploadSize = swfuploadify.queueData.queueSize; 544 | swfuploadify.queueData.uploadQueue.push('*'); 545 | swfuploadify.startUpload(); 546 | } else { 547 | for (var n = 0; n < args.length; n++) { 548 | swfuploadify.queueData.uploadSize += swfuploadify.queueData.files[args[n]].size; 549 | swfuploadify.queueData.uploadQueue.push(args[n]); 550 | } 551 | swfuploadify.startUpload(swfuploadify.queueData.uploadQueue.shift()); 552 | } 553 | } else { 554 | swfuploadify.startUpload(); 555 | } 556 | 557 | }); 558 | 559 | } 560 | 561 | } 562 | 563 | // These functions handle all the events that occur with the file uploader 564 | var handlers = { 565 | 566 | // Triggered when the file dialog is opened 567 | onDialogOpen : function() { 568 | // Load the swfupload settings 569 | var settings = this.settings; 570 | 571 | // Reset some queue info 572 | this.queueData.errorMsg = 'Some files were not added to the queue:'; 573 | this.queueData.filesReplaced = 0; 574 | this.queueData.filesCancelled = 0; 575 | 576 | // Call the user-defined event handler 577 | if (settings.onDialogOpen) settings.onDialogOpen.call(this); 578 | }, 579 | 580 | // Triggered when the browse dialog is closed 581 | onDialogClose : function(filesSelected, filesQueued, queueLength) { 582 | // Load the swfupload settings 583 | var settings = this.settings; 584 | 585 | // Update the queue information 586 | this.queueData.filesErrored = filesSelected - filesQueued; 587 | this.queueData.filesSelected = filesSelected; 588 | this.queueData.filesQueued = filesQueued - this.queueData.filesCancelled; 589 | this.queueData.queueLength = queueLength; 590 | 591 | // Run the default event handler 592 | if ($.inArray('onDialogClose', settings.overrideEvents) < 0) { 593 | if (this.queueData.filesErrored > 0) { 594 | alert(this.queueData.errorMsg); 595 | } 596 | } 597 | 598 | // Call the user-defined event handler 599 | if (settings.onDialogClose) settings.onDialogClose.call(this, this.queueData); 600 | 601 | // Upload the files if auto is true 602 | if (settings.auto) $('#' + settings.id).uploadify('upload', '*'); 603 | }, 604 | 605 | // Triggered once for each file added to the queue 606 | onSelect : function(file) { 607 | // Load the swfupload settings 608 | var settings = this.settings; 609 | 610 | // Check if a file with the same name exists in the queue 611 | var queuedFile = {}; 612 | for (var n in this.queueData.files) { 613 | queuedFile = this.queueData.files[n]; 614 | if (queuedFile.uploaded != true && queuedFile.name == file.name) { 615 | var replaceQueueItem = confirm('The file named "' + file.name + '" is already in the queue.\nDo you want to replace the existing item in the queue?'); 616 | if (!replaceQueueItem) { 617 | this.cancelUpload(file.id); 618 | this.queueData.filesCancelled++; 619 | return false; 620 | } else { 621 | $('#' + queuedFile.id).remove(); 622 | this.cancelUpload(queuedFile.id); 623 | this.queueData.filesReplaced++; 624 | } 625 | } 626 | } 627 | 628 | // Get the size of the file 629 | var fileSize = Math.round(file.size / 1024); 630 | var suffix = 'KB'; 631 | if (fileSize > 1000) { 632 | fileSize = Math.round(fileSize / 1000); 633 | suffix = 'MB'; 634 | } 635 | var fileSizeParts = fileSize.toString().split('.'); 636 | fileSize = fileSizeParts[0]; 637 | if (fileSizeParts.length > 1) { 638 | fileSize += '.' + fileSizeParts[1].substr(0,2); 639 | } 640 | fileSize += suffix; 641 | 642 | // Truncate the filename if it's too long 643 | var fileName = file.name; 644 | if (fileName.length > 25) { 645 | fileName = fileName.substr(0,25) + '...'; 646 | } 647 | 648 | // Create the file data object 649 | itemData = { 650 | 'fileID' : file.id, 651 | 'instanceID' : settings.id, 652 | 'fileName' : fileName, 653 | 'fileSize' : fileSize 654 | } 655 | 656 | // Create the file item template 657 | if (settings.itemTemplate == false) { 658 | settings.itemTemplate = '
\ 659 |
\ 660 | X\ 661 |
\ 662 | ${fileName} (${fileSize})\ 663 |
\ 664 |
\ 665 |
\ 666 |
'; 667 | } 668 | 669 | // Run the default event handler 670 | if ($.inArray('onSelect', settings.overrideEvents) < 0) { 671 | 672 | // Replace the item data in the template 673 | itemHTML = settings.itemTemplate; 674 | for (var d in itemData) { 675 | itemHTML = itemHTML.replace(new RegExp('\\$\\{' + d + '\\}', 'g'), itemData[d]); 676 | } 677 | 678 | // Add the file item to the queue 679 | $('#' + settings.queueID).append(itemHTML); 680 | } 681 | 682 | this.queueData.queueSize += file.size; 683 | this.queueData.files[file.id] = file; 684 | 685 | // Call the user-defined event handler 686 | if (settings.onSelect) settings.onSelect.apply(this, arguments); 687 | }, 688 | 689 | // Triggered when a file is not added to the queue 690 | onSelectError : function(file, errorCode, errorMsg) { 691 | // Load the swfupload settings 692 | var settings = this.settings; 693 | 694 | // Run the default event handler 695 | if ($.inArray('onSelectError', settings.overrideEvents) < 0) { 696 | switch(errorCode) { 697 | case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED: 698 | if (settings.queueSizeLimit > errorMsg) { 699 | this.queueData.errorMsg += '\nThe number of files selected exceeds the remaining upload limit (' + errorMsg + ').'; 700 | } else { 701 | this.queueData.errorMsg += '\nThe number of files selected exceeds the queue size limit (' + settings.queueSizeLimit + ').'; 702 | } 703 | break; 704 | case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: 705 | this.queueData.errorMsg += '\nThe file "' + file.name + '" exceeds the size limit (' + settings.fileSizeLimit + ').'; 706 | break; 707 | case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: 708 | this.queueData.errorMsg += '\nThe file "' + file.name + '" is empty.'; 709 | break; 710 | case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: 711 | this.queueData.errorMsg += '\nThe file "' + file.name + '" is not an accepted file type (' + settings.fileTypeDesc + ').'; 712 | break; 713 | } 714 | } 715 | if (errorCode != SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) { 716 | delete this.queueData.files[file.id]; 717 | } 718 | 719 | // Call the user-defined event handler 720 | if (settings.onSelectError) settings.onSelectError.apply(this, arguments); 721 | }, 722 | 723 | // Triggered when all the files in the queue have been processed 724 | onQueueComplete : function() { 725 | if (this.settings.onQueueComplete) this.settings.onQueueComplete.call(this, this.settings.queueData); 726 | }, 727 | 728 | // Triggered when a file upload successfully completes 729 | onUploadComplete : function(file) { 730 | // Load the swfupload settings 731 | var settings = this.settings, 732 | swfuploadify = this; 733 | 734 | // Check if all the files have completed uploading 735 | var stats = this.getStats(); 736 | this.queueData.queueLength = stats.files_queued; 737 | if (this.queueData.uploadQueue[0] == '*') { 738 | if (this.queueData.queueLength > 0) { 739 | this.startUpload(); 740 | } else { 741 | this.queueData.uploadQueue = []; 742 | 743 | // Call the user-defined event handler for queue complete 744 | if (settings.onQueueComplete) settings.onQueueComplete.call(this, this.queueData); 745 | } 746 | } else { 747 | if (this.queueData.uploadQueue.length > 0) { 748 | this.startUpload(this.queueData.uploadQueue.shift()); 749 | } else { 750 | this.queueData.uploadQueue = []; 751 | 752 | // Call the user-defined event handler for queue complete 753 | if (settings.onQueueComplete) settings.onQueueComplete.call(this, this.queueData); 754 | } 755 | } 756 | 757 | // Call the default event handler 758 | if ($.inArray('onUploadComplete', settings.overrideEvents) < 0) { 759 | if (settings.removeCompleted) { 760 | switch (file.filestatus) { 761 | case SWFUpload.FILE_STATUS.COMPLETE: 762 | setTimeout(function() { 763 | if ($('#' + file.id)) { 764 | swfuploadify.queueData.queueSize -= file.size; 765 | swfuploadify.queueData.queueLength -= 1; 766 | delete swfuploadify.queueData.files[file.id] 767 | $('#' + file.id).fadeOut(500, function() { 768 | $(this).remove(); 769 | }); 770 | } 771 | }, settings.removeTimeout * 1000); 772 | break; 773 | case SWFUpload.FILE_STATUS.ERROR: 774 | if (!settings.requeueErrors) { 775 | setTimeout(function() { 776 | if ($('#' + file.id)) { 777 | swfuploadify.queueData.queueSize -= file.size; 778 | swfuploadify.queueData.queueLength -= 1; 779 | delete swfuploadify.queueData.files[file.id]; 780 | $('#' + file.id).fadeOut(500, function() { 781 | $(this).remove(); 782 | }); 783 | } 784 | }, settings.removeTimeout * 1000); 785 | } 786 | break; 787 | } 788 | } else { 789 | file.uploaded = true; 790 | } 791 | } 792 | 793 | // Call the user-defined event handler 794 | if (settings.onUploadComplete) settings.onUploadComplete.call(this, file); 795 | }, 796 | 797 | // Triggered when a file upload returns an error 798 | onUploadError : function(file, errorCode, errorMsg) { 799 | // Load the swfupload settings 800 | var settings = this.settings; 801 | 802 | // Set the error string 803 | var errorString = 'Error'; 804 | switch(errorCode) { 805 | case SWFUpload.UPLOAD_ERROR.HTTP_ERROR: 806 | errorString = 'HTTP Error (' + errorMsg + ')'; 807 | break; 808 | case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL: 809 | errorString = 'Missing Upload URL'; 810 | break; 811 | case SWFUpload.UPLOAD_ERROR.IO_ERROR: 812 | errorString = 'IO Error'; 813 | break; 814 | case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR: 815 | errorString = 'Security Error'; 816 | break; 817 | case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED: 818 | alert('The upload limit has been reached (' + errorMsg + ').'); 819 | errorString = 'Exceeds Upload Limit'; 820 | break; 821 | case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED: 822 | errorString = 'Failed'; 823 | break; 824 | case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND: 825 | break; 826 | case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED: 827 | errorString = 'Validation Error'; 828 | break; 829 | case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED: 830 | errorString = 'Cancelled'; 831 | this.queueData.queueSize -= file.size; 832 | this.queueData.queueLength -= 1; 833 | if (file.status == SWFUpload.FILE_STATUS.IN_PROGRESS || $.inArray(file.id, this.queueData.uploadQueue) >= 0) { 834 | this.queueData.uploadSize -= file.size; 835 | } 836 | // Trigger the onCancel event 837 | if (settings.onCancel) settings.onCancel.call(this, file); 838 | delete this.queueData.files[file.id]; 839 | break; 840 | case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED: 841 | errorString = 'Stopped'; 842 | break; 843 | } 844 | 845 | // Call the default event handler 846 | if ($.inArray('onUploadError', settings.overrideEvents) < 0) { 847 | 848 | if (errorCode != SWFUpload.UPLOAD_ERROR.FILE_CANCELLED && errorCode != SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED) { 849 | $('#' + file.id).addClass('uploadify-error'); 850 | } 851 | 852 | // Reset the progress bar 853 | $('#' + file.id).find('.uploadify-progress-bar').css('width','1px'); 854 | 855 | // Add the error message to the queue item 856 | if (errorCode != SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND && file.status != SWFUpload.FILE_STATUS.COMPLETE) { 857 | $('#' + file.id).find('.data').html(' - ' + errorString); 858 | } 859 | } 860 | 861 | var stats = this.getStats(); 862 | this.queueData.uploadsErrored = stats.upload_errors; 863 | 864 | // Call the user-defined event handler 865 | if (settings.onUploadError) settings.onUploadError.call(this, file, errorCode, errorMsg, errorString); 866 | }, 867 | 868 | // Triggered periodically during a file upload 869 | onUploadProgress : function(file, fileBytesLoaded, fileTotalBytes) { 870 | // Load the swfupload settings 871 | var settings = this.settings; 872 | 873 | // Setup all the variables 874 | var timer = new Date(); 875 | var newTime = timer.getTime(); 876 | var lapsedTime = newTime - this.timer; 877 | if (lapsedTime > 500) { 878 | this.timer = newTime; 879 | } 880 | var lapsedBytes = fileBytesLoaded - this.bytesLoaded; 881 | this.bytesLoaded = fileBytesLoaded; 882 | var queueBytesLoaded = this.queueData.queueBytesUploaded + fileBytesLoaded; 883 | var percentage = Math.round(fileBytesLoaded / fileTotalBytes * 100); 884 | 885 | // Calculate the average speed 886 | var suffix = 'KB/s'; 887 | var mbs = 0; 888 | var kbs = (lapsedBytes / 1024) / (lapsedTime / 1000); 889 | kbs = Math.floor(kbs * 10) / 10; 890 | if (this.queueData.averageSpeed > 0) { 891 | this.queueData.averageSpeed = Math.floor((this.queueData.averageSpeed + kbs) / 2); 892 | } else { 893 | this.queueData.averageSpeed = Math.floor(kbs); 894 | } 895 | if (kbs > 1000) { 896 | mbs = (kbs * .001); 897 | this.queueData.averageSpeed = Math.floor(mbs); 898 | suffix = 'MB/s'; 899 | } 900 | 901 | // Call the default event handler 902 | if ($.inArray('onUploadProgress', settings.overrideEvents) < 0) { 903 | if (settings.progressData == 'percentage') { 904 | $('#' + file.id).find('.data').html(' - ' + percentage + '%'); 905 | } else if (settings.progressData == 'speed' && lapsedTime > 500) { 906 | $('#' + file.id).find('.data').html(' - ' + this.queueData.averageSpeed + suffix); 907 | } 908 | $('#' + file.id).find('.uploadify-progress-bar').css('width', percentage + '%'); 909 | } 910 | 911 | // Call the user-defined event handler 912 | if (settings.onUploadProgress) settings.onUploadProgress.call(this, file, fileBytesLoaded, fileTotalBytes, queueBytesLoaded, this.queueData.uploadSize); 913 | }, 914 | 915 | // Triggered right before a file is uploaded 916 | onUploadStart : function(file) { 917 | // Load the swfupload settings 918 | var settings = this.settings; 919 | 920 | var timer = new Date(); 921 | this.timer = timer.getTime(); 922 | this.bytesLoaded = 0; 923 | if (this.queueData.uploadQueue.length == 0) { 924 | this.queueData.uploadSize = file.size; 925 | } 926 | if (settings.checkExisting) { 927 | $.ajax({ 928 | type : 'POST', 929 | async : false, 930 | url : settings.checkExisting, 931 | data : {filename: file.name}, 932 | success : function(data) { 933 | if (data == 1) { 934 | var overwrite = confirm('A file with the name "' + file.name + '" already exists on the server.\nWould you like to replace the existing file?'); 935 | if (!overwrite) { 936 | this.cancelUpload(file.id); 937 | $('#' + file.id).remove(); 938 | if (this.queueData.uploadQueue.length > 0 && this.queueData.queueLength > 0) { 939 | if (this.queueData.uploadQueue[0] == '*') { 940 | this.startUpload(); 941 | } else { 942 | this.startUpload(this.queueData.uploadQueue.shift()); 943 | } 944 | } 945 | } 946 | } 947 | } 948 | }); 949 | } 950 | 951 | // Call the user-defined event handler 952 | if (settings.onUploadStart) settings.onUploadStart.call(this, file); 953 | }, 954 | 955 | // Triggered when a file upload returns a successful code 956 | onUploadSuccess : function(file, data, response) { 957 | // Load the swfupload settings 958 | var settings = this.settings; 959 | var stats = this.getStats(); 960 | this.queueData.uploadsSuccessful = stats.successful_uploads; 961 | this.queueData.queueBytesUploaded += file.size; 962 | 963 | // Call the default event handler 964 | if ($.inArray('onUploadSuccess', settings.overrideEvents) < 0) { 965 | $('#' + file.id).find('.data').html(' - Complete'); 966 | } 967 | 968 | // Call the user-defined event handler 969 | if (settings.onUploadSuccess) settings.onUploadSuccess.call(this, file, data, response); 970 | } 971 | 972 | } 973 | 974 | $.fn.uploadify = function(method) { 975 | 976 | if (methods[method]) { 977 | return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 978 | } else if (typeof method === 'object' || !method) { 979 | return methods.init.apply(this, arguments); 980 | } else { 981 | $.error('The method ' + method + ' does not exist in $.uploadify'); 982 | } 983 | 984 | } 985 | 986 | })($); -------------------------------------------------------------------------------- /assets/uploadify-cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjflyttp/yii2-uploadify-widget/5f538e5f7a61ba43bdae5114df3c9540b460d0cb/assets/uploadify-cancel.png -------------------------------------------------------------------------------- /assets/uploadify.css: -------------------------------------------------------------------------------- 1 | /* 2 | Uploadify 3 | Copyright (c) 2012 Reactive Apps, Ronnie Garcia 4 | Released under the MIT License 5 | */ 6 | 7 | .uploadify { 8 | position: relative; 9 | margin-bottom: 1em; 10 | } 11 | .uploadify-button { 12 | background-color: #505050; 13 | background-image: linear-gradient(bottom, #505050 0%, #707070 100%); 14 | background-image: -o-linear-gradient(bottom, #505050 0%, #707070 100%); 15 | background-image: -moz-linear-gradient(bottom, #505050 0%, #707070 100%); 16 | background-image: -webkit-linear-gradient(bottom, #505050 0%, #707070 100%); 17 | background-image: -ms-linear-gradient(bottom, #505050 0%, #707070 100%); 18 | background-image: -webkit-gradient( 19 | linear, 20 | left bottom, 21 | left top, 22 | color-stop(0, #505050), 23 | color-stop(1, #707070) 24 | ); 25 | background-position: center top; 26 | background-repeat: no-repeat; 27 | -webkit-border-radius: 30px; 28 | -moz-border-radius: 30px; 29 | border-radius: 30px; 30 | border: 2px solid #808080; 31 | color: #FFF; 32 | font: bold 12px Arial, Helvetica, sans-serif; 33 | text-align: center; 34 | text-shadow: 0 -1px 0 rgba(0,0,0,0.25); 35 | width: 100%; 36 | } 37 | .uploadify:hover .uploadify-button { 38 | background-color: #606060; 39 | background-image: linear-gradient(top, #606060 0%, #808080 100%); 40 | background-image: -o-linear-gradient(top, #606060 0%, #808080 100%); 41 | background-image: -moz-linear-gradient(top, #606060 0%, #808080 100%); 42 | background-image: -webkit-linear-gradient(top, #606060 0%, #808080 100%); 43 | background-image: -ms-linear-gradient(top, #606060 0%, #808080 100%); 44 | background-image: -webkit-gradient( 45 | linear, 46 | left bottom, 47 | left top, 48 | color-stop(0, #606060), 49 | color-stop(1, #808080) 50 | ); 51 | background-position: center bottom; 52 | } 53 | .uploadify-button.disabled { 54 | background-color: #D0D0D0; 55 | color: #808080; 56 | } 57 | .uploadify-queue { 58 | margin-bottom: 1em; 59 | } 60 | .uploadify-queue-item { 61 | background-color: #F5F5F5; 62 | -webkit-border-radius: 3px; 63 | -moz-border-radius: 3px; 64 | border-radius: 3px; 65 | font: 11px Verdana, Geneva, sans-serif; 66 | margin-top: 5px; 67 | max-width: 350px; 68 | padding: 10px; 69 | } 70 | .uploadify-error { 71 | background-color: #FDE5DD !important; 72 | } 73 | .uploadify-queue-item .cancel a { 74 | background: url('uploadify-cancel.png') 0 0 no-repeat; 75 | float: right; 76 | height: 16px; 77 | text-indent: -9999px; 78 | width: 16px; 79 | } 80 | .uploadify-queue-item.completed { 81 | background-color: #E5E5E5; 82 | } 83 | .uploadify-progress { 84 | background-color: #E5E5E5; 85 | margin-top: 10px; 86 | width: 100%; 87 | } 88 | .uploadify-progress-bar { 89 | background-color: #0099FF; 90 | height: 3px; 91 | width: 1px; 92 | } -------------------------------------------------------------------------------- /assets/uploadify.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjflyttp/yii2-uploadify-widget/5f538e5f7a61ba43bdae5114df3c9540b460d0cb/assets/uploadify.swf -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xj/yii2-uploadify-widget", 3 | "description": "yii2-uploadify-widget", 4 | "license": "BSD-3-Clause", 5 | "authors": [ 6 | { 7 | "name": "xjflyttp", 8 | "email": "xjflyttp@gmail.com" 9 | } 10 | ], 11 | "require": { 12 | "yiisoft/yii2": "*" 13 | }, 14 | "autoload": { 15 | "psr-4": { 16 | "xj\\uploadify\\": "" 17 | } 18 | } 19 | } 20 | --------------------------------------------------------------------------------