diff --git a/admin/tool/xmldb/actions/check_foreign_keys/check_foreign_keys.class.php b/admin/tool/xmldb/actions/check_foreign_keys/check_foreign_keys.class.php index 67e886f8e00b9..128b50291671a 100644 --- a/admin/tool/xmldb/actions/check_foreign_keys/check_foreign_keys.class.php +++ b/admin/tool/xmldb/actions/check_foreign_keys/check_foreign_keys.class.php @@ -53,6 +53,8 @@ function init() { 'noviolatedforeignkeysfound' => 'tool_xmldb', 'violatedforeignkeysfound' => 'tool_xmldb', 'violations' => 'tool_xmldb', + 'unknowntable' => 'tool_xmldb', + 'unknownfield' => 'tool_xmldb', )); } @@ -75,6 +77,19 @@ protected function check_table(xmldb_table $xmldb_table, array $metacolumns) { } $o.='
  • ' . $this->str['key'] . ': ' . $xmldb_key->readableInfo() . ' '; + $reftable = $xmldb_key->getRefTable(); + if (!$dbman->table_exists($reftable)) { + $o.='' . $this->str['unknowntable'] . ''; + // Add the missing index to the list + $violation = new stdClass(); + $violation->string = 'fkunknowntable'; + $violation->table = $xmldb_table; + $violation->key = $xmldb_key; + $violation->reftable = $reftable; + $violatedkeys[] = $violation; + continue; + } + // Work out the SQL to find key violations. $keyfields = $xmldb_key->getFields(); $reffields = $xmldb_key->getRefFields(); @@ -82,6 +97,19 @@ protected function check_table(xmldb_table $xmldb_table, array $metacolumns) { $nullnessconditions = array(); $params = array(); foreach ($keyfields as $i => $field) { + if (!$dbman->field_exists($reftable, $reffields[$i])) { + $o.='' . $this->str['unknownfield'] . ''; + // Add the missing index to the list + $violation = new stdClass(); + $violation->string = 'fkunknownfield'; + $violation->table = $xmldb_table; + $violation->key = $xmldb_key; + $violation->reftable = $reftable; + $violation->reffield = $reffields[$i]; + $violatedkeys[] = $violation; + continue 2; + } + $joinconditions[] = 't1.' . $field . ' = t2.' . $reffields[$i]; $xmldb_field = $xmldb_table->getField($field); $default = $xmldb_field->getDefault(); @@ -97,7 +125,7 @@ protected function check_table(xmldb_table $xmldb_table, array $metacolumns) { } $nullnessconditions[] = 't2.id IS NULL'; $sql = 'SELECT count(1) FROM {' . $xmldb_table->getName() . - '} t1 LEFT JOIN {' . $xmldb_key->getRefTable() . '} t2 ON ' . + '} t1 LEFT JOIN {' . $reftable . '} t2 ON ' . implode(' AND ', $joinconditions) . ' WHERE ' . implode(' AND ', $nullnessconditions); @@ -109,6 +137,7 @@ protected function check_table(xmldb_table $xmldb_table, array $metacolumns) { $o.='' . $this->str['violations'] . ''; // Add the missing index to the list $violation = new stdClass; + $violation->string = 'fkviolationdetails'; $violation->table = $xmldb_table; $violation->key = $xmldb_key; $violation->numviolations = $violations; @@ -145,8 +174,11 @@ protected function display_results(array $violatedkeys) { $violation->tablename = $violation->table->getName(); $violation->keyname = $violation->key->getName(); - $r.= '
  • ' .get_string('fkviolationdetails', 'tool_xmldb', $violation) . - '
    ' . s($violation->sql) . '; ' . s($violation->sqlparams) . '
  • '; + $r.= '
  • ' .get_string($violation->string, 'tool_xmldb', $violation); + if (!empty($violation->sql)) { + $r.= '
    ' . s($violation->sql) . '; ' . s($violation->sqlparams) . '
    '; + } + $r.= '
  • '; } $r.= ' '; } else { diff --git a/admin/tool/xmldb/lang/en/tool_xmldb.php b/admin/tool/xmldb/lang/en/tool_xmldb.php index 040cf3acb548a..f89293fbc2349 100644 --- a/admin/tool/xmldb/lang/en/tool_xmldb.php +++ b/admin/tool/xmldb/lang/en/tool_xmldb.php @@ -106,6 +106,8 @@ $string['fieldsusedinkey'] = 'This field is used as key.'; $string['filemodifiedoutfromeditor'] = 'Warning: File locally modified while using the XMLDB Editor. Saving will overwrite local changes.'; $string['filenotwriteable'] = 'File not writeable'; +$string['fkunknownfield'] = 'Foreign key {$a->keyname} on table {$a->tablename} points to a non-existent field {$a->reffield} in referenced table {$a->reftable}.'; +$string['fkunknowntable'] = 'Foreign key {$a->keyname} on table {$a->tablename} points to a non-existent table {$a->reftable}.'; $string['fkviolationdetails'] = 'Foreign key {$a->keyname} on table {$a->tablename} is violated by {$a->numviolations} out of {$a->numrows} rows.'; $string['floatincorrectdecimals'] = 'Incorrect number of decimals for float field'; $string['floatincorrectlength'] = 'Incorrect length for float field'; @@ -183,6 +185,8 @@ $string['table'] = 'Table'; $string['tablenameempty'] = 'The table name cannot be empty'; $string['tables'] = 'Tables'; +$string['unknownfield'] = 'Refers to an unknown field'; +$string['unknowntable'] = 'Refers to an unknown table'; $string['unload'] = 'Unload'; $string['up'] = 'Up'; $string['view'] = 'View';