MDL-46093 quiz review should default to showing everything on one page

... as long as the quiz is not too big. At the moment, that limit is
set to 50 questions.
This commit is contained in:
Tim Hunt 2014-06-22 11:03:03 +01:00
parent 7a4832ecb9
commit 097dbfe11a
3 changed files with 337 additions and 19 deletions

View file

@ -433,6 +433,9 @@ class quiz_attempt {
/** @var string to identify the abandoned state. */
const ABANDONED = 'abandoned';
/** @var int maximum number of slots in the quiz for the review page to default to show all. */
const MAX_SLOTS_FOR_DEFAULT_REVIEW_SHOW_ALL = 50;
// Basic data.
protected $quizobj;
protected $attempt;
@ -522,7 +525,10 @@ class quiz_attempt {
return quiz_attempt_state_name($state);
}
private function determine_layout() {
/**
* Parse attempt->layout to populate the other arrays the represent the layout.
*/
protected function determine_layout() {
$this->pagelayout = array();
// Break up the layout string into pages.
@ -544,15 +550,16 @@ class quiz_attempt {
}
}
// Number the questions.
private function number_questions() {
/**
* Work out the number to display for each question/slot.
*/
protected function number_questions() {
$number = 1;
foreach ($this->pagelayout as $page => $slots) {
foreach ($slots as $slot) {
$question = $this->quba->get_question($slot);
if ($question->length > 0) {
if ($length = $this->is_real_question($slot)) {
$this->questionnumbers[$slot] = $number;
$number += $question->length;
$number += $length;
} else {
$this->questionnumbers[$slot] = get_string('infoshort', 'quiz');
}
@ -934,10 +941,11 @@ class quiz_attempt {
/**
* Is a particular question in this attempt a real question, or something like a description.
* @param int $slot the number used to identify this question within this attempt.
* @return bool whether that question is a real question.
* @return int whether that question is a real question. Actually returns the
* question length, which could theoretically be greater than one.
*/
public function is_real_question($slot) {
return $this->quba->get_question($slot)->length != 0;
return $this->quba->get_question($slot)->length;
}
/**
@ -1135,16 +1143,25 @@ class quiz_attempt {
* @param int $slot indicates which question to link to.
* @param int $page if specified, the URL of this particular page of the attempt, otherwise
* the URL will go to the first page. If -1, deduce $page from $slot.
* @param bool $showall if true, the URL will be to review the entire attempt on one page,
* and $page will be ignored.
* @param bool|null $showall if true, the URL will be to review the entire attempt on one page,
* and $page will be ignored. If null, a sensible default will be chosen.
* @param int $thispage if not -1, the current page. Will cause links to other things on
* this page to be output as only a fragment.
* @return string the URL to review this attempt.
*/
public function review_url($slot = null, $page = -1, $showall = false, $thispage = -1) {
public function review_url($slot = null, $page = -1, $showall = null, $thispage = -1) {
return $this->page_and_question_url('review', $slot, $page, $showall, $thispage);
}
/**
* By default, should this script show all questions on one page for this attempt?
* @param string $script the script name, e.g. 'attempt', 'summary', 'review'.
* @return whether show all on one page should be on by default.
*/
public function get_default_show_all($script) {
return $script == 'review' && count($this->questionpages) < self::MAX_SLOTS_FOR_DEFAULT_REVIEW_SHOW_ALL;
}
// Bits of content =========================================================
/**
@ -1572,15 +1589,22 @@ class quiz_attempt {
* 0 to just use the $page parameter.
* @param int $page -1 to look up the page number from the slot, otherwise
* the page number to go to.
* @param bool $showall if true, return a URL with showall=1, and not page number
* @param bool|null $showall if true, return a URL with showall=1, and not page number.
* if null, then an intelligent default will be chosen.
* @param int $thispage the page we are currently on. Links to questions on this
* page will just be a fragment #q123. -1 to disable this.
* @return The requested URL.
*/
protected function page_and_question_url($script, $slot, $page, $showall, $thispage) {
$defaultshowall = $this->get_default_show_all($script);
if ($showall === null && ($page == 0 || $page == -1)) {
$showall = $defaultshowall;
}
// Fix up $page.
if ($page == -1) {
if (!is_null($slot) && !$showall) {
if ($slot !== null && !$showall) {
$page = $this->get_question_page($slot);
} else {
$page = 0;
@ -1593,7 +1617,7 @@ class quiz_attempt {
// Add a fragment to scroll down to the question.
$fragment = '';
if (!is_null($slot)) {
if ($slot !== null) {
if ($slot == reset($this->pagelayout[$page])) {
// First question on page, go to top.
$fragment = '#';
@ -1609,8 +1633,8 @@ class quiz_attempt {
} else {
$url = new moodle_url('/mod/quiz/' . $script . '.php' . $fragment,
array('attempt' => $this->attempt->id));
if ($showall) {
$url->param('showall', 1);
if ($page == 0 && $showall != $defaultshowall) {
$url->param('showall', (int) $showall);
} else if ($page > 0) {
$url->param('page', $page);
}