Monday, October 08, 2007

SWFUpload Revision 7.0 beta 2

Update: Revision 6.2 & 7 require Flash Player 9.0.28 or higher. However they fail to do proper checking to ensure that the necessary minimum Flash Player version is present. I will release an update to the R6 and R7 lines shortly.

Revision 7 beta 2

SWFUpload Revision 7.0 beta 2 is out!. I even updated the demos this time. It's all posted at the usual place: http://swfupload.praxion.co.za/. Many thanks again to our Host!

Don't forget to visit the Official SWFUpload site to show your support and to get some support.

Why Beta?

There is a bug in Flash Player that affects SWFUpload severely. It is more apparent in R7 because of the change in the Event design. I really like the new event design so I'm working hard to keep it. I'm not sure that this version is stable or how compatible it is with browsers on different operating systems. So it'll be Beta for a little while.

Changes in R7b2 from R7b1
  • I worked around an encoding bug in Flash Player where the Server Data or a file name or any string that contains a backslash (\) or a quotation mark (") in the wrong place will cause a JavaScript error which causes events to abort. Stupid Flash Player. See source for details.
  • I moved the ERROR_CODE_* constants in to "sub" objects so it's more clear what group the error belongs to (queue errors/upload errors). I changed all the error code numbers too. You didn't use any magic numbers, right?
  • Added the UPLOAD_STOPPED upload error which can supplement for an uploadStopped event.
  • Updated Flash calls and event calls with setTimeout to avoid limitations in Flash's ExternalInterface api. Stupid Flash. I haven't had any problems but watch out for concurrency and execution order issues.
  • Added a customSettings object to the SWFUpload instance so you can just set your own variables on an instance rather than using addSetting and getSetting (you can still use addSetting/getSetting if you want).
  • Changed the FILE_NOT_FOUND error code to FILE_ID_NOT_FOUND which is more precise.
  • Changed the parameter order on some events so the file object is always first in an effort to be more consistent.
Known Issues
  • You can run in to problems if, from JavaScript, you call in to Flash; which then calls back to JavaScript; who then tries to call back in to Flash. That final call in to Flash will fail. This is most apparent when calling startUpload() which calls back to uploadStart. If you try to call in to Flash from here, calling getStats() for instance, you may get an error or just a silent failure. I've work for 6 full days trying to understand and get around this. I've done pretty well by wrapping all the calls I could in setTimeouts but you can still force the bug so be careful. Stupid Flash.
  • Setting the file_post_name does not seem to work in the Linux Flash Player. It's an unnecessary feature anyway so don't use it unless you really have to (and you shouldn't have to). Thanks to Shadow Walker for the Linux bug reports.
  • You have to return something from your upload_url script or uploadComplete will never be called and your uploads will hang. I sometimes call echo ' ';
Where's the docs?

If anyone wants to write up some HTML format docs that'd be great. Otherwise I'll get to it eventually. In the meanwhile it's a good idea to skim through all the SWFUpload posts (the really old ones are still relevant). I've tried to include lots of comments in the code and between all the demos you can see how to do just about everything. Still, some docs would be nice.

34 comments:

  1. frankblack3:06 PM

    Unfortunately the swfupload site is offline, so I post against my promise here: on flash upload the mimetype is always returned as application/octet-stream? seems to be that the correct mimetype isn't passed through.

    any workaround? and even more strange: jpeg-files never give the upload finished signal, every other file is finished correctly

    ReplyDelete
  2. RE: SWFUpload sites

    I'm not sure which SWFUpload site you are referring to but the Official site seems up, this site is up and the R7 demo site is up.

    RE: mimetype

    There is no work around for the file mimetype. Flash provides no way to get the mimetype and no way to send it. Sorry. I'm not sure why you need the mime type. It's no better or worse than the a file extension. If you really want to validate a file you'll have to check its content.

    RE: JPGs not finishing.

    Can you be more specific? Does this occur in one of the demos? What file sizes are you using? Do any other events fire (uploadProgress, uploadError, uploadComplete, fileComplete)? Which browser(s) are you having trouble in? What version of Flash Player are you using? Have you verified that your upload script is working correctly?

    -Thanks-

    ReplyDelete
  3. frankblack3:54 PM

    Thx for your patience. http://swfupload.mammon.se/ is not reachable for me (your link on the news).

    The jpg is 11.953 Bytes long. No special chars in the name. Flash Player is 9.0.47.0. upload script is working, files are uploaded. problems with ie6 and ff 2.0.0.7

    maybe you can cut this out later? here is my debug info:
    ----- DEBUG OUTPUT ----
    ID: SWFUpload_0
    ui_function: {
    }
    ui_container_id: flashUI1
    degraded_container_id: degradedUI1
    upload_url: upload.php
    file_post_name: Filedata
    post_params: {
    xuserid: user_1_
    PHPSESSID: 28308549012605d3991a2a384f33b22f
    }
    file_types: *.*
    file_types_description: All Files
    file_size_limit: 102400
    file_upload_limit: 0
    file_queue_limit: 1
    flash_url: swfupload.swf
    flash_width: 1px
    flash_height: 1px
    flash_color: #FFFFFF
    debug_enabled: true
    ----- DEBUG OUTPUT END ----


    SWF DEBUG: SWFUpload Init Complete
    SWF DEBUG:
    SWF DEBUG: ----- SWF DEBUG OUTPUT ----
    SWF DEBUG: Build Number: 20070918160000
    SWF DEBUG: movieName: SWFUpload_0
    SWF DEBUG: Upload URL: upload.php
    SWF DEBUG: File Types String: *.*
    SWF DEBUG: Parsed File Types:
    SWF DEBUG: File Types Description: All Files (*.*)
    SWF DEBUG: File Size Limit: 102400
    SWF DEBUG: File Upload Limit: 0
    SWF DEBUG: File Queue Limit: 0
    SWF DEBUG: Post Params:
    SWF DEBUG: xuserid=user_1_
    SWF DEBUG: PHPSESSID=28308549012605d3991a2a384f33b22f
    SWF DEBUG: ----- END SWF DEBUG OUTPUT ----
    SWF DEBUG:
    Flash called back and is ready.
    SWF DEBUG: Event: fileDialogStart : Browsing files. Multi Select. Allowed file types: *.*
    SWF DEBUG: Select Handler: Files Selected from Multi-Dialog. Processing file list
    SWF DEBUG: Event: fileQueued : File ID: SWFUpload_0_0
    SWF DEBUG: Event: fileDialogComplete : Finished adding files
    SWF DEBUG: StartUpload(): Starting Upload: First file in queue
    SWF DEBUG: StartFile: First file in queue
    SWF DEBUG: Global Post Item: xuserid=user_1_
    SWF DEBUG: Global Post Item: PHPSESSID=28308549012605d3991a2a384f33b22f
    SWF DEBUG: startFile(): File Reference found. Starting upload to upload.php. File ID: SWFUpload_0_0
    SWF DEBUG: Event: uploadStart : File ID: SWFUpload_0_0
    SWF DEBUG: Event: uploadProgress: File ID: SWFUpload_0_0. Bytes: 11953. Total: 11953

    all other filetypes are working

    ReplyDelete
  4. The only thing I can think of is that your upload script is not returning any data. You must return some data. My most simple test script look like this:

    <?php echo ' '; />

    That's it but it returns data (a space) and keeps things simple.

    If you do not return anything then Flash Player never fires the internal complete event and the upload appears to stall.

    PHP can be troublesome with this because if you configure it to hide all error output but PHP still returns a 200 status code even when an error occurs. It is good practice to have errors hidden in production systems so you need to make sure all your errors are handled correctly so, even if your PHP craps out, everything still works.

    ReplyDelete
  5. WizX20 - NL1:47 AM

    First of all, great uploader and thnx for sharing this with us.

    I found a small bug in you're demo: multiuploaddemo. When you cancel a single upload in the list (stats) an Unhandled Error: [object Object] occures.

    Perhaps you can give me a hint on how to fix this? I'm not a great javascript programmer.

    -- Debug output --
    SWF DEBUG: Event: fileQueued : File ID: SWFUpload_0_1
    SWF DEBUG: Event: fileDialogComplete : Finished adding files
    SWF DEBUG: Event: uploadError : SWFUpload_0_1. Cancelling queued upload
    SWF DEBUG: Event: uploadError : SWFUpload_0_1. Cancelling queued upload
    Error Code: [object Object], File name: undefined, File size: undefined, Message: File Cancelled

    ReplyDelete
  6. Thanks for the report. I found old code in the SWF file that I should have removed but missed. It is causing uploadError to be called twice, but the second time all the parameters are undefined. I'll get that fixed and out with beta 3.

    ReplyDelete
  7. This comment has been removed by a blog administrator.

    ReplyDelete
  8. Truly amazing script! Keep up the good work. I will post any updates. Via open source!

    ReplyDelete
  9. Viva open source!!!

    ReplyDelete
  10. We're using revision 6.2. Great code, thanks a lot. I saw your Update note, and can tell you that we are waiting anxiously for the update that fixes the Flash version check (9.0.28). We ran into this bug with a number of users.

    ReplyDelete
  11. It's a simple fix. Replace line 193 of SWFUpload.as with:

    if (flash.net.FileReferenceList && flash.net.FileReference && flash.net.URLRequest && flash.external.ExternalInterface && flash.external.ExternalInterface.available && DataEvent.UPLOAD_COMPLETE_DATA) {

    this adds a check for the DataEvent.UPLOAD_COMPLETE_DATA which was added in 9.0.28.

    ReplyDelete
  12. hey everybody...

    call me stupid or something, but where can i set the folder where the files should be uploaded into?? I'm sure its one of the most stupid questions everrr, but its driving me nuts and i cannot find it..

    please be patient with a little nwebei and tell me how ;)

    thank u so much..

    ReplyDelete
  13. I'm not quite sure what you are asking.

    R7 has a setting called upload_url that points to the upload script on the server. This would be like the action="" url in your FORM tag.

    Your server-side script then handles the upload just like any HTTP upload. Every language and Framework handles file uploads differently. You'll have to refer to the available documentation for specifics. The only thing to remember is that SWFUpload posts the file with the POST variable name 'Filedata' by default.

    If you download the demos look at upload.php for various different examples of handling the file upload.

    Lastly, SWFUpload only uploads one file at a time (even though it lets you select and queue multiple files). This is good because it keeps your upload script very simple.

    ReplyDelete
  14. Jack,

    thx for the quick answer..but still...I took a look at the upload scripts..and quite frankly, I have no idea how to make it happen. I just want to upload the selected files into a folder on my server. I use php, if that helps you...


    If you could help me to make it work I would really appreciate it!

    thank you so much

    ReplyDelete
  15. oops, sorry, I mean Jake!!!

    I'm really sorry

    ReplyDelete
  16. Properly handling file uploads in PHP is a big topic with many options, security issues and other caveats.

    You should start at the PHP website:
    Handling File Uploads in PHP and
    More PHP file upload resources

    ----
    Here is a quick sample one-liner that saves an uploaded file from SWFUpload.

    move_uploaded_file($_FILES["Filedata"]["tmp_name"], "c:\\my_file_storage\\" + $_FILES["Filedata"]["name"]);

    ----
    I recommend creating a regular simple HTML form for uploading a single file. Create your PHP upload handling script and test thoroughly using your HTML form. When it is all working properly then use SWFUpload.

    This is how I develop for SWFUpload. Since SWFUpload hides the server side from you it is hard to track down problems in the upload script. Making a simple test page without SWFUpload prevents me from spending hours trying to fix SWFUpload when the problem was in my upload script or PHP configuration all along.

    For instance, I could not upload large files with SWFUpload and could not figure out why and spent forever trying to figure out what was wrong with the code. Turns out my PHP setting limited uploads to 7MB and I only realized the problem was server side when I finally put together my simple test form.

    Good luck! If you have any specific questions about a PHP script I can try to help. You may take this over to the SWFUpload forums (if they're working) where it's easier to have long discussions about things like this.

    ReplyDelete
  17. Thanks for adding the UPLOAD_STOPPED error code! Very helpful for my implementation.

    I would like to help with documentation. I am fairly new to this project, but I have implemented it successfully in my current project, so I think I have a good understanding of how it works (at least on the JS side.)

    Just reading through swfupload.js and noticed in your ALL internal event handlers that the debug message for an invalid external handler is "fileDialogStart event not defined." Not a big deal since you automatically attach default handlers, but it would be confusing if it ever came up.

    ReplyDelete
  18. Darren4:01 AM

    Does anyone know how to get the cancel button working in the application demo? Thanks!

    ReplyDelete
  19. @Chris. I've started some documentation (just a little bit) which I've posted here. Feel free to download and begin filling in sections (or clarifying/correcting the bits I've already done). Send them back and I'll merge them in.

    I've corrected the fileDialogStart messages. I am always missing things like that when I copy/paste ;)

    @darren
    That's a bug. I'll get it fixed. On line 211 of handlers.js if you remove 'file_id' from the call to cancelUpload(file_id) then it should work, maybe.

    ReplyDelete
  20. chris1:51 PM

    BUG REPORT

    External uploadStart event handler does not fire.

    Problem: Coding error in the internal event handler.

    Solution: make the following changes in swfupload.js

    Line 709: delete "return true;"
    Line 711: function parameter "files" should be "file"

    ReplyDelete
  21. Oops. Those'll be fixed in beta 3. I plan to release it this weekend.

    We might even have some docs ready by then :)

    ReplyDelete
  22. Hello,
    Great work !!
    For this bug found by wizx20 :

    -- Debug output --
    SWF DEBUG: Event: fileQueued : File ID: SWFUpload_0_1
    SWF DEBUG: Event: fileDialogComplete : Finished adding files
    SWF DEBUG: Event: uploadError : SWFUpload_0_1. Cancelling queued upload
    SWF DEBUG: Event: uploadError : SWFUpload_0_1. Cancelling queued upload
    Error Code: [object Object], File name: undefined, File size: undefined, Message: File Cancelled

    I think there is a mistake in SWFUpload.as in ExternalInterface.call (around line 446 )

    It is :


    ExternalInterface.call(callback, error_code, file_object, message);


    And it should be :


    ExternalInterface.call(callback, file_object, error_code, message);


    I got it fixed with this.

    Hery

    ReplyDelete
  23. Hello Jake,

    I was wondering if SWFUpload would like a new (more dynamic) site using Drupal. I'd be willing to put it together, as well as host it for free. I absolutely love the project, and want it to succeed.

    By more dynamic, I mean it would integrate forums, bug tracking, wiki for documentation and project management. It would really help out and would be my way of contributing back to the project. In addition, it would look like the currently existing "official" website.

    I'd also be willing to register and maintain a domain name for a more permanent SWFUpload home. Some domain ideas are swfupload.org, swfuploadproject.com, swfuploadisthebestuploaderever.com, etc. We'd just need to change the nameservers.

    If you want a demonstration of what it would be like, I could have a mock up of what the final version would be like in about two weeks. Let me know what you think!

    Thanks a lot and I'll talk to you soon.

    Rob

    ReplyDelete
  24. I think it would be great to set up a project site.

    Of course you realize that this isn't exactly the way I intended this project to go. I was keeping it loose so I could do whatever I wanted and could quit at any time. Oh well.

    The only issue I see is that I don't own the "SWFUpload" name. I'm not sure what the guys at Mammon think. I've sent them an email. It may be that the name needs to change. It may be better to change the name anyways and make a break.

    ReplyDelete
  25. chris9:04 AM

    BUG REPORT

    I have run into the situation when stopping or cancelling an upload, the current upload file will be reported as having been stopped or cancelled, but the destination server receives the complete file. In PHP I would expect the error code for the upload to indicate an incomplete upload (error# 3), but the error code indicates a successful upload (error# 0) and the file size is correct. Furthermore, the file has not been corrupted in any way.

    This only happens when the upload time is very short, ie uploading small files.

    One way to correct this may be to add progress detection to the StopUpload routine in the .AS file. You coud then setup a global flag that indicates to the ServerData_Handler routine if the fileComplete event shoud be fired. The global flag would have to be set to TRUE by the StartFile routine. The StopUpload routine would then determine the upload progress for the current file and either stop the upload (as it is currently coded) or set the flag to FALSE.

    ReplyDelete
  26. I was working on this last night. I added a "sleep(30)" statement to my upload.php so I would have time to cancel small uploads. When I cancelled the small upload during that 30 second period the browser would lock up until the 30 seconds had completed and then R7 behaves exactly as you described.

    Your solution is good and basically means disabling cancel and stop during that period of server-side processing between the time that the file has been uploaded and the upload script has finished. But the correct events still need to be fired.

    I'll have to work on this. It's kind of a mess.

    ReplyDelete
  27. i install to my site but when i click on upload file button i got the error message upload1.browse is not a function. any solution?

    ReplyDelete
  28. wizx204:08 AM

    @slavenabil
    It means the function does not exists or the function can not be found. Did you include the handlers.js file correct (as provided in the example).

    check swfupload.mammon.se

    ReplyDelete
  29. wizx204:20 AM

    @Hery

    Great! Now I have one problem. I don't have a copy of flash 9 and haven't worked with flash for quite a while. Perhaps you could be so kind to post the fixed .swf file somewhere for me? I would be forever greatfull :-)

    ReplyDelete
  30. rob loach1:12 PM

    I've been working on implementing this branch into Drupal (http://drupal.org) and it's coming along quite nicely (http://drupal.org/project/swfupload). Your branch will be in the next version, but I'm currently running into some problems that others have found.

    I'm currently working on making it as extensible as possible. Right now SWFUpload is just used to replace file attachments on websites, I'm going to be using your version to make it so that they can use this for any file uploading process.

    As for a new website for it, I've started putting the pieces together and should have something nice within two weeks. If you're ever on MSN, give me a shout at removed by admin

    Thanks,
    Rob

    ReplyDelete
  31. @slavenabil:
    What version are you using?
    R7b2 changed the name from browse() to selectFiles(). It sounds like you're mixing versions (maybe).

    But what happens in the demo is:
    1) Init SWFUpload
    2) Store the SWFUpload instance in 'upload1' variable
    3) Browse button click event set to 'upload1.browse()'

    The problem is either the variable 'upload1' is not being set or 'browse()' does not exist (or both).

    ReplyDelete
  32. @wizx20

    Check out FlashDevelop (version 3). Get that installed and setup and you don't need FlashStudio to build SWFUpload.

    ReplyDelete
  33. @Hery
    That "ExternalInterface.call" should not even be there. I've replaced all my direct calls to ExternalInterface with a wrapper class called ExternalCall. This class ensures that things get called "right". There are a few bugs in the ExternalInterface library that I'm having to work around.

    This'll be fixed in beta 3.

    ReplyDelete
  34. "Setting the file_post_name does not seem to work in the Linux Flash Player. It's an unnecessary feature anyway so don't use it unless you really have to (and you shouldn't have to). Thanks to Shadow Walker for the Linux bug reports."

    Why is this so? It's actually pretty handy! What else should I do if it's and "unnecessary" feature?

    ReplyDelete