diff --git a/admin/health.php b/admin/health.php index 66d7b67f957..434f48f6686 100644 --- a/admin/health.php +++ b/admin/health.php @@ -619,6 +619,110 @@ class problem_000014 extends problem_base { } } +class problem_000017 extends problem_base { + function title() { + return 'Question categories tree structure'; + } + function find_problems() { + static $answer = null; + + if (is_null($answer)) { + $categories = get_records('question_categories', '', '', 'id'); + + // Look for missing parents. + $missingparent = array(); + foreach ($categories as $category) { + if ($category->parent != 0 && !array_key_exists($category->parent, $categories)) { + $missingparent[$category->id] = $category; + } + } + + // Look for loops. + $loops = array(); + while (!empty($categories)) { + $current = array_pop($categories); + $thisloop = array($current->id => $current); + while (true) { + if (isset($thisloop[$current->parent])) { + // Loop detected + $loops[$current->id] = $thisloop; + break; + } else if (!isset($categories[$current->parent])) { + // Got to the top level, or a category we already know is OK. + break; + } else { + // Continue following the path. + $current = $categories[$current->parent]; + $thisloop[$current->id] = $current; + unset($categories[$current->id]); + } + } + } + + $answer = array($missingparent, $loops); + } + + return $answer; + } + function exists() { + list($missingparent, $loops) = $this->find_problems(); + return !empty($missingparent) || !empty($loops); + } + function severity() { + return SEVERITY_ANNOYANCE; + } + function description() { + list($missingparent, $loops) = $this->find_problems(); + + $description = '
The question categories should be arranged into tree ' . + ' structures by the question_categories.parent field. Sometimes ' . + ' this tree structure gets messed up.
'; + + if (!empty($missingparent)) { + $description .= 'The following categories are missing their parents:
The following categories form a loop of parents:
Consider executing the following SQL queries. These fix ' . + 'the problem by moving some categories to the top level.
'; + + if (!empty($missingparent)) { + $solution .= "UPDATE " . $CFG->prefix . "question_categories\n" .
+ " SET parent = 0\n" .
+ " WHERE id IN (" . implode(',', array_keys($missingparent)) . ");\n";
+ }
+
+ if (!empty($loops)) {
+ $solution .= "UPDATE " . $CFG->prefix . "question_categories\n" .
+ " SET parent = 0\n" .
+ " WHERE id IN (" . implode(',', array_keys($loops)) . ");\n";
+ }
+
+ return $solution;
+ }
+}
+
class problem_00000x extends problem_base {
function title() {
return '';