Merge pull request #9108 from owncloud/uploadintofolderfix
Fix many issues with drag and drop upload
This commit is contained in:
commit
d5819a5ecd
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue