Skip to content

Commit 0deccfb

Browse files
Merge pull request #133 from catalyst/issue132-ophaned-records
Issue #132: ensure child records are deleted with their parents
2 parents 2241fdb + 429018c commit 0deccfb

9 files changed

+121
-4
lines changed

classes/observation_manager.php

+1
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ public static function delete_observation_point(int $observationid, int $obpoint
216216

217217
$transaction = $DB->start_delegated_transaction();
218218

219+
$DB->delete_records('observation_point_responses', ['obs_pt_id' => $obpointid]);
219220
$DB->delete_records('observation_points', ['id' => $obpointid, 'obs_id' => $observationid]);
220221

221222
// Shuffle those above down.

classes/session_manager.php

+12
Original file line numberDiff line numberDiff line change
@@ -303,4 +303,16 @@ public static function cancel_session(int $sessionid) {
303303
'finish_time' => time()]);
304304
return;
305305
}
306+
307+
/**
308+
* Deletes observation session
309+
* @param int $observationid ID of the observation instance
310+
* @param int $sessionid ID of the observation session to delete
311+
*/
312+
public static function delete_observation_session(int $observationid, int $sessionid) {
313+
global $DB;
314+
315+
$DB->delete_records('observation_point_responses', ['obs_ses_id' => $sessionid]);
316+
$DB->delete_records('observation_sessions', ['id' => $sessionid, 'obs_id' => $observationid]);
317+
}
306318
}

classes/timeslot_manager.php

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ public static function delete_time_slot(int $observationid, int $slotid, int $ac
155155
self::send_cancellation_message($observationid, $slotid, $timeslot->observee_id, $actioninguserid);
156156
}
157157

158+
$DB->delete_records('observation_notifications', ['timeslot_id' => $slotid]);
158159
$DB->delete_records('observation_timeslots', ['id' => $slotid, 'obs_id' => $observationid]);
159160
}
160161

db/upgrade.php

+26
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,31 @@ function xmldb_observation_upgrade($oldversion) {
108108
upgrade_mod_savepoint(true, 2021052533, 'observation');
109109
}
110110

111+
if ($oldversion < 2024052801) {
112+
// Clean up any orphan records.
113+
$obssqlwhere = 'obs_id NOT IN (SELECT id FROM {observation})';
114+
115+
// Time slots.
116+
$DB->delete_records_select('observation_timeslots', $obssqlwhere);
117+
118+
// Notifications.
119+
$sqlwhere = 'timeslot_id NOT IN (SELECT id FROM {observation_timeslots})';
120+
$DB->delete_records_select('observation_notifications', $sqlwhere);
121+
122+
// Sessions.
123+
$DB->delete_records_select('observation_sessions', $obssqlwhere);
124+
125+
// Points.
126+
$DB->delete_records_select('observation_points', $obssqlwhere);
127+
128+
// Point responses.
129+
$sqlwhere = 'obs_pt_id NOT IN (SELECT id FROM {observation_points})
130+
OR obs_ses_id NOT IN (SELECT id FROM {observation_sessions})';
131+
$DB->delete_records_select('observation_point_responses', $sqlwhere);
132+
133+
// Observation savepoint reached.
134+
upgrade_mod_savepoint(true, 2024052801, 'observation');
135+
}
136+
111137
return true;
112138
}

lib.php

+22-2
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,29 @@ function observation_update_instance($data): bool {
106106
* @return bool true
107107
*/
108108
function observation_delete_instance($id) {
109-
global $DB;
109+
global $DB, $USER;
110+
111+
if (!$observation = $DB->get_record('observation', ['id' => $id])) {
112+
return false;
113+
}
114+
115+
$timeslots = \mod_observation\timeslot_manager::get_time_slots($observation->id);
116+
foreach ($timeslots as $timeslot) {
117+
\mod_observation\timeslot_manager::delete_time_slot($observation->id, $timeslot->id, $USER->id);
118+
}
119+
120+
$sessions = \mod_observation\session_manager::get_sessions($observation->id);
121+
foreach ($sessions as $session) {
122+
\mod_observation\session_manager::delete_observation_session($observation->id, $session->id);
123+
}
124+
125+
$points = \mod_observation\observation_manager::get_observation_points($observation->id);
126+
foreach ($points as $point) {
127+
\mod_observation\observation_manager::delete_observation_point($observation->id, $point->id);
128+
}
129+
130+
$DB->delete_records('observation', ['id' => $observation->id]);
110131

111-
$DB->delete_records('observation', array('id' => $id));
112132
return true;
113133
}
114134

tests/observation_point_test.php

+9
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ private static function create_valid_point($observationid) {
9090
* Tests CRUD operations for observation point with expected data.
9191
*/
9292
public function test_crud_expected () {
93+
global $DB;
94+
9395
$data = self::VALID_DATA;
9496
$data['obs_id'] = $this->instance->id;
9597

@@ -137,6 +139,9 @@ public function test_crud_expected () {
137139
$this->assertTrue(in_array($editeddata->title, array_column($returndata, 'title')));
138140
$this->assertFalse(in_array($data['title'], array_column($returndata, 'title')));
139141

142+
$responses = $DB->get_records('observation_point_responses', ['obs_pt_id' => $returnedpoint->id]);
143+
$this->assertCount(1, $responses);
144+
140145
// Delete point.
141146
\mod_observation\observation_manager::delete_observation_point($this->instance->id, $returnedpoint->id);
142147

@@ -145,6 +150,10 @@ public function test_crud_expected () {
145150

146151
$this->assertEmpty($returndata);
147152

153+
// Confirm response also deleted.
154+
$responses = $DB->get_records('observation_point_responses', ['obs_pt_id' => $returnedpoint->id]);
155+
$this->assertCount(0, $responses);
156+
148157
// Cannot access point as no longer exists (throws exception).
149158
$this->expectException('dml_exception');
150159
\mod_observation\observation_manager::get_existing_point_data($this->instance->id, $returnedpoint->id);

tests/observation_session_test.php

+35
Original file line numberDiff line numberDiff line change
@@ -285,4 +285,39 @@ public function test_start_session_lockout_neg() {
285285
\mod_observation\session_manager::start_session($obid, $oberid, $this->observee->id);
286286
\mod_observation\session_manager::start_session($obid, $oberid, $this->observee2->id);
287287
}
288+
289+
/**
290+
* Tests CRUD operations for observation point with expected data.
291+
*/
292+
public function test_crud_expected() {
293+
global $DB;
294+
295+
// Create session and submit point response.
296+
$sessionid = $this->create_session();
297+
$response = (object)self::VALID_RESPONSE;
298+
\mod_observation\observation_manager::submit_point_response($sessionid, $this->pointid1, $response);
299+
300+
$responses = $DB->get_records('observation_point_responses', ['obs_pt_id' => $this->pointid1]);
301+
$this->assertCount(1, $responses);
302+
303+
// Delete session and test response is also deleted.
304+
\mod_observation\session_manager::delete_observation_session($this->instance->id, $sessionid);
305+
306+
$responses = $DB->get_records('observation_point_responses', ['obs_pt_id' => $this->pointid1]);
307+
$this->assertCount(0, $responses);
308+
309+
// Create another session and submit point response.
310+
$sessionid = $this->create_session();
311+
$response = (object)self::VALID_RESPONSE;
312+
\mod_observation\observation_manager::submit_point_response($sessionid, $this->pointid1, $response);
313+
314+
$responses = $DB->get_records('observation_point_responses', ['obs_pt_id' => $this->pointid1]);
315+
$this->assertCount(1, $responses);
316+
317+
// Delete point and test related responses are deleted.
318+
\mod_observation\observation_manager::delete_observation_point($this->instance->id, $this->pointid1);
319+
320+
$responses = $DB->get_records('observation_point_responses', ['obs_pt_id' => $this->pointid1]);
321+
$this->assertCount(0, $responses);
322+
}
288323
}

tests/timeslot_notification_test.php

+13
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,19 @@ public function test_notification_crud() {
111111

112112
$notifys = \mod_observation\timeslot_manager::get_users_notifications($this->instance->id, $this->observee->id);
113113
$this->assertEquals(0, count($notifys));
114+
115+
// Create a different notification.
116+
\mod_observation\timeslot_manager::create_notification($this->instance->id, $this->slot2id, $this->observee2->id,
117+
(object) self::NOTIFY_DATA);
118+
119+
$notifys = \mod_observation\timeslot_manager::get_users_notifications($this->instance->id, $this->observee2->id);
120+
$this->assertEquals(1, count($notifys));
121+
122+
// Delete timeslot 2 and check notification is also deleted.
123+
\mod_observation\timeslot_manager::delete_time_slot($this->instance->id, $this->slot2id, $this->observer->id);
124+
125+
$notifys = \mod_observation\timeslot_manager::get_users_notifications($this->instance->id, $this->observee2->id);
126+
$this->assertEquals(0, count($notifys));
114127
}
115128

116129
/**

version.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525

2626
defined('MOODLE_INTERNAL') || die();
2727

28-
$plugin->version = 2022041900;
29-
$plugin->release = 2022041900;
28+
$plugin->version = 2024052801;
29+
$plugin->release = 2024052801;
3030
$plugin->requires = 2022041900;
3131
$plugin->component = 'mod_observation';
3232
$plugin->maturity = MATURITY_STABLE;

0 commit comments

Comments
 (0)