CC-1335 Plupload has been added to support multi-file upload.

This commit is contained in:
naomiaro 2010-08-30 10:51:13 -07:00
parent 71a97cdc93
commit 318337391c
9 changed files with 1035 additions and 575 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,177 @@
/*
Plupload
------------------------------------------------------------------- */
.plupload_button {
display: -moz-inline-box; /* FF < 3*/
display: inline-block;
font: normal 12px sans-serif;
text-decoration: none;
color: #42454a;
border: 1px solid #bababa;
padding: 2px 8px 3px 20px;
margin-right: 4px;
background: #f3f3f3 url('../img/buttons.png') no-repeat 0 center;
outline: 0;
/* Optional rounded corners for browsers that support it */
-moz-border-radius: 3px;
-khtml-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
}
.plupload_button:hover {
color: #000;
text-decoration: none;
}
.plupload_disabled, a.plupload_disabled:hover {
color: #737373;
border-color: #c5c5c5;
background: #ededed url('../img/buttons-disabled.png') no-repeat 0 center;
cursor: default;
}
.plupload_add {
background-position: -181px center;
}
.plupload_wrapper {
font: normal 11px Verdana,sans-serif;
width: 100%;
}
.plupload_container {
padding: 8px;
background: url('../img/transp50.png');
/*-moz-border-radius: 5px;*/
}
.plupload_container input {
border: 1px solid #DDD;
font: normal 11px Verdana,sans-serif;
width: 98%;
}
.plupload_header {background: #2A2C2E url('../img/backgrounds.gif') repeat-x;}
.plupload_header_content {
background: url('../img/backgrounds.gif') no-repeat 0 -317px;
min-height: 56px;
padding-left: 60px;
color: #FFF;
}
.plupload_header_title {
font: normal 18px sans-serif;
padding: 6px 0 3px;
}
.plupload_header_text {
font: normal 12px sans-serif;
}
.plupload_filelist {
margin: 0;
padding: 0;
list-style: none;
}
.plupload_scroll .plupload_filelist {
height: 185px;
background: #F5F5F5;
overflow-y: scroll;
}
.plupload_filelist li {
padding: 10px 8px;
background: #F5F5F5 url('../img/backgrounds.gif') repeat-x 0 -156px;
border-bottom: 1px solid #DDD;
}
.plupload_filelist_header, .plupload_filelist_footer {
background: #DFDFDF;
padding: 8px 8px;
color: #42454A;
}
.plupload_filelist_header {
border-top: 1px solid #EEE;
border-bottom: 1px solid #CDCDCD;
}
.plupload_filelist_footer {border-top: 1px solid #FFF; height: 22px; line-height: 20px; vertical-align: middle;}
.plupload_file_name {float: left; overflow: hidden}
.plupload_file_status {color: #777;}
.plupload_file_status span {color: #42454A;}
.plupload_file_size, .plupload_file_status, .plupload_progress {
float: right;
width: 80px;
}
.plupload_file_size, .plupload_file_status, .plupload_file_action {text-align: right;}
.plupload_filelist .plupload_file_name {width: 205px}
.plupload_file_action {
float: right;
width: 16px;
height: 16px;
margin-left: 15px;
}
.plupload_file_action * {
display: none;
width: 16px;
height: 16px;
}
li.plupload_uploading {background: #ECF3DC url('../img/backgrounds.gif') repeat-x 0 -238px;}
li.plupload_done {color:#AAA}
li.plupload_delete a {
background: url('../img/delete.gif');
}
li.plupload_failed a {
background: url('../img/error.gif');
cursor: default;
}
li.plupload_done a {
background: url('../img/done.gif');
cursor: default;
}
.plupload_progress, .plupload_upload_status {
display: none;
}
.plupload_progress_container {
margin-top: 3px;
border: 1px solid #CCC;
background: #FFF;
padding: 1px;
}
.plupload_progress_bar {
width: 0px;
height: 7px;
background: #CDEB8B;
}
.plupload_scroll .plupload_filelist_header .plupload_file_action, .plupload_scroll .plupload_filelist_footer .plupload_file_action {
margin-right: 17px;
}
/* Floats */
.plupload_clear,.plupload_clearer {clear: both;}
.plupload_clearer, .plupload_progress_bar {
display: block;
font-size: 0;
line-height: 0;
}
li.plupload_droptext {
background: transparent;
text-align: center;
vertical-align: middle;
border: 0;
line-height: 165px;
}

View File

@ -1004,3 +1004,26 @@ table.masterpalette td{
#upcoming_plstart {
visibility: hidden;
}
#plupload_error {
width: 95%;
height: 150px;
overflow: auto;
margin: 0 auto;
}
#plupload_error table {
border: 0;
}
#plupload_error table tr {
}
#plupload_error table td {
border: 0;
}
#plupload_error table td:first-child {
border-right: 1px solid #000000;
}

View File

@ -30,6 +30,15 @@ switch ($_REQUEST['act']) {
$uiHandler->logout(TRUE);
break;
case "plupload":
$ui_tmpid = $uiHandler->pluploadFile($_REQUEST);
if($ui_tmpid) {
$uiHandler->SCRATCHPAD->addItem($ui_tmpid);
}
ob_end_clean();
die('{"jsonrpc" : "2.0", "error" : {}}');
// file/webstream handling
case "addFileData":
if (($ui_tmpid = $uiHandler->uploadFile(array_merge($_REQUEST, $_FILES), $ui_fmask["file"])) !== FALSE) {
@ -462,16 +471,14 @@ switch ($_REQUEST['act']) {
if ($_REQUEST['is_popup']) {
$uiHandler->redirUrl = UI_BROWSER.'?popup[]=_reload_parent&popup[]=_close';
}
break;
//break;
}
if ($uiHandler->alertMsg) {
$_SESSION['alertMsg'] = $uiHandler->alertMsg;
}
//$ui_wait = 0;
//if (ob_get_contents()) {
// $ui_wait = 10;
//}
ob_end_clean();
if (isset($_REQUEST['target'])) {
header('Location: ui_browser.php?act='.$_REQUEST['target']);

View File

@ -14,11 +14,77 @@
</h1>
{if $editItem.type == 'audioclip' || $editItem.type == 'file'}
<div id="div_Data">
{if $_REQUEST.act == 'addFileData'}
<form id="plupload_form">
<div id="plupload_files"></div>
<div id="plupload_error"><table></table></div>
</form>
{literal}
<script type="text/javascript">
$("#plupload_files").pluploadQueue({
// General settings
runtimes : 'html5',
url : 'ui_handler.php?act=plupload',
filters : [
{title: "Audio Files", extensions: "ogg,mp3"}
]
});
var uploader = $("#plupload_files").pluploadQueue();
var files_error = new Array();
uploader.bind('FileUploaded', function(up, file, json) {
if (!json.response) {
//alert("problem");
return;
}
var j = eval("(" + json.response + ")");
if(j.error.message) {
var row = $("<tr/>")
.append('<td>' + file.name +'</td>')
.append('<td>' + j.error.message + '</td>');
$("#plupload_error").find("table").append(row);
files_error.push(file);
if(files_error.length % 2 === 0){
row.addClass("blue1");
}
else {
row.addClass("blue2");
}
}
if(up.state === plupload.STOPPED){
var i;
for( i=0; i< files_error.length; i++ ){
up.removeFile(files_error[i]);
}
}
});
uploader.bind('Error', function(up, err) {
console.log(err);
});
</script>
{/literal}
{*
{UIBROWSER->fileForm id=$editItem.id folderId=$editItem.folderId assign="dynform"}
{include file="sub/dynForm_plain.tpl}
{assign var="_uploadform" value=null}
*}
{/if}
</div>
@ -27,7 +93,10 @@
</div>
{/if}
{if $editItem.type == 'webstream'}
<div id="div_Data">
{UIBROWSER->webstreamForm id=$editItem.id folderId=$editItem.folderId assign="dynform"}
{include file="sub/dynForm_plain.tpl}
@ -43,6 +112,7 @@
{include file="file/metadataform.tpl"}
{/if}
</div>
</div>

View File

@ -9,10 +9,17 @@
{* <link rel="stylesheet" href="styles.css"> *}
<link href="styles_campcaster.css" rel="stylesheet" type="text/css" />
<link href="assets/plupload/plupload.queue.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="assets/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="assets/plupload/plupload.full.min.js"></script>
<script type="text/javascript" src="assets/plupload/jquery.plupload.queue.min.js"></script>
{include file="script/basics.js.tpl"}
{include file="script/contextmenu.js.tpl"}
{include file="script/collector.js.tpl"}
{include file="script/alttext.js.tpl"}
</head>
<body>

View File

@ -105,6 +105,158 @@ class uiHandler extends uiBase {
}
} // fn logout
function processFile($audio_file, $caller){
global $CC_CONFIG;
if ($this->testForAudioType($audio_file) === FALSE) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "uses an unsupported file type."}}');
}
$md5 = md5_file($audio_file);
$duplicate = StoredFile::RecallByMd5($md5);
if ($duplicate) {
$_SESSION['plupload'] = "is duplicate";
if (PEAR::isError($duplicate)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}');
}
else {
$duplicateName = $this->gb->getMetadataValue($duplicate->getId(), UI_MDATA_KEY_TITLE, $this->sessid);
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "An identical audioclip named ' . $duplicateName . ' already exists in the storage server."}}');
}
}
$metadata = camp_get_audio_metadata($audio_file);
if (PEAR::isError($metadata)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $metadata->getMessage() + '}}');
}
// #2196 no id tag -> use the original filename
if (basename($audio_file) == $metadata['dc:title']) {
$metadata['dc:title'] = basename($audio_file);
$metadata['ls:filename'] = basename($audio_file);
}
// bsSetMetadataBatch doesnt like these values
unset($metadata['audio']);
unset($metadata['playtime_seconds']);
$values = array(
"filename" => basename($audio_file),
"filepath" => $audio_file,
"filetype" => "audioclip",
"mime" => $metadata["dc:format"],
"md5" => $md5
);
$storedFile = $this->gb->putFile(NULL, $values, $this->sessid);
if (PEAR::isError($storedFile)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $storedFile->getMessage() + '}}');
}
$result = $this->gb->bsSetMetadataBatch($storedFile->getId(), $metadata);
return $storedFile->getId();
}
function pluploadFile($data)
{
header('Content-type: text/plain; charset=UTF-8');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
// Settings
$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
$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;
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
// 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);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
fclose($out);
return $this->processFile($targetDir . DIRECTORY_SEPARATOR . $fileName);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
}
// Return JSON-RPC response
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
}
// --- files ---
/**
@ -127,8 +279,11 @@ class uiHandler extends uiBase {
$id = $formdata['id'];
$folderId = $formdata['folderId'];
if (Greenbox::getFileType($folderId) != 'Folder') {
$this->_retMsg('The target is not a folder.');
$this->_retMsg('The target is not a folder: ' . $folderId . ' id: ' . $id);
$this->redirUrl = UI_BROWSER."?act=fileList";
return FALSE;
}