Created one function that handles file update to be used from both JS and nonJS filepicker
$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['folderrecurse'] = 'Folder can not be moved to it\'s own subfolder';
$string['getfile'] = 'Select this file';
$string['hidden'] = 'Hidden';
$string['help'] = 'Help';
// 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]);
- }
+ $updatedata['filename'] = optional_param('newfilename', $filename, PARAM_FILE);
+ $updatedata['filepath'] = $newfilepath = optional_param('newfilepath', $filepath, PARAM_PATH);
+ if (($v = optional_param('newlicense', false, PARAM_TEXT)) !== false) {
+ $updatedata['license'] = $v;
}
-
- if (!empty($updatedata)) {
- 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'))));
- }
- $file->rename($newfilepath, $newfilename);
- }
- if (array_key_exists('license', $updatedata)) {
- $file->set_license($updatedata['license']);
- }
- if (array_key_exists('author', $updatedata)) {
- $file->set_author($updatedata['author']);
- }
- $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
- $file->set_timemodified(time());
- }
+ if (($v = optional_param('newauthor', false, PARAM_TEXT)) !== false) {
+ $updatedata['author'] = $v;
+ }
+ try {
+ repository::update_draftfile($draftid, $filepath, $filename, $updatedata);
+ } catch (moodle_exception $e) {
+ die(json_encode((object)array('error' => $e->getMessage())));
}
-
die(json_encode((object)array('filepath' => $newfilepath)));
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);
- if ($newfilepath == $filepath) {
- // no action required
- die(json_encode((object)array('filepath' => $parent)));
- }
- 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 (preg_match("|^$xfilepath|", $parent)) {
- // we can not move folder to it's own subfolder
- die(json_encode((object)array('error' => get_string('folderrecurse', 'repository'))));
- }
-
- //we must update directory and all children too
- $files = $fs->get_area_files($user_context->id, 'user', 'draft', $draftid);
- foreach ($files as $file) {
- if (!preg_match("|^$xfilepath|", $file->get_filepath())) {
- continue;
- }
- // move one by one
- $path = preg_replace("|^$xfilepath|", $newfilepath, $file->get_filepath());
- if ($dirname !== $newdirname && $file->get_filepath() === $filepath && $file->get_filename() === '.') {
- // this is the main directory we move/rename AND it has actually been renamed
- $file->set_timemodified(time());
- }
- $file->rename($path, $file->get_filename());
+ try {
+ repository::update_draftfile($draftid, $filepath, '.', array('filepath' => $newfilepath));
+ } catch (moodle_exception $e) {
+ die(json_encode((object)array('error' => $e->getMessage())));
}
-
- $return = new stdClass();
- $return->filepath = $parent;
- echo json_encode($return);
- die;
+ die(json_encode((object)array('filepath' => $parent)));
case 'zip':
$filepath = required_param('filepath', PARAM_PATH);
break;
case 'rename':
-
- if ($fs->file_exists($user_context->id, 'user', 'draft', $itemid, $draftpath, $newfilename)) {
- print_error('fileexists');
- } else if ($file = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $draftpath, $filename)) {
- $newfile = $fs->create_file_from_storedfile(array('filename'=>$newfilename), $file);
- $file->delete();
- }
-
+ repository::update_draftfile($itemid, $draftpath, $filename, array('filename' => $newfilename));
$home_url->param('action', 'browse');
$home_url->param('draftpath', $draftpath);
redirect($home_url);
case 'movefile':
if (!empty($targetpath)) {
- if ($fs->file_exists($user_context->id, 'user', 'draft', $itemid, $targetpath, $filename)) {
- print_error('cannotmovefile');
- } else if ($file = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $draftpath, $filename)) {
- $newfile = $fs->create_file_from_storedfile(array('filepath'=>$targetpath), $file);
- $file->delete();
- } else {
- var_dump('cannot find file');
- die;
- }
+ repository::update_draftfile($itemid, $draftpath, $filename, array('filepath' => $targetpath));
$home_url->param('action', 'browse');
$home_url->param('draftpath', $targetpath);
redirect($home_url);
return false;
}
+ /**
+ * Updates a file in draft filearea.
+ *
+ * This function can only update fields filepath, filename, author, license.
+ * If anything (except filepath) is updated, timemodified is set to current time.
+ * If filename or filepath is updated the file unconnects from it's origin
+ * and therefore all references to it will be converted to copies when
+ * filearea is saved.
+ *
+ * @param int $draftid
+ * @param string $filepath path to the directory containing the file, or full path in case of directory
+ * @param string $filename name of the file, or '.' in case of directory
+ * @param array $updatedata array of fields to change (only filename, filepath, license and/or author can be updated)
+ * @throws moodle_exception if for any reason file can not be updated (file does not exist, target already exists, etc.)
+ */
+ public static function update_draftfile($draftid, $filepath, $filename, $updatedata) {
+ global $USER;
+ $fs = get_file_storage();
+ $usercontext = context_user::instance($USER->id);
+ // make sure filename and filepath are present in $updatedata
+ $updatedata = $updatedata + array('filepath' => $filepath, 'filename' => $filename);
+ $filemodified = false;
+ if (!$file = $fs->get_file($usercontext->id, 'user', 'draft', $draftid, $filepath, $filename)) {
+ if ($filename === '.') {
+ throw new moodle_exception('foldernotfound', 'repository');
+ } else {
+ throw new moodle_exception('filenotfound', 'error');
+ }
+ }
+ if (!$file->is_directory()) {
+ // This is a file
+ if ($updatedata['filepath'] !== $filepath || $updatedata['filename'] !== $filename) {
+ // Rename/move file: check that target file name does not exist.
+ if ($fs->file_exists($usercontext->id, 'user', 'draft', $draftid, $updatedata['filepath'], $updatedata['filename'])) {
+ throw new moodle_exception('fileexists', 'repository');
+ }
+ if (($filesource = @unserialize($file->get_source())) && isset($filesource->original)) {
+ unset($filesource->original);
+ $file->set_source(serialize($filesource));
+ }
+ $file->rename($updatedata['filepath'], $updatedata['filename']);
+ // timemodified is updated only when file is renamed and not updated when file is moved.
+ $filemodified = $filemodified || ($updatedata['filename'] !== $filename);
+ }
+ if (array_key_exists('license', $updatedata) && $updatedata['license'] !== $file->get_license()) {
+ // Update license and timemodified.
+ $file->set_license($updatedata['license']);
+ $filemodified = true;
+ }
+ if (array_key_exists('author', $updatedata) && $updatedata['author'] !== $file->get_author()) {
+ // Update author and timemodified.
+ $file->set_author($updatedata['author']);
+ $filemodified = true;
+ }
+ // Update timemodified:
+ if ($filemodified) {
+ $file->set_timemodified(time());
+ }
+ } else {
+ // This is a directory - only filepath can be updated for a directory (it was moved).
+ if ($updatedata['filepath'] === $filepath) {
+ // nothing to update
+ return;
+ }
+ if ($fs->file_exists($usercontext->id, 'user', 'draft', $draftid, $updatedata['filepath'], '.')) {
+ // bad luck, we can not rename if something already exists there
+ throw new moodle_exception('folderexists', 'repository');
+ }
+ $xfilepath = preg_quote($filepath, '|');
+ if (preg_match("|^$xfilepath|", $updatedata['filepath'])) {
+ // we can not move folder to it's own subfolder
+ throw new moodle_exception('folderrecurse', 'repository');
+ }
+
+ // If directory changed the name, update timemodified.
+ $filemodified = (basename(rtrim($file->get_filepath(), '/')) !== basename(rtrim($updatedata['filepath'], '/')));
+
+ // Now update directory and all children.
+ $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftid);
+ foreach ($files as $f) {
+ if (preg_match("|^$xfilepath|", $f->get_filepath())) {
+ $path = preg_replace("|^$xfilepath|", $updatedata['filepath'], $f->get_filepath());
+ if (($filesource = @unserialize($f->get_source())) && isset($filesource->original)) {
+ // unset original so the references are not shown any more
+ unset($filesource->original);
+ $f->set_source(serialize($filesource));
+ }
+ $f->rename($path, $f->get_filename());
+ if ($filemodified && $f->get_filepath() === $updatedata['filepath'] && $f->get_filename() === $filename) {
+ $f->set_timemodified(time());
+ }
+ }
+ }
+ }
+ }
+
/**
* Delete a temp file from draft area
*