Menu

[r507]: / swfupload / trunk / FlashDevelop / classes / SWFUpload.as  Maximize  Restore  History

Download this file

780 lines (652 with data), 33.1 kB

  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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
package {
/*
* Development note: This code needs a security audit. E.g. If someone sets the control id string as some javascript it
* could make funny things happen with the callbacks.
*
* */
import flash.display.Sprite;
import flash.net.FileReferenceList;
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.events.*;
import flash.external.ExternalInterface;
import FileItem;
public class SWFUpload extends Sprite {
public static function main():void
{
var SWFUpload:SWFUpload = new SWFUpload();
}
private var fileBrowser:FileReferenceList = new FileReferenceList();
private var file_queue:Array = new Array(); // holds a list of all items that are to be uploaded.
private var current_file_item:FileItem = null; // the item that is currently being uploaded.
private var single_upload:Boolean = false; // Indicates whether a single file is being upload or the entire queue
private var completed_uploads:Number = 0; // Tracks the uploads that have been completed (no errors, not cancelled, not too big)
private var queued_uploads:Number = 0; // Tracks the FileItems that are waiting to be uploaded.
private var valid_file_extensions:Array = new Array();// Holds the parsed valid extensions.
// Callbacks
private var flashReady_Callback:String;
private var dialogCancelled_Callback:String;
private var fileQueued_Callback:String;
private var fileValidation_Callback:String;
private var fileProgress_Callback:String;
private var fileCancelled_Callback:String;
private var fileComplete_Callback:String;
private var queueComplete_Callback:String;
private var queueStopped_Callback:String;
private var error_Callback:String;
private var debug_Callback:String;
// Values passed in from the HTML
private var controlID:String;
private var uploadTargetURL:String;
private var filePostName:String;
private var uploadPostObject:Object;
private var fileTypes:String;
private var fileTypesDescription:String;
private var fileSizeLimit:Number;
private var fileUploadLimit:Number = 0;
private var fileQueueLimit:Number = 0;
private var beginUploadOnQueue:Boolean;
private var useServerDataEvent:Boolean;
private var fileValidation:Boolean;
private var debugEnabled:Boolean;
// Error code "constants"
private var ERROR_CODE_HTTP_ERROR:Number = -10;
private var ERROR_CODE_MISSING_UPLOAD_TARGET:Number = -20;
private var ERROR_CODE_IO_ERROR:Number = -30;
private var ERROR_CODE_SECURITY_ERROR:Number = -40;
private var ERROR_CODE_FILE_EXCEEDS_SIZE_LIMIT:Number = -50;
private var ERROR_CODE_ZERO_BYTE_FILE:Number = -60;
private var ERROR_CODE_UPLOAD_LIMIT_EXCEEDED:Number = -70;
private var ERROR_CODE_UPLOAD_FAILED:Number = -80;
private var ERROR_CODE_QUEUE_LIMIT_EXCEEDED:Number = -90;
private var ERROR_CODE_SPECIFIED_FILE_NOT_FOUND:Number = -100;
private var ERROR_CODE_INVALID_FILETYPE:Number = -110;
public function SWFUpload() {
//flash.system.Security.allowDomain("*"); // Allow any domain to use this SWF to upload files
// Setup file FileReferenceList events
this.fileBrowser.addEventListener(Event.SELECT, this.Select_Handler);
this.fileBrowser.addEventListener(Event.CANCEL, this.DialogCancelled_Handler);
// Get the control ID
this.controlID = root.loaderInfo.parameters.controlID;
// Configure the callbacks
this.flashReady_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].flashReady";
this.dialogCancelled_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].dialogCancelled";
this.fileQueued_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].fileQueued";
this.fileValidation_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].fileValidation";
this.fileProgress_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].fileProgress";
this.fileCancelled_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].fileCancelled";
this.fileComplete_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].fileComplete";
this.queueComplete_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].queueComplete";
this.queueStopped_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].queueStopped";
this.error_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].error";
this.debug_Callback = "SWFUpload.instances[\"" + this.controlID + "\"].debug";
// Get the Flash Vars
this.uploadTargetURL = root.loaderInfo.parameters.uploadTargetURL;
this.filePostName = root.loaderInfo.parameters.filePostName;
this.fileTypes = root.loaderInfo.parameters.fileTypes;
this.fileTypesDescription = root.loaderInfo.parameters.fileTypesDescription + " (" + this.fileTypes + ")";
this.loadPostParams(root.loaderInfo.parameters.params);
if (!this.filePostName) {
this.filePostName = "Filedata";
}
if (!this.fileTypes) {
this.fileTypes = "*.*";
}
if (!this.fileTypesDescription) {
this.fileTypesDescription = "All Files";
}
this.LoadFileExensions(this.fileTypes);
try {
this.fileValidation = root.loaderInfo.parameters.fileValidation == "true" ? true : false;
} catch (ex:Object) {
this.fileValidation = false;
}
try {
this.beginUploadOnQueue = root.loaderInfo.parameters.beginUploadOnQueue == "true" ? true : false;
} catch (ex:Object) {
this.beginUploadOnQueue = false;
}
try {
this.useServerDataEvent = root.loaderInfo.parameters.useServerDataEvent == "true" ? true : false;
} catch (ex:Object) {
this.useServerDataEvent = false;
}
try {
this.debugEnabled = root.loaderInfo.parameters.debugEnabled == "true" ? true : false;
} catch (ex:Object) {
this.debugEnabled = false;
}
try {
this.fileSizeLimit = Number(root.loaderInfo.parameters.fileSizeLimit);
if (this.fileSizeLimit < 0) this.fileSizeLimit = 0;
} catch (ex:Object) {
this.fileSizeLimit = 0;
}
try {
this.fileUploadLimit = Number(root.loaderInfo.parameters.fileUploadLimit);
if (this.fileUploadLimit < 0) this.fileUploadLimit = 0;
} catch (ex:Object) {
this.fileUploadLimit = 0;
}
try {
this.fileQueueLimit = Number(root.loaderInfo.parameters.fileQueueLimit);
if (this.fileQueueLimit < 0) this.fileQueueLimit = 0;
} catch (ex:Object) {
this.fileQueueLimit = 0;
}
// There is no sense in allowing more files to be queued than is allowed to be uploaded
if (this.fileQueueLimit > this.fileUploadLimit) this.fileQueueLimit = this.fileUploadLimit;
try {
ExternalInterface.addCallback("Browse", this.SelectFiles);
ExternalInterface.addCallback("StartUpload", this.StartUpload);
ExternalInterface.addCallback("StopUpload", this.StopUpload);
ExternalInterface.addCallback("CancelUpload", this.CancelUpload);
ExternalInterface.addCallback("CancelQueue", this.CancelQueue);
ExternalInterface.addCallback("AddFileParam", this.AddFileParam);
ExternalInterface.addCallback("RemoveFileParam", this.RemoveFileParam);
ExternalInterface.addCallback("SetUploadTargetURL", this.SetUploadTargetURL);
ExternalInterface.addCallback("SetPostParams", this.SetPostParams);
ExternalInterface.addCallback("SetFileTypes", this.SetFileTypes);
ExternalInterface.addCallback("SetFileSizeLimit", this.SetFileSizeLimit);
ExternalInterface.addCallback("SetFileUploadLimit", this.SetFileUploadLimit);
ExternalInterface.addCallback("SetFileQueueLimit", this.SetFileQueueLimit);
ExternalInterface.addCallback("SetBeginUploadOnQueue", this.SetBeginUploadOnQueue);
ExternalInterface.addCallback("SetUseServerDataEvent", this.SetUseServerDataEvent);
ExternalInterface.addCallback("SetValidateFiles", this.SetValidateFiles);
ExternalInterface.addCallback("SetFilePostName", this.SetFilePostName);
ExternalInterface.addCallback("SetDebugEnabled", this.SetDebugEnabled);
} catch (ex:Error) {
this.Debug("Callbacks where not set.");
}
this.Debug("SWFUpload Init Complete");
this.PrintDebugInfo();
// Do some feature detection
if (flash.net.FileReferenceList && flash.net.FileReference && flash.net.URLRequest && flash.external.ExternalInterface && flash.external.ExternalInterface.available) {
ExternalInterface.call(this.flashReady_Callback);
} else {
this.Debug("Feature Detection Failed");
}
}
/* *****************************************
* FileReference Event Handlers
* *************************************** */
private function DialogCancelled_Handler(event:Event):void {
this.Debug("Event: DialogCancel: File Dialog window cancelled.");
ExternalInterface.call(this.dialogCancelled_Callback);
}
private function FileProgress_Handler(event:ProgressEvent):void {
this.Debug("Event: Progress: File ID: " + this.current_file_item.id + ". Bytes: " + event.bytesLoaded + ". Total: " + event.bytesTotal);
ExternalInterface.call(this.fileProgress_Callback, this.current_file_item.ToJavaScriptObject(), event.bytesLoaded, event.bytesTotal);
}
private function FileComplete_Handler(event:Event):void {
this.Debug("Event: Complete: File ID: " + this.current_file_item.id + ". Upload Complete. Calling uploadComplete.");
this.completed_uploads++;
ExternalInterface.call(this.fileComplete_Callback, this.current_file_item.ToJavaScriptObject());
this.UploadComplete();
}
private function ServerData_Handler(event:DataEvent):void {
this.Debug("Event: UploadCompleteData: File ID: " + this.current_file_item.id + " Data: " + event.data);
this.completed_uploads++;
ExternalInterface.call(this.fileComplete_Callback, this.current_file_item.ToJavaScriptObject(), event.data);
this.UploadComplete();
}
private function HTTPError_Handler(event:HTTPStatusEvent):void {
this.Debug("Event: HTTPStatus: File ID: " + this.current_file_item.id + ". HTTP Status: " + event.status + ".");
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_HTTP_ERROR, this.current_file_item.ToJavaScriptObject(), event.status);
this.UploadComplete();
}
// Note: Flash Player does not support Uploads that require authentication. Attempting this will trigger an IO Error
private function IOError_Handler(event:IOErrorEvent):void {
if(!this.uploadTargetURL.length) {
this.Debug("Event: IOError: File ID: " + this.current_file_item.id + ". Upload Backend string is empty.");
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_MISSING_UPLOAD_TARGET, this.current_file_item.ToJavaScriptObject(), event.text);
} else {
this.Debug("Event: IOError: File ID: " + this.current_file_item.id + ". IO Error.");
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_IO_ERROR, this.current_file_item.ToJavaScriptObject(), event.text);
}
this.UploadComplete();
}
private function SecurityError_Handler(event:SecurityErrorEvent):void {
this.Debug("Event: SecurityError: File Number: " + this.current_file_item.id + ". Error:" + event.text);
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_SECURITY_ERROR, this.current_file_item.ToJavaScriptObject(), event.text);
this.UploadComplete();
}
private function Select_Handler(event:Event):void {
this.Debug("Event: Files Selected from Dialog. Processing file list");
var file_reference_list:Array = this.fileBrowser.fileList;
// Determine how many files may be queued
var queue_slots_remaining:Number = this.fileUploadLimit - (this.completed_uploads + this.queued_uploads);
queue_slots_remaining = (queue_slots_remaining > this.fileQueueLimit && this.fileQueueLimit > 0) ? this.fileQueueLimit : queue_slots_remaining;
// Check if the number of files selected is greater than the number allowed to queue up.
if (file_reference_list.length > queue_slots_remaining && (this.fileUploadLimit != 0 || this.fileQueueLimit > 0)) {
this.Debug("onSelect: Selected Files exceed remaining Queue size.");
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_QUEUE_LIMIT_EXCEEDED, null, queue_slots_remaining);
} else {
// Process each selected file
for (var i:Number = 0; i < file_reference_list.length; i++) {
var file_item:FileItem = new FileItem(file_reference_list[i], this.controlID);
// Check the size, if it's within the limit add it to the upload list.
var size_result:Number = this.CheckFileSize(file_item);
var is_valid_filetype:Boolean = this.CheckFileType(file_item);
if(size_result == 0 && is_valid_filetype) {
this.Debug("onSelect: File within size limit and of valid type. Adding to queue and making callback.");
this.file_queue.push(file_item);
this.queued_uploads++;
ExternalInterface.call(this.fileQueued_Callback, file_item.ToJavaScriptObject());
}
else if (!is_valid_filetype) {
this.Debug("onSelect: File not of a valid type. Making error callback.");
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_INVALID_FILETYPE, file_item.ToJavaScriptObject(), "File is not an allowed file type.");
}
else if (size_result > 0) {
this.Debug("onSelect: File exceeds size limit. Making error callback.");
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_FILE_EXCEEDS_SIZE_LIMIT, file_item.ToJavaScriptObject(), "File size exceeds allowed limit.");
} else if (size_result < 0) {
this.Debug("onSelect: File is zero bytes. Making error callback.");
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_ZERO_BYTE_FILE, file_item.ToJavaScriptObject(), "File is zero bytes and cannot be uploaded.");
}
}
// If we are currently uploading files
if (this.beginUploadOnQueue && this.queued_uploads > 0) {
this.Debug("onSelect: Uploads set to begin immediately. Calling StartUpload.");
this.StartUpload();
}
}
}
/* ****************************************************************
Externally exposed functions
****************************************************************** */
// Opens a file browser dialog. Once files are selected the "onselect" event is triggered.
private function SelectFiles():void {
var allowed_file_types:String = "*.*";
var allowed_file_types_description:String = "All Files";
if (this.fileTypes.length > 0) allowed_file_types = this.fileTypes;
if (this.fileTypesDescription.length > 0) allowed_file_types_description = this.fileTypesDescription;
this.fileBrowser.browse([new FileFilter(allowed_file_types_description, allowed_file_types)]);
this.Debug("UploadFile: Browsing files. " + allowed_file_types);
}
// Starts uploading. If a file_id is given then only that file is uploaded, otherwise the entire queue is uploaded.
// If the file_id is not found no upload begins and an error is called back
private function StartUpload(file_id:String = ""):void {
if (this.current_file_item == null) {
this.Debug("StartUpload(): Starting Upload. " + (file_id ? "File ID:" + file_id : "Next file in queue"));
this.StartFile(file_id);
} else {
this.Debug("StartUpload(): Upload run already in progress");
}
}
// Cancel the current upload and stops. Doesn't advance the upload pointer. Starting again will re-upload the current file.
private function StopUpload():void {
if (this.current_file_item != null) {
// Cancel the upload and re-queue the FileItem
this.current_file_item.file_reference.cancel();
// Remove the event handlers
this.current_file_item.file_reference.removeEventListener(ProgressEvent.PROGRESS, this.FileProgress_Handler);
this.current_file_item.file_reference.removeEventListener(IOErrorEvent.IO_ERROR, this.IOError_Handler);
this.current_file_item.file_reference.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.SecurityError_Handler);
this.current_file_item.file_reference.removeEventListener(HTTPStatusEvent.HTTP_STATUS, this.HTTPError_Handler);
this.current_file_item.file_reference.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA, this.ServerData_Handler);
this.current_file_item.file_reference.removeEventListener(Event.COMPLETE, this.FileComplete_Handler);
this.file_queue.unshift(this.current_file_item);
ExternalInterface.call(this.queueStopped_Callback, this.current_file_item.ToJavaScriptObject());
this.current_file_item = null;
this.Debug("StopUpload(): upload stopped.");
} else {
this.Debug("StopUpload(): Upload run not in progress");
}
}
// Cancels the upload specified by file_id
private function CancelUpload(file_id:String):void {
if (file_id) {
if (this.current_file_item != null && this.current_file_item.id == file_id) {
this.current_file_item.file_reference.cancel();
ExternalInterface.call(this.fileCancelled_Callback, this.current_file_item.ToJavaScriptObject());
this.Debug("CancelUpload(): Cancelling current upload");
this.UploadComplete(); // <-- this advanced the upload to the next file
} else {
// Find the file in the queue
var file_index:Number = this.FindIndexInFileQueue(file_id);
if (file_index >= 0) {
// Remove the file from the queue
var file_item:FileItem = FileItem(this.file_queue[file_index]);
this.file_queue[file_index] = null;
this.queued_uploads--;
// Cancel the file (just for good measure) and make the callback
file_item.file_reference.cancel();
ExternalInterface.call(this.fileCancelled_Callback, file_item.ToJavaScriptObject());
// Get rid of the file object
file_item = null;
this.Debug("CancelUpload(): Cancelling queued upload");
}
}
}
}
private function CancelQueue():void {
this.Debug("CancelQueue(): Cancelling remaining queue.");
// Cancel the current upload
if (this.current_file_item != null) {
this.current_file_item.file_reference.cancel();
ExternalInterface.call(this.fileCancelled_Callback, this.current_file_item.ToJavaScriptObject());
}
while (this.file_queue.length > 0) {
var file_item:FileItem = FileItem(this.file_queue.shift());
if (file_item != null) {
file_item.file_reference.cancel(); // Cancel the FileReference just for good measure
this.queued_uploads--;
ExternalInterface.call(this.fileCancelled_Callback, file_item.ToJavaScriptObject());
file_item = null;
}
}
// If we were uploading a file complete it's process
if (this.current_file_item != null) {
this.UploadComplete();
}
}
private function AddFileParam(file_id:String, name:String, value:String):Boolean {
var file_index:Number = this.FindIndexInFileQueue(file_id);
if (file_index >= 0) {
var file_item:FileItem = FileItem(this.file_queue[file_index]);
file_item.AddParam(name, value);
return true;
} else {
return false;
}
}
private function RemoveFileParam(file_id:String, name:String):Boolean {
var file_index:Number = this.FindIndexInFileQueue(file_id);
if (file_index >= 0) {
var file_item:FileItem = FileItem(this.file_queue[file_index]);
file_item.RemoveParam(name);
return true;
} else {
return false;
}
}
private function SetUploadTargetURL(url:String):void {
if (typeof(url) !== "undefined" && url !== "") {
this.uploadTargetURL = url;
}
}
private function SetPostParams(post_object:Object):void {
if (typeof(post_object) !== "undefined" && post_object !== null) {
this.uploadPostObject = post_object;
}
}
private function SetFileTypes(types:String, description:String):void {
this.fileTypes = types;
this.fileTypesDescription = description;
this.LoadFileExensions(this.fileTypes);
}
private function SetFileSizeLimit(bytes:Number):void {
if (bytes < 0) bytes = 0;
this.fileSizeLimit = bytes;
}
private function SetFileUploadLimit(file_upload_limit:Number):void {
if (file_upload_limit < 0) file_upload_limit = 0;
this.fileUploadLimit = file_upload_limit;
}
private function SetFileQueueLimit(file_queue_limit:Number):void {
if (file_queue_limit < 0) file_queue_limit = 0;
this.fileQueueLimit = file_queue_limit;
}
private function SetBeginUploadOnQueue(begin_upload_on_queue:Boolean):void {
this.beginUploadOnQueue = begin_upload_on_queue;
}
private function SetUseServerDataEvent(use_server_data_event:Boolean):void {
this.useServerDataEvent = use_server_data_event;
}
private function SetValidateFiles(validate_files:Boolean):void {
this.fileValidation = validate_files;
}
private function SetFilePostName(file_post_name:String):void {
if (file_post_name != "") {
this.filePostName = file_post_name;
}
}
private function SetDebugEnabled(debug_enabled:Boolean):void {
this.debugEnabled = debug_enabled;
}
/* *************************************************************
File processing and handling functions
*************************************************************** */
//
private function StartFile(file_id:String = ""):void {
// Only upload a file uploads are being processed.
// startFile could be called by a file cancellation even when we aren't currently uploading
if (this.current_file_item != null) {
this.Debug("StartFile(): Upload already in progress. Exiting.");
return;
}
this.Debug("StartFile: " + (file_id ? "File ID " + file_id : "Next file in queue"));
// Get the next file to upload
if (!file_id) {
this.single_upload = false;
while (this.file_queue.length > 0 && this.current_file_item == null) {
// Check that File Reference is valid (if not make sure it's deleted and get the next one on the next loop)
this.current_file_item = FileItem(this.file_queue.shift()); // Cast back to a FileItem
if (typeof(this.current_file_item) == "undefined") {
this.current_file_item = null;
continue;
}
// Check that we haven't exceeded the upload_limit, if so handle the file and go to the next.
else if (this.completed_uploads >= this.fileUploadLimit && this.fileUploadLimit != 0) {
this.Debug("StartFile(): Upload limit reached. Making callback and skipping file. File ID: " + this.current_file_item.id);
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_UPLOAD_LIMIT_EXCEEDED, this.current_file_item.ToJavaScriptObject(), "The upload limit has been reached.");
this.current_file_item = null;
continue;
}
}
} else {
this.single_upload = true;
var file_index:Number = this.FindIndexInFileQueue(file_id);
if (file_index >= 0) {
this.current_file_item = FileItem(this.file_queue[file_index]);
this.file_queue[file_index] = null;
} else {
this.Debug("StartFile(): File ID not found in queue: " + file_id);
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_SPECIFIED_FILE_NOT_FOUND, null, "File ID not queued.");
}
}
// Start the upload if we found an item to upload
if (this.current_file_item != null) {
// Build the URLRequest
var request:URLRequest = this.BuildRequest();
// Begin the upload
this.Debug("startFile(): File Reference found. Starting upload to " + request.url + ". File ID: " + this.current_file_item.id);
try {
// Validate the file
if (!this.fileValidation) {
// Set the event handlers
this.current_file_item.file_reference.addEventListener(ProgressEvent.PROGRESS, this.FileProgress_Handler);
this.current_file_item.file_reference.addEventListener(IOErrorEvent.IO_ERROR, this.IOError_Handler);
this.current_file_item.file_reference.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.SecurityError_Handler);
this.current_file_item.file_reference.addEventListener(HTTPStatusEvent.HTTP_STATUS, this.HTTPError_Handler);
// Set the appropriate server data/file complete event handler
if (this.useServerDataEvent) {
this.current_file_item.file_reference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, this.ServerData_Handler);
} else {
this.current_file_item.file_reference.addEventListener(Event.COMPLETE, this.FileComplete_Handler);
}
// Upload the file
this.current_file_item.file_reference.upload(request, this.filePostName, false);
} else {
if (ExternalInterface.call(this.fileValidation_Callback, this.current_file_item.ToJavaScriptObject())) {
this.Debug("startFile(): File Validated.");
// Set the event handlers
this.current_file_item.file_reference.addEventListener(ProgressEvent.PROGRESS, this.FileProgress_Handler);
this.current_file_item.file_reference.addEventListener(IOErrorEvent.IO_ERROR, this.IOError_Handler);
this.current_file_item.file_reference.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.SecurityError_Handler);
this.current_file_item.file_reference.addEventListener(HTTPStatusEvent.HTTP_STATUS, this.HTTPError_Handler);
// Set the appropriate server data/file complete event handler
if (this.useServerDataEvent) {
this.current_file_item.file_reference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, this.ServerData_Handler);
} else {
this.current_file_item.file_reference.addEventListener(Event.COMPLETE, this.FileComplete_Handler);
}
// Upload the file
this.current_file_item.file_reference.upload(request, this.filePostName, false);
} else {
this.Debug("startFile(): Did not validate.");
this.StopUpload();
}
}
}
catch (ex:Error) {
this.Debug("startFile(): Upload Failed.");
ExternalInterface.call(this.error_Callback, this.ERROR_CODE_UPLOAD_FAILED, this.current_file_item.ToJavaScriptObject(), ex.message);
this.current_file_item = null;
}
}
// Otherwise we've would have looped through all the FileItems. This means the queue is empty)
else {
this.Debug("startFile(): No File Reference found. All uploads must be complete, cancelled, or errored out.");
this.Debug("startFile(): Ending upload run. Completed Uploads: " + this.completed_uploads);
if (this.completed_uploads > 0) {
this.Debug("startFile(): Queue is complete and at least one file has been uploaded. Making QueueComplete callback.");
ExternalInterface.call(this.queueComplete_Callback, this.completed_uploads);
}
}
}
// Completes the file upload by deleting it's reference, advancing the pointer, and starting the next upload.
private function UploadComplete():void {
this.Debug("UploadComplete(): Upload complete. Removing File Reference and starting the next upload.");
// Remove the pointer, the space in the array still exists
this.current_file_item = null;
this.queued_uploads--;
// Start the next file upload
if (!this.single_upload) {
this.StartFile();
}
}
/* *************************************************************
Utility Functions
*************************************************************** */
// Check the size of the file against the allowed file size. If it is less the return TRUE. If it is too large return FALSE
private function CheckFileSize(file_item:FileItem):Number {
if (file_item.file_reference.size == 0) {
return -1;
} else if (this.fileSizeLimit != 0 && file_item.file_reference.size > (this.fileSizeLimit * 1000)) {
return 1;
} else {
return 0;
}
}
private function CheckFileType(file_item:FileItem):Boolean {
// If no extensions are defined then a *.* was passed and the check is unnecessary
if (this.valid_file_extensions.length == 0) {
return true;
}
var fileRef:FileReference = file_item.file_reference;
var last_dot_index:Number = fileRef.name.lastIndexOf(".");
var extension:String = "";
if (last_dot_index >= 0) {
extension = fileRef.name.substr(last_dot_index + 1).toLowerCase();
}
var is_valid_filetype:Boolean = false;
for (var i:Number=0; i < this.valid_file_extensions.length; i++) {
if (String(this.valid_file_extensions[i]) == extension) {
is_valid_filetype = true;
break;
}
}
return is_valid_filetype;
}
private function BuildRequest():URLRequest {
// Build the Post values
var key:String;
var post:URLVariables = new URLVariables();
for (key in this.uploadPostObject) {
this.Debug("Global Post Item: " + key + "=" + this.uploadPostObject[key]);
if (this.uploadPostObject.hasOwnProperty(key)) {
post[key] = this.uploadPostObject[key];
}
}
var file_post:Object = this.current_file_item.GetPostObject();
for (key in file_post) {
this.Debug("File Post Item: " + key + "=" + this.uploadPostObject[key]);
if (file_post.hasOwnProperty(key)) {
post[key] = file_post[key];
}
}
// Create the request object
var request:URLRequest = new URLRequest();
request.method = URLRequestMethod.POST;
request.url = this.uploadTargetURL;
request.data = post;
return request;
}
private function Debug(msg:String):void {
if (this.debugEnabled) {
var lines:Array = msg.split("\n");
for (var i:Number=0; i < lines.length; i++) {
lines[i] = "SWF DEBUG: " + lines[i];
}
ExternalInterface.call(this.debug_Callback, lines.join("\n"));
}
}
private function PrintDebugInfo():void {
var debug_info:String = "\n----- SWF DEBUG OUTPUT ----\n";
debug_info += "ControlID: " + this.controlID + "\n";
debug_info += "Upload Target URL: " + this.uploadTargetURL + "\n";
debug_info += "Begin Upload on Queue: " + this.beginUploadOnQueue + "\n";
debug_info += "Validate Files: " + this.fileValidation + "\n";
debug_info += "File Types String: " + this.fileTypes + "\n";
debug_info += "Parsed File Types: " + this.valid_file_extensions.toString() + "\n";
debug_info += "File Types Description: " + this.fileTypesDescription + "\n";
debug_info += "File Size Limit: " + this.fileSizeLimit + "\n";
debug_info += "File Upload Limit: " + this.fileUploadLimit + "\n";
debug_info += "File Queue Limit: " + this.fileQueueLimit + "\n";
debug_info += "Post Params:\n";
for (var key:String in this.uploadPostObject) {
debug_info += " " + key + "=" + this.uploadPostObject[key] + "\n";
}
debug_info += "----- END SWF DEBUG OUTPUT ----\n";
this.Debug(debug_info);
}
private function FindIndexInFileQueue(file_id:String):Number {
for (var i:Number = 0; i<this.file_queue.length; i++) {
var item:FileItem = this.file_queue[i];
if (item != null && item.id == file_id) return i;
}
return -1;
}
// Parse the file extensions in to an array so we can validate them agains
// the files selected later.
private function LoadFileExensions(filetypes:String):void {
var extensions:Array = filetypes.split(";");
this.valid_file_extensions = new Array();
for (var i:Number=0; i < extensions.length; i++) {
var extension:String = String(extensions[i]);
var dot_index:Number = extension.lastIndexOf(".");
if (dot_index >= 0) {
extension = extension.substr(dot_index + 1).toLowerCase();
} else {
extension = extension.toLowerCase();
}
// If one of the extensions is * then we allow all files
if (extension == "*") {
this.valid_file_extensions = new Array();
break;
}
this.valid_file_extensions.push(extension);
}
}
private function loadPostParams(param_string:String):void {
var post_object:Object = {};
if (param_string != null) {
var name_value_pairs:Array = param_string.split("&");
for (var i:Number = 0; i < name_value_pairs.length; i++) {
var name_value:String = String(name_value_pairs[i]);
var index_of_equals:Number = name_value.indexOf("=");
if (index_of_equals > 0) {
post_object[decodeURIComponent(name_value.substring(0, index_of_equals))] = decodeURIComponent(name_value.substr(index_of_equals + 1));
}
}
}
this.uploadPostObject = post_object;
}
}
}
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.