Can someone please post an implementation of Codeigniter and plupload?
Please post the controller and view.
thanks
This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.
The active forums are here.
November 03, 2010 10:04am
Subscribe [10]#1 / Nov 03, 2010 10:04am
Can someone please post an implementation of Codeigniter and plupload?
Please post the controller and view.
thanks
#2 / Jan 25, 2011 6:51pm
You could try to port it your self from the PLUpload upload.php file.
https://github.com/moxiecode/plupload/blob/master/examples/upload.php
I’ll post it later, but I still think you should have tried yourself first and then posted here what you couldn’t get working. We’re not here to do your work!
#3 / Feb 24, 2011 3:36am
Well, I am like the OP trying to figure out how to get plupload going.
I am stuck trying to even get the ‘widget’ to show up on the page.
I am using carabiner so my code is a little all over the place 😊
controllers/diva
class Diva extends CI_Controller {
function __construct()
{
parent::__construct();
}
function index()
{
// Load up helpers
$this->load->helper(array('form', 'url'));
// Load up libraries
$this->load->library('carabiner');
//Setup variables to pass to the views
$data['breadcrumb'] ='';
//Open up all the views and display the data
$this->load->view('header_upload');
$this->load->view('menu');
$this->load->view('diva',$data);
$this->load->view('footer');
}
function process_upload()
{
// Taken from plupload - sample upload file
$targetDir = base_url() .DIRECTORY_SEPARATOR. "tmpupload";
$cleanupTargetDir = false; // Remove old files
$maxFileAge = 60 * 60; // Temp file age in seconds
// 5 minutes execution time
@set_time_limit(5 * 60);
// Get parameters
$chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
$chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;
// Clean the fileName for security reasons
$fileName = preg_replace('/[^\w\._]+/', '', $fileName);
// Create target dir
if (!file_exists($targetDir))
@mkdir($targetDir);
// Remove old temp files
if (is_dir($targetDir) && ($dir = opendir($targetDir))) {
while (($file = readdir($dir)) !== false)
{
$filePath = $targetDir . DIRECTORY_SEPARATOR . $file;
// Remove temp files if they are older than the max age
if (preg_match('/\\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge)) @unlink($filePath);
}
closedir($dir);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
// Look for the content type header
if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
if (isset($_SERVER["CONTENT_TYPE"]))
$contentType = $_SERVER["CONTENT_TYPE"];
if (strpos($contentType, "multipart") !== false)
{
if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name']))
{
// Open temp file
$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out)
{
// Read binary input stream and append it to temp file
$in = fopen($_FILES['file']['tmp_name'], "rb");
if ($in)
{
while ($buff = fread($in, 4096))
fwrite($out, $buff);
}
else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
fclose($out);
unlink($_FILES['file']['tmp_name']);
}
else
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
}
else
die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
}
else
{
// Open temp file
$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out)
{
// Read binary input stream and append it to temp file
$in = fopen("php://input", "rb");
if ($in)
{
while ($buff = fread($in, 4096))
fwrite($out, $buff);
}controllers/header_upload
<!doctype html>
<html>
<head>
<?php
$this->carabiner->css('wlb.css','screen');
$this->carabiner->css('upload.css','screen');
$this->carabiner->js('gears_init.js');
$this->carabiner->js('plupload.full.min.js');
$this->carabiner->js('jquery.plupload.queue.min.js');
$this->carabiner->js('upload.js');
$this->carabiner->display('jquery');
$this->carabiner->display('both');
?>
</head>Continued in next post
#4 / Feb 24, 2011 3:39am
Continued.
upload.js
$(function() {
$("#uploader").plupload({
// General settings
runtimes : 'gears,flash,html5',
url : 'diva/process_upload',
max_file_size : '1000mb',
chunk_size : '1mb',
unique_names : true,
// Resize images on clientside if we can
// resize : {width : 320, height : 240, quality : 90},
// Specify what files to browse for
filters : [
{title : "Document files", extensions : "doc,docx,txt,xls,ppt,pdf"},
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Video files", extensions : "avi,wmv,qt"},
{title : "Audio files", extensions : "mp3,flac"},
{title : "Zip files", extensions : "zip"}
],
// Flash settings
flash_swf_url : 'assets/scripts/plupload.flash.swf',
});
// Client side form validation
$('form').submit(function(e) {
var uploader = $('#uploader').pluploadQueue();
// Validate number of uploaded files
if (uploader.total.uploaded == 0) {
// Files in queue upload them first
if (uploader.files.length > 0) {
// When all files are uploaded submit form
uploader.bind('UploadProgress', function() {
if (uploader.total.uploaded == uploader.files.length)
$('form').submit();
});
uploader.start();
} else
alert('You must at least upload one file.');
e.preventDefault();
}
});
});views/diva
...
<div class="upload">
Select some files to upload
<?php echo form_open('diva/process_upload'); ?>
<div id = "uploader">You need Google Gears, Flash or HTML5</div>
<?php form_close(); ?>
</div><!-- end upload div -->The generated page has all the css/js files and I have clicked to make sure they are there and load.
Anyone have any ideas why I am not even getting the widget to show up? Granted, I have not slept in about 20 hours and am probably just missing something very easy, but I can’t find it.
Thanks.
#5 / Sep 04, 2011 12:42am
DavidBer - Did you ever get this going? I’d love to know how you did it. I really want to use plupload but I want to be sure that someone has successfully implemented it in CI.
Thanks!
Andrew
#6 / Sep 07, 2011 2:51am
Well for the sake of impatience, I managed to turn it into a library. Woohoo! It’s working great too. Super simple to implement. If anyone wants the files for this, just PM me and I’ll send them over.
#7 / Sep 07, 2011 5:25am
Hi AndrewC,
I abstracted the upload code a while back, separating each different style of uploading (using the input stream or multipart, etc) and separating the uploading part from the processing afterwards. I got some amazing results (both in development time and in performance).
Did you just put the code into a library, or abstracted it greatly as well? I’m asking, because if you did differently, I’m very interested in benchmarks: if you could post some, that would be great (just code execution benchmarks, not uploading time). I’m upgrading my company’s publishing platform and I’m trying to optimize the performance greatly!
Fabian
#8 / Sep 07, 2011 10:29am
I did have to rewrite some of the content in order to put it into a library. For instance, I created a config file for the target directory and execution time. I also used carabiner for the view (to do the js and css). I used a fair amount of their code, but cleaned it up a bit.
I have no benchmarks or other quantifiable data as this is a whole new site project and I’m not worried about the performance… yet.
Anyway, what I did is a good start for a new install with very little configuration needed. Now that I’ve done that part, I will be going through and adding more fancy stuff like thumbnails and image segregation based on user id etc.
Just for the sake of sharing for others, here’s the library (goes in application/libraries):
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Plupload {
public $target_folder;
public $execution_time;
public function __construct()
{
$this->CI =& get_instance();
if( $this->CI->config->load('plupload', TRUE, TRUE) ){
$plupload_config = $this->CI->config->item('plupload');
$this->config($plupload_config);
}
}
public function config($config)
{
foreach ($config as $key => $value)
{
$this->$key = $value;
}
if (!file_exists($this->target_folder))
{
@mkdir($this->target_folder);
}
@set_time_limit($this->execution_time);
}
public function process_upload($data,$files)
{
// Get parameters
$chunk = isset($data["chunk"]) ? $data["chunk"] : 0;
$chunks = isset($data["chunks"]) ? $data["chunks"] : 0;
$fileName = isset($data["name"]) ? $data["name"] : '';
// Clean the fileName for security reasons
$fileName = preg_replace('/[^\w\._]+/', '', $fileName);
// Make sure the fileName is unique but only if chunking is disabled
if ($chunks < 2 && file_exists($this->target_folder . DIRECTORY_SEPARATOR . $fileName)) {
$ext = strrpos($fileName, '.');
$fileName_a = substr($fileName, 0, $ext);
$fileName_b = substr($fileName, $ext);
$count = 1;
while (file_exists($this->target_folder . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b))
{
$count++;
}
$fileName = $fileName_a . '_' . $count . $fileName_b;
}
if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
{
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
}
if (isset($_SERVER["CONTENT_TYPE"]))
{
$contentType = $_SERVER["CONTENT_TYPE"];
}
// Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
if (strpos($contentType, "multipart") !== false)
{
if (isset($files['file']['tmp_name']) && is_uploaded_file($files['file']['tmp_name']))
{
// Open temp file
$out = fopen($this->target_folder . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out)
{
// Read binary input stream and append it to temp file
$in = fopen($files['file']['tmp_name'], "rb");
if ($in)
{
while ($buff = fread($in, 4096))
{
fwrite($out, $buff);
}
}
else
{
return '{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}';
}
fclose($in);
fclose($out);
@unlink($files['file']['tmp_name']);
}
else
{
return '{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}';
}
}
else
{
return '{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}';
}
}
else
{
// Open temp file
$out = fopen($this->target_folder . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out)
{
// Read binary input stream and append it to temp file
$in = fopen("php://input", "rb");
if ($in)
{
while ($buff = fread($in, 4096))
{
fwrite($out, $buff);
}
}
else
{
return '{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}';
}
fclose($in);
fclose($out);
}
else
{
return '{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}';
}
}
// Return JSON-RPC response
return '{"jsonrpc" : "2.0", "result" : "'.$fileName.'", "id" : "id"}';
}
private function _load($lib=NULL)
{
if($lib == NULL) return FALSE;
if( isset($this->loaded[$lib]) ):
return FALSE;
else:
$this->CI->load->library($lib);
$this->loaded[$lib] = TRUE;
return TRUE;
endif;
}
}#9 / Sep 07, 2011 10:37am
Here is the config file (goes in application/config):
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Plupload configuration file.
* CodeIgniter-library for Ajax Uploading
*/
$config['target_folder'] = $_SERVER['DOCUMENT_ROOT']."/user_photos"; // Change the value here to match your hosting temporary upload location
$config['execution_time'] = 300; // 5 minutes execution timeAnd here’s the controller for the upload method:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Uploader extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->helper('url');
$this->load->library('plupload');
}
function upload()
{
echo $this->plupload->process_upload($_REQUEST,$_FILES);
}
}There’s certainly more to it, in that you have to create your view for the upload screen. I am using the jquery widget. The “url” variable in the javascript in the view would be set to “/uploader/upload” in the above controller example.
Additionally, you could pass more info through the process_upload function to do other things, like append a user id to the target directory etc.
But the point with this is to make it super simple to implement the Plupload in CI.
#10 / Sep 07, 2011 8:15pm
Hi Andrew,
Looks really good already!
I would have loved benchmarks, but never mind. Some pointers to how you could make your code even easier to read:
- PLupload uses json returns to report error or success. You could easily put them into a separate function in your class.
- Don’t use constant’s in your class. They are global, and ‘keep alive’ if you load other classes, models or controllers in the same session as this one. In stead, use instance variables.
- Separate the upload parts for multipart uploading and php://input stream uploading. After that, check what they have in common and put that in a different block as well. That way your code will be much more readable, and much more DRY.
Hope it helps,
Fabian
#11 / Oct 04, 2011 10:15pm
Hi Andrew,
Very good code!
This code has a GIT repository?
#12 / Dec 05, 2011 2:20pm
Thank you! This worked perfectly for a project I’m working on. Greatly appreciated.
#13 / Jan 24, 2012 6:26pm
I tried this with the native code first, and then used this setup (thanks!), but I’m getting the same problem in both - a 404 error where the “url” isn’t found. I have debugged and found that my class “uploader” is found ok, but the method is being set to “php”, instead of “upload”, even though the url clearly states “url: ‘/uploader/upload’”. The method is being overridden somehow.
I have tried to debug other methods which are unrelated to this upload form, which all work fine and the class/method values are as expected.
Any ideas why this is? Have I some configuration setting wrong? I’m using the copied and pasted code from this post, and the [removed] code copied/pasted from the plupload site. All I have changed is my URL.
Thanks,
Diarmid
#14 / Jan 24, 2012 6:44pm
Stepping deeper into the debug, I see that in system/core/URI.php within the fetch_uri() method, the URI is being detected as /uploader/php/upload.php. I changed the “url” in the client-side code to /uploader/do_upload’ but the URI is still detected as ‘uploader/php/upload.php’ so that seems to be getting inherited from somewhere.
Not sure if this helps anyone help me?
#15 / Jan 25, 2012 2:43am
I’ve found the controller part of the URI isn’t even actually that url specified in the plupload configuration script, it’s just the current controller. It’s just appending /php/upload.php to the current controller name. Still no closer to finding out how to set the URI to get it working though.