$oldquestions = explode(',', $quiz->questions); // The questions in the old order. $questions = array(); // For questions in the new order. $rawdata = (array) data_submitted(); $moveonpagequestions = array(); $moveselectedonpage = optional_param('moveselectedonpagetop', 0, PARAM_INT); if (!$moveselectedonpage) { $moveselectedonpage = optional_param('moveselectedonpagebottom', 0, PARAM_INT); } foreach ($rawdata as $key => $value) { if (preg_match('!^g([0-9]+)$!', $key, $matches)) { // Parse input for question -> grades. $questionid = $matches[1]; $quiz->grades[$questionid] = unformat_float($value); quiz_update_question_instance($quiz->grades[$questionid], $questionid, $quiz); $deletepreviews = true; $recomputesummarks = true; } else { if (preg_match('!^o(pg)?([0-9]+)$!', $key, $matches)) { // Parse input for ordering info. $questionid = $matches[2]; // Make sure two questions don't overwrite each other. If we get a second // question with the same position, shift the second one along to the next gap. $value = clean_param($value, PARAM_INTEGER); while (array_key_exists($value, $questions)) { $value++; } if ($matches[1]) { // This is a page-break entry. $questions[$value] = 0;
/** * Add a question to a quiz * * Adds a question to a quiz by updating $quiz as well as the * quiz and quiz_question_instances tables. It also adds a page break * if required. * @return boolean false if the question was already in the quiz * @param int $id The id of the question to be added * @param object $quiz The extended quiz object as used by edit.php * This is updated by this function * @param int $page Which page in quiz to add the question on; if 0 (default), add at the end */ function quiz_add_quiz_question($id, &$quiz, $page = 0) { global $DB; $questions = explode(',', $quiz->questions); if (in_array($id, $questions)) { return false; } // remove ending page break if it is not needed if ($breaks = array_keys($questions, 0)) { // determine location of the last two page breaks $end = end($breaks); $last = prev($breaks); $last = $last ? $last : -1; if (!$quiz->questionsperpage || $end - $last - 1 < $quiz->questionsperpage) { array_pop($questions); } } if (is_int($page) && $page >= 1) { $numofpages = quiz_number_of_pages($quiz->questions); if ($numofpages < $page) { //the page specified does not exist in quiz $page = 0; } else { // add ending page break - the following logic requires doing //this at this point $questions[] = 0; $currentpage = 1; $addnow = false; foreach ($questions as $question) { if ($question == 0) { $currentpage++; //The current page is the one after the one we want to add on, //so we add the question before adding the current page. if ($currentpage == $page + 1) { $questions_new[] = $id; } } $questions_new[] = $question; } $questions = $questions_new; } } if ($page == 0) { // add question $questions[] = $id; // add ending page break $questions[] = 0; } // Save new questionslist in database $quiz->questions = implode(',', $questions); if (!$DB->set_field('quiz', 'questions', $quiz->questions, array('id' => $quiz->id))) { print_error('cannotsavequestion', 'quiz'); } // update question grades $quiz->grades[$id] = $DB->get_field('question', 'defaultgrade', array('id' => $id)); quiz_update_question_instance($quiz->grades[$id], $id, $quiz->instance); return true; }
/** * Add a question to a quiz * * Adds a question to a quiz by updating $quiz as well as the * quiz and quiz_question_instances tables. It also adds a page break * if required. * @return boolean false if the question was already in the quiz * @param int $id The id of the question to be added * @param object $quiz The extended quiz object as used by edit.php * This is updated by this function */ function quiz_add_quiz_question($id, &$quiz) { $questions = explode(",", $quiz->questions); if (in_array($id, $questions)) { return false; } // remove ending page break if it is not needed if ($breaks = array_keys($questions, 0)) { // determine location of the last two page breaks $end = end($breaks); $last = prev($breaks); $last = $last ? $last : -1; if (!$quiz->questionsperpage or $end - $last - 1 < $quiz->questionsperpage) { array_pop($questions); } } // add question $questions[] = $id; // add ending page break $questions[] = 0; // Save new questionslist in database $quiz->questions = implode(",", $questions); if (!set_field('quiz', 'questions', $quiz->questions, 'id', $quiz->id)) { error('Could not save question list'); } // update question grades $questionrecord = get_record("question", "id", $id); $quiz->grades[$id] = $questionrecord->defaultgrade; quiz_update_question_instance($quiz->grades[$id], $id, $quiz->instance); return true; }
$significantchangemade = true; } if (optional_param('savechanges', false, PARAM_BOOL) and confirm_sesskey()) { /// We need to save the new ordering (if given) and the new grades $oldquestions = explode(",", $quiz->questions); // the questions in the old order $questions = array(); // for questions in the new order $rawgrades = (array) data_submitted(); unset($quiz->grades); foreach ($rawgrades as $key => $value) { /// Parse input for question -> grades if (preg_match('!^q([0-9]+)$!', $key, $matches)) { $key = $matches[1]; $quiz->grades[$key] = clean_param($value, PARAM_INTEGER); quiz_update_question_instance($quiz->grades[$key], $key, $quiz->instance); /// Parse input for ordering info } elseif (preg_match('!^o([0-9]+)$!', $key, $matches)) { $key = $matches[1]; // Make sure two questions don't overwrite each other. If we get a second // question with the same position, shift the second one along to the next gap. $value = clean_param($value, PARAM_INTEGER); while (array_key_exists($value, $questions)) { $value++; } $questions[$value] = $oldquestions[$key]; } } // If ordering info was given, reorder the questions if ($questions) { ksort($questions);
if ($modform->id != $savequizid) { error("Error saving quiz settings, please do not change two quizes from the same browser", $CFG->wwwroot . '/mod/quiz/edit.php?quizid=' . $savequizid); } /// We need to save the new ordering (if given) and the new grades $oldquestions = explode(",", $modform->questions); // the questions in the old order $questions = array(); // for questions in the new order $rawgrades = $_POST; unset($modform->grades); foreach ($rawgrades as $key => $value) { // Parse input for question -> grades if (substr($key, 0, 1) == "q") { $key = substr($key, 1); $modform->grades[$key] = $value; quiz_update_question_instance($modform->grades[$key], $key, $modform->instance); } elseif (substr($key, 0, 1) == "o") { // Parse input for ordering info $key = substr($key, 1); $questions[$value] = $oldquestions[$key]; } } // If ordering info was given, reorder the questions if ($questions) { ksort($questions); $modform->questions = implode(",", $questions); // Always have a page break at the end $modform->questions = $modform->questions . ',0'; // Avoid duplicate page breaks while (strpos($modform->questions, ',0,0')) { $modform->questions = str_replace(',0,0', ',0', $modform->questions);
public function create_quiz($quizsettings, $qs) { global $SITE, $DB; $this->setAdminUser(); $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); $slots = array(); $qidsbycat = array(); $sumofgrades = 0; for ($rowno = 0; $rowno < $qs->getRowCount(); $rowno++) { $q = $this->explode_dot_separated_keys_to_make_subindexs($qs->getRow($rowno)); $catname = array('name' => $q['cat']); if (!($cat = $DB->get_record('question_categories', array('name' => $q['cat'])))) { $cat = $questiongenerator->create_question_category($catname); } $q['catid'] = $cat->id; foreach (array('which' => null, 'overrides' => array()) as $key => $default) { if (empty($q[$key])) { $q[$key] = $default; } } if ($q['type'] !== 'random') { // Don't actually create random questions here. $overrides = array('category' => $cat->id, 'defaultmark' => $q['mark']) + $q['overrides']; $question = $questiongenerator->create_question($q['type'], $q['which'], $overrides); $q['id'] = $question->id; if (!isset($qidsbycat[$q['cat']])) { $qidsbycat[$q['cat']] = array(); } if (!empty($q['which'])) { $name = $q['type'] . '_' . $q['which']; } else { $name = $q['type']; } $qidsbycat[$q['catid']][$name] = $q['id']; } if (!empty($q['slot'])) { $slots[$q['slot']] = $q; $sumofgrades += $q['mark']; } } ksort($slots); // Make a quiz. $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); // Settings from param override defaults. $aggregratedsettings = $quizsettings + array('course' => $SITE->id, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => $sumofgrades); $this->quiz = $quizgenerator->create_instance($aggregratedsettings); $this->randqids = array(); foreach ($slots as $slotno => $slotquestion) { if ($slotquestion['type'] !== 'random') { quiz_add_quiz_question($slotquestion['id'], $this->quiz, 0); // Setting default mark above does not affect the grade for multi-answer question type (and maybe others??). // Set the mark again just to be sure. quiz_update_question_instance($slotquestion['mark'], $slotquestion['id'], $this->quiz); } else { quiz_add_random_questions($this->quiz, 0, $slotquestion['catid'], 1, 0); $this->randqids[$slotno] = $qidsbycat[$slotquestion['catid']]; } } }