/** * Store an entire {@link question_attempt} in the database, * including all the question_attempt_steps that comprise it. * @param question_attempt $qa the question attempt to store. * @param object $context the context of the owning question_usage_by_activity. */ public function insert_question_attempt(question_attempt $qa, $context) { $record = new stdClass(); $record->questionusageid = $qa->get_usage_id(); $record->slot = $qa->get_slot(); $record->behaviour = $qa->get_behaviour_name(); $record->questionid = $qa->get_question()->id; $record->variant = $qa->get_variant(); $record->maxmark = $qa->get_max_mark(); $record->minfraction = $qa->get_min_fraction(); $record->flagged = $qa->is_flagged(); $record->questionsummary = $qa->get_question_summary(); $record->rightanswer = $qa->get_right_answer_summary(); $record->responsesummary = $qa->get_response_summary(); $record->timemodified = time(); $record->id = $this->db->insert_record('question_attempts', $record); foreach ($qa->get_step_iterator() as $seq => $step) { $this->insert_question_attempt_step($step, $record->id, $seq, $context); } }
/** * Perform a regrade. This replays all the actions from $oldqa into this * attempt. * @param question_attempt $oldqa the attempt to regrade. * @param bool $finished whether the question attempt should be forced to be finished * after the regrade, or whether it may still be in progress (default false). */ public function regrade(question_attempt $oldqa, $finished) { $first = true; foreach ($oldqa->get_step_iterator() as $step) { $this->observer->notify_step_deleted($step, $this); if ($first) { // First step of the attempt. $first = false; $this->start($oldqa->behaviour, $oldqa->get_variant(), $step->get_all_data(), $step->get_timecreated(), $step->get_user_id(), $step->get_id()); } else { if ($step->has_behaviour_var('finish') && count($step->get_submitted_data()) > 1) { // This case relates to MDL-32062. The upgrade code from 2.0 // generates attempts where the final submit of the question // data, and the finish action, are in the same step. The system // cannot cope with that, so convert the single old step into // two new steps. $submitteddata = $step->get_submitted_data(); unset($submitteddata['-finish']); $this->process_action($submitteddata, $step->get_timecreated(), $step->get_user_id(), $step->get_id()); $this->finish($step->get_timecreated(), $step->get_user_id()); } else { // This is the normal case. Replay the next step of the attempt. $this->process_action($step->get_submitted_data(), $step->get_timecreated(), $step->get_user_id(), $step->get_id()); } } } if ($finished) { $this->finish(); } }
/** * Store an entire {@link question_attempt} in the database, * including all the question_attempt_steps that comprise it. * @param question_attempt $qa the question attempt to store. * @param context $context the context of the owning question_usage_by_activity. */ public function insert_question_attempt(question_attempt $qa, $context) { $record = new stdClass(); $record->questionusageid = $qa->get_usage_id(); $record->slot = $qa->get_slot(); $record->behaviour = $qa->get_behaviour_name(); $record->questionid = $qa->get_question()->id; $record->variant = $qa->get_variant(); $record->maxmark = $qa->get_max_mark(); $record->minfraction = $qa->get_min_fraction(); $record->maxfraction = $qa->get_max_fraction(); $record->flagged = $qa->is_flagged(); $record->questionsummary = $qa->get_question_summary(); if (core_text::strlen($record->questionsummary) > question_bank::MAX_SUMMARY_LENGTH) { // It seems some people write very long quesions! MDL-30760 $record->questionsummary = core_text::substr($record->questionsummary, 0, question_bank::MAX_SUMMARY_LENGTH - 3) . '...'; } $record->rightanswer = $qa->get_right_answer_summary(); $record->responsesummary = $qa->get_response_summary(); $record->timemodified = time(); $record->id = $this->db->insert_record('question_attempts', $record); $qa->set_database_id($record->id); foreach ($qa->get_step_iterator() as $seq => $step) { $this->insert_question_attempt_step($step, $record->id, $seq, $context); } }
/** * Perform a regrade. This replays all the actions from $oldqa into this * attempt. * @param question_attempt $oldqa the attempt to regrade. * @param bool $finished whether the question attempt should be forced to be finished * after the regrade, or whether it may still be in progress (default false). */ public function regrade(question_attempt $oldqa, $finished) { $first = true; foreach ($oldqa->get_step_iterator() as $step) { $this->observer->notify_step_deleted($step, $this); if ($first) { $first = false; $this->start($oldqa->behaviour, $oldqa->get_variant(), $step->get_all_data(), $step->get_timecreated(), $step->get_user_id(), $step->get_id()); } else { $this->process_action($step->get_submitted_data(), $step->get_timecreated(), $step->get_user_id(), $step->get_id()); } } if ($finished) { $this->finish(); } }
/** * Store an entire {@link question_attempt} in the database, * including all the question_attempt_steps that comprise it. * * You should not call this method directly. You should use * @link question_engine::save_questions_usage_by_activity()}. * * @param question_attempt $qa the question attempt to store. * @param context $context the context of the owning question_usage_by_activity. * @return array of question_attempt_step_data rows, that still need to be inserted. */ public function insert_question_attempt(question_attempt $qa, $context) { $record = new stdClass(); $record->questionusageid = $qa->get_usage_id(); $record->slot = $qa->get_slot(); $record->behaviour = $qa->get_behaviour_name(); $record->questionid = $qa->get_question()->id; $record->variant = $qa->get_variant(); $record->maxmark = $qa->get_max_mark(); $record->minfraction = $qa->get_min_fraction(); $record->maxfraction = $qa->get_max_fraction(); $record->flagged = $qa->is_flagged(); $record->questionsummary = $qa->get_question_summary(); if (core_text::strlen($record->questionsummary) > question_bank::MAX_SUMMARY_LENGTH) { // It seems some people write very long quesions! MDL-30760 $record->questionsummary = core_text::substr($record->questionsummary, 0, question_bank::MAX_SUMMARY_LENGTH - 3) . '...'; } $record->rightanswer = $qa->get_right_answer_summary(); $record->responsesummary = $qa->get_response_summary(); $record->timemodified = time(); $record->id = $this->db->insert_record('question_attempts', $record); $qa->set_database_id($record->id); // Initially an array of array of question_attempt_step_objects. // Built as a nested array for efficiency, then flattened. $stepdata = array(); foreach ($qa->get_step_iterator() as $seq => $step) { $stepdata[] = $this->insert_question_attempt_step($step, $record->id, $seq, $context); } return call_user_func_array('array_merge', $stepdata); }
/** * Update a question_attempts row to refect any changes in a question_attempt * (but not any of its steps). * * You should not call this method directly. You should use * @link question_engine::save_questions_usage_by_activity()}. * * @param question_attempt $qa the question attempt that has changed. */ public function update_question_attempt(question_attempt $qa) { $record = new stdClass(); $record->id = $qa->get_database_id(); $record->slot = $qa->get_slot(); $record->variant = $qa->get_variant(); $record->maxmark = $qa->get_max_mark(); $record->minfraction = $qa->get_min_fraction(); $record->maxfraction = $qa->get_max_fraction(); $record->flagged = $qa->is_flagged(); $record->questionsummary = $qa->get_question_summary(); $record->rightanswer = $qa->get_right_answer_summary(); $record->responsesummary = $qa->get_response_summary(); $record->timemodified = time(); $this->db->update_record('question_attempts', $record); }