From 9fb4a6300bdf03288e00a6738ea82728b7d9df61 Mon Sep 17 00:00:00 2001 From: Dongsheng Cai Date: Mon, 2 May 2011 10:11:19 +0800 Subject: [PATCH] MDL-26388, pop up a dialog when attaching a file already being used in draft area. --- lang/en/repository.php | 5 + lib/form/filemanager.js | 6 +- lib/outputrequirementslib.php | 5 +- repository/coursefiles/lib.php | 53 ++------- repository/filepicker.js | 103 ++++++++++++++++- repository/lib.php | 196 ++++++++++++++++++++++++++++++++- repository/local/lib.php | 46 +------- repository/recent/lib.php | 59 +++++++--- repository/repository_ajax.php | 42 +++---- repository/upload/lib.php | 46 ++++---- repository/user/lib.php | 37 +------ 11 files changed, 415 insertions(+), 183 deletions(-) diff --git a/lang/en/repository.php b/lang/en/repository.php index d57cef11f0b..bb2d551fe3a 100644 --- a/lang/en/repository.php +++ b/lang/en/repository.php @@ -94,6 +94,9 @@ $string['errorpostmaxsize'] = 'The uploaded file may exceed max_post_size direct $string['existingrepository'] = 'This repository already exists'; $string['federatedsearch'] = 'Federated search'; $string['fileexists'] = 'File name already being used, please use another name'; +$string['fileexistsdialog_editor'] = 'A file with that name has already been attached to the text you are editing.'; +$string['fileexistsdialog_filemanager'] = 'A file with that name has already been attached'; +$string['fileexistsdialogheader'] = 'File exists'; $string['filename'] = 'Filename'; $string['filenotnull'] = 'You must select a file to upload.'; $string['filesaved'] = 'The file has been saved'; @@ -138,6 +141,7 @@ $string['off'] = 'Enabled but hidden'; $string['openpicker'] = 'Choose a file...'; $string['operation'] = 'Operation'; $string['on'] = 'Enabled and visible'; +$string['overwrite'] = 'Overwrite'; $string['personalrepositories'] = 'Available repository instances'; $string['plugin'] = 'Repository plug-ins'; $string['pluginerror'] = 'Errors in repository plugin.'; @@ -148,6 +152,7 @@ $string['readonlyinstance'] = 'You cannot edit/delete a read-only instance'; $string['refresh'] = 'Refresh'; $string['refreshnonjsfilepicker'] = 'Please close this window and refresh non-javascript file picker'; $string['removed'] = 'Repository removed'; +$string['renameto'] = 'Rename to'; $string['repositories'] = 'Repositories'; $string['repository'] = 'Repository'; $string['repositorycourse'] = 'Course repositories'; diff --git a/lib/form/filemanager.js b/lib/form/filemanager.js index 7cae69587db..cf6837b0e1c 100644 --- a/lib/form/filemanager.js +++ b/lib/form/filemanager.js @@ -595,7 +595,11 @@ M.form_filemanager.init = function(Y, options) { scope: scope, params: params, callback: function(id, obj, args) { - scope.refresh(obj.filepath); + if (obj == false) { + alert(M.str.repository.fileexists); + } else { + scope.refresh(obj.filepath); + } Y.one('#fm-rename-input').set('value', ''); scope.rename_dialog.hide(); } diff --git a/lib/outputrequirementslib.php b/lib/outputrequirementslib.php index 2e1e782a6f0..b6939c0b9a2 100644 --- a/lib/outputrequirementslib.php +++ b/lib/outputrequirementslib.php @@ -415,7 +415,10 @@ class page_requirements_manager { array('cancel'), array('chooselicense', 'repository'), array('author', 'repository'), array('ok', 'moodle'), array('error', 'moodle'), array('info', 'moodle'), array('norepositoriesavailable', 'repository'), array('norepositoriesexternalavailable', 'repository'), array('nofilesattached', 'repository'), array('filepicker', 'repository'), - array('nofilesavailable', 'repository') + array('nofilesavailable', 'repository'), array('overwrite', 'repository'), + array('renameto', 'repository'), array('fileexists', 'repository'), + array('fileexistsdialogheader', 'repository'), array('fileexistsdialog_editor', 'repository'), + array('fileexistsdialog_filemanager', 'repository') )); break; case 'core_comment': diff --git a/repository/coursefiles/lib.php b/repository/coursefiles/lib.php index 7242f6e53c4..15381aeaa13 100644 --- a/repository/coursefiles/lib.php +++ b/repository/coursefiles/lib.php @@ -123,50 +123,6 @@ class repository_coursefiles extends repository { return $ret; } - /** - * Copy a file to file area - * - * @global object $USER - * @global object $DB - * @param string $encoded The metainfo of file, it is base64 encoded php serialized data - * @param string $draftitemid itemid - * @param string $new_filename The intended name of file - * @param string $new_filepath the new path in draft area - * @return array The information of file - */ - public function copy_to_area($encoded, $draftitemid, $new_filepath, $new_filename) { - global $USER, $DB; - $info = array(); - - $browser = get_file_browser(); - $fs = get_file_storage(); - $user_context = get_context_instance(CONTEXT_USER, $USER->id); - - // the final file - $params = unserialize(base64_decode($encoded)); - $contextid = clean_param($params['contextid'], PARAM_INT); - $fileitemid = clean_param($params['itemid'], PARAM_INT); - $filename = clean_param($params['filename'], PARAM_FILE); - $filepath = clean_param($params['filepath'], PARAM_PATH);; - $filearea = clean_param($params['filearea'], PARAM_ALPHAEXT); - $component = clean_param($params['component'], PARAM_ALPHAEXT); - $context = get_context_instance_by_id($contextid); - - if ($existingfile = $fs->get_file($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $new_filename)) { - throw new moodle_exception('fileexists'); - } - - $file_info = $browser->get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename); - $file_info->copy_to_storage($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $new_filename); - - $info['itemid'] = $draftitemid; - $info['title'] = $new_filename; - $info['contextid'] = $user_context->id; - $info['filesize'] = $file_info->get_filesize(); - - return $info; - } - public function get_link($encoded) { $info = array(); @@ -216,4 +172,13 @@ class repository_coursefiles extends repository { public static function get_type_option_names() { return array(); } + + /** + * Does this repository used to browse moodle files? + * + * @return boolean + */ + public function has_moodle_files() { + return true; + } } diff --git a/repository/filepicker.js b/repository/filepicker.js index 1be291ab827..e66e8dff5e9 100644 --- a/repository/filepicker.js +++ b/repository/filepicker.js @@ -85,7 +85,11 @@ M.core_filepicker.init = function(Y, options) { request: function(args, redraw) { var client_id = args.client_id; - var api = this.api + '?action='+args.action; + if (!args.api) { + var api = this.api + '?action='+args.action; + } else { + var api = args.api + '?action='+args.action; + } var params = {}; var scope = this; if (args['scope']) { @@ -147,6 +151,14 @@ M.core_filepicker.init = function(Y, options) { scope.print_msg(data.error, 'error'); scope.list(); return; + } else if (data && data.event) { + switch (data.event) { + case 'fileexists': + scope.process_existing_file(data); + break; + default: + break; + } } else { if (data.msg) { scope.print_msg(data.msg, 'info'); @@ -172,6 +184,94 @@ M.core_filepicker.init = function(Y, options) { this.wait('load'); } }, + process_existing_file: function(data) { + var scope = this; + var repository_id = scope.active_repo.id; + var client_id = scope.options.client_id; + var handleOverwrite = function() { + // overwrite + var dialog = this; + var params = {} + params['existingfilename'] = data.existingfile.filename; + params['existingfilepath'] = data.existingfile.filepath; + params['newfilename'] = data.newfile.filename; + params['newfilepath'] = data.newfile.filepath; + scope.request({ + 'params': params, + 'scope': scope, + 'action':'overwrite', + 'path': '', + 'client_id': client_id, + 'repository_id': repository_id, + 'callback': function(id, o, args) { + dialog.cancel(); + scope.hide(); + // editor needs to update url + // filemanager do nothing + if (scope.options.editor_target&&scope.options.env=='editor') { + scope.options.editor_target.value=data.existingfile.url; + scope.options.editor_target.onchange(); + } + } + }, true); + } + var handleRename = function() { + if (scope.options.editor_target&&scope.options.env=='editor') { + scope.options.editor_target.value=data.newfile.url; + scope.options.editor_target.onchange(); + } + this.cancel(); + scope.hide(); + data.client_id = client_id; + var formcallback_scope = null; + if (scope.options.magicscope) { + formcallback_scope = scope.options.magicscope; + } else { + formcallback_scope = scope; + } + scope.options.formcallback.apply(formcallback_scope, [data]); + } + var handleCancel = function() { + // Delete tmp file + var dialog = this; + var params = {}; + params['newfilename'] = data.newfile.filename; + params['newfilepath'] = data.newfile.filepath; + scope.request({ + 'params': params, + 'scope': scope, + 'action':'deletetmpfile', + 'path': '', + 'client_id': client_id, + 'repository_id': repository_id, + 'callback': function(id, o, args) { + scope.hide(); + dialog.cancel(); + } + }, true); + } + var dialog = new YAHOO.widget.SimpleDialog("dlg", { + width: "50em", + fixedcenter: true, + modal: true, + close: false, + icon: YAHOO.widget.SimpleDialog.ICON_HELP, + visible: true, + draggable: true, + buttons: [{ text: M.str.repository.overwrite, handler: handleOverwrite }, + { text: M.str.repository.renameto + ' "' + data.newfile.filename + '"', handler: handleRename }, + { text: M.str.moodle.cancel, handler: handleCancel, isDefault:true}] + }); + dialog.setHeader(M.str.repository.fileexistsdialogheader); + if (scope.options.env=='editor') { + dialog.setBody(M.str.repository.fileexistsdialog_editor); + } else { + dialog.setBody(M.str.repository.fileexistsdialog_filemanager); + } + + dialog.render(document.body); + dialog.show(); + }, print_msg: function(msg, type) { var client_id = this.options.client_id; var dlg_id = 'fp-msg-dlg-'+client_id; @@ -1113,7 +1213,6 @@ M.core_filepicker.init = function(Y, options) { this.print_paging('header'); //} - var toolbar = Y.one('#repo-tb-'+client_id); if(!r.nosearch) { diff --git a/repository/lib.php b/repository/lib.php index 70c58d6947b..82a1b6a7fb2 100644 --- a/repository/lib.php +++ b/repository/lib.php @@ -33,6 +33,7 @@ require_once($CFG->libdir . '/formslib.php'); define('FILE_EXTERNAL', 1); define('FILE_INTERNAL', 2); +define('RENAME_SUFFIX', '_2'); /** * This class is used to manage repository plugins @@ -586,6 +587,125 @@ abstract class repository { } } + /** + * Check if file already exists in draft area + * + * @param int $itemid + * @param string $filepath + * @param string $filename + * @return boolean + */ + public static function draftfile_exists($itemid, $filepath, $filename) { + global $USER; + $fs = get_file_storage(); + $usercontext = get_context_instance(CONTEXT_USER, $USER->id); + if ($fs->get_file($usercontext->id, 'user', 'draft', $itemid, $filepath, $filename)) { + return true; + } else { + return false; + } + } + + /** + * Does this repository used to browse moodle files? + * + * @return boolean + */ + public function has_moodle_files() { + return false; + } + /** + * This function is used to copy a moodle file to draft area + * + * @global object $USER + * @global object $DB + * @param string $encoded The metainfo of file, it is base64 encoded php serialized data + * @param string $draftitemid itemid + * @param string $new_filename The intended name of file + * @param string $new_filepath the new path in draft area + * @return array The information of file + */ + public function copy_to_area($encoded, $draftitemid, $new_filepath, $new_filename) { + global $USER, $DB; + + if ($this->has_moodle_files() == false) { + throw new coding_exception('Only repository used to browse moodle files can use copy_to_area'); + } + + $browser = get_file_browser(); + $params = unserialize(base64_decode($encoded)); + $user_context = get_context_instance(CONTEXT_USER, $USER->id); + + $contextid = clean_param($params['contextid'], PARAM_INT); + $fileitemid = clean_param($params['itemid'], PARAM_INT); + $filename = clean_param($params['filename'], PARAM_FILE); + $filepath = clean_param($params['filepath'], PARAM_PATH);; + $filearea = clean_param($params['filearea'], PARAM_ALPHAEXT); + $component = clean_param($params['component'], PARAM_ALPHAEXT); + + $context = get_context_instance_by_id($contextid); + // the file needs to copied to draft area + $file_info = $browser->get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename); + + if (repository::draftfile_exists($draftitemid, $new_filepath, $new_filename)) { + // create new file + $unused_filename = repository::get_unused_filename($draftitemid, $new_filepath, $new_filename); + $file_info->copy_to_storage($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $unused_filename); + $event = array(); + $event['event'] = 'fileexists'; + $event['newfile'] = new stdClass; + $event['newfile']->filepath = $new_filepath; + $event['newfile']->filename = $unused_filename; + $event['newfile']->url = moodle_url::make_draftfile_url($draftitemid, $new_filepath, $unused_filename)->out(); + $event['existingfile'] = new stdClass; + $event['existingfile']->filepath = $new_filepath; + $event['existingfile']->filename = $new_filename; + $event['existingfile']->url = moodle_url::make_draftfile_url($draftitemid, $filepath, $filename)->out();; + return $event; + } else { + $file_info->copy_to_storage($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $new_filename); + $info = array(); + $info['itemid'] = $draftitemid; + $info['title'] = $new_filename; + $info['contextid'] = $user_context->id; + $info['url'] = moodle_url::make_draftfile_url($draftitemid, $new_filepath, $new_filename)->out();; + $info['filesize'] = $file_info->get_filesize(); + return $info; + } + } + + /** + * Get unused filename by appending suffix + * + * @param int $itemid + * @param string $filepath + * @param string $filename + * @return string + */ + public static function get_unused_filename($itemid, $filepath, $filename) { + global $USER; + $fs = get_file_storage(); + while (repository::draftfile_exists($itemid, $filepath, $filename)) { + $filename = repository::append_suffix($filename); + } + return $filename; + } + + /** + * Append a suffix to filename + * + * @param string $filename + * @return string + */ + function append_suffix($filename) { + $pathinfo = pathinfo($filename); + if (empty($pathinfo['extension'])) { + return $filename . RENAME_SUFFIX; + } else { + return $pathinfo['filename'] . RENAME_SUFFIX . '.' . $pathinfo['extension']; + } + } + /** * Return all types that you a user can create/edit and which are also visible * Note: Mostly used in order to know if at least one editable type can be set @@ -861,7 +981,24 @@ abstract class repository { } $fs = get_file_storage(); if ($existingfile = $fs->get_file($context->id, $record->component, $record->filearea, $record->itemid, $record->filepath, $record->filename)) { - throw new moodle_exception('fileexists'); + $draftitemid = $record->itemid; + $new_filename = repository::get_unused_filename($draftitemid, $record->filepath, $record->filename); + $old_filename = $record->filename; + // create a tmp file + $record->filename = $new_filename; + $newfile = $fs->create_file_from_pathname($record, $thefile); + $event = array(); + $event['event'] = 'fileexists'; + $event['newfile'] = new stdClass; + $event['newfile']->filepath = $record->filepath; + $event['newfile']->filename = $new_filename; + $event['newfile']->url = moodle_url::make_draftfile_url($draftitemid, $record->filepath, $new_filename)->out(); + + $event['existingfile'] = new stdClass; + $event['existingfile']->filepath = $record->filepath; + $event['existingfile']->filename = $old_filename; + $event['existingfile']->url = moodle_url::make_draftfile_url($draftitemid, $record->filepath, $old_filename)->out();; + return $event; } if ($file = $fs->create_file_from_pathname($record, $thefile)) { if (empty($CFG->repository_no_delete)) { @@ -1552,6 +1689,54 @@ abstract class repository { return $str; } } + + /** + * Overwrite an existing file + * + * @param int $itemid + * @param string $filepath + * @param string $filename + * @param string $newfilepath + * @param string $newfilename + * @return boolean + */ + function overwrite_existing_draftfile($itemid, $filepath, $filename, $newfilepath, $newfilename) { + global $USER; + $fs = get_file_storage(); + $user_context = get_context_instance(CONTEXT_USER, $USER->id); + if ($file = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $filepath, $filename)) { + if ($tempfile = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $newfilepath, $newfilename)) { + // delete existing file to release filename + $file->delete(); + // create new file + $newfile = $fs->create_file_from_storedfile(array('filepath'=>$filepath, 'filename'=>$filename), $tempfile); + // remove temp file + $tempfile->delete(); + return true; + } + } + return false; + } + + /** + * Delete a temp file from draft area + * + * @param int $draftitemid + * @param string $filepath + * @param string $filename + * @return boolean + */ + function delete_tempfile_from_draft($draftitemid, $filepath, $filename) { + global $USER; + $fs = get_file_storage(); + $user_context = get_context_instance(CONTEXT_USER, $USER->id); + if ($file = $fs->get_file($user_context->id, 'user', 'draft', $draftitemid, $filepath, $filename)) { + $file->delete(); + return true; + } else { + return false; + } + } } /** @@ -1835,3 +2020,12 @@ function initialise_filepicker($args) { } return $return; } +/** + * Small function to walk an array to attach repository ID + * @param array $value + * @param string $key + * @param int $id + */ +function repository_attach_id(&$value, $key, $id){ + $value['repo_id'] = $id; +} diff --git a/repository/local/lib.php b/repository/local/lib.php index 91b0d45289a..ab374d6efdf 100644 --- a/repository/local/lib.php +++ b/repository/local/lib.php @@ -162,49 +162,11 @@ class repository_local extends repository { } /** - * Copy a file to file area + * Does this repository used to browse moodle files? * - * @global object $USER - * @global object $DB - * @param string $encoded The metainfo of file, it is base64 encoded php serialized data - * @param string $draftitemid itemid - * @param string $new_filename The intended name of file - * @param string $new_filepath the new path in draft area - * @return array The information of file + * @return boolean */ - public function copy_to_area($encoded, $draftitemid, $new_filepath, $new_filename) { - global $USER, $DB; - $info = array(); - - $browser = get_file_browser(); - $fs = get_file_storage(); - $user_context = get_context_instance(CONTEXT_USER, $USER->id); - - // the final file - $params = unserialize(base64_decode($encoded)); - $contextid = clean_param($params['contextid'], PARAM_INT); - $fileitemid = clean_param($params['itemid'], PARAM_INT); - $filename = clean_param($params['filename'], PARAM_FILE); - $filepath = clean_param($params['filepath'], PARAM_PATH);; - $filearea = clean_param($params['filearea'], PARAM_ALPHAEXT); - $component = clean_param($params['component'], PARAM_ALPHAEXT); - $context = get_context_instance_by_id($contextid); - - if ($existingfile = $fs->get_file($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $new_filename)) { - throw new moodle_exception('fileexists'); - } - - $file_info = $browser->get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename); - $file_info->copy_to_storage($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $new_filename); - - $info['itemid'] = $draftitemid; - $info['title'] = $new_filename; - $info['contextid'] = $user_context->id; - $info['filesize'] = $file_info->get_filesize(); - - return $info; - } - function get_file_count($contextid) { - global $DB; + public function has_moodle_files() { + return true; } } diff --git a/repository/recent/lib.php b/repository/recent/lib.php index 2176940343e..ddf3ef73f75 100644 --- a/repository/recent/lib.php +++ b/repository/recent/lib.php @@ -137,7 +137,7 @@ class repository_recent extends repository { return FILE_INTERNAL; } /** - * Copy a file to file area + * This function overwrite the default implement to copying file using file_storage * * @global object $USER * @global object $DB @@ -157,11 +157,11 @@ class repository_recent extends repository { $params = unserialize(base64_decode($encoded)); $contextid = clean_param($params['contextid'], PARAM_INT); - $fileitemid = clean_param($params['itemid'], PARAM_INT); - $filename = clean_param($params['filename'], PARAM_FILE); - $filepath = clean_param($params['filepath'], PARAM_PATH);; - $filearea = clean_param($params['filearea'], PARAM_ALPHAEXT); - $component = clean_param($params['component'], PARAM_ALPHAEXT); + $fileitemid = clean_param($params['itemid'], PARAM_INT); + $filename = clean_param($params['filename'], PARAM_FILE); + $filepath = clean_param($params['filepath'], PARAM_PATH);; + $filearea = clean_param($params['filearea'], PARAM_ALPHAEXT); + $component = clean_param($params['component'], PARAM_ALPHAEXT); // XXX: // When user try to pick a file from other filearea, normally file api will use file browse to @@ -171,28 +171,51 @@ class repository_recent extends repository { // To get 'recent' plugin working, we need to use lower level file_stoarge class to bypass the // capability check, we will use a better workaround to improve it. if ($stored_file = $fs->get_file($contextid, $component, $filearea, $fileitemid, $filepath, $filename)) { + // verify user id if ($USER->id != $stored_file->get_userid()) { throw new moodle_exception('errornotyourfile', 'repository'); } $file_record = array('contextid'=>$user_context->id, 'component'=>'user', 'filearea'=>'draft', 'itemid'=>$draftitemid, 'filepath'=>$new_filepath, 'filename'=>$new_filename, 'sortorder'=>0); - if ($file = $fs->get_file($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $new_filename)) { + + // test if file already exists + if (repository::draftfile_exists($draftitemid, $new_filepath, $new_filename)) { + // create new file + $unused_filename = repository::get_unused_filename($draftitemid, $new_filepath, $new_filename); + $file_record['filename'] = $unused_filename; + // create a tmp file + $fs->create_file_from_storedfile($file_record, $stored_file); + $event = array(); + $event['event'] = 'fileexists'; + $event['newfile'] = new stdClass; + $event['newfile']->filepath = $new_filepath; + $event['newfile']->filename = $unused_filename; + $event['newfile']->url = moodle_url::make_draftfile_url($draftitemid, $new_filepath, $unused_filename)->out(); + $event['existingfile'] = new stdClass; + $event['existingfile']->filepath = $new_filepath; + $event['existingfile']->filename = $new_filename; + $event['existingfile']->url = moodle_url::make_draftfile_url($draftitemid, $new_filepath, $new_filename)->out();; + return $event; + } else { + $fs->create_file_from_storedfile($file_record, $stored_file); $info = array(); - $info['title'] = $file->get_filename(); - $info['itemid'] = $file->get_itemid(); - $info['filesize'] = $file->get_filesize(); - $info['contextid'] = $file->get_contextid(); + $info['title'] = $new_filename; + $info['itemid'] = $draftitemid; + $info['filesize'] = $stored_file->get_filesize(); + $info['contextid'] = $user_context->id; return $info; } - $fs->create_file_from_storedfile($file_record, $stored_file); } + return false; - $info = array(); - $info['title'] = $new_filename; - $info['itemid'] = $draftitemid; - $info['filesize'] = $stored_file->get_filesize(); - $info['contextid'] = $user_context->id; + } - return $info; + /** + * Does this repository used to browse moodle files? + * + * @return boolean + */ + public function has_moodle_files() { + return true; } } diff --git a/repository/repository_ajax.php b/repository/repository_ajax.php index a2d354c070a..7f0e1276539 100644 --- a/repository/repository_ajax.php +++ b/repository/repository_ajax.php @@ -201,17 +201,12 @@ switch ($action) { echo json_encode($info); die; } else { - if (in_array($repo->options['type'], array('local', 'recent', 'user', 'coursefiles'))) { //TODO: this hardcoding is a really ugly hack (skodak) + // some repository plugins deal with moodle internal files, so we cannot use get_file + // method, so we use copy_to_area method + // (local, user, coursefiles, recent) + if ($repo->has_moodle_files()) { $fileinfo = $repo->copy_to_area($source, $itemid, $saveas_path, $saveas_filename); - $info = array(); - $info['file'] = $fileinfo['title']; - $info['id'] = $itemid; - $info['url'] = $CFG->httpswwwroot.'/draftfile.php/'.$fileinfo['contextid'].'/user/draft/'.$itemid.'/'.$fileinfo['title']; - $filesize = $fileinfo['filesize']; - if (($maxbytes!==-1) && ($filesize>$maxbytes)) { - throw new file_exception('maxbytes'); - } - echo json_encode($info); + echo json_encode($fileinfo); die; } // Download file to moodle @@ -266,14 +261,23 @@ switch ($action) { die; } break; -} -/** - * Small function to walk an array to attach repository ID - * @param array $value - * @param string $key - * @param int $id - */ -function repository_attach_id(&$value, $key, $id){ - $value['repo_id'] = $id; + case 'overwrite': + // existing file + $filepath = required_param('existingfilepath', PARAM_PATH); + $filename = required_param('existingfilename', PARAM_FILE); + // user added file which needs to replace the existing file + $newfilepath = required_param('newfilepath', PARAM_PATH); + $newfilename = required_param('newfilename', PARAM_FILE); + + echo json_encode(repository::overwrite_existing_draftfile($itemid, $filepath, $filename, $newfilepath, $newfilename)); + break; + + case 'deletetmpfile': + // delete tmp file + $newfilepath = required_param('newfilepath', PARAM_PATH); + $newfilename = required_param('newfilename', PARAM_FILE); + echo json_encode(repository::delete_tempfile_from_draft($itemid, $newfilepath, $newfilename)); + + break; } diff --git a/repository/upload/lib.php b/repository/upload/lib.php index 3619d4f60b2..82850423a95 100644 --- a/repository/upload/lib.php +++ b/repository/upload/lib.php @@ -140,21 +140,35 @@ class repository_upload extends repository { if (($maxbytes!==-1) && (filesize($_FILES[$elname]['tmp_name']) > $maxbytes)) { throw new file_exception('maxbytes'); } - - if ($file = $fs->get_file($context->id, $record->component, $record->filearea, $record->itemid, $record->filepath, $record->filename)) { - throw new moodle_exception('fileexists', 'repository'); - } - $record->contextid = $context->id; $record->userid = $USER->id; $record->source = ''; - $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']); + if (repository::draftfile_exists($record->itemid, $record->filepath, $record->filename)) { + $existingfilename = $record->filename; + $unused_filename = repository::get_unused_filename($record->itemid, $record->filepath, $record->filename); + $record->filename = $unused_filename; + $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']); + $event = array(); + $event['event'] = 'fileexists'; + $event['newfile'] = new stdClass; + $event['newfile']->filepath = $record->filepath; + $event['newfile']->filename = $unused_filename; + $event['newfile']->url = moodle_url::make_draftfile_url($record->itemid, $record->filepath, $unused_filename)->out(); - return array( - 'url'=>moodle_url::make_draftfile_url($record->itemid, $record->filepath, $record->filename)->out(), - 'id'=>$record->itemid, - 'file'=>$record->filename); + $event['existingfile'] = new stdClass; + $event['existingfile']->filepath = $record->filepath; + $event['existingfile']->filename = $existingfilename; + $event['existingfile']->url = moodle_url::make_draftfile_url($record->itemid, $record->filepath, $existingfilename)->out();; + return $event; + } else { + $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']); + + return array( + 'url'=>moodle_url::make_draftfile_url($record->itemid, $record->filepath, $record->filename)->out(), + 'id'=>$record->itemid, + 'file'=>$record->filename); + } } /** @@ -180,16 +194,4 @@ class repository_upload extends repository { public function supported_returntypes() { return FILE_INTERNAL; } - - /** - * Upload file to local filesystem pool - * @param string $elname name of element - * @param string $filearea - * @param string $filepath - * @param string $filename - use specified filename, if not specified name of uploaded file used - * @param bool $override override file if exists - * @return mixed stored_file object or false if error; may throw exception if duplicate found - */ - public function upload_to_filepool($elname, $record, $override = true) { - } } diff --git a/repository/user/lib.php b/repository/user/lib.php index 25e62f009c7..38d6d1ba3fc 100644 --- a/repository/user/lib.php +++ b/repository/user/lib.php @@ -125,40 +125,11 @@ class repository_user extends repository { } /** - * Copy a file to file area + * Does this repository used to browse moodle files? * - * @global object $USER - * @global object $DB - * @param string $encoded The metainfo of file, it is base64 encoded php serialized data - * @param string $draftitemid itemid - * @param string $new_filename The intended name of file - * @param string $new_filepath the new path in draft area - * @return array The information of file + * @return boolean */ - public function copy_to_area($encoded, $draftitemid, $new_filepath, $new_filename) { - global $USER, $DB; - - $browser = get_file_browser(); - $params = unserialize(base64_decode($encoded)); - $user_context = get_context_instance(CONTEXT_USER, $USER->id); - - $contextid = clean_param($params['contextid'], PARAM_INT); - $fileitemid = clean_param($params['itemid'], PARAM_INT); - $filename = clean_param($params['filename'], PARAM_FILE); - $filepath = clean_param($params['filepath'], PARAM_PATH);; - $filearea = clean_param($params['filearea'], PARAM_ALPHAEXT); - $component = clean_param($params['component'], PARAM_ALPHAEXT); - - $context = get_context_instance_by_id($contextid); - $file_info = $browser->get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename); - $file_info->copy_to_storage($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $new_filename); - - $info = array(); - $info['itemid'] = $draftitemid; - $info['title'] = $new_filename; - $info['contextid'] = $user_context->id; - $info['filesize'] = $file_info->get_filesize(); - - return $info; + public function has_moodle_files() { + return true; } }