How to integrate uploadify in Zend Framework 1.9.6

Post Pic

A detailed tutorial will show you how to integrate Zend Framework version 1.9.6 with jQuery Uploadify version 2.1.0. The tutorial covers all the basic aspects of the process from installing the framework on a multi zend applications with the same library/separate configurations system to integrating the jQuery Uploadify into your website. The uploads will be made in a secure folder, outside the public area of your server from where you can manipulate the files as you wish.

In a previous post, i talked about integrating the script jQuery Uploadify into the CakePHP framework. Today, i will show you how to integrate it into Zend Framework 1.9.6.
Our goal is simple: create a new zend application that uses a common library, gets its configuration files from a custom location and integrate it with Uploadify

Application folders & the public files

First of all, you will need to download the Zend Framework. You can download it from the Zend site here. In this tutorial, i will work with the 1.9.6 version of the framework.

We will now create our directory structure for the framework.

  • Create a folder in /var/www/public_html/uploadify/ named public.
  • Create two folders in /var/www/ named application and library.
  • Inside the library folder, create a new folder named 1.9.6. Inside this folder, add your Zend library folder, so you would have /var/www/library/1.9.6/Zend.

In your public folder add a file named index.php with the following contents:

define('DS',DIRECTORY_SEPARATOR);

/**
* If you followed the tutorial example paths then the following paths
* would be like : /var/www/public_html/uploadify/../../
*/
define('LIBRARY_PATH',
	realpath(dirname(__FILE__) .
	'..' . DS . '..' . DS .
	'library' . DS . '1.9.6')
);
define('APPLICATION_PATH',
	realpath(dirname(__FILE__) .
	'..' . DS . '..' . DS .
	'application' ));

define('APPLICATION_ENV','production');

$paths = array(
	LIBRARY_PATH,
	get_include_path()
);

set_include_path(implode(PATH_SEPARATOR, $paths));

/** Zend_Application */
require_once 'Zend/Application.php';

$application = new Zend_Application(
	APPLICATION_ENV,
	APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap();
$application->run();

Add a new file called .htaccess here with the following contents:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

Create a folder named scripts and a folder named images. Inside the scripts put the jQuery library, the jQuery.uploadify.v2.1.0.min.js, the swfobject.js and create a new file named scripts.js.

Inside the scripts.js add the following lines.

$(document).ready(function() {
	$('#upload_container').uploadify({
		'uploader' : uploadify_swf_file,
		'script'   : upload_php_file,
		'folder'   : upload_folder,
		'cancelImg': upload_cancel_img,
		'auto'     : true
	});
});

Inside the public folder put the uploadify.swf .

Inside the images folder put the cancel.png .

Now you are done with the public folder. On to the application..

The application config

The config file ( /configs/application.ini ) can have the default values.

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0

bootstrap.path = APPLICATION_PATH "/Bootstrap.php";
bootstrap.class = "Bootstrap";

resources.frontController.controllerDirectory = APPLICATION_PATH
"/controllers";

resources.layout.layout = "layout";
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts";

resources.view.encoding = "UTF-8";
resources.view.basePath = APPLICATION_PATH "/views/";

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

The application controller

Create a new file in your controllers folder named UploadifyController.php with the following contents:

/**
 * @name UploadifyController
 * @desc The controller to serve the main page for our upload example.
 *
 * @author Andrei
 * @filesource application/controllers/UploadifyController.php
 * @version 1.0.0
 */

Class UploadifyController extends Zend_Controller_Action
{

	public function indexAction(){}

	public function uploadAction()
	{
		if (! empty ( $_FILES ))
		{
			$tempFile = $_FILES ['Filedata'] ['tmp_name'];
			$targetFile = APPLICATION_PATH . DS . 'uploads'
			. DS . $_FILES ['Filedata'] ['name'];

			move_uploaded_file ( $tempFile, $targetFile );
			echo "1";
		}
		else
		{
			echo 'No files sent';
		}
	}
}

Create a folder in your APPLICATION_PATH named uploads and make it writable by PHP (ex: chmod 0777).

What have we done so far?
Now, we basically have an application that displays a nice empty page with the uploadify script included, have all the JS code in external files and JS variables that contain dynamic data (aka PHP variables) in our main layout.

The application views

Make sure you have the folder uploadify in your /views/scripts/ folder and inside it the files index.phtml and upload.phtml .

Inside the index.phtml make sure you have the following line somewhere (where you want to have the uploadify generated) :

< div id = "upload_container" >< /div >

Inside your layout.phtml make sure you have the following code (stripped so it can be displayed properly):

< script
	type="text/javascript"
	src="< ?php
		echo $this->baseUrl('/js/swfobject.js');
		?>">

< script
	type="text/javascript"
	src="< ?php
		echo $this->baseUrl('/js/jquery.uploadify.v2.1.0.min.js');
		?>">

< script type="text/javascript">
	var uploadify_swf_file = '
		< ?php
			echo $this->baseUrl(
				'/uploadify_files/uploadify.swf'
			);
		?>
	';
	var upload_php_file    = '
		< ?php
			echo $this->url(
					array(
						'controller' => 'uploadify',
						'action' => 'upload'
					)
			);
		?>
	';
	var upload_folder      = '
		< ?php
			echo $this->baseUrl(
				'/uploads/'
			);
		?>';
	var upload_cancel_img  = '
		< ?php
			echo $this->baseUrl(
				'/uploadify_files/cancel.png'
			);
		?>';
< /script>
< script
	type="text/javascript"
	src="< ?php echo $this->baseUrl('/js/script.js'); ?>">

Conclusion

Now, everything should work. If you browse your application at example.com/uploadify/ you should see the uploadify button here.

If you have any problems implementing the tutorial, feel free to contact me via comments below and I’ll try to help you fix them.

$(document).ready(function() {
$(‘#upload_container’).uploadify({
‘uploader’ : uploadify_swf_file,
’script’ : upload_php_file,
‘folder’ : upload_folder,
‘cancelImg’: upload_cancel_img,
‘auto’ : true,
‘onError’: function (event, queueID ,fileObj, errorObj) {
var msg;
if (errorObj.status == 404) {
alert(‘Could not find upload script. Use a path relative to: ‘+’;');
msg = ‘Could not find upload script.’;
} else if (errorObj.type === “HTTP”)
msg = errorObj.type+”: “+errorObj.status;
else if (errorObj.type ===”File Size”)
msg = fileObj.name+’
;’+errorObj.type+’ Limit: ‘+Math.round(errorObj.sizeLimit/1024)+’KB’;
else
msg = errorObj.type+”: “+errorObj.text;
alert(msg);
$(“#fileUpload” + queueID).fadeOut(250, function() { $(“#fileUpload” + queueID).remove()});
return false;
},

});
});

  • Erik
    Hello,

    Thanks for this tutorial! I tried using it in my zend framework application, but I can't get it to work, the upload button doesn't show up. All the paths seem to be configured in the right way, when I render the HTML, I get this:

    <script type="text/javascript" src="/lib/uploadify/swfobject.js" ></script>
    <script type="text/javascript" src="/lib/uploadify/jquery.uploadify.v2.1.0.min.js" ></script>
    <script type="text/javascript">
    var uploadify_swf_file = '/lib/uploadify/uploadify.swf';
    var upload_php_file = '/cms/auction/upload';
    var upload_folder = '/img/auction';
    var upload_cancel_img = '/lib/uploadify/cancel.png';
    </script>
    <script type="text/javascript" src="/lib/uploadify/scripts.js" ></script>

    As you can see, I've done some modifications to the file paths, but they all point to existing files, any udea what I could have done wrong?
  • Hello,

    Thank you for the excellent write up on integrating Uploadify and Zend. I've got this working on my local machine but I am having a problem when I test on a live server (godaddy hosted). I've used the example code from the Uploadify download to test the live server and I am able to upload files successfully to the specified directory. So I don't think the error is with the server configuration.
    I'm getting a 406 error when I try to do the upload within zend. Here's a log entry from the server: "POST /public/uploadify/uploadecg/sid/3 HTTP/1.1" 406 486 "-" "Shockwave Flash" The controller I created accepts the paramater 'sid.' The progress bar goes to 100% then I get a Http Error.

    The 406 error was leading me to think it was an issue with the upload folder or even the tmp directory but it works fine with the example script so it has to be something in the code in my zend app. I know this info is a bit vague but do you have any suggestions as to where I can look to find the source of the error.

    Regards
    Navin
  • Hello Navin,

    If I understood correctly, the tutorial I wrote above worked on your dev machine but not on the live server? If this is the case then its most likely NOT a code issue (could be but its not the source of the error) and its most likely a settings in your webserver / php configuration.

    Basically what your error tells you is that the client (the SWF in this case) said it accepted some type of content but the webserver sent another type of content. Most likely you have a problem with the Mod_Security apache plugin.

    Can you try the following and tell me if it solved your problem?

    Put this in your .htaccess somewhere

    <IfModule mod_security.c>
    SecFilterEngine Off
    SecFilterScanPOST Off
    </IfModule>

    I did not understand completely but did you try the example script on the LIVE server and it worked?
  • Yes I did put the example code on my server and it worked. That's the reason I don't think it has to do with server config. I tried using that IfModule bit but it made no difference. I think I have eliminated the possibility that it is a configuration issue with the server by successfully testing with the example code.

    I modified the example code to use the same files (js and swf files) used by my app and to use the same upload folder. The only difference is the script called to upload the file. This works fine until I change the script to call the zend controller action to handle the uploading. The call to the zend controller action from the example code works fine on my local machine.

    I did some further testing and I commented out the code in the controller upload action and I got the same error. It would seem to be the call to the controller action is where the error is occurring.

    Update: I've got this working by calling the upload script from the example code. Basically I call the script as an 'external-to-zend' php file. I'm not sure why the call to the controller action does not work though.

    Cheers
    Navin
  • hi

    i've created Zend Framework Uploadify Extension what use different idea to implement Uploadify.
    more can be found here: http://gondo.webdesigners.sk/zend-framework-upl...

    .gondo
  • Hello,

    This is a very general error and I cannot tell you exactly what it could cause it. You need to look in your apache logs / error logs and find the error there. Once that is found, you could post it here and I will gladly help you fix it. If you cannot find the error there, try debugging with "die('test1');" in your code to see where the problem appears (line by line).

    Good luck!
  • QaziArsalan
    Hello Andrei Gabreanu !
    As a fresh graduate and internee I am having problem in using jquery plugin on my website, please can u guide me how can i implement it I am using PhpEd for this purpose. when I run this code I get an error "HTTP error".
    Greeting and Thanks,
    Arsalan
  • Jordi Aragones
    Well... I can see pros and cons in both points although I'm not sure what it's better in my case... the project that I'm developing will spend some bandwidth (has videos) and that means that maybe it could be nice to upload directly to s3 (in order to save money in bandwidth).

    I will check if I can interact with my db using the defaults functions in uploadify (onOpen, onError, onCancel, onAllComplete).

    Thanks for your help and thoughts! ;)
    Jordi
  • Sorry about the above comment, it might be confusing since i wrote it on a hurry. I meant to say that the option with the background process is better then sending the file directly to S3 after upload (saves bandwidth that might be used in that moment for some performance)
  • Hello!

    I believe your toughts are correct (not sure though) but I am pretty sure that the solution should be either of these 2 and not what you are trying to do:

    Sending the file DIRECTLY to S3 AFTER the user has uploaded to your server should be done (do the "echo "1" before the process that starts in the background)

    Just trigger it somehow when the upload is done on your server, send it to S3 and then delete it from your server.

    You can then just tell the user that the file is being moved in the cloud / CDN and then just actually move it. The advantage with this method is that you have full control of the whole process, meaning that you can make a Que of files and upload them later (or not if you have a limit of some sort).

    The easiest way to achieve this is to upload the file somewhere on your file system or database, and have a cron job that checks at each X time if that folder or DB table is empty. If it is not, then start doing the S3 process for each item, checking conditions (file is good, not an EXE and so on) and you are finish.

    Hope these thoughts help!

    Regards,
    Andrei
  • Jordi Aragones
    Hi Andrei!

    The solution that you give me is almost the same that I was trying and I get the same result... I realize that the behavior of the component is... (I'm testing in localhost and upload file to S3) the next one...

    1) When I select the file, it starts the upload.
    2) The progress information it starts to count till 100%.
    3) It shows 100% till $s3->putObject finish and in this moment I sent echo "1"; and shows complete.

    At this moment I was thinking that it didn't work... but... now my conclusion or question is (and sorry if it is that one and I make you lose your time):

    1) I select my file in my computer, it starts the upload from my computer to my server. In my case localhost, but if I take a big file (size: 300M), this process takes a while -> and is this moment that the uploadify progress bar counts.

    2) I'm counting till 100% -> the transfer between my computer (or users computer) to my server (or local server).

    3) move_uploaded_file function takes a while (and it just a while to mv a file from tmp file in server to my uploaded_file folder in my server -> it sends echo "1"; and the users doesn't notice anything. BUT... if I move from my server to another server with a "slow" connection as we have in Spain, till I sent echo "1"; (to say Complete) it takes a lot of time! And it's for this reason that for me it looks that it isn't working (it reach 100% and it takes a lot of time to finish till complete).

    Am I right? Then I think that I have to option to avoid this problem:

    1) To upload the file direct to S3, as some solutions are proposed in internet.
    2) I upload the files to my server and then in another process or background process... I sent this file to S3, without needing the user to be waiting.

    What do you think?

    Thanks anyway for your help!
    Jordi
  • Hello Jordi,

    Have you tried doing the $s3->putObject(...); then put echo 1; exit(); ?

    Uploadify is waiting for the 1 to show up or "No files sent". Have you tried faking this? It should work like this.

    Make sure no fatal error occurs while doing the s3 move because this would mean that uploadify will NOT get any response (thus fail).

    I would do something like this:

    public function uploadAction()
    {
    if (! empty ( $_FILES ))
    {
    $tempFile = $_FILES ['Filedata'] ['tmp_name'];
    $targetFile = APPLICATION_PATH . DS . 'uploads'
    . DS . $_FILES ['Filedata'] ['name'];

    // move_uploaded_file ( $tempFile, $targetFile );
    try {
    //your S3 code goes here
    if ($s3->putObject(“files/2″, file_get_contents($tempFile)))
    {
    echo "1";
    }
    else
    {
    echo "Error at S3";
    }
    }
    catch (Exception $e)
    {
    echo 'Exception: ' . $e;
    }

    echo "1";
    }
    else
    {
    echo 'No files sent';
    }
    }

    Then ,just check the response you get from the server via FireBug or another way and if its ok, move on to making sure uploadify gets it as it should.

    Good luck and if you have time, tell me if it worked!
  • Jordi Aragones
    Hi! First of all thank you very much for your tutorial it was really helpful.

    But... I got another problem that maybe you know how to solve it, I would like to save my file in Amazon S3 (now it get save in my server HD). I tried to change the line of move_uploaded_file (of my controller) for a new line that looks like $s3->putObject("files/2", file_get_contents($tempFile)); (using Zend_Service_Amazon_S3) the problem is that I suppose that uploadify component is waiting for some information that it come back from the function move_uploaded_file, and putObject (from Zend) doesn't come back.

    My question (as I think that you suppose) is: Is there any way to do what I want to do from my controller? I tried in google and all I get is to upload direct from uploadify to S3 (without any controller).

    Thanks again!
    Jordi
  • Thank you Renato! I'm glad it helped!
  • @Andrei

    You did a great job with this tutorial!
    It helped me to implement uploadify in my Zend Project..

    Thanks!
  • @Jacqueline

    First of all you should not have the Zend library in configs directory. You should have like this:

    uploadify-zend/application/
    uploadify-zend/library/1.9.6/Zend

    and then set your include paths to match these. Try playing with the paths in the index.php until you get something else then errors (just play with DIRNAME() for each path to go up/down in the directory tree.

    Hope it helps!
  • Jacqueline
    Hi Andrei,

    I tried just uploading made a unique design and called it 'uploadify-zend' I made the following folder structure:
    within my htdocs (I use xampp):

    uploadify-zend : uploadify-zend/application
    uploadify-zend/application/controller
    uploadify-zend/application/controller/UploadifyController.php
    uploadify-zend/application/views
    uploadify-zend/application/views/layouts
    uploadify-zend/application/views/layouts/layout.phml
    uploadify-zend/application/views/scripts
    uploadify-zend/application/views/scripts/uploadify
    index.phtml
    upload.phtml
    uploadify-zend/configs
    uploadify-zend/configs/application.ini
    uploadify-zend/configs/library
    uploadify-zend/configs/library/1.9.6/Zend
    uploadify-zend/public/
    uploadify-zend/public/css
    uploadify-zend/public/scripts
    uploadify-zend/public/swf
    uploadify-zend/public/images
    uploadify-zend/uploads
    uploadify-zend/index.php
    uploadify-zend/.htacces

    and I was returned the following error:

    Warning: require_once(Zend/Application.php) [function.require-once]: failed to open stream: No such file or directory in C:\xampp\htdocs\uploadify-zend\index.php on line 29

    Fatal error: require_once() [function.require]: Failed opening required 'Zend/Application.php' (include_path=';.;C:\xampp\php\pear\') in C:\xampp\htdocs\uploadify-zend\index.php on line 29
  • Ok! You are welcome.
  • Jacqueline
    Hi Andrei button uploadify is appearing, he even looks like the progress bar, the only thing that is happening is the rescue of the physical file in hd.

    But I will do the tests again tomorrow and will send you more information!
    Thank you very much,
    Jacqueline
  • @Jacqueline

    The upload.phtml was used just so Zend would not fail requesting you to have a view for your upload action. (You have several options to remove it from the controller but for simplicity sake i did not use them) so basically the upload.phtml file is just an empty file.

    Can you tell me if the uploadify button appears or not? Make sure that the paths are good (90% of cases when it doesn't work it is because of the paths not being good) and that there are no JS errors. If you want to debug, the easiest way is to try and upload tons of files and just print out the $_FILES array in the upload action.

    Last thing, be sure that you can access each file from the JS is storing in variables.

    Please tell me if it is working or give me some more information's once you have done all of these.

    Regards,
    Andrei
blog comments powered by Disqus

Popular tags

Partner Blogs

Latest tweets


Get Adobe Flash playerPlugin by wpburn.com wordpress themes
Web Analytics