-
Bug
-
Resolution: Duplicate
-
Minor
-
None
-
4.4.1
-
None
-
MOODLE_404_STABLE
When the completion criteria for a course is COMPLETION_CRITERIA_TYPE_ACTIVITY, shouldn't all of the COMPLETION_COMPLETE* constants be valid (1,2,3 and 4)?
Specifically, if the activity completion for a quiz is "Passing grade or all available attempts completed", the course_modules_completion.completionstate could be any of COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL, or COMPLETION_COMPLETE_FAIL_HIDDEN), however the course_modules.completionpassgrade field overrides the activity completion value when course completion is checked (in mark_course_completions_activity_criteria() from /completion/classes/api.php).
Shouldn't the where clause for mc.completionstate be changed to a get_in_or_equal that includes all the COMPLETION_COMPLETE constants?
I'm unsure if this would cause issues elsewhere, but changing the query as below does resolve this specific issue.
To reproduce:
- Create a course with completion tracking enabled
- Create a quiz activity within that course, set a passing grade, set Attempts allowed to 2, and the activity completion conditions to "Receive a grade", "Passing grade", "Passing grade or all available attempts completed".
- Save the changes.
- Add a few questions to the quiz.
- Set the course completion Condition: Activity Completion and mark the quiz you created.
- Attempt and fail the quiz 2 times as a student.
- The quiz activity shows the correct completion, but the course is never marked complete.
public static function mark_course_completions_activity_criteria($userdata = null): int { |
global $DB; // Get all users who meet this criteria |
$completionstates = [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL, COMPLETION_COMPLETE_FAIL_HIDDEN];
|
list($insql, $inparams) = $DB->get_in_or_equal($completionstates, SQL_PARAMS_NAMED, 'completionstate'); |
$params = array_merge($inparams, ['criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY, 'contextlevel' => CONTEXT_COURSE]); $sql = "SELECT DISTINCT c.id AS course, |
cr.id AS criteriaid,
|
ra.userid AS userid,
|
mc.timemodified AS timecompleted
|
FROM {course_completion_criteria} cr
|
INNER JOIN {course} c ON cr.course = c.id
|
INNER JOIN {context} con ON con.instanceid = c.id
|
INNER JOIN {role_assignments} ra ON ra.contextid = con.id
|
INNER JOIN {course_modules} cm ON cm.id = cr.moduleinstance
|
INNER JOIN {course_modules_completion} mc ON mc.coursemoduleid = cr.moduleinstance AND mc.userid = ra.userid
|
LEFT JOIN {course_completion_crit_compl} cc ON cc.criteriaid = cr.id AND cc.userid = ra.userid
|
WHERE cr.criteriatype = :criteriatype
|
AND con.contextlevel = :contextlevel
|
AND c.enablecompletion = 1 |
AND cc.id IS NULL
|
AND mc.completionstate $insql"; if ($userdata) { |
$params['courseid'] = $userdata['courseid']; |
$params['userid'] = $userdata['userid']; |
$sql .= " AND c.id = :courseid AND ra.userid = :userid"; |
// Mark as complete. |
$record = $DB->get_record_sql($sql, $params);
|
if ($record) { |
$completion = new \completion_criteria_completion((array) $record, DATA_OBJECT_FETCH_BY_KEY); |
$result = $completion->mark_complete($record->timecompleted);
|
return $result; |
}
|
} else { |
// Loop through completions, and mark as complete. |
$rs = $DB->get_recordset_sql($sql, $params);
|
foreach ($rs as $record) {
|
$completion = new \completion_criteria_completion((array) $record, DATA_OBJECT_FETCH_BY_KEY); |
$completion->mark_complete($record->timecompleted);
|
}
|
$rs->close();
|
}
|
return 0; |
}
|
|
- duplicates
-
MDL-79631 "Passing grade or all available attempts completed" activity condition in Quiz is not working as expected
- Open