$currentgroup = groups_get_activity_group($this->cm, true);
$this->users = get_users_by_capability($this->context, 'mod/quiz:attempt','','','','',$currentgroup,'',false);
- $this->userids = implode(',', array_keys($this->users));
if (!empty($questionid)) {
echo '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>'; // for overlib
- if ($data = data_submitted()) { // post data submitted, process it
+ if ($data = data_submitted() && $this->users) { // post data submitted, process it
confirm_sesskey();
// now go through all of the responses and save them.
foreach($data->manualgrades as $uniqueid => $response) {
// get our attempt
$uniqueid = clean_param($uniqueid, PARAM_INT);
- list($usql, $params) = $DB->get_in_or_equal(explode(',', $this->userids));
+ list($usql, $params) = $DB->get_in_or_equal(array_keys($this->users));
if (!$attempt = $DB->get_record_sql("SELECT * FROM {quiz_attempts} " .
"WHERE uniqueid = ? AND " .
}
return true;
}
- $gradeablequestionids = implode(',',array_keys($gradeableqs));
- $qattempts = quiz_get_total_qas_graded_and_ungraded($quiz, $gradeablequestionids, $this->userids);
+ $qattempts = quiz_get_total_qas_graded_and_ungraded($quiz, array_keys($gradeableqs), array_keys($this->users));
if(empty($qattempts)) {
notify(get_string('noattemptstoshow', 'quiz'));
return true;
"ON (qs.id = qns.newgraded AND qs.question = ?) ";
$params[] = $questionid;
}
- list($usql, $u_params) = $DB->get_in_or_equal(explode(',', $this->userids));
+ list($usql, $u_params) = $DB->get_in_or_equal(array_keys($this->users));
if ($gradenextungraded || $gradeungraded) { // get ungraded attempts
- $where = 'WHERE u.id $usql AND qs.event NOT IN ('.QUESTION_EVENTS_GRADED.') ';
+ $where = "WHERE u.id $usql AND qs.event NOT IN (".QUESTION_EVENTS_GRADED.') ';
$params = array_merge($params, $u_params);
} else if ($userid) { // get all the attempts for a specific user
$where = 'WHERE u.id=?';
$namekey = 'fullname';
}
if ($this->groupstudents){
- list($g_usql, $g_params) = $DB->get_in_or_equal(explode(',', $this->groupstudents));
+ list($g_usql, $g_params) = $DB->get_in_or_equal($this->groupstudents);
$groupaveragesql = $averagesql." AND qg.userid $g_usql";
$groupaverage = $DB->get_record_sql($groupaveragesql, array_merge($params, $g_params));
$this->add_data_keyed($groupaveragerow);
}
- list($s_usql, $s_params) = $DB->get_in_or_equal(explode(',', $this->students));
+ list($s_usql, $s_params) = $DB->get_in_or_equal($this->students);
$overallaverage = $DB->get_record_sql($averagesql." AND qg.userid $s_usql", array_merge($params, $s_params));
$overallaveragerow = array($namekey => get_string('overallaverage', 'grades'),
'sumgrades' => round($overallaverage->grade, $this->quiz->decimalpoints),
}
}
+
+ function query_db($pagesize, $useinitialsbar=true){
+ // Add table joins so we can sort by question grade
+ // unfortunately can't join all tables necessary to fetch all grades
+ // to get the state for one question per attempt row we must join two tables
+ // and there is a limit to how many joins you can have in one query. In MySQL it
+ // is 61. This means that when having more than 29 questions the query will fail.
+ // So we join just the tables needed to sort the attempts.
+ if($sort = $this->get_sql_sort()) {
+ if ($this->detailedmarks) {
+ $this->sql->from .= ' ';
+ $sortparts = explode(',', $sort);
+ $matches = array();
+ foreach($sortparts as $sortpart) {
+ $sortpart = trim($sortpart);
+ if (preg_match('/^qsgrade([0-9]+)/', $sortpart, $matches)){
+ $qid = intval($matches[1]);
+ $this->sql->fields .= ", qs$qid.grade AS qsgrade$qid, qs$qid.event AS qsevent$qid, qs$qid.id AS qsid$qid";
+ $this->sql->from .= "LEFT JOIN {question_sessions} qns$qid ON qns$qid.attemptid = qa.uniqueid AND qns$qid.questionid = :qid$qid ";
+ $this->sql->from .= "LEFT JOIN {question_states} qs$qid ON qs$qid.id = qns$qid.newgraded ";
+ $this->sql->params['qid'.$qid] = $qid;
+ }
+ }
+ }
+ }
+ parent::query_db($pagesize, $useinitialsbar);
+ }
}
?>
}
$line->x_data = $bandlabels;
-$useridlist = join(',',array_keys(get_users_by_capability($modcontext, 'mod/quiz:attempt','','','','','','',false)));
-$line->y_data['allusers'] = quiz_report_grade_bands($bandwidth, $bands, $quizid, $useridlist);
+$userids = array_keys(get_users_by_capability($modcontext, 'mod/quiz:attempt','','','','','','',false));
+$line->y_data['allusers'] = quiz_report_grade_bands($bandwidth, $bands, $quizid, $userids);
if ($currentgroup){
//only turn on legends if there is more than one set of bars
$line->parameter['legend'] = 'outside-top';
$pageoptions['mode'] = 'overview';
$reporturl = new moodle_url($CFG->wwwroot.'/mod/quiz/report.php', $pageoptions);
- list($qmsubselect, $params) = quiz_report_qm_filter_subselect($quiz); // careful: these are named params in $params!!
+ $qmsubselect = quiz_report_qm_filter_subselect($quiz); // careful: these are named params in $params!!
$mform = new mod_quiz_report_overview_settings($reporturl, array('qmsubselect'=> $qmsubselect, 'quiz'=>$quiz));
if ($fromform = $mform->get_data()){
//work out the sql for this table.
if (!$students = get_users_by_capability($context, 'mod/quiz:attempt','','','','','','',false)){
$students = array();
+ } else {
+ $students = array_keys($students);
}
- $studentslist = join(',',array_keys($students));
if (empty($currentgroup)) {
// all users who can attempt quizzes
- $groupstudentslist = '';
- $allowedlist = explode(',', $studentslist);
+ $allowed = $students;
+ $groupstudents = array();
} else {
// all users who can attempt quizzes and who are in the currently selected group
if (!$groupstudents = get_users_by_capability($context, 'mod/quiz:attempt','','','','',$currentgroup,'',false)){
$groupstudents = array();
+ } else {
+ $groupstudents = array_keys($groupstudents);
}
- $allowedlist = array_keys($groupstudents);
- $groupstudentslist = join(',', $allowedlist);
+ $allowed = $groupstudents;
}
if ($detailedmarks) {
} else {
$questions = array();
}
- $table = new quiz_report_overview_table($quiz , $qmsubselect, $groupstudentslist,
- $studentslist, $detailedmarks, $questions, $candelete, $reporturl, $displayoptions);
+ $table = new quiz_report_overview_table($quiz , $qmsubselect, $groupstudents,
+ $students, $detailedmarks, $questions, $candelete, $reporturl, $displayoptions);
$table->is_downloading($download, get_string('reportoverview','quiz'),
"$COURSE->shortname ".format_string($quiz->name,true));
if (!$table->is_downloading()) {
// This part is the same for all cases - join users and quiz_attempts tables
$from = '{user} u ';
$from .= 'LEFT JOIN {quiz_attempts} qa ON qa.userid = u.id AND qa.quiz = :quizid';
- $params["quizid"] = $quiz->id;
+ $params = array('quizid' => $quiz->id);
if ($qmsubselect && $qmfilter){
$from .= ' AND '.$qmsubselect;
break;
case QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH:
// Show only students with attempts
- list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowedlist, SQL_PARAMS_NAMED, 'u0000');
+ list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowed, SQL_PARAMS_NAMED, 'u0000');
$params += $allowed_params;
$where = "u.id $allowed_usql AND qa.preview = 0 AND qa.id IS NOT NULL";
break;
case QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH_NO:
// Show only students without attempts
- list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowedlist, SQL_PARAMS_NAMED, 'u0000');
+ list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowed, SQL_PARAMS_NAMED, 'u0000');
$params += $allowed_params;
$where = "u.id $allowed_usql AND qa.id IS NULL";
break;
case QUIZ_REPORT_ATTEMPTS_ALL_STUDENTS:
// Show all students with or without attempts
- list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowedlist, SQL_PARAMS_NAMED, 'u0000');
+ list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowed, SQL_PARAMS_NAMED, 'u0000');
$params += $allowed_params;
$where = "u.id $allowed_usql AND (qa.preview = 0 OR qa.preview IS NULL)";
break;
$table->set_count_sql("SELECT COUNT(1) FROM $from WHERE $where", $params);
- // Add table joins so we can sort by question grade
- // unfortunately can't join all tables necessary to fetch all grades
- // to get the state for one question per attempt row we must join two tables
- // and there is a limit to how many joins you can have in one query. In MySQL it
- // is 61. This means that when having more than 29 questions the query will fail.
- // So we join just the tables needed to sort the attempts.
- if($sort = $table->get_sql_sort()) {
- if (!$table->is_downloading() && $detailedmarks) {
- $from .= ' ';
- $sortparts = explode(',', $sort);
- $matches = array();
- foreach($sortparts as $sortpart) {
- $sortpart = trim($sortpart);
- if (preg_match('/^qsgrade([0-9]+)/', $sortpart, $matches)){
- $qid = intval($matches[1]);
- $fields .= ", qs$qid.grade AS qsgrade$qid, qs$qid.event AS qsevent$qid, qs$qid.id AS qsid$qid";
- $from .= "LEFT JOIN {question_sessions} qns$qid ON qns$qid.attemptid = qa.uniqueid AND qns$qid.questionid = :qid ";
- $from .= "LEFT JOIN {question_states} qs$qid ON qs$qid.id = qns$qid.newgraded ";
- $params['qid'] = $qid;
- } else {
- $newsort[] = $sortpart;
- }
- }
- $select .= ' ';
- }
- }
+
$table->set_sql($fields, $from, $where, $params);
+
// Define table columns
$columns = array();
$headers = array();
function quiz_get_average_grade_for_questions($quiz, $userids){
global $CFG, $DB;
- list($qmfilter, $params) = quiz_report_qm_filter_subselect($quiz, 'qa.userid'); //NAMED PARAMS!
- $params['quizid2'] = $quiz->id;
- list($usql, $u_params) = $DB->get_in_or_equal(explode(',', $userids), SQL_PARAMS_NAMED, 'u0000');
+ $qmfilter = quiz_report_qm_filter_subselect($quiz, 'qa.userid');
+ $params['quizid'] = $quiz->id;
+ list($usql, $u_params) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED, 'u0000');
$params += $u_params;
$questionavgssql = "SELECT qs.question, AVG(qs.grade) FROM
{question_sessions} qns,
{question_states} qs
WHERE qns.attemptid = qa.uniqueid AND " .
($qmfilter?$qmfilter.' AND ':'') . "
- qa.quiz = :quizid2 AND
+ qa.quiz = :quizid AND
qa.userid $usql AND
qs.event IN (".QUESTION_EVENTS_GRADED.") AND
qns.newgraded = qs.id GROUP BY qs.question";
function quiz_get_total_qas_graded_and_ungraded($quiz, $questionids, $userids){
global $CFG, $DB;
$params = array($quiz->id);
- list($u_sql, $u_params) = $DB->get_in_or_equal(explode(',', $userids));
- list($q_sql, $q_params) = $DB->get_in_or_equal(explode(',', $questionids));
+ list($u_sql, $u_params) = $DB->get_in_or_equal($userids);
+ list($q_sql, $q_params) = $DB->get_in_or_equal($questionids);
$params = array_merge($params, $u_params, $q_params);
$sql = "SELECT qs.question, COUNT(1) AS totalattempts,
* one attempt that will be graded for each user. Or return
* empty string if all attempts contribute to final grade.
*/
-function quiz_report_qm_filter_subselect($quiz, $useridsql = 'u.id'){
+function quiz_report_qm_filter_subselect($quiz, $useridsql = 'u.id', $quizidsql = 'qa.quiz'){
global $CFG;
if ($quiz->attempts == 1) {//only one attempt allowed on this quiz
return '';
break;
}
- $params = array();
+ //no new params in this query, it is assumed that quizid will be used somewhere else
+ //in the main query.
if ($qmfilterattempts){
$qmsubselect = "(SELECT id FROM {quiz_attempts} " .
- "WHERE quiz = :quizid1 AND $useridsql = userid " .
+ "WHERE quiz = $quizidsql AND userid = $useridsql " .
"ORDER BY $qmorderby LIMIT 1)=qa.id";
- $params['quizid1'] = $quiz->id;
} else {
$qmsubselect = '';
}
- return array($qmsubselect, $params);
+ return $qmsubselect;
}
-function quiz_report_grade_bands($bandwidth, $bands, $quizid, $useridlist){
+function quiz_report_grade_bands($bandwidth, $bands, $quizid, $userids){
global $CFG, $DB;
- list($usql, $params) = $DB->get_in_or_equal(explode(',', $useridlist));
+ list($usql, $params) = $DB->get_in_or_equal($userids);
$sql = "SELECT
FLOOR(qg.grade/$bandwidth) AS band,
COUNT(1) AS num
WHERE qg.quiz = q.id AND qg.userid $usql AND qg.quiz = ?
GROUP BY band
ORDER BY band";
- $params[] = $quiz->id;
+ $params[] = $quizid;
$data = $DB->get_records_sql_menu($sql, $params);
//need to create array elements with values 0 at indexes where there is no element
$data = $data + array_fill(0, $bands+1, 0);