diff --git a/mod/lesson/lang/en/lesson.php b/mod/lesson/lang/en/lesson.php index dcdc50c35ef..528c7ea9028 100644 --- a/mod/lesson/lang/en/lesson.php +++ b/mod/lesson/lang/en/lesson.php @@ -73,6 +73,8 @@ $string['answersfornumerical'] = 'Answers for numerical questions should be matc $string['arrangebuttonshorizontally'] = 'Arrange content buttons horizontally?'; $string['attempt'] = 'Attempt: {$a}'; $string['attemptheader'] = 'Attempt'; +$string['attemptinfonograde'] = '{$a->timestart} ({$a->duration})'; +$string['attemptinfowithgrade'] = '{$a->grade}% {$a->timestart} ({$a->duration})'; $string['attempts'] = 'Attempts'; $string['attemptsdeleted'] = 'Deleted attempts'; $string['attemptsremaining'] = 'You have {$a} attempt(s) remaining'; @@ -151,6 +153,7 @@ $string['deletingpage'] = 'Deleting page: {$a}'; $string['dependencyon'] = 'Dependent on'; $string['dependencyon_help'] = 'This setting allows access to this lesson to be dependent upon a student\'s performance in another lesson in the same course. Any combination of time spent, completed or "grade better than" may be used.'; $string['description'] = 'Description'; +$string['deselectallattempts'] = 'Deselect all attempts'; $string['detailedstats'] = 'Detailed statistics'; $string['didnotanswerquestion'] = 'Did not answer this question.'; $string['didnotreceivecredit'] = 'Did not receive credit'; @@ -374,6 +377,7 @@ $string['nooverridedata'] = 'You must override at least one of the lesson settin $string['noretake'] = 'You are not allowed to retake this lesson.'; $string['normal'] = 'Normal - follow lesson path'; $string['notcompleted'] = 'Not completed'; +$string['notcompletedwithdate'] = 'Not completed ({$a})'; $string['notyetcompleted'] = 'Lesson has been started, but not yet completed'; $string['notdefined'] = 'Not defined'; $string['notenoughsubquestions'] = 'Not enough sub-questions have been defined!'; @@ -520,6 +524,7 @@ $string['scores'] = 'Scores'; $string['search:activity'] = 'Lesson - activity information'; $string['secondpluswrong'] = 'Not quite. Would you like to try again?'; $string['selectaqtype'] = 'Select a question type'; +$string['selectallattempts'] = 'Select all attempts'; $string['sent'] = 'Sent'; $string['shortanswer'] = 'Short answer'; $string['showanunansweredpage'] = 'Show an unanswered page'; @@ -578,6 +583,7 @@ $string['viewreports2'] = 'View {$a} completed attempts'; $string['warning'] = 'Warning'; $string['welldone'] = 'Well done!'; $string['whatdofirst'] = 'What would you like to do first?'; +$string['withselectedattempts'] = 'With selected attempts...'; $string['wronganswerjump'] = 'Wrong answer jump'; $string['wronganswerscore'] = 'Wrong answer score'; $string['wrongresponse'] = 'Wrong response'; diff --git a/mod/lesson/locallib.php b/mod/lesson/locallib.php index a12beefe80e..812c5c8ee4f 100644 --- a/mod/lesson/locallib.php +++ b/mod/lesson/locallib.php @@ -686,7 +686,7 @@ function lesson_process_group_deleted_in_course($courseid, $groupid = null) { * @since Moodle 3.3 */ function lesson_get_overview_report_table_and_data(lesson $lesson, $currentgroup) { - global $DB, $CFG; + global $DB, $CFG, $OUTPUT; require_once($CFG->dirroot . '/mod/lesson/pagetypes/branchtable.php'); $context = $lesson->context; @@ -902,7 +902,25 @@ function lesson_get_overview_report_table_and_data(lesson $lesson, $currentgroup $headers[] = get_user_field_name($field); } - $headers [] = get_string('attempts', 'lesson'); + $caneditlesson = has_capability('mod/lesson:edit', $context); + $attemptsheader = get_string('attempts', 'lesson'); + if ($caneditlesson) { + $selectall = get_string('selectallattempts', 'lesson'); + $deselectall = get_string('deselectallattempts', 'lesson'); + // Build the select/deselect all control. + $selectallid = 'selectall-attempts'; + $mastercheckbox = new \core\output\checkbox_toggleall('lesson-attempts', true, [ + 'id' => $selectallid, + 'name' => $selectallid, + 'value' => 1, + 'label' => $selectall, + 'selectall' => $selectall, + 'deselectall' => $deselectall, + 'labelclasses' => 'form-check-label' + ]); + $attemptsheader = $OUTPUT->render($mastercheckbox); + } + $headers [] = $attemptsheader; // Set up the table object. if ($data->lessonscored) { @@ -924,7 +942,7 @@ function lesson_get_overview_report_table_and_data(lesson $lesson, $currentgroup $table->wrap = []; $table->wrap = array_pad($table->wrap, $colcount, 'nowrap'); - $table->attributes['class'] = 'standardtable generaltable'; + $table->attributes['class'] = 'table table-striped'; // print out the $studentdata array // going through each student that has attempted the lesson, so, each student should have something to be displayed @@ -937,7 +955,7 @@ function lesson_get_overview_report_table_and_data(lesson $lesson, $currentgroup $dataforstudent->attempts = array(); // gather the data for each user attempt $bestgrade = 0; - $bestgradefound = false; + // $tries holds all the tries/retries a student has done $tries = $studentdata[$student->id]; $studentname = fullname($student, true); @@ -946,44 +964,65 @@ function lesson_get_overview_report_table_and_data(lesson $lesson, $currentgroup $dataforstudent->attempts[] = $try; // Start to build up the checkbox and link. - if (has_capability('mod/lesson:edit', $context)) { - $temp = ' '; - } else { - $temp = ''; - } + $attempturlparams = [ + 'id' => $cm->id, + 'action' => 'reportdetail', + 'userid' => $try['userid'], + 'try' => $try['try'], + ]; - $temp .= "id&action=reportdetail&userid=".$try['userid'] - .'&try='.$try['try'].'" class="lesson-attempt-link">'; if ($try["grade"] !== null) { // if null then not done yet // this is what the link does when the user has completed the try $timetotake = $try["timeend"] - $try["timestart"]; - $temp .= $try["grade"]."%"; - $bestgradefound = true; if ($try["grade"] > $bestgrade) { $bestgrade = $try["grade"]; } - $temp .= " ".userdate($try["timestart"]); - $temp .= ", (".format_time($timetotake).")"; + + $attemptdata = (object)[ + 'grade' => $try["grade"], + 'timestart' => userdate($try["timestart"]), + 'duration' => format_time($timetotake), + ]; + $attemptlinkcontents = get_string('attemptinfowithgrade', 'lesson', $attemptdata); + } else { if ($try["end"]) { // User finished the lesson but has no grade. (Happens when there are only content pages). - $temp .= " ".userdate($try["timestart"]); $timetotake = $try["timeend"] - $try["timestart"]; - $temp .= ", (".format_time($timetotake).")"; + $attemptdata = (object)[ + 'timestart' => userdate($try["timestart"]), + 'duration' => format_time($timetotake), + ]; + $attemptlinkcontents = get_string('attemptinfonograde', 'lesson', $attemptdata); } else { // This is what the link does/looks like when the user has not completed the attempt. - $temp .= get_string("notcompleted", "lesson"); if ($try['timestart'] !== 0) { // Teacher previews do not track time spent. - $temp .= " ".userdate($try["timestart"]); + $attemptlinkcontents = get_string("notcompletedwithdate", "lesson", userdate($try["timestart"])); + } else { + $attemptlinkcontents = get_string("notcompleted", "lesson"); } - $temp .= ""; $timetotake = null; } } + $attempturl = new moodle_url('/mod/lesson/report.php', $attempturlparams); + $attemptlink = html_writer::link($attempturl, $attemptlinkcontents, ['class' => 'lesson-attempt-link']); + + if ($caneditlesson) { + $attemptid = 'attempt-' . $try['userid'] . '-' . $try['try']; + $attemptname = 'attempts[' . $try['userid'] . '][' . $try['try'] . ']'; + + $checkbox = new \core\output\checkbox_toggleall('lesson-attempts', false, [ + 'id' => $attemptid, + 'name' => $attemptname, + 'label' => $attemptlink + ]); + $attemptlink = $OUTPUT->render($checkbox); + } + // build up the attempts array - $attempts[] = $temp; + $attempts[] = $attemptlink; // Run these lines for the stats only if the user finnished the lesson. if ($try["end"]) { diff --git a/mod/lesson/report.php b/mod/lesson/report.php index 4f289718a4e..4fd027a8a4a 100644 --- a/mod/lesson/report.php +++ b/mod/lesson/report.php @@ -139,39 +139,51 @@ if ($action === 'delete') { echo $OUTPUT->box($seeallgradeslink, 'allcoursegrades'); } - // Print it all out! + // The attempts table. + $attemptstable = html_writer::table($table); + + // The HTML that we will be displaying which includes the attempts table and bulk actions menu, if necessary. + $attemptshtml = $attemptstable; + + // Show bulk actions when user has capability to edit the lesson. if (has_capability('mod/lesson:edit', $context)) { - echo "
\n - \n - id\" />\n"; + $reporturl = new moodle_url('/mod/lesson/report.php'); + $formid = 'mod-lesson-report-form'; + + // Sesskey hidden input. + $formcontents = html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()]); + + // CMID hidden input. + $formcontents .= html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'id', 'value' => $cm->id]); + + // Attempts table. + $formcontents .= $attemptstable; + + // Bulk actions menu. + $attemptsactions = [ + 'delete' => get_string('deleteselected') + ]; + $bulkactions = new single_select($reporturl, 'action', $attemptsactions, '', ['' => 'choosedots'], $formid); + $bulkactions->set_label(get_string('withselectedattempts', 'lesson')); + $bulkactions->disabled = true; + $bulkactions->attributes = [ + 'data-action' => 'toggle', + 'data-togglegroup' => 'lesson-attempts', + 'data-toggle' => 'action', + ]; + $bulkactionshtml = $OUTPUT->render($bulkactions); + $formcontents .= $OUTPUT->box($bulkactionshtml, 'center'); + + // Build the attempts form. + $formattributes = [ + 'id' => $formid, + 'method' => 'post', + ]; + $attemptshtml = html_writer::tag('form', $formcontents, $formattributes); } - echo html_writer::table($table); - - if (has_capability('mod/lesson:edit', $context)) { - $checklinks = ''.get_string('selectall').' / '; - $checklinks .= ''.get_string('deselectall').''; - $checklinks .= html_writer::label('action', 'menuaction', false, array('class' => 'accesshide')); - $options = array('delete' => get_string('deleteselected')); - $attributes = array('id' => 'actionid', 'class' => 'custom-select ml-1'); - $checklinks .= html_writer::select($options, 'action', 0, array('' => 'choosedots'), $attributes); - $PAGE->requires->js_amd_inline(" - require(['jquery'], function($) { - $('#actionid').change(function() { - $('#mod-lesson-report-form').submit(); - }); - $('#checkall').click(function(e) { - $('#mod-lesson-report-form').find('input:checkbox').prop('checked', true); - e.preventDefault(); - }); - $('#checknone').click(function(e) { - $('#mod-lesson-report-form').find('input:checkbox').prop('checked', false); - e.preventDefault(); - }); - });"); - echo $OUTPUT->box($checklinks, 'center'); - echo '
'; - } + // Show the attempts HTML. + echo $attemptshtml; // Calculate the Statistics. if ($data->avetime == null) {