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);
 }
Exemple #2
0
/**
 * 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;
}
Exemple #3
0
 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);
 }
Exemple #4
0
    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);
            }
        }
    }
Exemple #5
0
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'));
 }