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.
This commit is contained in:
tjhunt 2009-02-27 08:45:05 +00:00
parent 1fd211a770
commit 4299df1daf
5 changed files with 298 additions and 221 deletions

View File

@ -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))) {

View File

@ -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 '<div class="quizpage"><span class="pagetitle">'.
get_string('page').'&nbsp;'.$pagecount.
'</span><div class="pagecontent">';
$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 '<div class="pagestatus">';
print_string("noquestionsonpage", "quiz");
echo '</div>';
if ($allowdelete && !$quiz->questionsperpage) { // remove from quiz, not question delete.
if ($allowdelete && !$quiz->questionsperpage) {
echo '<div class="quizpagedelete">';
echo "<a title=\"".get_string("removeemptypage","quiz")."\" href=\"".
$pageurl->out_action(array('deleteemptypage'=>$i)).
"\"><img src=\"$CFG->pixpath/t/delete.gif\" ".
"class=\"iconsmall\"".
" alt=\"$strremove\" /></a>";
echo '<a title="' . get_string('removeemptypage', 'quiz') . '" href="' .
$pageurl->out_action(array('deleteemptypage' => $i - 1)) .
'"><img src="' . $CFG->pixpath . '/t/delete.gif" ' .
'class="iconsmall" alt="' . $strremove . '" /></a>';
echo '</div>';
}
}
@ -396,31 +497,31 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete=true,
<div class="questioncontrols">
<?php
if ($count != 0) {
if(!$hasattempts){
if (!$hasattempts) {
$upbuttonclass="";
if (!($count < $lastindex-1)) {
if ($count >= $lastindex - 1) {
$upbuttonclass="upwithoutdown";
}
echo "<a title=\"$strmoveup\" href=\"".
$pageurl->out_action(array('up'=>$count))."\"><img
$pageurl->out_action(array('up' => $question->id))."\"><img
src=\"$CFG->pixpath/t/up.gif\" class=\"iconsmall
$upbuttonclass\" alt=\"$strmoveup\" /></a>";
}
}
if ($count < $lastindex-1) {
if ($count < $lastindex - 1) {
if(!$hasattempts){
echo "<a title=\"$strmovedown\" href=\"".
$pageurl->out_action(array('down'=>$count))."\"><img
$pageurl->out_action(array('down' => $question->id))."\"><img
src=\"$CFG->pixpath/t/down.gif\" class=\"iconsmall\"".
" alt=\"$strmovedown\" /></a>";
}
}
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 "<a title=\"$strremove\" href=\"".
$pageurl->out_action(array('delete'=>$count))."\">
$pageurl->out_action(array('remove' => $question->id))."\">
<img src=\"$CFG->pixpath/t/delete.gif\" ".
"class=\"iconsmall\" alt=\"$strremove\" /></a>";
}
@ -437,7 +538,7 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete=true,
<?php echo $pageurl->hidden_params_out(); ?>
<input type="hidden" name="savechanges" value="save" />
<?php
echo '<input type="text" name="q'.$qnum.'" id="inputq'.$qnum.'" size="' . ($quiz->decimalpoints + 2) . '"
echo '<input type="text" name="g'.$qnum.'" id="inputq'.$qnum.'" size="' . ($quiz->decimalpoints + 2) . '"
value="'.(0 + $quiz->grades[$qnum]).
'" tabindex="'.($lastindex+$qno).'" />';
?>

View File

@ -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;

View File

@ -0,0 +1,62 @@
<?php
/**
* Unit tests for (some of) mod/quiz/editlib.php.
*
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package quiz
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page.
}
require_once($CFG->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');
}
}
?>

View File

@ -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());