Merge branch 'MDL-83784_404' of https://github.com/cwarwicker/moodle into MOODLE_404_STABLE
This commit is contained in:
@@ -1067,6 +1067,13 @@ class edit_renderer extends \plugin_renderer_base {
|
||||
$temp->questiontext = '';
|
||||
$temp->name = $structure->describe_random_slot($slot->id);
|
||||
$instancename = quiz_question_tostring($temp);
|
||||
if (strpos($instancename, structure::MISSING_QUESTION_CATEGORY_PLACEHOLDER) !== false) {
|
||||
$label = html_writer::span(
|
||||
get_string('missingcategory', 'mod_quiz'),
|
||||
'badge bg-danger text-white h-50'
|
||||
);
|
||||
$instancename = str_replace(structure::MISSING_QUESTION_CATEGORY_PLACEHOLDER, $label, $instancename);
|
||||
}
|
||||
|
||||
$configuretitle = get_string('configurerandomquestion', 'quiz');
|
||||
$qtype = \question_bank::get_qtype($question->qtype, false);
|
||||
|
||||
@@ -42,6 +42,12 @@ use stdClass;
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class structure {
|
||||
|
||||
/**
|
||||
* Placeholder string used when a question category is missing.
|
||||
*/
|
||||
const MISSING_QUESTION_CATEGORY_PLACEHOLDER = 'missing_question_category';
|
||||
|
||||
/** @var quiz_settings the quiz this is the structure of. */
|
||||
protected $quizobj = null;
|
||||
|
||||
@@ -1759,6 +1765,13 @@ class structure {
|
||||
// Now, put the data required for each slot into $this->randomslotcategories and $this->randomslottags.
|
||||
foreach ($randomcategoriesandtags as $slotid => $catandtags) {
|
||||
$qcategoryid = $catandtags['cat']['values'];
|
||||
|
||||
// If the category does not exist, replace with a temporary placeholder.
|
||||
if (!array_key_exists($qcategoryid, $categories)) {
|
||||
$this->randomslotcategories[$slotid] = self::MISSING_QUESTION_CATEGORY_PLACEHOLDER;
|
||||
continue;
|
||||
}
|
||||
|
||||
$qcategory = $categories[$qcategoryid];
|
||||
$includesubcategories = $catandtags['cat']['includesubcategories'];
|
||||
$this->randomslotcategories[$slotid] = $this->get_used_category_description($qcategory, $includesubcategories);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use core_question\local\bank\filter_condition_manager;
|
||||
use core_question\question_reference_manager;
|
||||
use mod_quiz\quiz_settings;
|
||||
use mod_quiz\question\bank\random_question_view;
|
||||
@@ -58,6 +59,7 @@ $setreference = $DB->get_record('question_set_references',
|
||||
['itemid' => $slot->id, 'component' => 'mod_quiz', 'questionarea' => 'slot']);
|
||||
$filterconditions = json_decode($setreference->filtercondition, true);
|
||||
$filterconditions = question_reference_manager::convert_legacy_set_reference_filter_condition($filterconditions);
|
||||
$filterconditions = filter_condition_manager::filter_invalid_values($filterconditions);
|
||||
|
||||
$params = $filterconditions;
|
||||
$params['cmid'] = $cm->id;
|
||||
@@ -132,9 +134,10 @@ if ($mform->is_cancelled()) {
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
$PAGE->set_title('Random question');
|
||||
$heading = get_string('randomediting', 'mod_quiz');
|
||||
$PAGE->set_title($heading);
|
||||
$PAGE->set_heading($COURSE->fullname);
|
||||
$PAGE->navbar->add('Random question');
|
||||
$PAGE->navbar->add($heading);
|
||||
|
||||
// Custom View.
|
||||
$questionbank = new random_question_view($contexts, $thispageurl, $course, $cm, $params, $extraparams);
|
||||
@@ -151,7 +154,6 @@ $PAGE->requires->js_call_amd('mod_quiz/update_random_question_filter_condition',
|
||||
|
||||
// Display a heading, question editing form.
|
||||
echo $OUTPUT->header();
|
||||
$heading = get_string('randomediting', 'mod_quiz');
|
||||
echo $OUTPUT->heading_with_help($heading, 'randomquestion', 'mod_quiz');
|
||||
echo $updateform;
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
@@ -555,6 +555,7 @@ $string['maxmarks_help'] = 'The maximum mark available for each question.';
|
||||
|
||||
$string['min'] = 'Min';
|
||||
$string['minutes'] = 'Minutes';
|
||||
$string['missingcategory'] = 'Missing question category';
|
||||
$string['missingcorrectanswer'] = 'Correct answer must be specified';
|
||||
$string['missingitemtypename'] = 'Missing name';
|
||||
$string['missingquestion'] = 'This question no longer seems to exist';
|
||||
|
||||
@@ -71,3 +71,18 @@ Feature: Moving a question to another category should not affect random question
|
||||
And I should see "I was edited" in the "Used category new" "list_item"
|
||||
And I am on the "Quiz 1" "mod_quiz > Edit" page
|
||||
And I should see "Random (Used category new) based on filter condition" on quiz page "1"
|
||||
|
||||
@javascript
|
||||
Scenario: A random question with an invalid category should still be editable
|
||||
Given I am on the "Quiz 1" "mod_quiz > Edit" page logged in as "teacher1"
|
||||
When I open the "last" add to quiz menu
|
||||
And I follow "a random question"
|
||||
And I apply question bank filter "Category" with value "Used category"
|
||||
And I press "Add random question"
|
||||
And I should see "Random (Used category) based on filter condition" on quiz page "1"
|
||||
And I am on the "Course 1" "core_question > course question categories" page
|
||||
And I click on "Delete" "link" in the "Used category" "list_item"
|
||||
And I press "Save in category"
|
||||
And I am on the "Quiz 1" "mod_quiz > Edit" page logged in as "teacher1"
|
||||
Then I should not see "Random (Used category) based on filter condition" on quiz page "1"
|
||||
And I should see "Missing question category" on quiz page "1"
|
||||
|
||||
@@ -336,4 +336,35 @@ class category_condition extends condition {
|
||||
public function is_required(): bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function filter_invalid_values(array $filterconditions): array {
|
||||
|
||||
global $DB;
|
||||
|
||||
$defaultcatid = explode(',', $filterconditions['cat'])[0];
|
||||
|
||||
[$insql, $inparams] = $DB->get_in_or_equal($filterconditions['filter']['category']['values']);
|
||||
$categories = $DB->get_records_select('question_categories', "id {$insql}",
|
||||
$inparams, null, 'id');
|
||||
$categoryids = array_keys($categories);
|
||||
|
||||
foreach ($filterconditions['filter']['category']['values'] as $key => $catid) {
|
||||
|
||||
// Check that the category still exists, and if not, remove it from the conditions.
|
||||
if (!in_array($catid, $categoryids)) {
|
||||
unset($filterconditions['filter']['category']['values'][$key]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If we now don't have any valid categories, use the default loaded from the page.
|
||||
if (count($filterconditions['filter']['category']['values']) === 0) {
|
||||
$filterconditions['filter']['category']['values'] = [$defaultcatid];
|
||||
}
|
||||
|
||||
return $filterconditions;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -200,6 +200,21 @@ abstract class condition {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be overridden in condition classes to filter out anything invalid from the filterconditions array.
|
||||
*
|
||||
* This can be applied anywhere where the $filterconditions array exists, to let condition plugins remove elements
|
||||
* from the array, based on their own internal logic/validation. For example, this is used on the
|
||||
* /mod/quiz/editrandom.php page to filter out question categories which no longer exist, which previously
|
||||
* broke the editrandom page.
|
||||
*
|
||||
* @param array $filterconditions
|
||||
* @return array
|
||||
*/
|
||||
public function filter_invalid_values(array $filterconditions): array {
|
||||
return $filterconditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an array of filters, pick the entry that matches the condition key and return it.
|
||||
*
|
||||
|
||||
@@ -117,4 +117,24 @@ class filter_condition_manager {
|
||||
}
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out invalid values from the filterconditions array,
|
||||
*
|
||||
* @param array $filterconditions
|
||||
* @return array
|
||||
* @throws \dml_exception
|
||||
*/
|
||||
public static function filter_invalid_values(array $filterconditions): array {
|
||||
|
||||
$classes = self::get_condition_classes();
|
||||
foreach ($classes as $class) {
|
||||
$condition = new $class();
|
||||
$filterconditions = $condition->filter_invalid_values($filterconditions);
|
||||
}
|
||||
|
||||
return $filterconditions;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
This files describes API changes for code that uses the question API.
|
||||
|
||||
=== 4.4.7 ===
|
||||
* Question bank Condition classes can now implement a function called
|
||||
"filter_invalid_values($filterconditions)" to remove anything from the
|
||||
filterconditions array which is invalid or should not be there.
|
||||
|
||||
=== 4.4 ===
|
||||
* The following previously deprecated methods have been removed and can no longer be used:
|
||||
- `submit_tags_form`
|
||||
|
||||
Reference in New Issue
Block a user