public function test_quiz_report_index_by_keys() { $datum = array(); $object = new stdClass(); $object->qid = 3; $object->aid = 101; $object->response = ''; $object->grade = 3; $datum[] = $object; $indexed = quiz_report_index_by_keys($datum, array('aid', 'qid')); $this->assertEquals($indexed[101][3]->qid, 3); $this->assertEquals($indexed[101][3]->aid, 101); $this->assertEquals($indexed[101][3]->response, ''); $this->assertEquals($indexed[101][3]->grade, 3); $indexed = quiz_report_index_by_keys($datum, array('aid', 'qid'), false); $this->assertEquals($indexed[101][3][0]->qid, 3); $this->assertEquals($indexed[101][3][0]->aid, 101); $this->assertEquals($indexed[101][3][0]->response, ''); $this->assertEquals($indexed[101][3][0]->grade, 3); }
/** * Takes an array of objects and constructs a multidimensional array keyed by * the keys it finds on the object. * @param array $datum an array of objects with properties on the object * including the keys passed as the next param. * @param array $keys Array of strings with the names of the properties on the * objects in datum that you want to index the multidimensional array by. * @param bool $keysunique If there is not only one object for each * combination of keys you are using you should set $keysunique to true. * Otherwise all the object will be added to a zero based array. So the array * returned will have count($keys) + 1 indexs. * @return array multidimensional array properly indexed. */ function quiz_report_index_by_keys($datum, $keys, $keysunique = true) { if (!$datum) { return array(); } $key = array_shift($keys); $datumkeyed = array(); foreach ($datum as $data) { if ($keys || !$keysunique) { $datumkeyed[$data->{$key}][]= $data; } else { $datumkeyed[$data->{$key}]= $data; } } if ($keys) { foreach ($datumkeyed as $datakey => $datakeyed) { $datumkeyed[$datakey] = quiz_report_index_by_keys($datakeyed, $keys, $keysunique); } } return $datumkeyed; }
function quiz_questions_stats($quiz, $currentgroup, $nostudentsingroup, $useallattempts, $groupstudents, $questions) { global $DB; $timemodified = time() - QUIZ_REPORT_TIME_TO_CACHE_STATS; $params = array('quizid' => $quiz->id, 'groupid' => (int) $currentgroup, 'allattempts' => $useallattempts, 'timemodified' => $timemodified); if (!($quizstats = $DB->get_record_select('quiz_statistics', 'quizid = :quizid AND groupid = :groupid AND allattempts = :allattempts AND timemodified > :timemodified', $params, '*', true))) { list($s, $usingattemptsstring, $quizstats, $qstats) = $this->quiz_stats($nostudentsingroup, $quiz->id, $currentgroup, $groupstudents, $questions, $useallattempts); if ($s) { $toinsert = (object) ((array) $quizstats + $params); $toinsert->timemodified = time(); $quizstats->id = $DB->insert_record('quiz_statistics', $toinsert); foreach ($qstats->questions as $question) { $question->_stats->quizstatisticsid = $quizstats->id; $DB->insert_record('quiz_question_statistics', $question->_stats, false, true); } foreach ($qstats->subquestions as $subquestion) { $subquestion->_stats->quizstatisticsid = $quizstats->id; $DB->insert_record('quiz_question_statistics', $subquestion->_stats, false, true); } foreach ($qstats->responses as $response) { $response->quizstatisticsid = $quizstats->id; $DB->insert_record('quiz_question_response_stats', $response, false); } } if ($qstats) { $questions = $qstats->questions; $subquestions = $qstats->subquestions; } else { $questions = array(); $subquestions = array(); } } else { //use cached results if ($useallattempts) { $usingattemptsstring = get_string('allattempts', 'quiz_statistics'); $s = $quizstats->allattemptscount; } else { $usingattemptsstring = get_string('firstattempts', 'quiz_statistics'); $s = $quizstats->firstattemptscount; } $subquestions = array(); $questionstats = $DB->get_records('quiz_question_statistics', array('quizstatisticsid' => $quizstats->id), 'subquestion ASC'); $questionstats = quiz_report_index_by_keys($questionstats, array('subquestion', 'questionid')); if (1 < count($questionstats)) { list($mainquestionstats, $subquestionstats) = $questionstats; $subqstofetch = array_keys($subquestionstats); $subquestions = question_load_questions($subqstofetch); foreach (array_keys($subquestions) as $subqid) { $subquestions[$subqid]->_stats = $subquestionstats[$subqid]; } } elseif (count($questionstats)) { $mainquestionstats = $questionstats[0]; } if (count($questionstats)) { foreach (array_keys($questions) as $qid) { $questions[$qid]->_stats = $mainquestionstats[$qid]; } } } return array($quizstats, $questions, $subquestions, $s, $usingattemptsstring); }
function check_overall_grades($quiz, $userids=array(), $attemptids=array()) { global $DB; //recalculate $attempt->sumgrade //already updated in regrade_question_in_attempt $sql = "UPDATE {quiz_attempts} SET sumgrades= " . "COALESCE((SELECT SUM(qs.grade) FROM {question_sessions} qns, {question_states} qs " . "WHERE qns.newgraded = qs.id AND qns.attemptid = {quiz_attempts}.uniqueid ), 0) WHERE "; $attemptsql=''; if (!$attemptids) { if ($userids) { list($usql, $params) = $DB->get_in_or_equal($userids); $attemptsql .= "{quiz_attempts}.userid $usql AND "; } else { $params = array(); } $attemptsql .= "{quiz_attempts}.quiz =? AND preview = 0"; $params[] = $quiz->id; } else { list($asql, $params) = $DB->get_in_or_equal($attemptids); $attemptsql .= "{quiz_attempts}.uniqueid $asql"; } $sql .= $attemptsql; if (!$DB->execute($sql, $params)) { print_error('err_failedtorecalculateattemptgrades', 'quiz_overview'); } // Update the overall quiz grades if ($attemptids) { //make sure we fetch all attempts for users to calculate grade. //not just those that have changed. $sql = "SELECT qa2.* FROM {quiz_attempts} qa2 WHERE " . "qa2.userid IN (SELECT DISTINCT userid FROM {quiz_attempts} WHERE $attemptsql) " . "AND qa2.timefinish > 0"; } else { $sql = "SELECT * FROM {quiz_attempts} WHERE $attemptsql AND timefinish > 0"; } if ($attempts = $DB->get_records_sql($sql, $params)) { $attemptsbyuser = quiz_report_index_by_keys($attempts, array('userid', 'id')); foreach($attemptsbyuser as $userid => $attemptsforuser) { quiz_save_best_grade($quiz, $userid, $attemptsforuser); } } }
function quiz_get_regraded_qs($attemptidssql, $limitfrom = 0, $limitnum = 0) { global $CFG, $DB; if ($attemptidssql && is_array($attemptidssql)) { list($asql, $params) = $DB->get_in_or_equal($attemptidssql); $regradedqsql = "SELECT qqr.* FROM " . "{quiz_question_regrade} qqr " . "WHERE qqr.attemptid {$asql}"; $regradedqs = $DB->get_records_sql($regradedqsql, $params, $limitfrom, $limitnum); } else { if ($attemptidssql && is_object($attemptidssql)) { $regradedqsql = "SELECT qqr.* FROM " . $attemptidssql->from . ", " . "{quiz_question_regrade} qqr " . "WHERE qqr.attemptid = qa.uniqueid AND " . $attemptidssql->where; $regradedqs = $DB->get_records_sql($regradedqsql, $attemptidssql->params, $limitfrom, $limitnum); } else { return array(); } } return quiz_report_index_by_keys($regradedqs, array('attemptid', 'questionid')); }
/** * Get all the questions in all the attempts being displayed that need regrading. * @return array A two dimensional array $questionusageid => $slot => $regradeinfo. */ protected function get_regraded_questions() { global $DB; $qubaids = $this->get_qubaids_condition(); $regradedqs = $DB->get_records_select('quiz_overview_regrades', 'questionusageid ' . $qubaids->usage_id_in(), $qubaids->usage_id_in_params()); return quiz_report_index_by_keys($regradedqs, array('questionusageid', 'slot')); }