I love developing usable and rich web applications using the latest techniques available.

SWFUpload part II

December 19, 2006

Well I did it, I’ve got SWFUpload working with Cakephp and infact it’s really easy. In your fileupload handling you need to use the following array

$this->params['form']['Filedata']

I think the rest is pretty easy for you to get working and that’s why I won’t go further into this. You can drop a comment of you have any problems.

Because i’m in a good mood, I deciced to post some example code.

Update (03-03-2007)
Be sure to read the comments, James Revillini has made some nice work the last few weeks.

Here is the code for the uploads controller, use the example from the SWFUpload in your view.

< ?php
class UploadsController extends AppController
{
var $uses = array('video');
public function index() {

if(!empty($this->params['form']['Filedata'])) {

$uploadpath = “videos” . DS;
$uploadfile = $uploadpath . $this->params['form']['Filedata']['name'];

if(move_uploaded_file($this->params['form']['Filedata']['tmp_name'], $uploadfile))
{
$this->render(‘succes’);
}
else {
$this->Session->setFlash(‘Something went wrong…’);
$this->render();
}
}
}
}
?>

Allright here’s the view for the upload form

    And here is the javascript file i’m using (needs prototype.js)

    Event.observe(window, ‘load’, function() {
    mmSWFUpload.init({
    debug : false,
    upload_backend : “http://clipbox.dev/upload/”,
    target : “SWFUpload”,
    // link_mode : “standalone”,
    // link_text : “Upload”,
    // css_class : “myCustomClass”,
    allowed_filesize : “500000″,
    allowed_filetypes : “*.mp3;*.gif;*.jpg;*.png;”,
    upload_start_callback : ‘uploadStart’,
    upload_progress_callback : ‘uploadProgress’,
    upload_complete_callback : ‘uploadComplete’,
    upload_error_callback : ‘uploadError’,
    upload_cancel_callback : ‘uploadCancel’,
    upload_queue_complete_callback : ‘uploadQueueComplete’
    })
    }
    );

    uploadError = function(error) {
    alert(‘error’);
    }
    uploadStart = function(fileObj) {

    $(“filesDisplay”).style.display = “block”;

    var li = document.createElement(“li”);
    var txt = document.createTextNode(fileObj.name);

    li.className = “uploading”;
    li.id = fileObj.name;

    var prg = document.createElement(“span”);
    prg.id = fileObj.name + “progress”;
    prg.className = “progressBar”

    li.appendChild(txt);
    li.appendChild(prg);

    $(“mmUploadFileListing”).appendChild(li);

    }

    uploadProgress = function(fileObj, bytesLoaded) {
    var progress = $(fileObj.name + “progress”);
    var percent = Math.ceil((bytesLoaded / fileObj.size) * 100)

    progress.style.background = “url(/js/SWFUpload/images/progressbar.png) no-repeat -” + (100 – percent) + “px 0″;

    }

    uploadComplete = function(fileObj) {
    $(fileObj.name).className = “uploadDone”;
    $(fileObj.name).innerHTML += ” ” + (Math.ceil(fileObj.size / 1000)) + ” kb”;
    }

    uploadQueueComplete = function(fileObj) {
    alert(“Queue done!”);
    }

    uploadCancel = function() {
    alert(“You pressed cancel!”);
    $(“SWFUpload”).ih();
    }

    I’m only using this for testing and I’ll finetune this later, anyway have fun with it :)

    Bookmark and Share
    Filed under: General

    19 Comments »

    1. Hi again, thanks alot for your email, my problem actually was that i was having a route set for “upload” wich was sending the request to another controller, another one of those stupis mistakes I tend to do sometimes! :)

      SWFupload really is a wonderful piece of code and has really helped to improve the UI of my app!

      Ps. Keep the good posts coming!

      19/12/2006 @ 8:08 pmKim Fransman
    2. Hi again, just one more question, what to you set the “upload_backend” to in your view?

      19/12/2006 @ 8:26 pmKim Fransman
    3. I Used the same code as the example you find in the zip of SWFUpload and put that in the view. I will post it for u tomorrow

      24/12/2006 @ 1:06 am — eelco
    4. Hi Eelco, great job! I was only wondering how i can get the filenames into my model. Are they saved in a form field?

      29/01/2007 @ 1:20 pm — ron
    5. You mean the file name of the file that has been uploaded?

      $this->params['form']['Filedata']['name']

      More information about file upload with php can be found here
      http://nl3.php.net/features.file-upload

      Only difference with cakephp is that u need to use ‘$this->params['form']‘ instead of ‘$_FILES’

      have fun :)

      04/02/2007 @ 6:43 pmEelco
    6. This is sweet. I’ve used SWFUpload in another application and it’s pretty rad. It’s nice of you to explain integration with Cake, as I’ll need this functionality in my application soon.

      Peace,
      James

      24/02/2007 @ 7:17 amjames revillini
    7. I just spent the last 3 hours trying again and again to get this to work.

      My issue was that I had tried to rename the file input on the front end, and on the backend, I was trying to access $this->params['form']['new_input_name']. Unfortunately, I think you’re stuck using $this->params['form']['Filedata'].. I hope this saves someone else some time. I almost rammed a spoon through my temple because it was the closest object to me at the time.

      01/03/2007 @ 8:39 amjames revillini
    8. I’m afraid so yeah.

      I haven’t been digging around in the front-end code that much, so I can’t help you with this one.

      Still there should be some way to change the post variable name in flash.

      02/03/2007 @ 2:59 pmEelco
    9. Hi again. i just wanted to post a little bit more about my experiences using SWFUpload with Cake.

      Getting the files to save on the file system was fairly easy after I got past the problem I mentioned in my last post. The next issue I had was with saving meta-info about the file in my database because I want the site user to be logged in when they send uploads.

      The issue is that flash opens a new session because it doesn’t have the same user-agent string. Cake uses the user-agent string to form a hash that goes into your session id. Since flash is sending ‘Shockwave Flash,’ Cake considers it a different user; therefore none of the session/authorization data that you would expect to be available to the upload controller is there, and any data you want to pass back will be unavailable as well.

      The only solution I found was a bit of a hack which opens a security hole, but works if you’re not immensely concerned about session hijacking. It is posted at http://groups.google.com/group/cake-php/browse_thread/thread/5cedbe5a1718e9ce/3924743d44746f42?lnk=gst&q=swfupload&rnum=1#3924743d44746f42 and basically involves sending the session id via URL along with the post data.

      On another note, I also needed to ensure that the existing files would not get overwritten, so I wrote this:


      $filedirname = 'files';
      $uploadpath = WWW_ROOT . $filedirname . DS;
      $wwwpath = '/' . $filedirname . '/';
      $filename = $this->params['form']['Filedata']['name'];

      // on duplicate, append a digit to the end of the name
      $filenumber = 0;
      $filesuffix = '';
      $fileparts = explode('.', $filename);
      $fileext = '.' . array_pop($fileparts);
      $filename = implode('.', $fileparts);
      //try to find a good name
      while(file_exists($newfile = $uploadpath . $filename . $filesuffix . $fileext)) {
      // and keep increasing it until we have a unique name
      $filenumber++;
      $filesuffix = '(' . $filenumber . ')';
      }
      if(move_uploaded_file($this->params['form']['Filedata']['tmp_name'], $newfile)){
      //do what you got to - it is saved
      } else {
      //bummer - it did not save!
      }

      My next steps are to figure out how to send proper HTTP status response headers depending on whether the upload succeeded or not. The way the code is now, the flash file is going to receive a 200 no matter what, which means that the thing will always assume it succeeded. If you have any tips on doing those status headers in a Cake-friendly way, do tell.

      Thanks again.

      03/03/2007 @ 11:32 amjames revillini
    10. Wow you’ve put some nice work into it, very nice! I’m sure there are more people running into this.

      Unfortunately I haven’t had time to digg into this as much as you did, so I’m afraid I can’t help u with the request headers at the moment.

      Would I find out some more about it you’ll be the first to hear.

      Mayb it’s a good idea to make some sort of upload component in the future?

      Good luck!

      03/03/2007 @ 2:12 pmEelco
    11. Agreed. As soon as I get my app doing everything I need it to, I plan to make the uploader into a component. I’ll paste it at my site and let you know. I’ve now got it creating directories which mimic the objects i’m associating it with to avoid naming collisions i.e. WWW_ROOT . ‘/files/documents/1/’ . $filename

      Talk to you soon. Oh, and BTW, your ported JSON component is AWESOME. I’m using it all over the place.

      05/03/2007 @ 1:09 amjames revillini
    12. hehe, Great to hear that!
      Good luck with the component, you’re doing a really good job.

      05/03/2007 @ 11:22 amEelco Wiersma
    13. SwfUploadComponent is done! I just made the final revisions to it last night. Gwoo actually stepped in and helped me refine it a bit, which was really great. Peace!

      24/03/2007 @ 9:43 pmjames revillini
    14. @james revillini

      Regarding to session problem with SWFUpload: solution described in google group (modifications in app/config/bootstrap.php and cake/libs/session.php, session id in GET) could be achieved by two lines of code.

      Just

      a) at the end of controller’s method which renders form with upload
      and also b) right at start of method which handles upload

      (usually it will be one method) put code

      $this->Session->del(‘Configure’);

      In this case – cake will not try to validate UserAgent but it will still use same session. And a bonus for free: this security hole will be not opened for whole application.

      18/04/2007 @ 10:14 pmpoLK
    15. Thanks for noticing poLK, hopefully James will update his component soon :)

      19/04/2007 @ 3:59 pmEelco Wiersma
    16. Sorry for mistake in my above post, correct code is $this->Session->del(’Config’);

      By the way: don’t think it is perfect solution, especially if You’re using CakePHP 1.2 and You’re keeping selected language for i18n in session by $this->Session->write('Config.language');

      20/04/2007 @ 8:26 ampoLK
    17. [...] after a bit of trawling came across this and [...]

    18. http://landotwan.info/viagra/blog-buy-viagra.php

      30/01/2008 @ 11:01 pmmaximopa
    19. [...] to Eelco Wiersma for the original code which I used as a basis for development. Also, thanks to gwoo for guidance and cakebin pastes – he [...]

    Leave a comment