Zend Framework Uploadify Extension

UPDATED: 26.7.2010, added working example

ZFUE – Zend Framework Uploadify Extension v 1.0

Content

How does it works
What you need.
How to
    – Download
    – ZF Form Element
    – ZFUE My_Form_Element_File setup()
    – Handling upload
    – Options
    – Fix session problem
TODO
License
Bugs
Download

How does it works

ZFUE tries to simplify Uploadify integration and prevent duplicate code for handling file upload.
It embeds itself upon exiting Zend_Form_Element_File object and retrieve as much information, as it can from original setup. That means it check for different ZF validators, such es ‘Extension’, ‘Size’ and creates necessary settings for Uploadify.
It also handle uploading file into defined destination (if not defined, file is uploaded to default temp directory), so you don’t have to create specific page just to handle file uploading for Uploadify.
While uploading, it validates uploaded file against setup validators, so it provides same level of security as classic file upload.
After form submit, it overwrites Zend_Form_Element_File settings and tries to simulate original file upload behavior.
ZFUE also solves $_SESSION problem for non IE browsers.

What you need

Zend Framework – i am using version 1.9 but this extension should work every with newer versions, as long as there will not be drastic change in ZF library code.
Uploadify – i am using version 2.1.0 (what is latest at the moment)

You will also need jQuery and SWFObject libraries, but uploadify already comes with this, so you don need to download it separately, unless there will be newer version you would like to use.

How to

Download

Download latest version. Unzip downloaded content and copy it to ‘library’ directory, next to ‘Zend’ directory (on the same level). So your ‘library’ directory tree will looks like this:

  • library
    • My
      • Form
        • Decorator
          • Uploadify.php
        • Element
          • File.php
          • Uploadify.php
    • Zend

ZF Form Element

  1. In your Zend_Form definition, replace Form_Element_File with My_Form_Element_File.
  2. Add prefix path to your decorator (allow ZF to find your custom decorator).
  3. Load custom decorator.
  4. At the end of setup chain call ‘create()’ function. (if you do not use setup chain, call this function when you finish your setup)
Before


$file = new Form_Element_File( 'my_file' );
$file->setOptions(array(
    'required' => true,
    'label' => 'Label'
))
->setDestination( '/tmp' )
->addValidators(array(
    'array( 'Count', true, 1 ),
    'array( 'Extension', true, array( 'csv' ))
))
->setDecorators(array(
    'File',
    'Description',
    'Label',
    'array('Errors', array('placement' => 'prepend'))
));
$form->addElement($file);

After


$file = new My_Form_Element_File( 'my_file' );
$file->setOptions(array(
    'required' => true,
    'label' => 'Label'
))
->setDestination( '/tmp' )
->addValidators(array(
    'array( 'Count', true, 1 ),
    'array( 'Extension', true, array( 'csv' ))
))
->addPrefixPath('My_Form_Decorator', 'My/Form/Decorator/', 'decorator')
->setDecorators(array(
    'File',
    'Description',
    'Label',
    'array('Errors', array('placement' => 'prepend')),
    array('Uploadify', array('text' => 'Nahrať súbor'))
))
->create();
$form->addElement($file);

Can it be simpler ?

ZFUE My_Form_Element_File setup()

Now you have to write My_Form_Element_File ‘setup()’ function.

$options – represent Uploadify options
Several options are created for you automatically and you are not allowed to change them. (If you do, ZFUE will not work properly.)
These are:
‘sizeLimit’, ‘fileExt’, ‘fileDataName’, ‘script’, ‘scriptData’
ZFUE custom option:
‘myShowUpload’ – tells if upload link will be displayed on the beginning.

Then you have to load ‘uploadify.css’, ‘jquery.uploadify.v2.1.0.min.js’, ‘swfobject.js’ and ‘jQuery.js’.
You can do this here or anywhere else as far it will be rendered on the page.

You can also add rename filter, to rename uploaded file.
$this->addFilter(‘rename’, ‘new_name’);
There is build function in My_Form_Element_Uploadify what you can use.
$this->addFilter(‘rename’, $this->getRandomFileName());

Handling upload

In your controller, you are handling file upload similar to this:

$form = new Custom_Zend_Form();
if ($this->getRequest()->isPost()) {
    if ($form->isValid($this->getRequest()->getParams())) {
        $form->getElement('my_file')->receive();
    }
}

So all you need to do is add one additional condition:

$form = new Custom_Zend_Form();
if ($this->getRequest()->isPost()) {
    if ($form->isValid($this->getRequest()->getParams())) {
        if ( ! $subForm->getElement('subor')->isUploadify()) {
            $form->getElement('my_file')->receive();
        }
    }
}

And thats all.

Options

In your controller, you can add rename filter to original file uploader and use My_Form_Element_Uploadify function ‘getRandomFileName()’ to generate random name:

$form->getElement('my_file')->addFilter('rename', $subForm->getElement('subor')->getRandomFileName())->receive();

Fucntion:

$form->getElement('my_file')->getFileName()

will return proper file path.

Fix session problem

Overview

Flash is lame program and cant handle sessions in other browsers than IE. So if you use sessions to authenticate user, you have to pass the sessions into flash and than again retrieve it in the code.
Right now, ZFUE is automatically adding PHPSESSID into Uploadify ‘scriptData’ option (thats why you are not allowed to change it right now, or you can, but you have to think about this session problem)
To retrieve $_SESSION information before you authenticate user, call this function:

My_Form_Element_Uploadify::bypassSession();

Usually before:
if (Zend_Auth::getInstance()->hasIdentity()) {}

TODO

Overwrite these functions and populate them with correct data when ZFUE is in ues:
$form->getElement(‘my_file’)->getFileSize();
$form->getElement(‘my_file’)->getMime;
Allow to setup Uploadify ‘scriptData’ option.
Multiple file upload.

Download

ZFUE.v.1.0.zip – 6. 4. 2010
ZFUE GIT repository with working example

note: it’s first time i am using GIT so every help would be appreciate. also if someone would like to contribute, email me. (email is on contact page)

36 thoughts on “Zend Framework Uploadify Extension

  1. Ken

    Would this work with multiple form elements. For example, text, checkbox and a file element in 1 form?

  2. gondo Post author

    hi, will try to provide complex ZF project example soon. for now i can just say that i am using exactly the same code in one of my project an it works just fine :)

  3. Nicklas

    Can’t get it work, even if I copy My into library I get:
    “Fatal error: Class ‘My_Form_Element_File’ not found i”

  4. Infidel

    What about complete example? Today I spend half on my day trying to make it work, but I fail. It don’t show any errors, just not uploading file..

  5. smak

    Thanks, works great!

    Some servers use a different session name than PHPSESSID. In this case the fix for the session problem won’t work. Could be resolved by:

    public static function bypassSession()
    {
    if (isset($_POST[‘PHPSESSID’])) {
    $_COOKIE[session_name()] = $_POST[‘PHPSESSID’];
    }
    }

  6. Rogers Sampaio

    I am trying to integrating this, but I have a doubt in which controller action I should place the form processing logic. Anyone can help?

    I already placed in the index controller, but its not seems to work. The form renders but when I upload it gives me http error.

    Please help

  7. gondo Post author

    hi folks, thanks for support, i am currently finishing git push with working example.
    @smak: thanks for advice, i’ve integrated it into the code

  8. mits

    Hello,

    nice script, but in my page not working.
    In js console show error:
    document.getElementById(a(this).attr(“id”) + “Uploader”).startFileUpload is not a function
    [Break on this error] if(jQuery){(function(a){a.extend(a.fn,…ileUploadQueue(false)})}})})(jQuery)};
    jquery….min.js (line 26)

    view in page: http://yfrog.com/0kbugozj
    I work on zend framework 1.10.7

    How can I fix it ?

  9. gondo Post author

    hi
    well from what you posted, you got error in javascript.
    first of all, when you are using jQuery, you dont have to call getElementById() at all. than “a(this).attr(“id”) + “Uploader”” is wrong, what is the first “a” ?
    i am not sure what exactly do you want to achieve with this code, but try to solve this syntax error and if you ll got more problems, provide some example url where i would be able to have a look. (post it here or you cna email me to keep it private)
    thanks
    .gondo

  10. mits

    hmmm I download your code and thats all (I copy files (php, flash, etc.) and set paths only) :)
    I would like to run this, but script show errors.

  11. Johnny

    Hi Gondo :),

    Your tutorial and sample code is great!! And its really easy to use, thanks!

    I only have a small problem, when a user tries to upload a file, it gives a “HTTP Error”. Its happening during the “onComplete” process, where do i specify the submission page of the upload process?

  12. Tom

    @Johnny: I think you just have to put following line at the end of your upload action in your controller: $this->_redirect(‘/uploaded’);
    See the git-repository for more details.

  13. gondo Post author

    @mits, @Johnyy: did u tried example code from git? if so and still got problem, try to explain it little more, email me error messages and try to describe situation when they appear.
    @Tom: thx :)
    @all: if anyone got some improvements, email me and we can discuss it

  14. Tom

    @gondo: No problem…
    But I also have a question. I want to run your extension with the ZF and I did what you wrote and also checked the git-repository but it doens’t work for me. Uploadify works (because I see the button and the flash uploader) but always when I try to upload the stuff it throws following error: “File ‘file’ was not uploaded”. Do you have an idea what I made wrong (or what is wrong)? I don’t think that I need to post the code because it’s equal to the code from the git-repo.
    I’m using ZF 1.10.5 and Uploadify in the newest version 2.1.0 like you.

    Thanks in advance :-)

  15. gondo Post author

    @Tom: i’ve tested code in git repo and it was working for me (thats why i posted it :) so you can try to debug upload process. there is build in debug functionality what can be used. basically you can call log method to save some output during uploading. u have to store output into log file because of ajax call and other process what happens under the hood, you wont be able to see error output on the screen.
    if you are getting “file was not uploaded” message, first check if everything is setup properly (mainly file permissions on directory where you are uploading to), if all files are linked correctly and if you are not getting any js error during uploading.

  16. Tom

    @gondo: Thanks for your reply. I also tried to debug with writing log files. In my controller following line returns false:
    $form->getElement(‘file’)->isUploadify()

    I don’t get any JS error and all files are linked correctly. I also have the correct permissions for saving the images. (It also works with standard file upload)

    When I add the option “required” => true then in my controller it returns false at the valid check:
    $form->isValid($this->getRequest()->getParams())

    -> returns false

    Any other ideas what I made wrong? Thank your for helping!

Leave a Reply