diff --git a/mod/lesson/action/continue.php b/mod/lesson/action/continue.php
index cd7c3a1379b..0083147a02d 100644
--- a/mod/lesson/action/continue.php
+++ b/mod/lesson/action/continue.php
@@ -704,17 +704,9 @@
}
}
- // this calculates the ongoing score
+ // This calculates and prints the ongoing score message
if ($lesson->ongoing) {
- if (isteacher($course->id)) {
- echo "
".get_string("teacherongoingwarning", "lesson")."
";
- } else {
- $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
- if (isset($USER->modattempts[$lesson->id])) {
- $ntries--;
- }
- lesson_calculate_ongoing_score($lesson, $USER->id, $ntries);
- }
+ lesson_print_ongoing_score($lesson);
}
// display response (if there is one - there should be!)
diff --git a/mod/lesson/locallib.php b/mod/lesson/locallib.php
index ae80f145305..d6798da6acc 100644
--- a/mod/lesson/locallib.php
+++ b/mod/lesson/locallib.php
@@ -1204,123 +1204,155 @@ function lesson_print_tree($pageid, $lesson, $cmid) {
/**
* Calculates a user's grade for a lesson.
*
- * This is used for the ongoing score feature. It will calculate the user's
- * score based on how many points they have earned thus far in the lesson out
- * of the maximum that they could have earned. Example: user answers 4 questions out
- * of 20. Of the 4, the user earned 5 points out of a possible 12. So, their current
- * score would be 5 out of 12 and not 5 out of the total for the whole lesson.
- * This function is also used by essay grading. It is used to recalculate a students grade
- * after a teacher assigns a grade for an essay.
- *
* @param object $lesson The lesson that the user is taking.
- * @param int $userid Id of the user.
* @param int $retries The attempt number.
- * @param boolean $return A flag to return the grade or print it out.
- * @return float May return the grade.
- * @todo Break out the grading section of this code to use for grading lessons (also have grading code in view.php)
+ * @param int $userid Id of the user (optinal, default current user).
+ * @return object { nquestions => number of questions answered
+ attempts => number of question attempts
+ total => max points possible
+ earned => points earned by student
+ grade => calculated percentage grade
+ nmanual => number of manually graded questions
+ manualpoints => point value for manually graded questions }
*/
-function lesson_calculate_ongoing_score($lesson, $userid, $retries, $return=false) {
- if (!$lesson->custom) {
- $ncorrect = 0;
- $temp = array();
- if ($pagesanswered = get_records_select("lesson_attempts", "lessonid = $lesson->id AND
- userid = $userid AND retry = $retries order by timeseen")) {
+function lesson_grade($lesson, $ntries, $userid = 0) {
+ global $USER;
- foreach ($pagesanswered as $pageanswered) {
- if (!array_key_exists($pageanswered->pageid, $temp)) {
- $temp[$pageanswered->pageid] = array($pageanswered->correct, 1);
- } else {
- if ($temp[$pageanswered->pageid][1] < $lesson->maxattempts) {
- $n = $temp[$pageanswered->pageid][1] + 1;
- $temp[$pageanswered->pageid] = array($pageanswered->correct, $n);
- }
- }
- }
- foreach ($temp as $value => $key) {
- if ($key[0] == 1) {
- $ncorrect += 1;
- }
- }
+ if (empty($userid)) {
+ $userid = $USER->id;
+ }
+
+ // Zero out everything
+ $ncorrect = 0;
+ $nviewed = 0;
+ $score = 0;
+ $nmanual = 0;
+ $manualpoints = 0;
+ $thegrade = 0;
+ $nquestions = 0;
+ $total = 0;
+ $earned = 0;
+
+ if ($useranswers = get_records_select("lesson_attempts", "lessonid = $lesson->id AND
+ userid = $userid AND retry = $ntries", "timeseen")) {
+ // group each try with its page
+ $attemptset = array();
+ foreach ($useranswers as $useranswer) {
+ $attemptset[$useranswer->pageid][] = $useranswer;
}
- $nviewed = count($temp); // this counts number of Questions the user viewed
- if ($nviewed != 0) {
- $thegrade = round(100 * $ncorrect / $nviewed, 5);
- } else {
- $thegrade = 0;
- }
-
- if ($return) {
- return $thegrade;
- } else {
- $output = new stdClass;
- $output->correct = $ncorrect;
- $output->viewed = $nviewed;
- print_simple_box(get_string("ongoingnormal", "lesson", $output), "center");
- }
-
- } else {
- $score = 0;
- $essayquestions = 0;
- $essayquestionpoints = 0;
- $bestscore = 0;
- $thegrade = 0;
-
- if ($useranswers = get_records_select("lesson_attempts", "lessonid = $lesson->id AND
- userid = $userid AND retry = $retries", "timeseen")) {
- // group each try with its page
- foreach ($useranswers as $useranswer) {
- $attemptset[$useranswer->pageid][] = $useranswer;
- }
-
- $pageids = array_keys($attemptset);
- $pageids = implode(",", $pageids);
-
- // get only the pages and their answers that the user answered
- $answeredpages = get_records_select("lesson_pages", "lessonid = $lesson->id AND id IN($pageids)");
- $pageanswers = get_records_select("lesson_answers", "lessonid = $lesson->id AND pageid IN($pageids)");
-
- foreach ($attemptset as $attempts) {
- if(count($attempts) > $lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
- $attempt = $attempts[$lesson->maxattempts - 1];
- } else {
- // else, user attempted the question less than the max, so grab the last one
- $attempt = end($attempts);
- }
- // if essay question, handle it, otherwise add to score
- if ($answeredpages[$attempt->pageid]->qtype == LESSON_ESSAY) {
- $essayinfo = unserialize($attempt->useranswer);
- $score += $essayinfo->score;
- $essayquestions++;
- $essayquestionpoints += $pageanswers[$attempt->answerid]->score;
- } else {
- $score += $pageanswers[$attempt->answerid]->score;
- }
- }
- $bestscores = array();
- // find the highest possible score per page
- foreach ($pageanswers as $pageanswer) {
- if(isset($bestscores[$pageanswer->pageid])) {
- if ($bestscores[$pageanswer->pageid] < $pageanswer->score) {
- $bestscores[$pageanswer->pageid] = $pageanswer->score;
- }
- } else {
- $bestscores[$pageanswer->pageid] = $pageanswer->score;
- }
- }
-
- $bestscore = array_sum($bestscores);
- $thegrade = round(100 * $score / $bestscore, 5);
- }
-
- if ($return) {
- return $thegrade;
+ // Drop all attempts that go beyond max attempts for the lesson
+ foreach ($attemptset as $key => $set) {
+ $attemptset[$key] = array_slice($set, 0, $lesson->maxattempts);
+ }
+
+ $pageids = implode(",", array_keys($attemptset));
+
+ // get only the pages and their answers that the user answered
+ $pages = get_records_select("lesson_pages", "lessonid = $lesson->id AND id IN($pageids)");
+ $answers = get_records_select("lesson_answers", "lessonid = $lesson->id AND pageid IN($pageids)");
+
+ // Number of pages answered
+ $nquestions = count($pages);
+
+ foreach ($attemptset as $attempts) {
+ if ($lesson->custom) {
+ $attempt = end($attempts);
+ // If essay question, handle it, otherwise add to score
+ if ($pages[$attempt->pageid]->qtype == LESSON_ESSAY) {
+ $essayinfo = unserialize($attempt->useranswer);
+ $earned += $essayinfo->score;
+ $nmanual++;
+ $manualpoints += $answers[$attempt->answerid]->score;
+ } else {
+ $earned += $answers[$attempt->answerid]->score;
+ }
+ } else {
+ foreach ($attempts as $attempt) {
+ $earned += $attempt->correct;
+ }
+ $attempt = end($attempts); // doesn't matter which one
+ // If essay question, increase numbers
+ if ($pages[$attempt->pageid]->qtype == LESSON_ESSAY) {
+ $nmanual++;
+ $manualpoints++;
+ }
+ }
+ // Number of times answered
+ $nviewed += count($attempts);
+ }
+
+ if ($lesson->custom) {
+ $bestscores = array();
+ // Find the highest possible score per page to get our total
+ foreach ($answers as $answer) {
+ if(isset($bestscores[$answer->pageid]) and $bestscores[$answer->pageid] < $answer->score) {
+ $bestscores[$answer->pageid] = $answer->score;
+ } else {
+ $bestscores[$answer->pageid] = $answer->score;
+ }
+ }
+ $total = array_sum($bestscores);
} else {
- // not taking into account essay questions... may want to?
- $ongoingoutput = new stdClass;
- $ongoingoutput->score = $score;
- $ongoingoutput->currenthigh = $bestscore;
- print_simple_box(get_string("ongoingcustom", "lesson", $ongoingoutput), "center");
+ // Check to make sure the student has answered the minimum questions
+ if ($lesson->minquestions and $nquestions < $lesson->minquestions) {
+ // Nope, increase number viewed by the amount of unanswered questions
+ $total = $nviewed + ($lesson->minquestions - $nquestions);
+ } else {
+ $total = $nviewed;
+ }
+ }
+ }
+
+ if ($total) { // not zero
+ $thegrade = round(100 * $earned / $total, 5);
+ }
+
+ // Build the grade information object
+ $gradeinfo = new stdClass;
+ $gradeinfo->nquestions = $nquestions;
+ $gradeinfo->attempts = $nviewed;
+ $gradeinfo->total = $total;
+ $gradeinfo->earned = $earned;
+ $gradeinfo->grade = $thegrade;
+ $gradeinfo->nmanual = $nmanual;
+ $gradeinfo->manualpoints = $manualpoints;
+
+ return $gradeinfo;
+}
+
+/**
+ * Prints the on going message to the user.
+ *
+ * With custom grading On, displays points
+ * earned out of total points possible thus far.
+ * With custom grading Off, displays number of correct
+ * answers out of total attempted.
+ *
+ * @param object $lesson The lesson that the user is taking.
+ * @return void
+ **/
+function lesson_print_ongoing_score($lesson) {
+ global $USER;
+
+ if (isteacher($lesson->course)) {
+ echo "".get_string('teacherongoingwarning', 'lesson').'
';
+ } else {
+ $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
+ if (isset($USER->modattempts[$lesson->id])) {
+ $ntries--;
+ }
+ $gradeinfo = lesson_grade($lesson, $ntries);
+
+ $a = new stdClass;
+ if ($lesson->custom) {
+ $a->score = $gradeinfo->earned;
+ $a->currenthigh = $gradeinfo->total;
+ print_simple_box(get_string("ongoingcustom", "lesson", $a), "center");
+ } else {
+ $a->correct = $gradeinfo->earned;
+ $a->viewed = $gradeinfo->attempts;
+ print_simple_box(get_string("ongoingnormal", "lesson", $a), "center");
}
}
}
diff --git a/mod/lesson/view.php b/mod/lesson/view.php
index df244a495cb..01d17d13597 100644
--- a/mod/lesson/view.php
+++ b/mod/lesson/view.php
@@ -630,45 +630,28 @@
}
}
- /// this calculates the ongoing score
- if ($lesson->ongoing && !empty($pageid)) {
- if (isteacher($course->id)) {
- echo "".get_string('teacherongoingwarning', 'lesson').'
';
- } else {
- $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
- if (isset($USER->modattempts[$lesson->id])) {
- $ntries--;
- }
- lesson_calculate_ongoing_score($lesson, $USER->id, $ntries);
- }
+ /// This calculates and prints the ongoing score
+ if ($lesson->ongoing and !empty($pageid)) {
+ lesson_print_ongoing_score($lesson);
}
if ($page->qtype == LESSON_BRANCHTABLE) {
if ($lesson->minquestions and isstudent($course->id)) {
// tell student how many questions they have seen, how many are required and their grade
$ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
- $nviewed = count_records("lesson_attempts", "lessonid", $lesson->id, "userid",
- $USER->id, "retry", $ntries);
- if ($nviewed) {
- echo "".get_string("numberofpagesviewed", "lesson", $nviewed).
+
+ $gradeinfo = lesson_grade($lesson, $ntries);
+
+ if ($gradeinfo->attempts) {
+ echo "
".get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions).
"; (".get_string("youshouldview", "lesson", $lesson->minquestions).")
";
// count the number of distinct correct pages
- if ($correctpages = get_records_select("lesson_attempts", "lessonid = $lesson->id
- AND userid = $USER->id AND retry = $ntries AND correct = 1")) {
- foreach ($correctpages as $correctpage) {
- $temp[$correctpage->pageid] = 1;
- }
- $ncorrect = count($temp);
- } else {
- $nccorrect = 0;
+ if ($gradeinfo->nquestions < $lesson->minquestions) {
+ $gradeinfo->nquestions = $lesson->minquestions;
}
- if ($nviewed < $lesson->minquestions) {
- $nviewed = $lesson->minquestions;
- }
- echo get_string("numberofcorrectanswers", "lesson", $ncorrect)."
\n";
- $thegrade = intval(100 * $ncorrect / $nviewed);
+ echo get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned)."
\n";
echo get_string("yourcurrentgradeis", "lesson",
- number_format($thegrade * $lesson->grade / 100, 1)).
+ number_format($gradeinfo->grade * $lesson->grade / 100, 1)).
" (".get_string("outof", "lesson", $lesson->grade).")
\n";
}
}
@@ -1019,110 +1002,40 @@
$ntries--; // need to look at the old attempts :)
}
if (isstudent($course->id)) {
- if ($nviewed = count_records("lesson_attempts", "lessonid", $lesson->id, "userid",
- $USER->id, "retry", $ntries)) {
+
+ $gradeinfo = lesson_grade($lesson, $ntries);
+
+ if ($gradeinfo->attempts) {
if (!$lesson->custom) {
- $ncorrect = 0;
- $temp = array();
- // count the number of distinct correct pages
- if ($correctpages = get_records_select("lesson_attempts", "lessonid = $lesson->id AND
- userid = $USER->id AND retry = $ntries AND correct = 1")) {
- foreach ($correctpages as $correctpage) {
- $temp[$correctpage->pageid] = 1;
- }
- $ncorrect = count($temp);
- }
- echo "".get_string("numberofpagesviewed", "lesson", $nviewed).
+ echo "
".get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions).
"
\n";
if ($lesson->minquestions) {
- if ($nviewed < $lesson->minquestions) {
+ if ($gradeinfo->nquestions < $lesson->minquestions) {
// print a warning and set nviewed to minquestions
echo "".get_string("youshouldview", "lesson",
- $lesson->minquestions)." ".get_string("pages", "lesson")."
\n";
- $nviewed = $lesson->minquestions;
+ $lesson->minquestions)."\n";
}
}
- echo "".get_string("numberofcorrectanswers", "lesson", $ncorrect).
+ echo "
".get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned).
"
\n";
- $thegrade = round(100 * $ncorrect / $nviewed, 5);
- echo "".get_string("gradeis", "lesson",
- number_format($thegrade * $lesson->grade / 100, 1)).
- " (".get_string("outof", "lesson", $lesson->grade).")
\n";
-
- } else {
- $score = 0;
- $essayquestions = 0;
- $essayquestionpoints = 0;
-
- if ($useranswers = get_records_select("lesson_attempts", "lessonid = $lesson->id AND
- userid = $USER->id AND retry = $ntries", "timeseen")) {
- // group each try with its page
- foreach ($useranswers as $useranswer) {
- $attemptset[$useranswer->pageid][] = $useranswer;
- }
-
- $pageids = array_keys($attemptset);
- $pageids = implode(",", $pageids);
-
- // get only the pages and their answers that the user answered
- $answeredpages = get_records_select("lesson_pages", "lessonid = $lesson->id AND id IN($pageids)");
- $pageanswers = get_records_select("lesson_answers", "lessonid = $lesson->id AND pageid IN($pageids)");
-
- foreach ($attemptset as $attempts) {
- if(count($attempts) > $lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
- $attempt = $attempts[$lesson->maxattempts - 1];
- } else {
- // else, user attempted the question less than the max, so grab the last one
- $attempt = end($attempts);
- }
- // if essay question, handle it, otherwise add to score
- if ($answeredpages[$attempt->pageid]->qtype == LESSON_ESSAY) {
- $essayinfo = unserialize($attempt->useranswer);
- $score += $essayinfo->score;
- $essayquestions++;
- $essayquestionpoints += $pageanswers[$attempt->answerid]->score;
- } else {
- if (array_key_exists($attempt->answerid, $pageanswers)) {
- $score += $pageanswers[$attempt->answerid]->score;
- }
- }
- }
- $bestscores = array();
- // find the highest possible score per page
- foreach ($pageanswers as $pageanswer) {
- if(isset($bestscores[$pageanswer->pageid])) {
- if ($bestscores[$pageanswer->pageid] < $pageanswer->score) {
- $bestscores[$pageanswer->pageid] = $pageanswer->score;
- }
- } else {
- $bestscores[$pageanswer->pageid] = $pageanswer->score;
- }
- }
-
- $bestscore = array_sum($bestscores);
- }
-
- $thegrade = round(100 * $score / $bestscore, 5);
- $a = new stdClass;
- if ($essayquestions > 0) {
- $a->score = $score;
- $a->tempmaxgrade = $bestscore - $essayquestionpoints;
- $a->essayquestions = $essayquestions;
- $a->grade = $bestscore;
- echo "".get_string("displayscorewithessays", "lesson", $a)."
";
- } else {
- $a->score = $score;
- $a->grade = $bestscore;
- echo "".get_string("displayscorewithoutessays", "lesson", $a)."
";
- }
- echo "".get_string("gradeis", "lesson",
- number_format($thegrade * $lesson->grade / 100, 1)).
- " (".get_string("outof", "lesson", $lesson->grade).")
\n";
-
}
+ $a = new stdClass;
+ $a->score = $gradeinfo->earned;
+ $a->grade = $gradeinfo->total;
+ if ($gradeinfo->nmanual) {
+ $a->tempmaxgrade = $gradeinfo->total - $gradeinfo->manualpoints;
+ $a->essayquestions = $gradeinfo->nmanual;
+ echo "".get_string("displayscorewithessays", "lesson", $a)."
";
+ } else {
+ echo "".get_string("displayscorewithoutessays", "lesson", $a)."
";
+ }
+ echo "".get_string("gradeis", "lesson",
+ number_format($gradeinfo->grade * $lesson->grade / 100, 1)).
+ " (".get_string("outof", "lesson", $lesson->grade).")
\n";
+
$grade->lessonid = $lesson->id;
$grade->userid = $USER->id;
- $grade->grade = $thegrade;
+ $grade->grade = $gradeinfo->grade;
$grade->completed = time();
if (!$lesson->practice) {
if (isset($USER->modattempts[$lesson->id])) { // if reviewing, make sure update old grade record
@@ -1821,10 +1734,9 @@
$grade = current($grades);
- // I modded this function a bit so it would work here... :) ;) :P
- $updategrade->grade = lesson_calculate_ongoing_score($lesson, $essay->userid, $essay->retry, true);
+ $gradeinfo = lesson_grade($lesson, $essay->retry, $essay->userid);
$updategrade->id = $grade->id;
-
+ $updategrade->grade = $gradeinfo->grade;
if(update_record("lesson_grades", $updategrade)) {
redirect("view.php?id=$cm->id&action=essayview", get_string("updatesuccess", "lesson"));
} else {