Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-82153

Course completion criteria COMPLETION_CRITERIA_TYPE_ACTIVITY and Quiz

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: Minor Minor
    • None
    • 4.4.1
    • Course completion
    • 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:

      1. Create a course with completion tracking enabled
      2. 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".
      3. Save the changes.
      4. Add a few questions to the quiz.
      5. Set the course completion Condition: Activity Completion and mark the quiz you created.
      6. Attempt and fail the quiz 2 times as a student.
      7. 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;
          }
       

       

       

            Unassigned Unassigned
            bkenwell@gmail.com Brian Kenwell
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:

                Error rendering 'clockify-timesheets-time-tracking-reports:timer-sidebar'. Please contact your Jira administrators.