From 4299df1daf93e1ee71fa13a2601e5c61584e7b73 Mon Sep 17 00:00:00 2001 From: tjhunt Date: Fri, 27 Feb 2009 08:45:05 +0000 Subject: [PATCH] quiz editing: Refactor the editing actions to make functions in editlib.php for most of them. In the process, do MDL-17456, move/delete questions by question id rather than position, for greater robustness. --- mod/quiz/edit.php | 236 ++++++++-------------------- mod/quiz/editlib.php | 193 +++++++++++++++++------ mod/quiz/locallib.php | 21 ++- mod/quiz/simpletest/testeditlib.php | 62 ++++++++ mod/quiz/startattempt.php | 7 +- 5 files changed, 298 insertions(+), 221 deletions(-) create mode 100644 mod/quiz/simpletest/testeditlib.php diff --git a/mod/quiz/edit.php b/mod/quiz/edit.php index 3f177cdedc4..e8d95a709af 100644 --- a/mod/quiz/edit.php +++ b/mod/quiz/edit.php @@ -167,54 +167,43 @@ if (isset($quiz->instance) && empty($quiz->grades)) { // Construct an array to $quiz->grades = quiz_get_all_question_grades($quiz); } -// SECTION: PROCESS COMMANDS // -// If any edit action makes a significant change to the structure of the quiz, -// then we will need to delete all preview attempts. -$significantchangemade = false; +// Process commands ============================================================ -if (($up = optional_param('up', false, PARAM_INT)) !== false && confirm_sesskey()) { -/// Move the given question up a slot - $questions = explode(',', $quiz->questions); - if ($up > 0 && isset($questions[$up])) { - //$prevkey = ($questions[$up-1] == 0) ? $up-2 : $up-1; - $prevkey = $up-1; - $swap = $questions[$prevkey]; - $questions[$prevkey] = $questions[$up]; - $questions[$up] = $swap; - $quiz->questions = implode(',', $questions); - $quiz->questions = quiz_clean_layout($quiz->questions); - if (!$DB->set_field('quiz', 'questions', $quiz->questions, - array('id' => $quiz->instance))) { - print_error('cannotsavequestion', 'quiz'); - } - $significantchangemade = true; +// Get the list of question ids had their check-boxes ticked. +$selectedquestionids = array(); +$params = (array) data_submitted(); +foreach ($params as $key => $value) { + if (preg_match('!^s([0-9]+)$!', $key, $matches)) { + $selectedquestionids[] = $matches[1]; } } -if (($down = optional_param('down', false, PARAM_INT)) !== false && confirm_sesskey()) { -/// Move the given question down a slot - $questions = explode(',', $quiz->questions); - if ($down < count($questions)) { - //$nextkey = ($questions[$down+1] == 0) ? $down+2 : $down+1; - $nextkey = $down+1; - $swap = $questions[$nextkey]; - $questions[$nextkey] = $questions[$down]; - $questions[$down] = $swap; - $quiz->questions = implode(',', $questions); - $quiz->questions = quiz_clean_layout($quiz->questions); - if (!$DB->set_field('quiz', 'questions', $quiz->questions, - array('id' => $quiz->instance))) { - print_error('cannotsavequestion', 'quiz'); - } - $significantchangemade = true; - } +if (($up = optional_param('up', false, PARAM_INT)) && confirm_sesskey()) { + $quiz->questions = quiz_move_question_up($quiz->questions, $up); + quiz_save_new_layout($quiz); + redirect($thispageurl->out()); +} + +if (($down = optional_param('down', false, PARAM_INT)) && confirm_sesskey()) { + $quiz->questions = quiz_move_question_down($quiz->questions, $down); + quiz_save_new_layout($quiz); + redirect($thispageurl->out()); +} + +if (optional_param('repaginate', false, PARAM_BOOL) && confirm_sesskey()) { + // Re-paginate the quiz + $questionsperpage = optional_param('questionsperpage', $quiz->questionsperpage, PARAM_INT); + $quiz->questions = quiz_repaginate($quiz->questions, $questionsperpage ); + quiz_save_new_layout($quiz); } if (($addquestion = optional_param('addquestion', 0, PARAM_INT)) && confirm_sesskey()) { /// Add a single question to the current quiz $addonpage = optional_param('addonpage', 0, PARAM_INT); quiz_add_quiz_question($addquestion, $quiz, $addonpage); - $significantchangemade = true; + quiz_update_sumgrades($quiz); + quiz_delete_previews($quiz); + redirect($thispageurl->out()); } if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) { @@ -226,24 +215,20 @@ if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) { quiz_add_quiz_question($key, $quiz); } } - $significantchangemade = true; + quiz_update_sumgrades($quiz); + quiz_delete_previews($quiz); + redirect($thispageurl->out()); } -$qcobject = new question_category_object( - $pagevars['cpage'], - $thispageurl, - $contexts->having_one_edit_tab_cap('categories'), - $defaultcategoryid, - $defaultcategory, - null, - $contexts->having_cap('moodle/question:add')); +$qcobject = new question_category_object($pagevars['cpage'], $thispageurl, + $contexts->having_one_edit_tab_cap('categories'), $defaultcategoryid, + $defaultcategory, null, $contexts->having_cap('moodle/question:add')); $newrandomcategory = false; $newquestioninfo = quiz_process_randomquestion_formdata($qcobject); if ($newquestioninfo) { $newrandomcategory = $newquestioninfo->newrandomcategory; if (!$newrandomcategory) { - print_r($newquestioninfo); print_error('cannotcreatecategory'); } else { add_to_log($quiz->course, 'quiz', 'addcategory', @@ -311,114 +296,48 @@ if ((optional_param('addrandom', false, PARAM_BOOL) || $newrandomcategory) && co } } - $significantchangemade = true; + quiz_update_sumgrades($quiz); + quiz_delete_previews($quiz); + redirect($thispageurl->out()); } -$addpagesafterquestions = array(); -if ($addnewpagesafterselected = optional_param('addnewpagesafterselected', null)) { - $rawgrades = (array) data_submitted(); - foreach ($rawgrades as $key => $value) { - /// Parse input for question -> grades - if (preg_match('!^s([0-9]+)$!', $key, $matches)) { - $addpagesafterquestions[] = $matches[1]; - } +if (optional_param('addnewpagesafterselected', null) && !empty($selectedquestionids) && confirm_sesskey()) { + foreach ($selectedquestionids as $questionid) { + $quiz->questions = quiz_add_page_break_after($quiz->questions, $questionid); } + quiz_save_new_layout($quiz); + redirect($thispageurl->out()); } $addpage = optional_param('addpage', false, PARAM_INT); -if (($addpage || !empty($addpagesafterquestions)) && confirm_sesskey()) { -/// Move the given question up a slot - - $questions = explode(',', $quiz->questions); - - $pagebreakid = '0'; - if ($addpage > 0 && isset($questions[$addpage])) { - array_splice($questions, $addpage, 0, $pagebreakid); - $significantchangemade = true; - } - foreach ($addpagesafterquestions as $key => $questionid) { - $addpage = array_search($questionid, $questions)+1; - if ($addpage > 0 && isset($questions[$addpage])) { - $pagebreakid = '0'; - array_splice($questions, $addpage, 0, $pagebreakid); - $significantchangemade = true; - } - } - $quiz->questions = implode(',', $questions); - $quiz->questions = quiz_clean_layout($quiz->questions); - - if (!$DB->set_field('quiz', 'questions', $quiz->questions, - array('id' => $quiz->instance))) { - print_error('cannotsavequestion', 'quiz'); - } -} - -if (optional_param('repaginate', false, PARAM_BOOL) && confirm_sesskey()) { - // Re-paginate the quiz - $questionsperpage = optional_param('questionsperpage', - $quiz->questionsperpage, PARAM_INT); - $quiz->questions = quiz_repaginate($quiz->questions, - $questionsperpage ); - if (!$DB->set_field('quiz', 'questions', $quiz->questions, array('id' => $quiz->id))) { - print_error('cannotsavelayout', 'quiz'); - } - $significantchangemade = true; +if ($addpage !== false && confirm_sesskey()) { + $quiz->questions = quiz_add_page_break_at($quiz->questions, $addpage); + quiz_save_new_layout($quiz); + redirect($thispageurl->out()); } $deleteemptypage = optional_param('deleteemptypage', false, PARAM_INT); if (($deleteemptypage !== false) && confirm_sesskey()) { - $questions = explode(',', $quiz->questions); - if ($deleteemptypage>0) { - //it points to a value one too big due to the display logic - $deleteemptypage--; - } - if (((int)$questions[$deleteemptypage]) == 0) { - $questions = explode(',', $quiz->questions); - $endpart = array_slice($questions, $deleteemptypage + 1, null, true); - $beginpart = array_slice($questions, 0, $deleteemptypage, true); - $questions = array_merge($beginpart, $endpart); - $quiz->questions = implode(',', $questions); - $quiz->questions = quiz_clean_layout($quiz->questions); - } - if (!$DB->set_field('quiz', 'questions', $quiz->questions, - array('id' => $quiz->instance))) { - print_error('cannotsavequestion', 'quiz'); - } + $quiz->questions = quiz_delete_empty_page($quiz->questions, $deleteemptypage); + quiz_save_new_layout($quiz); + redirect($thispageurl->out()); } -$deletequestions = array(); -if ($quizdeleteselected = optional_param('quizdeleteselected', false)) { - $rawgrades = (array) data_submitted(); - foreach ($rawgrades as $key => $value) { - /// Parse input for question -> grades - if (preg_match('!^s([0-9]+)$!', $key, $matches)) { - $deletequestions[] = $matches[1]; - } - } +$remove = optional_param('remove', false, PARAM_INT); +if (($remove = optional_param('remove', false, PARAM_INT)) && confirm_sesskey()) { + quiz_remove_question($quiz, $remove); + quiz_update_sumgrades($quiz); + quiz_delete_previews($quiz); + redirect($thispageurl->out()); } -$delete = optional_param('delete', false, PARAM_INT); -if (($delete !== false || !empty($deletequestions)) && confirm_sesskey()) { - - //was: if ($delete > 0 ) { - if ($delete !==false) { - quiz_delete_quiz_question($delete, $quiz); - $significantchangemade = true; - } - foreach ($deletequestions as $key => $questionid) { - $questions = explode(',', $quiz->questions); - $delete = array_search($questionid, $questions); - if ($delete !== false) { - quiz_delete_quiz_question($delete, $quiz); - $significantchangemade = true; - } - } - $quiz->questions = quiz_clean_layout($quiz->questions); - - if (!$DB->set_field('quiz', 'questions', $quiz->questions, - array('id' => $quiz->instance))) { - print_error('cannotsavequestion', 'quiz'); +if (optional_param('quizdeleteselected', false, PARAM_BOOL) && !empty($selectedquestionids) && confirm_sesskey()) { + foreach ($selectedquestionids as $questionid) { + quiz_remove_question($quiz, $questionid); } + quiz_update_sumgrades($quiz); + quiz_delete_previews($quiz); + redirect($thispageurl->out()); } if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) { @@ -436,7 +355,7 @@ if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) { } foreach ($rawgrades as $key => $value) { - if (preg_match('!^q([0-9]+)$!', $key, $matches)) { + if (preg_match('!^g([0-9]+)$!', $key, $matches)) { /// Parse input for question -> grades $key = $matches[1]; $quiz->grades[$key] = $value; @@ -453,28 +372,21 @@ if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) { $value++; } $questions[$value] = $oldquestions[$key]; - - } else if (preg_match('!^s([0-9]+)$!', $key, $matches)) { - // Parse input for selected questions - // (add new pages after questions in quiz) - $key = $matches[1]; - if ($moveselectedonpage) { - $moveonpagequestions[] = $key; - } } } + // If ordering info was given, reorder the questions if ($questions) { ksort($questions); $quiz->questions = implode(',', $questions) . ',0'; $quiz->questions = quiz_clean_layout($quiz->questions); - } + //get a list of questions to move, later to be added in the appropriate //place in the string - if ($moveonpagequestions) { + if ($moveselectedonpage) { $questions = explode(',', $quiz->questions); - foreach ($moveonpagequestions as $page => $question) { + foreach ($selectedquestionids as $page => $question) { //remove the questions from their original positions first while (($delpos = array_search($question, $questions)) !== FALSE) { //in case there are multiple instances because of an error, remove all @@ -499,14 +411,14 @@ if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) { $pagebreakpositions = array_keys($questions, 0); //move to the end of the selected page $moveselectedpos = $pagebreakpositions[$moveselectedonpage - 1]; - foreach ($moveonpagequestions as $question) { + foreach ($selectedquestionids as $question) { array_splice($questions, $moveselectedpos, 0, $question); //place the next one after this one: $moveselectedpos++; } $quiz->questions = implode(',', $questions); } - if ($moveonpagequestions || $questions) { + if ($moveselectedonpage || $questions) { if (!$DB->set_field('quiz', 'questions', $quiz->questions, array('id' => $quiz->instance))) { print_error('cannotsavequestion', 'quiz'); @@ -520,24 +432,14 @@ if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) { } } - $significantchangemade = true; -} -/// Delete any teacher preview attempts if the quiz has been modified -if ($significantchangemade) { - $previewattempts = $DB->get_records_select('quiz_attempts', - 'quiz = ? AND preview = 1', array($quiz->id)); - if ($previewattempts) { - foreach ($previewattempts as $attempt) { - quiz_delete_attempt($attempt, $quiz); - } - } quiz_update_sumgrades($quiz); + quiz_delete_previews($quiz); redirect($thispageurl->out()); } $questionbank->process_actions($thispageurl, $cm); -/// all commands have been dealt with, now print the page +// End of process commands ===================================================== if (isset($quiz->instance) && $DB->record_exists_select('quiz_attempts', 'quiz = ? AND preview = 0', array($quiz->instance))) { diff --git a/mod/quiz/editlib.php b/mod/quiz/editlib.php index 513eeebae49..ec9c662dc62 100644 --- a/mod/quiz/editlib.php +++ b/mod/quiz/editlib.php @@ -35,35 +35,45 @@ require_once("locallib.php"); define('NUM_QS_TO_SHOW_IN_RANDOM', 3); /** -* Delete a question from a quiz -* -* Deletes a question or a pagebreak from a quiz by updating $quiz -* as well as the quiz, quiz_question_instances -* @return boolean false if the question was not in the quiz -* @param int $id The id of the question to be deleted -* @param object $quiz The extended quiz object as used by edit.php -* This is updated by this function -*/ -function quiz_delete_quiz_question($id, &$quiz) { + * Remove a question from a quiz + * @param object $quiz the quiz object. + * @param int $questionid The id of the question to be deleted. + */ +function quiz_remove_question($quiz, $questionid) { global $DB; - // TODO: For the sake of safety check that this question can be deleted - // safely, i.e., that it is not already in use. - $questions = explode(",", $quiz->questions); - // only do something if this question exists - if (!isset($questions[$id])) { - return false; + $questionids = explode(',', $quiz->questions); + $key = array_search($questionid, $questionids); + if ($key === false) { + return; } - $question = $questions[$id]; - unset($questions[$id]); - $quiz->questions = implode(",", $questions); - // save new questionlist in database - if (!$DB->set_field('quiz', 'questions', $quiz->questions, array('id' => $quiz->instance))) { - print_error('cannotsavequestion', 'quiz'); + unset($questionids[$key]); + $quiz->questions = implode(',', $questionids); + $DB->set_field('quiz', 'questions', $quiz->questions, array('id' => $quiz->id)); + $DB->delete_records('quiz_question_instances', array('quiz' => $quiz->instance, 'question' => $questionid)); +} + +/** + * Remove an empty page from the quiz layout. If that is not possible, do nothing. + * @param string $layout the existinng layout, $quiz->questions. + * @param integer $index the position into $layout where the empty page should be removed. + * @return the updated layout + */ +function quiz_delete_empty_page($layout, $index) { + $questionids = explode(',', $layout); + + if ($index < -1 || $index >= count($questionids) - 1) { + return $layout; } - $DB->delete_records('quiz_question_instances', array('quiz' => $quiz->instance, 'question'=> $question)); - return true; + + if (($index >= 0 && $questionids[$index] != 0) || $questionids[$index + 1] != 0) { + return $layout; // This was not an empty page. + } + + unset($questionids[$index + 1]); + + return implode(',', $questionids); } /** @@ -141,6 +151,53 @@ function quiz_add_quiz_question($id, &$quiz, $page=0) { return true; } +/** + * Add a page break after at particular position$. + * @param string $layout the existinng layout, $quiz->questions. + * @param integer $index the position into $layout where the empty page should be removed. + * @return the updated layout + */ +function quiz_add_page_break_at($layout, $index) { + $questionids = explode(',', $layout); + if ($index < 0 || $index >= count($questionids)) { + return $layout; + } + + array_splice($questionids, $index, 0, '0'); + + return implode(',', $questionids); +} + +/** + * Add a page break after a particular question. + * @param string $layout the existinng layout, $quiz->questions. + * @param integer $qustionid the question to add the page break after. + * @return the updated layout + */ +function quiz_add_page_break_after($layout, $questionid) { + $questionids = explode(',', $layout); + $key = array_search($questionid, $questionids); + if ($key === false || !$questionid) { + return $layout; + } + + array_splice($questionids, $key + 1, 0, '0'); + + return implode(',', $questionids); +} + +/** + * Update the database after $quiz->questions has been changed. For example, + * this deletes preview attempts and updates $quiz->sumgrades. + * @param $quiz the quiz object. + */ +function quiz_save_new_layout($quiz) { + global $DB; + $DB->set_field('quiz', 'questions', $quiz->questions, array('id' => $quiz->id)); + quiz_update_sumgrades($quiz); + quiz_delete_previews($quiz); +} + /** * Save changes to question instance * @@ -165,6 +222,52 @@ function quiz_update_question_instance($grade, $questionid, $quizid) { } } +// Private function used by the following two. +function _quiz_move_question($layout, $questionid, $shift) { + if (!$questionid || !($shift == 1 || $shift == -1)) { + return $layout; + } + + $questionids = explode(',', $layout); + $key = array_search($questionid, $questionids); + if ($key === false) { + return $layout; + } + + $otherkey = $key + $shift; + if ($otherkey < 0 || $otherkey >= count($questionids) - 1) { + return $layout; + } + + $temp = $questionids[$otherkey]; + $questionids[$otherkey] = $questionids[$key]; + $questionids[$key] = $temp; + + return implode(',', $questionids); +} + +/** + * Move a particular question one space earlier in the $quiz->questions list. + * If that is not possible, do nothing. + * @param string $layout the existinng layout, $quiz->questions. + * @param integer $questionid the id of a question. + * @return the updated layout + */ +function quiz_move_question_up($layout, $questionid) { + return _quiz_move_question($layout, $questionid, -1); +} + +/** + * Move a particular question one space later in the $quiz->questions list. + * If that is not possible, do nothing. + * @param string $layout the existinng layout, $quiz->questions. + * @param integer $questionid the id of a question. + * @return the updated layout + */ +function quiz_move_question_down($layout, $questionid) { + return _quiz_move_question($layout, $questionid, +1); +} + /** * Prints a list of quiz questions for the edit.php main view for edit * ($reordertool=false) and order and paging ($reordertool=true) tabs @@ -319,30 +422,28 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete=true, $questions[$qnum]->qtype = 'missingtype'; } $deletex="delete.gif"; - if($qnum!=0 OR ($qnum==0&&!$pageopen)){ + if ($qnum != 0 || ($qnum == 0 && !$pageopen)) { //this is either a question or a page break after another // (no page is currently open) - if(!$pageopen){ + if (!$pageopen) { //if no page is open, start display of a page $pagecount++; echo '
'. get_string('page').' '.$pagecount. '
'; - $pageopen=true; + $pageopen = true; } - if($qnum==0 && $i<$questiontotalcount){ - //this is a consequent 0 (signaling empty page), tell - // the user the page is empty + if ($qnum == 0 && $i < $questiontotalcount) { + // This is the second successive page break. Tell the user the page is empty. echo '
'; print_string("noquestionsonpage", "quiz"); echo '
'; - if ($allowdelete && !$quiz->questionsperpage) { // remove from quiz, not question delete. + if ($allowdelete && !$quiz->questionsperpage) { echo ''; } } @@ -396,31 +497,31 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete=true,
= $lastindex - 1) { $upbuttonclass="upwithoutdown"; } echo "out_action(array('up'=>$count))."\">out_action(array('up' => $question->id))."\">pixpath/t/up.gif\" class=\"iconsmall $upbuttonclass\" alt=\"$strmoveup\" />"; } } - if ($count < $lastindex-1) { + if ($count < $lastindex - 1) { if(!$hasattempts){ echo "out_action(array('down'=>$count))."\">out_action(array('down' => $question->id))."\">pixpath/t/down.gif\" class=\"iconsmall\"". " alt=\"$strmovedown\" />"; } } - if ($allowdelete && question_has_capability_on($question, 'use', - $question->category)) { // remove from quiz, not question delete. - if(!$hasattempts){ + if ($allowdelete && question_has_capability_on($question, 'use', $question->category)) { + // remove from quiz, not question delete. + if (!$hasattempts) { echo "out_action(array('delete'=>$count))."\"> + $pageurl->out_action(array('remove' => $question->id))."\"> pixpath/t/delete.gif\" ". "class=\"iconsmall\" alt=\"$strremove\" />"; } @@ -437,7 +538,7 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete=true, hidden_params_out(); ?> decimalpoints + 2) . '" + echo ''; ?> diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index ea7c8d4157d..c618ea2b951 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -204,6 +204,24 @@ function quiz_delete_attempt($attempt, $quiz) { quiz_update_grades($quiz, $userid); } +/** + * Delete all the preview attempts at a quiz, or possibly all the attempts belonging + * to one user. + * @param object $quiz the quiz object. + * @param integer $userid (optional) if given, only delete the previews belonging to this user. + */ +function quiz_delete_previews($quiz, $userid = null) { + global $DB; + $conditions = array('quiz' => $quiz->id, 'preview' => 1); + if (!empty($userid)) { + $conditions['userid'] = $userid; + } + $previewattempts = $DB->get_records('quiz_attempts', $conditions); + foreach ($previewattempts as $attempt) { + quiz_delete_attempt($attempt, $quiz); + } +} + /// Functions to do with quiz layout and pages //////////////////////////////// /** @@ -298,7 +316,7 @@ function quiz_first_questionnumber($quizlayout, $pagelayout) { * @param boolean $shuffle Should the questions be reordered randomly? * @return string the new layout string */ -function quiz_repaginate($layout, $perpage, $shuffle=false) { +function quiz_repaginate($layout, $perpage, $shuffle = false) { $layout = str_replace(',0', '', $layout); // remove existing page breaks $questions = explode(',', $layout); //remove empty pages from beginning @@ -306,7 +324,6 @@ function quiz_repaginate($layout, $perpage, $shuffle=false) { array_shift($questions); } if ($shuffle) { - srand((float)microtime() * 1000000); // for php < 4.2 shuffle($questions); } $i = 1; diff --git a/mod/quiz/simpletest/testeditlib.php b/mod/quiz/simpletest/testeditlib.php new file mode 100644 index 00000000000..0a931c5bda3 --- /dev/null +++ b/mod/quiz/simpletest/testeditlib.php @@ -0,0 +1,62 @@ +dirroot . '/mod/quiz/editlib.php'); + +class quiz_editlib_test extends UnitTestCase { + function test_quiz_move_question_up() { + $this->assertEqual(quiz_move_question_up('0', 123), '0'); + $this->assertEqual(quiz_move_question_up('1,2,0', 1), '1,2,0'); + $this->assertEqual(quiz_move_question_up('1,2,0', 0), '1,2,0'); + $this->assertEqual(quiz_move_question_up('1,2,0', 2), '2,1,0'); + $this->assertEqual(quiz_move_question_up('1,2,0,3,4,0', 3), '1,2,3,0,4,0'); + $this->assertEqual(quiz_move_question_up('1,2,3,0,4,0', 4), '1,2,3,4,0,0'); + } + + function test_quiz_move_question_down() { + $this->assertEqual(quiz_move_question_down('0', 123), '0'); + $this->assertEqual(quiz_move_question_down('1,2,0', 2), '1,2,0'); + $this->assertEqual(quiz_move_question_down('1,2,0', 0), '1,2,0'); + $this->assertEqual(quiz_move_question_down('1,2,0', 1), '2,1,0'); + $this->assertEqual(quiz_move_question_down('1,2,0,3,4,0', 2), '1,0,2,3,4,0'); + $this->assertEqual(quiz_move_question_down('1,0,2,3,0,4,0', 1), '0,1,2,3,0,4,0'); + } + + function test_quiz_delete_empty_page() { + $this->assertEqual(quiz_delete_empty_page('0', 0), '0'); + $this->assertEqual(quiz_delete_empty_page('1,2,0', 2), '1,2,0'); + $this->assertEqual(quiz_delete_empty_page('0,1,2,0', -1), '1,2,0'); + $this->assertEqual(quiz_delete_empty_page('0,1,2,0', 0), '0,1,2,0'); + $this->assertEqual(quiz_delete_empty_page('1,2,0', 3), '1,2,0'); + $this->assertEqual(quiz_delete_empty_page('1,2,0', -1), '1,2,0'); + $this->assertEqual(quiz_delete_empty_page('1,2,0,0', 2), '1,2,0'); + $this->assertEqual(quiz_delete_empty_page('1,2,0,0', 1), '1,2,0,0'); + $this->assertEqual(quiz_delete_empty_page('1,2,0,0,3,4,0', 2), '1,2,0,3,4,0'); + $this->assertEqual(quiz_delete_empty_page('0,0,1,2,0', 0), '0,1,2,0'); + } + + function test_quiz_add_page_break_after() { + $this->assertEqual(quiz_add_page_break_after('0', 1), '0'); + $this->assertEqual(quiz_add_page_break_after('1,2,0', 1), '1,0,2,0'); + $this->assertEqual(quiz_add_page_break_after('1,2,0', 2), '1,2,0,0'); + $this->assertEqual(quiz_add_page_break_after('1,2,0', 0), '1,2,0'); + } + + function test_quiz_add_page_break_at() { + $this->assertEqual(quiz_add_page_break_at('0', 0), '0,0'); + $this->assertEqual(quiz_add_page_break_at('1,2,0', 0), '0,1,2,0'); + $this->assertEqual(quiz_add_page_break_at('1,2,0', 1), '1,0,2,0'); + $this->assertEqual(quiz_add_page_break_at('1,2,0', 2), '1,2,0,0'); + $this->assertEqual(quiz_add_page_break_at('1,2,0', 3), '1,2,0'); + } +} +?> \ No newline at end of file diff --git a/mod/quiz/startattempt.php b/mod/quiz/startattempt.php index e68484677de..82d234f7b6f 100644 --- a/mod/quiz/startattempt.php +++ b/mod/quiz/startattempt.php @@ -89,12 +89,7 @@ if (!$quizobj->is_preview_user() && $messages) { $accessmanager->do_password_check($quizobj->is_preview_user()); /// Delete any previous preview attempts belonging to this user. -if ($oldattempts = $DB->get_records_select('quiz_attempts', "quiz = ? - AND userid = ? AND preview = 1", array($quiz->id, $USER->id))) { - foreach ($oldattempts as $oldattempt) { - quiz_delete_attempt($oldattempt, $quiz); - } -} +quiz_delete_previews($quiz, $USER->id); /// Create the new attempt and initialize the question sessions $attempt = quiz_create_attempt($quiz, $attemptnumber, $lastattempt, time(), $quizobj->is_preview_user());