This commit is contained in:
Ilya Tregubov
2022-02-24 09:43:59 +02:00
99 changed files with 619 additions and 988 deletions
@@ -43,7 +43,7 @@ Feature: Backup user data
| Feedback for the response 'False'. | So you think it is false |
And I log out
When I am on the "Quiz 1" "quiz activity" page logged in as student1
And I follow "Attempt quiz"
And I press "Attempt quiz"
And I click on "True" "radio" in the "First question" "question"
And I click on "False" "radio" in the "Second question" "question"
And I press "Finish attempt"
+1 -1
View File
@@ -57,7 +57,7 @@ Feature: Award badges based on activity completion
And the "Receive a passing grade" completion condition of "Test quiz name" is displayed as "failed"
And the "Receive a pass grade or complete all available attempts" completion condition of "Test quiz name" is displayed as "todo"
When I am on the "Test quiz name" "quiz activity" page
And I follow "Attempt quiz"
And I press "Re-attempt quiz"
And I set the field "False" to "1"
And I press "Finish attempt ..."
And I press "Submit all and finish"
+2
View File
@@ -281,6 +281,8 @@ $string['published'] = 'shared';
$string['qtypeveryshort'] = 'T';
$string['questionaffected'] = '<a href="{$a->qurl}">Question "{$a->name}" ({$a->qtype})</a> is in this question category but is also being used in <a href="{$a->qurl}">quiz "{$a->quizname}"</a> in another course "{$a->coursename}".';
$string['questionbank'] = 'Question bank';
$string['questionbanknavigation'] = 'Question bank tertiary navigation';
$string['questioncategories'] = 'Question categories';
$string['questioncategory'] = 'Question category';
$string['questioncatsfor'] = 'Question categories for \'{$a}\'';
$string['questiondoesnotexist'] = 'This question does not exist';
+1 -1
View File
@@ -275,7 +275,7 @@ class quiz {
}
/**
* @return bool wether the current user is someone who previews the quiz,
* @return bool whether the current user is someone who previews the quiz,
* rather than attempting it.
*/
public function is_preview_user() {
@@ -0,0 +1,60 @@
<?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\local\views;
use core\navigation\views\secondary as core_secondary;
/**
* Class secondary_navigation_view.
*
* Custom implementation for a plugin.
*
* @package mod_quiz
* @category navigation
* @copyright 2021 Sujith Haridasan <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class secondary extends core_secondary {
/**
* Define a custom secondary nav order/view.
*
* @return array
*/
protected function get_default_module_mapping(): array {
$defaultmaping = parent::get_default_module_mapping();
$defaultmaping[self::TYPE_SETTING] = array_merge($defaultmaping[self::TYPE_SETTING], [
'mod_quiz_edit' => 3,
'quiz_report' => 4,
'mod_quiz_useroverrides' => 6,
'roleassign' => 7,
'filtermanage' => 8,
'roleoverride' => 9,
'rolecheck' => 9.1,
'logreport' => 10,
'backup' => 11,
'restore' => 12,
'competencybreakdown' => 13,
]);
$defaultmaping[self::TYPE_CONTAINER] = [
'questionbank' => 5,
];
return $defaultmaping;
}
}
@@ -57,6 +57,9 @@ class edit_renderer extends \plugin_renderer_base {
\core_question\local\bank\question_edit_contexts $contexts, \moodle_url $pageurl, array $pagevars) {
$output = '';
// Page title.
$output .= $this->heading(get_string('questions', 'quiz'));
// Information at the top.
$output .= $this->quiz_state_warnings($structure);
@@ -0,0 +1,111 @@
<?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 in the quiz secondary navigation
*
* The user/group overrides are now handled in the secondary navigation.
* This class provides the data for the templates to handle the data for
* overrides tab.
*
* @package mod_quiz
* @copyright 2021 Sujith Haridasan <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class overrides_actions implements renderable, templatable {
/** @var int The course module ID. */
private $cmid;
/** @var string The mode passed for the overrides url. */
private $mode;
/** @var bool Check if the user have capabilities to list overrides. */
private $canedit;
/** @var bool Should the add override button be enabled or disabled. */
private $addenabled;
/**
* overrides_action 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 bool $addenabled Whether the add button should be enabled or disabled.
*/
public function __construct(int $cmid, string $mode, bool $canedit, bool $addenabled) {
$this->cmid = $cmid;
$this->mode = $mode;
$this->canedit = $canedit;
$this->addenabled = $addenabled;
}
/**
* Create the add override button.
*
* @param \renderer_base $output an instance of the quiz renderer.
* @return \single_button the button, ready to reander.
*/
public function create_add_button(\renderer_base $output): \single_button {
$addoverrideurl = new moodle_url('/mod/quiz/overrideedit.php',
['cmid' => $this->cmid, 'action' => 'add' . $this->mode]);
if ($this->mode === 'group') {
$label = get_string('addnewgroupoverride', 'quiz');
} else {
$label = get_string('addnewuseroverride', 'quiz');
}
$addoverridebutton = new \single_button($addoverrideurl, $label, 'get', true);
if (!$this->addenabled) {
$addoverridebutton->disabled = true;
}
return $addoverridebutton;
}
public function export_for_template(renderer_base $output): array {
global $PAGE;
$templatecontext = [];
// Build the navigation drop-down.
$useroverridesurl = new moodle_url('/mod/quiz/overrides.php', ['cmid' => $this->cmid, 'mode' => 'user']);
$groupoverridesurl = new moodle_url('/mod/quiz/overrides.php', ['cmid' => $this->cmid, 'mode' => 'group']);
$menu = [
$useroverridesurl->out(false) => get_string('useroverrides', 'quiz'),
$groupoverridesurl->out(false) => get_string('groupoverrides', 'quiz')
];
$overridesnav = new url_select($menu, $PAGE->url->out(false), null, 'quizoverrides');
$templatecontext['overridesnav'] = $overridesnav->export_for_template($output);
// Build the add button - but only if the user can edit.
if ($this->canedit) {
$templatecontext['addoverridebutton'] = $this->create_add_button($output)->export_for_template($output);
}
return $templatecontext;
}
}
@@ -1,98 +0,0 @@
<?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 <[email protected]>
* @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),
];
}
}
-68
View File
@@ -1,68 +0,0 @@
<?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 <[email protected]>
* @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;
}
}
@@ -1,65 +0,0 @@
<?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 <[email protected]>
* @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;
}
}
@@ -1,101 +0,0 @@
<?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 <[email protected]>
* @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 {
if ($this->canedit) {
$data['addquestionlink'] = (new moodle_url('/mod/quiz/edit.php', ['cmid' => $this->cmid]))->out(false);
}
}
return $data;
}
}
+1 -7
View File
@@ -59,7 +59,7 @@ $defaultcategory = $defaultcategoryobj->id . ',' . $defaultcategoryobj->contexti
$quizhasattempts = quiz_has_attempts($quiz->id);
$PAGE->set_url($thispageurl);
$PAGE->set_secondary_active_tab("modulepage");
$PAGE->set_secondary_active_tab("mod_quiz_edit");
// Get the course object and related bits.
$course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST);
@@ -187,14 +187,8 @@ $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'));
+1 -4
View File
@@ -47,10 +47,7 @@ $PAGE->navbar->add($strquizzes);
$PAGE->set_title($strquizzes);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading($strquizzes, 2);
}
echo $OUTPUT->heading($strquizzes, 2);
// Get all the appropriate data.
if (!$quizzes = get_all_instances_in_course("quiz", $course)) {
+2 -1
View File
@@ -686,7 +686,8 @@ $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 quiz';
$string['previewquiz'] = 'Preview {$a}';
$string['previewquizstart'] = '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.';
+5 -6
View File
@@ -570,7 +570,7 @@ function quiz_user_complete($course, $user, $mod, $quiz) {
* @param int $userid the userid.
* @param string $status 'all', 'finished' or 'unfinished' to control
* @param bool $includepreviews
* @return an array of all the user's attempts at this quiz. Returns an empty
* @return array of all the user's attempts at this quiz. Returns an empty
* array if there are none.
*/
function quiz_get_user_attempts($quizids, $userid, $status = 'finished', $includepreviews = false) {
@@ -1727,15 +1727,14 @@ function quiz_extend_settings_navigation(settings_navigation $settings, navigati
$url = new moodle_url('/mod/quiz/overrides.php', ['cmid' => $settings->get_page()->cm->id, 'mode' => 'user']);
$node = navigation_node::create(get_string('overrides', 'quiz'),
$url, navigation_node::TYPE_SETTING, null, 'mod_quiz_useroverrides');
$quiznode->add_node($node, $beforekey);
$settingsoverride = $quiznode->add_node($node, $beforekey);
}
if (has_capability('mod/quiz:manage', $settings->get_page()->cm->context)) {
$node = navigation_node::create(get_string('editquiz', 'quiz'),
$node = navigation_node::create(get_string('questions', 'quiz'),
new moodle_url('/mod/quiz/edit.php', array('cmid' => $settings->get_page()->cm->id)),
navigation_node::TYPE_SETTING, null, 'mod_quiz_edit', new pix_icon('t/edit', ''));
$editquiznode = $quiznode->add_node($node, $beforekey);
$editquiznode->set_show_in_secondary_navigation(false);
$quiznode->add_node($node, $beforekey);
}
if (has_capability('mod/quiz:preview', $settings->get_page()->cm->context)) {
@@ -1758,7 +1757,7 @@ function quiz_extend_settings_navigation(settings_navigation $settings, navigati
array('id' => $settings->get_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', '')));
null, 'quiz_report', new pix_icon('i/report', '')));
foreach ($reportlist as $report) {
$url = new moodle_url('/mod/quiz/report.php', ['id' => $settings->get_page()->cm->id, 'mode' => $report]);
+38 -37
View File
@@ -302,39 +302,17 @@ foreach ($overrides as $override) {
}
}
// Display a list of overrides.
echo $OUTPUT->header();
echo $OUTPUT->heading($title);
// Output the table and button.
$output = '';
$output .= html_writer::start_tag('div', ['id' => 'quizoverrides']);
if (count($table->data)) {
$output .= html_writer::table($table);
} else {
if ($groupmode) {
$output .= $OUTPUT->notification(get_string('overridesnoneforgroups', 'quiz'), 'info', false);
} else {
$output .= $OUTPUT->notification(get_string('overridesnoneforusers', 'quiz'), 'info', false);
}
}
if ($hasinactive) {
$output .= $OUTPUT->notification(get_string('inactiveoverridehelp', 'quiz'), 'info', false);
}
$addbutton = '';
$options = [];
// Work out what else needs to be displayed.
$addenabled = true;
$warningmessage = '';
if ($canedit) {
$output .= html_writer::start_tag('div', ['class' => 'buttons']);
if ($groupmode) {
if (empty($groups)) {
// There are no groups.
$output .= $OUTPUT->notification(get_string('groupsnone', 'quiz'), 'error');
$options['disabled'] = true;
$warningmessage = get_string('groupsnone', 'quiz');
$addenabled = false;
}
} else {
$users = [];
// See if there are any students in the quiz.
if ($showallgroups) {
$users = get_users_by_capability($context, 'mod/quiz:attempt', 'u.id');
@@ -343,6 +321,7 @@ if ($canedit) {
$users = get_users_by_capability($context, 'mod/quiz:attempt', 'u.id', '', '', '', array_keys($groups));
$nousermessage = get_string('usersnone', 'quiz');
} else {
$users = [];
$nousermessage = get_string('groupsnone', 'quiz');
}
$info = new \core_availability\info_module($cm);
@@ -350,22 +329,44 @@ if ($canedit) {
if (empty($users)) {
// There are no students.
$output .= $OUTPUT->notification($nousermessage, 'error');
$options['disabled'] = true;
$warningmessage = $nousermessage;
$addenabled = false;
}
}
$output .= html_writer::end_tag('div');
}
$output .= html_writer::end_tag('div');
// Outputs overrides action.
$overridesaction = new \mod_quiz\output\overridesaction($cmid, $mode, $canedit, $options);
// Tertiary navigation.
echo $OUTPUT->header();
$renderer = $PAGE->get_renderer('mod_quiz');
echo $renderer->overrides_action($overridesaction);
$tertiarynav = new \mod_quiz\output\overrides_actions($cmid, $mode, $canedit, $addenabled);
echo $renderer->render($tertiarynav);
// Now output what we captured after the overrides action.
echo $output;
if ($mode === 'user') {
echo $OUTPUT->heading(get_string('useroverrides', 'quiz'));
} else {
echo $OUTPUT->heading(get_string('groupoverrides', 'quiz'));
}
// Output the table and button.
echo html_writer::start_tag('div', ['id' => 'quizoverrides']);
if (count($table->data)) {
echo html_writer::table($table);
} else {
if ($groupmode) {
echo $OUTPUT->notification(get_string('overridesnoneforgroups', 'quiz'), 'info', false);
} else {
echo $OUTPUT->notification(get_string('overridesnoneforusers', 'quiz'), 'info', false);
}
}
if ($hasinactive) {
echo $OUTPUT->notification(get_string('inactiveoverridehelp', 'quiz'), 'info', false);
}
if ($warningmessage) {
echo $OUTPUT->notification($warningmessage, 'error');
}
echo html_writer::end_tag('div');
// Finish the page.
echo $OUTPUT->footer();
+112 -119
View File
@@ -428,6 +428,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
public function start_attempt_page(quiz $quizobj, mod_quiz_preflight_check_form $mform) {
$output = '';
$output .= $this->header();
$output .= $this->during_attempt_tertiary_nav($quizobj->view_url());
$output .= $this->heading(format_string($quizobj->get_quiz_name(), true,
array("context" => $quizobj->get_context())));
$output .= $this->quiz_intro($quizobj->get_quiz(), $quizobj->get_cm());
@@ -446,20 +447,13 @@ class mod_quiz_renderer extends plugin_renderer_base {
* @param array $slots Contains an array of integers that relate to questions
* @param int $id The ID of an attempt
* @param int $nextpage The number of the next page
* @return string HTML to output.
*/
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->during_attempt_tertiary_nav($attemptobj->view_url());
$output .= $this->quiz_notices($messages);
$output .= $this->countdown_timer($attemptobj, time());
$output .= $this->attempt_form($attemptobj, $page, $slots, $id, $nextpage);
@@ -467,6 +461,25 @@ class mod_quiz_renderer extends plugin_renderer_base {
return $output;
}
/**
* Render the tertiary navigation for pages during the attempt.
*
* @param string|moodle_url $quizviewurl url of the view.php page for this quiz.
* @return string HTML to output.
*/
public function during_attempt_tertiary_nav($quizviewurl): string {
$output = '';
$output .= html_writer::start_div('container-fluid mb-3');
$output .= html_writer::start_div('row');
$output .= html_writer::link($quizviewurl, get_string('back'),
['class' => 'btn btn-secondary']);
$output .= html_writer::end_div();
$output .= html_writer::end_div();
return $output;
}
/**
* Returns any notices.
*
@@ -549,7 +562,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 mb-4'));
$output .= html_writer::start_tag('div', array('class' => 'submitbtns'));
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',
@@ -634,7 +647,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, ['class' => 'float-left']) . "\n";
$output .= html_writer::tag('p', $message, ['class' => 'text-left']);
}
return $output;
}
@@ -651,6 +664,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
public function summary_page($attemptobj, $displayoptions) {
$output = '';
$output .= $this->header();
$output .= $this->during_attempt_tertiary_nav($attemptobj->view_url());
$output .= $this->heading(format_string($attemptobj->get_quiz_name()));
$output .= $this->heading(get_string('summaryofattempt', 'quiz'), 3);
$output .= $this->summary_table($attemptobj, $displayoptions);
@@ -686,19 +700,22 @@ 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 (!is_null($heading) && empty($heading)) {
$heading = get_string('sectionnoname', 'quiz');
}
if ($heading) {
if ($heading !== null) {
// There is a heading here.
$rowclasses = 'quizsummaryheading';
if ($heading) {
$heading = format_string($heading);
} else if (count($attemptobj->get_quizobj()->get_sections()) > 1) {
// If this is the start of an unnamed section, and the quiz has more
// than one section, then add a default heading.
$heading = get_string('sectionnoname', 'quiz');
$rowclasses .= ' dimmed_text';
}
$cell = new html_table_cell(format_string($heading));
$cell->header = true;
$cell->colspan = $tablewidth;
$table->data[] = array($cell);
$classes = 'quizsummaryheading';
if ($heading === get_string('sectionnoname', 'quiz')) {
$classes .= ' dimmed_text';
}
$table->rowclasses[] = $classes;
$table->rowclasses[] = $rowclasses;
}
// Don't display information items.
@@ -770,6 +787,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
$button->add_action(new confirm_action(get_string('confirmclose', 'quiz'), null,
get_string('submitallandfinish', 'quiz')));
}
$button->primary = true;
$duedate = $attemptobj->get_due_date();
$message = '';
@@ -793,43 +811,75 @@ class mod_quiz_renderer extends plugin_renderer_base {
/**
* Generates the view page
*
* @param int $course The id of the course
* @param array $quiz Array conting quiz data
* @param int $cm Course Module ID
* @param int $context The page context ID
* @param array $infomessages information about this quiz
* @param stdClass $course the course settings row from the database.
* @param stdClass $quiz the quiz settings row from the database.
* @param stdClass $cm the course_module settings row from the database.
* @param context_module $context the quiz context.
* @param mod_quiz_view_object $viewobj
* @param string $buttontext text for the start/continue attempt button, if
* it should be shown.
* @param array $infomessages further information about why the student cannot
* attempt this quiz now, if appicable this quiz
* @return string HTML to display
*/
public function view_page($course, $quiz, $cm, $context, $viewobj) {
$output = '';
$output .= $this->view_information($quiz, $cm, $context, $viewobj->infomessages, $viewobj->quizhasquestions);
$output .= $this->view_page_tertiary_nav($viewobj);
$output .= $this->view_information($quiz, $cm, $context, $viewobj->infomessages);
$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;
}
/**
* Render the tertiary navigation for the view page.
*
* @param mod_quiz_view_object $viewobj the information required to display the view page.
* @return string HTML to output.
*/
public function view_page_tertiary_nav(mod_quiz_view_object $viewobj): string {
$content = '';
if ($viewobj->buttontext) {
$attemptbtn = $this->start_attempt_button($viewobj->buttontext,
$viewobj->startattempturl, $viewobj->preflightcheckform,
$viewobj->popuprequired, $viewobj->popupoptions);
$content .= $attemptbtn;
}
if ($viewobj->canedit && !$viewobj->quizhasquestions) {
$content .= html_writer::link($viewobj->editurl, get_string('addquestion', 'quiz'),
['class' => 'btn btn-secondary']);
}
if ($content) {
return html_writer::div(html_writer::div($content, 'row'), 'container-fluid mb-3');
} else {
return '';
}
}
/**
* Work out, and render, whatever buttons, and surrounding info, should appear
* at the end of the review page.
* @param mod_quiz_view_object $viewobj the information required to display
* the view page.
*
* @param mod_quiz_view_object $viewobj the information required to display the view page.
* @return string HTML to output.
*/
public function view_page_buttons(mod_quiz_view_object $viewobj) {
$output = '';
if (!$viewobj->quizhasquestions) {
$output .= $this->generate_no_questions_message();
$output .= html_writer::div(
$this->notification(get_string('noquestions', 'quiz'), 'warning', false),
'text-left mb-3');
}
$output .= $this->access_messages($viewobj->preventmessages);
if ($viewobj->showbacktocourse) {
$output .= $this->single_button($viewobj->backtocourseurl,
get_string('backtocourse', 'quiz'), 'get',
array('class' => 'continuebutton'));
}
return $output;
}
@@ -882,12 +932,12 @@ class mod_quiz_renderer extends plugin_renderer_base {
/**
* Generate a message saying that this quiz has no questions, with a button to
* go to the edit page, if the user has the right capability.
* @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.
*
* @param bool $canedit can the current user edit the quiz?
* @param moodle_url $editurl URL of the edit quiz page.
* @return string HTML to output.
*
* @deprecated since Moodle 4.0 MDL-71915 - please do not use this function any more.
*/
public function no_questions_message($canedit, $editurl) {
debugging('no_questions_message() is deprecated, please use generate_no_questions_message() instead.', DEBUG_DEVELOPER);
@@ -905,34 +955,20 @@ 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
*
* @param int $course The course ID
* @param array $quiz Array contingin quiz data
* @param int $cm Course Module ID
* @param int $context The page contect ID
* @param stdClass $course the course settings row from the database.
* @param stdClass $quiz the quiz settings row from the database.
* @param stdClass $cm the course_module settings row from the database.
* @param context_module $context the quiz context.
* @param array $messages Array containing any messages
* @param bool $quizhasquestions If quiz has questions
* @param mod_quiz_view_object $viewobj
*/
public function view_page_guest($course, $quiz, $cm, $context, $messages, $quizhasquestions = false) {
public function view_page_guest($course, $quiz, $cm, $context, $messages, $viewobj) {
$output = '';
$output .= $this->view_information($quiz, $cm, $context, $messages, $quizhasquestions);
$output .= $this->view_page_tertiary_nav($viewobj);
$output .= $this->view_information($quiz, $cm, $context, $messages);
$guestno = html_writer::tag('p', get_string('guestsno', 'quiz'));
$liketologin = html_writer::tag('p', get_string('liketologin'));
$referer = get_local_referer(false);
@@ -943,17 +979,18 @@ class mod_quiz_renderer extends plugin_renderer_base {
/**
* Outputs and error message for anyone who is not enrolle don the course
*
* @param int $course The course ID
* @param array $quiz Array contingin quiz data
* @param int $cm Course Module ID
* @param int $context The page contect ID
* @param stdClass $course the course settings row from the database.
* @param stdClass $quiz the quiz settings row from the database.
* @param stdClass $cm the course_module settings row from the database.
* @param context_module $context the quiz context.
* @param array $messages Array containing any messages
* @param bool $quizhasquestions If quiz has questions
* @param mod_quiz_view_object $viewobj
*/
public function view_page_notenrolled($course, $quiz, $cm, $context, $messages, $quizhasquestions = false) {
public function view_page_notenrolled($course, $quiz, $cm, $context, $messages, $viewobj) {
global $CFG;
$output = '';
$output .= $this->view_information($quiz, $cm, $context, $messages, $quizhasquestions);
$output .= $this->view_page_tertiary_nav($viewobj);
$output .= $this->view_information($quiz, $cm, $context, $messages);
$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));
@@ -974,14 +1011,10 @@ class mod_quiz_renderer extends plugin_renderer_base {
public function view_information($quiz, $cm, $context, $messages, bool $quizhasquestions = false) {
$output = '';
// 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);
// Output any access messages.
if ($messages) {
$output .= $this->box($this->access_messages($messages), 'quizinfo');
}
// Show number of attempts summary to those who can view reports.
if (has_capability('mod/quiz:viewreports', $context)) {
@@ -1367,46 +1400,6 @@ 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 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));
}
}
@@ -1469,7 +1462,7 @@ class mod_quiz_view_object {
public $buttontext;
/** @var moodle_url $startattempturl URL to start an attempt. */
public $startattempturl;
/** @var moodleform|null $preflightcheckform confirmation form that must be
/** @var mod_quiz_preflight_check_form|null $preflightcheckform confirmation form that must be
* submitted before an attempt is started, if required. */
public $preflightcheckform;
/** @var moodle_url $startattempturl URL for any Back to the course button. */
@@ -41,8 +41,7 @@ Feature: Basic use of the Manual grading report
Scenario: Use the Manual grading report
# Check report shows nothing when there are no attempts.
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "teacher1"
And I navigate to "Results > Manual grading" in current page administration
When I am on the "Quiz 1" "mod_quiz > Manual grading report" page logged in as "teacher1"
Then I should see "Quiz 1" in the "//nav[contains(concat(' ', normalize-space(@aria-label), ' '), ' Navigation bar ')]" "xpath_element"
And I should see "Quiz 1"
And I should see "Nothing to display"
@@ -125,8 +124,7 @@ Feature: Basic use of the Manual grading report
Given user "student1" has attempted "Quiz 1" with responses:
| slot | response |
| 1 | Paris |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "teacher1"
And I navigate to "Results > Manual grading" in current page administration
When I am on the "Quiz 1" "mod_quiz > Manual grading report" page logged in as "teacher1"
And I follow "Also show questions that have been graded automatically"
And I click on "update grades" "link" in the "Short answer 001" "table_row"
Then I should see "Attempt number 1 for S1 Student1 (student1, S1000, student1@example.com, little yellow frog)"
@@ -33,8 +33,7 @@ Feature: Basic use of the Responses report
@javascript
Scenario: Report works when there are no attempts
Given I am on the "Quiz 1" "quiz activity" page logged in as teacher
When I navigate to "Results > Responses" in current page administration
When I am on the "Quiz 1" "mod_quiz > Responses report" page logged in as teacher
Then I should see "Attempts: 0"
And I should see "Nothing to display"
And I set the field "Attempts from" to "enrolled users who have not attempted the quiz"
@@ -53,8 +52,7 @@ Feature: Basic use of the Responses report
| 1 | 3.14 |
And user "student1" has finished an attempt at quiz "Quiz 1"
And I am on the "Quiz 1" "quiz activity" page logged in as teacher
And I navigate to "Results > Responses" in current page administration
When I am on the "Quiz 1" "mod_quiz > Responses report" page logged in as teacher
Then I should see "Attempts: 1"
And I should see "Student One"
And I should not see "Student Two"
@@ -70,8 +68,7 @@ Feature: Basic use of the Responses report
@javascript
Scenario: Report does not allow strange combinations of options
Given I am on the "Quiz 1" "quiz activity" page logged in as teacher
And I navigate to "Results > Responses" in current page administration
Given I am on the "Quiz 1" "mod_quiz > Responses report" page logged in as teacher
And the "Which tries" "select" should be enabled
When I set the field "Attempts from" to "enrolled users who have not attempted the quiz"
Then the "Which tries" "select" should be disabled
@@ -39,12 +39,11 @@ Feature: Basic use of the Statistics report
@javascript
Scenario: Report works when there are no attempts
Given I am on the "Quiz 1" "quiz activity" page logged in as teacher1
And I navigate to "Results > Statistics" in current page administration
When I am on the "Quiz 1" "mod_quiz > Statistics report" page logged in as teacher1
Then I should see "No attempts have been made at this quiz, or all attempts have questions that need manual grading."
And I should not see "Statistics for question positions"
And "Show chart data" "link" should not exist
When user "student1" has attempted "Quiz 1" with responses:
And user "student1" has attempted "Quiz 1" with responses:
| slot | response |
| 1 | True |
| 2 | False |
@@ -59,10 +58,9 @@ Feature: Basic use of the Statistics report
| 1 | False |
| 2 | False |
| 3 | False |
And I am on the "Quiz 1" "quiz activity" page logged in as teacher1
And I navigate to "Results > Statistics" in current page administration
And I am on the "Quiz 1" "mod_quiz > Statistics report" page logged in as teacher1
And I press "Show report"
Then I should not see "No questions have been attempted yet"
And I should not see "No questions have been attempted yet"
And "Show chart data" "link" should exist
# Question A statistics breakdown.
+1 -2
View File
@@ -243,8 +243,7 @@
/** Mod quiz view **/
#page-mod-quiz-view .quizinfo,
#page-mod-quiz-view #page .quizgradefeedback,
#page-mod-quiz-view #page .quizattempt {
#page-mod-quiz-view #page .quizgradefeedback {
text-align: center;
}
@@ -15,29 +15,33 @@
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template mod_quiz/quiz_overrides
@template mod_quiz/overrides_actions
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
* overridesnav - must alwasy be present.
* addoverridebutton - should only be present if the user has permission to add a new override.
Example context (json):
{
"overrides": {
"overridesnav": {
"options": [{
"name": "User overrides",
"value": "/mod/quiz/overrides.php?cmid=71&mode=user"
},
{
"name": "Group overrrides",
"name": "Group overrides",
"value": "/mod/quiz/overrides.php?cmid=71&mode=group"
}
]
},
"canedit": true,
"overridesbtn": {
"addoverridebutton": {
"id": "single_button1234",
"method": "get",
"url": "http://localhost/moodle/mod/quiz/overrideedit.php",
@@ -59,17 +63,15 @@
}}
<div class="container-fluid mb-3">
<div class="row">
{{#overrides}}
{{#overridesnav}}
<div class="col-xs-6">
{{>core/url_select}}
</div>
{{/overrides}}
{{#canedit}}
{{#overridesbtn}}
<div class="ml-2">
{{>core/single_button}}
</div>
{{/overridesbtn}}
{{/canedit}}
{{/overridesnav}}
{{#addoverridebutton}}
<div class="ml-3">
{{>core/single_button}}
</div>
{{/addoverridebutton}}
</div>
</div>
@@ -1,39 +0,0 @@
{{!
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>
@@ -1,39 +0,0 @@
{{!
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>
@@ -1,49 +0,0 @@
{{!
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>
+1 -1
View File
@@ -36,7 +36,7 @@ Feature: Add a quiz
And I log out
And I am on the "Test quiz name" "quiz activity" page logged in as student1
And I follow "Attempt quiz"
And I press "Attempt quiz"
Then I should see "Question 1"
And I should see "Answer the first question"
And I set the field "True" to "1"
+3 -3
View File
@@ -45,7 +45,7 @@ Feature: Attempt a quiz
And I should see "Grade"
And I should see "25.00 out of 100.00"
And I follow "Finish review"
And I follow "Attempt quiz"
And I press "Re-attempt quiz"
@javascript
Scenario: Attempt a quiz with mulitple sections
@@ -73,7 +73,7 @@ Feature: Attempt a quiz
| Section 3 | 5 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
Then I should see "Section 1" in the "Quiz navigation" "block"
And I should see question "1" in section "Section 1" in the quiz navigation
@@ -125,7 +125,7 @@ Feature: Attempt a quiz
| TF1 | 1 |
| TF2 | 2 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
Then I should see "Text of the first question"
And I should not see "Text of the second question"
And I press "Next page"
+13 -13
View File
@@ -30,7 +30,7 @@ Feature: The various checks that may happen when an attept is started
| question | page |
| TF1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
Then I should see "Text of the first question"
@javascript
@@ -42,11 +42,11 @@ Feature: The various checks that may happen when an attept is started
| question | page |
| TF1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
Then I should see "To attempt this quiz you need to know the quiz password" in the "region-main" "region"
And I should see "Your attempt will have a time limit of 1 hour. When you " in the "region-main" "region"
And I press "Attempt quiz"
Then I should see "To attempt this quiz you need to know the quiz password" in the "Start attempt" "dialogue"
And I should see "Your attempt will have a time limit of 1 hour. When you " in the "Start attempt" "dialogue"
And I set the field "Quiz password" to "Frog"
And I click on "Start attempt" "button" in the "region-main" "region"
And I click on "Start attempt" "button" in the "Start attempt" "dialogue"
And I should see "Text of the first question"
@javascript
@@ -58,10 +58,10 @@ Feature: The various checks that may happen when an attept is started
| question | page |
| TF1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I click on "Cancel" "button" in the "region-main" "region"
And I press "Attempt quiz"
And I click on "Cancel" "button" in the "Start attempt" "dialogue"
Then I should see "Quiz 1 description"
And "Attempt quiz" "link" should be visible
And "Attempt quiz" "button" should be visible
@javascript
Scenario: Start a quiz with time limit and password, get the password wrong first time
@@ -72,9 +72,9 @@ Feature: The various checks that may happen when an attept is started
| question | page |
| TF1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
And I set the field "Quiz password" to "Toad"
And I click on "Start attempt" "button" in the "region-main" "region"
And I click on "Start attempt" "button" in the "Start attempt" "dialogue"
Then I should see "Quiz 1 description"
And I should see "To attempt this quiz you need to know the quiz password"
And I should see "Your attempt will have a time limit of 1 hour. When you "
@@ -94,9 +94,9 @@ Feature: The various checks that may happen when an attept is started
| question | page |
| TF1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
And I set the field "Quiz password" to "Toad"
And I click on "Start attempt" "button" in the "region-main" "region"
And I click on "Start attempt" "button" in the "Start attempt" "dialogue"
And I should see "Quiz 1 description"
And I should see "To attempt this quiz you need to know the quiz password"
And I should see "Your attempt will have a time limit of 1 hour. When you "
@@ -106,4 +106,4 @@ Feature: The various checks that may happen when an attept is started
And I press tab key in "Quiz password" "field"
And I press "Cancel"
Then I should see "Quiz 1 description"
And "Attempt quiz" "link" should be visible
And "Attempt quiz" "button" should be visible
@@ -34,7 +34,7 @@ Feature: Allow students to redo questions in a practice quiz, without starting a
@javascript
Scenario: After completing a question, there is a redo question button that restarts the question
Given I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
When I follow "Attempt quiz"
When I press "Attempt quiz"
And I click on "False" "radio" in the "First question" "question"
And I click on "Check" "button" in the "First question" "question"
And I press "Try another question like this one"
@@ -44,7 +44,7 @@ Feature: Allow students to redo questions in a practice quiz, without starting a
@javascript
Scenario: The redo question button is visible but disabled for teachers
Given I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
When I follow "Attempt quiz"
When I press "Attempt quiz"
And I click on "False" "radio" in the "First question" "question"
And I click on "Check" "button" in the "First question" "question"
And I log out
@@ -56,7 +56,7 @@ Feature: Allow students to redo questions in a practice quiz, without starting a
@javascript
Scenario: The redo question buttons are no longer visible after the attempt is submitted.
Given I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
When I follow "Attempt quiz"
When I press "Attempt quiz"
And I click on "False" "radio" in the "First question" "question"
And I click on "Check" "button" in the "First question" "question"
And I press "Finish attempt ..."
@@ -67,7 +67,7 @@ Feature: Allow students to redo questions in a practice quiz, without starting a
@javascript @_switch_window
Scenario: Teachers reviewing can see all the questions attempted in a slot
Given I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
When I follow "Attempt quiz"
When I press "Attempt quiz"
And I click on "False" "radio" in the "First question" "question"
And I click on "Check" "button" in the "First question" "question"
And I press "Try another question like this one"
@@ -86,8 +86,7 @@ Feature: Allow students to redo questions in a practice quiz, without starting a
And I switch to the main window
And the state of "First question" question is shown as "Not answered"
And I should not see "Submit" in the ".history" "css_element"
And I am on the "Quiz 1" "mod_quiz > View" page
And I navigate to "Results > Statistics" in current page administration
And I am on the "Quiz 1" "mod_quiz > Statistics report" page logged in as teacher
And I follow "TF1"
And "False" row "Frequency" column of "quizresponseanalysis" table should contain "100.00%"
And "True" row "Frequency" column of "quizresponseanalysis" table should contain "0.00%"
@@ -96,7 +95,7 @@ Feature: Allow students to redo questions in a practice quiz, without starting a
@javascript
Scenario: Redoing question 1 should save any changes to question 2 on the same page
Given I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
When I follow "Attempt quiz"
When I press "Attempt quiz"
And I click on "False" "radio" in the "First question" "question"
And I click on "Check" "button" in the "First question" "question"
And I click on "True" "radio" in the "Second question" "question"
@@ -117,7 +116,7 @@ Feature: Allow students to redo questions in a practice quiz, without starting a
| slot | actualquestion |
| 1 | TF1 |
And I am on the "Quiz 2" "mod_quiz > View" page logged in as "student"
When I follow "Attempt quiz"
When I press "Continue your attempt"
And I should see "First question"
And I click on "False" "radio"
And I click on "Check" "button"
@@ -139,7 +138,8 @@ Feature: Allow students to redo questions in a practice quiz, without starting a
| slot | response |
| 1 | J.K.Rowling |
And I am on the "Quiz 2" "mod_quiz > View" page logged in as "teacher"
And I navigate to "Results > Manual grading" in current page administration
And I navigate to "Results" in current page administration
And I select "Manual grading" from the "jump" singleselect
And I follow "Also show questions that have been graded automatically"
When I click on "update grades" "link" in the "SA1" "table_row"
Then I set the field "Comment" to "I have adjusted your mark to 1.0"
@@ -35,7 +35,7 @@ Feature: Attempt a quiz where some questions require that the previous question
| TF2 | 1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
Then I should see "First question"
And I should see "This question cannot be attempted until the previous question has been completed."
@@ -63,7 +63,7 @@ Feature: Attempt a quiz where some questions require that the previous question
| TF2 | 1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
And I click on "True" "radio" in the "First question" "question"
And I press "Check"
@@ -88,7 +88,7 @@ Feature: Attempt a quiz where some questions require that the previous question
| TF2 | 1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
And I press "Finish attempt ..."
And I press "Submit all and finish"
And I click on "Submit all and finish" "button" in the "Confirmation" "dialogue"
@@ -111,7 +111,7 @@ Feature: Attempt a quiz where some questions require that the previous question
| TF2 | 1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
Then I should see "First question"
And I should see "Second question"
@@ -135,7 +135,7 @@ Feature: Attempt a quiz where some questions require that the previous question
| Section 1 | 1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
Then I should see "First question"
And I should see "Second question"
@@ -160,7 +160,7 @@ Feature: Attempt a quiz where some questions require that the previous question
| Section 2 | 2 | 0 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
And I press "Next page"
Then I should see "Second question"
@@ -181,7 +181,7 @@ Feature: Attempt a quiz where some questions require that the previous question
| TF2 | 1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
Then I should see "First question"
And I should see "Second question"
@@ -202,7 +202,7 @@ Feature: Attempt a quiz where some questions require that the previous question
| TF2 | 1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
Then I should see "First question"
And I should see "Second question"
@@ -223,7 +223,7 @@ Feature: Attempt a quiz where some questions require that the previous question
| TF1 | 1 | 1 |
When I am on the "Quiz 1" "mod_quiz > View" page logged in as "student"
And I follow "Attempt quiz"
And I press "Attempt quiz"
Then I should see "Read me"
And I should see "First question"
+1
View File
@@ -68,6 +68,7 @@ class behat_mod_quiz extends behat_question_base {
* | User overrides | Quiz name | The manage user overrides page |
* | Grades report | Quiz name | The overview report for a quiz |
* | Responses report | Quiz name | The responses report for a quiz |
* | Manual grading report | Quiz name | The manual grading report for a quiz |
* | Statistics report | Quiz name | The statistics report for a quiz |
* | Attempt review | Quiz name > username > [Attempt] attempt no | Review page for a given attempt (review.php) |
*
@@ -41,7 +41,7 @@ Feature: Set a quiz to be marked complete when the student uses all attempts all
And the "Receive a passing grade" completion condition of "Test quiz name" is displayed as "failed"
And the "Receive a pass grade or complete all available attempts" completion condition of "Test quiz name" is displayed as "todo"
And I follow "Test quiz name"
And I follow "Attempt quiz"
And I press "Re-attempt quiz"
And I set the field "<answer>" to "1"
And I press "Finish attempt ..."
And I press "Submit all and finish"
@@ -43,7 +43,7 @@ Feature: Set a quiz to be marked complete when the student completes a minimum a
And I am on "Course 1" course homepage
And the "Make attempts: 2" completion condition of "Test quiz name" is displayed as "todo"
And I follow "Test quiz name"
And I follow "Attempt quiz"
And I press "Re-attempt quiz"
And I set the field "False" to "1"
And I press "Finish attempt ..."
And I press "Submit all and finish"
+4 -2
View File
@@ -101,21 +101,23 @@ Feature: Edit quiz page - adding things
# Create a couple of sub categories.
When I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
And I select "Categories" from the "questionbankactionselect" singleselect
And I select "Categories" from the "Question bank tertiary navigation" singleselect
Then I should see "Add category"
And I follow "Add category"
Then I set the field "Parent category" to "Default for C1"
And I set the field "Name" to "Subcat 1"
And I set the field "Category info" to "This is sub category 1"
And I press "id_submitbutton"
And I should see "Subcat 1"
And I follow "Add category"
Then I set the field "Parent category" to "Default for C1"
And I set the field "Name" to "Subcat 2"
And I set the field "Category info" to "This is sub category 2"
And I press "id_submitbutton"
And I should see "Subcat 2"
And I select "Questions" from the "questionbankactionselect" singleselect
And I select "Questions" from the "Question bank tertiary navigation" singleselect
And I should see "Question bank"
And I should see "Select a category"
@@ -20,7 +20,6 @@ Feature: Edit quiz marks with attempts
| activity | name | course | idnumber | grade | decimalpoints | questiondecimalpoints |
| quiz | Quiz 1 | C1 | quiz1 | 20 | 2 | -1 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I add a "True/False" question to the "Quiz 1" quiz with:
| Question name | First question |
| Question text | Answer me |
@@ -31,7 +30,7 @@ Feature: Edit quiz marks with attempts
| Default mark | 3.0 |
And I log out
And I am on the "Quiz 1" "mod_quiz > View" page logged in as "student1"
And I follow "Attempt quiz"
And I press "Attempt quiz"
And I log out
And I log in as "teacher1"
And I am on the "Quiz 1" "mod_quiz > Edit" page
@@ -29,7 +29,7 @@ Feature: Teachers can override the grade for any question
| question | page |
| TF1 | 1 |
And I am on the "Quiz 1" "mod_quiz > View" page logged in as "student1"
And I follow "Attempt quiz"
And I press "Attempt quiz"
And I follow "Finish attempt ..."
And I press "Submit all and finish"
And I click on "Submit all and finish" "button" in the "Confirmation" "dialogue"
+1 -1
View File
@@ -44,6 +44,6 @@ Feature: Preview a quiz as a teacher
@javascript
Scenario: Preview the quiz
Given I am on the "Quiz 1" "mod_quiz > View" page logged in as "teacher"
When I follow "Preview quiz"
When I press "Preview quiz"
Then I should see "Question 1"
And "Start a new preview" "button" should exist
@@ -62,7 +62,7 @@ Feature: View activity completion in the quiz activity
And the "Receive a grade" completion condition of "Test quiz name" is displayed as "done"
And the "Receive a passing grade" completion condition of "Test quiz name" is displayed as "failed"
And the "Receive a pass grade or complete all available attempts" completion condition of "Test quiz name" is displayed as "todo"
And I follow "Attempt quiz"
And I press "Re-attempt quiz"
And I set the field "<answer>" to "1"
And I press "Finish attempt ..."
And I press "Submit all and finish"
@@ -56,7 +56,7 @@ Feature: Quiz group override
Then the "Override group" select box should contain "Group 1"
And the "Override group" select box should not contain "Group 2"
Scenario: Override Group 1 as teacher in no group
Scenario: Add button disabled if there are no groups
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/site:accessallgroups | Prevent | editingteacher | Course | C1 |
@@ -186,3 +186,13 @@ Feature: Quiz user override
And I click on "Delete" "link" in the "Student One" "table_row"
And I should see "Student One (student1@example.com, yellow frog)"
Scenario: Add button disabled if no users
Given the following "courses" exist:
| fullname | shortname | category |
| Course 2 | C2 | 0 |
And the following "activities" exist:
| activity | name | course | idnumber |
| quiz | Other quiz | C2 | quiz2 |
When I am on the "Other quiz" "mod_quiz > User overrides" page logged in as "admin"
Then the "Add user override" "button" should be disabled
+2 -4
View File
@@ -8,10 +8,8 @@ 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.
* New argument quizhasquestions has been added to public methods: view_information in mod/quiz/renderer.php.
* The function no_questions_message() in class mod_quiz_renderer is deprecated. There is no replacement.
* quiz_slots has been updated as a part of https://docs.moodle.org/dev/Question_bank_improvements_for_Moodle_4.0
The fields removed will be now manage by a new table in core_question:
- question_set_reference -> Records where a specific question is used.
+1 -1
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2022020300;
$plugin->version = 2022020301;
$plugin->requires = 2021052500;
$plugin->component = 'mod_quiz';
+5 -9
View File
@@ -147,12 +147,8 @@ if (html_is_blank($quiz->intro)) {
$PAGE->activityheader->set_description('');
}
$PAGE->add_body_class('limitedwidth');
/** @var mod_quiz_renderer $output */
$output = $PAGE->get_renderer('mod_quiz');
// MDL-71915 Will remove this place holder.
if (defined('BEHAT_SITE_RUNNING')) {
$PAGE->has_secondary_navigation_setter(false);
}
$PAGE->add_header_action($OUTPUT->region_main_settings_menu());
// Print table with existing attempts.
if ($attempts) {
@@ -225,13 +221,13 @@ if (!$viewobj->quizhasquestions) {
if ($viewobj->preventmessages) {
$viewobj->buttontext = '';
} else if ($viewobj->numattempts == 0) {
$viewobj->buttontext = get_string('attemptquiznow', 'quiz');
$viewobj->buttontext = get_string('attemptquiz', 'quiz');
} else {
$viewobj->buttontext = get_string('reattemptquiz', 'quiz');
}
} else if ($canpreview) {
$viewobj->buttontext = get_string('previewquiznow', 'quiz');
$viewobj->buttontext = get_string('previewquizstart', 'quiz');
}
}
@@ -254,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, $viewobj->quizhasquestions);
echo $output->view_page_guest($course, $quiz, $cm, $context, $viewobj->infomessages, $viewobj);
} 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, $viewobj->quizhasquestions);
echo $output->view_page_notenrolled($course, $quiz, $cm, $context, $viewobj->infomessages, $viewobj);
} else {
echo $output->view_page($course, $quiz, $cm, $context, $viewobj);
}
+2
View File
@@ -60,6 +60,8 @@ $PAGE->set_url($url);
$streditingquestions = get_string('movequestions', 'qbank_bulkmove');
$PAGE->set_title($streditingquestions);
$PAGE->set_heading($COURSE->fullname);
$PAGE->activityheader->disable();
$PAGE->set_secondary_active_tab("questionbank");
if ($category) {
list($tocategoryid, $contextid) = explode(',', $category);
@@ -23,14 +23,14 @@ Feature: Use the qbank plugin manager page for bulkmove
And I should see "Bulk move questions"
And I click on "Disable" "link" in the "Bulk move questions" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I click on "First question" "checkbox"
And I click on "With selected" "button"
Then I should not see question bulk action "move"
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "Bulk move questions" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I click on "First question" "checkbox"
And I click on "With selected" "button"
And I should see question bulk action "move"
@@ -120,7 +120,7 @@ Feature: A Teacher can comment in a question
Scenario: Comments added from the quiz page are visible
Given I log in as "teacher1"
And I am on the "Test quiz" "quiz activity" page
When I navigate to "Edit quiz" in current page administration
When I navigate to "Questions" in current page administration
And I press "Add"
And I follow "from question bank"
And I click on "Select" "checkbox" in the "First question" "table_row"
@@ -133,7 +133,7 @@ Feature: A Teacher can comment in a question
And I should see "Some new comment"
And I switch to the main window
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I choose "Preview" action for "First question" in the question bank
And I click on "Comments" "link"
And I should see "Some new comment"
@@ -141,7 +141,7 @@ Feature: A Teacher can comment in a question
And I delete "Some new comment" comment from question preview
And I should not see "Some new comment"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Edit quiz" in current page administration
And I navigate to "Questions" in current page administration
And I click on "Preview question" "link"
And I switch to "questionpreview" window
And I press "Comments"
@@ -38,7 +38,7 @@ Feature: A teacher can edit question with custom fields
| Feedback for the response 'True'. | So you think it is true |
| Feedback for the response 'False'. | So you think it is false |
And I am on the "Test quiz name" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
Scenario: Edit a previously created question and see the custom field in the overview table and in the question preview.
When I choose "Edit question" action for "First question" in the question bank
@@ -38,7 +38,7 @@ Feature: The visibility of question custom fields control where they are display
| Feedback for the response 'True'. | So you think it is true |
| Feedback for the response 'False'. | So you think it is false |
And I am on the "Test quiz name" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
@javascript
Scenario: Display custom question fields to teachers based on their visibility.
+2
View File
@@ -58,6 +58,8 @@ $PAGE->set_url($url);
$streditingquestions = get_string('deletequestion', 'qbank_deletequestion');
$PAGE->set_title($streditingquestions);
$PAGE->set_heading($COURSE->fullname);
$PAGE->activityheader->disable();
$PAGE->set_secondary_active_tab("questionbank");
// Unhide a question.
if (($unhide = optional_param('unhide', '', PARAM_INT)) and confirm_sesskey()) {
@@ -23,13 +23,13 @@ Feature: Use the qbank plugin manager page for deletequestion
And I should see "Delete question"
And I click on "Disable" "link" in the "Delete question" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I click on ".dropdown-toggle" "css_element" in the "First question" "table_row"
Then I should not see "Delete" in the "region-main" "region"
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "Delete question" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I click on ".dropdown-toggle" "css_element" in the "First question" "table_row"
And I should see "Delete" in the "region-main" "region"
@@ -40,13 +40,13 @@ Feature: Use the qbank plugin manager page for deletequestion
And I should see "Delete question"
And I click on "Disable" "link" in the "Delete question" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I click on "With selected" "button"
Then I should not see question bulk action "deleteselected"
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "Delete question" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I click on "With selected" "button"
And I should see question bulk action "deleteselected"
@@ -54,7 +54,7 @@ Feature: Use the qbank plugin manager page for deletequestion
Scenario: I should not see the deleted questions in the base view
Given I log in as "admin"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I click on "First question" "checkbox"
And I click on "First question second" "checkbox"
And I click on "With selected" "button"
@@ -23,7 +23,7 @@ Feature: Use the qbank plugin manager page for editquestion
And I should see "Edit question"
And I click on "Disable" "link" in the "Edit question" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
Then I should not see "Status"
And I click on ".dropdown-toggle" "css_element" in the "First question" "table_row"
And I should not see "Edit question" in the "region-main" "region"
@@ -31,7 +31,7 @@ Feature: Use the qbank plugin manager page for editquestion
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "Edit question" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I click on ".dropdown-toggle" "css_element" in the "First question" "table_row"
Then I should see "Status"
And I click on ".dropdown-toggle" "css_element" in the "First question" "table_row"
@@ -21,7 +21,7 @@ Feature: Use the qbank base view to test the status change using
Scenario: Question status dropdown should change the status of the question
Given I log in as "admin"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I set the field "Select a category" to "Test questions"
And I should see "Test questions"
And I should see "Ready" in the "First question" "table_row"
+4 -4
View File
@@ -48,13 +48,13 @@ $PAGE->set_title($strexportquestions);
$PAGE->set_heading($COURSE->fullname);
$PAGE->activityheader->disable();
echo $OUTPUT->header();
// Print horizontal nav if needed.
$renderer = $PAGE->get_renderer('core_question', 'bank');
echo $OUTPUT->header();
$qbankaction = new \core_question\output\qbank_actionbar($thispageurl);
echo $renderer->qbank_action_menu($qbankaction);
$qbankaction = new \core_question\output\qbank_action_menu($thispageurl);
echo $renderer->render($qbankaction);
$exportform = new export_form($thispageurl,
['contexts' => $contexts->having_one_edit_tab_cap('export'), 'defaultcategory' => $pagevars['cat']]);
+4 -4
View File
@@ -75,13 +75,13 @@ $PAGE->set_title($txt->importquestions);
$PAGE->set_heading($COURSE->fullname);
$PAGE->activityheader->disable();
echo $OUTPUT->header();
// Print horizontal nav if needed.
$renderer = $PAGE->get_renderer('core_question', 'bank');
echo $OUTPUT->header();
$qbankaction = new \core_question\output\qbank_actionbar($thispageurl);
echo $renderer->qbank_action_menu($qbankaction);
$qbankaction = new \core_question\output\qbank_action_menu($thispageurl);
echo $renderer->render($qbankaction);
// File upload form submitted.
if ($form = $importform->get_data()) {
+16 -9
View File
@@ -50,11 +50,13 @@ $param->confirm = optional_param('confirm', 0, PARAM_INT);
$param->cancel = optional_param('cancel', '', PARAM_ALPHA);
$param->move = optional_param('move', 0, PARAM_INT);
$param->moveto = optional_param('moveto', 0, PARAM_INT);
$param->edit = optional_param('edit', 0, PARAM_INT);
$param->edit = optional_param('edit', null, PARAM_INT);
$url = new moodle_url($thispageurl);
foreach ((array)$param as $key => $value) {
if (($key !== 'cancel' && $value !== 0) || ($key === 'cancel' && $value !== '')) {
if (($key !== 'cancel' && $key !== 'edit' && $value !== 0) ||
($key === 'cancel' && $value !== '') ||
($key === 'edit' && $value !== null)) {
$url->param($key, $value);
}
}
@@ -144,7 +146,9 @@ if ($qcobject->catform->is_cancelled()) {
redirect($thispageurl);
}
if ($param->edit) {
if ($param->edit !== null || $qcobject->catform->is_submitted()) {
// In the is_submitted case, we only get here if it was submitted,
// but not valid, so we need to show the validation error.
$PAGE->navbar->add(get_string('editingcategory', 'question'));
}
@@ -152,17 +156,20 @@ $PAGE->set_title(get_string('editcategories', 'question'));
$PAGE->set_heading($COURSE->fullname);
$PAGE->activityheader->disable();
echo $OUTPUT->header();
// Print horizontal nav if needed.
$renderer = $PAGE->get_renderer('core_question', 'bank');
echo $OUTPUT->header();
$qbankaction = new \core_question\output\qbank_actionbar($url);
echo $renderer->qbank_action_menu($qbankaction);
$qbankaction = new \core_question\output\qbank_action_menu($url);
echo $renderer->render($qbankaction);
// Display the UI.
if (!empty($param->edit)) {
$qcobject->edit_single_category($param->edit);
if ($param->edit !== null || $qcobject->catform->is_submitted()) {
// In the is_submitted case, we only get here if it was submitted,
// but not valid, so we need to show the validation error.
// In this case, category id is in the 'id' hidden filed.
$qcobject->edit_single_category($param->edit ?? required_param('id', PARAM_INT));
} else if ($questionstomove) {
$qcobject->display_move_form($questionstomove, $category);
} else {
@@ -71,7 +71,7 @@ class question_category_edit_form extends moodleform {
$mform->addHelpButton('idnumber', 'idnumber', 'question');
$mform->setType('idnumber', PARAM_RAW);
$this->add_action_buttons(false, get_string('addcategory', 'question'));
$this->add_action_buttons(true, get_string('addcategory', 'question'));
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
@@ -136,7 +136,8 @@ class question_category_object {
foreach ($this->editlists as $key => $list) {
list($paged, $count) = $this->editlists[$key]->list_from_records($paged, $count);
}
$this->catform = new question_category_edit_form($this->pageurl, compact('contexts', 'currentcat'));
$this->catform = new question_category_edit_form($this->pageurl,
['contexts' => $contexts, 'currentcat' => $currentcat ?? 0]);
if (!$currentcat) {
$this->catform->set_data(['parent' => $defaultcategory]);
}
@@ -147,15 +148,8 @@ class question_category_object {
*
*/
public function display_user_interface(): void {
// Interface for editing existing categories.
$this->output_edit_lists();
echo \html_writer::empty_tag('br');
// Interface for adding a new category.
$this->output_new_table();
echo \html_writer::empty_tag('br');
}
/**
@@ -174,7 +168,7 @@ class question_category_object {
public function output_edit_lists(): void {
global $OUTPUT;
echo $OUTPUT->heading_with_help(get_string('editcategories', 'question'), 'editcategories', 'question');
echo $OUTPUT->heading_with_help(get_string('questioncategories', 'question'), 'editcategories', 'question');
foreach ($this->editlists as $context => $list) {
$listhtml = $list->to_html(0, ['str' => $this->str]);
@@ -208,26 +202,29 @@ class question_category_object {
}
/**
* Edit a category.
* Edit a category, or add a new one if the id is zero.
*
* @param int $categoryid Category id.
*/
public function edit_single_category(int $categoryid): void {
// Interface for adding a new category.
global $DB;
// Interface for editing existing categories.
$category = $DB->get_record("question_categories", ["id" => $categoryid]);
if (empty($category)) {
throw new moodle_exception('invalidcategory', '', '', $categoryid);
} else if ($category->parent == 0) {
throw new moodle_exception('cannotedittopcat', 'question', '', $categoryid);
} else {
if ($categoryid) {
// Editing an existing category.
$category = $DB->get_record("question_categories", ["id" => $categoryid], '*', MUST_EXIST);
if ($category->parent == 0) {
throw new moodle_exception('cannotedittopcat', 'question', '', $categoryid);
}
$category->parent = "{$category->parent},{$category->contextid}";
$category->submitbutton = get_string('savechanges');
$category->categoryheader = $this->str->edit;
$this->catform->set_data($category);
$this->catform->display();
}
// Show the form.
$this->catform->display();
}
/**
@@ -22,7 +22,9 @@ Feature: A teacher can move question categories in the question bank
Scenario: A question category can be moved to another context
When I follow "Test quiz"
And I navigate to "Question bank > Categories" in current page administration
And I navigate to "Question bank" in current page administration
And I select "Categories" from the "Question bank tertiary navigation" singleselect
And I follow "Add category"
And I set the following fields to these values:
| Name | Test category |
| Parent category | Top for Test quiz |
@@ -32,7 +34,9 @@ Feature: A teacher can move question categories in the question bank
Scenario: A question category can be moved to top level
When I follow "Test quiz"
And I navigate to "Question bank > Categories" in current page administration
And I navigate to "Question bank" in current page administration
And I select "Categories" from the "Question bank tertiary navigation" singleselect
And I follow "Add category"
And I set the following fields to these values:
| Name | Test category |
| Parent category | Default for Test quiz |
@@ -28,7 +28,8 @@ Feature: A teacher can put questions in categories in the question bank
Scenario: A new question category can be created
When I navigate to "Question bank" in current page administration
And I select "Categories" from the "questionbankactionselect" singleselect
And I select "Categories" from the "Question bank tertiary navigation" singleselect
And I follow "Add category"
And I set the following fields to these values:
| Name | New Category 1 |
| Parent category | Top |
@@ -40,11 +41,12 @@ Feature: A teacher can put questions in categories in the question bank
And I should see "newcatidnumber"
And I should see "(0)"
And I should see "Created as a test" in the "New Category 1" "list_item"
And I follow "Add category"
And "New Category 1 [newcatidnumber]" "option" should exist in the "Parent category" "select"
Scenario: A question category can be edited
When I navigate to "Question bank" in current page administration
And I select "Categories" from the "questionbankactionselect" singleselect
And I select "Categories" from the "Question bank tertiary navigation" singleselect
And I click on "Edit this category" "link" in the "Subcategory" "list_item"
And the field "parent" matches value "&nbsp;&nbsp;&nbsp;Default for C1"
And I set the following fields to these values:
@@ -56,15 +58,16 @@ Feature: A teacher can put questions in categories in the question bank
Scenario: An empty question category can be deleted
When I navigate to "Question bank" in current page administration
And I select "Categories" from the "questionbankactionselect" singleselect
And I select "Categories" from the "Question bank tertiary navigation" singleselect
And I click on "Delete" "link" in the "Subcategory" "list_item"
Then I should not see "Subcategory"
Scenario: An non-empty question category can be deleted if you move the contents elsewhere
When I navigate to "Question bank" in current page administration
And I select "Categories" from the "questionbankactionselect" singleselect
And I select "Categories" from the "Question bank tertiary navigation" singleselect
And I click on "Delete" "link" in the "Used category" "list_item"
And I should see "The category 'Used category' contains 1 questions"
And I press "Save in category"
Then I should not see "Used category"
And I follow "Add category"
And I should see "Default for C1 (1)"
@@ -24,18 +24,19 @@ Feature: A teacher can put questions with idnumbers in categories with idnumbers
| Course | C1 | Top | top | |
| Course | C1 | top | Used category | c1used |
And I navigate to "Question bank" in current page administration
And I select "Categories" from the "questionbankactionselect" singleselect
And I select "Categories" from the "Question bank tertiary navigation" singleselect
And I follow "Add category"
And I set the following fields to these values:
| Name | Sub used category |
| Parent category | Used category |
| Category info | Created as a test |
| ID number | c1used |
And I press "Add category"
And I press "submitbutton"
# Standard warning.
Then I should see "This ID number is already in use"
# Correction to a unique idnumber for the context.
And I set the field "ID number" to "c1unused"
And I press "Add category"
And I press "submitbutton"
Then I should see "Sub used category"
And I should see "ID number"
And I should see "c1unused"
@@ -48,7 +49,7 @@ Feature: A teacher can put questions with idnumbers in categories with idnumbers
| Course | C1 | Top | top | |
| Course | C1 | top | Used category | c1used |
And I navigate to "Question bank" in current page administration
And I select "Categories" from the "questionbankactionselect" singleselect
And I select "Categories" from the "Question bank tertiary navigation" singleselect
And I click on "Edit this category" "link" in the "Used category" "list_item"
And I press "Save changes"
Then I should not see "This ID number is already in use"
@@ -26,7 +26,8 @@ Feature: Use the qbank plugin manager page for managecategories
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "Manage categories" "table_row"
And I am on the "Test quiz" "quiz activity" page
And "Categories" "link" should exist in current page administration
And I navigate to "Question bank" in current page administration
And I should see "Categories" in the "//div[contains(@class, 'urlselect')]//option[contains(text(), 'Categories')]" "xpath_element"
Scenario: Enable/disable the tab New category when tyring to add a random question to a quiz
Given I log in as "admin"
@@ -34,7 +35,7 @@ Feature: Use the qbank plugin manager page for managecategories
And I should see "Manage categories"
And I click on "Disable" "link" in the "Manage categories" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Edit quiz" in current page administration
And I click on "Add question" "link"
And I open the "last" add to quiz menu
And I follow "a random question"
Then I should not see "New category"
@@ -42,7 +43,7 @@ Feature: Use the qbank plugin manager page for managecategories
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "Manage categories" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Edit quiz" in current page administration
And I click on "Add question" "link"
And I open the "last" add to quiz menu
And I follow "a random question"
And I should see "New category"
@@ -22,14 +22,14 @@ Feature: Use the qbank plugin manager page for statistics
And I should see "Question statistics"
And I click on "Disable" "link" in the "Question statistics" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
Then I should not see "Facility index"
And I should not see "Discriminative efficiency"
And I should not see "Need for revision"
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "Question statistics" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I should see "Facility index"
And I should see "Discriminative efficiency"
And I should see "Need for revision"
@@ -73,8 +73,7 @@ Feature: Show statistics in question bank
| 1 | True |
| 2 | True |
When I am on the "Course 1" course page logged in as admin
When I navigate to "Question bank" in current page administration
And I select "Questions" from the "questionbankactionselect" singleselect
And I navigate to "Question bank" in current page administration
And I should see "50.00%" in the "TF1" "table_row"
And I should see "75.00%" in the "TF2" "table_row"
And I should see "75.00%" in the "TF3" "table_row"
@@ -90,8 +89,7 @@ Feature: Show statistics in question bank
| 1 | True |
| 2 | True |
When I am on the "Course 1" course page logged in as admin
When I navigate to "Question bank" in current page administration
And I select "Questions" from the "questionbankactionselect" singleselect
And I navigate to "Question bank" in current page administration
And I should see "50.00%" in the "TF1" "table_row"
And I should see "75.00%" in the "TF2" "table_row"
And I should see "75.00%" in the "TF3" "table_row"
@@ -108,9 +106,6 @@ Feature: Show statistics in question bank
| 2 | True |
When I am on the "Course 1" course page logged in as admin
And I navigate to "Question bank" in current page administration
And I select "Questions" from the "questionbankactionselect" singleselect
When I navigate to "Question bank" in current page administration
And I select "Questions" from the "questionbankactionselect" singleselect
And I should see "Likely" in the "TF1" "table_row"
And I should see "Unlikely" in the "TF2" "table_row"
And I should see "Unlikely" in the "TF3" "table_row"
@@ -132,8 +127,7 @@ Feature: Show statistics in question bank
| 1 | True |
| 2 | False |
When I am on the "Course 1" course page logged in as admin
When I navigate to "Question bank" in current page administration
And I select "Questions" from the "questionbankactionselect" singleselect
And I navigate to "Question bank" in current page administration
And I should see "Likely" in the "TF1" "table_row"
And I should see "Very likely" in the "TF2" "table_row"
And I should see "Very likely" in the "TF3" "table_row"
@@ -22,19 +22,19 @@ Feature: Use the qbank plugin manager page for question usage
And I should see "Question usage"
When I click on "Disable" "link" in the "Question usage" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
Then I should not see "Usage"
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "Question usage" "table_row"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I should see "Usage"
@javascript
Scenario: Question usage modal should work without any usage data
Given I log in as "admin"
And I am on the "Test quiz" "quiz activity" page
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I set the field "Select a category" to "Test questions"
And I should see "Test questions"
And I should see "0" on the usage column
@@ -25,11 +25,17 @@ use url_select;
/**
* Rendered HTML elements for tertiary nav for Question bank.
*
* Provides the links for question bank tertiary navigation, below
* are the links provided for the urlselector:
* Questions, Categories, Import and Export
* Also "Add category" button is added to tertiary nav for the categories.
* The "Add category" would take the user to separate page, add category page.
*
* @package core_question
* @copyright 2021 Sujith Haridasan <sujith@moodle.com>
* @package core_question
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qbank_actionbar implements templatable, renderable {
class qbank_action_menu implements templatable, renderable {
/** @var moodle_url */
private $currenturl;
@@ -57,7 +63,7 @@ class qbank_actionbar implements templatable, renderable {
$exportlink = new moodle_url('/question/bank/exportquestions/export.php', $this->currenturl->params());
$menu = [
$questionslink->out(false) => get_string('questions', 'question'),
$questionslink->out(false) => get_string('questions', 'question'),
];
if (\core\plugininfo\qbank::is_plugin_enabled("qbank_managecategories")) {
@@ -65,39 +71,19 @@ class qbank_actionbar implements templatable, renderable {
}
$menu[$importlink->out(false)] = get_string('import', 'question');
$menu[$exportlink->out(false)] = get_string('export', 'question');
$additional = $this->get_additional_menu_elements();
$menu += $additional ?: [];
$addcategory = null;
if (strpos($this->currenturl->get_path(), 'category.php') !== false &&
$this->currenturl->param('edit') === null) {
$addcategory = $this->currenturl->out(false, ['edit' => 0]);
}
$urlselect = new url_select($menu, $this->currenturl->out(false), null, 'questionbankaction');
$urlselect->set_label('questionbankactionselect', ['class' => 'accesshide']);
$urlselect->set_label(get_string('questionbanknavigation', 'question'), ['class' => 'accesshide']);
return ['questionbankselect' => $urlselect->export_for_template($output)];
}
/**
* Gets the additional third party navigation nodes.
*
* @return array|null The additional menu elements.
*/
protected function get_additional_menu_elements(): ?array {
global $PAGE;
$qbnode = $PAGE->settingsnav->find('questionbank', \navigation_node::TYPE_CONTAINER);
$othernodes = [];
foreach ($qbnode->children as $key => $value) {
if (array_search($value->key, $this->expected_nodes()) === false) {
$othernodes[] = $value;
}
}
$result = \core\navigation\views\secondary::create_menu_element($othernodes, true);
return $result;
}
/**
* Returns a list of expected child navigation nodes for 'questionbank'.
*
* @return array The expected nodes
*/
protected function expected_nodes(): array {
return ['questions', 'categories', 'import', 'export'];
return [
'questionbankselect' => $urlselect->export_for_template($output),
'addcategory' => $addcategory
];
}
}
+4 -3
View File
@@ -48,13 +48,14 @@ $PAGE->set_title($streditingquestions);
$PAGE->set_heading($COURSE->fullname);
$PAGE->activityheader->disable();
echo $OUTPUT->header();
// Print horizontal nav if needed.
$renderer = $PAGE->get_renderer('core_question', 'bank');
echo $OUTPUT->header();
// Render the selection action.
$qbankaction = new \core_question\output\qbank_actionbar($url);
echo $renderer->qbank_action_menu($qbankaction);
$qbankaction = new \core_question\output\qbank_action_menu($url);
echo $renderer->render($qbankaction);
// Print the question area.
$questionbank->display($pagevars, 'questions');
@@ -26,7 +26,7 @@ Feature: Test exporting questions using Aiken format.
Scenario: Aiken export
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_aiken" to "1"
When I press "Export questions to file"
Then following "click here" should download between "68" and "70" bytes
@@ -20,7 +20,7 @@ Feature: Test importing questions from Aiken format.
@javascript @_file_upload
Scenario: import some Aiken questions
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_aiken" to "1"
And I upload "question/format/aiken/tests/fixtures/questions.aiken.txt" file to "Import" filemanager
And I press "id_submitbutton"
@@ -20,7 +20,7 @@ Feature: Test importing questions from GIFT format.
@javascript @_file_upload
Scenario: import some GIFT questions
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_gift" to "1"
And I upload "question/format/gift/tests/fixtures/questions.gift.txt" file to "Import" filemanager
And I press "id_submitbutton"
@@ -33,7 +33,7 @@ Feature: Test importing questions from GIFT format.
# Now export again.
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_gift" to "1"
And I press "Export questions to file"
And following "click here" should download between "1500" and "1800" bytes
@@ -41,7 +41,7 @@ Feature: Test importing questions from GIFT format.
@javascript @_file_upload
Scenario: import a GIFT file which specifies the category
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_gift" to "1"
And I upload "question/format/gift/tests/fixtures/questions_in_category.gift.txt" file to "Import" filemanager
And I press "id_submitbutton"
@@ -20,7 +20,7 @@ Feature: Test importing questions from Moodle XML format.
@javascript @_file_upload
Scenario: import some true/false questions from Moodle XML format
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/format/xml/tests/fixtures/truefalse.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -35,7 +35,7 @@ Feature: Test importing questions from Moodle XML format.
# Now export again.
And I am on "Course 1" course homepage
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I set the field "Export category" to "TrueFalse"
And I press "Export questions to file"
@@ -44,7 +44,7 @@ Feature: Test importing questions from Moodle XML format.
@javascript @_file_upload
Scenario: import some multiple choice questions from Moodle XML format
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/format/xml/tests/fixtures/multichoice.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -57,7 +57,7 @@ Feature: Test importing questions from Moodle XML format.
@javascript @_file_upload
Scenario: import some multi-answer questions from Moodle XML format
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/format/xml/tests/fixtures/multianswer.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -70,7 +70,7 @@ Feature: Test importing questions from Moodle XML format.
@javascript @_file_upload
Scenario: import some questions with legacy-style images from Moodle XML format
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/format/xml/tests/fixtures/sample_questions_with_old_image_tag.xml" file to "Import" filemanager
And I press "id_submitbutton"
-11
View File
@@ -182,17 +182,6 @@ class core_question_bank_renderer extends plugin_renderer_base {
return '';
}
/**
* Get the rendered HTML for the action area in Question bank.
*
* @param \core_question\output\qbank_actionbar $qbankactionbar qbankactionbar object.
* @return string rendered HTML string from template.
*/
public function qbank_action_menu(\core_question\output\qbank_actionbar $qbankactionbar): string {
return $this->render_from_template('core_question/qbank_action_menu',
$qbankactionbar->export_for_template($this));
}
/**
* Build the HTML for a specified set of question types.
*
+37 -30
View File
@@ -16,42 +16,46 @@
}}
{{!
@template core_question/qbank_action_menu
Add selector in the question bank tab.
Question bank tertiary navigtion.
Classes required for JS:
* none
Data attributes required for JS:
* data-region
Context variables required for this template:
* see question/classes/output/qbank_actionbar.php
Example context (json):
{
"action" : "http://localhost/moodle/course/jumpto.php",
"classes" : "urlselect",
"formid" : "questionbankaction",
"id" : "url_select61a85bc543dca7",
"label" : "questionbankactionselect",
"options" : [
{
"name" : "Questions",
"selected" : true,
"value" : "/question/edit.php?courseid=7"
},
{
"name" : "Categories",
"selected" : false,
"value" : "/question/bank/managecategories/category.php?courseid=7"
},
{
"name" : "Import",
"selected" : false,
"value" : "/question/bank/importquestions/import.php?courseid=7"
},
{
"name" : "Export",
"selected" : false,
"value" : "/question/bank/exportquestions/export.php?courseid=7"
}
]
"questionbankselect": {
"action": "http://localhost/moodle/course/jumpto.php",
"classes": "urlselect",
"formid": "questionbankaction",
"id": "url_select61a85bc543dca7",
"label": "Question bank tertiary navigation",
"options": [{
"name": "Questions",
"selected": true,
"value": "/question/edit.php?courseid=7"
},
{
"name": "Categories",
"selected": false,
"value": "/question/bank/managecategories/category.php?courseid=7"
},
{
"name": "Import",
"selected": false,
"value": "/question/bank/importquestions/import.php?courseid=7"
},
{
"name": "Export",
"selected": false,
"value": "/question/bank/exportquestions/export.php?courseid=7"
}
]
},
"addcategory": "http://localhost/moodle/question/bank/managecategories/addcategory.php?cmid=71"
}
}}
<div class="container-fluid mb-2">
@@ -59,5 +63,8 @@
{{#questionbankselect}}
{{>core/url_select}}
{{/questionbankselect}}
{{#addcategory}}
<a class="btn btn-primary ml-2" href="{{ addcategory }}">{{#str}}addcategory, question {{/str}}</a>
{{/addcategory}}
</div>
</div>
@@ -60,7 +60,7 @@ Feature: A teacher can delete questions in the question bank
And I click on "Also show old questions" "checkbox"
And I should see "Test used question to be deleted"
And I am on the "Test quiz" "quiz activity" page
And I follow "Preview quiz"
And I click on "Preview quiz" "button"
And I should see "Write about whatever you want"
@javascript
@@ -27,7 +27,7 @@ Feature: Test exporting drag and drop onto image questions
Scenario: Export a drag and drop onto image question
# Import sample file.
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
And following "click here" should download between "18600" and "19150" bytes
@@ -20,7 +20,7 @@ Feature: Test importing drag and drop onto image questions
@javascript @_file_upload
Scenario: import drag and drop onto image question.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/ddimageortext/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -27,7 +27,7 @@ Feature: Test exporting drag and drop markers questions
Scenario: Export a drag and drop markers question
# Import sample file.
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
And following "click here" should download between "233700" and "233950" bytes
@@ -20,7 +20,7 @@ Feature: Test importing drag and drop markers questions
@javascript @_file_upload
Scenario: import drag and drop markers question.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/ddmarker/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -27,7 +27,7 @@ Feature: Test exporting drag and drop into text questions
Scenario: Export a drag and drop into text question
# Import sample file.
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
And following "click here" should download between "1550" and "1700" bytes
@@ -20,7 +20,7 @@ Feature: Test importing drag and drop into text questions
@javascript @_file_upload
Scenario: import drag and drop into text question.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/ddwtos/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -25,7 +25,7 @@ Feature: Test exporting Description questions
Scenario: Export a Description question
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "650" and "900" bytes
@@ -20,7 +20,7 @@ Feature: Test importing Description questions
@javascript @_file_upload
Scenario: import a Description question.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/description/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -27,7 +27,7 @@ Feature: Test exporting Essay questions
Scenario: Export 3 Essay questions
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "3000" and "3500" bytes
@@ -46,7 +46,7 @@ I need to limit the submittable file types
And I upload "lib/tests/fixtures/empty.txt" file to "Files" filemanager
And I press "Save changes"
And I am on the "Quiz 1" "quiz activity" page
And I follow "Attempt quiz"
And I press "Attempt quiz"
And I should see "First question"
And I should see "You can drag and drop files here to add them."
And I click on "Add..." "button"
@@ -64,7 +64,7 @@ I need to limit the submittable file types
And I upload "lib/tests/fixtures/upload_users.csv" file to "Files" filemanager
And I press "Save changes"
And I am on the "Quiz 1" "quiz activity" page
And I follow "Attempt quiz"
And I press "Attempt quiz"
And I should see "First question"
And I should see "You can drag and drop files here to add them."
And I click on "Add..." "button"
@@ -20,7 +20,7 @@ Feature: Test importing Essay questions
@javascript @_file_upload
Scenario: import Essay question.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/essay/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -21,7 +21,7 @@ Feature: Import and export select missing words questions
Scenario: Import and export select missing words questions
# Import sample file.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/gapselect/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -34,7 +34,7 @@ Feature: Import and export select missing words questions
# Now export again.
And I am on "Course 1" course homepage
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "1650" and "1800" bytes
@@ -25,7 +25,7 @@ Feature: Test exporting Matching questions
Scenario: Export a Matching question
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "1600" and "1750" bytes
@@ -20,7 +20,7 @@ Feature: Test importing Matching questions
@javascript @_file_upload
Scenario: import Matching question.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/match/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -40,7 +40,7 @@ Feature: Clear my answers
@javascript
Scenario: Attempt a quiz and reset my chosen answer.
Given I am on the "Quiz 1" "quiz activity" page logged in as student1
When I follow "Attempt quiz"
When I press "Attempt quiz"
And I should see "Question One"
And I click on "Four" "qtype_multichoice > Answer" in the "Question One" "question"
And I should see "Clear my choice"
@@ -52,7 +52,7 @@ Feature: Clear my answers
@javascript
Scenario: Attempt a quiz and revisit a cleared answer.
Given I am on the "Quiz 1" "quiz activity" page logged in as student1
When I follow "Attempt quiz"
When I press "Attempt quiz"
And I should see "Question One"
And I click on "Four" "qtype_multichoice > Answer" in the "Question One" "question"
And I follow "Finish attempt ..."
@@ -26,7 +26,7 @@ Feature: Test exporting Multiple choice questions
Scenario: Export a Multiple choice question
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "3900" and "4100" bytes
@@ -20,7 +20,7 @@ Feature: Test importing Multiple choice questions
@javascript @_file_upload
Scenario: import Multiple choice question.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/multichoice/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -26,7 +26,7 @@ Feature: Test exporting Numerical questions
Scenario: Export a Numerical question
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "3650" and "3750" bytes
@@ -20,7 +20,7 @@ Feature: Test importing Numerical questions
@javascript @_file_upload
Scenario: import Numerical question.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/numerical/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -25,7 +25,7 @@ Feature: Test exporting Short answer questions
Scenario: Export a Short answer question
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "1200" and "1450" bytes
@@ -20,7 +20,7 @@ Feature: Test importing Short answer questions
@javascript @_file_upload
Scenario: import Matching question.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/shortanswer/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -25,7 +25,7 @@ Feature: Test exporting True/False questions
Scenario: Export a True/False question
When I navigate to "Question bank" in current page administration
And I select "Export" from the "questionbankactionselect" singleselect
And I select "Export" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "1000" and "1200" bytes
@@ -20,7 +20,7 @@ Feature: Test importing True/False questions
@javascript @_file_upload
Scenario: import a True/False question.
When I navigate to "Question bank" in current page administration
And I select "Import" from the "questionbankactionselect" singleselect
And I select "Import" from the "Question bank tertiary navigation" singleselect
And I set the field "id_format_xml" to "1"
And I upload "question/type/truefalse/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -44,7 +44,7 @@ Feature: A Teacher can generate question instance reports
@javascript
Scenario: Generate report displaying hidden questions
Given I am on the "Test quiz Q001" "quiz activity" page logged in as "admin"
And I navigate to "Question bank > Questions" in current page administration
And I navigate to "Question bank" in current page administration
And I click on "Edit" "link" in the "TF" "table_row"
And I choose "Delete" in the open action menu
And I press "Delete"
@@ -1,65 +0,0 @@
<?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/>.
/**
* Step definitions related to mod_quiz overrides for the Classic theme.
*
* @package theme_classic
* @category test
* @copyright 2019 Michael Hawkins
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
require_once(__DIR__ . '/../../../../mod/quiz/tests/behat/behat_mod_quiz.php');
use Behat\Gherkin\Node\TableNode as TableNode;
/**
* Step definitions related to mod_quiz overrides for the Classic theme.
*
* @package theme_classic
* @category test
* @copyright 2019 Michael Hawkins
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_classic_behat_mod_quiz extends behat_mod_quiz {
/**
* Adds a question to the existing quiz with filling the form.
* The form for creating a question should be on one page.
*
* @param string $questiontype
* @param string $quizname
* @param TableNode $questiondata with data for filling the add question form
*/
public function i_add_question_to_the_quiz_with($questiontype, $quizname, TableNode $questiondata) {
$quizname = $this->escape($quizname);
$editquiz = $this->escape(get_string('editquiz', 'quiz'));
$menuxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' dropdown-toggle')]";
$itemxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' addquestion ')]";
$this->execute('behat_general::click_link', $quizname);
$this->execute("behat_navigation::i_navigate_to_in_current_page_administration", $editquiz);
$this->execute("behat_general::i_click_on", array($menuxpath, "xpath_element"));
$this->execute("behat_general::i_click_on", array($itemxpath, "xpath_element"));
$this->finish_adding_question($questiontype, $questiondata);
}
}
@@ -158,7 +158,7 @@ class behat_theme_classic_behat_navigation extends behat_navigation {
$this->find('xpath', $menuxpath, $exception);
} catch (Exception $e) {
// For question bank a different approach.
$menuxpath = $rootxpath . "//div[contains(@class, 'dropdown-menu')]";
$menuxpath = $rootxpath;
if ($selectortype === 'link') {
$menuxpath .= "//a[contains(text(), 'Categories')]";
}