MDL-31901: Updating/moving files in FileManager
- added new functions to the backend (repository/draftfiles_ajax.php) to allow changing of file name, location, license and author in one request - enabled changing file properties using JS UI (lib/form/filemanager.js)
This commit is contained in:
@@ -107,6 +107,9 @@ $string['filenotnull'] = 'You must select a file to upload.';
|
||||
$string['filesaved'] = 'The file has been saved';
|
||||
$string['filepicker'] = 'File picker';
|
||||
$string['filesizenull'] = 'File size cannot be determined';
|
||||
$string['folderexists'] = 'Folder name already being used, please use another name';
|
||||
$string['foldernotfound'] = 'Folder not found';
|
||||
$string['folderrecurse'] = 'Folder can not be moved to it\s own subfolder';
|
||||
$string['getfile'] = 'Select this file';
|
||||
$string['hidden'] = 'Hidden';
|
||||
$string['choosealink'] = 'Choose a link...';
|
||||
|
||||
@@ -196,6 +196,25 @@ class stored_file {
|
||||
$DB->delete_records('files_reference', array('id'=>$this->file_record->referencefileid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update some file record fields
|
||||
*
|
||||
* @param stdClass $dataobject
|
||||
*/
|
||||
public function update($dataobject) {
|
||||
// TODO MDL-28666 THIS FUNCTION IS COPIED FROM UNFINISHED CODE OF MDL-28666.
|
||||
global $DB;
|
||||
$keys = array_keys((array)$this->file_record);
|
||||
foreach ($dataobject as $field => $value) {
|
||||
if (in_array($field, $keys)) {
|
||||
$this->file_record->$field = $value;
|
||||
} else {
|
||||
throw new coding_exception("Invalid field name, $field doesn't exist in file record");
|
||||
}
|
||||
}
|
||||
$DB->update_record('files', $this->file_record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a directory?
|
||||
*
|
||||
|
||||
+44
-63
@@ -417,11 +417,11 @@ M.form_filemanager.init = function(Y, options) {
|
||||
node.highlight(false);
|
||||
node.origlist = obj.list?obj.list:null;
|
||||
node.origpath = obj.path?obj.path:null;
|
||||
node.origcurrentpath = node.path?node.path:'/';
|
||||
node.children = [];
|
||||
for(k in list) {
|
||||
if (list[k].type == 'folder' && retrieved_children[list[k].filepath]) {
|
||||
// if this child is a folder and has already been retrieved
|
||||
retrieved_children[list[k].filepath].fileinfo = list[k];
|
||||
node.children[node.children.length] = retrieved_children[list[k].filepath];
|
||||
} else {
|
||||
// append new file to the list
|
||||
@@ -491,7 +491,7 @@ M.form_filemanager.init = function(Y, options) {
|
||||
// save current path and filelist (in case we want to jump to other viewmode)
|
||||
this.options.path = e.node.origpath;
|
||||
this.options.list = e.node.origlist;
|
||||
this.currentpath = e.node.origcurrentpath;
|
||||
this.currentpath = e.node.path;
|
||||
this.print_path();
|
||||
//this.content_scrolled();
|
||||
}
|
||||
@@ -533,82 +533,64 @@ M.form_filemanager.init = function(Y, options) {
|
||||
var selectnode = this.filemanager.one('.fp-select');
|
||||
var fileinfo = this.selectui.fileinfo;
|
||||
|
||||
var newfilename = selectnode.one('.fp-saveas input').get('value');
|
||||
var newfilename = Y.Lang.trim(selectnode.one('.fp-saveas input').get('value'));
|
||||
var filenamechanged = (newfilename && newfilename != fileinfo.fullname);
|
||||
var pathselect = selectnode.one('.fp-path select'),
|
||||
pathindex = pathselect.get('selectedIndex'),
|
||||
targetpath = pathselect.get("options").item(pathindex).get('value');
|
||||
var filepathchanged = (targetpath != this.get_parent_folder_name(fileinfo));
|
||||
var newauthor = Y.Lang.trim(selectnode.one('.fp-author input').get('value'));
|
||||
var authorchanged = (newauthor != Y.Lang.trim(fileinfo.author));
|
||||
var licenseselect = selectnode.one('.fp-license select'),
|
||||
licenseindex = licenseselect.get('selectedIndex'),
|
||||
newlicense = licenseselect.get("options").item(licenseindex).get('value');
|
||||
var licensechanged = (newlicense != fileinfo.license);
|
||||
|
||||
if (filenamechanged && filepathchanged) {
|
||||
alert('Sorry, simultaneous changing of name and path is not supported yet'); // TODO
|
||||
return;
|
||||
var params, action;
|
||||
if (fileinfo.type == 'folder') {
|
||||
if (!newfilename) {
|
||||
this.print_msg(M.str.repository.entername, 'error');
|
||||
return;
|
||||
}
|
||||
if (filenamechanged || filepathchanged) {
|
||||
params = {filepath:fileinfo.filepath, newdirname:newfilename, newfilepath:targetpath};
|
||||
action = 'updatedir';
|
||||
}
|
||||
} else {
|
||||
if (!newfilename) {
|
||||
this.print_msg(M.str.repository.enternewname, 'error');
|
||||
return;
|
||||
}
|
||||
if (filenamechanged || filepathchanged || licensechanged || authorchanged) {
|
||||
params = {filepath:fileinfo.filepath, filename:fileinfo.fullname,
|
||||
newfilename:newfilename, newfilepath:targetpath,
|
||||
newlicense:newlicense, newauthor:newauthor};
|
||||
action = 'updatefile';
|
||||
}
|
||||
}
|
||||
if (!filenamechanged && !filepathchanged) {
|
||||
if (!action) {
|
||||
// no changes
|
||||
this.selectui.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
selectnode.addClass('loading');
|
||||
|
||||
// RENAME
|
||||
if (filenamechanged) {
|
||||
var action = '';
|
||||
var params = {};
|
||||
if (fileinfo.type == 'folder') {
|
||||
params['filepath'] = fileinfo.filepath;
|
||||
params['filename'] = '.';
|
||||
params['newdirname'] = newfilename;
|
||||
action = 'renamedir';
|
||||
} else {
|
||||
params['filepath'] = fileinfo.filepath;
|
||||
params['filename'] = fileinfo.fullname;
|
||||
params['newfilename'] = newfilename;
|
||||
action = 'rename';
|
||||
}
|
||||
this.request({
|
||||
action: action,
|
||||
scope: this,
|
||||
params: params,
|
||||
callback: function(id, obj, args) {
|
||||
if (obj == false) {
|
||||
selectnode.removeClass('loading');
|
||||
args.scope.print_msg(M.str.repository.fileexists, 'error');
|
||||
} else {
|
||||
args.scope.selectui.hide();
|
||||
args.scope.refresh(obj.filepath);
|
||||
if (typeof M.core_formchangechecker != 'undefined') {
|
||||
M.core_formchangechecker.set_form_changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// MOVE
|
||||
if (filepathchanged) {
|
||||
var params = {};
|
||||
if (fileinfo.type == 'folder') {
|
||||
action = 'movedir';
|
||||
} else {
|
||||
action = 'movefile';
|
||||
}
|
||||
params['filepath'] = fileinfo.filepath;
|
||||
params['filename'] = fileinfo.fullname;
|
||||
params['newfilepath'] = targetpath;
|
||||
this.request({
|
||||
action: action,
|
||||
scope: this,
|
||||
params: params,
|
||||
callback: function(id, obj, args) {
|
||||
this.request({
|
||||
action: action,
|
||||
scope: this,
|
||||
params: params,
|
||||
callback: function(id, obj, args) {
|
||||
if (obj.error) {
|
||||
selectnode.removeClass('loading');
|
||||
args.scope.print_msg(obj.error, 'error');
|
||||
} else {
|
||||
args.scope.selectui.hide();
|
||||
args.scope.refresh((obj && obj.filepath) ? obj.filepath : '/');
|
||||
if (typeof M.core_formchangechecker != 'undefined') {
|
||||
M.core_formchangechecker.set_form_changed();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
setup_select_file: function() {
|
||||
var selectnode = this.filemanager.one('.fp-select');
|
||||
@@ -742,8 +724,7 @@ M.form_filemanager.init = function(Y, options) {
|
||||
selectnode.all('.fp-path select option').each(function(el){
|
||||
if (el.get('value') == foldername) {el.set('selected', true);}
|
||||
});
|
||||
selectnode.all('.fp-author input').set('disabled','disabled'); //TODO
|
||||
selectnode.all('.fp-license select').set('disabled','disabled'); //TODO
|
||||
selectnode.all('.fp-author input, .fp-license select').set('disabled',(node.type == 'folder')?'disabled':'');
|
||||
// display static information about a file (when known)
|
||||
var attrs = ['datemodified','datecreated','size','dimensions'];
|
||||
for (var i in attrs) {
|
||||
|
||||
@@ -76,8 +76,6 @@ switch ($action) {
|
||||
$fs->create_directory($user_context->id, 'user', 'draft', $draftid, file_correct_filepath(file_correct_filepath($filepath).$newdirname));
|
||||
$return = new stdClass();
|
||||
$return->filepath = $filepath;
|
||||
$return->tree = new stdClass();
|
||||
file_get_drafarea_folders($draftid, '/', $return->tree);
|
||||
echo json_encode($return);
|
||||
die;
|
||||
|
||||
@@ -123,7 +121,54 @@ switch ($action) {
|
||||
echo json_encode($return);
|
||||
die;
|
||||
|
||||
case 'updatefile':
|
||||
// Allows to Rename file, move it to another directory, change it's license and author information in one request
|
||||
$filename = required_param('filename', PARAM_FILE);
|
||||
$filepath = required_param('filepath', PARAM_PATH);
|
||||
|
||||
$fs = get_file_storage();
|
||||
if (!($file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, $filename))) {
|
||||
die(json_encode((object)array('error' => get_string('filenotfound', 'error'))));
|
||||
}
|
||||
|
||||
$updatedata = array();
|
||||
$updatedata['filename'] = $newfilename = optional_param('newfilename', $file->get_filename(), PARAM_FILE);
|
||||
$updatedata['filepath'] = $newfilepath = optional_param('newfilepath', $file->get_filepath(), PARAM_PATH);
|
||||
$updatedata['license'] = optional_param('newlicense', $file->get_license(), PARAM_TEXT);
|
||||
$updatedata['author'] = optional_param('newauthor', $file->get_author(), PARAM_TEXT);
|
||||
foreach ($updatedata as $key => $value) {
|
||||
if (''.$value === ''.$file->{'get_'.$key}()) {
|
||||
unset($updatedata[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($updatedata)) {
|
||||
$updatedata['timemodified'] = $file->get_timemodified();
|
||||
$changes = array_diff(array_keys($updatedata), array('filepath'));
|
||||
if (!empty($changes)) {
|
||||
// any change except for the moving to another folder alters 'Date modified' of the file
|
||||
$updatedata['timemodified'] = time();
|
||||
}
|
||||
if (array_key_exists('filename', $updatedata) || array_key_exists('filepath', $updatedata)) {
|
||||
// check that target file name does not exist
|
||||
if ($fs->file_exists($user_context->id, 'user', 'draft', $draftid, $newfilepath, $newfilename)) {
|
||||
die(json_encode((object)array('error' => get_string('fileexists', 'repository'))));
|
||||
}
|
||||
try {
|
||||
$newfile = $fs->create_file_from_storedfile($updatedata, $file);
|
||||
} catch (Exception $e) {
|
||||
die(json_encode((object)array('error' => $e->getMessage())));
|
||||
}
|
||||
$file->delete();
|
||||
} else {
|
||||
$file->update((object)$updatedata);
|
||||
}
|
||||
}
|
||||
|
||||
die(json_encode((object)array('filepath' => $newfilepath)));
|
||||
|
||||
case 'rename':
|
||||
// TODO deprecate this, use 'updatefile' instead
|
||||
$filename = required_param('filename', PARAM_FILE);
|
||||
$filepath = required_param('filepath', PARAM_PATH);
|
||||
$newfilename = required_param('newfilename', PARAM_FILE);
|
||||
@@ -143,8 +188,57 @@ switch ($action) {
|
||||
}
|
||||
die;
|
||||
|
||||
case 'updatedir':
|
||||
$filepath = required_param('filepath', PARAM_PATH);
|
||||
$fs = get_file_storage();
|
||||
if (!$dir = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, '.')) {
|
||||
die(json_encode((object)array('error' => get_string('foldernotfound', 'repository'))));
|
||||
}
|
||||
$parts = explode('/', trim($dir->get_filepath(), '/'));
|
||||
$dirname = end($parts);
|
||||
$newdirname = required_param('newdirname', PARAM_FILE);
|
||||
$parent = required_param('newfilepath', PARAM_PATH);
|
||||
$newfilepath = clean_param($parent . '/' . $newdirname . '/', PARAM_PATH);
|
||||
//we must update directory and all children too
|
||||
if ($fs->get_directory_files($user_context->id, 'user', 'draft', $draftid, $newfilepath, true)) {
|
||||
//bad luck, we can not rename if something already exists there
|
||||
die(json_encode((object)array('error' => get_string('folderexists', 'repository'))));
|
||||
}
|
||||
$xfilepath = preg_quote($filepath, '|');
|
||||
if ($newfilepath !== $filepath && preg_match("|^$xfilepath|", $parent)) {
|
||||
// we can not move folder to it's own subfolder
|
||||
die(json_encode((object)array('error' => get_string('folderrecurse', 'repository'))));
|
||||
}
|
||||
|
||||
$files = $fs->get_area_files($user_context->id, 'user', 'draft', $draftid);
|
||||
$moved = array();
|
||||
foreach ($files as $file) {
|
||||
if (!preg_match("|^$xfilepath|", $file->get_filepath())) {
|
||||
continue;
|
||||
}
|
||||
// move one by one
|
||||
$path = preg_replace("|^$xfilepath|", $newfilepath, $file->get_filepath());
|
||||
$updatedata = array('filepath' => $path, 'timemodified' => $file->get_timemodified());
|
||||
if ($dirname !== $newdirname && $file->get_filepath() === $filepath) {
|
||||
// this is the main directory we move/rename AND it has actually been renamed
|
||||
$updatedata['timemodified'] = time();
|
||||
}
|
||||
$fs->create_file_from_storedfile($updatedata, $file);
|
||||
$moved[] = $file;
|
||||
}
|
||||
foreach ($moved as $file) {
|
||||
// delete all old
|
||||
$file->delete();
|
||||
}
|
||||
|
||||
$return = new stdClass();
|
||||
$return->filepath = $parent;
|
||||
echo json_encode($return);
|
||||
die;
|
||||
|
||||
case 'renamedir':
|
||||
case 'movedir':
|
||||
// TODO deprecate this, use 'renamemovedir' instead
|
||||
|
||||
$filepath = required_param('filepath', PARAM_PATH);
|
||||
$fs = get_file_storage();
|
||||
@@ -195,12 +289,11 @@ switch ($action) {
|
||||
} else {
|
||||
$return->filepath = $newfilepath;
|
||||
}
|
||||
$return->tree = new stdClass();
|
||||
file_get_drafarea_folders($draftid, '/', $return->tree);
|
||||
echo json_encode($return);
|
||||
die;
|
||||
|
||||
case 'movefile':
|
||||
// TODO deprecate this, use 'updatefile' instead
|
||||
$filename = required_param('filename', PARAM_FILE);
|
||||
$filepath = required_param('filepath', PARAM_PATH);
|
||||
$newfilepath = required_param('newfilepath', PARAM_PATH);
|
||||
@@ -284,8 +377,6 @@ switch ($action) {
|
||||
if ($newfile = $file->extract_to_storage($zipper, $user_context->id, 'user', 'draft', $draftid, $filepath, $USER->id)) {
|
||||
$return = new stdClass();
|
||||
$return->filepath = $filepath;
|
||||
$return->tree = new stdClass();
|
||||
file_get_drafarea_folders($draftid, '/', $return->tree);
|
||||
echo json_encode($return);
|
||||
} else {
|
||||
echo json_encode(false);
|
||||
|
||||
Reference in New Issue
Block a user