Merge pull request #9108 from owncloud/uploadintofolderfix

Fix many issues with drag and drop upload
This commit is contained in:
Morris Jobke 2014-06-20 19:01:05 +02:00
commit d5819a5ecd
5 changed files with 59 additions and 69 deletions

View File

@ -26,7 +26,7 @@ if (empty($_POST['dirToken'])) {
// return only read permissions for public upload // return only read permissions for public upload
$allowedPermissions = OCP\PERMISSION_READ; $allowedPermissions = OCP\PERMISSION_READ;
$public_directory = !empty($_POST['subdir']) ? $_POST['subdir'] : '/'; $publicDirectory = !empty($_POST['subdir']) ? $_POST['subdir'] : '/';
$linkItem = OCP\Share::getShareByToken($_POST['dirToken']); $linkItem = OCP\Share::getShareByToken($_POST['dirToken']);
if ($linkItem === false) { if ($linkItem === false) {
@ -50,13 +50,15 @@ if (empty($_POST['dirToken'])) {
$dir = sprintf( $dir = sprintf(
"/%s/%s", "/%s/%s",
$path, $path,
$public_directory $publicDirectory
); );
if (!$dir || empty($dir) || $dir === false) { if (!$dir || empty($dir) || $dir === false) {
OCP\JSON::error(array('data' => array_merge(array('message' => $l->t('Unable to set upload directory.'))))); OCP\JSON::error(array('data' => array_merge(array('message' => $l->t('Unable to set upload directory.')))));
die(); die();
} }
$dir = rtrim($dir, '/');
} }
} }
@ -113,33 +115,33 @@ if ($maxUploadFileSize >= 0 and $totalSize > $maxUploadFileSize) {
} }
$result = array(); $result = array();
$directory = '';
if (strpos($dir, '..') === false) { if (strpos($dir, '..') === false) {
$fileCount = count($files['name']); $fileCount = count($files['name']);
for ($i = 0; $i < $fileCount; $i++) { for ($i = 0; $i < $fileCount; $i++) {
// Get the files directory // target directory for when uploading folders
if(isset($_POST['file_directory']) === true) { $relativePath = '';
$directory = '/'.$_POST['file_directory']; if(!empty($_POST['file_directory'])) {
$relativePath = '/'.$_POST['file_directory'];
} }
// $path needs to be normalized - this failed within drag'n'drop upload to a sub-folder // $path needs to be normalized - this failed within drag'n'drop upload to a sub-folder
if (isset($_POST['resolution']) && $_POST['resolution']==='autorename') { if (isset($_POST['resolution']) && $_POST['resolution']==='autorename') {
// append a number in brackets like 'filename (2).ext' // append a number in brackets like 'filename (2).ext'
$target = OCP\Files::buildNotExistingFileName(stripslashes($dir.$directory), $files['name'][$i]); $target = OCP\Files::buildNotExistingFileName(stripslashes($dir . $relativePath), $files['name'][$i]);
} else { } else {
$target = \OC\Files\Filesystem::normalizePath(stripslashes($dir.$directory).'/'.$files['name'][$i]); $target = \OC\Files\Filesystem::normalizePath(stripslashes($dir . $relativePath).'/'.$files['name'][$i]);
} }
if(empty($directory) === true) // relative dir to return to the client
{ if (isset($publicDirectory)) {
$directory = \OC\Files\Filesystem::normalizePath(stripslashes($dir)); // path relative to the public root
if (isset($public_directory)) { $returnedDir = $publicDirectory . $relativePath;
// If we are uploading from the public app, } else {
// we want to send the relative path in the ajax request. // full path
$directory = $public_directory; $returnedDir = $dir . $relativePath;
}
} }
$returnedDir = \OC\Files\Filesystem::normalizePath($returnedDir);
if ( ! \OC\Files\Filesystem::file_exists($target) if ( ! \OC\Files\Filesystem::file_exists($target)
|| (isset($_POST['resolution']) && $_POST['resolution']==='replace') || (isset($_POST['resolution']) && $_POST['resolution']==='replace')
@ -163,7 +165,7 @@ if (strpos($dir, '..') === false) {
$data['uploadMaxFilesize'] = $maxUploadFileSize; $data['uploadMaxFilesize'] = $maxUploadFileSize;
$data['maxHumanFilesize'] = $maxHumanFileSize; $data['maxHumanFilesize'] = $maxHumanFileSize;
$data['permissions'] = $meta['permissions'] & $allowedPermissions; $data['permissions'] = $meta['permissions'] & $allowedPermissions;
$data['directory'] = $directory; $data['directory'] = $returnedDir;
$result[] = $data; $result[] = $data;
} }
@ -187,7 +189,7 @@ if (strpos($dir, '..') === false) {
$data['uploadMaxFilesize'] = $maxUploadFileSize; $data['uploadMaxFilesize'] = $maxUploadFileSize;
$data['maxHumanFilesize'] = $maxHumanFileSize; $data['maxHumanFilesize'] = $maxHumanFileSize;
$data['permissions'] = $meta['permissions'] & $allowedPermissions; $data['permissions'] = $meta['permissions'] & $allowedPermissions;
$data['directory'] = $directory; $data['directory'] = $returnedDir;
$result[] = $data; $result[] = $data;
} }
} }

View File

@ -346,7 +346,7 @@ OC.Upload = {
// noone set update parameters, we set the minimum // noone set update parameters, we set the minimum
data.formData = { data.formData = {
requesttoken: oc_requesttoken, requesttoken: oc_requesttoken,
dir: FileList.getCurrentDirectory(), dir: data.targetDir || FileList.getCurrentDirectory(),
file_directory: fileDirectory file_directory: fileDirectory
}; };
} }

View File

@ -1561,17 +1561,12 @@
dir = dropTarget.data('dir') || '/'; dir = dropTarget.data('dir') || '/';
} }
// update folder in form // add target dir
data.formData = function() { data.targetDir = dir;
return [
{name: 'dir', value: dir},
{name: 'requesttoken', value: oc_requesttoken},
{name: 'file_directory', value: data.files[0].relativePath}
];
};
} else { } else {
// we are dropping somewhere inside the file list, which will // we are dropping somewhere inside the file list, which will
// upload the file to the current directory // upload the file to the current directory
data.targetDir = self.getCurrentDirectory();
// cancel uploads to current dir if no permission // cancel uploads to current dir if no permission
var isCreatable = (self.getDirectoryPermissions() & OC.PERMISSION_CREATE) !== 0; var isCreatable = (self.getDirectoryPermissions() & OC.PERMISSION_CREATE) !== 0;
@ -1654,15 +1649,34 @@
data.context.find('td.filesize').text(humanFileSize(size)); data.context.find('td.filesize').text(humanFileSize(size));
} else { } else {
// only append new file if uploaded into the current folder // only append new file if uploaded into the current folder
if (file.directory !== '/' && file.directory !== self.getCurrentDirectory()) { if (file.directory !== self.getCurrentDirectory()) {
// Uploading folders actually uploads a list of files
// for which the target directory (file.directory) might lie deeper
// than the current directory
var fileDirectory = file.directory.replace('/','').replace(/\/$/, "").split('/'); var fileDirectory = file.directory.replace('/','').replace(/\/$/, "");
var currentDirectory = self.getCurrentDirectory().replace('/','').replace(/\/$/, "") + '/';
if (fileDirectory.length === 1) { if (currentDirectory !== '/') {
// abort if fileDirectory does not start with current one
if (fileDirectory.indexOf(currentDirectory) !== 0) {
return;
}
// remove the current directory part
fileDirectory = fileDirectory.substr(currentDirectory.length);
}
// only take the first section of the path
fileDirectory = fileDirectory.split('/');
var fd;
// if the first section exists / is a subdir
if (fileDirectory.length) {
fileDirectory = fileDirectory[0]; fileDirectory = fileDirectory[0];
// Get the directory // See whether it is already in the list
var fd = self.findFileEl(fileDirectory); fd = self.findFileEl(fileDirectory);
if (fd.length === 0) { if (fd.length === 0) {
var dir = { var dir = {
name: fileDirectory, name: fileDirectory,
@ -1672,20 +1686,16 @@
size: 0, size: 0,
id: file.parentId id: file.parentId
}; };
self.add(dir, {insert: true}); fd = self.add(dir, {insert: true});
} }
} else {
fileDirectory = fileDirectory[0]; // update folder size
size = parseInt(fd.attr('data-size'), 10);
size += parseInt(file.size, 10);
fd.attr('data-size', size);
fd.find('td.filesize').text(OC.Util.humanFileSize(size));
} }
fileDirectory = self.findFileEl(fileDirectory);
// update folder size
size = parseInt(fileDirectory.attr('data-size'), 10);
size += parseInt(file.size, 10);
fileDirectory.attr('data-size', size);
fileDirectory.find('td.filesize').text(humanFileSize(size));
return; return;
} }

View File

@ -1730,20 +1730,6 @@ describe('OCA.Files.FileList tests', function() {
return ev; return ev;
} }
/**
* Convert form data to a flat list
*
* @param formData form data array as used by jquery.upload
* @return map based on the array's key values
*/
function decodeFormData(data) {
var map = {};
_.each(data.formData(), function(entry) {
map[entry.name] = entry.value;
});
return map;
}
beforeEach(function() { beforeEach(function() {
// simulate data structure from jquery.upload // simulate data structure from jquery.upload
uploadData = { uploadData = {
@ -1803,11 +1789,7 @@ describe('OCA.Files.FileList tests', function() {
ev = dropOn(fileList.findFileEl('somedir').find('td:eq(2)'), uploadData); ev = dropOn(fileList.findFileEl('somedir').find('td:eq(2)'), uploadData);
expect(ev.result).not.toEqual(false); expect(ev.result).not.toEqual(false);
expect(uploadData.formData).toBeDefined(); expect(uploadData.targetDir).toEqual('/subdir/somedir');
formData = decodeFormData(uploadData);
expect(formData.dir).toEqual('/subdir/somedir');
expect(formData.file_directory).toEqual('fileToUpload.txt');
expect(formData.requesttoken).toBeDefined();
}); });
it('drop on a breadcrumb inside the table triggers upload to target folder', function() { it('drop on a breadcrumb inside the table triggers upload to target folder', function() {
var ev, formData; var ev, formData;
@ -1815,11 +1797,7 @@ describe('OCA.Files.FileList tests', function() {
ev = dropOn(fileList.$el.find('.crumb:eq(2)'), uploadData); ev = dropOn(fileList.$el.find('.crumb:eq(2)'), uploadData);
expect(ev.result).not.toEqual(false); expect(ev.result).not.toEqual(false);
expect(uploadData.formData).toBeDefined(); expect(uploadData.targetDir).toEqual('/a/b');
formData = decodeFormData(uploadData);
expect(formData.dir).toEqual('/a/b');
expect(formData.file_directory).toEqual('fileToUpload.txt');
expect(formData.requesttoken).toBeDefined();
}); });
}); });
}); });

View File

@ -128,7 +128,7 @@ OCA.Sharing.PublicApp = {
data.formData = { data.formData = {
requesttoken: $('#publicUploadRequestToken').val(), requesttoken: $('#publicUploadRequestToken').val(),
dirToken: $('#dirToken').val(), dirToken: $('#dirToken').val(),
subdir: self.fileList.getCurrentDirectory(), subdir: data.targetDir || self.fileList.getCurrentDirectory(),
file_directory: fileDirectory file_directory: fileDirectory
}; };
}); });