From 69beea71659d402ee288dfd59f022362d929760c Mon Sep 17 00:00:00 2001 From: "Gerard (Gerry) Caulfield" Date: Wed, 14 Dec 2011 09:05:52 +0800 Subject: [PATCH] MDL-30724 Limit assignment_count_real_submissions() to only select real submissions I've also refactored some code so that it is more structured and allows for easier overriding of function associated with counting submissions and updated associated doc blocks. --- mod/assignment/lib.php | 76 +++++++++++-------- .../type/upload/assignment.class.php | 29 ++++++- .../type/uploadsingle/assignment.class.php | 34 ++++++++- 3 files changed, 101 insertions(+), 38 deletions(-) diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php index 683b3de1697..82bbf46db07 100644 --- a/mod/assignment/lib.php +++ b/mod/assignment/lib.php @@ -1878,15 +1878,31 @@ class assignment_base { function get_submissions($sort='', $dir='DESC') { return assignment_get_all_submissions($this->assignment, $sort, $dir); } - + /** - * Counts all real assignment submissions by ENROLLED students (not empty ones) + * Counts all complete (real) assignment submissions by enrolled students * - * @param int $groupid optional If nonzero then count is restricted to this group - * @return int The number of submissions + * @param int $groupid (optional) If nonzero then count is restricted to this group + * @return int The number of submissions */ function count_real_submissions($groupid=0) { - return assignment_count_real_submissions($this->cm, $groupid); + global $CFG; + global $DB; + + // Grab the context assocated with our course module + $context = get_context_instance(CONTEXT_MODULE, $this->cm->id); + + // Get ids of users enrolled in the given course. + list($enroledsql, $params) = get_enrolled_sql($context, 'mod/assignment:view', $groupid); + $params['assignmentid'] = $this->cm->instance; + + // Get ids of users enrolled in the given course. + return $DB->count_records_sql("SELECT COUNT('x') + FROM {assignment_submissions} s + LEFT JOIN {assignment} a ON a.id = s.assignment + INNER JOIN ($enroledsql) u ON u.id = s.userid + WHERE s.assignment = :assignmentid AND + s.timemodified > 0", $params); } /** @@ -3463,44 +3479,38 @@ function assignment_get_unmailed_submissions($starttime, $endtime) { } /** - * Counts all real assignment submissions by ENROLLED students (not empty ones) - * - * There are also assignment type methods count_real_submissions() which in the default - * implementation simply call this function. - * @param $groupid int optional If nonzero then count is restricted to this group - * @return int The number of submissions + * Counts all complete (real) assignment submissions by enrolled students for the given course modeule. + * + * @deprecated Since Moodle 2.2 MDL-abc - Please do not use this function any more. + * @param cm_info $cm The course module that we wish to perform the count on. + * @param int $groupid (optional) If nonzero then count is restricted to this group + * @return int The number of submissions */ function assignment_count_real_submissions($cm, $groupid=0) { global $CFG, $DB; - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + // Grab the assignment type for the given course module + $assignmenttype = $DB->get_field($cm->modname, 'assignmenttype', array('id' => $cm->instance)); - // this is all the users with this capability set, in this context or higher - if ($users = get_enrolled_users($context, 'mod/assignment:view', $groupid, 'u.id')) { - $users = array_keys($users); + // Create the expected class file path and class name for the returned assignemnt type + $filename = "{$CFG->dirroot}/mod/assignment/type/{$assignmenttype}/assignment.class.php"; + $classname = "assignment_{$assignmenttype}"; + + // If the file exists and the class is not already loaded we require the class file + if (file_exists($file) && !class_exists($class)) { + require_once($file); } - - // if groupmembersonly used, remove users who are not in any group - if ($users and !empty($CFG->enablegroupmembersonly) and $cm->groupmembersonly) { - if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) { - $users = array_intersect($users, array_keys($groupingusers)); - } + // If the required class is still not loaded then we revert to assignment base + if (!class_exists($class)) { + $classname = 'assignment_base'; } + $instance = new $classname; - if (empty($users)) { - return 0; - } - - $userlists = implode(',', $users); - - return $DB->count_records_sql("SELECT COUNT('x') - FROM {assignment_submissions} - WHERE assignment = ? AND - timemodified > 0 AND - userid IN ($userlists)", array($cm->instance)); + // Attach the course module to the assignment type instance and then call the method for counting submissions + $instance->cm = $cm; + return $instance->count_real_submissions($groupid); } - /** * Return all assignment submissions by ENROLLED students (even empty) * diff --git a/mod/assignment/type/upload/assignment.class.php b/mod/assignment/type/upload/assignment.class.php index 16818c1134d..15319d85ede 100644 --- a/mod/assignment/type/upload/assignment.class.php +++ b/mod/assignment/type/upload/assignment.class.php @@ -396,6 +396,34 @@ class assignment_upload extends assignment_base { parent::process_feedback($mform); } + /** + * Counts all complete (real) assignment submissions by enrolled students. This overrides assignment_base::count_real_submissions(). + * This is necessary for advanced file uploads where we need to check that the data2 field is equal to "submitted" to determine + * if a submission is complete. + * + * @param int $groupid (optional) If nonzero then count is restricted to this group + * @return int The number of submissions + */ + function count_real_submissions($groupid=0) { + global $CFG; + global $DB; + + // Grab the context assocated with our course module + $context = get_context_instance(CONTEXT_MODULE, $this->cm->id); + + // Get ids of users enrolled in the given course. + list($enroledsql, $params) = get_enrolled_sql($context, 'mod/assignment:view', $groupid); + $params['assignmentid'] = $this->cm->instance; + + // Get ids of users enrolled in the given course. + return $DB->count_records_sql("SELECT COUNT('x') + FROM {assignment_submissions} s + LEFT JOIN {assignment} a ON a.id = s.assignment + INNER JOIN ($enroledsql) u ON u.id = s.userid + WHERE s.assignment = :assignmentid AND + s.data2 = 'submitted'", $params); + } + function print_responsefiles($userid, $return=false) { global $CFG, $USER, $OUTPUT, $PAGE; @@ -422,7 +450,6 @@ class assignment_upload extends assignment_base { echo $output; } - /** * Upload files * upload_file function requires moodle form instance and file manager options diff --git a/mod/assignment/type/uploadsingle/assignment.class.php b/mod/assignment/type/uploadsingle/assignment.class.php index bc2abe3796d..706489e96f2 100644 --- a/mod/assignment/type/uploadsingle/assignment.class.php +++ b/mod/assignment/type/uploadsingle/assignment.class.php @@ -92,7 +92,6 @@ class assignment_uploadsingle extends assignment_base { $this->view_footer(); } - function process_feedback() { if (!$feedback = data_submitted() or !confirm_sesskey()) { // No incoming data? return false; @@ -101,7 +100,35 @@ class assignment_uploadsingle extends assignment_base { $offset = required_param('offset', PARAM_INT); $mform = $this->display_submission($offset, $userid, false); parent::process_feedback($mform); - } + } + + /** + * Counts all complete (real) assignment submissions by enrolled students. This overrides assignment_base::count_real_submissions(). + * This is necessary for simple file uploads where we need to check that the numfiles field is greater than zero to determine if a + * submission is complete. + * + * @param int $groupid (optional) If nonzero then count is restricted to this group + * @return int The number of submissions + */ + function count_real_submissions($groupid=0) { + global $CFG; + global $DB; + + // Grab the context assocated with our course module + $context = get_context_instance(CONTEXT_MODULE, $this->cm->id); + + // Get ids of users enrolled in the given course. + list($enroledsql, $params) = get_enrolled_sql($context, 'mod/assignment:view', $groupid); + $params['assignmentid'] = $this->cm->instance; + + // Get ids of users enrolled in the given course. + return $DB->count_records_sql("SELECT COUNT('x') + FROM {assignment_submissions} s + LEFT JOIN {assignment} a ON a.id = s.assignment + INNER JOIN ($enroledsql) u ON u.id = s.userid + WHERE s.assignment = :assignmentid AND + s.numfiles > 0", $params); + } function print_responsefiles($userid, $return=false) { global $CFG, $USER, $OUTPUT, $PAGE; @@ -155,7 +182,6 @@ class assignment_uploadsingle extends assignment_base { echo $OUTPUT->box_end(); } - function upload($mform) { $action = required_param('action', PARAM_ALPHA); switch ($action) { @@ -434,4 +460,4 @@ class mod_assignment_uploadsingle_response_form extends moodleform { // buttons $this->add_action_buttons(false, get_string('uploadthisfile')); } -} \ No newline at end of file +}