mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 00:12:56 +02:00
Merge branch 'master_MDL-71614-previewquestion' of https://github.com/catalyst/moodle-MDL-70329
This commit is contained in:
commit
5c78efaaea
@ -1946,6 +1946,7 @@ class core_plugin_manager {
|
||||
'exportquestions',
|
||||
'importquestions',
|
||||
'managecategories',
|
||||
'previewquestion',
|
||||
'tagquestion',
|
||||
'viewcreator',
|
||||
'viewquestionname',
|
||||
|
@ -757,55 +757,34 @@ function question_move_category_to_context($categoryid, $oldcontextid, $newconte
|
||||
* @param object $context context to run the preview in (affects things like
|
||||
* filter settings, theme, lang, etc.) Defaults to $PAGE->context.
|
||||
* @return moodle_url the URL.
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see qbank_previewquestion\helper::question_preview_url()
|
||||
* @todo MDL-71679 uncomment the debug messages after implementing the changes in mod_quiz.
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
function question_preview_url($questionid, $preferredbehaviour = null,
|
||||
$maxmark = null, $displayoptions = null, $variant = null, $context = null) {
|
||||
// Debugging message will be re-added after implementing the changes in mod_quiz.
|
||||
// ...debugging('Function question_preview_url() has been deprecated and moved to qbank_previewquestion plugin,
|
||||
// Please use qbank_previewquestion\helper::question_preview_url() instead.', DEBUG_DEVELOPER);.
|
||||
|
||||
$params = array('id' => $questionid);
|
||||
|
||||
if (is_null($context)) {
|
||||
global $PAGE;
|
||||
$context = $PAGE->context;
|
||||
}
|
||||
if ($context->contextlevel == CONTEXT_MODULE) {
|
||||
$params['cmid'] = $context->instanceid;
|
||||
} else if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
$params['courseid'] = $context->instanceid;
|
||||
}
|
||||
|
||||
if (!is_null($preferredbehaviour)) {
|
||||
$params['behaviour'] = $preferredbehaviour;
|
||||
}
|
||||
|
||||
if (!is_null($maxmark)) {
|
||||
$params['maxmark'] = format_float($maxmark, -1);
|
||||
}
|
||||
|
||||
if (!is_null($displayoptions)) {
|
||||
$params['correctness'] = $displayoptions->correctness;
|
||||
$params['marks'] = $displayoptions->marks;
|
||||
$params['markdp'] = $displayoptions->markdp;
|
||||
$params['feedback'] = (bool) $displayoptions->feedback;
|
||||
$params['generalfeedback'] = (bool) $displayoptions->generalfeedback;
|
||||
$params['rightanswer'] = (bool) $displayoptions->rightanswer;
|
||||
$params['history'] = (bool) $displayoptions->history;
|
||||
}
|
||||
|
||||
if ($variant) {
|
||||
$params['variant'] = $variant;
|
||||
}
|
||||
|
||||
return new moodle_url('/question/preview.php', $params);
|
||||
return \qbank_previewquestion\helper::question_preview_url($questionid, $preferredbehaviour = null,
|
||||
$maxmark = null, $displayoptions = null, $variant = null, $context = null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array that can be passed as $params to the {@link popup_action} constructor.
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see qbank_previewquestion\helper::question_preview_popup_params()
|
||||
* @todo MDL-71679 uncomment the debug messages after implementing the changes to mod_quiz.
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
function question_preview_popup_params() {
|
||||
return array(
|
||||
'height' => 600,
|
||||
'width' => 800,
|
||||
);
|
||||
// Debugging message will be re-added after implementing the changes in mod_quiz.
|
||||
// ...debugging('Function question_preview_popup_params() has been deprecated and moved to qbank_previewquestion plugin,
|
||||
// Please use qbank_previewquestion\helper::question_preview_popup_params() instead.', DEBUG_DEVELOPER);.
|
||||
|
||||
return \qbank_previewquestion\helper::question_preview_popup_params();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2143,8 +2122,7 @@ function question_pluginfile($course, $context, $component, $filearea, $args, $f
|
||||
}
|
||||
|
||||
if ($module === 'core_question_preview') {
|
||||
require_once($CFG->dirroot . '/question/previewlib.php');
|
||||
return question_preview_question_pluginfile($course, $context,
|
||||
return qbank_previewquestion\helper::question_preview_question_pluginfile($course, $context,
|
||||
$component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
|
||||
|
||||
} else {
|
||||
|
@ -80,6 +80,11 @@ information provided here is intended especially for developers.
|
||||
- question_category_options() => qbank_managecategories\helper::question_category_options()
|
||||
- question_add_context_in_key() => qbank_managecategories\helper::question_add_context_in_key()
|
||||
- question_fix_top_names() => qbank_managecategories\helper::question_fix_top_names()
|
||||
* Following methods are now deprecated in questionlib and moved to the new qbank_previewquestion plugin:
|
||||
- question_preview_url() is moved to qbank_previewquestion\helper::question_preview_url()
|
||||
- question_preview_popup_params() is moved to \qbank_previewquestion\helper::question_preview_popup_params()
|
||||
Calling these functions in the question will point to the plugin, but the deprecation message will be activated in MDL-72004.
|
||||
The deprecated codes are removed from the questionlib for those two methods.
|
||||
|
||||
=== 3.11.2 ===
|
||||
* For security reasons, filelib has been updated so all requests now use emulated redirects.
|
||||
|
2
question/bank/previewquestion/amd/build/preview.min.js
vendored
Normal file
2
question/bank/previewquestion/amd/build/preview.min.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
define ("qbank_previewquestion/preview",["exports","jquery"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);a.init=function init(a){if(!a){var b=document.getElementById("close-previewquestion-page");b.onclick=function(){window.close()}}c("responseform")};var c=function(a){var b=document.getElementById(a);if(b){d(b);e(b);f(".questionflagsavebutton",b);g(b)}},d=function(a){a.setAttribute("autocomplete","off")},e=function(a){a.addEventListener("submit",function(){(0,b.default)(this).submit(function(){return!1});return!0})},f=function(a,b){b.querySelectorAll(a).forEach(function(a){return a.remove()})},g=function(a){var b=window.location.href.match(/^.*[?&]scrollpos=(\d*)(?:&|$|#).*$/,"$1");if(b){window.scrollTo(0,b[1]);a.addEventListener("DOMContentLoaded",function(){window.scrollTo(0,b[1])})}}});
|
||||
//# sourceMappingURL=preview.min.js.map
|
File diff suppressed because one or more lines are too long
117
question/bank/previewquestion/amd/src/preview.js
Normal file
117
question/bank/previewquestion/amd/src/preview.js
Normal file
@ -0,0 +1,117 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Javascript for preview.
|
||||
*
|
||||
* @module qbank_preview/preview
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import $ from 'jquery';
|
||||
|
||||
/**
|
||||
* Set up the actions.
|
||||
*
|
||||
* @method init
|
||||
* @param {bool} redirect Redirect.
|
||||
*/
|
||||
export const init = (redirect) => {
|
||||
if (!redirect) {
|
||||
let closeButton = document.getElementById('close-previewquestion-page');
|
||||
closeButton.onclick = () => {
|
||||
window.close();
|
||||
};
|
||||
}
|
||||
// Set up the form to be displayed.
|
||||
setupQuestionForm('responseform');
|
||||
};
|
||||
|
||||
/**
|
||||
* Set up the form element to be displayed.
|
||||
*
|
||||
* @method setupQuestionForm
|
||||
* @param {string} formElement The form element.
|
||||
*/
|
||||
const setupQuestionForm = (formElement) => {
|
||||
let form = document.getElementById(formElement);
|
||||
if (form) {
|
||||
// Turning off browser autocomplete.
|
||||
autocompleteOff(form);
|
||||
// Stop a question form being submitted more than once.
|
||||
preventRepeatSubmission(form);
|
||||
// Removes any '.questionflagsavebutton's, since we have JavaScript to toggle.
|
||||
removeClass('.questionflagsavebutton', form);
|
||||
// Scroll to the position indicated by scrollpos= in the URL, if it is there.
|
||||
scrollToSavedPos(form);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the autocomplete off.
|
||||
*
|
||||
* @method autocompleteOff
|
||||
* @param {object} form The form element.
|
||||
*/
|
||||
const autocompleteOff = (form) => {
|
||||
form.setAttribute("autocomplete", "off");
|
||||
};
|
||||
|
||||
/**
|
||||
* Event handler to stop a question form being submitted more than once.
|
||||
*
|
||||
* @method preventRepeatSubmission
|
||||
* @param {object} form The form element.
|
||||
*/
|
||||
const preventRepeatSubmission = (form) => {
|
||||
form.addEventListener("submit", function() {
|
||||
$(this).submit(function() {
|
||||
return false;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes a class inside an element.
|
||||
*
|
||||
* @method removeClass
|
||||
* @param {string} classname Class name.
|
||||
* @param {object} form The form element.
|
||||
*/
|
||||
const removeClass = (classname, form) => {
|
||||
form.querySelectorAll(classname).forEach(e => e.remove());
|
||||
};
|
||||
|
||||
/**
|
||||
* If there is a parameter like scrollpos=123 in the URL, scroll to that saved position.
|
||||
* (Note: Moodle 4.0 and above do NOT support Internet Explorer 11 and below.)
|
||||
*
|
||||
* @method scrollToSavedPos
|
||||
* @param {object} form The form element.
|
||||
*/
|
||||
const scrollToSavedPos = (form) => {
|
||||
let matches = window.location.href.match(/^.*[?&]scrollpos=(\d*)(?:&|$|#).*$/, '$1');
|
||||
if (matches) {
|
||||
// DOMContentLoaded is the effective one here. I am leaving the immediate call to
|
||||
// window.scrollTo in case it reduces flicker.
|
||||
window.scrollTo(0, matches[1]);
|
||||
form.addEventListener("DOMContentLoaded", () => {
|
||||
window.scrollTo(0, matches[1]);
|
||||
});
|
||||
}
|
||||
};
|
@ -0,0 +1,96 @@
|
||||
<?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 qbank_previewquestion\form;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/formslib.php');
|
||||
|
||||
use moodleform;
|
||||
use question_display_options;
|
||||
use question_engine;
|
||||
|
||||
/**
|
||||
* Settings form for the preview options.
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright 2009 The Open University
|
||||
* @author 2021 Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class preview_options_form extends moodleform {
|
||||
|
||||
public function definition() {
|
||||
$mform = $this->_form;
|
||||
|
||||
$hiddenorvisible = [
|
||||
question_display_options::HIDDEN => get_string('notshown', 'question'),
|
||||
question_display_options::VISIBLE => get_string('shown', 'question'),
|
||||
];
|
||||
|
||||
$mform->addElement('header', 'attemptoptionsheader', get_string('attemptoptions', 'question'));
|
||||
|
||||
$behaviours = question_engine::get_behaviour_options(
|
||||
$this->_customdata['quba']->get_preferred_behaviour());
|
||||
$mform->addElement('select', 'behaviour',
|
||||
get_string('howquestionsbehave', 'question'), $behaviours);
|
||||
$mform->addHelpButton('behaviour', 'howquestionsbehave', 'question');
|
||||
|
||||
$mform->addElement('float', 'maxmark', get_string('markedoutof', 'question'), ['size' => '5']);
|
||||
|
||||
if ($this->_customdata['maxvariant'] > 1) {
|
||||
$variants = range(1, $this->_customdata['maxvariant']);
|
||||
$mform->addElement('select', 'variant', get_string('questionvariant', 'question'),
|
||||
array_combine($variants, $variants));
|
||||
}
|
||||
$mform->setType('variant', PARAM_INT);
|
||||
|
||||
$mform->addElement('submit', 'saverestart',
|
||||
get_string('restartwiththeseoptions', 'question'));
|
||||
|
||||
$mform->addElement('header', 'displayoptionsheader', get_string('displayoptions', 'question'));
|
||||
|
||||
$mform->addElement('select', 'correctness', get_string('whethercorrect', 'question'),
|
||||
$hiddenorvisible);
|
||||
|
||||
$marksoptions = [
|
||||
question_display_options::HIDDEN => get_string('notshown', 'question'),
|
||||
question_display_options::MAX_ONLY => get_string('showmaxmarkonly', 'question'),
|
||||
question_display_options::MARK_AND_MAX => get_string('showmarkandmax', 'question'),
|
||||
];
|
||||
$mform->addElement('select', 'marks', get_string('marks', 'question'), $marksoptions);
|
||||
|
||||
$mform->addElement('select', 'markdp', get_string('decimalplacesingrades', 'question'),
|
||||
question_engine::get_dp_options());
|
||||
|
||||
$mform->addElement('select', 'feedback',
|
||||
get_string('specificfeedback', 'question'), $hiddenorvisible);
|
||||
|
||||
$mform->addElement('select', 'generalfeedback',
|
||||
get_string('generalfeedback', 'question'), $hiddenorvisible);
|
||||
|
||||
$mform->addElement('select', 'rightanswer',
|
||||
get_string('rightanswer', 'question'), $hiddenorvisible);
|
||||
|
||||
$mform->addElement('select', 'history',
|
||||
get_string('responsehistory', 'question'), $hiddenorvisible);
|
||||
|
||||
$mform->addElement('submit', 'saveupdate',
|
||||
get_string('updatedisplayoptions', 'question'));
|
||||
}
|
||||
|
||||
}
|
250
question/bank/previewquestion/classes/helper.php
Normal file
250
question/bank/previewquestion/classes/helper.php
Normal file
@ -0,0 +1,250 @@
|
||||
<?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 qbank_previewquestion;
|
||||
|
||||
use context;
|
||||
use moodle_url;
|
||||
use question_display_options;
|
||||
use question_engine;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class helper contains all the helper functions.
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright 2010 The Open University
|
||||
* @author 2021 Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class helper {
|
||||
|
||||
/**
|
||||
* Called via pluginfile.php -> question_pluginfile to serve files belonging to
|
||||
* a question in a question_attempt when that attempt is a preview.
|
||||
*
|
||||
* @param stdClass $course course settings object
|
||||
* @param stdClass $context context object
|
||||
* @param string $component the name of the component we are serving files for.
|
||||
* @param string $filearea the name of the file area.
|
||||
* @param int $qubaid the question_usage this image belongs to.
|
||||
* @param int $slot the relevant slot within the usage.
|
||||
* @param array $args the remaining bits of the file path.
|
||||
* @param bool $forcedownload whether the user must be forced to download the file.
|
||||
* @param array $fileoptions
|
||||
* @return void false if file not found, does not return if found - justsend the file
|
||||
*/
|
||||
public static function question_preview_question_pluginfile($course, $context, $component,
|
||||
$filearea, $qubaid, $slot, $args, $forcedownload, $fileoptions): void {
|
||||
global $USER, $DB, $CFG;
|
||||
|
||||
list($context, $course, $cm) = get_context_info_array($context->id);
|
||||
require_login($course, false, $cm);
|
||||
|
||||
$quba = question_engine::load_questions_usage_by_activity($qubaid);
|
||||
|
||||
if (!question_has_capability_on($quba->get_question($slot, false), 'use')) {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
$options = new question_display_options();
|
||||
$options->feedback = question_display_options::VISIBLE;
|
||||
$options->numpartscorrect = question_display_options::VISIBLE;
|
||||
$options->generalfeedback = question_display_options::VISIBLE;
|
||||
$options->rightanswer = question_display_options::VISIBLE;
|
||||
$options->manualcomment = question_display_options::VISIBLE;
|
||||
$options->history = question_display_options::VISIBLE;
|
||||
if (!$quba->check_file_access($slot, $options, $component,
|
||||
$filearea, $args, $forcedownload)) {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
$fs = get_file_storage();
|
||||
$relativepath = implode('/', $args);
|
||||
$fullpath = "/{$context->id}/{$component}/{$filearea}/{$relativepath}";
|
||||
if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
send_stored_file($file, 0, 0, $forcedownload, $fileoptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* The the URL to use for actions relating to this preview.
|
||||
*
|
||||
* @param int $questionid the question being previewed.
|
||||
* @param int $qubaid the id of the question usage for this preview.
|
||||
* @param question_preview_options $options the options in use.
|
||||
* @param context $context
|
||||
* @param moodle_url $returnurl
|
||||
* @return moodle_url
|
||||
*/
|
||||
public static function question_preview_action_url($questionid, $qubaid,
|
||||
question_preview_options $options, $context, $returnurl = null): moodle_url {
|
||||
$params = [
|
||||
'id' => $questionid,
|
||||
'previewid' => $qubaid,
|
||||
];
|
||||
if ($context->contextlevel == CONTEXT_MODULE) {
|
||||
$params['cmid'] = $context->instanceid;
|
||||
} else if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
$params['courseid'] = $context->instanceid;
|
||||
}
|
||||
if ($returnurl !== null) {
|
||||
$params['returnurl'] = $returnurl;
|
||||
}
|
||||
$params = array_merge($params, $options->get_url_params());
|
||||
return new moodle_url('/question/bank/previewquestion/preview.php', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* The the URL to use for actions relating to this preview.
|
||||
* @param int $questionid the question being previewed.
|
||||
* @param context $context the current moodle context.
|
||||
* @param int $previewid optional previewid to sign post saved previewed answers.
|
||||
* @param moodle_url $returnurl
|
||||
* @return moodle_url
|
||||
*/
|
||||
public static function question_preview_form_url($questionid, $context, $previewid = null, $returnurl = null): moodle_url {
|
||||
$params = [
|
||||
'id' => $questionid,
|
||||
];
|
||||
if ($context->contextlevel == CONTEXT_MODULE) {
|
||||
$params['cmid'] = $context->instanceid;
|
||||
} else if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
$params['courseid'] = $context->instanceid;
|
||||
}
|
||||
if ($previewid) {
|
||||
$params['previewid'] = $previewid;
|
||||
}
|
||||
if ($returnurl !== null) {
|
||||
$params['returnurl'] = $returnurl;
|
||||
}
|
||||
return new moodle_url('/question/bank/previewquestion/preview.php', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the current preview, if any, and redirect to start a new preview.
|
||||
* @param int $previewid
|
||||
* @param int $questionid
|
||||
* @param object $displayoptions
|
||||
* @param object $context
|
||||
* @param moodle_url $returnurl
|
||||
*/
|
||||
public static function restart_preview($previewid, $questionid, $displayoptions, $context, $returnurl = null): void {
|
||||
global $DB;
|
||||
|
||||
if ($previewid) {
|
||||
$transaction = $DB->start_delegated_transaction();
|
||||
question_engine::delete_questions_usage_by_activity($previewid);
|
||||
$transaction->allow_commit();
|
||||
}
|
||||
redirect(self::question_preview_url($questionid, $displayoptions->behaviour,
|
||||
$displayoptions->maxmark, $displayoptions, $displayoptions->variant, $context, $returnurl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the URL for starting a new preview of a given question with the given options.
|
||||
* @param integer $questionid the question to preview.
|
||||
* @param string $preferredbehaviour the behaviour to use for the preview.
|
||||
* @param float $maxmark the maximum to mark the question out of.
|
||||
* @param question_display_options $displayoptions the display options to use.
|
||||
* @param int $variant the variant of the question to preview. If null, one will
|
||||
* be picked randomly.
|
||||
* @param object $context context to run the preview in (affects things like
|
||||
* filter settings, theme, lang, etc.) Defaults to $PAGE->context.
|
||||
* @param moodle_url $returnurl
|
||||
* @return moodle_url the URL.
|
||||
*/
|
||||
public static function question_preview_url($questionid, $preferredbehaviour = null,
|
||||
$maxmark = null, $displayoptions = null, $variant = null, $context = null, $returnurl = null): moodle_url {
|
||||
|
||||
$params = ['id' => $questionid];
|
||||
|
||||
if (is_null($context)) {
|
||||
global $PAGE;
|
||||
$context = $PAGE->context;
|
||||
}
|
||||
if ($context->contextlevel == CONTEXT_MODULE) {
|
||||
$params['cmid'] = $context->instanceid;
|
||||
} else if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
$params['courseid'] = $context->instanceid;
|
||||
}
|
||||
|
||||
if (!is_null($preferredbehaviour)) {
|
||||
$params['behaviour'] = $preferredbehaviour;
|
||||
}
|
||||
|
||||
if (!is_null($maxmark)) {
|
||||
$params['maxmark'] = format_float($maxmark, -1);
|
||||
}
|
||||
|
||||
if (!is_null($displayoptions)) {
|
||||
$params['correctness'] = $displayoptions->correctness;
|
||||
$params['marks'] = $displayoptions->marks;
|
||||
$params['markdp'] = $displayoptions->markdp;
|
||||
$params['feedback'] = (bool) $displayoptions->feedback;
|
||||
$params['generalfeedback'] = (bool) $displayoptions->generalfeedback;
|
||||
$params['rightanswer'] = (bool) $displayoptions->rightanswer;
|
||||
$params['history'] = (bool) $displayoptions->history;
|
||||
}
|
||||
|
||||
if (!is_null($returnurl)) {
|
||||
$params['returnurl'] = $returnurl;
|
||||
}
|
||||
|
||||
if ($variant) {
|
||||
$params['variant'] = $variant;
|
||||
}
|
||||
|
||||
return new moodle_url('/question/bank/previewquestion/preview.php', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Popup params for the question preview.
|
||||
* @return array that can be passed as $params to the {@see popup_action} constructor.
|
||||
*/
|
||||
public static function question_preview_popup_params(): array {
|
||||
return [
|
||||
'height' => 600,
|
||||
'width' => 800,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extra elements for preview from qbank plugins.
|
||||
*
|
||||
* @param \question_definition $question
|
||||
* @param int $courseid
|
||||
* @return array
|
||||
*/
|
||||
public static function get_preview_extra_elements(\question_definition $question, int $courseid): array {
|
||||
$plugintype = 'qbank';
|
||||
$functionname = 'preview_display';
|
||||
$extrahtml = [];
|
||||
$comment = '';
|
||||
$plugins = get_plugin_list_with_function($plugintype, $functionname);
|
||||
foreach ($plugins as $componentname => $plugin) {
|
||||
$pluginhtml = component_callback($componentname, $functionname, [$question, $courseid]);
|
||||
if ($componentname === 'qbank_comment') {
|
||||
$comment = $pluginhtml;
|
||||
continue;
|
||||
}
|
||||
$extrahtml[] = $pluginhtml;
|
||||
}
|
||||
return [$comment, $extrahtml];
|
||||
}
|
||||
}
|
68
question/bank/previewquestion/classes/output/renderer.php
Normal file
68
question/bank/previewquestion/classes/output/renderer.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace qbank_previewquestion\output;
|
||||
|
||||
use context;
|
||||
use qbank_previewquestion\helper;
|
||||
|
||||
/**
|
||||
* Class renderer for rendering preview url
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright 2009 The Open University
|
||||
* @author 2021 Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class renderer extends \plugin_renderer_base {
|
||||
|
||||
/**
|
||||
* Render an icon, optionally with the word 'Preview' beside it, to preview a given question.
|
||||
*
|
||||
* @param int $questionid the id of the question to be previewed.
|
||||
* @param context $context the context in which the preview is happening.
|
||||
* Must be a course or category context.
|
||||
* @param bool $showlabel if true, show the word 'Preview' after the icon.
|
||||
* If false, just show the icon.
|
||||
*/
|
||||
public function question_preview_link($questionid, context $context, $showlabel) {
|
||||
if ($showlabel) {
|
||||
$alt = '';
|
||||
$label = get_string('preview');
|
||||
$attributes = [];
|
||||
} else {
|
||||
$alt = get_string('preview');
|
||||
$label = '';
|
||||
$attributes = ['title' => $alt];
|
||||
}
|
||||
|
||||
$image = $this->pix_icon('t/preview', $alt, '', ['class' => 'iconsmall']);
|
||||
$link = helper::question_preview_url($questionid, null, null, null, null, $context);
|
||||
$action = new \popup_action('click', $link, 'questionpreview', helper::question_preview_popup_params());
|
||||
|
||||
return $this->action_link($link, $image . $label, $action, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the preview page.
|
||||
*
|
||||
* @param array $previewdata
|
||||
*/
|
||||
public function render_preview_page($previewdata) {
|
||||
return $this->render_from_template('qbank_previewquestion/preview_question', $previewdata);
|
||||
}
|
||||
|
||||
}
|
34
question/bank/previewquestion/classes/plugin_feature.php
Normal file
34
question/bank/previewquestion/classes/plugin_feature.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?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 qbank_previewquestion;
|
||||
|
||||
/**
|
||||
* Class columns is the entrypoint for the columns.
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class plugin_feature extends \core_question\local\bank\plugin_features_base{
|
||||
|
||||
public function get_question_columns($qbank): array {
|
||||
return [
|
||||
new preview_action_column($qbank)
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
<?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 qbank_previewquestion;
|
||||
|
||||
use core_question\local\bank\menu_action_column_base;
|
||||
|
||||
/**
|
||||
* Question bank columns for the preview action icon.
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright 2009 Tim Hunt
|
||||
* @author 2021 Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class preview_action_column extends menu_action_column_base {
|
||||
|
||||
/**
|
||||
* @var string store this lang string for performance.
|
||||
*/
|
||||
protected $strpreview;
|
||||
|
||||
public function init(): void {
|
||||
parent::init();
|
||||
$this->strpreview = get_string('preview');
|
||||
}
|
||||
|
||||
public function get_name(): string {
|
||||
return 'previewaction';
|
||||
}
|
||||
|
||||
protected function get_url_icon_and_label(\stdClass $question): array {
|
||||
if (!\question_bank::is_qtype_installed($question->qtype)) {
|
||||
// It sometimes happens that people end up with junk questions
|
||||
// in their question bank of a type that is no longer installed.
|
||||
// We cannot do most actions on them, because that leads to errors.
|
||||
return [null, null, null];
|
||||
}
|
||||
|
||||
if (question_has_capability_on($question, 'use')) {
|
||||
$context = $this->qbank->get_most_specific_context();
|
||||
$url = helper::question_preview_url($question->id, null, null,
|
||||
null, null, $context, $this->qbank->returnurl);
|
||||
return [$url, 't/preview', $this->strpreview];
|
||||
} else {
|
||||
return [null, null, null];
|
||||
}
|
||||
}
|
||||
}
|
32
question/bank/previewquestion/classes/privacy/provider.php
Normal file
32
question/bank/previewquestion/classes/privacy/provider.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?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 qbank_previewquestion\privacy;
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for qbank_previewquestion implementing null_provider.
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements \core_privacy\local\metadata\null_provider {
|
||||
|
||||
public static function get_reason(): string {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
<?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 qbank_previewquestion;
|
||||
|
||||
use question_display_options;
|
||||
|
||||
/**
|
||||
* Displays question preview options as default and set the options.
|
||||
*
|
||||
* Setting default, getting and setting user preferences in question preview options.
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright 2010 The Open University
|
||||
* @author 2021 Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class question_preview_options extends question_display_options {
|
||||
|
||||
/** @var string the behaviour to use for this preview. */
|
||||
public $behaviour;
|
||||
|
||||
/** @var number the maximum mark to use for this preview. */
|
||||
public $maxmark;
|
||||
|
||||
/** @var int the variant of the question to preview. */
|
||||
public $variant;
|
||||
|
||||
/** @var string prefix to append to field names to get user_preference names. */
|
||||
const OPTIONPREFIX = 'question_preview_options_';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param \stdClass $question
|
||||
*/
|
||||
public function __construct($question) {
|
||||
$this->behaviour = 'deferredfeedback';
|
||||
$this->maxmark = $question->defaultmark;
|
||||
$this->variant = null;
|
||||
$this->correctness = self::VISIBLE;
|
||||
$this->marks = self::MARK_AND_MAX;
|
||||
$this->markdp = get_config('quiz', 'decimalpoints');
|
||||
$this->feedback = self::VISIBLE;
|
||||
$this->numpartscorrect = $this->feedback;
|
||||
$this->generalfeedback = self::VISIBLE;
|
||||
$this->rightanswer = self::VISIBLE;
|
||||
$this->history = self::HIDDEN;
|
||||
$this->flags = self::HIDDEN;
|
||||
$this->manualcomment = self::HIDDEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Names of the options we store in the user preferences table.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_user_pref_fields(): array {
|
||||
return ['behaviour', 'correctness', 'marks', 'markdp', 'feedback', 'generalfeedback', 'rightanswer', 'history'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Names and param types of the options we read from the request.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_field_types(): array {
|
||||
return [
|
||||
'behaviour' => PARAM_ALPHA,
|
||||
'maxmark' => PARAM_LOCALISEDFLOAT,
|
||||
'variant' => PARAM_INT,
|
||||
'correctness' => PARAM_BOOL,
|
||||
'marks' => PARAM_INT,
|
||||
'markdp' => PARAM_INT,
|
||||
'feedback' => PARAM_BOOL,
|
||||
'generalfeedback' => PARAM_BOOL,
|
||||
'rightanswer' => PARAM_BOOL,
|
||||
'history' => PARAM_BOOL,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the value of the options from the user_preferences table.
|
||||
*/
|
||||
public function load_user_defaults(): void {
|
||||
$defaults = get_config('question_preview');
|
||||
foreach ($this->get_user_pref_fields() as $field) {
|
||||
$this->$field = get_user_preferences(
|
||||
self::OPTIONPREFIX . $field, $defaults->$field);
|
||||
}
|
||||
$this->numpartscorrect = $this->feedback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a change to the user's preview options to the database.
|
||||
* @param object $newoptions
|
||||
*/
|
||||
public function save_user_preview_options($newoptions): void {
|
||||
foreach ($this->get_user_pref_fields() as $field) {
|
||||
if (isset($newoptions->$field)) {
|
||||
set_user_preference(self::OPTIONPREFIX . $field, $newoptions->$field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of any fields included in the request.
|
||||
*/
|
||||
public function set_from_request(): void {
|
||||
foreach ($this->get_field_types() as $field => $type) {
|
||||
$this->$field = optional_param($field, $this->$field, $type);
|
||||
}
|
||||
$this->numpartscorrect = $this->feedback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters needed in the URL when continuing this preview.
|
||||
*
|
||||
* @return array URL fragment.
|
||||
*/
|
||||
public function get_url_params(): array {
|
||||
$params = [];
|
||||
foreach ($this->get_field_types() as $field => $notused) {
|
||||
if ($field === 'behaviour' || $field === 'maxmark' || is_null($this->$field)) {
|
||||
continue;
|
||||
}
|
||||
$params[$field] = $this->$field;
|
||||
}
|
||||
return $params;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Strings for component qbank_previewquestion, language 'en'
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['pluginname'] = 'Preview question';
|
||||
$string['privacy:metadata'] = 'Preview question plugin does not store any user data.';
|
315
question/bank/previewquestion/preview.php
Normal file
315
question/bank/previewquestion/preview.php
Normal file
@ -0,0 +1,315 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* This page displays a preview of a question
|
||||
*
|
||||
* The preview uses the option settings from the activity within which the question
|
||||
* is previewed or the default settings if no activity is specified. The question session
|
||||
* information is stored in the session as an array of subsequent states rather
|
||||
* than in the database.
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright Alex Smith {@link http://maths.york.ac.uk/serving_maths}
|
||||
* @author 2021 Safat Shahin <safatshahin@catalyst-au.net> and numerous contributors.
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(__DIR__ . '/../../../config.php');
|
||||
require_once($CFG->libdir . '/questionlib.php');
|
||||
|
||||
use qbank_previewquestion\form\preview_options_form;
|
||||
use qbank_previewquestion\question_preview_options;
|
||||
use qbank_previewquestion\helper;
|
||||
|
||||
/**
|
||||
* The maximum number of variants previewable. If there are more variants than this for a question
|
||||
* then we only allow the selection of the first x variants.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
define('QUESTION_PREVIEW_MAX_VARIANTS', 100);
|
||||
|
||||
\core_question\local\bank\helper::require_plugin_enabled('qbank_previewquestion');
|
||||
|
||||
// Get and validate question id.
|
||||
$id = required_param('id', PARAM_INT);
|
||||
$returnurl = optional_param('returnurl', null, PARAM_RAW);
|
||||
$question = question_bank::load_question($id);
|
||||
|
||||
if ($returnurl) {
|
||||
$returnurl = new moodle_url($returnurl);
|
||||
}
|
||||
|
||||
// Were we given a particular context to run the question in?
|
||||
// This affects things like filter settings, or forced theme or language.
|
||||
if ($cmid = optional_param('cmid', 0, PARAM_INT)) {
|
||||
$cm = get_coursemodule_from_id(false, $cmid);
|
||||
require_login($cm->course, false, $cm);
|
||||
$context = context_module::instance($cmid);
|
||||
|
||||
} else if ($courseid = optional_param('courseid', 0, PARAM_INT)) {
|
||||
require_login($courseid);
|
||||
$context = context_course::instance($courseid);
|
||||
|
||||
} else {
|
||||
require_login();
|
||||
$category = $DB->get_record('question_categories', ['id' => $question->category], '*', MUST_EXIST);
|
||||
$context = context::instance_by_id($category->contextid);
|
||||
$PAGE->set_context($context);
|
||||
// Note that in the other cases, require_login will set the correct page context.
|
||||
}
|
||||
question_require_capability_on($question, 'use');
|
||||
$PAGE->set_pagelayout('popup');
|
||||
|
||||
// Get and validate display options.
|
||||
$maxvariant = min($question->get_num_variants(), QUESTION_PREVIEW_MAX_VARIANTS);
|
||||
$options = new question_preview_options($question);
|
||||
$options->load_user_defaults();
|
||||
$options->set_from_request();
|
||||
$PAGE->set_url(helper::question_preview_url($id, $options->behaviour, $options->maxmark,
|
||||
$options, $options->variant, $context));
|
||||
|
||||
// Get and validate existing preview, or start a new one.
|
||||
$previewid = optional_param('previewid', 0, PARAM_INT);
|
||||
|
||||
if ($previewid) {
|
||||
try {
|
||||
$quba = question_engine::load_questions_usage_by_activity($previewid);
|
||||
|
||||
} catch (Exception $e) {
|
||||
// This may not seem like the right error message to display, but
|
||||
// actually from the user point of view, it makes sense.
|
||||
throw new moodle_exception('submissionoutofsequencefriendlymessage', 'question',
|
||||
helper::question_preview_url($question->id, $options->behaviour,
|
||||
$options->maxmark, $options, $options->variant, $context), null, $e);
|
||||
}
|
||||
|
||||
if ($quba->get_owning_context()->instanceid != $USER->id) {
|
||||
throw new moodle_exception('notyourpreview', 'question');
|
||||
}
|
||||
|
||||
$slot = $quba->get_first_question_number();
|
||||
$usedquestion = $quba->get_question($slot, false);
|
||||
if ($usedquestion->id != $question->id) {
|
||||
throw new moodle_exception('questionidmismatch', 'question');
|
||||
}
|
||||
$question = $usedquestion;
|
||||
$options->variant = $quba->get_variant($slot);
|
||||
|
||||
} else {
|
||||
$quba = question_engine::make_questions_usage_by_activity(
|
||||
'core_question_preview', context_user::instance($USER->id));
|
||||
$quba->set_preferred_behaviour($options->behaviour);
|
||||
$slot = $quba->add_question($question, $options->maxmark);
|
||||
|
||||
if ($options->variant) {
|
||||
$options->variant = min($maxvariant, max(1, $options->variant));
|
||||
} else {
|
||||
$options->variant = rand(1, $maxvariant);
|
||||
}
|
||||
|
||||
$quba->start_question($slot, $options->variant);
|
||||
|
||||
$transaction = $DB->start_delegated_transaction();
|
||||
question_engine::save_questions_usage_by_activity($quba);
|
||||
$transaction->allow_commit();
|
||||
}
|
||||
$options->behaviour = $quba->get_preferred_behaviour();
|
||||
$options->maxmark = $quba->get_question_max_mark($slot);
|
||||
|
||||
// Create the settings form, and initialise the fields.
|
||||
$optionsform = new preview_options_form(helper::question_preview_form_url($question->id, $context, $previewid, $returnurl),
|
||||
['quba' => $quba, 'maxvariant' => $maxvariant]);
|
||||
$optionsform->set_data($options);
|
||||
|
||||
// Process change of settings, if that was requested.
|
||||
if ($newoptions = $optionsform->get_submitted_data()) {
|
||||
// Set user preferences.
|
||||
$options->save_user_preview_options($newoptions);
|
||||
if (!isset($newoptions->variant)) {
|
||||
$newoptions->variant = $options->variant;
|
||||
}
|
||||
if (isset($newoptions->saverestart)) {
|
||||
helper::restart_preview($previewid, $question->id, $newoptions, $context, $returnurl);
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare a URL that is used in various places.
|
||||
$actionurl = helper::question_preview_action_url($question->id, $quba->get_id(), $options, $context, $returnurl);
|
||||
|
||||
// Process any actions from the buttons at the bottom of the form.
|
||||
if (data_submitted() && confirm_sesskey()) {
|
||||
|
||||
try {
|
||||
|
||||
if (optional_param('restart', false, PARAM_BOOL)) {
|
||||
helper::restart_preview($previewid, $question->id, $options, $context, $returnurl);
|
||||
|
||||
} else if (optional_param('fill', null, PARAM_BOOL)) {
|
||||
$correctresponse = $quba->get_correct_response($slot);
|
||||
if (!is_null($correctresponse)) {
|
||||
$quba->process_action($slot, $correctresponse);
|
||||
|
||||
$transaction = $DB->start_delegated_transaction();
|
||||
question_engine::save_questions_usage_by_activity($quba);
|
||||
$transaction->allow_commit();
|
||||
}
|
||||
redirect($actionurl);
|
||||
|
||||
} else if (optional_param('finish', null, PARAM_BOOL)) {
|
||||
$quba->process_all_actions();
|
||||
$quba->finish_all_questions();
|
||||
|
||||
$transaction = $DB->start_delegated_transaction();
|
||||
question_engine::save_questions_usage_by_activity($quba);
|
||||
$transaction->allow_commit();
|
||||
redirect($actionurl);
|
||||
|
||||
} else {
|
||||
$quba->process_all_actions();
|
||||
|
||||
$transaction = $DB->start_delegated_transaction();
|
||||
question_engine::save_questions_usage_by_activity($quba);
|
||||
$transaction->allow_commit();
|
||||
|
||||
$scrollpos = optional_param('scrollpos', '', PARAM_RAW);
|
||||
if ($scrollpos !== '') {
|
||||
$actionurl->param('scrollpos', (int) $scrollpos);
|
||||
}
|
||||
redirect($actionurl);
|
||||
}
|
||||
|
||||
} catch (question_out_of_sequence_exception $e) {
|
||||
throw new moodle_exception('submissionoutofsequencefriendlymessage', 'question', $actionurl);
|
||||
|
||||
} catch (Exception $e) {
|
||||
// This sucks, if we display our own custom error message, there is no way
|
||||
// to display the original stack trace.
|
||||
$debuginfo = '';
|
||||
if (!empty($e->debuginfo)) {
|
||||
$debuginfo = $e->debuginfo;
|
||||
}
|
||||
throw new moodle_exception('errorprocessingresponses', 'question', $actionurl,
|
||||
$e->getMessage(), $debuginfo);
|
||||
}
|
||||
}
|
||||
|
||||
if ($question->length) {
|
||||
$displaynumber = '1';
|
||||
} else {
|
||||
$displaynumber = 'i';
|
||||
}
|
||||
$restartdisabled = [];
|
||||
$finishdisabled = [];
|
||||
$filldisabled = [];
|
||||
if ($quba->get_question_state($slot)->is_finished()) {
|
||||
$finishdisabled = ['disabled' => 'disabled'];
|
||||
$filldisabled = ['disabled' => 'disabled'];
|
||||
}
|
||||
// If question type cannot give us a correct response, disable this button.
|
||||
if (is_null($quba->get_correct_response($slot))) {
|
||||
$filldisabled = ['disabled' => 'disabled'];
|
||||
}
|
||||
if (!$previewid) {
|
||||
$restartdisabled = ['disabled' => 'disabled'];
|
||||
}
|
||||
|
||||
// Prepare technical info to be output.
|
||||
$qa = $quba->get_question_attempt($slot);
|
||||
$technical = [];
|
||||
$technical[] = get_string('behaviourbeingused', 'question',
|
||||
question_engine::get_behaviour_name($qa->get_behaviour_name()));
|
||||
$technical[] = get_string('technicalinfominfraction', 'question', $qa->get_min_fraction());
|
||||
$technical[] = get_string('technicalinfomaxfraction', 'question', $qa->get_max_fraction());
|
||||
$technical[] = get_string('technicalinfovariant', 'question', $qa->get_variant());
|
||||
$technical[] = get_string('technicalinfoquestionsummary', 'question', s($qa->get_question_summary()));
|
||||
$technical[] = get_string('technicalinforightsummary', 'question', s($qa->get_right_answer_summary()));
|
||||
$technical[] = get_string('technicalinforesponsesummary', 'question', s($qa->get_response_summary()));
|
||||
$technical[] = get_string('technicalinfostate', 'question', '' . $qa->get_state());
|
||||
|
||||
// Start output.
|
||||
$title = get_string('previewquestion', 'question', format_string($question->name));
|
||||
$headtags = question_engine::initialise_js() . $quba->render_question_head_html($slot);
|
||||
$PAGE->set_title($title);
|
||||
$PAGE->set_heading($title);
|
||||
echo $OUTPUT->header();
|
||||
|
||||
$previewdata = [];
|
||||
$previewdata['actionurl'] = $actionurl;
|
||||
$previewdata['session'] = sesskey();
|
||||
$previewdata['slot'] = $slot;
|
||||
// Output of the question.
|
||||
$previewdata['question'] = $quba->render_question($slot, $options, $displaynumber);
|
||||
$previewdata['restartdisabled'] = html_writer::attributes($restartdisabled);
|
||||
$previewdata['finishdisabled'] = html_writer::attributes($finishdisabled);
|
||||
$previewdata['filldisabled'] = html_writer::attributes($filldisabled);
|
||||
// Output the technical info.
|
||||
$previewdata['techinfo'] = print_collapsible_region_start('', 'techinfo', get_string('technicalinfo', 'question'),
|
||||
'core_question_preview_techinfo_collapsed', true, true, $OUTPUT->help_icon('technicalinfo', 'question'));
|
||||
foreach ($technical as $info) {
|
||||
$previewdata['techinfo'] .= html_writer::tag('p', $info, ['class' => 'notifytiny']);
|
||||
}
|
||||
$previewdata['techinfo'] .= print_collapsible_region_end(true);
|
||||
|
||||
// Output a link to export this single question.
|
||||
if (question_has_capability_on($question, 'view')) {
|
||||
if (class_exists('qbank_exporttoxml\\exporttoxml_helper')) {
|
||||
if (\core\plugininfo\qbank::is_plugin_enabled('qbank_exporttoxml')) {
|
||||
$exportfunction = '\\qbank_exporttoxml\\exporttoxml_helper::question_get_export_single_question_url';
|
||||
$previewdata['exporttoxml'] = html_writer::link($exportfunction($question),
|
||||
get_string('exportonequestion', 'question'));
|
||||
}
|
||||
} else {
|
||||
$exportfunction = 'question_get_export_single_question_url';
|
||||
$previewdata['exporttoxml'] = html_writer::link($exportfunction($question),
|
||||
get_string('exportonequestion', 'question'));
|
||||
}
|
||||
}
|
||||
|
||||
// Display the settings form.
|
||||
$previewdata['options'] = $optionsform->render();
|
||||
|
||||
list($comment, $extraelements) = helper::get_preview_extra_elements($question, $COURSE->id);
|
||||
|
||||
if (!empty($comment)) {
|
||||
$previewdata['comments'] = $comment;
|
||||
}
|
||||
|
||||
if (!empty($extraelements)) {
|
||||
$elements = [];
|
||||
foreach ($extraelements as $extraelement) {
|
||||
$element = new stdClass();
|
||||
$element->extrapreviewelements = $extraelement;
|
||||
$elements[] = $element;
|
||||
}
|
||||
$previewdata['extrapreviewelements'] = $elements;
|
||||
}
|
||||
|
||||
$previewdata['redirect'] = false;
|
||||
if (!is_null($returnurl)) {
|
||||
$previewdata['redirect'] = true;
|
||||
$previewdata['redirecturl'] = $returnurl;
|
||||
}
|
||||
|
||||
echo $PAGE->get_renderer('qbank_previewquestion')->render_preview_page($previewdata);
|
||||
|
||||
// Log the preview of this question.
|
||||
$event = \core\event\question_viewed::create_from_question_instance($question, $context);
|
||||
$event->trigger();
|
||||
|
||||
$PAGE->requires->js_call_amd('qbank_previewquestion/preview', 'init', [$previewdata['redirect']]);
|
||||
echo $OUTPUT->footer();
|
@ -0,0 +1,89 @@
|
||||
{{!
|
||||
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 qbank_previewquestion/preview_question
|
||||
|
||||
The preview page for the question type preview.
|
||||
* actionurl - Url to post to
|
||||
* session - Moodle session
|
||||
* slot - The identifying number of the first question that was added to this usage
|
||||
* question - The html of the actual question from the engine
|
||||
* restartdisabled - The attributes to enable or disable the button, same for finishdisabled and filldisabled
|
||||
* techinfo - Technical information like fraction, state, behaviour etc
|
||||
* exporttoxml - Link to export the question to xml
|
||||
* redirecturl - Url to the base view
|
||||
* comments - Comments api html
|
||||
* extrapreviewelements - Any plugin implementing the callback and sending extra html to view something in the preview page
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"previewdata": [
|
||||
{
|
||||
"actionurl": "/",
|
||||
"session": "E2PwCfrnzz",
|
||||
"slot": "1",
|
||||
"question": "<div>question html</div>",
|
||||
"restartdisabled": "disabled='disabled'",
|
||||
"finishdisabled": "disabled='disabled'",
|
||||
"filldisabled": "disabled='disabled'",
|
||||
"techinfo": "<div>Behaviour being used: Deferred feedback</div>",
|
||||
"redirecturl": "/",
|
||||
"exporttoxml": "Download this question in Moodle XML format",
|
||||
"comments": "html from comments api",
|
||||
"extrapreviewelements": "<div>callback to get html from plugins need to show info in preview</div>"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
<form id="responseform" method="post" action="{{{actionurl}}}" enctype="multipart/form-data" autocomplete="off">
|
||||
<div>
|
||||
<input type="hidden" name="sesskey" value="{{session}}">
|
||||
<input type="hidden" name="slots" value="{{slot}}">
|
||||
<input type="hidden" name="scrollpos" value="" id="scrollpos">
|
||||
</div>
|
||||
{{{question}}}
|
||||
<div id="previewcontrols" class="controls input-group">
|
||||
<input type="submit" name="restart" value="{{#str}} restart, question{{/str}}" class="btn btn-secondary" {{{restartdisabled}}}>
|
||||
<input type="submit" name="save" value="{{#str}} save, question{{/str}}" class="btn btn-secondary" {{{finishdisabled}}}>
|
||||
<input type="submit" name="fill" value="{{#str}} fillincorrect, question{{/str}}" class="btn btn-secondary" {{{filldisabled}}}>
|
||||
<input type="submit" name="finish" value="{{#str}} submitandfinish, question{{/str}}" class="btn btn-secondary" {{{finishdisabled}}}>
|
||||
{{^redirect}}
|
||||
<input type="button" name="close" value="{{#str}} closepreview, question{{/str}}" class="btn btn-secondary" id="close-previewquestion-page">
|
||||
{{/redirect}}
|
||||
{{#redirect}}
|
||||
<a href="{{{redirecturl}}}" class="btn btn-secondary">{{#str}} closepreview, question{{/str}}</a>
|
||||
{{/redirect}}
|
||||
</div>
|
||||
</form>
|
||||
{{{techinfo}}}
|
||||
{{{exporttoxml}}}
|
||||
{{#comments}}
|
||||
<div class="row">
|
||||
<div class="col-6 text-left">
|
||||
{{{options}}}
|
||||
</div>
|
||||
<div class="col-6 question-comment-view">
|
||||
{{{comments}}}
|
||||
</div>
|
||||
</div>
|
||||
{{/comments}}
|
||||
{{^comments}}
|
||||
{{{options}}}
|
||||
{{/comments}}
|
||||
{{#extrapreviewelements}}
|
||||
{{{extrapreviewelements}}}
|
||||
{{/extrapreviewelements}}
|
@ -1,4 +1,4 @@
|
||||
@core @core_question @javascript @_switch_window
|
||||
@qbank @qbank_previewquestion @javascript
|
||||
Feature: A teacher can preview questions in the question bank
|
||||
In order to ensure the questions are properly created
|
||||
As a teacher
|
||||
@ -11,6 +11,9 @@ Feature: A teacher can preview questions in the question bank
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | format |
|
||||
| Course 1 | C1 | weeks |
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber |
|
||||
| quiz | Test quiz | C1 | quiz1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
@ -21,10 +24,9 @@ Feature: A teacher can preview questions in the question bank
|
||||
| questioncategory | qtype | name |
|
||||
| Test questions | numerical | Test question to be previewed |
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I am on the "Test quiz" "quiz activity" page
|
||||
And I navigate to "Question bank > Questions" in current page administration
|
||||
When I choose "Preview" action for "Test question to be previewed" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
|
||||
Scenario: Question preview shows the question and other information
|
||||
Then the state of "What is pi to two d.p.?" question is shown as "Not yet answered"
|
@ -0,0 +1,50 @@
|
||||
@qbank @qbank_previewquestion
|
||||
Feature: Use the qbank plugin manager page for previewquestion
|
||||
In order to check the plugin behaviour with enable and disable
|
||||
|
||||
Background:
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber |
|
||||
| quiz | Test quiz | C1 | quiz1 |
|
||||
And the following "question categories" exist:
|
||||
| contextlevel | reference | name |
|
||||
| Course | C1 | Test questions |
|
||||
And the following "questions" exist:
|
||||
| questioncategory | qtype | name | questiontext |
|
||||
| Test questions | truefalse | First question | Answer the first question |
|
||||
|
||||
@javascript
|
||||
Scenario: Enable/disable previewquestion column from the base view
|
||||
Given I log in as "admin"
|
||||
When I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
|
||||
And I should see "Preview question"
|
||||
And I click on "Disable" "link" in the "Preview 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 click on "#action-menu-toggle-2" "css_element" in the "First question" "table_row"
|
||||
Then I should not see "Preview" 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 "Preview 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 click on "#action-menu-toggle-2" "css_element" in the "First question" "table_row"
|
||||
And I should see "Preview" in the "region-main" "region"
|
||||
|
||||
Scenario: Enable/disable preview button from question edit form
|
||||
Given I log in as "admin"
|
||||
When I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
|
||||
And I should see "Preview question"
|
||||
And I click on "Disable" "link" in the "Preview 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 choose "Edit question" action for "First question" in the question bank
|
||||
Then I should not see "Preview" 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 "Preview 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 choose "Edit question" action for "First question" in the question bank
|
||||
And I should see "Preview" in the "region-main" "region"
|
159
question/bank/previewquestion/tests/helper_test.php
Normal file
159
question/bank/previewquestion/tests/helper_test.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?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 qbank_previewquestion;
|
||||
|
||||
use core\plugininfo\qbank;
|
||||
|
||||
/**
|
||||
* Helper tests for question preview.
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \qbank_previewquestion\helper
|
||||
*/
|
||||
class helper_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* @var bool|\context|\context_course $context
|
||||
*/
|
||||
public $context;
|
||||
|
||||
/**
|
||||
* @var object $questiondata;
|
||||
*/
|
||||
public $questiondata;
|
||||
|
||||
/**
|
||||
* @var \question_usage_by_activity $quba
|
||||
*/
|
||||
public $quba;
|
||||
|
||||
/**
|
||||
* @var question_preview_options $options
|
||||
*/
|
||||
public $options;
|
||||
|
||||
/**
|
||||
* @var \moodle_url $returnurl
|
||||
*/
|
||||
public $returnurl;
|
||||
|
||||
/**
|
||||
* Test set up.
|
||||
*
|
||||
* This is executed before running any test in this file.
|
||||
*/
|
||||
public function setUp(): void {
|
||||
global $USER;
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
$generator = $this->getDataGenerator();
|
||||
$questiongenerator = $generator->get_plugin_generator('core_question');
|
||||
// Create a course.
|
||||
$course = $generator->create_course();
|
||||
$this->context = \context_course::instance($course->id);
|
||||
// Create a question in the default category.
|
||||
$contexts = new \question_edit_contexts($this->context);
|
||||
$cat = question_make_default_categories($contexts->all());
|
||||
$this->questiondata = $questiongenerator->create_question('numerical', null,
|
||||
['name' => 'Example question', 'category' => $cat->id]);
|
||||
$this->quba = \question_engine::make_questions_usage_by_activity('core_question_preview', \context_user::instance($USER->id));
|
||||
$this->options = new question_preview_options($this->questiondata);
|
||||
$this->options->load_user_defaults();
|
||||
$this->options->set_from_request();
|
||||
$this->returnurl = new \moodle_url('/question/edit.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the preview action url from the helper class.
|
||||
*
|
||||
* @covers ::question_preview_action_url
|
||||
*/
|
||||
public function test_question_preview_action_url() {
|
||||
$actionurl = helper::question_preview_action_url($this->questiondata->id, $this->quba->get_id(), $this->options,
|
||||
$this->context, $this->returnurl);
|
||||
$params = [
|
||||
'id' => $this->questiondata->id,
|
||||
'previewid' => $this->quba->get_id(),
|
||||
'returnurl' => $this->returnurl,
|
||||
'courseid' => $this->context->instanceid
|
||||
];
|
||||
$params = array_merge($params, $this->options->get_url_params());
|
||||
$expectedurl = new \moodle_url('/question/bank/previewquestion/preview.php', $params);
|
||||
$this->assertEquals($expectedurl, $actionurl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the preview form url from the helper class.
|
||||
*
|
||||
* @covers ::question_preview_form_url
|
||||
*/
|
||||
public function test_question_preview_form_url() {
|
||||
$formurl = helper::question_preview_form_url($this->questiondata->id, $this->context, $this->quba->get_id(), $this->returnurl);
|
||||
$params = [
|
||||
'id' => $this->questiondata->id,
|
||||
'previewid' => $this->quba->get_id(),
|
||||
'returnurl' => $this->returnurl,
|
||||
'courseid' => $this->context->instanceid
|
||||
];
|
||||
$expectedurl = new \moodle_url('/question/bank/previewquestion/preview.php', $params);
|
||||
$this->assertEquals($expectedurl, $formurl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the preview url from the helper class.
|
||||
*
|
||||
* @covers ::question_preview_url
|
||||
*/
|
||||
public function test_question_preview_url() {
|
||||
$previewurl = helper::question_preview_url($this->questiondata->id, $this->options->behaviour, $this->options->maxmark,
|
||||
$this->options, $this->options->variant, $this->context);
|
||||
$params = [
|
||||
'id' => $this->questiondata->id,
|
||||
'behaviour' => $this->options->behaviour,
|
||||
'maxmark' => $this->options->maxmark,
|
||||
'courseid' => $this->context->instanceid
|
||||
];
|
||||
// Extra params for options.
|
||||
$params['correctness'] = $this->options->correctness;
|
||||
$params['marks'] = $this->options->marks;
|
||||
$params['markdp'] = $this->options->markdp;
|
||||
$params['feedback'] = (bool) $this->options->feedback;
|
||||
$params['generalfeedback'] = (bool) $this->options->generalfeedback;
|
||||
$params['rightanswer'] = (bool) $this->options->rightanswer;
|
||||
$params['history'] = (bool) $this->options->history;
|
||||
$expectedurl = new \moodle_url('/question/bank/previewquestion/preview.php', $params);
|
||||
$this->assertEquals($expectedurl, $previewurl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the preview comment callback if available.
|
||||
*
|
||||
* @covers ::get_preview_extra_elements
|
||||
*/
|
||||
public function test_get_preview_extra_elements() {
|
||||
$question = \question_bank::load_question($this->questiondata->id);
|
||||
list($comment, $extraelements) = helper::get_preview_extra_elements($question, $this->context->instanceid);
|
||||
if (qbank::is_plugin_enabled('qbank_comment')) {
|
||||
$this->assertEquals("<div class='comment-area'>", $comment);
|
||||
} else {
|
||||
$this->assertEquals('', $comment);
|
||||
}
|
||||
}
|
||||
}
|
31
question/bank/previewquestion/version.php
Normal file
31
question/bank/previewquestion/version.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Version information for qbank_previewquestion.
|
||||
*
|
||||
* @package qbank_previewquestion
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->component = 'qbank_previewquestion';
|
||||
$plugin->version = 2021072200;
|
||||
$plugin->requires = 2021052500;
|
||||
$plugin->maturity = MATURITY_STABLE;
|
@ -674,8 +674,13 @@ class view {
|
||||
* Get the URL to preview a question.
|
||||
* @param \stdClass $questiondata the data defining the question.
|
||||
* @return \moodle_url the URL.
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see \qbank_previewquestion\helper::question_preview_url()
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
public function preview_question_url($questiondata) {
|
||||
debugging('Function preview_question_url() has been deprecated and moved to qbank_previewquestion plugin,
|
||||
please use qbank_previewquestion\helper::question_preview_url() instead.', DEBUG_DEVELOPER);
|
||||
return question_preview_url($questiondata->id, null, null, null, null,
|
||||
$this->get_most_specific_context());
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ class_alias('qbank_editquestion\copy_action_column', 'question_bank_copy_action_
|
||||
* @deprecated since Moodle 2.7 MDL-40457
|
||||
* @todo MDl-72004 delete the class alias, not done in MDL-71516 for any potential error from other plugins.
|
||||
*/
|
||||
class_alias('core_question\bank\preview_action_column', 'question_bank_preview_action_column', true);
|
||||
class_alias('qbank_previewquestion\preview_action_column', 'question_bank_preview_action_column', true);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -48,24 +48,19 @@ class core_question_renderer extends plugin_renderer_base {
|
||||
* Must be a course or category context.
|
||||
* @param bool $showlabel if true, show the word 'Preview' after the icon.
|
||||
* If false, just show the icon.
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see qbank_previewquestion\output\renderer
|
||||
* @todo MDL-71679 uncomment the debugging message after implementing the changes in mod_quiz
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
public function question_preview_link($questionid, context $context, $showlabel) {
|
||||
if ($showlabel) {
|
||||
$alt = '';
|
||||
$label = get_string('preview');
|
||||
$attributes = array();
|
||||
} else {
|
||||
$alt = get_string('preview');
|
||||
$label = '';
|
||||
$attributes = array('title' => $alt);
|
||||
}
|
||||
// Debugging message will be re-added after implementing the changes in mod_quiz.
|
||||
// ...debugging('Function question_preview_link() has been deprecated and moved to qbank_previewquestion plugin,
|
||||
// Please use qbank_previewquestion renderer.', DEBUG_DEVELOPER);.
|
||||
|
||||
$image = $this->pix_icon('t/preview', $alt, '', array('class' => 'iconsmall'));
|
||||
$link = question_preview_url($questionid, null, null, null, null, $context);
|
||||
$action = new popup_action('click', $link, 'questionpreview',
|
||||
question_preview_popup_params());
|
||||
|
||||
return $this->action_link($link, $image . $label, $action, $attributes);
|
||||
return $this->page->get_renderer('qbank_previewquestion')->question_preview_link(
|
||||
$questionid, $context, $showlabel
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,7 +69,7 @@ $PAGE->set_pagelayout('popup');
|
||||
|
||||
// Get and validate display options.
|
||||
$maxvariant = min($question->get_num_variants(), QUESTION_PREVIEW_MAX_VARIANTS);
|
||||
$options = new question_preview_options($question);
|
||||
$options = new qbank_previewquestion\question_preview_options($question);
|
||||
$options->load_user_defaults();
|
||||
$options->set_from_request();
|
||||
$PAGE->set_url(question_preview_url($id, $options->behaviour, $options->maxmark,
|
||||
@ -136,7 +136,7 @@ if ($newoptions = $optionsform->get_submitted_data()) {
|
||||
$newoptions->variant = $options->variant;
|
||||
}
|
||||
if (isset($newoptions->saverestart)) {
|
||||
restart_preview($previewid, $question->id, $newoptions, $context);
|
||||
qbank_previewquestion\helper::restart_preview($previewid, $question->id, $newoptions, $context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ if (data_submitted() && confirm_sesskey()) {
|
||||
try {
|
||||
|
||||
if (optional_param('restart', false, PARAM_BOOL)) {
|
||||
restart_preview($previewid, $question->id, $options, $context);
|
||||
qbank_previewquestion\helper::restart_preview($previewid, $question->id, $options, $context);
|
||||
|
||||
} else if (optional_param('fill', null, PARAM_BOOL)) {
|
||||
$correctresponse = $quba->get_correct_response($slot);
|
||||
|
@ -17,7 +17,7 @@
|
||||
/**
|
||||
* Library functions used by question/preview.php.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @package core_question
|
||||
* @subpackage questionengine
|
||||
* @copyright 2010 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
@ -34,9 +34,15 @@ require_once($CFG->libdir . '/formslib.php');
|
||||
*
|
||||
* @copyright 2009 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see qbank_previewquestion\form\preview_options_form
|
||||
* @todo MDL-71679 class renaming
|
||||
*/
|
||||
class preview_options_form extends moodleform {
|
||||
|
||||
public function definition() {
|
||||
debugging('Class preview_options_form has been deprecated and moved to qbank_previewquestion plugin,
|
||||
please use qbank_previewquestion\form\preview_options_form instead.', DEBUG_DEVELOPER);
|
||||
$mform = $this->_form;
|
||||
|
||||
$hiddenofvisible = array(
|
||||
@ -99,11 +105,15 @@ class preview_options_form extends moodleform {
|
||||
|
||||
|
||||
/**
|
||||
* Displays question preview options as default and set the options
|
||||
* Displays question preview options as default and set the options.
|
||||
*
|
||||
* Setting default, getting and setting user preferences in question preview options.
|
||||
*
|
||||
* @copyright 2010 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see qbank_previewquestion\output\question_preview_options
|
||||
* @todo MDL-71679 class renaming
|
||||
*/
|
||||
class question_preview_options extends question_display_options {
|
||||
/** @var string the behaviour to use for this preview. */
|
||||
@ -120,8 +130,11 @@ class question_preview_options extends question_display_options {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param stdClass $question
|
||||
*/
|
||||
public function __construct($question) {
|
||||
debugging('Class question_preview_options has been deprecated and moved to qbank_previewquestion plugin,
|
||||
please use qbank_previewquestion\question_preview_options instead.', DEBUG_DEVELOPER);
|
||||
$this->behaviour = 'deferredfeedback';
|
||||
$this->maxmark = $question->defaultmark;
|
||||
$this->variant = null;
|
||||
@ -228,42 +241,18 @@ class question_preview_options extends question_display_options {
|
||||
* @param int $slot the relevant slot within the usage.
|
||||
* @param array $args the remaining bits of the file path.
|
||||
* @param bool $forcedownload whether the user must be forced to download the file.
|
||||
* @param array $options additional options affecting the file serving
|
||||
* @return bool false if file not found, does not return if found - justsend the file
|
||||
* @param array $fileoptions
|
||||
* @return void false if file not found, does not return if found - justsend the file
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see qbank_previewquestion\helper::question_preview_question_pluginfile()
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
function question_preview_question_pluginfile($course, $context, $component,
|
||||
$filearea, $qubaid, $slot, $args, $forcedownload, $fileoptions) {
|
||||
global $USER, $DB, $CFG;
|
||||
|
||||
list($context, $course, $cm) = get_context_info_array($context->id);
|
||||
require_login($course, false, $cm);
|
||||
|
||||
$quba = question_engine::load_questions_usage_by_activity($qubaid);
|
||||
|
||||
if (!question_has_capability_on($quba->get_question($slot, false), 'use')) {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
$options = new question_display_options();
|
||||
$options->feedback = question_display_options::VISIBLE;
|
||||
$options->numpartscorrect = question_display_options::VISIBLE;
|
||||
$options->generalfeedback = question_display_options::VISIBLE;
|
||||
$options->rightanswer = question_display_options::VISIBLE;
|
||||
$options->manualcomment = question_display_options::VISIBLE;
|
||||
$options->history = question_display_options::VISIBLE;
|
||||
if (!$quba->check_file_access($slot, $options, $component,
|
||||
$filearea, $args, $forcedownload)) {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
$fs = get_file_storage();
|
||||
$relativepath = implode('/', $args);
|
||||
$fullpath = "/{$context->id}/{$component}/{$filearea}/{$relativepath}";
|
||||
if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
send_stored_file($file, 0, 0, $forcedownload, $fileoptions);
|
||||
debugging('Function question_preview_question_pluginfile() has been deprecated and moved to qbank_previewquestion plugin,
|
||||
please use qbank_previewquestion\helper::question_preview_question_pluginfile() instead.', DEBUG_DEVELOPER);
|
||||
qbank_previewquestion\helper::question_preview_question_pluginfile($course, $context,
|
||||
$component, $filearea, $qubaid, $slot, $args, $forcedownload, $fileoptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -271,20 +260,16 @@ function question_preview_question_pluginfile($course, $context, $component,
|
||||
* @param int $questionid the question being previewed.
|
||||
* @param int $qubaid the id of the question usage for this preview.
|
||||
* @param question_preview_options $options the options in use.
|
||||
* @param context $context
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see qbank_previewquestion\helper::question_preview_action_url()
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
function question_preview_action_url($questionid, $qubaid,
|
||||
question_preview_options $options, $context) {
|
||||
$params = array(
|
||||
'id' => $questionid,
|
||||
'previewid' => $qubaid,
|
||||
);
|
||||
if ($context->contextlevel == CONTEXT_MODULE) {
|
||||
$params['cmid'] = $context->instanceid;
|
||||
} else if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
$params['courseid'] = $context->instanceid;
|
||||
}
|
||||
$params = array_merge($params, $options->get_url_params());
|
||||
return new moodle_url('/question/preview.php', $params);
|
||||
debugging('Function question_preview_action_url() has been deprecated and moved to qbank_previewquestion plugin,
|
||||
please use qbank_previewquestion\helper::question_preview_action_url() instead.', DEBUG_DEVELOPER);
|
||||
qbank_previewquestion\helper::question_preview_action_url($questionid, $qubaid, $options, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -292,20 +277,14 @@ function question_preview_action_url($questionid, $qubaid,
|
||||
* @param int $questionid the question being previewed.
|
||||
* @param context $context the current moodle context.
|
||||
* @param int $previewid optional previewid to sign post saved previewed answers.
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see qbank_previewquestion\helper::question_preview_form_url()
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
function question_preview_form_url($questionid, $context, $previewid = null) {
|
||||
$params = array(
|
||||
'id' => $questionid,
|
||||
);
|
||||
if ($context->contextlevel == CONTEXT_MODULE) {
|
||||
$params['cmid'] = $context->instanceid;
|
||||
} else if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
$params['courseid'] = $context->instanceid;
|
||||
}
|
||||
if ($previewid) {
|
||||
$params['previewid'] = $previewid;
|
||||
}
|
||||
return new moodle_url('/question/preview.php', $params);
|
||||
debugging('Function question_preview_form_url() has been deprecated and moved to qbank_previewquestion plugin,
|
||||
please use qbank_previewquestion\helper::question_preview_form_url() instead.', DEBUG_DEVELOPER);
|
||||
qbank_previewquestion\helper::question_preview_form_url($questionid, $context, $previewid);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,15 +293,12 @@ function question_preview_form_url($questionid, $context, $previewid = null) {
|
||||
* @param int $questionid
|
||||
* @param object $displayoptions
|
||||
* @param object $context
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see qbank_previewquestion\helper::restart_preview()
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
function restart_preview($previewid, $questionid, $displayoptions, $context) {
|
||||
global $DB;
|
||||
|
||||
if ($previewid) {
|
||||
$transaction = $DB->start_delegated_transaction();
|
||||
question_engine::delete_questions_usage_by_activity($previewid);
|
||||
$transaction->allow_commit();
|
||||
}
|
||||
redirect(question_preview_url($questionid, $displayoptions->behaviour,
|
||||
$displayoptions->maxmark, $displayoptions, $displayoptions->variant, $context));
|
||||
debugging('Function restart_preview() has been deprecated and moved to qbank_previewquestion plugin,
|
||||
please use qbank_previewquestion\helper::restart_preview() instead.', DEBUG_DEVELOPER);
|
||||
qbank_previewquestion\helper::restart_preview($previewid, $questionid, $displayoptions, $context);
|
||||
}
|
||||
|
@ -80,8 +80,14 @@ M.core_scroll_manager.save_scroll_action = function(e) {
|
||||
|
||||
/**
|
||||
* If there is a parameter like scrollpos=123 in the URL, scroll to that saved position.
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see question\bank\qbank_previewquestion\amd\src
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
M.core_scroll_manager.scroll_to_saved_pos = function(Y) {
|
||||
Y.log("The scroll_to_saved_pos function has been deprecated. " +
|
||||
"Please use scrollToSavedPos() in qbank_preview/preview.js instead.", 'moodle-core-notification', 'warn');
|
||||
|
||||
var matches = window.location.href.match(/^.*[?&]scrollpos=(\d*)(?:&|$|#).*$/, '$1');
|
||||
if (matches) {
|
||||
// onDOMReady is the effective one here. I am leaving the immediate call to
|
||||
@ -153,8 +159,14 @@ M.core_question_engine.init_submit_button = function(Y, button) {
|
||||
* 5. Prevent the user from repeatedly submitting the form.
|
||||
* @param Y the Yahoo object. Needs to have the DOM and Event modules loaded.
|
||||
* @param form something that can be passed to Y.one, to find the form element.
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see question\bank\qbank_previewquestion\amd\src
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
M.core_question_engine.init_form = function(Y, form) {
|
||||
Y.log("The core_question_engine.init_form function has been deprecated. " +
|
||||
"Please use setupQuestionForm() in qbank_preview/preview.js instead.", 'moodle-core-notification', 'warn');
|
||||
|
||||
Y.one(form).setAttribute('autocomplete', 'off');
|
||||
|
||||
Y.on('submit', M.core_question_engine.prevent_repeat_submission, form, form, Y);
|
||||
@ -175,8 +187,14 @@ M.core_question_engine.init_form = function(Y, form) {
|
||||
* Event handler to stop a question form being submitted more than once.
|
||||
* @param e the form submit event.
|
||||
* @param form the form element.
|
||||
* @deprecated since Moodle 4.0
|
||||
* @see question\bank\qbank_previewquestion\amd\src
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
*/
|
||||
M.core_question_engine.prevent_repeat_submission = function(e, Y) {
|
||||
Y.log("The prevent_repeat_submission function has been deprecated. " +
|
||||
"Please use preventRepeatSubmission in qbank_preview/preview.js instead.", 'moodle-core-notification', 'warn');
|
||||
|
||||
if (M.core_question_engine.questionformalreadysubmitted) {
|
||||
e.halt();
|
||||
return;
|
||||
|
@ -27,7 +27,6 @@ Feature: Preview a drag-drop onto image question
|
||||
@javascript @_bug_phantomjs
|
||||
Scenario: Preview a question using the mouse.
|
||||
When I choose "Preview" action for "Drag onto image" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
# Increase window size and wait 2 seconds to ensure elements are placed properly by js.
|
||||
# Keep window large else drag will scroll the window to find element.
|
||||
And I change window size to "medium"
|
||||
@ -44,15 +43,12 @@ Feature: Preview a drag-drop onto image question
|
||||
And I press "Submit and finish"
|
||||
Then the state of "Identify the features" question is shown as "Correct"
|
||||
And I should see "Mark 1.00 out of 1.00"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript
|
||||
Scenario: Preview a question using the keyboard.
|
||||
When I choose "Preview" action for "Drag onto image" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
# Increase window size and wait 2 seconds to ensure elements are placed properly by js.
|
||||
And I change window size to "medium"
|
||||
And I wait "2" seconds
|
||||
And I type " " on place "1" in the drag and drop onto image question
|
||||
And I type " " on place "2" in the drag and drop onto image question
|
||||
And I type " " on place "3" in the drag and drop onto image question
|
||||
@ -64,4 +60,4 @@ Feature: Preview a drag-drop onto image question
|
||||
And I press "Submit and finish"
|
||||
Then the state of "Identify the features" question is shown as "Correct"
|
||||
And I should see "Mark 1.00 out of 1.00"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
@ -27,11 +27,6 @@ Feature: Preview a drag-drop marker question
|
||||
@javascript @_bug_phantomjs
|
||||
Scenario: Preview a question using the mouse.
|
||||
When I choose "Preview" action for "Drag markers" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
# Increase window size and wait 2 seconds to ensure elements are placed properly by js.
|
||||
# Keep window large else drag will scroll the window to find element.
|
||||
And I change window size to "large"
|
||||
And I wait "2" seconds
|
||||
# Odd, but the <br>s go to nothing, not a space.
|
||||
And I drag "OU" to "345,230" in the drag and drop markers question
|
||||
And I drag "Railway station" to "262,197" in the drag and drop markers question
|
||||
@ -40,28 +35,21 @@ Feature: Preview a drag-drop marker question
|
||||
And I press "Submit and finish"
|
||||
Then the state of "Please place the markers on the map of Milton Keynes" question is shown as "Correct"
|
||||
And I should see "Mark 1.00 out of 1.00"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript
|
||||
Scenario: Preview a question using the keyboard.
|
||||
When I choose "Preview" action for "Drag markers" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
# Increase window size and wait 2 seconds to ensure elements are placed properly by js.
|
||||
# Keep window large else drag will scroll the window to find element.
|
||||
And I change window size to "medium"
|
||||
And I wait "2" seconds
|
||||
And I type "up" "88" times on marker "Railway station" in the drag and drop markers question
|
||||
And I type "right" "26" times on marker "Railway station" in the drag and drop markers question
|
||||
And I press "Submit and finish"
|
||||
Then the state of "Please place the markers on the map of Milton Keynes" question is shown as "Partially correct"
|
||||
And I should see "Mark 0.25 out of 1.00"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript
|
||||
Scenario: Preview a question in responsive mode.
|
||||
When I choose "Preview" action for "Drag markers" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I change window size to "large"
|
||||
And I drag "OU" to "345,230" in the drag and drop markers question
|
||||
And I drag "Railway station" to "262,197" in the drag and drop markers question
|
||||
And I drag "Railway station" to "334,319" in the drag and drop markers question
|
||||
|
@ -28,42 +28,35 @@ Feature: Preview a drag-drop into text question
|
||||
@javascript @_bug_phantomjs
|
||||
Scenario: Preview a question using the mouse.
|
||||
When I choose "Preview" action for "Drag to text" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
# Increase window size and wait 2 seconds to ensure elements are placed properly by js.
|
||||
# Keep window large else drag will scroll the window to find element.
|
||||
And I change window size to "medium"
|
||||
And I wait "2" seconds
|
||||
And I drag "quick" to space "1" in the drag and drop into text question
|
||||
And I drag "fox" to space "2" in the drag and drop into text question
|
||||
And I drag "assiduous" to space "3" in the drag and drop into text question
|
||||
And I press "Submit and finish"
|
||||
Then the state of "The" question is shown as "Partially correct"
|
||||
And I should see "Mark 0.67 out of 1.00"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript
|
||||
Scenario: Preview a question using the keyboard & submit incomplete.
|
||||
When I choose "Preview" action for "Drag to text" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I type " " into space "1" in the drag and drop onto image question
|
||||
And I type " " into space "2" in the drag and drop onto image question
|
||||
And I type " " into space "3" in the drag and drop onto image question
|
||||
And I press "Save"
|
||||
Then the state of "The" question is shown as "Incomplete answer"
|
||||
And I should see "Please put an answer in each box."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript
|
||||
Scenario: Preview a question using the keyboard.
|
||||
When I choose "Preview" action for "Drag to text" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I type " " into space "1" in the drag and drop onto image question
|
||||
And I type " " into space "2" in the drag and drop onto image question
|
||||
And I type " " into space "3" in the drag and drop onto image question
|
||||
And I press "Submit and finish"
|
||||
Then the state of "The" question is shown as "Incorrect"
|
||||
And I should see "Mark 0.00 out of 1.00"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript
|
||||
Scenario: Preview a question that uses strange group numbers using the keyboard.
|
||||
@ -72,24 +65,19 @@ Feature: Preview a drag-drop into text question
|
||||
| Test questions | ddwtos | Funny groups | oddgroups |
|
||||
And I reload the page
|
||||
When I choose "Preview" action for "Funny groups" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I type " " into space "1" in the drag and drop onto image question
|
||||
And I type " " into space "2" in the drag and drop onto image question
|
||||
And I type " " into space "3" in the drag and drop onto image question
|
||||
And I press "Submit and finish"
|
||||
Then the state of "The" question is shown as "Correct"
|
||||
And I should see "Mark 1.00 out of 1.00"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript
|
||||
Scenario: Preview a infinite question.
|
||||
When I choose "Preview" action for "Drag to text infinite" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
# Increase window size.
|
||||
# Keep window large else drag will scroll the window to find element.
|
||||
And I change window size to "medium"
|
||||
And I press "Fill in correct responses"
|
||||
Then I should see "Option1" in the home area of drag and drop into text question
|
||||
And I should see "Option2" in the home area of drag and drop into text question
|
||||
And I should see "Option3" in the home area of drag and drop into text question
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
@ -27,8 +27,7 @@ Feature: Preview a Description question
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a Description question and submit a correct response.
|
||||
When I choose "Preview" action for "description-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I should see "Here is some information about the questions you are about to attempt."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
@ -258,17 +258,11 @@ abstract class question_edit_form extends question_wizard_form {
|
||||
$buttonarray[] = $mform->createElement('submit', 'updatebutton',
|
||||
get_string('savechangesandcontinueediting', 'question'));
|
||||
if ($this->can_preview()) {
|
||||
// Todo MDL-72004 changes for class renaming and default sort.
|
||||
if (class_exists('qbank_previewquestion\\preview_action_column')) {
|
||||
if (\core\plugininfo\qbank::is_plugin_enabled('qbank_previewquestion')) {
|
||||
$previewlink = $PAGE->get_renderer('qbank_previewquestion')->question_preview_link(
|
||||
$this->question->id, $this->context, true);
|
||||
}
|
||||
} else {
|
||||
$previewlink = $PAGE->get_renderer('core_question')->question_preview_link(
|
||||
if (\core\plugininfo\qbank::is_plugin_enabled('qbank_previewquestion')) {
|
||||
$previewlink = $PAGE->get_renderer('qbank_previewquestion')->question_preview_link(
|
||||
$this->question->id, $this->context, true);
|
||||
$buttonarray[] = $mform->createElement('static', 'previewlink', '', $previewlink);
|
||||
}
|
||||
$buttonarray[] = $mform->createElement('static', 'previewlink', '', $previewlink);
|
||||
}
|
||||
|
||||
$mform->addGroup($buttonarray, 'updatebuttonar', '', array(' '), false);
|
||||
|
@ -27,15 +27,13 @@ I need to choose the appropriate maxbytes for attachments
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview an Essay question and see the allowed maximum file sizes and number of attachments.
|
||||
When I choose "Preview" action for "essay-1-512KB" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
Then I should see "Please write a story about a frog."
|
||||
And I should see "Maximum file size: 512KB, maximum number of files: 1"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview an Essay question with Course upload limit and see the allowed maximum file size.
|
||||
When I choose "Preview" action for "essay-1-max" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
Then I should see "Please write a story about a frog."
|
||||
And I should see "Maximum file size: 1MB, maximum number of files: 1"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
@ -29,27 +29,24 @@ Feature: Preview Essay questions
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview an Essay question that uses the HTML editor.
|
||||
When I choose "Preview" action for "essay-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I should see "Please write a story about a frog."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview an Essay question that uses the HTML editor with embedded files.
|
||||
When I choose "Preview" action for "essay-002" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I should see "Please write a story about a frog."
|
||||
And I should see "You can drag and drop files here to add them."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview an Essay question that uses a plain text area.
|
||||
When I choose "Preview" action for "essay-003" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I should see "Please write a story about a frog."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
@ -39,7 +39,6 @@ Feature: Test all the basic functionality of this question type
|
||||
|
||||
# Preview it.
|
||||
When I choose "Preview" action for "Select missing words 001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
|
||||
# Gaps (drop-down menus) do not have labels. ids and names are generated
|
||||
# dynamically and therefore not reliable, i.e. this is an accessibility bug
|
||||
@ -122,7 +121,7 @@ Feature: Test all the basic functionality of this question type
|
||||
Then I should see "Your answer is incorrect"
|
||||
And I should see "The cat sat on the mat"
|
||||
And I should see "The correct answer is: The [cat] [sat] on the [mat]."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
# Backup the course and restore it.
|
||||
When I log out
|
||||
|
@ -43,7 +43,6 @@ Feature: Test editing a Matching question
|
||||
And I press "id_submitbutton"
|
||||
Then I should see "Edited Matching name"
|
||||
When I choose "Preview" action for "Edited Matching name" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
Then I should see "frog"
|
||||
And I should see "dog"
|
||||
And I should see "newt"
|
||||
|
@ -31,7 +31,6 @@ Feature: Preview a Matching question
|
||||
| Shuffle | 0 |
|
||||
And I press "id_submitbutton"
|
||||
When I choose "Preview" action for "matching-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub0')]" to "amphibian"
|
||||
@ -40,7 +39,7 @@ Feature: Preview a Matching question
|
||||
And I press "Check"
|
||||
Then I should see "Well done!"
|
||||
And I should see "General feedback."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a Matching question and submit a partially correct response.
|
||||
@ -49,7 +48,6 @@ Feature: Preview a Matching question
|
||||
| Shuffle | 0 |
|
||||
And I press "id_submitbutton"
|
||||
When I choose "Preview" action for "matching-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub0')]" to "amphibian"
|
||||
@ -58,7 +56,7 @@ Feature: Preview a Matching question
|
||||
And I press "Check"
|
||||
Then I should see "Parts, but only parts, of your response are correct."
|
||||
And I should see "General feedback."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a Matching question and submit an incorrect response.
|
||||
@ -67,7 +65,6 @@ Feature: Preview a Matching question
|
||||
| Shuffle | 0 |
|
||||
And I press "id_submitbutton"
|
||||
When I choose "Preview" action for "matching-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub0')]" to "mammal"
|
||||
@ -76,4 +73,4 @@ Feature: Preview a Matching question
|
||||
And I press "Check"
|
||||
Then I should see "That is not right at all."
|
||||
And I should see "General feedback."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
@ -28,7 +28,6 @@ Feature: Preview a Multiple choice question
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a Multiple choice question and submit a partially correct response.
|
||||
When I choose "Preview" action for "Multi-choice-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I click on "One" "qtype_multichoice > Answer"
|
||||
@ -38,12 +37,11 @@ Feature: Preview a Multiple choice question
|
||||
And I should see "Two is even"
|
||||
And I should see "Mark 0.50 out of 1.00"
|
||||
And I should see "Parts, but only parts, of your response are correct."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a Multiple choice question and submit a correct response.
|
||||
When I choose "Preview" action for "Multi-choice-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I click on "One" "qtype_multichoice > Answer"
|
||||
@ -55,12 +53,11 @@ Feature: Preview a Multiple choice question
|
||||
And I should see "Well done!"
|
||||
And I should see "The odd numbers are One and Three."
|
||||
And I should see "The correct answers are: One, Three"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a Multiple choice question and submit a correct response.
|
||||
When I choose "Preview" action for "Multi-choice-002" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I click on "One" "qtype_multichoice > Answer"
|
||||
@ -69,16 +66,15 @@ Feature: Preview a Multiple choice question
|
||||
And I should see "Mark 1.00 out of 1.00"
|
||||
And I should see "Well done!"
|
||||
And I should see "The correct answer is: One"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a multiple choice question (single response) and clear a previous selected option.
|
||||
When I choose "Preview" action for "Multi-choice-002" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I click on "One" "qtype_multichoice > Answer"
|
||||
Then I should see "Clear my choice"
|
||||
And I click on "Clear my choice" "text"
|
||||
And I should not see "Clear my choice"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
@ -31,7 +31,6 @@ Feature: Preview a Numerical question
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a Numerical question and submit a correct response.
|
||||
When I choose "Preview" action for "Numerical-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
Then I should see "What is pi to two d.p.?"
|
||||
When I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
@ -48,4 +47,4 @@ Feature: Preview a Numerical question
|
||||
And I press "Check"
|
||||
Then I should see "Very good."
|
||||
And I should see "Mark 1#00 out of 1#00"
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
@ -43,7 +43,6 @@ Feature: Test editing a Short answer question
|
||||
And I press "id_submitbutton"
|
||||
Then I should see "Edited shortanswer-001 name"
|
||||
When I choose "Preview" action for "Edited shortanswer-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
Then I should see "Name an amphibian:"
|
||||
# Set behaviour options
|
||||
And I set the following fields to these values:
|
||||
|
@ -27,7 +27,6 @@ Feature: Preview a Short answer question
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a Short answer question with correct answer
|
||||
When I choose "Preview" action for "shortanswer-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
Then I should see "Name an amphibian:"
|
||||
# Set behaviour options
|
||||
And I set the following fields to these values:
|
||||
@ -42,7 +41,6 @@ Feature: Preview a Short answer question
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a Short answer question with almost correct answer
|
||||
When I choose "Preview" action for "shortanswer-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
Then I should see "Name an amphibian:"
|
||||
# Set behaviour options
|
||||
And I set the following fields to these values:
|
||||
@ -57,7 +55,6 @@ Feature: Preview a Short answer question
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a Short answer question with incorrect answer
|
||||
When I choose "Preview" action for "shortanswer-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
Then I should see "Name an amphibian:"
|
||||
# Set behaviour options
|
||||
And I set the following fields to these values:
|
||||
|
@ -27,19 +27,17 @@ Feature: Preview a Trtue/False question
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a True/False question and submit a correct response.
|
||||
When I choose "Preview" action for "true-false-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I click on "True" "radio"
|
||||
And I press "Check"
|
||||
And I should see "This is the right answer."
|
||||
And I should see "The correct answer is 'True'."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
||||
@javascript @_switch_window
|
||||
Scenario: Preview a True/False question and submit an incorrect response.
|
||||
When I choose "Preview" action for "true-false-001" in the question bank
|
||||
And I switch to "questionpreview" window
|
||||
And I set the field "How questions behave" to "Immediate feedback"
|
||||
And I press "Start again with these options"
|
||||
And I click on "False" "radio"
|
||||
@ -47,4 +45,4 @@ Feature: Preview a Trtue/False question
|
||||
And I should see "This is the wrong answer."
|
||||
And I should see "You should have selected true."
|
||||
And I should see "The correct answer is 'True'."
|
||||
And I switch to the main window
|
||||
And I press "Close preview"
|
||||
|
@ -9,10 +9,16 @@ This files describes API changes for code that uses the question API.
|
||||
2) submit_tags_form and associated external services for question tag, tags_form in question/type,
|
||||
core_question_output_fragment_tags_form method in lib is deprecated and moved to the tagquestion plugin.
|
||||
|
||||
2) Function question_get_export_single_question_url() in questionlib has been deprecated
|
||||
3) Function question_get_export_single_question_url() in questionlib has been deprecated
|
||||
and moved to qbank_exporttoxml plugin, the new location is:
|
||||
qbank_exporttoxml\helper::question_get_export_single_question_url().
|
||||
|
||||
4) The following methods are deprecated in previewlib and moved to the previewquestion plugin:
|
||||
restart_preview(), question_preview_form_url(), question_preview_action_url(),
|
||||
question_preview_question_pluginfile()
|
||||
The following classes are deprecated in previewlib and moves the previewquestion plugin:
|
||||
question_preview_options, preview_options_form.
|
||||
|
||||
=== 3.9 ==
|
||||
|
||||
1) For years, the ..._questions_in_use callback has been the right way for plugins to
|
||||
|
@ -23,9 +23,14 @@ YUI.add('moodle-question-preview', function (Y, NAME) {
|
||||
/**
|
||||
* JavaScript required by the question preview pop-up.
|
||||
*
|
||||
* @deprecated since Moodle 4.0
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
* @module moodle-question-preview
|
||||
*/
|
||||
|
||||
Y.log("The moodle-question-preview module has been deprecated. " +
|
||||
"Please use moodle-qbank_previewquestion-preview instead.", 'moodle-core-notification', 'warn');
|
||||
|
||||
M.question = M.question || {};
|
||||
M.question.preview = M.question.preview || {};
|
||||
|
||||
|
@ -23,9 +23,12 @@ YUI.add('moodle-question-preview', function (Y, NAME) {
|
||||
/**
|
||||
* JavaScript required by the question preview pop-up.
|
||||
*
|
||||
* @deprecated since Moodle 4.0
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
* @module moodle-question-preview
|
||||
*/
|
||||
|
||||
|
||||
M.question = M.question || {};
|
||||
M.question.preview = M.question.preview || {};
|
||||
|
||||
|
5
question/yui/src/preview/js/preview.js
vendored
5
question/yui/src/preview/js/preview.js
vendored
@ -21,9 +21,14 @@
|
||||
/**
|
||||
* JavaScript required by the question preview pop-up.
|
||||
*
|
||||
* @deprecated since Moodle 4.0
|
||||
* @todo Final deprecation on Moodle 4.4 MDL-72438
|
||||
* @module moodle-question-preview
|
||||
*/
|
||||
|
||||
Y.log("The moodle-question-preview module has been deprecated. " +
|
||||
"Please use moodle-qbank_previewquestion-preview instead.", 'moodle-core-notification', 'warn');
|
||||
|
||||
M.question = M.question || {};
|
||||
M.question.preview = M.question.preview || {};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user