Passed
Push — master ( 8e22a2...c36d68 )
by Yannick
08:03
created

Version20250310215900::migrateBbbMeetings()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 42
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 31
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 42
rs 9.1128
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
8
9
use Chamilo\CoreBundle\Entity\User;
10
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
11
use Chamilo\CoreBundle\Entity\ConferenceMeeting;
12
use Chamilo\CoreBundle\Entity\ConferenceActivity;
13
use Chamilo\CoreBundle\Entity\ConferenceRecording;
14
use Doctrine\DBAL\Schema\Schema;
15
use Chamilo\CoreBundle\Entity\Course;
16
use Chamilo\CourseBundle\Entity\CGroup;
17
use Chamilo\CoreBundle\Entity\Session;
18
use Exception;
19
20
final class Version20250310215900 extends AbstractMigrationChamilo
21
{
22
    public function getDescription(): string
23
    {
24
        return 'Migrates data from BBB and Zoom plugins to the new conference system using Doctrine persistence.';
25
    }
26
27
    public function up(Schema $schema): void
28
    {
29
        $this->entityManager->beginTransaction();
0 ignored issues
show
Bug introduced by
The method beginTransaction() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

29
        $this->entityManager->/** @scrutinizer ignore-call */ 
30
                              beginTransaction();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
30
31
        try {
32
            // Migrate BBB Meetings
33
            if ($this->tableExists('plugin_bbb_meeting')) {
34
                $this->migrateBbbMeetings();
35
            }
36
37
            // Migrate BBB Activities
38
            if ($this->tableExists('plugin_bbb_room')) {
39
                $this->migrateBbbActivities();
40
            }
41
42
            // Migrate BBB Recordings
43
            if ($this->tableExists('plugin_bbb_meeting_format')) {
44
                $this->migrateBbbRecordings();
45
            }
46
47
            // Migrate Zoom Meetings
48
            if ($this->tableExists('plugin_zoom_meeting')) {
49
                $this->migrateZoomMeetings();
50
            }
51
52
            // Migrate Zoom Activities
53
            if ($this->tableExists('plugin_zoom_meeting_activity')) {
54
                $this->migrateZoomActivities();
55
            }
56
57
            // Migrate Zoom Recordings
58
            if ($this->tableExists('plugin_zoom_recording')) {
59
                $this->migrateZoomRecordings();
60
            }
61
62
            $this->entityManager->flush();
63
            $this->entityManager->commit();
64
        } catch (Exception $e) {
65
            $this->entityManager->rollBack();
66
            error_log('Migration failed: ' . $e->getMessage());
67
        }
68
    }
69
70
    private function migrateBbbMeetings(): void
71
    {
72
        $bbbMeetings = $this->connection->fetchAllAssociative("SELECT * FROM plugin_bbb_meeting");
73
74
        foreach ($bbbMeetings as $bbb) {
75
            $course = $this->getEntityById(Course::class, $bbb['c_id']);
76
            $user = $this->getEntityById(User::class, $bbb['user_id']);
77
            $group = $this->getEntityById(CGroup::class, $bbb['group_id']);
78
            $session = $this->getEntityById(Session::class, $bbb['session_id']);
79
80
            if (!$course) {
81
                continue;
82
            }
83
84
            $meeting = new ConferenceMeeting();
85
            $meeting->setServiceProvider('bbb');
86
            $meeting->setTitle($bbb['meeting_name']);
87
            $meeting->setRemoteId($bbb['remote_id']);
88
            $meeting->setInternalMeetingId($bbb['remote_id']);
89
            $meeting->setAttendeePw($bbb['attendee_pw']);
90
            $meeting->setModeratorPw($bbb['moderator_pw']);
91
            $meeting->setRecord((bool) $bbb['record']);
92
            $meeting->setStatus((int) $bbb['status']);
93
            $meeting->setWelcomeMsg($bbb['welcome_msg']);
94
            $meeting->setVisibility((int) $bbb['visibility']);
95
            $meeting->setVoiceBridge($bbb['voice_bridge']);
96
            $meeting->setVideoUrl($bbb['video_url']);
97
            $meeting->setHasVideoM4v((bool) $bbb['has_video_m4v']);
98
            $meeting->setClosedAt($bbb['closed_at'] ? new \DateTime($bbb['closed_at']) : null);
99
100
            $meeting->setCourse($course);
101
            $meeting->setUser($user);
102
            $meeting->setGroup($group);
103
104
            if ($session) {
105
                $meeting->setSession($session);
106
            }
107
108
            $this->entityManager->persist($meeting);
109
            $this->entityManager->flush();
110
111
            $this->meetingIdMap[$bbb['id']] = $meeting->getId();
112
        }
113
    }
114
115
    private function migrateBbbActivities(): void
116
    {
117
        $bbbActivities = $this->connection->fetchAllAssociative("SELECT * FROM plugin_bbb_room");
118
119
        foreach ($bbbActivities as $activity) {
120
            if (!isset($this->meetingIdMap[$activity['meeting_id']])) {
121
                continue;
122
            }
123
124
            $meeting = $this->entityManager->find(ConferenceMeeting::class, $this->meetingIdMap[$activity['meeting_id']]);
125
            $participant = $this->getEntityById(User::class, $activity['participant_id']);
126
127
            if (!$meeting || !$participant) {
128
                continue;
129
            }
130
131
            $conferenceActivity = new ConferenceActivity();
132
            $conferenceActivity->setMeeting($meeting);
133
            $conferenceActivity->setParticipant($participant);
134
            $conferenceActivity->setInAt(new \DateTime($activity['in_at']));
135
            $conferenceActivity->setOutAt($activity['out_at'] ? new \DateTime($activity['out_at']) : null);
136
            $conferenceActivity->setType('participant');
137
            $conferenceActivity->setEvent('joined');
138
139
            $this->entityManager->persist($conferenceActivity);
140
        }
141
    }
142
143
    private function migrateBbbRecordings(): void
144
    {
145
        $bbbRecordings = $this->connection->fetchAllAssociative("SELECT * FROM plugin_bbb_meeting_format");
146
147
        foreach ($bbbRecordings as $recording) {
148
            $meeting = $this->getEntityById(ConferenceMeeting::class, $recording['meeting_id']);
149
150
            if (!$meeting) {
151
                continue;
152
            }
153
154
            $conferenceRecording = new ConferenceRecording();
155
            $conferenceRecording->setMeeting($meeting);
156
            $conferenceRecording->setFormatType($recording['format_type']);
157
            $conferenceRecording->setResourceUrl($recording['resource_url']);
158
159
            $this->entityManager->persist($conferenceRecording);
160
        }
161
    }
162
163
    private function migrateZoomMeetings(): void
164
    {
165
        $zoomMeetings = $this->connection->fetchAllAssociative("SELECT * FROM plugin_zoom_meeting");
166
167
        foreach ($zoomMeetings as $zoom) {
168
            $course = $this->getEntityById(Course::class, $zoom['course_id']);
169
            $user = $this->getEntityById(User::class, $zoom['user_id']);
170
            $group = $this->getEntityById(CGroup::class, $zoom['group_id']);
171
            $session = $this->getEntityById(Session::class, $zoom['session_id']);
172
173
            if (!$course) {
174
                continue;
175
            }
176
177
            $meeting = new ConferenceMeeting();
178
            $meeting->setServiceProvider('zoom');
179
            $meeting->setRemoteId($zoom['meeting_id']);
180
            $meeting->setTitle($zoom['meeting_list_item_json']);
181
            $meeting->setSignAttendance((bool) $zoom['sign_attendance']);
182
            $meeting->setReasonToSignAttendance($zoom['reason_to_sign_attendance']);
183
            $meeting->setAccountEmail($zoom['account_email']);
184
185
            $meeting->setCourse($course);
186
            $meeting->setUser($user);
187
            $meeting->setGroup($group);
188
189
            if ($session) {
190
                $meeting->setSession($session);
191
            }
192
193
            $this->entityManager->persist($meeting);
194
            $this->entityManager->flush();
195
196
            $this->meetingIdMap[$zoom['id']] = $meeting->getId();
197
        }
198
    }
199
200
    private function migrateZoomActivities(): void
201
    {
202
        $zoomActivities = $this->connection->fetchAllAssociative("SELECT * FROM plugin_zoom_meeting_activity");
203
204
        foreach ($zoomActivities as $activity) {
205
            if (!isset($this->meetingIdMap[$activity['meeting_id']])) {
206
                continue;
207
            }
208
209
            $meeting = $this->entityManager->find(ConferenceMeeting::class, $this->meetingIdMap[$activity['meeting_id']]);
210
            $participant = $this->getEntityById(User::class, $activity['user_id']);
211
212
            if (!$meeting || !$participant) {
213
                continue;
214
            }
215
216
            $conferenceActivity = new ConferenceActivity();
217
            $conferenceActivity->setMeeting($meeting);
218
            $conferenceActivity->setParticipant($participant);
219
            $conferenceActivity->setInAt(new \DateTime($activity['created_at']));
220
            $conferenceActivity->setEvent($activity['event']);
221
222
            $this->entityManager->persist($conferenceActivity);
223
        }
224
    }
225
226
    private function migrateZoomRecordings(): void
227
    {
228
        $zoomRecordings = $this->connection->fetchAllAssociative("SELECT * FROM plugin_zoom_recording");
229
230
        foreach ($zoomRecordings as $recording) {
231
            $meeting = $this->getEntityById(ConferenceMeeting::class, $recording['meeting_id']);
232
233
            if (!$meeting) {
234
                continue;
235
            }
236
237
            $conferenceRecording = new ConferenceRecording();
238
            $conferenceRecording->setMeeting($meeting);
239
            $conferenceRecording->setFormatType('zoom');
240
            $conferenceRecording->setResourceUrl($recording['recording_meeting_json']);
241
242
            $this->entityManager->persist($conferenceRecording);
243
        }
244
    }
245
246
    private function getEntityById(string $entityClass, ?int $id): ?object
247
    {
248
        return $id ? $this->entityManager->find($entityClass, $id) : null;
249
    }
250
251
    private function tableExists(string $tableName): bool
252
    {
253
        try {
254
            $this->connection->executeQuery("SELECT 1 FROM $tableName LIMIT 1");
255
            return true;
256
        } catch (Exception $e) {
257
            return false;
258
        }
259
    }
260
261
    public function down(Schema $schema): void
262
    {
263
        $this->addSql("DELETE FROM conference_meeting WHERE service_provider = 'bbb';");
264
        $this->addSql("DELETE FROM conference_meeting WHERE service_provider = 'zoom';");
265
    }
266
}
267