Merge branch 'MDL-77591-401' of https://github.com/justusdieckmann/moodle into MOODLE_401_STABLE

This commit is contained in:
Ilya Tregubov 2023-06-21 16:58:44 +08:00
commit e34bb395fc
No known key found for this signature in database
GPG Key ID: 0F58186F748E55C1
2 changed files with 109 additions and 75 deletions

View File

@ -62,30 +62,31 @@ class assignfeedback_file_import_zip_form extends moodleform implements renderab
$mform->addElement('header', 'uploadzip', get_string('confirmuploadzip', 'assignfeedback_file'));
$currentgroup = groups_get_activity_group($assignment->get_course_module(), true);
$allusers = $assignment->list_participants($currentgroup, false);
$participants = array();
foreach ($allusers as $user) {
$participants[$assignment->get_uniqueid_for_user($user->id)] = $user;
}
$participants = $importer->get_participant_mapping($assignment);
$fs = get_file_storage();
$updates = array();
foreach ($files as $unzippedfile) {
$user = null;
$users = null;
$plugin = null;
$filename = '';
if ($importer->is_valid_filename_for_import($assignment, $unzippedfile, $participants, $user, $plugin, $filename)) {
if ($importer->is_file_modified($assignment, $user, $plugin, $filename, $unzippedfile)) {
if ($importer->is_valid_filename_for_import($assignment, $unzippedfile, $participants, $users, $plugin, $filename)) {
if ($importer->is_file_modified($assignment, $users, $plugin, $filename, $unzippedfile)) {
// Get a string we can show to identify this user.
$userdesc = fullname($user, has_capability('moodle/site:viewfullnames', $assignment->get_context()));
$path = pathinfo($filename);
if ($assignment->is_blind_marking()) {
$userdesc = get_string('hiddenuser', 'assign') .
$userdescs = [];
foreach ($users as $user) {
if ($assignment->is_blind_marking()) {
$userdescs[] = get_string('hiddenuser', 'assign') .
$assignment->get_uniqueid_for_user($user->id);
} else {
$userdescs[] = fullname($user, has_capability('moodle/site:viewfullnames', $assignment->get_context()));
}
}
$userdesc = join(", ", $userdescs);
$path = pathinfo($filename);
$grade = $assignment->get_user_grade($user->id, false);
$exists = false;

View File

@ -41,13 +41,13 @@ class assignfeedback_file_zip_importer {
*
* @param assign $assignment - The assignment instance
* @param stored_file $fileinfo - The fileinfo
* @param array $participants - A list of valid participants for this module indexed by unique_id
* @param stdClass $user - Set to the user that matches by participant id
* @param array $participants - A list of valid participants for this module indexed by unique_id or group id.
* @param array $users - Set to array with the user(s) that matches by participant id
* @param assign_plugin $plugin - Set to the plugin that exported the file
* @param string $filename - Set to truncated filename (prefix stripped)
* @return true If the participant Id can be extracted and this is a valid user
* @return bool If the participant Id can be extracted and this is a valid user
*/
public function is_valid_filename_for_import($assignment, $fileinfo, $participants, & $user, & $plugin, & $filename) {
public function is_valid_filename_for_import($assignment, $fileinfo, $participants, & $users, & $plugin, & $filename) {
if ($fileinfo->is_directory()) {
return false;
}
@ -91,7 +91,7 @@ class assignfeedback_file_zip_importer {
}
// Set user, which is by reference, so is used by the calling script.
$user = $participants[$participantid];
$users = $participants[$participantid];
// Set the plugin. This by reference, and is used by the calling script.
$plugin = $assignment->get_plugin_by_type($info[2], $info[3]);
@ -121,17 +121,27 @@ class assignfeedback_file_zip_importer {
* Does this file exist in any of the current files supported by this plugin for this user?
*
* @param assign $assignment - The assignment instance
* @param stdClass $user The user matching this uploaded file
* @param array|stdClass $users The user(s) matching this uploaded file
* @param assign_plugin $plugin The matching plugin from the filename
* @param string $filename The parsed filename from the zip
* @param stored_file $fileinfo The info about the extracted file from the zip
* @return bool - True if the file has been modified or is new
*/
public function is_file_modified($assignment, $user, $plugin, $filename, $fileinfo) {
public function is_file_modified($assignment, $users, $plugin, $filename, $fileinfo) {
$sg = null;
if (is_array($users)) {
$user = $users[0];
} else {
$user = $users;
}
if ($plugin->get_subtype() == 'assignsubmission') {
$sg = $assignment->get_user_submission($user->id, false);
if ($assignment->get_instance()->teamsubmission) {
$sg = $assignment->get_group_submission($user->id, 0, false);
} else {
$sg = $assignment->get_user_submission($user->id, false);
}
} else if ($plugin->get_subtype() == 'assignfeedback') {
$sg = $assignment->get_user_grade($user->id, false);
} else {
@ -228,6 +238,33 @@ class assignfeedback_file_zip_importer {
return $files;
}
/**
* Returns a mapping from unique user / group ids in folder names to array of moodle users.
*
* @param assign $assignment - The assignment instance
* @return array the mapping.
*/
public function get_participant_mapping(assign $assignment): array {
$currentgroup = groups_get_activity_group($assignment->get_course_module(), true);
$allusers = $assignment->list_participants($currentgroup, false);
$participants = array();
foreach ($allusers as $user) {
if ($assignment->get_instance()->teamsubmission) {
$group = $assignment->get_submission_group($user->id);
if (!$group) {
continue;
}
if (!isset($participants[$group->id])) {
$participants[$group->id] = [];
}
$participants[$group->id][] = $user;
} else {
$participants[$assignment->get_uniqueid_for_user($user->id)] = [$user];
}
}
return $participants;
}
/**
* Process an uploaded zip file
*
@ -249,67 +286,63 @@ class assignfeedback_file_zip_importer {
$fs = get_file_storage();
$files = $this->get_import_files($contextid);
$currentgroup = groups_get_activity_group($assignment->get_course_module(), true);
$allusers = $assignment->list_participants($currentgroup, false);
$participants = array();
foreach ($allusers as $user) {
$participants[$assignment->get_uniqueid_for_user($user->id)] = $user;
}
$participants = $this->get_participant_mapping($assignment);
foreach ($files as $unzippedfile) {
// Set the timeout for unzipping each file.
$user = null;
$users = null;
$plugin = null;
$filename = '';
if ($this->is_valid_filename_for_import($assignment, $unzippedfile, $participants, $user, $plugin, $filename)) {
if ($this->is_file_modified($assignment, $user, $plugin, $filename, $unzippedfile)) {
$grade = $assignment->get_user_grade($user->id, true);
if ($this->is_valid_filename_for_import($assignment, $unzippedfile, $participants, $users, $plugin, $filename)) {
if ($this->is_file_modified($assignment, $users, $plugin, $filename, $unzippedfile)) {
foreach ($users as $user) {
$grade = $assignment->get_user_grade($user->id, true);
// In 3.1 the default download structure of the submission files changed so that each student had their own
// separate folder, the files were not renamed and the folder structure was kept. It is possible that
// a user downloaded the submission files in 3.0 (or earlier) and edited the zip to add feedback or
// changed the behavior back to the previous format, the following code means that we will still support the
// old file structure. For more information please see - MDL-52489 / MDL-56022.
$path = pathinfo($filename);
if ($path['dirname'] == '.') { // Student submissions are not in separate folders.
$basename = $filename;
$dirname = "/";
$dirnamewslash = "/";
} else {
$basename = $path['basename'];
$dirname = $path['dirname'];
$dirnamewslash = $dirname . "/";
// In 3.1 the default download structure of the submission files changed so that each student had their own
// separate folder, the files were not renamed and the folder structure was kept. It is possible that
// a user downloaded the submission files in 3.0 (or earlier) and edited the zip to add feedback or
// changed the behavior back to the previous format, the following code means that we will still support the
// old file structure. For more information please see - MDL-52489 / MDL-56022.
$path = pathinfo($filename);
if ($path['dirname'] == '.') { // Student submissions are not in separate folders.
$basename = $filename;
$dirname = "/";
$dirnamewslash = "/";
} else {
$basename = $path['basename'];
$dirname = $path['dirname'];
$dirnamewslash = $dirname . "/";
}
if ($oldfile = $fs->get_file($contextid,
'assignfeedback_file',
ASSIGNFEEDBACK_FILE_FILEAREA,
$grade->id,
$dirname,
$basename)) {
// Update existing feedback file.
$oldfile->replace_file_with($unzippedfile);
$feedbackfilesupdated++;
} else {
// Create a new feedback file.
$newfilerecord = new stdClass();
$newfilerecord->contextid = $contextid;
$newfilerecord->component = 'assignfeedback_file';
$newfilerecord->filearea = ASSIGNFEEDBACK_FILE_FILEAREA;
$newfilerecord->filename = $basename;
$newfilerecord->filepath = $dirnamewslash;
$newfilerecord->itemid = $grade->id;
$fs->create_file_from_storedfile($newfilerecord, $unzippedfile);
$feedbackfilesadded++;
}
$userswithnewfeedback[$user->id] = 1;
// Update the number of feedback files for this user.
$fileplugin->update_file_count($grade);
// Update the last modified time on the grade which will trigger student notifications.
$assignment->notify_grade_modified($grade);
}
if ($oldfile = $fs->get_file($contextid,
'assignfeedback_file',
ASSIGNFEEDBACK_FILE_FILEAREA,
$grade->id,
$dirname,
$basename)) {
// Update existing feedback file.
$oldfile->replace_file_with($unzippedfile);
$feedbackfilesupdated++;
} else {
// Create a new feedback file.
$newfilerecord = new stdClass();
$newfilerecord->contextid = $contextid;
$newfilerecord->component = 'assignfeedback_file';
$newfilerecord->filearea = ASSIGNFEEDBACK_FILE_FILEAREA;
$newfilerecord->filename = $basename;
$newfilerecord->filepath = $dirnamewslash;
$newfilerecord->itemid = $grade->id;
$fs->create_file_from_storedfile($newfilerecord, $unzippedfile);
$feedbackfilesadded++;
}
$userswithnewfeedback[$user->id] = 1;
// Update the number of feedback files for this user.
$fileplugin->update_file_count($grade);
// Update the last modified time on the grade which will trigger student notifications.
$assignment->notify_grade_modified($grade);
}
}
}