From 3b8f3198defa763e7095ef8f95cf0d27b6e4cff4 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Tue, 30 Jan 2018 13:46:39 +1100 Subject: [PATCH] MDL-61132 Quiz: "Random" question from "Top" categories * Support for adding ranodm questions from "Top" categories --- lib/questionlib.php | 17 +++++++++ mod/quiz/addrandom.php | 4 ++ mod/quiz/addrandomform.php | 6 ++- question/type/random/edit_random_form.php | 5 ++- question/type/random/lang/en/qtype_random.php | 5 +++ question/type/random/questiontype.php | 38 +++++++++++++++++-- 6 files changed, 68 insertions(+), 7 deletions(-) diff --git a/lib/questionlib.php b/lib/questionlib.php index 75df7ac24de..904975f9fd0 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -1030,6 +1030,23 @@ function question_get_top_category($contextid, $create = false) { return $category; } +/** + * Gets the list of top categories in the given contexts in the array("categoryid,categorycontextid") format. + * + * @param array $contextids List of context ids + * @return array + */ +function question_get_top_categories_for_contexts($contextids) { + global $DB; + + $concatsql = $DB->sql_concat_join("','", ['id', 'contextid']); + list($insql, $params) = $DB->get_in_or_equal($contextids); + $sql = "SELECT $concatsql FROM {question_categories} WHERE contextid $insql AND parent = 0"; + $topcategories = $DB->get_fieldset_sql($sql, $params); + + return $topcategories; +} + /** * Gets the default category in the most specific context. * If no categories exist yet then default ones are created in all contexts. diff --git a/mod/quiz/addrandom.php b/mod/quiz/addrandom.php index 658ecb86cf2..144fe2e4909 100644 --- a/mod/quiz/addrandom.php +++ b/mod/quiz/addrandom.php @@ -85,6 +85,10 @@ if ($data = $mform->get_data()) { if (!empty($data->existingcategory)) { list($categoryid) = explode(',', $data->category); $includesubcategories = !empty($data->includesubcategories); + if (!$includesubcategories) { + // If the chosen category is a top category. + $includesubcategories = $DB->record_exists('question_categories', ['id' => $categoryid, 'parent' => 0]); + } $returnurl->param('cat', $data->category); } else if (!empty($data->newcategory)) { diff --git a/mod/quiz/addrandomform.php b/mod/quiz/addrandomform.php index f66832e4b28..7405ddae666 100644 --- a/mod/quiz/addrandomform.php +++ b/mod/quiz/addrandomform.php @@ -37,7 +37,6 @@ require_once($CFG->libdir.'/formslib.php'); class quiz_add_random_form extends moodleform { protected function definition() { - global $CFG, $DB; $mform =& $this->_form; $mform->setDisableShortforms(); @@ -49,11 +48,14 @@ class quiz_add_random_form extends moodleform { get_string('randomfromexistingcategory', 'quiz')); $mform->addElement('questioncategory', 'category', get_string('category'), - array('contexts' => $usablecontexts, 'top' => false)); + array('contexts' => $usablecontexts, 'top' => true)); $mform->setDefault('category', $this->_customdata['cat']); $mform->addElement('checkbox', 'includesubcategories', '', get_string('recurse', 'quiz')); + $tops = question_get_top_categories_for_contexts(array_column($contexts->all(), 'id')); + $mform->hideIf('includesubcategories', 'category', 'in', $tops); + $mform->addElement('select', 'numbertoadd', get_string('randomnumber', 'quiz'), $this->get_number_of_questions_to_add_choices()); diff --git a/question/type/random/edit_random_form.php b/question/type/random/edit_random_form.php index 6f771a0aee7..b2c2f2694e8 100644 --- a/question/type/random/edit_random_form.php +++ b/question/type/random/edit_random_form.php @@ -48,11 +48,14 @@ class qtype_random_edit_form extends question_edit_form { $mform->addElement('header', 'generalheader', get_string("general", 'form')); $mform->addElement('questioncategory', 'category', get_string('category', 'question'), - array('contexts' => $this->contexts->having_cap('moodle/question:useall'))); + array('contexts' => $this->contexts->having_cap('moodle/question:useall'), 'top' => true)); $mform->addElement('advcheckbox', 'questiontext[text]', get_string('includingsubcategories', 'qtype_random'), null, null, array(0, 1)); + $tops = question_get_top_categories_for_contexts(array_column($this->contexts->all(), 'id')); + $mform->hideIf('questiontext[text]', 'category', 'in', $tops); + $mform->addElement('hidden', 'qtype'); $mform->setType('qtype', PARAM_ALPHA); diff --git a/question/type/random/lang/en/qtype_random.php b/question/type/random/lang/en/qtype_random.php index 0e15605c38f..4c16d912cc3 100644 --- a/question/type/random/lang/en/qtype_random.php +++ b/question/type/random/lang/en/qtype_random.php @@ -29,6 +29,11 @@ $string['pluginname'] = 'Random'; $string['pluginname_help'] = 'A random question is not a question type as such, but is a way of inserting a randomly-chosen question from a specified category into an activity.'; $string['pluginnameediting'] = 'Editing a random question'; $string['randomqname'] = 'Random ({$a})'; +$string['randomqnamefromtop'] = 'Faulty random question! Please delete this question.'; $string['randomqplusname'] = 'Random ({$a} and subcategories)'; +$string['randomqplusnamecourse'] = 'Random (Any category in this course)'; +$string['randomqplusnamecoursecat'] = 'Random (Any category inside course category {$a})'; +$string['randomqplusnamemodule'] = 'Random (Any category of this quiz)'; +$string['randomqplusnamesystem'] = 'Random (Any system-level category)'; $string['selectedby'] = '{$a->questionname} selected by {$a->randomname}'; $string['selectmanualquestions'] = 'Random questions can use manually graded questions'; diff --git a/question/type/random/questiontype.php b/question/type/random/questiontype.php index 107e647acd1..aecdaf6f6da 100644 --- a/question/type/random/questiontype.php +++ b/question/type/random/questiontype.php @@ -127,12 +127,36 @@ class qtype_random extends question_type { * @return string the name this question should have. */ public function question_name($category, $includesubcategories) { - if ($includesubcategories) { - $string = 'randomqplusname'; + if ($category->parent && $includesubcategories) { + $name = get_string('randomqplusname', 'qtype_random', shorten_text($category->name, 100)); + } else if ($category->parent) { + $name = get_string('randomqname', 'qtype_random', shorten_text($category->name, 100)); + } else if ($includesubcategories) { + $context = context::instance_by_id($category->contextid); + + switch ($context->contextlevel) { + case CONTEXT_MODULE: + $name = get_string('randomqplusnamemodule', 'qtype_random'); + break; + case CONTEXT_COURSE: + $name = get_string('randomqplusnamecourse', 'qtype_random'); + break; + case CONTEXT_COURSECAT: + $name = get_string('randomqplusnamecoursecat', 'qtype_random', + shorten_text($context->get_context_name(false), 100)); + break; + case CONTEXT_SYSTEM: + $name = get_string('randomqplusnamesystem', 'qtype_random'); + break; + default: // Impossible. + $name = ''; + } } else { - $string = 'randomqname'; + // No question will ever be selected. So, let's warn the teacher. + $name = get_string('randomqnamefromtop', 'qtype_random'); } - return get_string($string, 'qtype_random', shorten_text($category->name, 100)); + + return $name; } protected function set_selected_question_name($question, $randomname) { @@ -143,11 +167,17 @@ class qtype_random extends question_type { } public function save_question($question, $form) { + global $DB; + $form->name = ''; + list($category) = explode(',', $form->category); // In case someone set the question text to true/false in the old style, set it properly. if ($form->questiontext['text']) { $form->questiontext['text'] = '1'; + } else if ($DB->record_exists('question_categories', ['id' => $category, 'parent' => 0])) { + // The chosen category is a top category. + $form->questiontext['text'] = '1'; } else { $form->questiontext['text'] = '0'; }