The Unwritten Manual: Ajax & Flash Multi File Uploader
I think my pet peeve of the day today is going to be developers who think that no documentation or setup instructions should be necessary for their little chunk of code… especially when it mashes up as many things as Harald Kirschner’s Fancy Uploader does.
(Then again, I should know better than to work off of someone’s code when they term themselves a “Web Craftsman” and have personal philosophies as headlining elements of their “about me” page.) See also: New Media Douchebags Explained.)
If you’re banging your head against this like I have been for the past four hours, you’ve probably figured out a few things. First, the library files that are required to make the javascript work need to be called in a particular order. That order is:
- The MooTools 1.2 –FULL– compressed library. Yes, I know he says you only need a few components. Yes, he lied. Selecting the components he specified will give you an error along the lines of “window.scroll is not a function at Swiff.Uploader.js (line 62)” … so save yourself the time and just pull down the full compressed/mangled MooTools.
- Fx.ProgressBar.js
- Swiff.Uploader.js
- FancyUpload2.js
- script.js
Stray from that order, and you develop problems. Also, I found that instead of using
window.addEvent('load',function ...
as the first line of script.js, it was better to use
window.addEvent('domready',function ...
.
Second, let’s take a look at the sample file that’s supposed to magically save what we spit out. Specifically, script.php — which receives the ajax update based on a session variable that’s set, and then saves the information with an indexed .ini file. First off, it’s hard to debug. Let’s use PHP’s output buffering functions to help that. You can use this snippet of code to write a log of what’s going on:
13 $logfile = fopen($folder.'logfile','a'); 14 ob_start(); 15 var_dump($_FILES); 16 var_dump($_POST); 17 var_dump($_GET); 18 fwrite($logfile,ob_get_contents()); 19 ob_end_clean();
What you’ll notice is that, with the default code that comes with the script, you’ll have the same session ID and since the session ID is created in the javascript and each session ID is incremented in the PHP script, you’ll overwrite your file if you’re uploading multiple files — which was the whole purpose of using flash and AJAX in the first place! This is what we call a brillant(sic) programming decision… or really, one where the developer just didn’t really THINK before he wrote it. I’ve rewritten my function to simply create a directory in the ‘uploads’ folder with a batch name that I enter on the main form. After all files have uploaded successfully (or not), I have a ‘continue’ button that does a bunch of database work and sucks the text of the files into the database.
Now, I’m working with a Zend Framework application here — this means that I need to make a few changes. First, the script depends on not having any authentication ahead of the request. While the browser will still maintain the session, the ajax requests won’t have the browser’s cookies and therefore will bounce off of any preDispatch authentication. To get around this but still stay secure, I generate a (hidden) temporary session ID, store it in the database, and clear the table on a regular basis.
I’m on a crunched deadline and still don’t quite have things working yet, but in the next day or two I’ll post the fruits of my labor. Too bad this uses MooTools and not Dojo… as far as I know, Dojo still doesn’t have a flash-compatible uploader that will allow multiple selection.
But back to where I started: Harald, dude, you ain’t no web “craftsman” if someone needs to spend 8 hours learning your code and writing workarounds before they can implement it.
Since I seem to be a New Media Douchebag, I should comment on your post to feel recognized and to celebrate your blog
.
Sorry for your 8 hours, I hope that you got your deadline. Sorry also for the long comment, I somehow feel like I need to defend myself.
A quote from the presentation about Web Craftsmanship, linked on my lame about page: “Craftsmen Are Life Learners”.
I share my scripts under an unrestricted open-source license, add showcases, changelogs, support via comments and mail. If I don’t write full tutorials for installation and tuning, I did simply not find the time. I also think that people benefit from installing scripts on their own and reading my code. I don’t have any drop-in-and-forget script because I simply don’t like them. I see scripts more as tools in a developers toolbox. If people don’t want to invest time and want a working & customized, they simply hire me.
Always keep in mind that you use this scripts for free, usually without adding a notice or telling the client. It should save time and money. I’m spending my free time between contract work (sometimes I do real work
) on updates and answer im-messages and e-mails.
Finally: Can I add your tutorial under CC-Attribution-Noncommercial-Share Alike to the project page?
Yes, but give me a few days to finish the tutorial. I’ll send you an email while it’s done. If you’d like to add the part above on how to debug it using PHP since the ajax may make that a little non-intuitive for most coders, feel free.
Don’t worry on the new media douchebag thing — I’m a sysadmin by trade right now, and being told by a sysadmin that you’re a douchebag is kind of like being told by a right-wing evangelical christian that you’re going to hell. You’re out in douchebaglandia with some pretty cool people that have done some awesome things. But to the curmudgeonly sysadmin in me, which needs to deploy your project and is then held responsible for it’s uptime, you’re all a pain in the ass.
From a fellow sysadmin who spent a week trying to get his form variables to the upload script:
‘data’: {field_id:$(‘field_id’).value},
was what finally worked for me in the swiffy initialization.
I found your page helpful as well. Wish I had found it sooner!