diff --git a/lib/questionlib.php b/lib/questionlib.php index 75df7ac24de60..904975f9fd064 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 658ecb86cf2d3..144fe2e49096a 100644 --- a/mod/quiz/addrandom.php +++ b/mod/quiz/addrandom.php @@ -85,6 +85,10 @@ 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 f66832e4b28ea..7405ddae66615 100644 --- a/mod/quiz/addrandomform.php +++ b/mod/quiz/addrandomform.php @@ -37,7 +37,6 @@ class quiz_add_random_form extends moodleform { protected function definition() { - global $CFG, $DB; $mform =& $this->_form; $mform->setDisableShortforms(); @@ -49,11 +48,14 @@ protected function definition() { 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 6f771a0aee756..b2c2f2694e821 100644 --- a/question/type/random/edit_random_form.php +++ b/question/type/random/edit_random_form.php @@ -48,11 +48,14 @@ protected function definition() { $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 0e15605c38f80..4c16d912cc393 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_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 107e647acd1a2..aecdaf6f6da75 100644 --- a/question/type/random/questiontype.php +++ b/question/type/random/questiontype.php @@ -127,12 +127,36 @@ public function get_question_options($question) { * @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 @@ protected function set_selected_question_name($question, $randomname) { } 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'; }