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)

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

works for me, even with subforms

A complete example would be interesting to see.

Tried your code and i am getting a file not uploaded error.

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 :)

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

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..

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'];
}
}

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

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

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 ?

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

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.

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?

@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.

@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

@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 :-)

@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.

@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!

@Tom: i’ve checked the code and “required” option is set to “true” by default in GIT repo and i’ve tested code in repo and it works http://github.com/gondo/ZFUE/blob/master/application/forms/upload.php
so if you don’t mind, send me your code or upload it somewhere (form class, controller where you process it and view file should be enough) and if i ll find some time i ll have a look.

Hi,

I have the same error like @Tom.
$form->getElement(‘file’)->isUploadify() – return false

When I change line:
protected $_isUploadify = true;

in My_Form_Element_Uploadify then I respone error (after upload):
info: 301
type: “HTTP”

sorry, error 301 was by htaccess :) but now I have error IO.

@mits: glad to hear that u moved on, what error exactly are u getting now?

Could you please provide steps to integrate uploadify with Zend framework 1.10?

I am using Zend 1.10

so please help me with this as i need to upload multiple files and save them to Temp folder.

Please help me..

Regards,
Pankaj

hi, if its version 1.0 or higher, this should work.
uploading multiple files wasn’t integrated yet, but you are more than happy to contribute.

@gondo: Thank you for your help but I think I have to fix this by my own and I also have nearly copy&past the code from you to my project but it still doesnt work. I also tried it with using different JQuery Versions but it doesnt work. Always the same error: “File was not uploaded”…

@mits: Have you found a solution yet?

Hello i have installed everything problem is don’t know where to handle files i am using multi files example is handling image on submit. I can not understand when to handle files and where ? when i handle on submit only one file is in form other files are in folder i have selected but for not continue names of files so out of control how many files are uploaded and names. Then i try to handle files one at the time in same controller -> action but end up with nothing. Can someone help me to figure that out. Thanks very match.

@sems: hi. this example shows how to handle just one file. in theory it should work for multiple files as well with some adjustments, but i’ve never needed that so i’ve not tried that.

@all: main reason for above code is to demonstrate the idea behind integrating Uplodify with ZF. it includes working example (or at least for me), but, as whole ZF, you ll have to understand how it works and adjust it to your needs.

Very good integration with Zend, but I’m having a little problem, I need to get the name of the file you’ve uploaded and save to a database, you can give me a hand?

@Luciano: hi. it was some time ago since i last time worked with this extension. but the main idea for this is, to behave like and extension of default Zend_Form_Element_File so you should be abe to get the file name as you would do it with Zend_Form_Element_File by calling getFileName() function.

I am reallly fascinated on this zend form element… really nice job you have done here. It would be interesting if somebody could write an zend form element class for uploadifiy that could be used in AJAX form submit. sorry for my english

How to determine the filepath / filename in onComplete if the rename filter is active?

onComplete: function(event, queueID, fileObj, response, data)

fileObj.filePath is the path BEFORE the rename filter renamed the file.

I also can’t figuring out, how to get the new path/filename.
Did you already found a solution Daniel?

Thx man, that works perfect!