From 4f2b765a15ba8ab318e97f8b87727706b4fc650c Mon Sep 17 00:00:00 2001 From: David Balch Date: Fri, 22 Nov 2019 13:57:02 +0000 Subject: [PATCH 1/8] Use "Name" for the header of the column containing student names. "Username" is more properly the login username, which may be useful to include as an option in the report. --- changelog.md | 3 +++ classes/lib.php | 6 +++--- templates/reportassign.mustache | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index 6b64a26..185490a 100755 --- a/changelog.md +++ b/changelog.md @@ -23,3 +23,6 @@ Improved display of buttons etc. Participant number is now always displayed for anonymous Assignments Option to add extensions directly from report Bug fixes + +Unreleased +Changed "Username" to "Name" (for firstname lastname), allowing "Username" separately for the user login name. diff --git a/classes/lib.php b/classes/lib.php index 829c14f..cb218c0 100644 --- a/classes/lib.php +++ b/classes/lib.php @@ -355,7 +355,7 @@ protected static function sanitise_filename($path) { array_map('chr', range(0,31)), array("<", ">", ":", '"', "\\", "|", "?", "*")); return str_replace($bad, "_", $path); - } + } /** * Get feedback @@ -693,7 +693,7 @@ public static function export($assignment, $filename, $submissions) { // Headers. $i = 0; $myxls->write_string(3, $i++, '#'); - $myxls->write_string(3, $i++, get_string('username')); + $myxls->write_string(3, $i++, get_string('name')); $myxls->write_string(3, $i++, get_string('participantno', 'report_assign')); foreach ($profilefields as $profilefield) { $myxls->write_string(3, $i++, get_string($profilefield)); @@ -788,7 +788,7 @@ public static function exportall($filename, $submissions) { $i = 0; $myxls->write_string(1, $i++, '#'); $myxls->write_string(1, $i++, get_string('assignmentname', 'report_assign')); - $myxls->write_string(1, $i++, get_string('username')); + $myxls->write_string(1, $i++, get_string('name')); $myxls->write_string(1, $i++, get_string('participantno', 'report_assign')); if ($fields != '') { foreach ($profilefields as $profilefield) { diff --git a/templates/reportassign.mustache b/templates/reportassign.mustache index 662cdbe..54fc74e 100755 --- a/templates/reportassign.mustache +++ b/templates/reportassign.mustache @@ -20,7 +20,7 @@ - + {{# blindmarking }} {{/ blindmarking }} From ff2b6d98cfa2d35f296e3690087b58c8d669a41f Mon Sep 17 00:00:00 2001 From: David Balch Date: Thu, 6 Aug 2020 17:53:29 +0100 Subject: [PATCH 2/8] Add option to split username into first & last fields. --- changelog.md | 1 + classes/lib.php | 58 ++++++++++++++++++++++++++++++--- classes/output/reportassign.php | 3 ++ lang/en/report_assign.php | 3 ++ settings.php | 18 +++++++++- templates/reportassign.mustache | 16 +++++++-- 6 files changed, 92 insertions(+), 7 deletions(-) diff --git a/changelog.md b/changelog.md index 185490a..6ab3022 100755 --- a/changelog.md +++ b/changelog.md @@ -26,3 +26,4 @@ Bug fixes Unreleased Changed "Username" to "Name" (for firstname lastname), allowing "Username" separately for the user login name. +Added option of splitting name into separate columns for first and last names. diff --git a/classes/lib.php b/classes/lib.php index cb218c0..824d76e 100644 --- a/classes/lib.php +++ b/classes/lib.php @@ -82,6 +82,28 @@ public static function allowed_to_view($assignid, $assignments) { return array_key_exists($assignid, $assignments); } + /** + * Get field options pref. + * @return array + */ + public static function get_field_options() { + $opts = get_config('report_assign', 'fieldoptions'); + if (empty($opts)) { + return; + } + if (strrpos($opts, ",") === false) { + $fieldoptions = [$opts => 1]; + } else { + $opts = array_filter(explode(',', $opts)); + $fieldoptions = []; + foreach ($opts as $opt) { + $fieldoptions[$opt] = 1; + } + } + + return $fieldoptions; + } + /** * Get the group(s) a user is a member of * @param int $userid @@ -675,6 +697,10 @@ public static function export($assignment, $filename, $submissions) { $profilefields = explode(',', $fields); } + // Field options pref. + $fieldoptions = self::get_field_options(); + $splitusername = !empty($fieldoptions['splitusername']); + // Group mode? $cm = get_coursemodule_from_instance('assign', $assignment->id); $groupmode = $cm->groupmode; @@ -693,7 +719,12 @@ public static function export($assignment, $filename, $submissions) { // Headers. $i = 0; $myxls->write_string(3, $i++, '#'); - $myxls->write_string(3, $i++, get_string('name')); + if ($splitusername) { + $myxls->write_string(3, $i++, get_string('firstname')); + $myxls->write_string(3, $i++, get_string('lastname')); + } else { + $myxls->write_string(3, $i++, get_string('name')); + } $myxls->write_string(3, $i++, get_string('participantno', 'report_assign')); foreach ($profilefields as $profilefield) { $myxls->write_string(3, $i++, get_string($profilefield)); @@ -725,7 +756,12 @@ public static function export($assignment, $filename, $submissions) { foreach ($submissions as $s) { $i = 0; $myxls->write_number($row, $i++, $linecount++); - $myxls->write_string($row, $i++, $s->fullname); + if ($splitusername) { + $myxls->write_string($row, $i++, $s->firstname); + $myxls->write_string($row, $i++, $s->lastname); + } else { + $myxls->write_string($row, $i++, $s->fullname); + } $myxls->write_string($row, $i++, $s->participantno); if ($fields != '') { foreach ($s->profiledata as $value) { @@ -772,6 +808,10 @@ public static function exportall($filename, $submissions) { $fields = get_config('report_assign', 'profilefields'); $profilefields = explode(',', $fields); + // Field options pref. + $fieldoptions = self::get_field_options(); + $splitusername = !empty($fieldoptions['splitusername']); + // Plagiarism plugins? $isturnitin = !empty(\core_plugin_manager::instance()->get_plugin_info('plagiarism_turnitin')); $isurkund = !empty(\core_plugin_manager::instance()->get_plugin_info('plagiarism_urkund')); @@ -788,7 +828,12 @@ public static function exportall($filename, $submissions) { $i = 0; $myxls->write_string(1, $i++, '#'); $myxls->write_string(1, $i++, get_string('assignmentname', 'report_assign')); - $myxls->write_string(1, $i++, get_string('name')); + if ($splitusername) { + $myxls->write_string(1, $i++, get_string('firstname')); + $myxls->write_string(1, $i++, get_string('lastname')); + } else { + $myxls->write_string(1, $i++, get_string('name')); + } $myxls->write_string(1, $i++, get_string('participantno', 'report_assign')); if ($fields != '') { foreach ($profilefields as $profilefield) { @@ -817,7 +862,12 @@ public static function exportall($filename, $submissions) { $i = 0; $myxls->write_number($row, $i++, $linecount++); $myxls->write_string($row, $i++, $s->assignmentname); - $myxls->write_string($row, $i++, $s->fullname); + if ($splitusername) { + $myxls->write_string($row, $i++, $s->firstname); + $myxls->write_string($row, $i++, $s->lastname); + } else { + $myxls->write_string($row, $i++, $s->fullname); + } $myxls->write_string($row, $i++, $s->participantno); if ($fields != '') { foreach ($s->profiledata as $value) { diff --git a/classes/output/reportassign.php b/classes/output/reportassign.php index 1d740a7..ad371ab 100755 --- a/classes/output/reportassign.php +++ b/classes/output/reportassign.php @@ -80,6 +80,8 @@ public function export_for_template(renderer_base $output) { $groupmode = $cm->groupmode; $groups = groups_get_all_groups($this->course->id); + $fieldoptions = \report_assign\lib::get_field_options(); + return [ 'canrevealnames' => has_capability('report/assign:shownames', $this->context) && $this->assignment->blindmarking, 'canexport' => has_capability('report/assign:export', $this->context), @@ -95,6 +97,7 @@ public function export_for_template(renderer_base $output) { 'profilefields' => $this->get_profilefields(), 'blindmarking' => $this->assignment->blindmarking, 'extensionsok' => $this->extensionsok, + 'fieldoptions' => $fieldoptions, ]; } diff --git a/lang/en/report_assign.php b/lang/en/report_assign.php index ca067f0..1337dbe 100644 --- a/lang/en/report_assign.php +++ b/lang/en/report_assign.php @@ -51,6 +51,8 @@ $string['feedback'] = 'Feedback'; $string['feedbackcomments'] = 'Feedback comments'; $string['feedbackfiles'] = 'Feedback files'; +$string['fieldoptions'] = 'Field options'; +$string['fieldoptions_desc'] = 'Modify how reports are generated'; $string['grade'] = 'Grade'; $string['grader'] = 'Grader'; $string['group'] = 'Group'; @@ -70,6 +72,7 @@ $string['released'] = 'Released'; $string['revealidentities'] = 'Identities revealed'; $string['selectassignment'] = 'Select assignment to view submission report'; +$string['splitusername'] = 'Split user\'s name into separate fields'; $string['status'] = 'Status'; $string['statusdraft'] = 'draft'; $string['statusnew'] = 'new'; diff --git a/settings.php b/settings.php index 340655d..0f6873d 100755 --- a/settings.php +++ b/settings.php @@ -52,4 +52,20 @@ $choices )); -} \ No newline at end of file + // Selector for field options. + $rawchoices = [ + 'splitusername', + ]; + $choices = []; + foreach ($rawchoices as $choice) { + $choices[$choice] = new lang_string($choice, 'report_assign'); + } + + $settings->add(new admin_setting_configmulticheckbox( + 'report_assign/fieldoptions', + new lang_string('fieldoptions', 'report_assign'), + new lang_string('fieldoptions_desc', 'report_assign'), + [], + $choices + )); +} diff --git a/templates/reportassign.mustache b/templates/reportassign.mustache index 54fc74e..be3df65 100755 --- a/templates/reportassign.mustache +++ b/templates/reportassign.mustache @@ -20,7 +20,13 @@
{{# str }}username{{/ str }}{{# str }}name{{/ str }}{{# str }}participantno, report_assign{{/ str }}
- + {{# fieldoptions.splitusername }} + + + {{/ fieldoptions.splitusername }} + {{^ fieldoptions.splitusername }} + + {{/ fieldoptions.splitusername }} {{# blindmarking }} {{/ blindmarking }} @@ -52,7 +58,13 @@ {{# submissions }} - + {{# fieldoptions.splitusername }} + + + {{/ fieldoptions.splitusername }} + {{^ fieldoptions.splitusername }} + + {{/ fieldoptions.splitusername }} {{# blindmarking }} {{/ blindmarking }} From 260bb07291f43e69af30833ad67783aae4819ed7 Mon Sep 17 00:00:00 2001 From: David Balch Date: Fri, 7 Aug 2020 09:15:48 +0100 Subject: [PATCH 3/8] Add username to profile field options. --- changelog.md | 1 + settings.php | 1 + 2 files changed, 2 insertions(+) diff --git a/changelog.md b/changelog.md index 6ab3022..9d53f42 100755 --- a/changelog.md +++ b/changelog.md @@ -27,3 +27,4 @@ Bug fixes Unreleased Changed "Username" to "Name" (for firstname lastname), allowing "Username" separately for the user login name. Added option of splitting name into separate columns for first and last names. +Added "Username" option to Profile field options (for login name). diff --git a/settings.php b/settings.php index 0f6873d..01afc12 100755 --- a/settings.php +++ b/settings.php @@ -29,6 +29,7 @@ $settings = new admin_settingpage('report_assign_settings', new lang_string('pluginname', 'report_assign')); $rawchoices = [ + 'username', 'email', 'idnumber', 'phone1', From adb4baf26131b0c071bb7e6e9f09412f87433f21 Mon Sep 17 00:00:00 2001 From: David Balch Date: Fri, 7 Aug 2020 10:06:05 +0100 Subject: [PATCH 4/8] Convert submission fields to a preference. Moves the hard-coded status, grade, grader, modified, and extension fields into a preference, and add other grading fields: - gradevalue - actual grade value, separate from maximum grade. - grademax - maximum grade - created - submission creation date - latenessincext - how late the submission was, including any extensions The fields gradevalue and grademax are intended as an alternative to grade, suitable for further processing outside of Moodle, via spreadsheet. The default choices are set to the previous hard-coded fields. NB: This has changed the field order in the columns. --- changelog.md | 5 + classes/lib.php | 223 +++++++++++++++++++++++++------- classes/output/reportassign.php | 19 ++- index.php | 4 +- lang/en/report_assign.php | 5 + settings.php | 22 ++++ templates/reportassign.mustache | 35 +++-- 7 files changed, 245 insertions(+), 68 deletions(-) diff --git a/changelog.md b/changelog.md index 9d53f42..aa8dec4 100755 --- a/changelog.md +++ b/changelog.md @@ -28,3 +28,8 @@ Unreleased Changed "Username" to "Name" (for firstname lastname), allowing "Username" separately for the user login name. Added option of splitting name into separate columns for first and last names. Added "Username" option to Profile field options (for login name). +Converted submission fields to a preference, adding options for: + - grade value and maximum grade in separate columns. + - submission creation date + - submission lateness (including extensions) +NB: This has changed the field order in the columns. diff --git a/classes/lib.php b/classes/lib.php index 824d76e..1fb4713 100644 --- a/classes/lib.php +++ b/classes/lib.php @@ -71,6 +71,49 @@ public static function get_assignments($id) { return $assignments; } + /** + * Get field choices from submissionfields pref. + * @return array + */ + public static function get_config_submissionfields() { + $fields = []; + $configstr = get_config('report_assign', 'submissionfields'); + + if ($configstr != '') { + $fields = explode(',', $configstr); + } + + return $fields; + } + + /** + * Get field choices from submissionfields pref, with strings. + * @return array + */ + public static function get_config_submissionfields_strings() { + $fieldsandstrings = []; + $configfields = self::get_config_submissionfields(); + + foreach ($configfields as $field) { + switch ($field) { + case 'grademax': + case 'gradevalue': + case 'grader': + case 'created': + case 'extension': + case 'latenessincext': + case 'released': + case 'log': + $fieldsandstrings[$field] = get_string($field, 'report_assign'); + break; + default: + $fieldsandstrings[$field] = get_string($field); + } + } + + return $fieldsandstrings; + } + /** * can the user view the data submitted * some checks @@ -191,6 +234,101 @@ protected static function get_turnitin_score($assid, $cmid, $userid) { } } + /** + * Get submission data. + * @param object $assign + * @param object $submission + * @param object $instance + * @param object $usersubmission + * @param object $userflags + * @param string $dateformat + * @return mixed + */ + public static function get_submission_data( + $assign, $submission, $instance, $usersubmission, $userflags, $dateformat + ) { + $submissiondata = []; + $submissionfields = self::get_config_submissionfields_strings(); + + if ($usersubmission) { + $userid = $submission->id; + + $gradeitem = $assign->get_grade_item(); + $grade = $assign->get_user_grade($userid, false); + $gradevalue = empty($grade) ? null : $grade->grade; + + foreach ($submissionfields as $fieldid => $fieldstring) { + switch ($fieldid) { + case 'created': + $submissiondata['created'] = userdate($usersubmission->timecreated, $dateformat); + break; + case 'modified': + $submissiondata['modified'] = userdate($usersubmission->timemodified, $dateformat); + break; + case 'grade': + $displaygrade = $assign->display_grade($gradevalue, false, $userid); + $submissiondata['grade'] = str_replace(' ', ' ', $displaygrade); + break; + case 'gradevalue': + if (!empty($grade) && $grade->grade >= 0) { + $gradevalue = $grade->grade; + } + if ($gradevalue == -1 || $gradevalue === null) { + $gradevalue = '-'; + } else { + $gradevalue = grade_format_gradevalue($grade->grade, $gradeitem); + } + $submissiondata['gradevalue'] = $gradevalue; + break; + case 'grademax': + $submissiondata['grademax'] = grade_format_gradevalue($gradeitem->grademax, $gradeitem); + break; + case 'grader': + $submissiondata['grader'] = self::get_grader($grade); + break; + case 'latenessincext': + $timesubmitted = $usersubmission->timemodified; + if ($submission->grantedextension && !empty($userflags)) { + $due = $userflags->extensionduedate; + } else { + $due = $instance->duedate; + } + if ($due && $timesubmitted > $due + && $usersubmission->status != ASSIGN_SUBMISSION_STATUS_NEW) { + $usertime = format_time($timesubmitted - $due); + $latemessage = get_string('submittedlateshort', 'assign', $usertime); + $submissiondata['latenessincext'] = $latemessage; + } else { + $submissiondata['latenessincext'] = '-'; + } + break; + case 'extension': + // Skip; extension is handled directly in add_assignment_data(). + break; + case 'released': + // Skip; extension is handled directly in add_assignment_data(). + + break; + default: + if (isset($usersubmission->$fieldid)) { + $submissiondata[$fieldid] = $usersubmission->$fieldid; + } else { + $submissiondata[$fieldid] = '-'; + } + } + } + } else { + foreach ($submissionfields as $fieldid => $fieldstring) { + if ($fieldid != 'extension') { + // Skip extension, which is handled directly in add_assignment_data(). + $submissiondata[$fieldid] = '-'; + } + } + } + + return $submissiondata; + } + /** * Get file submission plugin * and check it is enabled @@ -534,6 +672,9 @@ public static function add_assignment_data($courseid, $assid, $cm, $assign, $sub // Report date format. $dateformat = get_string('strftimedatetimeshort', 'langconfig'); + // Submission fields selected in preferences. + $submissionfields = self::get_config_submissionfields(); + // Get sub plugins. $filesubmission = self::get_submission_plugin_files($assign); @@ -552,7 +693,7 @@ public static function add_assignment_data($courseid, $assid, $cm, $assign, $sub $coursegrade = grade_get_grades($courseid, 'mod', 'assign', $cm->instance, $userid); $gradeinstance = reset($coursegrade->items[0]->grades); $dategraded = $gradeinstance->dategraded; - $submission->released = empty($dategraded) ? '-' : userdate($dategraded, $dateformat); + $released = empty($dategraded) ? '-' : userdate($dategraded, $dateformat); $submission->assignmentid = $assid; $submission->userid = $userid; $submission->loglink = new \moodle_url('/report/assign/userlog.php', [ @@ -569,27 +710,12 @@ public static function add_assignment_data($courseid, $assid, $cm, $assign, $sub } else { $usersubmission = $assign->get_user_submission($userid, false); } - if ($submission->grantedextension && !empty($userflags)) { - $submission->extensionduedate = userdate($userflags->extensionduedate, $dateformat); - } else { - $submission->extensionduedate = '-'; - } - if ($usersubmission) { - $submission->created = userdate($usersubmission->timecreated, $dateformat); - $submission->modified = userdate($usersubmission->timemodified, $dateformat); - $submission->status = get_string('status' . $usersubmission->status, 'report_assign'); - $submissionid = $usersubmission->id; - $grade = $assign->get_user_grade($userid, false); - $gradevalue = empty($grade) ? null : $grade->grade; - $displaygrade = $assign->display_grade($gradevalue, false, $userid); - $submission->grade = $displaygrade; - $submission->grader = self::get_grader($grade); - } else { - $submission->created = '-'; - $submission->modified = '-'; - $submission->status = '-'; - $submission->grade = '-'; - $submission->grader = '-'; + if (in_array('extension', $submissionfields)) { + if ($submission->grantedextension && !empty($userflags)) { + $submission->extensionduedate = userdate($userflags->extensionduedate, $dateformat); + } else { + $submission->extensionduedate = '-'; + } } $submission->participantno = empty($submission->recordid) ? '-' : $submission->recordid; list($submission->groups, $submission->groupids) = self::get_user_groups($userid, $courseid); @@ -598,6 +724,13 @@ public static function add_assignment_data($courseid, $assid, $cm, $assign, $sub $submission->files = self::get_submission_files($assign, $filesubmission, $usersubmission, $userid); $submission->profiledata = self::get_profile_data($profilefields, $submission); $submission->isprofiledata = count($profilefields) != 0; + $submission->submissiondata = self::get_submission_data( + $assign, $submission, $instance, $usersubmission, $userflags, $dateformat + ); + $submission->submissiondata['released'] = $released; + + // User fields. + $profilefields = explode(',', get_config('report_assign', 'profilefields')); } return $submissions; @@ -697,6 +830,9 @@ public static function export($assignment, $filename, $submissions) { $profilefields = explode(',', $fields); } + // Submission fields. + $submissionfields = self::get_config_submissionfields_strings(); + // Field options pref. $fieldoptions = self::get_field_options(); $splitusername = !empty($fieldoptions['splitusername']); @@ -732,8 +868,9 @@ public static function export($assignment, $filename, $submissions) { if ($groupmode) { $myxls->write_string(3, $i++, get_string('groups')); } - $myxls->write_string(3, $i++, get_string('status')); - $myxls->write_string(3, $i++, get_string('grade', 'report_assign')); + foreach ($submissionfields as $fieldid => $fieldstring) { + $myxls->write_string(3, $i++, $fieldstring); + } if ($urkundenabled = self::urkund_enabled($assignment->id)) { $myxls->write_string(3, $i++, get_string('urkund', 'report_assign')); } @@ -744,10 +881,6 @@ public static function export($assignment, $filename, $submissions) { $myxls->write_string(3, $i++, get_string('workflow', 'report_assign')); $myxls->write_string(3, $i++, get_string('allocatedmarker', 'report_assign')); } - $myxls->write_string(3, $i++, get_string('grader', 'report_assign')); - $myxls->write_string(3, $i++, get_string('modified')); - $myxls->write_string(3, $i++, get_string('released', 'report_assign')); - $myxls->write_string(3, $i++, get_string('extension', 'report_assign')); $myxls->write_string(3, $i++, get_string('files')); // Add some data. @@ -771,8 +904,12 @@ public static function export($assignment, $filename, $submissions) { if ($groupmode) { $myxls->write_string($row, $i++, $s->groups); } - $myxls->write_string($row, $i++, $s->status); - $myxls->write_string($row, $i++, html_entity_decode($s->grade)); + foreach ($s->submissiondata as $value) { + $myxls->write_string($row, $i++, $value); + } + if (!empty($s->extensionduedate)) { + $myxls->write_string($row, $i++, $s->extensionduedate); + } if ($urkundenabled) { $urkundscore = empty($s->urkund->similarityscore) ? '-' : $s->urkund->similarityscore; $myxls->write_string($row, $i++, $urkundscore); @@ -785,10 +922,6 @@ public static function export($assignment, $filename, $submissions) { $myxls->write_string($row, $i++, $s->workflow); $myxls->write_string($row, $i++, $s->marker); } - $myxls->write_string($row, $i++, $s->grader); - $myxls->write_string($row, $i++, $s->modified); - $myxls->write_string($row, $i++, $s->released); - $myxls->write_string($row, $i++, $s->extensionduedate); $myxls->write_string($row, $i++, $s->files); $row++; } @@ -808,6 +941,9 @@ public static function exportall($filename, $submissions) { $fields = get_config('report_assign', 'profilefields'); $profilefields = explode(',', $fields); + // Submission fields. + $submissionfields = self::get_config_submissionfields_strings(); + // Field options pref. $fieldoptions = self::get_field_options(); $splitusername = !empty($fieldoptions['splitusername']); @@ -841,8 +977,9 @@ public static function exportall($filename, $submissions) { } } $myxls->write_string(1, $i++, get_string('groups')); - $myxls->write_string(1, $i++, get_string('status')); - $myxls->write_string(1, $i++, get_string('grade')); + foreach ($submissionfields as $fieldid => $fieldstring) { + $myxls->write_string(1, $i++, $fieldstring); + } if ($isurkund) { $myxls->write_string(1, $i++, get_string('urkund', 'report_assign')); } @@ -850,9 +987,6 @@ public static function exportall($filename, $submissions) { $myxls->write_string(1, $i++, get_string('turnitin', 'report_assign')); } $myxls->write_string(1, $i++, get_string('allocatedmarker', 'report_assign')); - $myxls->write_string(1, $i++, get_string('modified')); - $myxls->write_string(1, $i++, get_string('duedate', 'report_assign')); - $myxls->write_string(1, $i++, get_string('extension', 'report_assign')); $myxls->write_string(1, $i++, get_string('files')); // Add some data. @@ -875,8 +1009,12 @@ public static function exportall($filename, $submissions) { } } $myxls->write_string($row, $i++, isset($s->groups) ? $s->groups : '-'); - $myxls->write_string($row, $i++, $s->status); - $myxls->write_string($row, $i++, html_entity_decode($s->grade)); + foreach ($s->submissiondata as $value) { + $myxls->write_string($row, $i++, $value); + } + if (!empty($s->extensionduedate)) { + $myxls->write_string($row, $i++, $s->extensionduedate); + } if ($isurkund) { $myxls->write_string($row, $i++, isset($s->urkund->similarityscore) ? $s->urkund->similarityscore : '-'); } @@ -884,9 +1022,6 @@ public static function exportall($filename, $submissions) { $myxls->write_string($row, $i++, isset($s->turnitin->similarityscore) ? $s->turnitin->similarityscore : '-'); } $myxls->write_string($row, $i++, isset($s->grader) ? $s->grader : '-'); - $myxls->write_string($row, $i++, $s->modified); - $myxls->write_string($row, $i++, $s->duedate); - $myxls->write_string($row, $i++, $s->extensionduedate); $myxls->write_string($row, $i++, $s->files); $row++; } diff --git a/classes/output/reportassign.php b/classes/output/reportassign.php index ad371ab..2228dab 100755 --- a/classes/output/reportassign.php +++ b/classes/output/reportassign.php @@ -42,18 +42,21 @@ class reportassign implements renderable, templatable { protected $submissions; + protected $assign; + protected $assignment; protected $showparticipantnumber; protected $extensionsok; - public function __construct($course, $context, $fullurl, $submissions, $assignment, $showparticipantnumber, $extensionsok) { + public function __construct($course, $context, $fullurl, $submissions, $assign, $showparticipantnumber, $extensionsok) { $this->course = $course; $this->context = $context; $this->fullurl = $fullurl; $this->submissions = $submissions; - $this->assignment = $assignment; + $this->assign = $assign; + $this->assignment = $assign->get_instance(); $this->showparticipantnumber = $showparticipantnumber; $this->extensionsok = $extensionsok; } @@ -82,18 +85,28 @@ public function export_for_template(renderer_base $output) { $fieldoptions = \report_assign\lib::get_field_options(); + // Get submission field headers. + $submissionfields = \report_assign\lib::get_config_submissionfields_strings(); + // Convert submission data from associative keys to indexed for template. + $submissions = array_values($this->submissions); + foreach ($submissions as $submission) { + $submission->submissiondata = array_values($submission->submissiondata); + } + return [ 'canrevealnames' => has_capability('report/assign:shownames', $this->context) && $this->assignment->blindmarking, 'canexport' => has_capability('report/assign:export', $this->context), 'baseurl' => $this->fullurl, 'backurl' => new \moodle_url('/report/assign/index.php', ['id' => $this->course->id]), - 'submissions' => array_values($this->submissions), + 'submissions' => $submissions, 'assignment' => $this->assignment, 'enableplagiarism' => !empty($CFG->enableplagiarism), 'turnitinenabled' => \report_assign\lib::turnitin_enabled($this->assignment->id), 'urkundenabled' => \report_assign\lib::urkund_enabled($this->assignment->id), 'groupselect' => $groupmode != 0, 'groups' => array_values($groups), + 'submissionfieldsenabled' => count($submissionfields), + 'submissionfields' => array_values($submissionfields), 'profilefields' => $this->get_profilefields(), 'blindmarking' => $this->assignment->blindmarking, 'extensionsok' => $this->extensionsok, diff --git a/index.php b/index.php index 0220fb0..ba80141 100644 --- a/index.php +++ b/index.php @@ -161,7 +161,7 @@ // Display report. $showparticipantnumber = $assignment->blindmarking && !$assign->is_blind_marking(); $extensionsok = report_assign\lib::is_extension_allowed($assign); - $reportassign = new report_assign\output\reportassign($course, $context, $fullurl, $submissions, $assignment, $showparticipantnumber, $extensionsok); + $reportassign = new report_assign\output\reportassign($course, $context, $fullurl, $submissions, $assign, $showparticipantnumber, $extensionsok); echo $output->render_reportassign($reportassign); // Trigger an assignment viewed event. @@ -182,5 +182,3 @@ } echo $output->footer(); - - diff --git a/lang/en/report_assign.php b/lang/en/report_assign.php index 1337dbe..5eca0db 100644 --- a/lang/en/report_assign.php +++ b/lang/en/report_assign.php @@ -54,9 +54,12 @@ $string['fieldoptions'] = 'Field options'; $string['fieldoptions_desc'] = 'Modify how reports are generated'; $string['grade'] = 'Grade'; +$string['grademax'] = 'Maximum grade'; +$string['gradevalue'] = 'Grade value'; $string['grader'] = 'Grader'; $string['group'] = 'Group'; $string['groupsubmission'] = 'Group submission'; +$string['latenessincext'] = 'Lateness (including extensions)'; $string['log'] = 'Log'; $string['name'] = 'Name'; $string['noassignments'] = 'There are no assignments in this course'; @@ -78,6 +81,8 @@ $string['statusnew'] = 'new'; $string['statusreopened'] = 'reopened'; $string['statussubmitted'] = 'submitted'; +$string['submissionfields'] = 'Submission fields'; +$string['submissionfields_desc'] = 'Include these submission fields in the report'; $string['submissions'] = 'Submissions'; $string['submitdate'] = 'Submit date'; $string['submitted'] = 'Submitted'; diff --git a/settings.php b/settings.php index 01afc12..af7baaa 100755 --- a/settings.php +++ b/settings.php @@ -53,6 +53,28 @@ $choices )); + // Selector for submission fields. + $submissionfields = [ + "status" => new lang_string('status'), + "grade" => new lang_string('grade'), + "gradevalue" => new lang_string('gradevalue', 'report_assign'), + "grademax" => new lang_string('grademax', 'report_assign'), + "grader" => new lang_string('grader', 'report_assign'), + "created" => new lang_string('created', 'report_assign'), + "modified" => new lang_string('modified'), + "latenessincext" => new lang_string('latenessincext', 'report_assign'), + "released" => new lang_string('released', 'report_assign'), + "extension" => new lang_string('extension', 'report_assign'), + ]; + + $settings->add(new admin_setting_configmulticheckbox( + 'report_assign/submissionfields', + new lang_string('submissionfields', 'report_assign'), + new lang_string('submissionfields_desc', 'report_assign'), + ["status" => 1, "grade" => 1, "grader" => 1, "modified" => 1, "extension" => 1], + $submissionfields + )); + // Selector for field options. $rawchoices = [ 'splitusername', diff --git a/templates/reportassign.mustache b/templates/reportassign.mustache index be3df65..0623948 100755 --- a/templates/reportassign.mustache +++ b/templates/reportassign.mustache @@ -33,11 +33,12 @@ {{# profilefields }} {{/ profilefields }} + {{# submissionfields }} + + {{/ submissionfields }} {{# groupselect }} {{/ groupselect }} - - {{# urkundenabled }} {{/ urkundenabled }} @@ -48,10 +49,6 @@ {{/ assignment.markingallocation }} - - - - @@ -76,8 +73,20 @@ {{# groupselect }} {{/ groupselect }} - - + {{# submissionfieldsenabled }} + {{# submissiondata }} + + {{/ submissiondata }} + {{# extensionduedate }} + + {{/ extensionduedate }} + {{/ submissionfieldsenabled }} {{# urkundenabled }} {{/ assignment.markingallocation }} - - - - From 7103369fec7fe0862523d802e59e731d6985a37d Mon Sep 17 00:00:00 2001 From: David Balch Date: Tue, 11 Aug 2020 17:11:17 +0100 Subject: [PATCH 5/8] Respect blind marking. Restrict name data available to only users with report/assign:shownames. --- classes/lib.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/classes/lib.php b/classes/lib.php index 1fb4713..c253acd 100644 --- a/classes/lib.php +++ b/classes/lib.php @@ -688,6 +688,9 @@ public static function add_assignment_data($courseid, $assid, $cm, $assign, $sub $profileconfig = trim(get_config('report_assign', 'profilefields')); $profilefields = empty($profileconfig) ? [] : explode(',', $profileconfig); + $context = $assign->get_context(); + $canrevealnames = $instance->revealidentities || has_capability('report/assign:shownames', $context); + foreach ($submissions as $submission) { $userid = $submission->id; $coursegrade = grade_get_grades($courseid, 'mod', 'assign', $cm->instance, $userid); @@ -717,6 +720,15 @@ public static function add_assignment_data($courseid, $assid, $cm, $assign, $sub $submission->extensionduedate = '-'; } } + if ($instance->blindmarking) { + if (!$canrevealnames) { + $s = '[' . get_string('blindmarkingon', 'report_assign') . ']'; + $submission->firstname = $s; + $submission->lastname = $s; + $submission->username = $s; + $submission->email = $s; + } + } $submission->participantno = empty($submission->recordid) ? '-' : $submission->recordid; list($submission->groups, $submission->groupids) = self::get_user_groups($userid, $courseid); $submission->urkund = self::get_urkund_score($assid, $cmid, $userid); From 2dfec45254292f4f3b8c664e0845253ba49096b6 Mon Sep 17 00:00:00 2001 From: David Balch Date: Tue, 11 Aug 2020 11:48:57 +0100 Subject: [PATCH 6/8] Convert File submission field to a submission plugin preference. Moves the hard-coded files column into a preference, and adds columns for whatever submission plugins are enabled. --- changelog.md | 1 + classes/lib.php | 176 +++++++++++++++++++++++++++++--- classes/output/reportassign.php | 5 + index.php | 4 +- lang/en/report_assign.php | 2 + settings.php | 23 +++++ templates/reportassign.mustache | 10 +- 7 files changed, 204 insertions(+), 17 deletions(-) diff --git a/changelog.md b/changelog.md index aa8dec4..d74e52e 100755 --- a/changelog.md +++ b/changelog.md @@ -33,3 +33,4 @@ Converted submission fields to a preference, adding options for: - submission creation date - submission lateness (including extensions) NB: This has changed the field order in the columns. +Converted File submission fields to a preference with all enabled submission plugins. diff --git a/classes/lib.php b/classes/lib.php index c253acd..772e462 100644 --- a/classes/lib.php +++ b/classes/lib.php @@ -114,6 +114,79 @@ public static function get_config_submissionfields_strings() { return $fieldsandstrings; } + /** + * Get plugin choices from submissionplugins config. + * @return array + */ + public static function get_config_submissionplugins() { + $fields = []; + $configstr = get_config('report_assign', 'submissionplugins'); + + if ($configstr != '') { + $fields = explode(',', $configstr); + } + + return $fields; + } + + /** + * Get config-enabled submission plugins enabled on an assignment. + * @param object $assign + * @return mixed + */ + public static function get_config_submissionplugins_assign($assign) { + $submissionplugins = []; + $configplugins = self::get_config_submissionplugins(); + + $assignplugins = $assign->get_submission_plugins(); + + foreach ($assignplugins as $plugin) { + if ($plugin->is_enabled() && in_array($plugin->get_type(), $configplugins)) { + $submissionplugins[$plugin->get_type()] = $plugin; + } + } + + return $submissionplugins; + } + + /** + * Get config-enabled submission plugins enabled on an assignment, with display strings. + * @param object $assign + * @return array + */ + public static function get_config_submissionplugins_assign_strings($assign) { + $fieldsandstrings = []; + + $submissionplugins = self::get_config_submissionplugins_assign($assign); + + foreach ($submissionplugins as $plugin) { + $fieldsandstrings[$plugin->get_type()] = $plugin->get_name(); + } + + return $fieldsandstrings; + } + + /** + * Get config-enabled submission plugins enabled enabled on the site, with display strings. + * @return array + */ + public static function get_config_submissionplugins_site_strings() { + $fieldsandstrings = []; + + // No assign object, so get all submission plugins. + $pluginmanager = \core_plugin_manager::instance(); + $submissionplugins = $pluginmanager->get_plugins_of_type('assignsubmission'); + + $configplugins = self::get_config_submissionplugins(); + foreach ($submissionplugins as $plugin) { + if ($plugin->is_enabled() && in_array($plugin->name, $configplugins)) { + $fieldsandstrings[$plugin->name] = $plugin->displayname; + } + } + + return $fieldsandstrings; + } + /** * can the user view the data submitted * some checks @@ -250,9 +323,8 @@ public static function get_submission_data( $submissiondata = []; $submissionfields = self::get_config_submissionfields_strings(); - if ($usersubmission) { + if ($usersubmission && $assign->has_submissions_or_grades()) { $userid = $submission->id; - $gradeitem = $assign->get_grade_item(); $grade = $assign->get_user_grade($userid, false); $gradevalue = empty($grade) ? null : $grade->grade; @@ -329,6 +401,61 @@ public static function get_submission_data( return $submissiondata; } + /** + * Get data for submission plugins. + * @param object $assign + * @param object $submission + * @param object $usersubmission + * @param object $filesubmission + * @param boolean $exportall + * @return mixed + */ + public static function get_submissionplugin_data( + $assign, $submission, $usersubmission, $filesubmission, $exportall + ) { + $submissionpluginsdata = []; + $submissionplugins = self::get_config_submissionplugins_assign($assign); + + if ($exportall) { + // When exporting all, ensure data columns align with header columns, by + // ensuring all submissions have at least a placeholder for each plugin type. + $configplugins = self::get_config_submissionplugins(); + foreach ($configplugins as $fieldid) { + $submissionpluginsdata[$fieldid] = '-'; + } + } + + if ($usersubmission && $assign->has_submissions_or_grades()) { + $userid = $submission->id; + $gradeitem = $assign->get_grade_item(); + $grade = $assign->get_user_grade($userid, false); + $gradevalue = empty($grade) ? null : $grade->grade; + + foreach ($submissionplugins as $fieldid => $plugin) { + if ($plugin->is_empty($usersubmission)) { + $submissionpluginsdata[$fieldid] = '-'; + } else { + switch ($fieldid) { + case 'file': + $submissionpluginsdata['file'] = self::get_submission_files( + $assign, $filesubmission, $usersubmission, $userid + ); + break; + default: + $submissionpluginsdata[$fieldid] = trim(html_to_text($plugin->view($usersubmission))); + } + } + } + } else { + // No submission. + foreach ($submissionplugins as $fieldid => $plugin) { + $submissionpluginsdata[$fieldid] = '-'; + } + } + + return $submissionpluginsdata; + } + /** * Get file submission plugin * and check it is enabled @@ -661,12 +788,13 @@ private static function get_workflow($userflags) { /** * Add assignment data * @param int $assid - * @param object $dm + * @param object $cm * @param assign $assign * @param array $submissions + * @param boolean $exportall * @return array */ - public static function add_assignment_data($courseid, $assid, $cm, $assign, $submissions) { + public static function add_assignment_data($courseid, $assid, $cm, $assign, $submissions, $exportall = false) { $cmid = $cm->id; // Report date format. @@ -675,7 +803,9 @@ public static function add_assignment_data($courseid, $assid, $cm, $assign, $sub // Submission fields selected in preferences. $submissionfields = self::get_config_submissionfields(); - // Get sub plugins. + // Submission plugin fields. + $submissionplugins = self::get_config_submissionplugins($assign); + $filesubmission = self::get_submission_plugin_files($assign); // Get instance. @@ -733,13 +863,15 @@ public static function add_assignment_data($courseid, $assid, $cm, $assign, $sub list($submission->groups, $submission->groupids) = self::get_user_groups($userid, $courseid); $submission->urkund = self::get_urkund_score($assid, $cmid, $userid); $submission->turnitin = self::get_turnitin_score($assid, $cmid, $userid); - $submission->files = self::get_submission_files($assign, $filesubmission, $usersubmission, $userid); $submission->profiledata = self::get_profile_data($profilefields, $submission); $submission->isprofiledata = count($profilefields) != 0; $submission->submissiondata = self::get_submission_data( $assign, $submission, $instance, $usersubmission, $userflags, $dateformat ); $submission->submissiondata['released'] = $released; + $submission->submissionplugindata = self::get_submissionplugin_data( + $assign, $submission, $usersubmission, $filesubmission, $exportall + ); // User fields. $profilefields = explode(',', get_config('report_assign', 'profilefields')); @@ -831,10 +963,13 @@ public static function turnitin_enabled($assignmentid) { * @param string $filename * @param array $submissions */ - public static function export($assignment, $filename, $submissions) { + public static function export($assign, $filename, $submissions) { global $CFG; require_once($CFG->dirroot.'/lib/excellib.class.php'); + // Get instance. + $assignment = $assign->get_instance(); + // Profile fields. $profilefields = []; $fields = get_config('report_assign', 'profilefields'); @@ -845,6 +980,9 @@ public static function export($assignment, $filename, $submissions) { // Submission fields. $submissionfields = self::get_config_submissionfields_strings(); + // Submission plugin fields. + $submissionplugins = self::get_config_submissionplugins_assign_strings($assign); + // Field options pref. $fieldoptions = self::get_field_options(); $splitusername = !empty($fieldoptions['splitusername']); @@ -883,6 +1021,9 @@ public static function export($assignment, $filename, $submissions) { foreach ($submissionfields as $fieldid => $fieldstring) { $myxls->write_string(3, $i++, $fieldstring); } + foreach ($submissionplugins as $fieldid => $fieldstring) { + $myxls->write_string(3, $i++, $fieldstring); + } if ($urkundenabled = self::urkund_enabled($assignment->id)) { $myxls->write_string(3, $i++, get_string('urkund', 'report_assign')); } @@ -893,7 +1034,6 @@ public static function export($assignment, $filename, $submissions) { $myxls->write_string(3, $i++, get_string('workflow', 'report_assign')); $myxls->write_string(3, $i++, get_string('allocatedmarker', 'report_assign')); } - $myxls->write_string(3, $i++, get_string('files')); // Add some data. $row = 4; @@ -922,6 +1062,9 @@ public static function export($assignment, $filename, $submissions) { if (!empty($s->extensionduedate)) { $myxls->write_string($row, $i++, $s->extensionduedate); } + foreach ($s->submissionplugindata as $value) { + $myxls->write_string($row, $i++, $value); + } if ($urkundenabled) { $urkundscore = empty($s->urkund->similarityscore) ? '-' : $s->urkund->similarityscore; $myxls->write_string($row, $i++, $urkundscore); @@ -934,7 +1077,6 @@ public static function export($assignment, $filename, $submissions) { $myxls->write_string($row, $i++, $s->workflow); $myxls->write_string($row, $i++, $s->marker); } - $myxls->write_string($row, $i++, $s->files); $row++; } $workbook->close(); @@ -956,13 +1098,17 @@ public static function exportall($filename, $submissions) { // Submission fields. $submissionfields = self::get_config_submissionfields_strings(); + // Submission plugin fields. + $submissionplugins = self::get_config_submissionplugins_site_strings(); + // Field options pref. $fieldoptions = self::get_field_options(); $splitusername = !empty($fieldoptions['splitusername']); // Plagiarism plugins? - $isturnitin = !empty(\core_plugin_manager::instance()->get_plugin_info('plagiarism_turnitin')); - $isurkund = !empty(\core_plugin_manager::instance()->get_plugin_info('plagiarism_urkund')); + $p = $CFG->enableplagiarism; + $isturnitin = $p && !empty(\core_plugin_manager::instance()->get_plugin_info('plagiarism_turnitin')); + $isurkund = $p && !empty(\core_plugin_manager::instance()->get_plugin_info('plagiarism_urkund')); $workbook = new \MoodleExcelWorkbook("-"); @@ -992,6 +1138,9 @@ public static function exportall($filename, $submissions) { foreach ($submissionfields as $fieldid => $fieldstring) { $myxls->write_string(1, $i++, $fieldstring); } + foreach ($submissionplugins as $fieldid => $fieldstring) { + $myxls->write_string(1, $i++, $fieldstring); + } if ($isurkund) { $myxls->write_string(1, $i++, get_string('urkund', 'report_assign')); } @@ -999,7 +1148,6 @@ public static function exportall($filename, $submissions) { $myxls->write_string(1, $i++, get_string('turnitin', 'report_assign')); } $myxls->write_string(1, $i++, get_string('allocatedmarker', 'report_assign')); - $myxls->write_string(1, $i++, get_string('files')); // Add some data. $row = 2; @@ -1027,6 +1175,9 @@ public static function exportall($filename, $submissions) { if (!empty($s->extensionduedate)) { $myxls->write_string($row, $i++, $s->extensionduedate); } + foreach ($s->submissionplugindata as $value) { + $myxls->write_string($row, $i++, $value); + } if ($isurkund) { $myxls->write_string($row, $i++, isset($s->urkund->similarityscore) ? $s->urkund->similarityscore : '-'); } @@ -1034,7 +1185,6 @@ public static function exportall($filename, $submissions) { $myxls->write_string($row, $i++, isset($s->turnitin->similarityscore) ? $s->turnitin->similarityscore : '-'); } $myxls->write_string($row, $i++, isset($s->grader) ? $s->grader : '-'); - $myxls->write_string($row, $i++, $s->files); $row++; } $workbook->close(); diff --git a/classes/output/reportassign.php b/classes/output/reportassign.php index 2228dab..e72fc26 100755 --- a/classes/output/reportassign.php +++ b/classes/output/reportassign.php @@ -87,10 +87,13 @@ public function export_for_template(renderer_base $output) { // Get submission field headers. $submissionfields = \report_assign\lib::get_config_submissionfields_strings(); + // Get submission plugin headers. + $submissionplugins = \report_assign\lib::get_config_submissionplugins_assign_strings($this->assign); // Convert submission data from associative keys to indexed for template. $submissions = array_values($this->submissions); foreach ($submissions as $submission) { $submission->submissiondata = array_values($submission->submissiondata); + $submission->submissionplugindata = array_values($submission->submissionplugindata); } return [ @@ -107,6 +110,8 @@ public function export_for_template(renderer_base $output) { 'groups' => array_values($groups), 'submissionfieldsenabled' => count($submissionfields), 'submissionfields' => array_values($submissionfields), + 'submissionpluginsenabled' => count($submissionplugins), + 'submissionplugins' => array_values($submissionplugins), 'profilefields' => $this->get_profilefields(), 'blindmarking' => $this->assignment->blindmarking, 'extensionsok' => $this->extensionsok, diff --git a/index.php b/index.php index ba80141..5ba434a 100644 --- a/index.php +++ b/index.php @@ -81,7 +81,7 @@ //$assignment = $DB->get_record('assign', ['id' => $assignid], '*', MUST_EXIST); $submissions = $assign->list_participants_with_filter_status_and_group(0); $cm = get_coursemodule_from_instance('assign', $assignid); - $submissions = report_assign\lib::add_assignment_data($course->id, $assignid, $cm, $assign, $submissions); + $submissions = report_assign\lib::add_assignment_data($course->id, $assignid, $cm, $assign, $submissions, $exportall); foreach ($submissions as $submission) { $submission->assignmentname = $assignment->name; $submission->duedate = empty($assignment->duedate) ? '-' : userdate($assignment->duedate, get_string('strftimedatetimeshort', 'langconfig')); @@ -146,7 +146,7 @@ if ($export) { $filename = "assign_{$assignment->name}.xls"; - report_assign\lib::export($assignment, $filename, $submissions); + report_assign\lib::export($assign, $filename, $submissions); // Trigger an assignment viewed event. $event = \report_assign\event\assignment_export::create([ diff --git a/lang/en/report_assign.php b/lang/en/report_assign.php index 5eca0db..753b318 100644 --- a/lang/en/report_assign.php +++ b/lang/en/report_assign.php @@ -83,6 +83,8 @@ $string['statussubmitted'] = 'submitted'; $string['submissionfields'] = 'Submission fields'; $string['submissionfields_desc'] = 'Include these submission fields in the report'; +$string['submissionplugins'] = 'Submission plugins'; +$string['submissionplugins_desc'] = 'Include information from these submission plugins in the report. (Plagiarism plugins are included separately)'; $string['submissions'] = 'Submissions'; $string['submitdate'] = 'Submit date'; $string['submitted'] = 'Submitted'; diff --git a/settings.php b/settings.php index af7baaa..3a67d95 100755 --- a/settings.php +++ b/settings.php @@ -75,6 +75,29 @@ $submissionfields )); + $pluginmanager = \core_plugin_manager::instance(); + // Selector for submission plugins. + $submissionplugins = $pluginmanager->get_plugins_of_type('assignsubmission'); + $submissionpluginfields = []; + foreach ($submissionplugins as $plugin) { + if ($plugin->name == 'comments') { + // Submission comments don't work like other plugins. + // It's not currently needed, so skip it. + continue; + } + if ($plugin->is_enabled()) { + $submissionpluginfields[$plugin->name] = $plugin->displayname; + } + } + + $settings->add(new admin_setting_configmulticheckbox( + 'report_assign/submissionplugins', + new lang_string('submissionplugins', 'report_assign'), + new lang_string('submissionplugins_desc', 'report_assign'), + ["file" => 1, "plagiarism_turnitin" => 1, "plagiarism_urkund" => 1], + $submissionpluginfields + )); + // Selector for field options. $rawchoices = [ 'splitusername', diff --git a/templates/reportassign.mustache b/templates/reportassign.mustache index 0623948..b867640 100755 --- a/templates/reportassign.mustache +++ b/templates/reportassign.mustache @@ -36,6 +36,9 @@ {{# submissionfields }} {{/ submissionfields }} + {{# submissionplugins }} + + {{/ submissionplugins }} {{# groupselect }} {{/ groupselect }} @@ -49,7 +52,6 @@ {{/ assignment.markingallocation }} - @@ -87,6 +89,11 @@ {{/ extensionduedate }} {{/ submissionfieldsenabled }} + {{# submissionpluginsenabled }} + {{# submissionplugindata }} + + {{/ submissionplugindata }} + {{/ submissionpluginsenabled }} {{# urkundenabled }} {{/ assignment.markingallocation }} - {{/ submissions }} From 7d5d45a2df08221d87232f8904d97cda34c73b2e Mon Sep 17 00:00:00 2001 From: David Balch Date: Tue, 11 Aug 2020 15:11:14 +0100 Subject: [PATCH 7/8] Add a placholder function for debugging. Trying to track down which field is getting an extra column can be pretty frustrating if there's no data that can be used to identify the field - when it's just the '-' empty value placeholder. Change false to true in the placeholder() function and it will put field ids in for many (not all) placeholders. --- changelog.md | 1 + classes/lib.php | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index d74e52e..1e63f04 100755 --- a/changelog.md +++ b/changelog.md @@ -34,3 +34,4 @@ Converted submission fields to a preference, adding options for: - submission lateness (including extensions) NB: This has changed the field order in the columns. Converted File submission fields to a preference with all enabled submission plugins. +Added a placeholder() function for debugging; identifying which field a placeholder is for. diff --git a/classes/lib.php b/classes/lib.php index 772e462..fc89ca0 100644 --- a/classes/lib.php +++ b/classes/lib.php @@ -37,6 +37,21 @@ class lib { + /** + * Give placeholder text, or the field id if debugging. + * @param string $fieldid + * @return string + */ + private static function placeholder($fieldid) { + + // Only set to true for debugging. + if (false) { + return "[placeholder: $fieldid]"; + } else { + return '-'; + } + } + /** * get blind assignments for this course * @param int $id course id @@ -346,7 +361,7 @@ public static function get_submission_data( $gradevalue = $grade->grade; } if ($gradevalue == -1 || $gradevalue === null) { - $gradevalue = '-'; + $gradevalue = self::placeholder($fieldid); } else { $gradevalue = grade_format_gradevalue($grade->grade, $gradeitem); } @@ -371,7 +386,7 @@ public static function get_submission_data( $latemessage = get_string('submittedlateshort', 'assign', $usertime); $submissiondata['latenessincext'] = $latemessage; } else { - $submissiondata['latenessincext'] = '-'; + $submissiondata['latenessincext'] = self::placeholder($fieldid); } break; case 'extension': @@ -393,7 +408,7 @@ public static function get_submission_data( foreach ($submissionfields as $fieldid => $fieldstring) { if ($fieldid != 'extension') { // Skip extension, which is handled directly in add_assignment_data(). - $submissiondata[$fieldid] = '-'; + $submissiondata[$fieldid] = self::placeholder($fieldid); } } } @@ -421,7 +436,7 @@ public static function get_submissionplugin_data( // ensuring all submissions have at least a placeholder for each plugin type. $configplugins = self::get_config_submissionplugins(); foreach ($configplugins as $fieldid) { - $submissionpluginsdata[$fieldid] = '-'; + $submissionpluginsdata[$fieldid] = self::placeholder($fieldid); } } @@ -433,7 +448,7 @@ public static function get_submissionplugin_data( foreach ($submissionplugins as $fieldid => $plugin) { if ($plugin->is_empty($usersubmission)) { - $submissionpluginsdata[$fieldid] = '-'; + $submissionpluginsdata[$fieldid] = self::placeholder($fieldid); } else { switch ($fieldid) { case 'file': @@ -449,7 +464,7 @@ public static function get_submissionplugin_data( } else { // No submission. foreach ($submissionplugins as $fieldid => $plugin) { - $submissionpluginsdata[$fieldid] = '-'; + $submissionpluginsdata[$fieldid] = self::placeholder($fieldid); } } From 8cbed7b6e02c51f9235c4a602bdfdaff4f13be1f Mon Sep 17 00:00:00 2001 From: David Balch Date: Tue, 11 Aug 2020 16:20:42 +0100 Subject: [PATCH 8/8] Add option to include course idnumber. Includes framework to adding more course fields easy. --- changelog.md | 1 + classes/lib.php | 82 +++++++++++++++++++++++++++++++++ classes/output/reportassign.php | 6 +++ lang/en/report_assign.php | 2 + settings.php | 13 ++++++ templates/reportassign.mustache | 8 ++++ 6 files changed, 112 insertions(+) diff --git a/changelog.md b/changelog.md index 1e63f04..12b8f0f 100755 --- a/changelog.md +++ b/changelog.md @@ -35,3 +35,4 @@ Converted submission fields to a preference, adding options for: NB: This has changed the field order in the columns. Converted File submission fields to a preference with all enabled submission plugins. Added a placeholder() function for debugging; identifying which field a placeholder is for. +Added course fields preference, for including more course info. (Only includes idnumber so far). diff --git a/classes/lib.php b/classes/lib.php index fc89ca0..2ed2b98 100644 --- a/classes/lib.php +++ b/classes/lib.php @@ -202,6 +202,69 @@ public static function get_config_submissionplugins_site_strings() { return $fieldsandstrings; } + /** + * Get course field choices from coursefields config. + * @return array + */ + public static function get_config_coursefields() { + $fields = []; + $configstr = get_config('report_assign', 'coursefields'); + + if ($configstr != '') { + $fields = explode(',', $configstr); + } + + return $fields; + } + + /** + * Get field choices from coursefields config, with strings. + * TODO: Add support for custom course fields. + * @return array + */ + public static function get_config_coursefields_strings() { + $fieldsandstrings = []; + $configfields = self::get_config_coursefields(); + + foreach ($configfields as $field) { + switch ($field) { + case 'idnumber': + $fieldsandstrings[$field] = get_string('idnumbercourse'); + break; + default: + $fieldsandstrings[$field] = get_string($field); + } + } + + return $fieldsandstrings; + } + + /** + * Get course config choices from coursefields config. + * @param int $courseid + * @return array + */ + public static function get_course_data($courseid) { + global $DB; + + $coursedata = []; + $configstr = get_config('report_assign', 'coursefields'); + + if (!empty($configstr)) { + $configfields = self::get_config_coursefields(); + $record = $DB->get_record('course', ['id' => $courseid], $configstr); + foreach ($configfields as $field) { + if (empty($record->$field)) { + $coursedata[$field] = self::placeholder('courseid'); + } else { + $coursedata[$field] = $record->$field; + } + } + } + + return $coursedata; + } + /** * can the user view the data submitted * some checks @@ -837,6 +900,7 @@ public static function add_assignment_data($courseid, $assid, $cm, $assign, $sub $canrevealnames = $instance->revealidentities || has_capability('report/assign:shownames', $context); foreach ($submissions as $submission) { + $submission->coursedata = self::get_course_data($courseid); $userid = $submission->id; $coursegrade = grade_get_grades($courseid, 'mod', 'assign', $cm->instance, $userid); $gradeinstance = reset($coursegrade->items[0]->grades); @@ -985,6 +1049,9 @@ public static function export($assign, $filename, $submissions) { // Get instance. $assignment = $assign->get_instance(); + // Course fields. + $coursefields = self::get_config_coursefields_strings('coursefields'); + // Profile fields. $profilefields = []; $fields = get_config('report_assign', 'profilefields'); @@ -1020,6 +1087,9 @@ public static function export($assign, $filename, $submissions) { // Headers. $i = 0; $myxls->write_string(3, $i++, '#'); + foreach ($coursefields as $fieldid => $fieldstring) { + $myxls->write_string(3, $i++, $fieldstring); + } if ($splitusername) { $myxls->write_string(3, $i++, get_string('firstname')); $myxls->write_string(3, $i++, get_string('lastname')); @@ -1056,6 +1126,9 @@ public static function export($assign, $filename, $submissions) { foreach ($submissions as $s) { $i = 0; $myxls->write_number($row, $i++, $linecount++); + foreach ($s->coursedata as $value) { + $myxls->write_string($row, $i++, $value); + } if ($splitusername) { $myxls->write_string($row, $i++, $s->firstname); $myxls->write_string($row, $i++, $s->lastname); @@ -1106,6 +1179,9 @@ public static function exportall($filename, $submissions) { global $CFG; require_once($CFG->dirroot.'/lib/excellib.class.php'); + // Course fields. + $coursefields = self::get_config_coursefields_strings('coursefields'); + // Profile fields. $fields = get_config('report_assign', 'profilefields'); $profilefields = explode(',', $fields); @@ -1136,6 +1212,9 @@ public static function exportall($filename, $submissions) { // Headers. $i = 0; $myxls->write_string(1, $i++, '#'); + foreach ($coursefields as $fieldid => $fieldstring) { + $myxls->write_string(1, $i++, $fieldstring); + } $myxls->write_string(1, $i++, get_string('assignmentname', 'report_assign')); if ($splitusername) { $myxls->write_string(1, $i++, get_string('firstname')); @@ -1170,6 +1249,9 @@ public static function exportall($filename, $submissions) { foreach ($submissions as $s) { $i = 0; $myxls->write_number($row, $i++, $linecount++); + foreach ($s->coursedata as $value) { + $myxls->write_string($row, $i++, $value); + } $myxls->write_string($row, $i++, $s->assignmentname); if ($splitusername) { $myxls->write_string($row, $i++, $s->firstname); diff --git a/classes/output/reportassign.php b/classes/output/reportassign.php index e72fc26..b2816cf 100755 --- a/classes/output/reportassign.php +++ b/classes/output/reportassign.php @@ -89,11 +89,15 @@ public function export_for_template(renderer_base $output) { $submissionfields = \report_assign\lib::get_config_submissionfields_strings(); // Get submission plugin headers. $submissionplugins = \report_assign\lib::get_config_submissionplugins_assign_strings($this->assign); + // Get course field headers. + $coursefields = \report_assign\lib::get_config_coursefields_strings('coursefields'); + // Convert submission data from associative keys to indexed for template. $submissions = array_values($this->submissions); foreach ($submissions as $submission) { $submission->submissiondata = array_values($submission->submissiondata); $submission->submissionplugindata = array_values($submission->submissionplugindata); + $submission->coursedata = array_values($submission->coursedata); } return [ @@ -116,6 +120,8 @@ public function export_for_template(renderer_base $output) { 'blindmarking' => $this->assignment->blindmarking, 'extensionsok' => $this->extensionsok, 'fieldoptions' => $fieldoptions, + 'coursefieldsenabled' => count($coursefields), + 'coursefields' => array_values($coursefields), ]; } diff --git a/lang/en/report_assign.php b/lang/en/report_assign.php index 753b318..9f7e070 100644 --- a/lang/en/report_assign.php +++ b/lang/en/report_assign.php @@ -34,6 +34,8 @@ $string['assignmentname'] = 'Assignment name'; $string['blindmarkingon'] = 'Blind marking on'; $string['byuser'] = 'By (user)'; +$string['coursefields'] = 'Course fields'; +$string['coursefields_desc'] = 'Include fields from the course record'; $string['created'] = 'Created'; $string['duedate'] = 'Due date'; $string['dumpfiles'] = 'Dump files'; diff --git a/settings.php b/settings.php index 3a67d95..65e5c50 100755 --- a/settings.php +++ b/settings.php @@ -98,6 +98,19 @@ $submissionpluginfields )); + // Selector for course options. + $coursefields = [ + "idnumber" => new lang_string('idnumbercourse'), + ]; + + $settings->add(new admin_setting_configmulticheckbox( + 'report_assign/coursefields', + new lang_string('coursefields', 'report_assign'), + new lang_string('coursefields_desc', 'report_assign'), + [], + $coursefields + )); + // Selector for field options. $rawchoices = [ 'splitusername', diff --git a/templates/reportassign.mustache b/templates/reportassign.mustache index b867640..2421a0a 100755 --- a/templates/reportassign.mustache +++ b/templates/reportassign.mustache @@ -20,6 +20,9 @@
{{# str }}name{{/ str }}{{# str }}firstname{{/ str }}{{# str }}lastname{{/ str }}{{# str }}name{{/ str }}{{# str }}participantno, report_assign{{/ str }}
{{ fullname }}{{ firstname }}{{ lastname }}{{ fullname }}{{ participantno }}{{{ . }}}{{{ . }}}{{# str }}groups{{/ str }}{{# str }}status{{/ str }}{{# str }}grade, report_assign{{/ str }}{{# str }}urkund, report_assign{{/ str }}{{# str }}workflow, report_assign{{/ str }} {{# str }}allocatedmarker, report_assign{{/ str }}{{# str }}grader, report_assign{{/ str }}{{# str }}modified{{/ str }}{{# str }}released, report_assign{{/ str }}{{# str }}extension, report_assign{{/ str }} {{# str }}files{{/ str }}   {{ groups }}{{ status }}{{{ grade }}}{{ . }}{{ extensionduedate }} + {{# extensionsok }} + + + + {{/ extensionsok}} + {{# urkund }} @@ -96,16 +105,6 @@ {{ workflow }} {{ marker }}{{ grader }}{{ modified }}{{ released }}{{ extensionduedate }} - {{# extensionsok }} - - - - {{/ extensionsok}} - {{ files }} {{# str }}log, report_assign{{/ str }}
{{{ . }}}{{{ . }}}{{# str }}groups{{/ str }}{{# str }}workflow, report_assign{{/ str }} {{# str }}allocatedmarker, report_assign{{/ str }}{{# str }}files{{/ str }}  
{{ . }} {{# urkund }} @@ -105,7 +112,6 @@ {{ workflow }} {{ marker }}{{ files }} {{# str }}log, report_assign{{/ str }}
+ {{# coursefields }} + + {{/ coursefields }} {{# fieldoptions.splitusername }} @@ -57,6 +60,11 @@ {{# submissions }} + {{# coursefieldsenabled }} + {{# coursedata }} + + {{/ coursedata }} + {{/ coursefieldsenabled }} {{# fieldoptions.splitusername }}
{{{ . }}}{{# str }}firstname{{/ str }} {{# str }}lastname{{/ str }}
{{ . }}{{ firstname }} {{ lastname }}