protected function check_typical_question_attempts_query(qubaid_condition $qubaids, $expectedsql, $expectedparams)
 {
     $sql = "SELECT qa.id, qa.maxmark\n            FROM {$qubaids->from_question_attempts('qa')}\n            WHERE {$qubaids->where()} AND qa.slot = :slot";
     $this->assertEqual($expectedsql, $sql);
     $params = $qubaids->from_where_params();
     $params['slot'] = 1;
     $this->assertEqual($expectedparams, $params);
 }
Example #2
0
 protected function check_typical_question_attempts_query(qubaid_condition $qubaids, $expectedsql, $expectedparams)
 {
     $sql = "SELECT qa.id, qa.maxmark\n            FROM {$qubaids->from_question_attempts('qa')}\n            WHERE {$qubaids->where()} AND qa.slot = :slot";
     $params = $qubaids->from_where_params();
     $params['slot'] = 1;
     // NOTE: parameter names may change thanks to $DB->inorequaluniqueindex, normal comparison is very wrong!!
     list($sql, $params) = $this->normalize_sql($sql, $params);
     list($expectedsql, $expectedparams) = $this->normalize_sql($expectedsql, $expectedparams);
     $this->assertEquals($expectedsql, $sql);
     $this->assertEquals($expectedparams, $params);
 }
Example #3
0
 /**
  * Get a subquery that returns the latest step of every qa in some qubas.
  * Currently, this is only used by the quiz reports. See
  * {@link quiz_attempts_report_table::add_latest_state_join()}.
  * @param string $alias alias to use for this inline-view.
  * @param qubaid_condition $qubaids restriction on which question_usages we
  *      are interested in. This is important for performance.
  * @return array with two elements, the SQL fragment and any params requried.
  */
 public function question_attempt_latest_state_view($alias, qubaid_condition $qubaids)
 {
     return array("(\n                SELECT {$alias}qa.id AS questionattemptid,\n                       {$alias}qa.questionusageid,\n                       {$alias}qa.slot,\n                       {$alias}qa.behaviour,\n                       {$alias}qa.questionid,\n                       {$alias}qa.variant,\n                       {$alias}qa.maxmark,\n                       {$alias}qa.minfraction,\n                       {$alias}qa.maxfraction,\n                       {$alias}qa.flagged,\n                       {$alias}qa.questionsummary,\n                       {$alias}qa.rightanswer,\n                       {$alias}qa.responsesummary,\n                       {$alias}qa.timemodified,\n                       {$alias}qas.id AS attemptstepid,\n                       {$alias}qas.sequencenumber,\n                       {$alias}qas.state,\n                       {$alias}qas.fraction,\n                       {$alias}qas.timecreated,\n                       {$alias}qas.userid\n\n                  FROM {$qubaids->from_question_attempts($alias . 'qa')}\n                  JOIN {question_attempt_steps} {$alias}qas ON\n                           {$alias}qas.id = {$this->latest_step_for_qa_subquery($alias . 'qa.id')}\n                 WHERE {$qubaids->where()}\n            ) {$alias}", $qubaids->from_where_params());
 }
Example #4
0
 /**
  * Get the ids of all the questions in a list of categories, with the number
  * of times they have already been used in a given set of usages.
  *
  * The result array is returned in order of increasing (count previous uses).
  *
  * @param array $categoryids an array question_category ids.
  * @param qubaid_condition $qubaids which question_usages to count previous uses from.
  * @param string $extraconditions extra conditions to AND with the rest of
  *      the where clause. Must use named parameters.
  * @param array $extraparams any parameters used by $extraconditions.
  * @return array questionid => count of number of previous uses.
  */
 public function get_questions_from_categories_with_usage_counts($categoryids, qubaid_condition $qubaids, $extraconditions = '', $extraparams = array())
 {
     global $DB;
     list($qcsql, $qcparams) = $DB->get_in_or_equal($categoryids, SQL_PARAMS_NAMED, 'qc');
     if ($extraconditions) {
         $extraconditions = ' AND (' . $extraconditions . ')';
     }
     return $DB->get_records_sql_menu("\n                    SELECT q.id, (SELECT COUNT(1)\n                                    FROM " . $qubaids->from_question_attempts('qa') . "\n                                   WHERE qa.questionid = q.id AND " . $qubaids->where() . "\n                                 ) AS previous_attempts\n\n                      FROM {question} q\n\n                     WHERE q.category {$qcsql} {$extraconditions}\n\n                  ORDER BY previous_attempts\n                ", $qubaids->from_where_params() + $qcparams + $extraparams);
 }
 /**
  * Load a {@link question_attempt} from the database, including all its
  * steps.
  * @param int $questionid the question to load all the attempts fors.
  * @param qubaid_condition $qubaids used to restrict which usages are included
  * in the query. See {@link qubaid_condition}.
  * @return array of question_attempts.
  */
 public function load_attempts_at_question($questionid, qubaid_condition $qubaids)
 {
     global $DB;
     $params = $qubaids->from_where_params();
     $params['questionid'] = $questionid;
     $records = $DB->get_recordset_sql("\nSELECT\n    quba.contextid,\n    quba.preferredbehaviour,\n    qa.id AS questionattemptid,\n    qa.questionusageid,\n    qa.slot,\n    qa.behaviour,\n    qa.questionid,\n    qa.variant,\n    qa.maxmark,\n    qa.minfraction,\n    qa.flagged,\n    qa.questionsummary,\n    qa.rightanswer,\n    qa.responsesummary,\n    qa.timemodified,\n    qas.id AS attemptstepid,\n    qas.sequencenumber,\n    qas.state,\n    qas.fraction,\n    qas.timecreated,\n    qas.userid,\n    qasd.name,\n    qasd.value\n\nFROM {$qubaids->from_question_attempts('qa')}\nJOIN {question_usages} quba ON quba.id = qa.questionusageid\nLEFT JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id\nLEFT JOIN {question_attempt_step_data} qasd ON qasd.attemptstepid = qas.id\n\nWHERE\n    {$qubaids->where()} AND\n    qa.questionid = :questionid\n\nORDER BY\n    quba.id,\n    qa.id,\n    qas.sequencenumber\n        ", $params);
     $questionattempts = array();
     while ($records->valid()) {
         $record = $records->current();
         $questionattempts[$record->questionattemptid] = question_attempt::load_from_records($records, $record->questionattemptid, new question_usage_null_observer(), $record->preferredbehaviour);
     }
     $records->close();
     return $questionattempts;
 }
Example #6
0
 /**
  * Get the number of times each variant has been used for each question in a list
  * in a set of usages.
  * @param array $questionids of question ids.
  * @param qubaid_condition $qubaids ids of the usages to consider.
  * @return array questionid => variant number => num uses.
  */
 public function load_used_variants(array $questionids, qubaid_condition $qubaids)
 {
     list($test, $params) = $this->db->get_in_or_equal($questionids, SQL_PARAMS_NAMED, 'qid');
     $recordset = $this->db->get_recordset_sql("\n                SELECT qa.questionid, qa.variant, COUNT(1) AS usescount\n                  FROM " . $qubaids->from_question_attempts('qa') . "\n                 WHERE qa.questionid {$test}\n                   AND " . $qubaids->where() . "\n              GROUP BY qa.questionid, qa.variant\n              ORDER BY COUNT(1) ASC\n                ", $params + $qubaids->from_where_params());
     $usedvariants = array_combine($questionids, array_fill(0, count($questionids), array()));
     foreach ($recordset as $row) {
         $usedvariants[$row->questionid][$row->variant] = $row->usescount;
     }
     $recordset->close();
     return $usedvariants;
 }
Example #7
0
 /**
  * Get all the STACK questions used in all the attempts at a quiz. (Note that
  * Moodle random questions may be being used.)
  * @param qubaid_condition $qubaids the attempts of interest.
  * @return array of rows from the question table.
  */
 protected function get_stack_questions_used_in_attempt(qubaid_condition $qubaids)
 {
     global $DB;
     return $DB->get_records_sql("\n                SELECT q.*\n                  FROM {question} q\n                  JOIN (\n                        SELECT qa.questionid, MIN(qa.slot) AS firstslot\n                          FROM {$qubaids->from_question_attempts('qa')}\n                         WHERE {$qubaids->where()}\n                      GROUP BY qa.questionid\n                       ) usedquestionids ON q.id = usedquestionids.questionid\n                 WHERE q.qtype = 'stack'\n              ORDER BY usedquestionids.firstslot\n                ", $qubaids->from_where_params());
 }