From: jamiesensei Date: Mon, 9 Jun 2008 13:27:31 +0000 (+0000) Subject: MDL-15113 "quiz dml conversion" - fixing some sql broken during the conversion and... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=8673a566150c2eeea9662e023a1c0f28507ff114;p=moodle.git MDL-15113 "quiz dml conversion" - fixing some sql broken during the conversion and removing unnecessary comma seperated list of ids where there are arrays of ids that can be used instead. --- diff --git a/mod/quiz/report/grading/report.php b/mod/quiz/report/grading/report.php index 290bcb1f59..6270b209fb 100644 --- a/mod/quiz/report/grading/report.php +++ b/mod/quiz/report/grading/report.php @@ -83,7 +83,6 @@ class quiz_report extends quiz_default_report { $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)) { @@ -113,7 +112,7 @@ class quiz_report extends quiz_default_report { echo ''; // 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. @@ -121,7 +120,7 @@ class quiz_report extends quiz_default_report { 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 " . @@ -171,8 +170,7 @@ class quiz_report extends quiz_default_report { } 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; @@ -449,9 +447,9 @@ class quiz_report extends quiz_default_report { "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=?'; diff --git a/mod/quiz/report/overview/overview_table.php b/mod/quiz/report/overview/overview_table.php index dd891676b9..6daeb7c6f8 100644 --- a/mod/quiz/report/overview/overview_table.php +++ b/mod/quiz/report/overview/overview_table.php @@ -41,7 +41,7 @@ class quiz_report_overview_table extends table_sql { $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)); @@ -55,7 +55,7 @@ class quiz_report_overview_table extends table_sql { $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), @@ -218,5 +218,32 @@ class quiz_report_overview_table extends table_sql { } } + + 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); + } } ?> diff --git a/mod/quiz/report/overview/overviewgraph.php b/mod/quiz/report/overview/overviewgraph.php index 88d65faf69..10b48be1e7 100644 --- a/mod/quiz/report/overview/overviewgraph.php +++ b/mod/quiz/report/overview/overviewgraph.php @@ -58,8 +58,8 @@ for ($i=0;$i < $quiz->grade;$i += $bandwidth){ } $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'; diff --git a/mod/quiz/report/overview/report.php b/mod/quiz/report/overview/report.php index 87ccdeda98..3046809b7d 100644 --- a/mod/quiz/report/overview/report.php +++ b/mod/quiz/report/overview/report.php @@ -53,7 +53,7 @@ class quiz_report extends quiz_default_report { $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()){ @@ -98,20 +98,22 @@ class quiz_report extends quiz_default_report { //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) { @@ -119,8 +121,8 @@ class quiz_report extends quiz_default_report { } 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()) { @@ -170,7 +172,7 @@ class quiz_report extends quiz_default_report { // 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; @@ -182,19 +184,19 @@ class quiz_report extends quiz_default_report { 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; @@ -202,34 +204,10 @@ class quiz_report extends quiz_default_report { $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(); diff --git a/mod/quiz/report/reportlib.php b/mod/quiz/report/reportlib.php index 33d89a940f..eb0254c53e 100644 --- a/mod/quiz/report/reportlib.php +++ b/mod/quiz/report/reportlib.php @@ -40,9 +40,9 @@ function quiz_get_newgraded_states($attemptids, $idxattemptq = true, $fields='qs 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, @@ -50,7 +50,7 @@ function quiz_get_average_grade_for_questions($quiz, $userids){ {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"; @@ -60,8 +60,8 @@ function quiz_get_average_grade_for_questions($quiz, $userids){ 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, @@ -143,7 +143,7 @@ function quiz_report_load_questions($quiz){ * 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 ''; @@ -164,21 +164,21 @@ function quiz_report_qm_filter_subselect($quiz, $useridsql = 'u.id'){ 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 @@ -187,7 +187,7 @@ function quiz_report_grade_bands($bandwidth, $bands, $quizid, $useridlist){ 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);