diff --git a/public/lib/classes/output/requirements/page_requirements_manager.php b/public/lib/classes/output/requirements/page_requirements_manager.php index 7a098ac98b5..a3ff1de5ced 100644 --- a/public/lib/classes/output/requirements/page_requirements_manager.php +++ b/public/lib/classes/output/requirements/page_requirements_manager.php @@ -877,6 +877,8 @@ class page_requirements_manager { ['maxareabytesreached', 'moodle'], ['serverconnection', 'error'], ['changesmadereallygoaway', 'moodle'], ['complete', 'moodle'], ['invalidfiletypetitle', 'repository'], + ['upload_error_folders_not_supported', 'repository_upload'], + ['upload_error_folders_not_supported_title', 'repository_upload'], ], ]; break; diff --git a/public/lib/form/dndupload.js b/public/lib/form/dndupload.js index e1d7a2a5eec..dbfaf43a1fe 100644 --- a/public/lib/form/dndupload.js +++ b/public/lib/form/dndupload.js @@ -325,8 +325,10 @@ M.form_dndupload.init = function(Y, options) { this.hide_drop_target(); var files = e._event.dataTransfer.files; + const items = e._event.dataTransfer.items; + let options; if (this.filemanager) { - var options = { + options = { files: files, options: this.options, repositoryid: this.repositoryid, @@ -346,9 +348,6 @@ M.form_dndupload.init = function(Y, options) { callbackClearProgress: Y.bind('clear_progress', this), callbackStartProgress: Y.bind('startProgress', this), }; - this.show_progress(); - var uploader = new dnduploader(options); - uploader.start_upload(); } else { if (files.length >= 1) { options = { @@ -371,11 +370,24 @@ M.form_dndupload.init = function(Y, options) { callbackClearProgress: Y.bind('clear_progress', this), callbackStartProgress: Y.bind('startProgress', this), }; - this.show_progress(); - uploader = new dnduploader(options); - uploader.start_upload(); } } + let uploader = new dnduploader(options); + for (let i = 0; i < items.length; i++) { + let entry = items[i].webkitGetAsEntry(); + if (!entry) { + continue; + } + if (entry.isDirectory && entry.name) { + uploader.print_msg( + M.util.get_string('upload_error_folders_not_supported', 'repository_upload', entry.name), + 'error', + 'uploaderrorfoldersnotsupported'); + return false; + } + } + this.show_progress(); + uploader.start_upload(); return false; }, @@ -667,6 +679,9 @@ M.form_dndupload.init = function(Y, options) { if (errorCode === 'invalidfiletypewithaccepted') { header = M.util.get_string('invalidfiletypetitle', 'repository'); } + if (errorCode === 'uploaderrorfoldersnotsupported') { + header = M.util.get_string('upload_error_folders_not_supported_title', 'repository_upload'); + } if (!this.msg_dlg) { this.msg_dlg_node = Y.Node.create(M.core_filepicker.templates.message); this.msg_dlg_node.generateID(); diff --git a/public/repository/upload/lang/en/repository_upload.php b/public/repository/upload/lang/en/repository_upload.php index c93b7c98925..505d9a587fd 100644 --- a/public/repository/upload/lang/en/repository_upload.php +++ b/public/repository/upload/lang/en/repository_upload.php @@ -34,5 +34,7 @@ $string['upload_error_no_file'] = 'No file was uploaded.'; $string['upload_error_no_tmp_dir'] = 'PHP is missing a temporary folder.'; $string['upload_error_cant_write'] = 'Failed to write file to disk.'; $string['upload_error_extension'] = 'A PHP extension stopped the file upload.'; +$string['upload_error_folders_not_supported'] = 'Compress the folder into a ZIP file to upload it.'; +$string['upload_error_folders_not_supported_title'] = 'This folder can\'t be uploaded'; $string['upload_error_invalid_file'] = 'The file \'{$a}\' is either empty or a folder. To upload folders zip them first.'; $string['privacy:metadata'] = 'The Upload a file repository plugin does not store or transmit any personal data.';