From 9de8a1728035be46808f1eecfb26746fae548c2a Mon Sep 17 00:00:00 2001 From: nvhai248 Date: Thu, 23 Oct 2025 14:37:21 +0700 Subject: [PATCH] MDL-61588 filepicker: improve the message if you upload the wrong type --- .../tests/behat/admin_upload_content.feature | 4 ++-- public/lang/en/deprecated.txt | 1 + public/lang/en/repository.php | 6 +++++- .../requirements/page_requirements_manager.php | 2 ++ public/lib/form/dndupload.js | 17 +++++++++++------ public/mod/data/tests/behat/add_entries.feature | 10 +++++----- public/repository/filepicker.js | 4 ++-- public/repository/repository_ajax.php | 14 +++++++++++++- .../tests/behat/upload_file_type.feature | 6 ++++-- public/repository/upload/lib.php | 17 ++++++++++++++--- 10 files changed, 59 insertions(+), 22 deletions(-) diff --git a/public/contentbank/contenttype/h5p/tests/behat/admin_upload_content.feature b/public/contentbank/contenttype/h5p/tests/behat/admin_upload_content.feature index f4d6e7a7261..83867f379c5 100644 --- a/public/contentbank/contenttype/h5p/tests/behat/admin_upload_content.feature +++ b/public/contentbank/contenttype/h5p/tests/behat/admin_upload_content.feature @@ -138,8 +138,8 @@ Feature: H5P file upload to content bank for admins And I set the field "Attachment" to "#dirroot#/lib/tests/fixtures/1.jpg" And I press "Upload this file" # Confirm that jpg files cannot be added to content bank. - Then "Image (JPEG) filetype cannot be accepted." "text" should exist - And I click on "OK" "button" in the "Error" "dialogue" + Then "The file '1.jpg' is not an accepted file type." "text" should exist + And I click on "OK" "button" in the "File type not accepted" "dialogue" And I click on "Close" "button" in the "File picker" "dialogue" And I click on "Cancel" "button" in the "Upload" "dialogue" # Confirm that jpg file was not added to the content bank. diff --git a/public/lang/en/deprecated.txt b/public/lang/en/deprecated.txt index f14974f4d51..2965514902b 100644 --- a/public/lang/en/deprecated.txt +++ b/public/lang/en/deprecated.txt @@ -95,3 +95,4 @@ privacy:metadata:schedule:subject,core_reportbuilder sitename,core_hub sitename_help,core_hub defaultissuerpassword_help,core_badges +invalidfiletype,core_repository diff --git a/public/lang/en/repository.php b/public/lang/en/repository.php index 1f0f9d73635..06f1e310fff 100644 --- a/public/lang/en/repository.php +++ b/public/lang/en/repository.php @@ -148,9 +148,10 @@ $string['instances'] = 'Repository instances'; $string['instancesforsite'] = '{$a} Site-wide common instance(s)'; $string['instancesforcourses'] = '{$a} Course-wide common instance(s)'; $string['instancesforusers'] = '{$a} User private instance(s)'; +$string['invalidfiletypetitle'] = 'File type not accepted'; +$string['invalidfiletypewithaccepted'] = 'The file \'{$a->filename}\' is not an accepted file type. The accepted file types are: {$a->acceptedfiletypes}'; $string['invalidjson'] = 'Invalid JSON string'; $string['invalidplugin'] = 'Invalid repository {$a} plugin'; -$string['invalidfiletype'] = '{$a} filetype cannot be accepted.'; $string['invalidrepositoryid'] = 'Invalid repository ID'; $string['invalidparams'] = 'Invalid parameters'; $string['isactive'] = 'Active?'; @@ -267,3 +268,6 @@ $string['privacy:metadata:repository_instances:username'] = 'The optional userna $string['privacy:metadata:repository_instances:password'] = 'The optional password configured for the repository instance.'; $string['privacy:metadata:repository_instances:timecreated'] = 'The date/time of creation for the repository instance.'; $string['privacy:metadata:repository_instances:timemodified'] = 'The date/time of modification of the repository instance.'; + +// Deprecated since Moodle 5.2. +$string['invalidfiletype'] = '{$a} filetype cannot be accepted.'; diff --git a/public/lib/classes/output/requirements/page_requirements_manager.php b/public/lib/classes/output/requirements/page_requirements_manager.php index 71052f7ef6b..41bb127173d 100644 --- a/public/lib/classes/output/requirements/page_requirements_manager.php +++ b/public/lib/classes/output/requirements/page_requirements_manager.php @@ -827,6 +827,7 @@ class page_requirements_manager { ['renameto', 'repository'], ['referencesexist', 'repository'], ['select', 'repository'], + ['invalidfiletypetitle', 'repository'], ], ]; break; @@ -886,6 +887,7 @@ class page_requirements_manager { ['sizegb', 'moodle'], ['sizemb', 'moodle'], ['sizekb', 'moodle'], ['sizeb', 'moodle'], ['maxareabytesreached', 'moodle'], ['serverconnection', 'error'], ['changesmadereallygoaway', 'moodle'], ['complete', 'moodle'], + ['invalidfiletypetitle', 'repository'], ], ]; break; diff --git a/public/lib/form/dndupload.js b/public/lib/form/dndupload.js index be4e93d6c4f..f7c91e2040d 100644 --- a/public/lib/form/dndupload.js +++ b/public/lib/form/dndupload.js @@ -652,16 +652,21 @@ M.form_dndupload.init = function(Y, options) { }, /** - * Display a message in a popup - * @param string msg - the message to display - * @param string type - 'error' or 'info' + * Display a message in a popup dialog. + * + * @param {string} msg - The message text to display. + * @param {string} type - The message type, 'error' or 'info'. + * @param {string} errorCode - The associated error code (optional). */ - print_msg: function(msg, type) { + print_msg: function(msg, type, errorCode) { var header = M.util.get_string('error', 'moodle'); if (type != 'error') { - type = 'info'; // one of only two types excepted + type = 'info'; // One of only two types excepted. header = M.util.get_string('info', 'moodle'); } + if (errorCode === 'invalidfiletypewithaccepted') { + header = M.util.get_string('invalidfiletypetitle', 'repository'); + } if (!this.msg_dlg) { this.msg_dlg_node = Y.Node.create(M.core_filepicker.templates.message); this.msg_dlg_node.generateID(); @@ -1051,7 +1056,7 @@ M.form_dndupload.init = function(Y, options) { var result = JSON.parse(xhr.responseText); if (result) { if (result.error) { - self.print_msg(result.error, 'error'); // TODO add filename? + self.print_msg(result.error, 'error', result.errorcode); self.uploadfinished(); } else { // Only update the filepicker if there were no errors diff --git a/public/mod/data/tests/behat/add_entries.feature b/public/mod/data/tests/behat/add_entries.feature index c9d4256a6d2..ccd683fdc39 100644 --- a/public/mod/data/tests/behat/add_entries.feature +++ b/public/mod/data/tests/behat/add_entries.feature @@ -171,11 +171,11 @@ Feature: Users can add entries to database activities Then I should see "" Examples: - | filepath | errormessage | - | #dirroot#/lib/tests/fixtures/empty.txt | Text file filetype cannot be accepted. | - | #dirroot#/lib/tests/fixtures/timezonewindows.xml | application/xml filetype cannot be accepted. | - | #dirroot#/mod/data/tests/fixtures/behat_preset.zip | Archive (ZIP) filetype cannot be accepted. | - | #dirroot#/mod/data/tests/fixtures/test_data_content.csv | Comma-separated values filetype cannot be accepted. | + | filepath | errormessage | + | #dirroot#/lib/tests/fixtures/empty.txt | The file 'empty.txt' is not an accepted file type. | + | #dirroot#/lib/tests/fixtures/timezonewindows.xml | The file 'timezonewindows.xml' is not an accepted file type. | + | #dirroot#/mod/data/tests/fixtures/behat_preset.zip | The file 'behat_preset.zip' is not an accepted file type. | + | #dirroot#/mod/data/tests/fixtures/test_data_content.csv | The file 'test_data_content.csv' is not an accepted file type. | @javascript @_file_upload Scenario: Users can upload picture files into a picture field diff --git a/public/repository/filepicker.js b/public/repository/filepicker.js index 4db058a35d5..c0f27193f0b 100644 --- a/public/repository/filepicker.js +++ b/public/repository/filepicker.js @@ -688,11 +688,11 @@ M.core_filepicker.init = function(Y, options) { } // error checking if (data && data.error) { - if (data.errorcode === 'invalidfiletype') { + if (data.errorcode === 'invalidfiletypewithaccepted') { // File type errors are not really errors, so report them less scarily. Y.use('moodle-core-notification-alert', function() { return new M.core.alert({ - title: M.util.get_string('error', 'moodle'), + title: M.util.get_string('invalidfiletypetitle', 'repository'), message: data.error, }); }); diff --git a/public/repository/repository_ajax.php b/public/repository/repository_ajax.php index 6706fc459a4..3d23ad91b8c 100644 --- a/public/repository/repository_ajax.php +++ b/public/repository/repository_ajax.php @@ -143,7 +143,19 @@ switch ($action) { $mimetypes[] = mimeinfo('type', $type); } if (!in_array(mimeinfo('type', $saveas_filename), $mimetypes)) { - throw new moodle_exception('invalidfiletype', 'repository', '', get_mimetype_description(array('filename' => $saveas_filename))); + $util = new \core_form\filetypes_util(); + throw new moodle_exception( + 'invalidfiletypewithaccepted', + 'repository', + '', + [ + 'filename' => $saveas_filename, + 'acceptedfiletypes' => $OUTPUT->render_from_template( + 'core_form/filetypes-descriptions', + $util->describe_file_types($accepted_types), + ), + ], + ); } } diff --git a/public/repository/tests/behat/upload_file_type.feature b/public/repository/tests/behat/upload_file_type.feature index 46c807ecf52..14869d0b636 100644 --- a/public/repository/tests/behat/upload_file_type.feature +++ b/public/repository/tests/behat/upload_file_type.feature @@ -11,7 +11,9 @@ Feature: File type can be validated on upload And I select "Upload a file" repository in file picker And I set the field "Attachment" to "#dirroot#/lib/form/tests/fixtures/filemanager_hideif_disabledif_form.php" And I click on "Upload this file" "button" in the "File picker" "dialogue" - Then I should see "Text file filetype cannot be accepted." in the "Error" "dialogue" - And I click on "OK" "button" in the "Error" "dialogue" + Then I should see "The file 'filemanager_hideif_disabledif_form.php' is not an accepted file type. The accepted file types are:" in the "File type not accepted" "dialogue" + And I should see "OpenDocument Text document .odt" in the "File type not accepted" "dialogue" + And I should see "PDF document .pdf" in the "File type not accepted" "dialogue" + And I click on "OK" "button" in the "File type not accepted" "dialogue" And I should see "Attachment" in the "File picker" "dialogue" And "Upload this file" "button" in the "File picker" "dialogue" should be visible diff --git a/public/repository/upload/lib.php b/public/repository/upload/lib.php index 4dd48c5938f..191f673a57d 100644 --- a/public/repository/upload/lib.php +++ b/public/repository/upload/lib.php @@ -80,7 +80,7 @@ class repository_upload extends repository { */ public function process_upload($saveasfilename, $maxbytes, $types = '*', $savepath = '/', $itemid = 0, $license = null, $author = '', $overwriteexisting = false, $areamaxbytes = FILE_AREA_MAX_BYTES_UNLIMITED) { - global $USER, $CFG; + global $USER, $CFG, $OUTPUT; \core\session\manager::write_close(); @@ -188,8 +188,19 @@ class repository_upload extends repository { // Check filetype. $filemimetype = file_storage::mimetype($_FILES[$elname]['tmp_name'], $record->filename); if (!in_array($filemimetype, $this->mimetypes)) { - throw new moodle_exception('invalidfiletype', 'repository', '', - get_mimetype_description(array('filename' => $_FILES[$elname]['name']))); + $util = new \core_form\filetypes_util(); + throw new moodle_exception( + 'invalidfiletypewithaccepted', + 'repository', + '', + [ + 'filename' => $record->filename, + 'acceptedfiletypes' => $OUTPUT->render_from_template( + 'core_form/filetypes-descriptions', + $util->describe_file_types($types), + ), + ], + ); } }