Skip to content

Commit f3ecce2

Browse files
Internal: Fix attendance fast migration to read session_id from c_item_property - refs BT#23159
1 parent d4ba418 commit f3ecce2

1 file changed

Lines changed: 26 additions & 8 deletions

File tree

src/CoreBundle/Command/MigrateAttendancesFastCommand.php

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
)]
2727
final class MigrateAttendancesFastCommand extends Command
2828
{
29-
private const RESOURCE_TYPE_ID_ATTENDANCE = 10;
30-
private const RESOURCE_TYPE_GROUP_ATTENDANCE = 10;
29+
public const RESOURCE_TYPE_ID_ATTENDANCE = 10;
30+
public const RESOURCE_TYPE_GROUP_ATTENDANCE = 10;
3131

3232
public function __construct(
3333
private readonly EntityManagerInterface $em,
@@ -72,11 +72,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7272
$hasAttendanceTitle = $this->tableHasColumn('c_attendance', 'title');
7373
$hasAttendanceName = $this->tableHasColumn('c_attendance', 'name');
7474

75+
// At this migration stage, c_attendance.session_id is expected to be removed.
76+
// We only rely on c_item_property.session_id when available.
77+
$hasItemPropertySessionId = $hasItemProperty && $this->tableHasColumn('c_item_property', 'session_id');
78+
7579
if (!$hasItemProperty && !$hasAttendanceCId) {
7680
$io->error('Cannot determine attendance->course mapping: c_item_property does not exist and c_attendance.c_id does not exist.');
7781
return Command::FAILURE;
7882
}
7983

84+
if ($hasItemProperty && !$hasItemPropertySessionId) {
85+
$io->note('c_item_property.session_id is not available. Session context will be stored as NULL in resource_link.');
86+
}
87+
8088
$courseIds = $this->getCourseIdsToProcess($hasItemProperty, $hasAttendanceCId);
8189

8290
if (0 === \count($courseIds)) {
@@ -126,7 +134,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
126134
hasItemProperty: $hasItemProperty,
127135
hasAttendanceCId: $hasAttendanceCId,
128136
hasAttendanceTitle: $hasAttendanceTitle,
129-
hasAttendanceName: $hasAttendanceName
137+
hasAttendanceName: $hasAttendanceName,
138+
hasItemPropertySessionId: $hasItemPropertySessionId
130139
);
131140

132141
if (0 === \count($attendanceRows)) {
@@ -141,9 +150,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
141150
try {
142151
foreach ($attendanceRows as $row) {
143152
$attendanceId = (int) $row['iid'];
144-
145153
$attendanceTitle = $this->pickAttendanceTitle($row, $attendanceId);
146154

155+
// session_id is read from c_item_property (when available).
156+
// Normalize 0 -> NULL as expected by resource_link.session_id.
147157
$attendanceSessionId = isset($row['session_id']) ? (int) $row['session_id'] : 0;
148158
$attendanceSessionId = 0 === $attendanceSessionId ? null : $attendanceSessionId;
149159

@@ -174,6 +184,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
174184
$uuid = Uuid::v4();
175185
$uuidValue = $uuidIsBinary ? $uuid->toBinary() : $uuid->toRfc4122();
176186

187+
// Keep the slug stable and unique by appending the iid.
177188
$slug = (string) $this->slugger->slug($attendanceTitle.'-'.$attendanceId)->lower();
178189

179190
$resourceNodeId = $this->insertResourceNode(
@@ -207,9 +218,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int
207218
'user_id' => $toUserId,
208219
]);
209220

221+
// resource_node.path should be aligned with the course tree: <coursePath>-<nodeId>/
210222
$newPath = $coursePath.'-'.$resourceNodeId.'/';
211223
$this->connection->update('resource_node', ['path' => $newPath], ['id' => $resourceNodeId]);
212224

225+
// Mark attendance as migrated by storing the new resource_node_id.
213226
$this->connection->update('c_attendance', ['resource_node_id' => $resourceNodeId], ['iid' => $attendanceId]);
214227

215228
$displayOrder++;
@@ -267,14 +280,18 @@ private function fetchPendingAttendancesForCourse(
267280
bool $hasItemProperty,
268281
bool $hasAttendanceCId,
269282
bool $hasAttendanceTitle,
270-
bool $hasAttendanceName
283+
bool $hasAttendanceName,
284+
bool $hasItemPropertySessionId
271285
): array {
272286
$selectTitle = $hasAttendanceTitle ? 'a.title' : 'NULL AS title';
273287
$selectName = $hasAttendanceName ? 'a.name' : 'NULL AS name';
274288

289+
// session_id comes ONLY from c_item_property when available, otherwise NULL.
290+
$selectSession = $hasItemPropertySessionId ? 'ip.session_id' : 'NULL';
291+
275292
if ($hasItemProperty) {
276293
return $this->connection->fetchAllAssociative(
277-
"SELECT a.iid, {$selectTitle}, {$selectName}, a.session_id
294+
"SELECT a.iid, {$selectTitle}, {$selectName}, {$selectSession} AS session_id
278295
FROM c_attendance a
279296
INNER JOIN c_item_property ip
280297
ON ip.tool = 'attendance'
@@ -286,10 +303,11 @@ private function fetchPendingAttendancesForCourse(
286303
);
287304
}
288305

289-
// Fallback using legacy c_id
306+
// Fallback using legacy c_id (no c_item_property available).
307+
// At this stage, we cannot infer a session_id, so we store NULL.
290308
if ($hasAttendanceCId) {
291309
return $this->connection->fetchAllAssociative(
292-
"SELECT a.iid, {$selectTitle}, {$selectName}, a.session_id
310+
"SELECT a.iid, {$selectTitle}, {$selectName}, NULL AS session_id
293311
FROM c_attendance a
294312
WHERE a.c_id = :cid AND a.resource_node_id IS NULL
295313
ORDER BY a.iid",

0 commit comments

Comments
 (0)