Merge branch 'MDL-57724-master' of git://github.com/jleyva/moodle

This commit is contained in:
David Monllao
2017-03-22 21:20:03 +01:00
7 changed files with 497 additions and 177 deletions
+113
View File
@@ -1537,4 +1537,117 @@ class mod_lesson_external extends external_api {
)
);
}
/**
* Describes the parameters for finish_attempt.
*
* @return external_external_function_parameters
* @since Moodle 3.3
*/
public static function finish_attempt_parameters() {
return new external_function_parameters (
array(
'lessonid' => new external_value(PARAM_INT, 'Lesson instance id.'),
'password' => new external_value(PARAM_RAW, 'Optional password (the lesson may be protected).', VALUE_DEFAULT, ''),
'outoftime' => new external_value(PARAM_BOOL, 'If the user run out of time.', VALUE_DEFAULT, false),
'review' => new external_value(PARAM_BOOL, 'If we want to review just after finishing (1 hour margin).',
VALUE_DEFAULT, false),
)
);
}
/**
* Finishes the current attempt.
*
* @param int $lessonid lesson instance id
* @param str $password optional password (the lesson may be protected)
* @param bool $outoftime optional if the user run out of time
* @param bool $review if we want to review just after finishing (1 hour margin)
* @return array of warnings and information about the finished attempt
* @since Moodle 3.3
* @throws moodle_exception
*/
public static function finish_attempt($lessonid, $password = '', $outoftime = false, $review = false) {
$params = array('lessonid' => $lessonid, 'password' => $password, 'outoftime' => $outoftime, 'review' => $review);
$params = self::validate_parameters(self::finish_attempt_parameters(), $params);
$warnings = array();
list($lesson, $course, $cm, $context) = self::validate_lesson($params['lessonid']);
// Update timer so the validation can check the time restrictions.
$timer = $lesson->update_timer();
// Return the validation to avoid exceptions in case the user is out of time.
$params['pageid'] = LESSON_EOL;
$validation = self::validate_attempt($lesson, $params, true);
if (array_key_exists('eolstudentoutoftime', $validation)) {
// Maybe we run out of time just now.
$params['outoftime'] = true;
unset($validation['eolstudentoutoftime']);
}
// Check if there are more errors.
if (!empty($validation)) {
reset($validation);
throw new moodle_exception(key($validation), 'lesson', '', current($validation)); // Throw first error.
}
$result = $lesson->process_eol_page($params['outoftime']);
// Return the data.
$validmessages = array(
'notenoughtimespent', 'numberofpagesviewed', 'youshouldview', 'numberofcorrectanswers',
'displayscorewithessays', 'displayscorewithoutessays', 'yourcurrentgradeisoutof', 'eolstudentoutoftimenoanswers',
'welldone', 'displayofgrade', 'reviewlesson', 'modattemptsnoteacher', 'progresscompleted');
$data = array();
foreach ($result as $el => $value) {
if ($value !== false) {
$message = '';
if (in_array($el, $validmessages)) { // Check if the data comes with an informative message.
$a = (is_bool($value)) ? null : $value;
$message = get_string($el, 'lesson', $a);
}
// Return the data.
$data[] = array(
'name' => $el,
'value' => (is_bool($value)) ? 1 : json_encode($value), // The data can be a php object.
'message' => $message
);
}
}
$result = array(
'data' => $data,
'messages' => self::format_lesson_messages($lesson),
'warnings' => $warnings,
);
return $result;
}
/**
* Describes the finish_attempt return value.
*
* @return external_single_structure
* @since Moodle 3.3
*/
public static function finish_attempt_returns() {
return new external_single_structure(
array(
'data' => new external_multiple_structure(
new external_single_structure(
array(
'name' => new external_value(PARAM_ALPHANUMEXT, 'Data name.'),
'value' => new external_value(PARAM_RAW, 'Data value.'),
'message' => new external_value(PARAM_RAW, 'Data message (translated string).'),
)
), 'The EOL page information data.'
),
'messages' => self::external_messages(),
'warnings' => new external_warnings(),
)
);
}
}
+8
View File
@@ -124,4 +124,12 @@ $functions = array(
'capabilities' => 'mod/lesson:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
'mod_lesson_finish_attempt' => array(
'classname' => 'mod_lesson_external',
'methodname' => 'finish_attempt',
'description' => 'Finishes the current attempt.',
'type' => 'write',
'capabilities' => 'mod/lesson:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
);
+192
View File
@@ -2790,6 +2790,198 @@ class lesson extends lesson_base {
$this->add_message(get_string('attemptsremaining', 'lesson', $result->attemptsremaining));
}
}
/**
* Process and return all the information for the end of lesson page.
*
* @param string $outoftime used to check to see if the student ran out of time
* @return stdclass an object with all the page data ready for rendering
* @since Moodle 3.3
*/
public function process_eol_page($outoftime) {
global $DB, $USER;
$course = $this->get_courserecord();
$cm = $this->get_cm();
$canmanage = $this->can_manage();
// Init all the possible fields and values.
$data = (object) array(
'gradelesson' => true,
'notenoughtimespent' => false,
'numberofpagesviewed' => false,
'youshouldview' => false,
'numberofcorrectanswers' => false,
'displayscorewithessays' => false,
'displayscorewithoutessays' => false,
'yourcurrentgradeisoutof' => false,
'eolstudentoutoftimenoanswers' => false,
'welldone' => false,
'progressbar' => false,
'displayofgrade' => false,
'reviewlesson' => false,
'modattemptsnoteacher' => false,
'activitylink' => false,
);
$ntries = $DB->count_records("lesson_grades", array("lessonid" => $this->properties->id, "userid" => $USER->id));
if (isset($USER->modattempts[$this->properties->id])) {
$ntries--; // Need to look at the old attempts :).
}
$gradeinfo = lesson_grade($this, $ntries);
$data->gradeinfo = $gradeinfo;
if ($this->properties->custom && !$canmanage) {
// Before we calculate the custom score make sure they answered the minimum
// number of questions. We only need to do this for custom scoring as we can
// not get the miniumum score the user should achieve. If we are not using
// custom scoring (so all questions are valued as 1) then we simply check if
// they answered more than the minimum questions, if not, we mark it out of the
// number specified in the minimum questions setting - which is done in lesson_grade().
// Get the number of answers given.
if ($gradeinfo->nquestions < $this->properties->minquestions) {
$data->gradelesson = false;
$a = new stdClass;
$a->nquestions = $gradeinfo->nquestions;
$a->minquestions = $this->properties->minquestions;
$this->add_message(get_string('numberofpagesviewednotice', 'lesson', $a));
}
}
if (!$canmanage) {
if ($data->gradelesson) {
// Store this now before any modifications to pages viewed.
$progresscompleted = $this->calculate_progress();
// Update the clock / get time information for this user.
$this->stop_timer();
// Update completion state.
$completion = new completion_info($course);
if ($completion->is_enabled($cm) && $this->properties->completionendreached) {
$completion->update_state($cm, COMPLETION_COMPLETE);
}
if ($this->properties->completiontimespent > 0) {
$duration = $DB->get_field_sql(
"SELECT SUM(lessontime - starttime)
FROM {lesson_timer}
WHERE lessonid = :lessonid
AND userid = :userid",
array('userid' => $USER->id, 'lessonid' => $this->properties->id));
if (!$duration) {
$duration = 0;
}
// If student has not spend enough time in the lesson, display a message.
if ($duration < $this->properties->completiontimespent) {
$a = new stdClass;
$a->timespentraw = $duration;
$a->timespent = format_time($duration);
$a->timerequiredraw = $this->properties->completiontimespent;
$a->timerequired = format_time($this->properties->completiontimespent);
$data->notenoughtimespent = $a;
}
}
if ($gradeinfo->attempts) {
if (!$this->properties->custom) {
$data->numberofpagesviewed = $gradeinfo->nquestions;
if ($this->properties->minquestions) {
if ($gradeinfo->nquestions < $this->properties->minquestions) {
$data->youshouldview = $this->properties->minquestions;
}
}
$data->numberofcorrectanswers = $gradeinfo->earned;
}
$a = new stdClass;
$a->score = $gradeinfo->earned;
$a->grade = $gradeinfo->total;
if ($gradeinfo->nmanual) {
$a->tempmaxgrade = $gradeinfo->total - $gradeinfo->manualpoints;
$a->essayquestions = $gradeinfo->nmanual;
$data->displayscorewithessays = $a;
} else {
$data->displayscorewithoutessays = $a;
}
if ($this->properties->grade != GRADE_TYPE_NONE) {
$a = new stdClass;
$a->grade = number_format($gradeinfo->grade * $this->properties->grade / 100, 1);
$a->total = $this->properties->grade;
$data->yourcurrentgradeisoutof = $a;
}
$grade = new stdClass();
$grade->lessonid = $this->properties->id;
$grade->userid = $USER->id;
$grade->grade = $gradeinfo->grade;
$grade->completed = time();
if (isset($USER->modattempts[$this->properties->id])) { // If reviewing, make sure update old grade record.
if (!$grades = $DB->get_records("lesson_grades",
array("lessonid" => $this->properties->id, "userid" => $USER->id), "completed DESC", '*', 0, 1)) {
throw new moodle_exception('cannotfindgrade', 'lesson');
}
$oldgrade = array_shift($grades);
$grade->id = $oldgrade->id;
$DB->update_record("lesson_grades", $grade);
} else {
$newgradeid = $DB->insert_record("lesson_grades", $grade);
}
} else {
if ($this->properties->timelimit) {
if ($outoftime == 'normal') {
$grade = new stdClass();
$grade->lessonid = $this->properties->id;
$grade->userid = $USER->id;
$grade->grade = 0;
$grade->completed = time();
$newgradeid = $DB->insert_record("lesson_grades", $grade);
$data->eolstudentoutoftimenoanswers = true;
}
} else {
$data->welldone = true;
}
}
// Update central gradebook.
lesson_update_grades($this, $USER->id);
$data->progresscompleted = $progresscompleted;
}
} else {
// Display for teacher.
if ($this->properties->grade != GRADE_TYPE_NONE) {
$data->displayofgrade = true;
}
}
if ($this->properties->modattempts && !$canmanage) {
// Make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time
// look at the attempt records to find the first QUESTION page that the user answered, then use that page id
// to pass to view again. This is slick cause it wont call the empty($pageid) code
// $ntries is decremented above.
if (!$attempts = $this->get_attempts($ntries)) {
$attempts = array();
$url = new moodle_url('/mod/lesson/view.php', array('id' => $cm->id));
} else {
$firstattempt = current($attempts);
$pageid = $firstattempt->pageid;
// If the student wishes to review, need to know the last question page that the student answered.
// This will help to make sure that the student can leave the lesson via pushing the continue button.
$lastattempt = end($attempts);
$USER->modattempts[$this->properties->id] = $lastattempt->pageid;
$url = new moodle_url('/mod/lesson/view.php', array('id' => $cm->id, 'pageid' => $pageid));
}
$data->reviewlesson = $url;
} else if ($this->properties->modattempts && $canmanage) {
$data->modattemptsnoteacher = true;
}
if ($this->properties->activitylink) {
$data->activitylink = $this->link_for_activitylink();
}
return $data;
}
}
+92 -3
View File
@@ -484,9 +484,10 @@ class mod_lesson_renderer extends plugin_renderer_base {
* Returns HTML to display a progress bar of progression through a lesson
*
* @param lesson $lesson
* @param int $progress optional, if empty it will be calculated
* @return string
*/
public function progress_bar(lesson $lesson) {
public function progress_bar(lesson $lesson, $progress = null) {
$context = context_module::instance($this->page->cm->id);
// lesson setting to turn progress bar on or off
@@ -499,8 +500,9 @@ class mod_lesson_renderer extends plugin_renderer_base {
return $this->output->notification(get_string('progressbarteacherwarning2', 'lesson'));
}
// Check if the user is reviewing the attempt.
$progress = $lesson->calculate_progress();
if ($progress === null) {
$progress = $lesson->calculate_progress();
}
// print out the Progress Bar. Attempted to put as much as possible in the style sheets.
$content = '<br />' . html_writer::tag('div', $progress . '%', array('class' => 'progress_bar_completed', 'style' => 'width: '. $progress . '%;'));
@@ -541,4 +543,91 @@ class mod_lesson_renderer extends plugin_renderer_base {
$output = html_writer::tag('p', $contents, $attributes);
return $output;
}
/**
* Returns the HTML for displaying the end of lesson page.
*
* @param lesson $lesson lesson instance
* @param stdclass $data lesson data to be rendered
* @return string HTML contents
*/
public function display_eol_page(lesson $lesson, $data) {
$output = '';
$canmanage = $lesson->can_manage();
$course = $lesson->courserecord;
if ($lesson->custom && !$canmanage && (($data->gradeinfo->nquestions < $lesson->minquestions))) {
$output .= $this->box_start('generalbox boxaligncenter');
}
if ($data->gradelesson) {
// We are using level 3 header because the page title is a sub-heading of lesson title (MDL-30911).
$output .= $this->heading(get_string("congratulations", "lesson"), 3);
$output .= $this->box_start('generalbox boxaligncenter');
}
if ($data->notenoughtimespent !== false) {
$output .= $this->paragraph(get_string("notenoughtimespent", "lesson", $data->notenoughtimespent), 'center');
}
if ($data->numberofpagesviewed !== false) {
$output .= $this->paragraph(get_string("numberofpagesviewed", "lesson", $data->numberofpagesviewed), 'center');
}
if ($data->youshouldview !== false) {
$output .= $this->paragraph(get_string("youshouldview", "lesson", $data->youshouldview), 'center');
}
if ($data->numberofcorrectanswers !== false) {
$output .= $this->paragraph(get_string("numberofcorrectanswers", "lesson", $data->numberofcorrectanswers), 'center');
}
if ($data->displayscorewithessays !== false) {
$output .= $this->box(get_string("displayscorewithessays", "lesson", $data->displayscorewithessays), 'center');
} else if ($data->displayscorewithoutessays !== false) {
$output .= $this->box(get_string("displayscorewithoutessays", "lesson", $data->displayscorewithoutessays), 'center');
}
if ($data->yourcurrentgradeisoutof !== false) {
$output .= $this->paragraph(get_string("yourcurrentgradeisoutof", "lesson", $data->yourcurrentgradeisoutof), 'center');
}
if ($data->eolstudentoutoftimenoanswers !== false) {
$output .= $this->paragraph(get_string("eolstudentoutoftimenoanswers", "lesson"));
}
if ($data->welldone !== false) {
$output .= $this->paragraph(get_string("welldone", "lesson"));
}
if ($data->progresscompleted !== false) {
$output .= $this->progress_bar($lesson, $data->progresscompleted);
}
if ($data->displayofgrade !== false) {
$output .= $this->paragraph(get_string("displayofgrade", "lesson"), 'center');
}
$output .= $this->box_end(); // End of Lesson button to Continue.
if ($data->reviewlesson !== false) {
$output .= html_writer::link($data->reviewlesson, get_string('reviewlesson', 'lesson'), array('class' => 'centerpadded lessonbutton standardbutton p-r-1'));
}
if ($data->modattemptsnoteacher !== false) {
$output .= $this->paragraph(get_string("modattemptsnoteacher", "lesson"), 'centerpadded');
}
if ($data->activitylink !== false) {
$output .= $data->activitylink;
}
$url = new moodle_url('/course/view.php', array('id' => $course->id));
$output .= html_writer::link($url, get_string('returnto', 'lesson', format_string($course->fullname, true)),
array('class' => 'centerpadded lessonbutton standardbutton p-r-1'));
if (has_capability('gradereport/user:view', context_course::instance($course->id))
&& $course->showgrades && $lesson->grade != 0 && !$lesson->practice) {
$url = new moodle_url('/grade/index.php', array('id' => $course->id));
$output .= html_writer::link($url, get_string('viewgrades', 'lesson'),
array('class' => 'centerpadded lessonbutton standardbutton p-r-1'));
}
return $output;
}
}
+89
View File
@@ -1042,4 +1042,93 @@ class mod_lesson_external_testcase extends externallib_advanced_testcase {
$this->assertFalse($result['maxattemptsreached']); // Still one attempt.
$this->assertEquals(50, $result['progress']);
}
/**
* Test finish attempt not doing anything.
*/
public function test_finish_attempt_not_doing_anything() {
$this->setUser($this->student);
// First we need to launch the lesson so the timer is on.
mod_lesson_external::launch_attempt($this->lesson->id);
$result = mod_lesson_external::finish_attempt($this->lesson->id);
$result = external_api::clean_returnvalue(mod_lesson_external::finish_attempt_returns(), $result);
$this->assertCount(0, $result['warnings']);
$returneddata = [];
foreach ($result['data'] as $data) {
$returneddata[$data['name']] = $data['value'];
}
$this->assertEquals(1, $returneddata['gradelesson']); // Graded lesson.
$this->assertEquals(1, $returneddata['welldone']); // Finished correctly (even without grades).
$gradeinfo = json_decode($returneddata['gradeinfo']);
$expectedgradeinfo = (object) [
'nquestions' => 0,
'attempts' => 0,
'total' => 0,
'earned' => 0,
'grade' => 0,
'nmanual' => 0,
'manualpoints' => 0,
];
}
/**
* Test finish attempt with correct answer.
*/
public function test_finish_attempt_with_correct_answer() {
global $DB;
$this->setUser($this->student);
// First we need to launch the lesson so the timer is on.
mod_lesson_external::launch_attempt($this->lesson->id);
// Attempt a question, correct answer.
$DB->set_field('lesson', 'custom', 0, array('id' => $this->lesson->id));
$DB->set_field('lesson', 'progressbar', 1, array('id' => $this->lesson->id));
$answercorrect = 0;
$p2answers = $DB->get_records('lesson_answers', array('lessonid' => $this->lesson->id, 'pageid' => $this->page2->id), 'id');
foreach ($p2answers as $answer) {
if ($answer->jumpto != 0) {
$answercorrect = $answer->id;
}
}
$data = array(
array(
'name' => 'answerid',
'value' => $answercorrect,
),
array(
'name' => '_qf__lesson_display_answer_form_truefalse',
'value' => 1,
)
);
$result = mod_lesson_external::process_page($this->lesson->id, $this->page2->id, $data);
$result = external_api::clean_returnvalue(mod_lesson_external::process_page_returns(), $result);
$result = mod_lesson_external::finish_attempt($this->lesson->id);
$result = external_api::clean_returnvalue(mod_lesson_external::finish_attempt_returns(), $result);
$this->assertCount(0, $result['warnings']);
$returneddata = [];
foreach ($result['data'] as $data) {
$returneddata[$data['name']] = $data['value'];
}
$this->assertEquals(1, $returneddata['gradelesson']); // Graded lesson.
$this->assertEquals(1, $returneddata['numberofpagesviewed']);
$this->assertEquals(1, $returneddata['numberofcorrectanswers']);
$gradeinfo = json_decode($returneddata['gradeinfo']);
$expectedgradeinfo = (object) [
'nquestions' => 1,
'attempts' => 1,
'total' => 1,
'earned' => 1,
'grade' => 100,
'nmanual' => 0,
'manualpoints' => 0,
];
}
}
+1 -1
View File
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2016120511; // The current module version (Date: YYYYMMDDXX)
$plugin->version = 2016120512; // The current module version (Date: YYYYMMDDXX)
$plugin->requires = 2016112900; // Requires this Moodle version
$plugin->component = 'mod_lesson'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 0;
+2 -173
View File
@@ -233,183 +233,12 @@ if ($pageid != LESSON_EOL) {
} else {
$lessoncontent = '';
// End of lesson reached work out grade.
// Used to check to see if the student ran out of time.
$outoftime = optional_param('outoftime', '', PARAM_ALPHA);
$ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
if (isset($USER->modattempts[$lesson->id])) {
$ntries--; // need to look at the old attempts :)
}
$gradelesson = true;
$gradeinfo = lesson_grade($lesson, $ntries);
if ($lesson->custom && !$canmanage) {
// Before we calculate the custom score make sure they answered the minimum
// number of questions. We only need to do this for custom scoring as we can
// not get the miniumum score the user should achieve. If we are not using
// custom scoring (so all questions are valued as 1) then we simply check if
// they answered more than the minimum questions, if not, we mark it out of the
// number specified in the minimum questions setting - which is done in lesson_grade().
// Get the number of answers given.
if ($gradeinfo->nquestions < $lesson->minquestions) {
$gradelesson = false;
$a = new stdClass;
$a->nquestions = $gradeinfo->nquestions;
$a->minquestions = $lesson->minquestions;
$lessoncontent .= $OUTPUT->box_start('generalbox boxaligncenter');
$lesson->add_message(get_string('numberofpagesviewednotice', 'lesson', $a));
}
}
if ($gradelesson) {
// We are using level 3 header because the page title is a sub-heading of lesson title (MDL-30911).
$lessoncontent .= $OUTPUT->heading(get_string("congratulations", "lesson"), 3);
$lessoncontent .= $OUTPUT->box_start('generalbox boxaligncenter');
}
if (!$canmanage) {
if ($gradelesson) {
// Store this now before any modifications to pages viewed.
$progressbar = $lessonoutput->progress_bar($lesson);
// Update the clock / get time information for this user.
$lesson->stop_timer();
// Update completion state.
$completion = new completion_info($course);
if ($completion->is_enabled($cm) && $lesson->completionendreached) {
$completion->update_state($cm, COMPLETION_COMPLETE);
}
if ($lesson->completiontimespent > 0) {
$duration = $DB->get_field_sql(
"SELECT SUM(lessontime - starttime)
FROM {lesson_timer}
WHERE lessonid = :lessonid
AND userid = :userid",
array('userid' => $USER->id, 'lessonid' => $lesson->id));
if (!$duration) {
$duration = 0;
}
// If student has not spend enough time in the lesson, display a message.
if ($duration < $lesson->completiontimespent) {
$a = new stdClass;
$a->timespent = format_time($duration);
$a->timerequired = format_time($lesson->completiontimespent);
$lessoncontent .= $lessonoutput->paragraph(get_string("notenoughtimespent", "lesson", $a), 'center');
}
}
if ($gradeinfo->attempts) {
if (!$lesson->custom) {
$lessoncontent .= $lessonoutput->paragraph(get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions), 'center');
if ($lesson->minquestions) {
if ($gradeinfo->nquestions < $lesson->minquestions) {
// print a warning and set nviewed to minquestions
$lessoncontent .= $lessonoutput->paragraph(get_string("youshouldview", "lesson", $lesson->minquestions), 'center');
}
}
$lessoncontent .= $lessonoutput->paragraph(get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned), 'center');
}
$a = new stdClass;
$a->score = $gradeinfo->earned;
$a->grade = $gradeinfo->total;
if ($gradeinfo->nmanual) {
$a->tempmaxgrade = $gradeinfo->total - $gradeinfo->manualpoints;
$a->essayquestions = $gradeinfo->nmanual;
$lessoncontent .= $OUTPUT->box(get_string("displayscorewithessays", "lesson", $a), 'center');
} else {
$lessoncontent .= $OUTPUT->box(get_string("displayscorewithoutessays", "lesson", $a), 'center');
}
if ($lesson->grade != GRADE_TYPE_NONE) {
$a = new stdClass;
$a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
$a->total = $lesson->grade;
$lessoncontent .= $lessonoutput->paragraph(get_string("yourcurrentgradeisoutof", "lesson", $a), 'center');
}
$grade = new stdClass();
$grade->lessonid = $lesson->id;
$grade->userid = $USER->id;
$grade->grade = $gradeinfo->grade;
$grade->completed = time();
if (isset($USER->modattempts[$lesson->id])) { // If reviewing, make sure update old grade record.
if (!$grades = $DB->get_records("lesson_grades",
array("lessonid" => $lesson->id, "userid" => $USER->id), "completed DESC", '*', 0, 1)) {
print_error('cannotfindgrade', 'lesson');
}
$oldgrade = array_shift($grades);
$grade->id = $oldgrade->id;
$DB->update_record("lesson_grades", $grade);
} else {
$newgradeid = $DB->insert_record("lesson_grades", $grade);
}
} else {
if ($lesson->timelimit) {
if ($outoftime == 'normal') {
$grade = new stdClass();
$grade->lessonid = $lesson->id;
$grade->userid = $USER->id;
$grade->grade = 0;
$grade->completed = time();
$newgradeid = $DB->insert_record("lesson_grades", $grade);
$lessoncontent .= $lessonoutput->paragraph(get_string("eolstudentoutoftimenoanswers", "lesson"));
}
} else {
$lessoncontent .= $lessonoutput->paragraph(get_string("welldone", "lesson"));
}
}
// update central gradebook
lesson_update_grades($lesson, $USER->id);
$lessoncontent .= $progressbar;
}
} else {
// display for teacher
if ($lesson->grade != GRADE_TYPE_NONE) {
$lessoncontent .= $lessonoutput->paragraph(get_string("displayofgrade", "lesson"), 'center');
}
}
$lessoncontent .= $OUTPUT->box_end(); //End of Lesson button to Continue.
if ($lesson->modattempts && !$canmanage) {
// make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time
// look at the attempt records to find the first QUESTION page that the user answered, then use that page id
// to pass to view again. This is slick cause it wont call the empty($pageid) code
// $ntries is decremented above
if (!$attempts = $lesson->get_attempts($ntries)) {
$attempts = array();
$url = new moodle_url('/mod/lesson/view.php', array('id'=>$PAGE->cm->id));
} else {
$firstattempt = current($attempts);
$pageid = $firstattempt->pageid;
// IF the student wishes to review, need to know the last question page that the student answered. This will help to make
// sure that the student can leave the lesson via pushing the continue button.
$lastattempt = end($attempts);
$USER->modattempts[$lesson->id] = $lastattempt->pageid;
$url = new moodle_url('/mod/lesson/view.php', array('id'=>$PAGE->cm->id, 'pageid'=>$pageid));
}
$lessoncontent .= html_writer::link($url, get_string('reviewlesson', 'lesson'),
array('class' => 'centerpadded lessonbutton standardbutton p-r-1'));
} elseif ($lesson->modattempts && $canmanage) {
$lessoncontent .= $lessonoutput->paragraph(get_string("modattemptsnoteacher", "lesson"), 'centerpadded');
}
if ($lesson->activitylink) {
$lessoncontent .= $lesson->link_for_activitylink();
}
$url = new moodle_url('/course/view.php', array('id'=>$course->id));
$lessoncontent .= html_writer::link($url, get_string('returnto', 'lesson', format_string($course->fullname, true)),
array('class' => 'centerpadded lessonbutton standardbutton p-r-1'));
if (has_capability('gradereport/user:view', context_course::instance($course->id))
&& $course->showgrades && $lesson->grade != 0 && !$lesson->practice) {
$url = new moodle_url('/grade/index.php', array('id' => $course->id));
$lessoncontent .= html_writer::link($url, get_string('viewgrades', 'lesson'),
array('class' => 'centerpadded lessonbutton standardbutton p-r-1'));
}
$data = $lesson->process_eol_page($outoftime);
$lessoncontent = $lessonoutput->display_eol_page($lesson, $data);
lesson_add_fake_blocks($PAGE, $cm, $lesson, $timer);
echo $lessonoutput->header($lesson, $cm, $currenttab, $extraeditbuttons, $lessonpageid, get_string("congratulations", "lesson"));