mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-61364 question: add support for course tags on modal
This commit is contained in:
parent
a15c745936
commit
e6890b1164
2
question/amd/build/edit_tags.min.js
vendored
2
question/amd/build/edit_tags.min.js
vendored
@ -1 +1 @@
|
||||
define(["jquery","core/fragment","core/str","core/modal_events","core/modal_factory","core/notification","core/custom_interaction_events","core_question/repository","core_question/selectors"],function(a,b,c,d,e,f,g,h,i){var j=function(a){a.find(i.actions.save).prop("disabled",!1)},k=function(a){a.find(i.actions.save).prop("disabled",!0)},l=function(a){return a.getBody().find("form").serialize()},m=function(a){var b=a.find(i.containers.loadingIcon);b.removeClass("hidden")},n=function(a){var b=a.find(i.containers.loadingIcon);b.addClass("hidden")},o=function(h){var l=e.create({type:e.types.SAVE_CANCEL,large:!1},[h,i.actions.edittags]).then(function(a){return c.get_string("questiontags","question").then(function(b){return a.setTitle(b),b}).fail(f.exception),a.getRoot().on(d.save,function(b){var c=a.getBody().find("form");c.submit(),b.preventDefault()}),a.getRoot().on("submit","form",function(b){p(a,h).then(function(){a.hide()}).fail(f.exception),b.preventDefault(),b.stopPropagation()}),a});h.on(g.events.activate,i.actions.edittags,function(c){var d=a(c.currentTarget),e=d.data("questionid"),g=!!d.data("cantag"),o=d.data("contextid");l.then(function(a){k(h),m(h);var c={id:e},d=b.loadFragment("question","tags_form",o,c);return a.setBody(d),d.then(function(){j(h)}).always(function(){n(h)}).fail(f.exception),g?a.getRoot().find(i.actions.save).show():a.getRoot().find(i.actions.save).hide(),a}).fail(f.exception),c.preventDefault()})},p=function(a,b){k(b),m(b);var c=l(a);return h.submitTagCreateUpdateForm(c).always(function(){n(b),j(b)}).fail(f.exception)};return{init:function(b){b=a(b),o(b)}}});
|
||||
define(["jquery","core/fragment","core/str","core/modal_events","core/modal_factory","core/notification","core/custom_interaction_events","core_question/repository","core_question/selectors"],function(a,b,c,d,e,f,g,h,i){var j=function(a){a.find(i.actions.save).prop("disabled",!1)},k=function(a){a.find(i.actions.save).prop("disabled",!0)},l=function(a){return a.getBody().find("form").serialize()},m=function(a){var b=a.find(i.containers.loadingIcon);b.removeClass("hidden")},n=function(a){var b=a.find(i.containers.loadingIcon);b.addClass("hidden")},o=function(a,b){a.getBody().attr("data-contextid",b)},p=function(a){return a.getBody().data("contextid")},q=function(a,b){a.getBody().attr("data-questionid",b)},r=function(a){return a.getBody().data("questionid")},s=function(h){var l=e.create({type:e.types.SAVE_CANCEL,large:!1},[h,i.actions.edittags]).then(function(a){return c.get_string("questiontags","question").then(function(b){return a.setTitle(b),b}).fail(f.exception),a.getRoot().on(d.save,function(b){var c=a.getBody().find("form");c.submit(),b.preventDefault()}),a.getRoot().on("submit","form",function(b){t(a,h).then(function(){a.hide()}).fail(f.exception),b.preventDefault(),b.stopPropagation()}),a});h.on(g.events.activate,i.actions.edittags,function(c){var d=a(c.currentTarget),e=d.data("questionid"),g=!!d.data("cantag"),p=d.data("contextid");l.then(function(a){k(h),m(h);var c={id:e},d=b.loadFragment("question","tags_form",p,c);return a.setBody(d),d.then(function(){j(h)}).always(function(){n(h)}).fail(f.exception),g?a.getRoot().find(i.actions.save).show():a.getRoot().find(i.actions.save).hide(),q(a,e),o(a,p),a}).fail(f.exception),c.preventDefault()})},t=function(a,b){k(b),m(b);var c=l(a),d=r(a),e=p(a);return h.submitTagCreateUpdateForm(d,e,c).always(function(){n(b),j(b)}).fail(f.exception)};return{init:function(b){b=a(b),s(b)}}});
|
2
question/amd/build/repository.min.js
vendored
2
question/amd/build/repository.min.js
vendored
@ -1 +1 @@
|
||||
define(["jquery","core/ajax"],function(a,b){var c=function(a){var c={methodname:"core_question_submit_tags_form",args:{formdata:a}};return b.call([c])[0]};return{submitTagCreateUpdateForm:c}});
|
||||
define(["jquery","core/ajax"],function(a,b){var c=function(a,c,d){var e={methodname:"core_question_submit_tags_form",args:{questionid:a,contextid:c,formdata:d}};return b.call([e])[0]};return{submitTagCreateUpdateForm:c}});
|
@ -98,6 +98,46 @@ define([
|
||||
loadingIconContainer.addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the context Id data attribute on the modal.
|
||||
*
|
||||
* @param {Promise} modal The modal promise.
|
||||
* @param {int} contextId The context id.
|
||||
*/
|
||||
var setContextId = function(modal, contextId) {
|
||||
modal.getBody().attr('data-contextid', contextId);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the context Id data attribute value from the modal body.
|
||||
*
|
||||
* @param {Promise} modal The modal promise.
|
||||
* @return {int} The context id.
|
||||
*/
|
||||
var getContextId = function(modal) {
|
||||
return modal.getBody().data('contextid');
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the question Id data attribute on the modal.
|
||||
*
|
||||
* @param {Promise} modal The modal promise.
|
||||
* @param {int} questionId The question Id.
|
||||
*/
|
||||
var setQuestionId = function(modal, questionId) {
|
||||
modal.getBody().attr('data-questionid', questionId);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the question Id data attribute value from the modal body.
|
||||
*
|
||||
* @param {Promise} modal The modal promise.
|
||||
* @return {int} The question Id.
|
||||
*/
|
||||
var getQuestionId = function(modal) {
|
||||
return modal.getBody().data('questionid');
|
||||
};
|
||||
|
||||
/**
|
||||
* Register event listeners for the module.
|
||||
*
|
||||
@ -186,6 +226,9 @@ define([
|
||||
modal.getRoot().find(QuestionSelectors.actions.save).hide();
|
||||
}
|
||||
|
||||
setQuestionId(modal, questionId);
|
||||
setContextId(modal, contextId);
|
||||
|
||||
return modal;
|
||||
}).fail(Notification.exception);
|
||||
|
||||
@ -207,9 +250,11 @@ define([
|
||||
startLoading(root);
|
||||
|
||||
var formData = getFormData(modal);
|
||||
var questionId = getQuestionId(modal);
|
||||
var contextId = getContextId(modal);
|
||||
|
||||
// Send the form data to the server for processing.
|
||||
return Repository.submitTagCreateUpdateForm(formData)
|
||||
return Repository.submitTagCreateUpdateForm(questionId, contextId, formData)
|
||||
.always(function() {
|
||||
// Regardless of success or error we should always stop
|
||||
// the loading icon and re-enable the buttons.
|
||||
|
@ -31,10 +31,12 @@ define(['jquery', 'core/ajax'], function($, Ajax) {
|
||||
* @param {string} formdata The URL encoded values from the form
|
||||
* @return {promise}
|
||||
*/
|
||||
var submitTagCreateUpdateForm = function(formdata) {
|
||||
var submitTagCreateUpdateForm = function(questionId, contextId, formdata) {
|
||||
var request = {
|
||||
methodname: 'core_question_submit_tags_form',
|
||||
args: {
|
||||
questionid: questionId,
|
||||
contextid: contextId,
|
||||
formdata: formdata
|
||||
}
|
||||
};
|
||||
|
@ -56,10 +56,11 @@ class tags_action_column extends action_column_base {
|
||||
question_has_capability_on($question, 'view')) {
|
||||
|
||||
$cantag = question_has_capability_on($question, 'tag');
|
||||
$category = $DB->get_record('question_categories', ['id' => $question->category], 'contextid');
|
||||
$url = $this->qbank->edit_question_url($question->id);
|
||||
$qbank = $this->qbank;
|
||||
$url = $qbank->edit_question_url($question->id);
|
||||
$editingcontext = $qbank->get_most_specific_context();
|
||||
|
||||
$this->print_tag_icon($question->id, $url, $cantag, $category->contextid);
|
||||
$this->print_tag_icon($question->id, $url, $cantag, $editingcontext->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,6 +122,8 @@ class core_question_external extends external_api {
|
||||
*/
|
||||
public static function submit_tags_form_parameters() {
|
||||
return new external_function_parameters([
|
||||
'questionid' => new external_value(PARAM_INT, 'The question id'),
|
||||
'contextid' => new external_value(PARAM_INT, 'The editing context id'),
|
||||
'formdata' => new external_value(PARAM_RAW, 'The data from the tag form'),
|
||||
]);
|
||||
}
|
||||
@ -129,51 +131,67 @@ class core_question_external extends external_api {
|
||||
/**
|
||||
* Handles the tags form submission.
|
||||
*
|
||||
* @param int $questionid The question id.
|
||||
* @param int $contextid The editing context id.
|
||||
* @param string $formdata The question tag form data in a URI encoded param string
|
||||
* @return array The created or modified question tag
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function submit_tags_form($formdata) {
|
||||
global $USER, $DB, $CFG;
|
||||
public static function submit_tags_form($questionid, $contextid, $formdata) {
|
||||
global $DB, $CFG;
|
||||
|
||||
$data = [];
|
||||
$result = ['status' => false];
|
||||
|
||||
// Parameter validation.
|
||||
$params = self::validate_parameters(self::submit_tags_form_parameters(), ['formdata' => $formdata]);
|
||||
$context = \context_user::instance($USER->id);
|
||||
$params = self::validate_parameters(self::submit_tags_form_parameters(), [
|
||||
'questionid' => $questionid,
|
||||
'contextid' => $contextid,
|
||||
'formdata' => $formdata
|
||||
]);
|
||||
|
||||
self::validate_context($context);
|
||||
$editingcontext = \context::instance_by_id($contextid);
|
||||
self::validate_context($editingcontext);
|
||||
parse_str($params['formdata'], $data);
|
||||
|
||||
if (!empty($data['id'])) {
|
||||
$questionid = clean_param($data['id'], PARAM_INT);
|
||||
$question = $DB->get_record('question', array('id' => $questionid));
|
||||
if (!$question = $DB->get_record_sql('
|
||||
SELECT q.*, qc.contextid
|
||||
FROM {question} q
|
||||
JOIN {question_categories} qc ON qc.id = q.category
|
||||
WHERE q.id = ?', [$questionid])) {
|
||||
print_error('questiondoesnotexist', 'question');
|
||||
}
|
||||
|
||||
require_once($CFG->libdir . '/questionlib.php');
|
||||
$cantag = question_has_capability_on($question, 'tag');
|
||||
require_once($CFG->libdir . '/questionlib.php');
|
||||
require_once($CFG->dirroot . '/question/type/tags_form.php');
|
||||
|
||||
require_once($CFG->dirroot . '/question/type/tags_form.php');
|
||||
$mform = new \core_question\form\tags(null, null, 'post', '', null, $cantag, $data);
|
||||
$cantag = question_has_capability_on($question, 'tag');
|
||||
$questioncontext = \context::instance_by_id($question->contextid);
|
||||
$formoptions = [
|
||||
'editingcontext' => $editingcontext,
|
||||
'questioncontext' => $questioncontext
|
||||
];
|
||||
|
||||
if ($validateddata = $mform->get_data()) {
|
||||
// Due to a mform bug, if there's no tags set on the tag element, it submits the name as the value.
|
||||
// The only way to discover is checking if the tag element is an array.
|
||||
if ($cantag) {
|
||||
if (is_array($validateddata->tags)) {
|
||||
$categorycontext = context::instance_by_id($validateddata->contextid);
|
||||
$mform = new \core_question\form\tags(null, $formoptions, 'post', '', null, $cantag, $data);
|
||||
|
||||
core_tag_tag::set_item_tags('core_question', 'question', $validateddata->id,
|
||||
$categorycontext, $validateddata->tags);
|
||||
if ($validateddata = $mform->get_data()) {
|
||||
if ($cantag) {
|
||||
if (isset($validateddata->tags)) {
|
||||
// Due to a mform bug, if there's no tags set on the tag element, it submits the name as the value.
|
||||
// The only way to discover is checking if the tag element is an array.
|
||||
$tags = is_array($validateddata->tags) ? $validateddata->tags : [];
|
||||
|
||||
$result['status'] = true;
|
||||
} else {
|
||||
// If the tags element is not array, this means we don't have any tags to be set.
|
||||
// This is the only way to assume the user removed all tags from the question.
|
||||
core_tag_tag::remove_all_item_tags('core_question', 'question', $validateddata->id);
|
||||
core_tag_tag::set_item_tags('core_question', 'question', $validateddata->id,
|
||||
$questioncontext, $tags);
|
||||
|
||||
$result['status'] = true;
|
||||
}
|
||||
$result['status'] = true;
|
||||
}
|
||||
|
||||
if (isset($validateddata->coursetags)) {
|
||||
$coursetags = is_array($validateddata->coursetags) ? $validateddata->coursetags : [];
|
||||
core_tag_tag::set_item_tags('core_question', 'question', $validateddata->id,
|
||||
$editingcontext->get_course_context(false), $coursetags);
|
||||
|
||||
$result['status'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,26 +41,42 @@ function core_question_output_fragment_tags_form($args) {
|
||||
require_once($CFG->dirroot . '/question/type/tags_form.php');
|
||||
require_once($CFG->libdir . '/questionlib.php');
|
||||
$id = clean_param($args['id'], PARAM_INT);
|
||||
$editingcontext = $args['context'];
|
||||
|
||||
$question = $DB->get_record('question', ['id' => $id]);
|
||||
$category = $DB->get_record('question_categories', array('id' => $question->category));
|
||||
$context = \context::instance_by_id($category->contextid);
|
||||
|
||||
$toform = new stdClass();
|
||||
$toform->id = $question->id;
|
||||
$toform->questioncategory = $category->name;
|
||||
$toform->questionname = $question->name;
|
||||
$toform->categoryid = $category->id;
|
||||
$toform->contextid = $category->contextid;
|
||||
$toform->context = $context->get_context_name();
|
||||
|
||||
if (core_tag_tag::is_enabled('core_question', 'question')) {
|
||||
$toform->tags = core_tag_tag::get_item_tags_array('core_question', 'question', $question->id);
|
||||
if ($coursecontext = $editingcontext->get_course_context(false)) {
|
||||
$course = $DB->get_record('course', ['id' => $coursecontext->instanceid]);
|
||||
$filtercourses = [$course];
|
||||
} else {
|
||||
$filtercourses = null;
|
||||
}
|
||||
|
||||
// Load the question tags and filter the course tags by the current
|
||||
// course.
|
||||
get_question_options($question, true, $filtercourses);
|
||||
|
||||
$category = $question->categoryobject;
|
||||
$questioncontext = \context::instance_by_id($category->contextid);
|
||||
|
||||
$formoptions = [
|
||||
'editingcontext' => $editingcontext,
|
||||
'questioncontext' => $questioncontext
|
||||
];
|
||||
$data = [
|
||||
'id' => $question->id,
|
||||
'questioncategory' => $category->name,
|
||||
'questionname' => $question->name,
|
||||
'categoryid' => $category->id,
|
||||
'contextid' => $category->contextid,
|
||||
'context' => $questioncontext->get_context_name(),
|
||||
'tags' => isset($question->tags) ? $question->tags : [],
|
||||
'coursetags' => isset($question->coursetags) ? $question->coursetags : [],
|
||||
];
|
||||
|
||||
$cantag = question_has_capability_on($question, 'tag');
|
||||
$mform = new \core_question\form\tags(null, null, 'post', '', null, $cantag, $toform);
|
||||
$mform->set_data($toform);
|
||||
$mform = new \core_question\form\tags(null, $formoptions, 'post', '', null, $cantag, $data);
|
||||
$mform->set_data($data);
|
||||
|
||||
return $mform->render();
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ class tags extends \moodleform {
|
||||
*/
|
||||
public function definition() {
|
||||
$mform = $this->_form;
|
||||
$customdata = $this->_customdata;
|
||||
|
||||
$mform->disable_form_change_checker();
|
||||
|
||||
$mform->addElement('hidden', 'id');
|
||||
@ -56,7 +58,29 @@ class tags extends \moodleform {
|
||||
$mform->addElement('static', 'questioncategory', get_string('categorycurrent', 'question'));
|
||||
$mform->addElement('static', 'context', '');
|
||||
|
||||
$mform->addElement('tags', 'tags', get_string('tags'),
|
||||
['itemtype' => 'question', 'component' => 'core_question']);
|
||||
if (\core_tag_tag::is_enabled('core_question', 'question')) {
|
||||
$mform->addElement('tags', 'tags', get_string('tags'),
|
||||
['itemtype' => 'question', 'component' => 'core_question']);
|
||||
|
||||
// Is the question category in a course context?
|
||||
$qcontext = $customdata['questioncontext'];
|
||||
$qcoursecontext = $qcontext->get_course_context(false);
|
||||
$iscourseoractivityquestion = !empty($qcoursecontext);
|
||||
// Is the current context we're editing in a course context?
|
||||
$editingcontext = $customdata['editingcontext'];
|
||||
$editingcoursecontext = $editingcontext->get_course_context(false);
|
||||
$iseditingcontextcourseoractivity = !empty($editingcoursecontext);
|
||||
|
||||
if ($iseditingcontextcourseoractivity && !$iscourseoractivityquestion) {
|
||||
// If the question is being edited in a course or activity context
|
||||
// and the question isn't a course or activity level question then
|
||||
// allow course tags to be added to the course.
|
||||
$coursetagheader = get_string('questionformtagheader', 'core_question',
|
||||
$editingcoursecontext->get_context_name(true));
|
||||
$mform->addElement('tags', 'coursetags', $coursetagheader,
|
||||
array('itemtype' => 'question', 'component' => 'core_question'));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user