From f285be0eaffbfe2ada1a6d746ec62de547528282 Mon Sep 17 00:00:00 2001 From: tjhunt Date: Wed, 20 Aug 2008 08:52:47 +0000 Subject: [PATCH] MDL-15605 Convert question bank consistency checks described in MoodleDocs (http://docs.moodle.org/en/Development:Question_bank_consistency_check) to health centre checks. --- admin/health.php | 191 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 1 deletion(-) diff --git a/admin/health.php b/admin/health.php index 0fb6e89bc51b5..c8a9a025455da 100644 --- a/admin/health.php +++ b/admin/health.php @@ -525,11 +525,200 @@ function solution() { } return 'Error counter was cleared.'; } else { - return '

Session errors can be caused by:

Reset counter.

'; + return '

Session errors can be caused by:

Reset counter

'; } } } +class problem_000012 extends problem_base { + function title() { + return 'Random questions data consistency'; + } + function exists() { + return record_exists_select('question', "qtype = 'random' AND parent <> id"); + } + function severity() { + return SEVERITY_ANNOYANCE; + } + function description() { + return '

For random questions, question.parent should equal question.id. ' . + 'There are some questions in your database for which this is not true. ' . + 'One way that this could have happened is for random questions restored from backup before ' . + 'MDL-5482 was fixed.

'; + } + function solution() { + global $CFG; + return '

Upgrade to Moodle 1.9.1 or later, or manually execute the SQL

' . + '
UPDATE ' . $CFG->prefix . 'question SET parent = id WHERE qtype = \'random\' and parent <> id;
'; + } +} + +class problem_000013 extends problem_base { + function title() { + return 'Multi-answer questions data consistency'; + } + function exists() { + global $CFG; + $positionexpr = sql_position(sql_concat("','", "q.id", "','"), + sql_concat("','", "qma.sequence", "','")); + return record_exists_sql(" + SELECT * FROM {$CFG->prefix}question q + JOIN {$CFG->prefix}question_multianswer qma ON $positionexpr > 0 + WHERE qma.question <> q.parent") || + record_exists_sql(" + SELECT * FROM {$CFG->prefix}question q + JOIN {$CFG->prefix}question parent_q ON parent_q.id = q.parent + WHERE q.category <> parent_q.category"); + } + function severity() { + return SEVERITY_ANNOYANCE; + } + function description() { + return '

For each sub-question whose id is listed in ' . + 'question_multianswer.sequence, its question.parent field should equal ' . + 'question_multianswer.question; and each sub-question should be in the same ' . + 'category as its parent. There are questions in your database for ' . + 'which this is not the case. One way that this could have happened is ' . + 'for multi-answer questions restored from backup before ' . + 'MDL-14750 was fixed.

'; + } + function solution() { + return '

Upgrade to Moodle 1.9.1 or later, or manually execute the ' . + 'code in question_multianswer_fix_subquestion_parents_and_categories in ' . + '/question/type/multianswer/db/upgrade.php' . + 'from the 1.9 stable branch.

'; + } +} + +class problem_000014 extends problem_base { + function title() { + return 'Only multianswer and random questions should be the parent of another question'; + } + function exists() { + global $CFG; + return record_exists_sql(" + SELECT * FROM {$CFG->prefix}question q + JOIN {$CFG->prefix}question parent_q ON parent_q.id = q.parent + WHERE parent_q.qtype NOT IN ('random', 'multianswer')"); + } + function severity() { + return SEVERITY_ANNOYANCE; + } + function description() { + return '

You have questions that violate this in your databse. ' . + 'You will need to investigate to determine how this happened.

'; + } + function solution() { + return '

It is impossible to give a solution without knowing more about ' . + ' how the problem was caused. You may be able to get help from the ' . + 'Quiz forum.

'; + } +} + +class problem_000015 extends problem_base { + function title() { + return 'Question categories should belong to a valid context'; + } + function exists() { + global $CFG; + return record_exists_sql(" + SELECT qc.*, (SELECT COUNT(1) FROM {$CFG->prefix}question q WHERE q.category = qc.id) AS numquestions + FROM {$CFG->prefix}question_categories qc + LEFT JOIN {$CFG->prefix}context con ON qc.contextid = con.id + WHERE con.id IS NULL"); + } + function severity() { + return SEVERITY_ANNOYANCE; + } + function description() { + global $CFG; + $problemcategories = get_records_sql(" + SELECT qc.id, qc.name, qc.contextid, (SELECT COUNT(1) FROM {$CFG->prefix}question q WHERE q.category = qc.id) AS numquestions + FROM {$CFG->prefix}question_categories qc + LEFT JOIN {$CFG->prefix}context con ON qc.contextid = con.id + WHERE con.id IS NULL + ORDER BY numquestions DESC, qc.name"); + $table = '' . + "\n"; + $maxnumquestions = 0; + if ($problemcategories) { + foreach ($problemcategories as $cat) { + $table .= "\n"; + if ($maxnumquestions < $cat->numquestions) { + $maxnumquestions = $cat->numquestions; + } + } + } + $table .= '
Cat idCategory nameContext idNum Questions
$cat->id/td>" . s($cat->name) . "" . + $cat->contextid ."$cat->numquestions
'; + return '

All question categories are linked to a context id, and, ' . + 'the context they are linked to must exist. The following categories ' . + 'belong to a non-existant category:

' . $table . '

Any of these ' . + 'categories that contain no questions can just be deleted form the database. ' . + 'Other categories will require more thought.

'; + } + function solution() { + global $CFG; + return '

You can delete the empty categories by executing the following SQL:

+DELETE FROM ' . $CFG->prefix . 'question_categories
+WHERE
+    NOT EXIST (SELECT * FROM ' . $CFG->prefix . 'question q WHERE q.category = qc.id)
+AND NOT EXIST (SELECT * FROM ' . $CFG->prefix . 'context context WHERE qc.contextid = con.id)
+        

Any remaining categories that contain questions will require more thought. ' . + 'People in the Quiz forum may be able to help.

'; + } +} + +class problem_000016 extends problem_base { + function title() { + return 'Question categories should belong to the same context as their parent'; + } + function exists() { + global $CFG; + return record_exists_sql(" + SELECT parent_qc.id AS parent, child_qc.id AS child, child_qc.contextid + FROM {$CFG->prefix}question_categories child_qc + JOIN {$CFG->prefix}question_categories parent_qc ON child_qc.parent = parent_qc.id + WHERE child_qc.contextid <> parent_qc.contextid"); + } + function severity() { + return SEVERITY_ANNOYANCE; + } + function description() { + global $CFG; + $problemcategories = get_records_sql(" + SELECT + parent_qc.id AS parentid, parent_qc.name AS parentname, parent_qc.contextid AS parentcon, + child_qc.id AS childid, child_qc.name AS childname, child_qc.contextid AS childcon + FROM {$CFG->prefix}question_categories child_qc + JOIN {$CFG->prefix}question_categories parent_qc ON child_qc.parent = parent_qc.id + WHERE child_qc.contextid <> parent_qc.contextid"); + $table = '' . + '' . + '' . + "\n"; + if ($problemcategories) { + foreach ($problemcategories as $cat) { + $table .= "\n"; + } + } + $table .= '
Child categoryParent category
IdNameContext idIdNameContext id
$cat->childid/td>" . s($cat->childname) . + "$cat->childcon$cat->parentid/td>" . s($cat->parentname) . + "$cat->parentcon
'; + return '

When one question category is the parent of another, then they ' . + 'should both belong to the same context. This is not true for the following categories:

' . + $table; + } + function solution() { + return '

An automated solution is difficult. It depends whether the ' . + 'parent or child category is in the wrong pace.' . + 'People in the Quiz forum may be able to help.

'; + } +} class problem_00000x extends problem_base { function title() {