AutorÃa | Ultima modificación | Ver Log |
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace mod_quiz\output;
use mod_quiz\quiz_attempt;
use moodle_url;
use question_attempt;
use question_display_options;
use question_state;
use renderable;
use user_picture;
/**
* Represents the navigation panel, and builds a {@see block_contents} to allow it to be output.
*
* This class is not currently renderable or templatable, but it probably should be in the future,
* which is why it is already in the output namespace.
*
* @package mod_quiz
* @category output
* @copyright 2008 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class navigation_panel_base {
/** @var quiz_attempt */
protected $attemptobj;
/** @var question_display_options */
protected $options;
/** @var integer */
protected $page;
/** @var boolean */
protected $showall;
/**
* Constructor.
*
* @param quiz_attempt $attemptobj construct the panel for this attempt.
* @param question_display_options $options display options in force.
* @param int $page which page of the quiz attempt is being shown, -1 if all.
* @param bool $showall whether all pages are being shown at once.
*/
public function __construct(quiz_attempt $attemptobj,
question_display_options $options, $page, $showall) {
$this->attemptobj = $attemptobj;
$this->options = $options;
$this->page = $page;
$this->showall = $showall;
}
/**
* Get the buttons and section headings to go in the quiz navigation block.
*
* @return renderable[] the buttons, possibly interleaved with section headings.
*/
public function get_question_buttons() {
$buttons = [];
foreach ($this->attemptobj->get_slots() as $slot) {
$heading = $this->attemptobj->get_heading_before_slot($slot);
if (!is_null($heading)) {
$sections = $this->attemptobj->get_quizobj()->get_sections();
if (!(empty($heading) && count($sections) == 1)) {
$buttons[] = new navigation_section_heading(format_string($heading));
}
}
$qa = $this->attemptobj->get_question_attempt($slot);
$showcorrectness = $this->options->correctness && $qa->has_marks();
$button = new navigation_question_button();
$button->id = 'quiznavbutton' . $slot;
$button->isrealquestion = $this->attemptobj->is_real_question($slot);
$button->number = $this->attemptobj->get_question_number($slot);
$button->stateclass = $qa->get_state_class($showcorrectness);
$button->navmethod = $this->attemptobj->get_navigation_method();
if (!$showcorrectness && $button->stateclass === 'notanswered') {
$button->stateclass = 'complete';
}
$button->statestring = $this->get_state_string($qa, $showcorrectness);
$button->page = $this->attemptobj->get_question_page($slot);
$button->currentpage = $this->showall || $button->page == $this->page;
$button->flagged = $qa->is_flagged();
$button->url = $this->get_question_url($slot);
if ($this->attemptobj->is_blocked_by_previous_question($slot)) {
$button->url = null;
$button->stateclass = 'blocked';
$button->statestring = get_string('questiondependsonprevious', 'quiz');
}
$buttons[] = $button;
}
return $buttons;
}
/**
* Get the human-readable description of the current state of a particular question.
*
* @param question_attempt $qa the attempt at the question of interest.
* @param bool $showcorrectness whether the current use is allowed to see if they have got the question right.
* @return string Human-readable description of the state.
*/
protected function get_state_string(question_attempt $qa, $showcorrectness) {
if ($qa->get_question(false)->length > 0) {
return $qa->get_state_string($showcorrectness);
}
// Special case handling for 'information' items.
if ($qa->get_state() == question_state::$todo) {
return get_string('notyetviewed', 'quiz');
} else {
return get_string('viewed', 'quiz');
}
}
/**
* Hook for subclasses to override to do output above the question buttons.
*
* @param renderer $output the quiz renderer to use.
* @return string HTML to output.
*/
public function render_before_button_bits(renderer $output) {
return '';
}
/**
* Hook that subclasses must override to do output after the question buttons.
*
* @param renderer $output the quiz renderer to use.
* @return string HTML to output.
*/
abstract public function render_end_bits(renderer $output);
/**
* Render the restart preview button.
*
* @param renderer $output the quiz renderer to use.
* @return string HTML to output.
*/
protected function render_restart_preview_link($output) {
if (!$this->attemptobj->is_own_preview()) {
return '';
}
return $output->restart_preview_button(new moodle_url(
$this->attemptobj->start_attempt_url(), ['forcenew' => true]));
}
/**
* Get the URL to navigate to a particular question.
*
* @param int $slot slot number, to identify the question.
* @return moodle_url|null URL if the user can navigate there, or null if they cannot.
*/
abstract protected function get_question_url($slot);
/**
* Get the user picture which should be displayed, if required.
*
* @return user_picture|null
*/
public function user_picture() {
global $DB;
if ($this->attemptobj->get_quiz()->showuserpicture == QUIZ_SHOWIMAGE_NONE) {
return null;
}
$user = $DB->get_record('user', ['id' => $this->attemptobj->get_userid()]);
$userpicture = new user_picture($user);
$userpicture->courseid = $this->attemptobj->get_courseid();
if ($this->attemptobj->get_quiz()->showuserpicture == QUIZ_SHOWIMAGE_LARGE) {
$userpicture->size = true;
}
return $userpicture;
}
/**
* Return 'allquestionsononepage' as CSS class name when $showall is set,
* otherwise, return 'multipages' as CSS class name.
*
* @return string, CSS class name
*/
public function get_button_container_class() {
// Quiz navigation is set on 'Show all questions on one page'.
if ($this->showall) {
return 'allquestionsononepage';
}
// Quiz navigation is set on 'Show one page at a time'.
return 'multipages';
}
}