summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Pritz <bluewind@xinu.at>2013-01-17 18:54:35 +0100
committerFlorian Pritz <bluewind@xinu.at>2013-01-17 21:25:44 +0100
commite1e658c6547a2b00a2b5b32bf3cd34ab8a5f2a52 (patch)
treef26e9ef785ff1d2f8d23b7235fb991e93d5e6d1c
parentdc3afcb35744ec5d9036fc329dab25f0c8dcd7a5 (diff)
Support multiple uploads in the same request
This change *should* be backwards compatible. Signed-off-by: Florian Pritz <bluewind@xinu.at>
-rw-r--r--application/controllers/file.php165
-rw-r--r--application/helpers/filebin_helper.php28
-rw-r--r--application/views/file/show_url.php10
-rw-r--r--application/views/file/upload_form.php5
-rw-r--r--application/views/file_plaintext/show_url.php3
-rw-r--r--application/views/file_plaintext/upload_form.php1
-rw-r--r--data/js/script.js26
7 files changed, 155 insertions, 83 deletions
diff --git a/application/controllers/file.php b/application/controllers/file.php
index 18e570b20..2b39309bb 100644
--- a/application/controllers/file.php
+++ b/application/controllers/file.php
@@ -84,7 +84,7 @@ class File extends CI_Controller {
}
// Try to guess what the user would like to do.
$id = $this->uri->segment(1);
- if(isset($_FILES['file'])) {
+ if(!empty($_FILES)) {
$this->do_upload();
} elseif ($id != "file" && $this->mfile->id_exists($id)) {
$this->_download();
@@ -264,7 +264,7 @@ class File extends CI_Controller {
$this->load->view('footer', $this->data);
}
- function _show_url($id, $lexer)
+ function _show_url($ids, $lexer)
{
$redirect = false;
@@ -272,35 +272,40 @@ class File extends CI_Controller {
$this->muser->require_session();
// keep the upload but require the user to login
$this->session->set_userdata("last_upload", array(
- "id" => $id,
+ "ids" => $ids,
"lexer" => $lexer
));
$this->session->set_flashdata("uri", "file/claim_id");
$this->muser->require_access();
}
- if ($lexer) {
- $this->data['url'] = site_url($id).'/'.$lexer;
- } else {
- $this->data['url'] = site_url($id).'/';
-
- $filedata = $this->mfile->get_filedata($id);
- $file = $this->mfile->file($filedata['hash']);
- $type = $filedata['mimetype'];
- $lexer = $this->mfile->should_highlight($type);
-
- // If we detected a highlightable file redirect,
- // otherwise show the URL because browsers would just show a DL dialog
+ foreach ($ids as $id) {
if ($lexer) {
- $redirect = true;
+ $this->data['urls'][] = site_url($id).'/'.$lexer;
+ } else {
+ $this->data['urls'][] = site_url($id).'/';
+
+ if (count($ids) == 1) {
+ $filedata = $this->mfile->get_filedata($id);
+ $file = $this->mfile->file($filedata['hash']);
+ $type = $filedata['mimetype'];
+ $lexer = $this->mfile->should_highlight($type);
+
+ // If we detected a highlightable file redirect,
+ // otherwise show the URL because browsers would just show a DL dialog
+ if ($lexer) {
+ $redirect = true;
+ }
+ }
}
}
if (is_cli_client()) {
$redirect = false;
}
- if ($redirect) {
- redirect($this->data['url'], "location", 303);
+
+ if ($redirect && count($ids) == 1) {
+ redirect($this->data['urls'][0], "location", 303);
} else {
$this->load->view('header', $this->data);
$this->load->view($this->var->view_dir.'/show_url', $this->data);
@@ -533,66 +538,85 @@ class File extends CI_Controller {
file_put_contents($file, $content);
chmod($file, 0600);
$this->mfile->add_file($hash, $id, $filename);
- $this->_show_url($id, false);
+ $this->_show_url(array($id), false);
}
// Handles uploaded files
function do_upload()
{
+ $ids = array();
+
$extension = $this->input->post('extension');
- if(!isset($_FILES['file']) || $_FILES['file']['error'] !== 0) {
- $this->output->set_status_header(400);
- $errors = array(
- 0=>"There is no error, the file uploaded with success",
- 1=>"The uploaded file exceeds the upload_max_filesize directive in php.ini",
- 2=>"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
- 3=>"The uploaded file was only partially uploaded",
- 4=>"No file was uploaded",
- 6=>"Missing a temporary folder"
- );
- $this->data["msg"] = "Unknown error.";
+ $files = getNormalizedFILES();
- if (isset($_FILES["file"])) {
- $this->data["msg"] = $errors[$_FILES['file']['error']];
- }
- $this->load->view('header', $this->data);
- $this->load->view($this->var->view_dir.'/upload_error', $this->data);
- $this->load->view('footer');
- return;
+ if (empty($files)) {
+ show_error("No file was uploaded or unknown error occured.");
}
- $filesize = filesize($_FILES['file']['tmp_name']);
- if ($filesize > $this->config->item('upload_max_size')) {
- $this->output->set_status_header(413);
- $this->load->view('header', $this->data);
- $this->load->view($this->var->view_dir.'/too_big');
- $this->load->view('footer');
- return;
- }
+ // Check for errors before doing anything
+ // First error wins and is displayed, these shouldn't happen that often anyway.
+ foreach ($files as $key => $file) {
+ // getNormalizedFILES() removes any file with error == 4
+ if ($file['error'] !== 0) {
+ $this->output->set_status_header(400);
+ $errors = array(
+ 0=>"There is no error, the file uploaded with success",
+ 1=>"The uploaded file exceeds the upload_max_filesize directive in php.ini",
+ 2=>"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
+ 3=>"The uploaded file was only partially uploaded",
+ 4=>"No file was uploaded",
+ 6=>"Missing a temporary folder"
+ );
- $id = $this->mfile->new_id();
- $hash = md5_file($_FILES['file']['tmp_name']);
+ $this->data["msg"] = "Unknown error.";
- // work around a curl bug and allow the client to send the real filename base64 encoded
- $filename = $this->input->post("filename");
- if ($filename !== false) {
- $filename = trim(base64_decode($filename, true), "\r\n\0\t\x0B");
- }
+ if (isset($file)) {
+ $this->data["msg"] = $errors[$file['error']];
+ }
+ $this->load->view('header', $this->data);
+ $this->load->view($this->var->view_dir.'/upload_error', $this->data);
+ $this->load->view('footer');
+ return;
+ }
- // fall back if base64_decode failed
- if ($filename === false) {
- $filename = $_FILES['file']['name'];
+ $filesize = filesize($file['tmp_name']);
+ if ($filesize > $this->config->item('upload_max_size')) {
+ $this->output->set_status_header(413);
+ $this->load->view('header', $this->data);
+ $this->load->view($this->var->view_dir.'/too_big');
+ $this->load->view('footer');
+ return;
+ }
}
- $folder = $this->mfile->folder($hash);
- file_exists($folder) || mkdir ($folder);
- $file = $this->mfile->file($hash);
+ foreach ($files as $key => $file) {
+ $id = $this->mfile->new_id();
+ $hash = md5_file($file['tmp_name']);
- move_uploaded_file($_FILES['file']['tmp_name'], $file);
- chmod($file, 0600);
- $this->mfile->add_file($hash, $id, $filename);
- $this->_show_url($id, $extension);
+ // work around a curl bug and allow the client to send the real filename base64 encoded
+ // TODO: this interface currently sets the same filename for every file if you use multiupload
+ $filename = $this->input->post("filename");
+ if ($filename !== false) {
+ $filename = trim(base64_decode($filename, true), "\r\n\0\t\x0B");
+ }
+
+ // fall back if base64_decode failed
+ if ($filename === false) {
+ $filename = $file['name'];
+ }
+
+ $folder = $this->mfile->folder($hash);
+ file_exists($folder) || mkdir ($folder);
+ $file_path = $this->mfile->file($hash);
+
+ move_uploaded_file($file['tmp_name'], $file_path);
+ chmod($file_path, 0600);
+ $this->mfile->add_file($hash, $id, $filename);
+ $ids[] = $id;
+ }
+
+ $this->_show_url($ids, $extension);
}
function claim_id()
@@ -600,15 +624,22 @@ class File extends CI_Controller {
$this->muser->require_access();
$last_upload = $this->session->userdata("last_upload");
- $id = $last_upload["id"];
+ $ids = $last_upload["ids"];
+ $errors = array();
- $filedata = $this->mfile->get_filedata($id);
+ foreach ($ids as $key => $id) {
+ $filedata = $this->mfile->get_filedata($id);
- if ($filedata["user"] != 0) {
- show_error("Someone already owns '$id', can't reassign.");
+ if ($filedata["user"] != 0) {
+ $errors[] = $id;
+ }
+
+ $this->mfile->adopt($id);
}
- $this->mfile->adopt($id);
+ if (!empty($errors)) {
+ show_error("Someone already owns '".implode(", ", $errors)."', can't reassign.");
+ }
$this->session->unset_userdata("last_upload");
diff --git a/application/helpers/filebin_helper.php b/application/helpers/filebin_helper.php
index 2f073c902..0951527fe 100644
--- a/application/helpers/filebin_helper.php
+++ b/application/helpers/filebin_helper.php
@@ -256,4 +256,32 @@ function handle_etag($etag)
}
}
+// Reference: http://php.net/manual/en/features.file-upload.multiple.php#109437
+// This is a little different because we don't care about the fieldname
+function getNormalizedFILES()
+{
+ $newfiles = array();
+ $ret = array();
+
+ foreach($_FILES as $fieldname => $fieldvalue)
+ foreach($fieldvalue as $paramname => $paramvalue)
+ foreach((array)$paramvalue as $index => $value)
+ $newfiles[$fieldname][$index][$paramname] = $value;
+
+ $i = 0;
+ foreach ($newfiles as $fieldname => $field) {
+ foreach ($field as $file) {
+ // skip empty fields
+ if ($file["error"] === 4) {
+ continue;
+ }
+ $ret[$i] = $file;
+ $ret[$i]["formfield"] = $fieldname;
+ $i++;
+ }
+ }
+
+ return $ret;
+}
+
# vim: set noet:
diff --git a/application/views/file/show_url.php b/application/views/file/show_url.php
index 3c08ed952..a3d965717 100644
--- a/application/views/file/show_url.php
+++ b/application/views/file/show_url.php
@@ -1,6 +1,8 @@
<div class="center">
- <p>
- You can get your file here:<br />
- <a href="<?php echo $url; ?>"><?php echo $url; ?></a><br />
- </p>
+ <p>You can get your file(s) here:</p>
+ <p>
+ <?php foreach ($urls as $key => $url) { ?>
+ <a href="<?php echo $url; ?>"><?php echo $url; ?></a><br />
+ <?php } ?>
+ </p>
</div>
diff --git a/application/views/file/upload_form.php b/application/views/file/upload_form.php
index a6f4eedc7..aaf36931a 100644
--- a/application/views/file/upload_form.php
+++ b/application/views/file/upload_form.php
@@ -13,7 +13,7 @@
<div class="span6">
<?php echo form_open_multipart('file/do_upload'); ?>
<h2>File upload</h2>
- <input id="file" type="file" name="file"><br>
+ <input class="file-upload" type="file" name="file[]" multiple="multiple"><br>
<button type="submit" id="upload_button" class="btn btn-primary">Upload it!</button>
</form>
<div class="alert alert-block alert-info">
@@ -22,7 +22,8 @@
Uploads/pastes are deleted after <?php echo $upload_max_age; ?> days
<?php if($small_upload_size > 0) {
echo "unless they are smaller than ".format_bytes($small_upload_size);
- } ?>. Maximum upload size is <?php echo format_bytes($max_upload_size); ?>
+ } ?>. Maximum upload size is <?php echo format_bytes($max_upload_size); ?>.
+ You can upload a maximum of <?php echo ini_get("max_file_uploads"); ?> files at once.
</p>
</div>
</div>
diff --git a/application/views/file_plaintext/show_url.php b/application/views/file_plaintext/show_url.php
index bb94d7422..64050ddcd 100644
--- a/application/views/file_plaintext/show_url.php
+++ b/application/views/file_plaintext/show_url.php
@@ -1,2 +1,3 @@
-<?php echo $url; ?>
+<?php
+echo implode(" ", $urls)."\n";
diff --git a/application/views/file_plaintext/upload_form.php b/application/views/file_plaintext/upload_form.php
index 7fe3aa801..a74e5d434 100644
--- a/application/views/file_plaintext/upload_form.php
+++ b/application/views/file_plaintext/upload_form.php
@@ -1,5 +1,6 @@
Uploads/pastes are deleted after <?php echo $upload_max_age; ?> days<?php if($small_upload_size > 0): ?> unless they are smaller than <?php echo format_bytes($small_upload_size); ?><?php endif; ?>.
Maximum upload size is <?php echo format_bytes($max_upload_size); ?>.
+You can upload a maximum of <?php echo ini_get("max_file_uploads"); ?> files at once.
How to link your uploads:
- "/<ID>/" automatically highlight the uploads
diff --git a/data/js/script.js b/data/js/script.js
index 4df973296..cb9afa66c 100644
--- a/data/js/script.js
+++ b/data/js/script.js
@@ -74,17 +74,25 @@ function fixedEncodeURIComponent (str) {
// check file size before uploading if browser support html5
if (window.File && window.FileList) {
function checkFileUpload(evt) {
- var f = evt.target.files[0];
- if (f.size > max_upload_size) {
- document.getElementById('upload_button').innerHTML = "File too big";
- document.getElementById('upload_button').disabled = true;
- } else {
- document.getElementById('upload_button').innerHTML = "Upload it!";
- document.getElementById('upload_button').disabled = false;
- }
+ var sum = 0;
+ var files = evt.target.files;
+
+ // TODO: check all forms, not only the one we are called from
+ for (var i = 0; i < files.length; i++) {
+ var f = evt.target.files[i];
+ sum += f.size;
+ }
+
+ if (sum > max_upload_size) {
+ document.getElementById('upload_button').innerHTML = "File(s) too big";
+ document.getElementById('upload_button').disabled = true;
+ } else {
+ document.getElementById('upload_button').innerHTML = "Upload it!";
+ document.getElementById('upload_button').disabled = false;
+ }
}
- $('#file').bind('change', checkFileUpload);
+ $('.file-upload').bind('change', checkFileUpload);
}
});