Skip to content

Commit 8e6f6b0

Browse files
committed
Fix bug in installation/updates to CodeRunner whereby all system-level prototypes were being ophaned rather than properly deleted prior to installation of the latest versions.
1 parent d1b9769 commit 8e6f6b0

File tree

1 file changed

+51
-2
lines changed

1 file changed

+51
-2
lines changed

db/upgradelib.php

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,57 @@ function delete_existing_prototypes($contextid) {
227227
AND q.name LIKE 'BUILT%IN_PROTOTYPE_%'";
228228
$prototypes = $DB->get_records_sql($query, [$contextid]);
229229
foreach ($prototypes as $question) {
230-
$DB->delete_records('question_coderunner_options', ['questionid' => $question->id]);
231-
$DB->delete_records('question', ['id' => $question->id]);
230+
// Use Moodle's proper question deletion API which handles all related tables
231+
// including question_versions, question_bank_entries, and other dependencies.
232+
question_delete_question($question->id);
233+
}
234+
235+
// Clean up any orphaned version records from previous upgrades that used
236+
// the old direct deletion method. Only clean up records that were originally
237+
// BUILTIN_PROTOTYPE questions by checking the naming pattern.
238+
$orphanedversions = $DB->get_records_sql(
239+
"SELECT DISTINCT qv.id
240+
FROM {question_versions} qv
241+
JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid
242+
JOIN {question_categories} qc ON qc.id = qbe.questioncategoryid
243+
LEFT JOIN {question} q ON q.id = qv.questionid
244+
WHERE qc.contextid = ?
245+
AND qc.name = 'CR_PROTOTYPES'
246+
AND q.id IS NULL
247+
AND EXISTS (
248+
SELECT 1 FROM {question_versions} qv2
249+
JOIN {question} q2 ON q2.id = qv2.questionid
250+
WHERE qv2.questionbankentryid = qbe.id
251+
AND q2.name LIKE 'BUILT%IN_PROTOTYPE_%'
252+
)",
253+
[$contextid]
254+
);
255+
256+
if (!empty($orphanedversions)) {
257+
mtrace(" Cleaning up " . count($orphanedversions) . " orphaned prototype version records");
258+
foreach ($orphanedversions as $versionrecord) {
259+
$DB->delete_records('question_versions', ['id' => $versionrecord->id]);
260+
}
261+
}
262+
263+
// Clean up any orphaned bank entries that have no versions left and were
264+
// originally for prototypes.
265+
$orphanedentries = $DB->get_records_sql(
266+
"SELECT DISTINCT qbe.id
267+
FROM {question_bank_entries} qbe
268+
JOIN {question_categories} qc ON qc.id = qbe.questioncategoryid
269+
LEFT JOIN {question_versions} qv ON qv.questionbankentryid = qbe.id
270+
WHERE qc.contextid = ?
271+
AND qc.name = 'CR_PROTOTYPES'
272+
AND qv.id IS NULL",
273+
[$contextid]
274+
);
275+
276+
if (!empty($orphanedentries)) {
277+
mtrace(" Cleaning up " . count($orphanedentries) . " orphaned prototype bank entries");
278+
foreach ($orphanedentries as $entryrecord) {
279+
$DB->delete_records('question_bank_entries', ['id' => $entryrecord->id]);
280+
}
232281
}
233282
}
234283

0 commit comments

Comments
 (0)