Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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)
  • Loading branch information...
commit c092681b4b4b1dfa5a80649d911c1c8c91af7e04 1 parent 694beb5
@marinaglancy marinaglancy authored
View
3  lang/en/repository.php
@@ -107,6 +107,9 @@
$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...';
View
19 lib/filestorage/stored_file.php
@@ -197,6 +197,25 @@ public function delete_reference() {
}
/**
+ * 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?
*
* Directories are only emulated, internally they are stored as empty
View
107 lib/form/filemanager.js
@@ -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) {
View
103 repository/draftfiles_ajax.php
@@ -76,8 +76,6 @@
$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 @@
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 @@
}
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 @@
} 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 @@
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);
Please sign in to comment.
Something went wrong with that request. Please try again.