diff --git a/lang/en_utf8/quiz.php b/lang/en_utf8/quiz.php index 0923b81234e..e0a1a65c185 100644 --- a/lang/en_utf8/quiz.php +++ b/lang/en_utf8/quiz.php @@ -586,6 +586,7 @@ $string['xml'] = 'Moodle XML format'; $string['xmlimportnoname'] = 'Missing question name in xml file'; $string['xmlimportnoquestion'] = 'Missing question text in xml file'; $string['xmltypeunsupported'] = 'Question type $a is not supported by xml import'; +$string['youneedtoenrol'] = 'You need to enrol in this course before you can attempt this quiz'; $string['yourfinalgradeis'] = 'Your final grade for this quiz is $a.'; $string['zerosignificantfiguresnotallowed'] = 'The correct answer cannot have zero significant figures!'; diff --git a/mod/quiz/attempt.php b/mod/quiz/attempt.php index 3f1ae33448e..3adf6703120 100644 --- a/mod/quiz/attempt.php +++ b/mod/quiz/attempt.php @@ -62,13 +62,17 @@ // if no questions have been set up yet redirect to edit.php if (!$quiz->questions and has_capability('mod/quiz:manage', $context)) { - redirect('edit.php?cmid='.$cm->id); + redirect($CFG->wwwroot . '/mod/quiz/edit.php?quizid=' . $quiz->id); } - // Get number for the next or unfinished attempt + if (!$ispreviewing) { + require_capability('mod/quiz:attempt', $context); + } + +/// Get number for the next or unfinished attempt if(!$attemptnumber = (int)get_field_sql('SELECT MAX(attempt)+1 FROM ' . - "{$CFG->prefix}quiz_attempts WHERE quiz = '{$quiz->id}' AND " . - "userid = '{$USER->id}' AND timefinish > 0 AND preview != 1")) { + "{$CFG->prefix}quiz_attempts WHERE quiz = '{$quiz->id}' AND " . + "userid = '{$USER->id}' AND timefinish > 0 AND preview != 1")) { $attemptnumber = 1; } @@ -76,22 +80,14 @@ $strquizzes = get_string("modulenameplural", "quiz"); $popup = $quiz->popup && !$ispreviewing; // Controls whether this is shown in a javascript-protected window. - // Check availability - if (isguestuser()) { - print_heading(get_string('guestsno', 'quiz')); - if (empty($popup)) { - print_footer($course); - } - exit; - } - +/// Check number of attempts $numberofpreviousattempts = count_records_select('quiz_attempts', "quiz = '{$quiz->id}' AND " . "userid = '{$USER->id}' AND timefinish > 0 AND preview != 1"); if ($quiz->attempts and $numberofpreviousattempts >= $quiz->attempts) { error(get_string('nomoreattempts', 'quiz'), "view.php?id={$cm->id}"); } - // Check subnet access +/// Check subnet access if ($quiz->subnet and !address_in_subnet(getremoteaddr(), $quiz->subnet)) { if ($ispreviewing) { notify(get_string('subnetnotice', 'quiz')); @@ -100,7 +96,7 @@ } } - // Check password access +/// Check password access if ($ispreviewing && $forcenew) { unset($SESSION->passwordcheckedquizzes[$quiz->id]); } @@ -171,7 +167,7 @@ } } - // Load attempt or create a new attempt if there is no unfinished one +/// Load attempt or create a new attempt if there is no unfinished one if ($ispreviewing and $forcenew) { // teacher wants a new preview // so we set a finish time on the current attempt (if any). @@ -324,7 +320,7 @@ // We have now finished processing form data } - // Finish attempt if requested +/// Finish attempt if requested if ($finishattempt) { // Set the attempt to be finished @@ -364,7 +360,7 @@ "$quiz->id", $cm->id); } - // Update the quiz attempt and the overall grade for the quiz +/// Update the quiz attempt and the overall grade for the quiz if ($responses || $finishattempt) { if (!update_record('quiz_attempts', $attempt)) { error('Failed to save the current quiz attempt!'); @@ -392,7 +388,7 @@ if ($finishattempt) { unset($SESSION->passwordcheckedquizzes[$quiz->id]); - redirect('review.php?attempt='.$attempt->id, 0); + redirect($CFG->wwwroot . '/mod/quiz/review.php?attempt='.$attempt->id, 0); } /// Print the quiz page //////////////////////////////////////////////////////// @@ -461,7 +457,7 @@ // Add a hidden field with the quiz id echo '
' . get_string('guestsno', 'quiz') . "
\n\n" . get_string('liketologin') . '', $loginurl, get_referer(false)); + finish_page($course); } - if (has_capability('mod/quiz:attempt', $context)) { + if (!(has_capability('mod/quiz:attempt', $context) || has_capability('mod/quiz:preview', $context))) { + print_box('' . get_string('youneedtoenrol', 'quiz') . '
' . + print_continue($CFG->wwwroot . '/course/view.php?id=' . $course->id, true) . + '
', 'generalbox', 'notice'); + finish_page($course); + } - // Get this user's attempts. - $attempts = quiz_get_user_attempts($quiz->id, $USER->id); - $unfinished = false; - if ($unfinishedattempt = quiz_get_user_attempt_unfinished($quiz->id, $USER->id)) { - $attempts[] = $unfinishedattempt; - $unfinished = true; - } - $numattempts = count($attempts); + // Get this user's attempts. + $attempts = quiz_get_user_attempts($quiz->id, $USER->id); + $unfinished = false; + if ($unfinishedattempt = quiz_get_user_attempt_unfinished($quiz->id, $USER->id)) { + $attempts[] = $unfinishedattempt; + $unfinished = true; + } + $numattempts = count($attempts); - $mygrade = quiz_get_best_grade($quiz, $USER->id); + $mygrade = quiz_get_best_grade($quiz, $USER->id); + + // Print table with existing attempts + if ($attempts) { + + print_heading('Summary of your previous attempts'); // Get some strings. $strattempt = get_string("attempt", "quiz"); @@ -172,234 +175,229 @@ $strmarks = get_string('marks', 'quiz'); $strfeedback = get_string('feedback', 'quiz'); - // Print table with existing attempts - if ($attempts) { + // Work out which columns we need, taking account what data is available in each attempt. + list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts, $context); - print_heading('Summary of your previous attempts'); + $gradecolumn = $someoptions->scores && $quiz->grade && $quiz->sumgrades; + $markcolumn = $gradecolumn && ($quiz->grade != $quiz->sumgrades); + $overallstats = $alloptions->scores; - // Work out which columns we need, taking account what data is available in each attempt. - list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts, $context); + $feedbackcolumn = quiz_has_feedback($quiz->id); + $overallfeedback = $feedbackcolumn && $alloptions->overallfeedback; - $gradecolumn = $someoptions->scores && $quiz->grade && $quiz->sumgrades; - $markcolumn = $gradecolumn && ($quiz->grade != $quiz->sumgrades); - $overallstats = $alloptions->scores; + // prepare table header + $table->class = 'generaltable quizattemptsummary'; + $table->head = array($strattempt, $strtimecompleted); + $table->align = array("center", "left"); + $table->size = array("", ""); + if ($markcolumn) { + $table->head[] = "$strmarks / $quiz->sumgrades"; + $table->align[] = 'center'; + $table->size[] = ''; + } + if ($gradecolumn) { + $table->head[] = "$strgrade / $quiz->grade"; + $table->align[] = 'center'; + $table->size[] = ''; + } + if ($feedbackcolumn) { + $table->head[] = $strfeedback; + $table->align[] = 'left'; + $table->size[] = ''; + } + if (isset($quiz->showtimetaken)) { + $table->head[] = $strtimetaken; + $table->align[] = 'left'; + $table->size[] = ''; + } - $feedbackcolumn = quiz_has_feedback($quiz->id); - $overallfeedback = $feedbackcolumn && $alloptions->overallfeedback; + // One row for each attempt + foreach ($attempts as $attempt) { + $attemptoptions = quiz_get_reviewoptions($quiz, $attempt, $context); + $row = array(); - // prepare table header - $table->class = 'generaltable quizattemptsummary'; - $table->head = array($strattempt, $strtimecompleted); - $table->align = array("center", "left"); - $table->size = array("", ""); - if ($markcolumn) { - $table->head[] = "$strmarks / $quiz->sumgrades"; - $table->align[] = 'center'; - $table->size[] = ''; - } - if ($gradecolumn) { - $table->head[] = "$strgrade / $quiz->grade"; - $table->align[] = 'center'; - $table->size[] = ''; - } - if ($feedbackcolumn) { - $table->head[] = $strfeedback; - $table->align[] = 'left'; - $table->size[] = ''; - } - if (isset($quiz->showtimetaken)) { - $table->head[] = $strtimetaken; - $table->align[] = 'left'; - $table->size[] = ''; + // Add the attempt number, making it a link, if appropriate. + if ($attempt->preview) { + $row[] = make_review_link(get_string('preview', 'quiz'), $quiz, $attempt); + } else { + $row[] = make_review_link($attempt->attempt, $quiz, $attempt); } - // One row for each attempt - foreach ($attempts as $attempt) { - $attemptoptions = quiz_get_reviewoptions($quiz, $attempt, $context); - $row = array(); - - // Add the attempt number, making it a link, if appropriate. - if ($attempt->preview) { - $row[] = make_review_link(get_string('preview', 'quiz'), $quiz, $attempt); - } else { - $row[] = make_review_link($attempt->attempt, $quiz, $attempt); - } - - // prepare strings for time taken and date completed + // prepare strings for time taken and date completed + $timetaken = ''; + $datecompleted = ''; + if ($attempt->timefinish > 0) { + // attempt has finished + $timetaken = format_time($attempt->timefinish - $attempt->timestart); + $datecompleted = userdate($attempt->timefinish); + } else if ($available) { + // The attempt is still in progress. + $timetaken = format_time(time() - $attempt->timestart); + $datecompleted = ''; + } else if ($quiz->timeclose) { + // The attempt was not completed but is also not available any more becuase the quiz is closed. + $timetaken = format_time($quiz->timeclose - $attempt->timestart); + $datecompleted = userdate($quiz->timeclose); + } else { + // Something wheird happened. $timetaken = ''; $datecompleted = ''; - if ($attempt->timefinish > 0) { - // attempt has finished - $timetaken = format_time($attempt->timefinish - $attempt->timestart); - $datecompleted = userdate($attempt->timefinish); - } else if ($available) { - // The attempt is still in progress. - $timetaken = format_time(time() - $attempt->timestart); - $datecompleted = ''; - } else if ($quiz->timeclose) { - // The attempt was not completed but is also not available any more becuase the quiz is closed. - $timetaken = format_time($quiz->timeclose - $attempt->timestart); - $datecompleted = userdate($quiz->timeclose); + } + $row[] = $datecompleted; + + if ($markcolumn) { + if ($attemptoptions->scores) { + $row[] = make_review_link(round($attempt->sumgrades, $quiz->decimalpoints), $quiz, $attempt); } else { - // Something wheird happened. - $timetaken = ''; - $datecompleted = ''; - } - $row[] = $datecompleted; - - if ($markcolumn) { - if ($attemptoptions->scores) { - $row[] = make_review_link(round($attempt->sumgrades, $quiz->decimalpoints), $quiz, $attempt); - } else { - $row[] = ''; - } - } - - // Ouside the if because we may be showing feedback but not grades. - $attemptgrade = quiz_rescale_grade($attempt->sumgrades, $quiz); - - if ($gradecolumn) { - if ($attemptoptions->scores) { - $formattedgrade = $attemptgrade; - // highlight the highest grade if appropriate - if ($overallstats && $numattempts > 1 && !is_null($mygrade) && $attemptgrade == $mygrade && $quiz->grademethod == QUIZ_GRADEHIGHEST) { - $table->rowclass[$attempt->attempt] = 'bestrow'; - } - - $row[] = make_review_link($formattedgrade, $quiz, $attempt); - } else { - $row[] = ''; - } - } - - if ($feedbackcolumn) { - if ($attemptoptions->overallfeedback) { - $row[] = quiz_feedback_for_grade($attemptgrade, $quiz->id); - } else { - $row[] = ''; - } - } - - if (isset($quiz->showtimetaken)) { - $row[] = $timetaken; - } - - $table->data[$attempt->attempt] = $row; - } // End of loop over attempts. - print_table($table); - } - - // Print information about the student's best score for this quiz if possible. - $moreattempts = $unfinished || $numattempts < $quiz->attempts || $quiz->attempts == 0; - if (!$moreattempts) { - print_heading(get_string("nomoreattempts", "quiz")); - } - - if ($numattempts && $quiz->sumgrades && !is_null($mygrade)) { - if ($overallstats) { - if ($available && $moreattempts) { - $a = new stdClass; - $a->method = quiz_get_grading_option_name($quiz->grademethod); - $a->mygrade = $mygrade; - $a->quizgrade = $quiz->grade; - print_heading(get_string('gradesofar', 'quiz', $a)); - } else { - print_heading(get_string('yourfinalgradeis', 'quiz', "$mygrade / $quiz->grade")); + $row[] = ''; } } - if ($overallfeedback) { - echo ''.quiz_feedback_for_grade($mygrade, $quiz->id).'
'; - } - } + // Ouside the if because we may be showing feedback but not grades. + $attemptgrade = quiz_rescale_grade($attempt->sumgrades, $quiz); - // Print a button to start/continue an attempt, if appropriate. - if (!$quiz->questions) { - print_heading(get_string("noquestions", "quiz")); + if ($gradecolumn) { + if ($attemptoptions->scores) { + $formattedgrade = $attemptgrade; + // highlight the highest grade if appropriate + if ($overallstats && $numattempts > 1 && !is_null($mygrade) && $attemptgrade == $mygrade && $quiz->grademethod == QUIZ_GRADEHIGHEST) { + $table->rowclass[$attempt->attempt] = 'bestrow'; + } - } else if ($available && $moreattempts) { - echo "'.quiz_feedback_for_grade($mygrade, $quiz->id).'
'; + } + } - // Work out if the quiz is temporarily unavailable because of the delay option. - if (!empty($attempts)) { - $tempunavailable = ''; - $lastattempt = end($attempts); - $lastattempttime = $lastattempt->timefinish; - if ($numattempts == 1 && $quiz->delay1 && $timenow <= $lastattempttime + $quiz->delay1) { - $tempunavailable = get_string('temporaryblocked', 'quiz') . - ' '. userdate($lastattempttime + $quiz->delay1). ''; - } else if ($numattempts > 1 && $quiz->delay2 && $timenow <= $lastattempttime + $quiz->delay2) { - $tempunavailable = get_string('temporaryblocked', 'quiz') . - ' '. userdate($lastattempttime + $quiz->delay2). ''; - } + // Print a button to start/continue an attempt, if appropriate. + if (!$quiz->questions) { + print_heading(get_string("noquestions", "quiz")); - // If so, display a message and prevent the start button from appearing. - if ($tempunavailable) { - print_simple_box($tempunavailable, "center"); - print_continue($CFG->wwwroot . '/course/view.php?id=' . $course->id); - $buttontext = ''; - } - } + } else if ($available && $moreattempts) { + echo "