MDL-71915 mod_quiz: Update the tertiary nav

Update the tertiary navigation for this
activity.
This commit is contained in:
Sujith Haridasan 2021-08-05 12:47:43 +05:30
parent 0f029c04d7
commit 6ba821dc01
27 changed files with 852 additions and 84 deletions

View File

@ -47,6 +47,8 @@ $PAGE->set_url($attemptobj->attempt_url(null, $page));
// During quiz attempts, the browser back/forwards buttons should force a reload.
$PAGE->set_cacheable(false);
$PAGE->set_secondary_active_tab("modulepage");
// Check login.
require_login($attemptobj->get_course(), false, $attemptobj->get_cm());

View File

@ -55,11 +55,6 @@ class edit_renderer extends \plugin_renderer_base {
\question_edit_contexts $contexts, \moodle_url $pageurl, array $pagevars) {
$output = '';
// Page title.
$output .= $this->heading_with_help(get_string('editingquizx', 'quiz',
format_string($quizobj->get_quiz_name())), 'editingquiz', 'quiz', '',
get_string('basicideasofquiz', 'quiz'), 2);
// Information at the top.
$output .= $this->quiz_state_warnings($structure);

View File

@ -0,0 +1,98 @@
<?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 moodle_url;
use renderable;
use renderer_base;
use templatable;
use url_select;
/**
* Render overrides action
*
* @package mod_quiz
* @copyright 2021 Sujith Haridasan <sujith@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class overridesaction implements renderable, templatable {
/** @var int */
private $cmid;
/** @var string */
private $mode;
/** @var bool */
private $canedit;
/** @var array */
private $options;
/**
* overridesaction constructor.
*
* @param int $cmid The course module id.
* @param string $mode The mode passed for the overrides url.
* @param bool $canedit Does the user have capabilities to list overrides.
* @param array $options The options passed to single button.
*/
public function __construct(int $cmid, string $mode, bool $canedit, array $options) {
$this->cmid = $cmid;
$this->mode = $mode;
$this->canedit = $canedit;
$this->options = $options;
}
/**
* Get the data for the template
*
* @param renderer_base $output renderer_base object.
* @return array data for the template.
*/
public function export_for_template(renderer_base $output): array {
global $PAGE;
$useroverride = new moodle_url('/mod/quiz/overrides.php', ['cmid' => $this->cmid, 'mode' => 'user']);
$groupoverride = new moodle_url('/mod/quiz/overrides.php', ['cmid' => $this->cmid, 'mode' => 'group']);
$menu = [
$useroverride->out(false) => get_string('useroverrides', 'quiz'),
$groupoverride->out(false) => get_string('groupoverrides', 'quiz')
];
$urlselect = new url_select($menu, $PAGE->url->out(false), null, 'quizoverrides');
$overridesbuttonurl =
new moodle_url('/mod/quiz/overrideedit.php', ['cmid' => $this->cmid, 'action' => 'add' . $this->mode]);
if ($this->mode === 'group') {
$overridesbutton = new \single_button($overridesbuttonurl, get_string( 'addnewgroupoverride', 'quiz'),
'post', true);
} else {
$overridesbutton = new \single_button($overridesbuttonurl, get_string( 'addnewuseroverride', 'quiz'),
'get', true);
}
if (isset($this->options['disabled'])) {
$overridesbutton->disabled = true;
}
return [
'overrides' => $urlselect->export_for_template($output),
'canedit' => $this->canedit,
'overridesbtn' => $overridesbutton->export_for_template($output),
];
}
}

View File

@ -0,0 +1,68 @@
<?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 renderable;
use renderer_base;
use templatable;
use moodle_url;
/**
* Render the tertiary elements for the edit page
*
* @package mod_quiz
* @copyright 2021 Sujith Haridasan <sujith@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class overwriteedit implements templatable, renderable {
/** @var int */
private $cmid;
/** @var bool */
private $quizhasquestion;
/**
* overwriteedit constructor.
*
* @param int $cmid The course module id.
* @param bool $quizhasquestion Check if quiz has question.
*/
public function __construct(int $cmid, bool $quizhasquestion) {
$this->cmid = $cmid;
$this->quizhasquestion = $quizhasquestion;
}
/**
* Provides the data for the template.
*
* @param renderer_base $output renderer_base object
* @return array data for the template
*/
public function export_for_template(renderer_base $output): array {
$data = [];
$data = [
'back' => (new moodle_url('/mod/quiz/view.php', ['id' => $this->cmid]))->out(false),
];
if ($this->quizhasquestion) {
$data['previewlink'] =
(new moodle_url('/mod/quiz/startattempt.php', ['cmid' => $this->cmid, 'sesskey' => sesskey()]))->out(false);
$data['previewquiz'] = get_string('previewquiz', 'mod_quiz');
}
return $data;
}
}

View File

@ -0,0 +1,65 @@
<?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 renderable;
use renderer_base;
use templatable;
use moodle_url;
/**
* Output the preview action area of this activity
*
* @package mod_quiz
* @copyright 2021 Sujith Haridasan <sujith@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class overwritepreview implements templatable, renderable {
/** @var int */
private $cmid;
/** @var bool */
private $canedit;
/**
* overwritepreview constructor.
*
* @param int $cmid The course module id.
* @param bool $canedit Can edit the quiz.
*/
public function __construct(int $cmid, bool $canedit) {
$this->cmid = $cmid;
$this->canedit = $canedit;
}
/**
* Provide data for the template
*
* @param renderer_base $output
* @return array data for the template
*/
public function export_for_template(renderer_base $output): array {
$data = [
'back' => (new moodle_url('/mod/quiz/view.php', ['id' => $this->cmid]))->out(false),
];
if ($this->canedit) {
$data['editlink'] = (new moodle_url('/mod/quiz/edit.php', ['cmid' => $this->cmid]))->out(false);
}
return $data;
}
}

View File

@ -0,0 +1,99 @@
<?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 moodle_url;
use renderer_base;
use templatable;
use renderable;
/**
* Render view action with preview and edit buttons
*
* @package mod_quiz
* @copyright 2021 Sujith Haridasan <sujith@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class previeweditaction implements templatable, renderable {
/** @var int */
private $cmid;
/** @var bool */
private $canedit;
/** @var bool */
private $canattempt;
/** @var bool */
private $canpreview;
/** @var bool */
private $quizhasquestions;
/** @var int */
private $attempts;
/**
* previeweditaction constructor.
*
* @param int $cmid The course module id.
* @param bool $canedit Can edit the quiz.
* @param bool $canattempt can attempt the quiz.
* @param bool $canpreview Can preview the quiz.
* @param bool $quizhasquestions If quiz has questions.
* @param int $attempts The attempts made.
*/
public function __construct(int $cmid, bool $canedit, bool $canattempt,
bool $canpreview, bool $quizhasquestions, int $attempts) {
$this->cmid = $cmid;
$this->canedit = $canedit;
$this->canattempt = $canattempt;
$this->canpreview = $canpreview;
$this->quizhasquestions = $quizhasquestions;
$this->attempts = $attempts;
}
/**
* Provide data for the template
*
* @param renderer_base $output renderer_base objects.
* @return array data for template
*/
public function export_for_template(renderer_base $output): array {
$data = [];
if ($this->quizhasquestions) {
if ($this->canpreview) {
$data['previewlink'] = (new moodle_url('/mod/quiz/startattempt.php',
['attempt' => $this->attempts, 'cmid' => $this->cmid, 'sesskey' => sesskey()]))->out(false);
$data['previewquiz'] = get_string('previewquiz', 'mod_quiz');
}
if ($this->canedit) {
$data['editlink'] = (new moodle_url('/mod/quiz/edit.php', ['cmid' => $this->cmid]))->out(false);
}
if ($this->canattempt && !$this->canpreview) {
$data['attemptlink'] =
(new moodle_url('/mod/quiz/startattempt.php', ['cmid' => $this->cmid, 'sesskey' => sesskey()]))->out(false);
}
} else {
$data['addquestionlink'] = (new moodle_url('/mod/quiz/edit.php', ['cmid' => $this->cmid]))->out(false);
}
return $data;
}
}

View File

@ -0,0 +1,73 @@
<?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 templatable;
use renderable;
use renderer_base;
use moodle_url;
use url_select;
/**
* Render results action
*
* @package mod_quiz
* @copyright 2021 Sujith Haridasan <sujith@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class resultsaction implements templatable, renderable {
/** @var int */
private $id;
/**
* resultsaction constructor.
*
* @param int $id The course module id.
*/
public function __construct(int $id) {
$this->id = $id;
}
/**
* Provide data for the template
*
* @param renderer_base $output renderer_base object.
* @return array data for template.
*/
public function export_for_template(renderer_base $output): array {
global $PAGE;
$gradeslink = new moodle_url('/mod/quiz/report.php', ['id' => $this->id, 'mode' => 'overview']);
$responseslink = new moodle_url('/mod/quiz/report.php', ['id' => $this->id, 'mode' => 'responses']);
$statisticslink = new moodle_url('/mod/quiz/report.php', ['id' => $this->id, 'mode' => 'statistics']);
$manualgrading = new moodle_url('/mod/quiz/report.php', ['id' => $this->id, 'mode' => 'grading']);
$menu = [
$gradeslink->out(false) => get_string('grades', 'grades'),
$responseslink->out(false) => get_string('responses', 'quiz_responses'),
$statisticslink->out(false) => get_string('statistics', 'quiz_statistics'),
$manualgrading->out(false) => get_string('grading', 'quiz_grading')
];
$urlselect = new url_select($menu, $PAGE->url->out(false), null, 'quizresults');
$data = [
'resultaction' => $urlselect->export_for_template($output)
];
return $data;
}
}

View File

@ -59,6 +59,7 @@ $defaultcategory = $defaultcategoryobj->id . ',' . $defaultcategoryobj->contexti
$quizhasattempts = quiz_has_attempts($quiz->id);
$PAGE->set_url($thispageurl);
$PAGE->set_secondary_active_tab("modulepage");
// Get the course object and related bits.
$course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST);
@ -185,8 +186,14 @@ $node = $PAGE->settingsnav->find('mod_quiz_edit', navigation_node::TYPE_SETTING)
if ($node) {
$node->make_active();
}
$overwriteedit = new \mod_quiz\output\overwriteedit($cmid, quiz_has_questions($quiz->id));
echo $OUTPUT->header();
$renderer = $PAGE->get_renderer('mod_quiz');
echo $renderer->overwrite_edit_action($overwriteedit);
// Initialise the JavaScript.
$quizeditconfig = new stdClass();
$quizeditconfig->url = $thispageurl->out(true, array('qbanktool' => '0'));

View File

@ -47,7 +47,10 @@ $PAGE->navbar->add($strquizzes);
$PAGE->set_title($strquizzes);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading($strquizzes, 2);
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading($strquizzes, 2);
}
// Get all the appropriate data.
if (!$quizzes = get_all_instances_in_course("quiz", $course)) {

View File

@ -7,3 +7,4 @@ completionpassdesc,mod_quiz
completionpass_help,mod_quiz
completiondetail:passgrade,mod_quiz
gradetopassnotset,mod_quiz
basicideasofquiz,mod_quiz

View File

@ -100,6 +100,7 @@ $string['attemptincomplete'] = 'That attempt (by {$a}) is not yet completed.';
$string['attemptlast'] = 'Last attempt';
$string['attemptnumber'] = 'Attempt';
$string['attemptquiznow'] = 'Attempt quiz now';
$string['attemptquiz'] = 'Attempt quiz';
$string['attemptreviewtitle'] = '{$a}: Attempt review';
$string['attemptreviewtitlepaged'] = '{$a->name}: Attempt review (page {$a->currentpage} of {$a->totalpages})';
$string['attempts'] = 'Attempts';
@ -124,7 +125,6 @@ $string['back'] = 'Back to preview question';
$string['backtocourse'] = 'Back to the course';
$string['backtoquestionlist'] = 'Back to question list';
$string['backtoquiz'] = 'Back to quiz editing';
$string['basicideasofquiz'] = 'The basic ideas of quiz-making';
$string['bestgrade'] = 'Best grade';
$string['bothattempts'] = 'Show students with and without attempts';
$string['browsersecurity'] = 'Browser security';
@ -673,7 +673,7 @@ $string['popupnotice'] = 'Students will see this quiz in a secure window';
$string['preprocesserror'] = 'Error occurred during pre-processing!';
$string['preview'] = 'Preview';
$string['previewquestion'] = 'Preview question';
$string['previewquiz'] = 'Preview {$a}';
$string['previewquiz'] = 'Preview quiz';
$string['previewquiznow'] = 'Preview quiz now';
$string['previous'] = 'Previous state';
$string['privacy:metadata:core_question'] = 'The quiz activity stores question usage information in the core_question subsystem.';
@ -1054,3 +1054,4 @@ $string['completionpassdesc'] = 'Student must achieve a passing grade to complet
$string['completionpass_help'] = 'If enabled, this activity is considered complete when the student receives a pass grade (as specified in the Grade section of the quiz settings) or higher.';
$string['completiondetail:passgrade'] = 'Receive a pass grade';
$string['gradetopassnotset'] = 'This quiz does not yet have a grade to pass set. It may be set in the Grade section of the quiz settings.';
$string['basicideasofquiz'] = 'The basic ideas of quiz-making';

View File

@ -1731,15 +1731,9 @@ function quiz_extend_settings_navigation($settings, $quiznode) {
}
if (has_any_capability(['mod/quiz:manageoverrides', 'mod/quiz:viewoverrides'], $PAGE->cm->context)) {
$url = new moodle_url('/mod/quiz/overrides.php', array('cmid'=>$PAGE->cm->id));
$node = navigation_node::create(get_string('groupoverrides', 'quiz'),
new moodle_url($url, array('mode'=>'group')),
navigation_node::TYPE_SETTING, null, 'mod_quiz_groupoverrides');
$quiznode->add_node($node, $beforekey);
$node = navigation_node::create(get_string('useroverrides', 'quiz'),
new moodle_url($url, array('mode'=>'user')),
navigation_node::TYPE_SETTING, null, 'mod_quiz_useroverrides');
$url = new moodle_url('/mod/quiz/overrides.php', array('cmid' => $PAGE->cm->id));
$node = navigation_node::create(get_string('overrides', 'quiz'),
$url, navigation_node::TYPE_SETTING, null, 'mod_quiz_useroverrides');
$quiznode->add_node($node, $beforekey);
}
@ -1748,7 +1742,8 @@ function quiz_extend_settings_navigation($settings, $quiznode) {
new moodle_url('/mod/quiz/edit.php', array('cmid'=>$PAGE->cm->id)),
navigation_node::TYPE_SETTING, null, 'mod_quiz_edit',
new pix_icon('t/edit', ''));
$quiznode->add_node($node, $beforekey);
$editquiznode = $quiznode->add_node($node, $beforekey);
$editquiznode->set_show_in_secondary_navigation(false);
}
if (has_capability('mod/quiz:preview', $PAGE->cm->context)) {
@ -1757,9 +1752,12 @@ function quiz_extend_settings_navigation($settings, $quiznode) {
$node = navigation_node::create(get_string('preview', 'quiz'), $url,
navigation_node::TYPE_SETTING, null, 'mod_quiz_preview',
new pix_icon('i/preview', ''));
$quiznode->add_node($node, $beforekey);
$previewnode = $quiznode->add_node($node, $beforekey);
$previewnode->set_show_in_secondary_navigation(false);
}
question_extend_settings_navigation($quiznode, $PAGE->cm->context)->trim_if_empty();
if (has_any_capability(array('mod/quiz:viewreports', 'mod/quiz:grade'), $PAGE->cm->context)) {
require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php');
$reportlist = quiz_report_list($PAGE->cm->context);
@ -1768,7 +1766,7 @@ function quiz_extend_settings_navigation($settings, $quiznode) {
array('id' => $PAGE->cm->id, 'mode' => reset($reportlist)));
$reportnode = $quiznode->add_node(navigation_node::create(get_string('results', 'quiz'), $url,
navigation_node::TYPE_SETTING,
null, null, new pix_icon('i/report', '')), $beforekey);
null, null, new pix_icon('i/report', '')));
foreach ($reportlist as $report) {
$url = new moodle_url('/mod/quiz/report.php',
@ -1778,8 +1776,6 @@ function quiz_extend_settings_navigation($settings, $quiznode) {
null, 'quiz_report_' . $report, new pix_icon('i/item', '')));
}
}
question_extend_settings_navigation($quiznode, $PAGE->cm->context)->trim_if_empty();
}
/**

View File

@ -89,7 +89,9 @@ $PAGE->set_title($title);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading(format_string($quiz->name, true, array('context' => $context)));
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($quiz->name, true, array('context' => $context)));
}
if ($override->groupid) {
$group = $DB->get_record('groups', ['id' => $override->groupid], 'id, name');

View File

@ -66,6 +66,9 @@ if ($overrideid) {
$PAGE->set_url($url);
// Activate the secondary nav tab.
$PAGE->set_secondary_active_tab("mod_quiz_useroverrides");
require_login($course, false, $cm);
$context = context_module::instance($cm->id);
@ -239,7 +242,9 @@ $PAGE->set_pagelayout('admin');
$PAGE->set_title($pagetitle);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading(format_string($quiz->name, true, array('context' => $context)));
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($quiz->name, true, array('context' => $context)));
}
$mform->display();

View File

@ -69,6 +69,9 @@ $PAGE->set_pagelayout('admin');
$PAGE->set_title($title);
$PAGE->set_heading($course->fullname);
// Activate the secondary nav tab.
$PAGE->set_secondary_active_tab("mod_quiz_useroverrides");
// Delete orphaned group overrides.
$sql = 'SELECT o.id
FROM {quiz_overrides} o
@ -303,32 +306,32 @@ echo $OUTPUT->header();
echo $OUTPUT->heading($title);
// Output the table and button.
echo html_writer::start_tag('div', ['id' => 'quizoverrides']);
$output = '';
$output .= html_writer::start_tag('div', ['id' => 'quizoverrides']);
if (count($table->data)) {
echo html_writer::table($table);
$output .= html_writer::table($table);
} else {
if ($groupmode) {
echo $OUTPUT->notification(get_string('overridesnoneforgroups', 'quiz'), 'info', false);
$output .= $OUTPUT->notification(get_string('overridesnoneforgroups', 'quiz'), 'info', false);
} else {
echo $OUTPUT->notification(get_string('overridesnoneforusers', 'quiz'), 'info', false);
$output .= $OUTPUT->notification(get_string('overridesnoneforusers', 'quiz'), 'info', false);
}
}
if ($hasinactive) {
echo $OUTPUT->notification(get_string('inactiveoverridehelp', 'quiz'), 'info', false);
$output .= $OUTPUT->notification(get_string('inactiveoverridehelp', 'quiz'), 'info', false);
}
$addbutton = '';
$options = [];
if ($canedit) {
echo html_writer::start_tag('div', ['class' => 'buttons']);
$options = [];
$output .= html_writer::start_tag('div', ['class' => 'buttons']);
if ($groupmode) {
if (empty($groups)) {
// There are no groups.
echo $OUTPUT->notification(get_string('groupsnone', 'quiz'), 'error');
$output .= $OUTPUT->notification(get_string('groupsnone', 'quiz'), 'error');
$options['disabled'] = true;
}
echo $OUTPUT->single_button($overrideediturl->out(true,
['action' => 'addgroup', 'cmid' => $cm->id]),
get_string('addnewgroupoverride', 'quiz'), 'post', $options);
} else {
$users = [];
// See if there are any students in the quiz.
@ -346,17 +349,22 @@ if ($canedit) {
if (empty($users)) {
// There are no students.
echo $OUTPUT->notification($nousermessage, 'error');
$output .= $OUTPUT->notification($nousermessage, 'error');
$options['disabled'] = true;
}
echo $OUTPUT->single_button($overrideediturl->out(true,
['action' => 'adduser', 'cmid' => $cm->id]),
get_string('addnewuseroverride', 'quiz'), 'get', $options);
}
echo html_writer::end_tag('div');
$output .= html_writer::end_tag('div');
}
echo html_writer::end_tag('div');
$output .= html_writer::end_tag('div');
// Outputs overrides action.
$overridesaction = new \mod_quiz\output\overridesaction($cmid, $mode, $canedit, $options);
$renderer = $PAGE->get_renderer('mod_quiz');
echo $renderer->overrides_action($overridesaction);
// Now output what we captured after the overrides action.
echo $output;
// Finish the page.
echo $OUTPUT->footer();

View File

@ -449,8 +449,17 @@ class mod_quiz_renderer extends plugin_renderer_base {
*/
public function attempt_page($attemptobj, $page, $accessmanager, $messages, $slots, $id,
$nextpage) {
$context = $attemptobj->get_quizobj()->get_context();
$cmid = $attemptobj->get_quizobj()->get_cmid();
$canedit = has_capability('mod/quiz:manage', $context);
$overwritepreview = new \mod_quiz\output\overwritepreview($cmid, $canedit);
$output = '';
$output .= $this->header();
$renderer = $this->page->get_renderer('mod_quiz');
$output .= $renderer->overwrite_preview_action($overwritepreview);
$output .= $this->quiz_notices($messages);
$output .= $this->countdown_timer($attemptobj, time());
$output .= $this->attempt_form($attemptobj, $page, $slots, $id, $nextpage);
@ -540,7 +549,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
protected function attempt_navigation_buttons($page, $lastpage, $navmethod = 'free') {
$output = '';
$output .= html_writer::start_tag('div', array('class' => 'submitbtns'));
$output .= html_writer::start_tag('div', array('class' => 'submitbtns mb-4'));
if ($page > 0 && $navmethod == 'free') {
$output .= html_writer::empty_tag('input', array('type' => 'submit', 'name' => 'previous',
'value' => get_string('navigateprevious', 'quiz'), 'class' => 'mod_quiz-prev-nav btn btn-secondary',
@ -625,7 +634,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
public function access_messages($messages) {
$output = '';
foreach ($messages as $message) {
$output .= html_writer::tag('p', $message) . "\n";
$output .= html_writer::tag('p', $message, ['class' => 'float-left']) . "\n";
}
return $output;
}
@ -677,21 +686,19 @@ class mod_quiz_renderer extends plugin_renderer_base {
foreach ($slots as $slot) {
// Add a section headings if we need one here.
$heading = $attemptobj->get_heading_before_slot($slot);
if ($heading) {
$heading = format_string($heading);
}
$sections = $attemptobj->get_quizobj()->get_sections();
if (!is_null($heading) && empty($heading) && count($sections) > 1) {
if (!is_null($heading) && empty($heading)) {
$heading = get_string('sectionnoname', 'quiz');
$heading = \html_writer::span($heading, 'dimmed_text');
}
if ($heading) {
$cell = new html_table_cell($heading);
$cell = new html_table_cell(format_string($heading));
$cell->header = true;
$cell->colspan = $tablewidth;
$table->data[] = array($cell);
$table->rowclasses[] = 'quizsummaryheading';
$classes = 'quizsummaryheading';
if ($heading === get_string('sectionnoname', 'quiz')) {
$classes .= ' dimmed_text';
}
$table->rowclasses[] = $classes;
}
// Don't display information items.
@ -799,10 +806,14 @@ class mod_quiz_renderer extends plugin_renderer_base {
*/
public function view_page($course, $quiz, $cm, $context, $viewobj) {
$output = '';
$output .= $this->view_information($quiz, $cm, $context, $viewobj->infomessages);
$output .= $this->view_information($quiz, $cm, $context, $viewobj->infomessages, $viewobj->quizhasquestions);
$output .= $this->view_table($quiz, $context, $viewobj);
$output .= $this->view_result_info($quiz, $context, $cm, $viewobj);
$output .= $this->box($this->view_page_buttons($viewobj), 'quizattempt');
// Output any access messages.
if ($viewobj->infomessages) {
$output .= $this->box($this->access_messages($viewobj->infomessages), 'quizinfo');
}
return $output;
}
@ -814,27 +825,11 @@ class mod_quiz_renderer extends plugin_renderer_base {
* @return string HTML to output.
*/
public function view_page_buttons(mod_quiz_view_object $viewobj) {
global $CFG;
$output = '';
if (!$viewobj->quizhasquestions) {
$output .= $this->no_questions_message($viewobj->canedit, $viewobj->editurl);
$output .= $this->generate_no_questions_message();
}
$output .= $this->access_messages($viewobj->preventmessages);
if ($viewobj->buttontext) {
$output .= $this->start_attempt_button($viewobj->buttontext,
$viewobj->startattempturl, $viewobj->preflightcheckform,
$viewobj->popuprequired, $viewobj->popupoptions);
}
if ($viewobj->showbacktocourse) {
$output .= $this->single_button($viewobj->backtocourseurl,
get_string('backtocourse', 'quiz'), 'get',
array('class' => 'continuebutton'));
}
return $output;
}
@ -890,9 +885,13 @@ class mod_quiz_renderer extends plugin_renderer_base {
* @param object $quiz the quiz settings.
* @param object $cm the course_module object.
* @param object $context the quiz context.
* @deprecated since Moodle 4.0 MDL-71915 - please do not use this function any more.
*
* @return string HTML to output.
*/
public function no_questions_message($canedit, $editurl) {
debugging('no_questions_message() is deprecated, please use generate_no_questions_message() instead.', DEBUG_DEVELOPER);
$output = html_writer::start_tag('div', array('class' => 'card text-center mb-3'));
$output .= html_writer::start_tag('div', array('class' => 'card-body'));
@ -906,6 +905,21 @@ class mod_quiz_renderer extends plugin_renderer_base {
return $output;
}
/**
* Generate a message saying that this quiz has no questions
*
* @return string HTML to output.
*/
public function generate_no_questions_message() {
$output = html_writer::start_tag('div', array('class' => 'text-left mb-3'));
$output .= $this->notification(get_string('noquestions', 'quiz'), 'warning', false);
$output .= html_writer::end_tag('div');
return $output;
}
/**
* Outputs an error message for any guests accessing the quiz
*
@ -914,10 +928,11 @@ class mod_quiz_renderer extends plugin_renderer_base {
* @param int $cm Course Module ID
* @param int $context The page contect ID
* @param array $messages Array containing any messages
* @param bool $quizhasquestions If quiz has questions
*/
public function view_page_guest($course, $quiz, $cm, $context, $messages) {
public function view_page_guest($course, $quiz, $cm, $context, $messages, $quizhasquestions = false) {
$output = '';
$output .= $this->view_information($quiz, $cm, $context, $messages);
$output .= $this->view_information($quiz, $cm, $context, $messages, $quizhasquestions);
$guestno = html_writer::tag('p', get_string('guestsno', 'quiz'));
$liketologin = html_writer::tag('p', get_string('liketologin'));
$referer = get_local_referer(false);
@ -933,11 +948,12 @@ class mod_quiz_renderer extends plugin_renderer_base {
* @param int $cm Course Module ID
* @param int $context The page contect ID
* @param array $messages Array containing any messages
* @param bool $quizhasquestions If quiz has questions
*/
public function view_page_notenrolled($course, $quiz, $cm, $context, $messages) {
public function view_page_notenrolled($course, $quiz, $cm, $context, $messages, $quizhasquestions = false) {
global $CFG;
$output = '';
$output .= $this->view_information($quiz, $cm, $context, $messages);
$output .= $this->view_information($quiz, $cm, $context, $messages, $quizhasquestions);
$youneedtoenrol = html_writer::tag('p', get_string('youneedtoenrol', 'quiz'));
$button = html_writer::tag('p',
$this->continue_button($CFG->wwwroot . '/course/view.php?id=' . $course->id));
@ -952,15 +968,18 @@ class mod_quiz_renderer extends plugin_renderer_base {
* @param object $cm the course_module object.
* @param context $context the quiz context.
* @param array $messages any access messages that should be described.
* @param bool $quizhasquestions does quiz has questions added.
* @return string HTML to output.
*/
public function view_information($quiz, $cm, $context, $messages) {
public function view_information($quiz, $cm, $context, $messages, bool $quizhasquestions = false) {
global $USER;
$output = '';
// Print quiz name.
$output .= $this->heading(format_string($quiz->name));
if (!$this->page->has_secondary_navigation()) {
$output .= $this->heading(format_string($quiz->name));
}
// Print any activity information (eg completion requirements / dates).
$cminfo = cm_info::create($cm);
@ -971,10 +990,14 @@ class mod_quiz_renderer extends plugin_renderer_base {
// Print quiz description.
$output .= $this->quiz_intro($quiz, $cm);
// Output any access messages.
if ($messages) {
$output .= $this->box($this->access_messages($messages), 'quizinfo');
}
// Print the preview, quiz buttons for tertiary nav.
$canedit = has_capability('mod/quiz:manage', $context);
$canpreview = has_capability('mod/quiz:preview', $context);
$canattempt = has_capability('mod/quiz:attempt', $context);
$previeweditaction = new \mod_quiz\output\previeweditaction($cm->id, $canedit, $canattempt, $canpreview, $quizhasquestions,
$quiz->attempts);
$renderer = $this->page->get_renderer('mod_quiz');
$output .= $renderer->preview_edit_action($previeweditaction);
// Show number of attempts summary to those who can view reports.
if (has_capability('mod/quiz:viewreports', $context)) {
@ -1360,6 +1383,56 @@ class mod_quiz_renderer extends plugin_renderer_base {
array('id' => 'connection-error', 'style' => 'display: none;', 'role' => 'alert')) .
html_writer::tag('div', $ok, array('id' => 'connection-ok', 'style' => 'display: none;', 'role' => 'alert'));
}
/**
* Get the rendered HTML for the action area of view.php
*
* @param \mod_quiz\output\previeweditaction $previeweditaction previeweditaction object.
* @return string rendered HTML for the action area of view.php
*/
public function preview_edit_action(\mod_quiz\output\previeweditaction $previeweditaction):string {
return $this->render_from_template('mod_quiz/quiz_preview_edit_action', $previeweditaction->export_for_template($this));
}
/**
* Get the rendered HTML for the action area of preview page
*
* @param \mod_quiz\output\overwritepreview $overwritepreview overwritepreview object.
* @return string rendered HTML for the preview page
*/
public function overwrite_preview_action(\mod_quiz\output\overwritepreview $overwritepreview): string {
return $this->render_from_template('mod_quiz/quiz_preview_action', $overwritepreview->export_for_template($this));
}
/**
* Get the rendered HTML for the action area of the edit page.
*
* @param \mod_quiz\output\overwriteedit $overwriteedit overwriteedit object.
* @return string rendered HTML for the edit page
*/
public function overwrite_edit_action(\mod_quiz\output\overwriteedit $overwriteedit): string {
return $this->render_from_template('mod_quiz/quiz_edit_action', $overwriteedit->export_for_template($this));
}
/**
* Get rendered HTML for the action area of the results page.
*
* @param \mod_quiz\output\resultsaction $resultsaction resultsaction object.
* @return string rendered HTML string from the template.
*/
public function get_results_action(\mod_quiz\output\resultsaction $resultsaction): string {
return $this->render_from_template('mod_quiz/quiz_results_action', $resultsaction->export_for_template($this));
}
/**
* Get rendered HTML for the action area of the overrides page.
*
* @param \mod_quiz\output\overridesaction $overridesaction the overridesaction object.
* @return string rendered HTML string from the template.
*/
public function overrides_action(\mod_quiz\output\overridesaction $overridesaction): string {
return $this->render_from_template('mod_quiz/quiz_overrides', $overridesaction->export_for_template($this));
}
}

View File

@ -68,7 +68,12 @@ abstract class quiz_default_report {
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
$context = context_module::instance($cm->id);
echo $OUTPUT->heading(format_string($quiz->name, true, array('context' => $context)));
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($quiz->name, true, array('context' => $context)));
}
$resultsaction = new \mod_quiz\output\resultsaction($cm->id);
$renderer = $PAGE->get_renderer('mod_quiz');
echo $renderer->get_results_action($resultsaction);
if (!empty($CFG->enableplagiarism)) {
require_once($CFG->libdir . '/plagiarismlib.php');
echo plagiarism_update_status($course, $cm);

View File

@ -42,6 +42,7 @@ if ($page !== 0) {
$url->param('showall', $showall);
}
$PAGE->set_url($url);
$PAGE->set_secondary_active_tab("modulepage");
$attemptobj = quiz_create_attempt_handling_errors($attemptid, $cmid);
$attemptobj->preload_all_attempt_step_users();

View File

@ -32,6 +32,7 @@ $cmid = optional_param('cmid', null, PARAM_INT);
$PAGE->set_url('/mod/quiz/summary.php', array('attempt' => $attemptid));
// During quiz attempts, the browser back/forwards buttons should force a reload.
$PAGE->set_cacheable(false);
$PAGE->set_secondary_active_tab("modulepage");
$attemptobj = quiz_create_attempt_handling_errors($attemptid, $cmid);

View File

@ -0,0 +1,39 @@
{{!
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/>.
}}
{{!
@template mod_quiz/quiz_edit_action
Actions bar at the top of the quiz edit page UI.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* see mod/quiz/classes/output/overwriteedit.php
Example context (json):
{
"back": "http://localhost/mod/quiz/view.php?id=2",
"previewlink": "http://localhost/mod/quiz/startattempt.php?cmid=2&sesskey=G8FPNoJz9r"
}
}}
<div class="container-fluid mb-3">
<div class="row">
<a class="btn btn-secondary" href="{{back}}">{{#str}}back, core {{/str}}</a>
{{#previewlink}}
<a class="btn btn-secondary ml-2" href="{{previewlink}}">{{#str}}previewquiz, quiz{{/str}}</a>
{{/previewlink}}
</div>
</div>

View File

@ -0,0 +1,75 @@
{{!
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/>.
}}
{{!
@template mod_quiz/quiz_overrides
Actions bar at the top of the overrides page UI.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* see mod/quiz/classes/output/overridesaction.php
Example context (json):
{
"overrides": {
"options": [{
"name": "User overrides",
"value": "/mod/quiz/overrides.php?cmid=71&mode=user"
},
{
"name": "Group overrrides",
"value": "/mod/quiz/overrides.php?cmid=71&mode=group"
}
]
},
"canedit": true,
"overridesbtn": {
"id": "single_button1234",
"method": "get",
"url": "http://localhost/moodle/mod/quiz/overrideedit.php",
"lablel": "Add user override",
"classes": "singlebutton",
"disabled": false,
"params": [
{
"name": "cmid",
"value": "73"
},
{
"name": "action",
"value": "adduser"
}
]
}
}
}}
<div class="container-fluid mb-3">
<div class="row">
{{#overrides}}
<div class="col-xs-6">
{{>core/url_select}}
</div>
{{/overrides}}
{{#canedit}}
{{#overridesbtn}}
<div class="ml-2">
{{>core/single_button}}
</div>
{{/overridesbtn}}
{{/canedit}}
</div>
</div>

View File

@ -0,0 +1,39 @@
{{!
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/>.
}}
{{!
@template mod_quiz/quiz_preview_action
Action bar at the top of the quiz attempt page UI.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* see mod/quiz/classes/output/overwritepreview.php
Example context (json):
{
"back": "http://localhost/mod/quiz/view.php?id=2",
"editlink": "http://localhost/mod/quiz/edit.php?cmid=3"
}
}}
<div class="container-fluid mb-3">
<div class="row">
<a class="btn btn-secondary" href="{{back}}">{{#str}}back, core {{/str}}</a>
{{#editlink}}
<a class="btn btn-primary ml-2" href="{{editlink}}">{{#str}}editquiz, quiz{{/str}}</a>
{{/editlink}}
</div>
</div>

View File

@ -0,0 +1,49 @@
{{!
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/>.
}}
{{!
@template mod_quiz/quiz_preview_edit_action
Actions bar at the top of the quiz view page
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* see mod/quiz/classes/output/previeweditaction.php
Example context (json):
{
"previewlink": "http://localhost/mod/quiz/startattempt.php?cmid=2&sesskey=G8FPNoJz9r",
"editlink": "http://localhost/mod/quiz/edit.php?cmid=3",
"attemptlink": "http://localhost/mod/quiz/startattempt.php?cmid=5&sesskey=psqFTeG0Hi",
"addquestionlink": "http://localhost/mod/quiz/edit.php?cmid=3"
}
}}
<div class="container-fluid mb-3">
<div class="row">
{{#previewlink}}
<a class="btn btn-secondary mr-2" href="{{previewlink}}">{{#str}}previewquiz, quiz{{/str}}</a>
{{/previewlink}}
{{#editlink}}
<a class="btn btn-primary mr-2" href="{{editlink}}">{{#str}}editquiz, quiz{{/str}}</a>
{{/editlink}}
{{#attemptlink}}
<a class="btn btn-primary" href="{{attemptlink}}">{{#str}}attemptquiz, quiz{{/str}}</a>
{{/attemptlink}}
{{#addquestionlink}}
<a class="btn btn-primary" href="{{addquestionlink}}">{{#str}}addquestion, quiz{{/str}}</a>
{{/addquestionlink}}
</div>
</div>

View File

@ -0,0 +1,58 @@
{{!
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/>.
}}
{{!
@template mod_quiz/quiz_results_action
Actions bar at the top of the report page UI.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* see mod/quiz/classes/output/resultsaction.php
Example context (json):
{
"resultaction": {
"id": "url_select_test",
"options": [{
"name": "Grades",
"value": "/mod/quiz/report.php?id=4&mode=overview"
},
{
"name": "Responses",
"value": "/mod/quiz/report.php?id=4&mode=responses"
},
{
"name": "Statistics",
"value": "/mod/quiz/report.php?id=4&mode=statistics"
},
{
"name": "Manual grading",
"value": "/mod/quiz/report.php?id=4&mode=grading"
}
]
}
}
}}
<div class="container-fluid mb-3">
<div class="row">
<div class="float-left">
{{#resultaction}}
{{>core/url_select}}
{{/resultaction}}
</div>
</div>
</div>

View File

@ -8,6 +8,11 @@ This files describes API changes in the quiz code.
- quiz_send_notification_messages() in mod/quiz/locallib.php
* The completionpass criteria has been moved to core as 'completionpassgrade'. Refer to completion/upgrade.txt for
further information.
* New argument quizhasquestions has been added to public methods: view_information, view_page_notenrolled and view_page_guest
in mod/quiz/renderer.php.
* The function no_questions_message() in class mod_quiz_renderer is deprecated. Please use generate_no_questions_message()
in the same class.
=== 3.11 ===

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2021101900;
$plugin->version = 2021101901;
$plugin->requires = 2021052500;
$plugin->component = 'mod_quiz';

View File

@ -250,11 +250,11 @@ echo $OUTPUT->header();
if (isguestuser()) {
// Guests can't do a quiz, so offer them a choice of logging in or going back.
echo $output->view_page_guest($course, $quiz, $cm, $context, $viewobj->infomessages);
echo $output->view_page_guest($course, $quiz, $cm, $context, $viewobj->infomessages, $viewobj->quizhasquestions);
} else if (!isguestuser() && !($canattempt || $canpreview
|| $viewobj->canreviewmine)) {
// If they are not enrolled in this course in a good enough role, tell them to enrol.
echo $output->view_page_notenrolled($course, $quiz, $cm, $context, $viewobj->infomessages);
echo $output->view_page_notenrolled($course, $quiz, $cm, $context, $viewobj->infomessages, $viewobj->quizhasquestions);
} else {
echo $output->view_page($course, $quiz, $cm, $context, $viewobj);
}