I didn't manage to find an upload progress plugin or wiki page so I'll try one. My solution is based on a lot's of plugins so I can understand it might not be the best one.
Dependencies
- sfUJSPlugin: Provides helpers for unobstrusive scripting
- http://digitalbush.com/projects/progress-bar-plugin jquery plugin for progressbar
- PHP 5.2 with APC ! Yes the php accelerator has a new feature since php 5.2 that will let you monitor POST request
- JSON PHP extension (default with PHP 5.2 but might be in a separate package depending on distribution)
Configuration
I have simply installed the plugins above, nothing special to be done, just following the wiki/html documentation pages.
jquery.progressbar I've copy/paste the css into "web/css/progressbar.css" and downloaded the js file into "web/js/jquery.progressbar.js" (I've rename it with the . dot to be conform with jquery plugin naming convention)
APC after installing apc either from you distribution package or from pecl (i.e howto ), then it's very important : to activate the apc monitoring feature just add "apc.rfc1867 = on" to your php.in or apc.conf file.
big file upload for big file upload (>2M):
you should play a bit with these php.ini settings: upload_max_filesize|post_max_size|max_execution_time|memory_limit
you might also check apache settings (if apache used): LimitRequestBody
code example
I use a very simple behaviour for my site but you'll be able to extend this example easily. I decided to use one unique action/template for all the upload module
the action
don't forget to modify the redirect <your_module>
<?php /** * Executes upload action * */ public function executeUpload() { if ($this->getRequest()->getMethod() == sfRequest::POST) { if ($this->getRequest()->hasFiles()) { foreach ($this->getRequest()->getFileNames() as $fileName) { $fileSize = $this->getRequest()->getFileSize($fileName); $fileType = $this->getRequest()->getFileType($fileName); $fileError = $this->getRequest()->hasFileError($fileName); $fileRealName = $this->getRequest()->getFileName($fileName); $uploadDir = sfConfig::get('sf_upload_dir'); $this->getRequest()->moveFile('test_file', $uploadDir.'/'.$fileRealName); $msg = "file uploaded ** $fileSize ** $fileType ** $fileError ** $fileRealName ** $uploadDir"; } }else{ $msg = "no file uploaded"; } $this->setFlash('message',$msg); $this->redirect('/<your_module>/upload'); } else if( ($progressKey = $this->getRequestParameter('progress_key')) != null ) { $status = apc_fetch('upload_'.$progressKey); $this->renderText( json_encode($status) ); return sfView::NONE; } //finally return sfView::SUCCESS; }
the view don't forget to modify the getJSON <your_module>
<?php use_helper('UJS') ?> <?php use_javascript('/js/jquery.progressbar.js') ?> <div id='flash'> <?php echo $sf_flash->get('message') ?> </h1> </div> <?php $uniqId = uniqid() ?> <form enctype="multipart/form-data" id="upload_form" action="" method="POST"> <input type="hidden" name="APC_UPLOAD_PROGRESS" id="progress_key" value="<?php echo $uniqId?>" /> <input type="file" id="test_file" name="test_file" /><br /> <input type="submit" id="submit" value="Upload!" /> </form> <div id='progressbar' style='display: none'/> <?php UJS(' $("#submit").click(function() { setInterval("$.getJSON(\'/<your_module>/upload\', { progress_key: \''.$uniqId.'\'}, function JSON(json){$(\'#progressbar\').show();$(\'#progressbar\').reportprogress(eval(json.current/json.total*100));} )", 1000) }); '); ?>
stylesheet Don't forget to include the css into the view.yml
uploadSuccess: stylesheets: [progressbar]
That's it ! Hope someone will find it usefull...
By the way thanks very much to Francois and other who contribute to th UJS/PJS/JQuery plugin which is simply incredible.
Note: this version is a very basic version, you could enhance it by using iframe and monitor the upload start/end instead of onclick/redirect tips used here... but hope someone might contribute and enhance this page ...
Benoit