Skip to content

Commit 08fcaee

Browse files
committed
MBS-10194: Make task more resilient to wrong course values in DB
1 parent cc2f79f commit 08fcaee

3 files changed

Lines changed: 120 additions & 4 deletions

File tree

classes/cachemanager.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,14 @@ public static function build_backlink_cache(int $courseid = 0) {
7373

7474
$records = $DB->get_recordset('learningmap', $conditions, '', 'id, placestore, backlink, course');
7575
foreach ($records as $record) {
76+
// If course does not exist for some reason, avoid running into errors and try to fix record.
77+
if (!$DB->record_exists('course', ['id' => $record->course])) {
78+
helper::repair_learningmap_record($record->id);
79+
continue;
80+
}
7681
$modinfo = get_fast_modinfo($record->course);
7782
$module = $modinfo->instances['learningmap'][$record->id];
7883
$placestore = json_decode($record->placestore);
79-
// If course does not exist for some reason, avoid running into errors.
80-
if (!$DB->record_exists('course', ['id' => $module->course])) {
81-
continue;
82-
}
8384
$coursepageurl = course_get_format($module->course)->get_view_url($module->sectionnum);
8485
$coursepageurl->set_anchor('module-' . $module->id);
8586
foreach ($placestore->places as $place) {

classes/helper.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,54 @@ public static function show_map_on_course_page($cm): bool {
3939
$courseformat = $course->format;
4040
return !empty($showmaponcoursepage) && $courseformat !== 'learningmap';
4141
}
42+
43+
/**
44+
* Repairs a learning map record by checking if the course exists and updating the record accordingly.
45+
*
46+
* @param int $learningmapid The ID of the learning map record to repair.
47+
* @return void
48+
*/
49+
public static function repair_learningmap_record(int $learningmapid): void {
50+
global $DB;
51+
52+
// Check if the learningmap record exists.
53+
if (!$DB->record_exists('learningmap', ['id' => $learningmapid])) {
54+
return;
55+
}
56+
57+
// Attempt to repair the learning map record.
58+
$record = $DB->get_record('learningmap', ['id' => $learningmapid], '*', MUST_EXIST);
59+
60+
if (!$DB->record_exists('course', ['id' => $record->course])) {
61+
// If the course does not exist, try to find the course from the course module.
62+
if (!PHPUNIT_TEST) {
63+
mtrace("Course with id {$record->course} does not exist, trying to find it from course module.");
64+
}
65+
$moduleid = $DB->get_field('modules', 'id', ['name' => 'learningmap']);
66+
if ($moduleid) {
67+
$courseid = $DB->get_field('course_modules', 'course', ['module' => $moduleid, 'instance' => $record->id]);
68+
if ($courseid) {
69+
if ($DB->record_exists('course', ['id' => $courseid])) {
70+
if (!PHPUNIT_TEST) {
71+
mtrace("Updating learning map record to course id {$courseid}.");
72+
}
73+
$record->course = $courseid;
74+
$record->timemodified = time();
75+
$DB->update_record('learningmap', $record);
76+
} else {
77+
if (!PHPUNIT_TEST) {
78+
mtrace(
79+
"Course with id {$courseid} does not exist, learning " .
80+
"map {$record->id} is an orphaned course module."
81+
);
82+
}
83+
}
84+
} else {
85+
if (!PHPUNIT_TEST) {
86+
mtrace("No course module found, learning map with id {$record->id} is an orphaned instance.");
87+
}
88+
}
89+
}
90+
}
91+
}
4292
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
namespace mod_learningmap;
18+
19+
/**
20+
* Tests for Learning map helper class
21+
*
22+
* @package mod_learningmap
23+
* @category test
24+
* @copyright 2025 ISB Bayern
25+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26+
*/
27+
#[\PHPUnit\Framework\Attributes\CoversClass(helper::class)]
28+
#[\PHPUnit\Framework\Attributes\CoversMethod(helper::class, 'repair_learningmap_record')]
29+
final class mod_learningmap_helper_test extends \advanced_testcase {
30+
/**
31+
* Tests the repair_learningmap_record method.
32+
*
33+
* @return void
34+
*/
35+
public function test_repair_learningmap_record(): void {
36+
global $DB;
37+
$this->resetAfterTest();
38+
$this->setAdminUser();
39+
$course = $this->getDataGenerator()->create_course();
40+
$learningmapid = $this->getDataGenerator()->create_module('learningmap', ['course' => $course->id])->id;
41+
42+
$recordbefore = $DB->get_record('learningmap', ['id' => $learningmapid], '*', MUST_EXIST);
43+
helper::repair_learningmap_record($learningmapid);
44+
$recordafter = $DB->get_record('learningmap', ['id' => $learningmapid], '*', MUST_EXIST);
45+
$this->assertEquals($recordbefore->course, $recordafter->course, 'The learning map record should not have changed.');
46+
47+
$DB->update_record('learningmap', ['id' => $learningmapid, 'course' => -1]);
48+
helper::repair_learningmap_record($learningmapid);
49+
$recordafter = $DB->get_record('learningmap', ['id' => $learningmapid], '*', MUST_EXIST);
50+
$this->assertEquals(
51+
$course->id,
52+
$recordafter->course,
53+
'The course id should have been updated in the learning map record.'
54+
);
55+
56+
$DB->delete_records('course', ['id' => $course->id]);
57+
helper::repair_learningmap_record($learningmapid);
58+
$recordafter = $DB->get_record('learningmap', ['id' => $learningmapid], '*', MUST_EXIST);
59+
$this->assertEquals(
60+
$recordbefore->course,
61+
$recordafter->course,
62+
'The learning map record should not have changed after trying to repair it with a non-existing course.'
63+
);
64+
}
65+
}

0 commit comments

Comments
 (0)