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

Version20250310215900   A

Complexity

Total Complexity 40

Size/Duplication

Total Lines 245
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 133
c 1
b 0
f 0
dl 0
loc 245
rs 9.2
wmc 40

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getDescription() 0 3 1
A migrateBbbRecordings() 0 17 3
A migrateBbbMeetings() 0 42 5
A migrateZoomRecordings() 0 17 3
A migrateBbbActivities() 0 25 6
A getEntityById() 0 3 2
A migrateZoomActivities() 0 23 5
A tableExists() 0 7 2
A down() 0 4 1
A migrateZoomMeetings() 0 34 4
C up() 0 40 8

How to fix   Complexity   

Complex Class

Complex classes like Version20250310215900 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Version20250310215900, and based on these observations, apply Extract Interface, too.

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