Passed
Pull Request — master (#6532)
by Angel Fernando Quiroz
09:22
created

VideoConferenceCallbackController::__invoke()   F

Complexity

Conditions 28
Paths > 20000

Size

Total Lines 144
Code Lines 90

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 28
eloc 90
c 1
b 0
f 0
nc 2247265
nop 2
dl 0
loc 144
rs 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Controller\Api;
8
9
use Chamilo\CoreBundle\Entity\Course;
10
use Chamilo\CourseBundle\Entity\CGroup;;
11
use Chamilo\CoreBundle\Entity\AccessUrl;
12
use Chamilo\CoreBundle\Entity\ConferenceActivity;
13
use Chamilo\CoreBundle\Entity\ConferenceMeeting;
14
use Chamilo\CoreBundle\Entity\ConferenceRecording;
15
use Chamilo\CoreBundle\Entity\Session;
16
use Chamilo\CoreBundle\Entity\User;
17
use Doctrine\ORM\EntityManagerInterface;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\HttpKernel\Attribute\AsController;
21
22
#[AsController]
23
class VideoConferenceCallbackController
24
{
25
    public function __invoke(Request $request, EntityManagerInterface $em): Response
26
    {
27
        // 1) Decode JSON payload
28
        $payload = json_decode($request->getContent(), true);
29
        if (!is_array($payload)) {
30
            return new Response('Invalid JSON', Response::HTTP_BAD_REQUEST);
31
        }
32
33
        // 2) Find or create the ConferenceMeeting by remoteId + provider
34
        $meetingRepo = $em->getRepository(ConferenceMeeting::class);
35
        $meeting = $meetingRepo->findOneBy([
36
            'remoteId'        => $payload['meeting_id']   ?? null,
37
            'serviceProvider' => $payload['provider']     ?? null,
38
        ]) ?? new ConferenceMeeting();
39
40
        // 3) Map all conference_meeting fields
41
        // --- associations via getReference() to avoid extra queries ---
42
        if (isset($payload['c_id'])) {
43
            // Try to actually fetch the Course entity
44
            $course = $em->find(Course::class, (int)$payload['c_id']);
45
            if ($course !== null) {
46
                $meeting->setCourse($course);
47
            }
48
        }
49
        if (isset($payload['session_id'])) {
50
            $session = $em->find(Session::class, (int)$payload['session_id']);
51
            if ($session !== null) {
52
                $meeting->setSession($session);
53
            }
54
        }
55
        if (isset($payload['access_url_id'])) {
56
            $url = $em->find(AccessUrl::class, (int)$payload['access_url_id']);
57
            if ($url) {
58
                $meeting->setAccessUrl($url);
59
            }
60
        }
61
        if (isset($payload['group_id'])) {
62
            $group = $em->find(CGroup::class, (int)$payload['group_id']);
63
            if ($group) {
64
                $meeting->setGroup($group);
65
            }
66
        }
67
        if (isset($payload['user_id'])) {
68
            $user = $em->find(User::class, (int)$payload['user_id']);
69
            if ($user) {
70
                $meeting->setUser($user);
71
            }
72
        }
73
        if (isset($payload['calendar_id'])) {
74
            $meeting->setCalendarId((int)$payload['calendar_id']);
75
        }
76
77
        // --- simple fields ---
78
        $meeting
79
            ->setServiceProvider($payload['provider']     ?? $meeting->getServiceProvider())
80
            ->setRemoteId($payload['meeting_id']          ?? $meeting->getRemoteId())
81
            ->setInternalMeetingId($payload['internal_meeting_id'] ?? $meeting->getInternalMeetingId())
82
            ->setTitle($payload['title']                  ?? $meeting->getTitle())
83
            ->setAttendeePw($payload['attendee_pw']       ?? $meeting->getAttendeePw())
84
            ->setModeratorPw($payload['moderator_pw']     ?? $meeting->getModeratorPw())
85
            ->setRecord((bool)($payload['record']         ?? $meeting->isRecord()))
86
            ->setStatus((int)($payload['status']          ?? $meeting->getStatus()))
87
            ->setWelcomeMsg($payload['welcome_msg']       ?? $meeting->getWelcomeMsg())
88
            ->setVisibility((int)($payload['visibility']  ?? $meeting->getVisibility()))
89
            ->setVoiceBridge($payload['voice_bridge']     ?? $meeting->getVoiceBridge())
90
            ->setVideoUrl($payload['video_url']           ?? $meeting->getVideoUrl())
91
            ->setHasVideoM4v((bool)($payload['has_video_m4v'] ?? $meeting->isHasVideoM4v()))
92
            ->setMeetingListItem($payload['meeting_list_item'] ?? $meeting->getMeetingListItem())
93
            ->setMeetingInfoGet($payload['meeting_info_get']   ?? $meeting->getMeetingInfoGet())
94
            ->setSignAttendance((bool)($payload['sign_attendance'] ?? $meeting->isSignAttendance()))
95
            ->setReasonToSignAttendance($payload['reason_to_sign_attendance'] ?? $meeting->getReasonToSignAttendance())
96
            ->setAccountEmail($payload['account_email']   ?? $meeting->getAccountEmail())
97
            ->setWebinarSchema($payload['webinar_schema'] ?? $meeting->getWebinarSchema());
98
99
        // --- timestamps: createdAt set in constructor, override closedAt if provided ---
100
        if (isset($payload['closed_at'])) {
101
            $meeting->setClosedAt(new \DateTime($payload['closed_at']));
102
        }
103
104
        // Persist if this is a new meeting
105
        if ($meeting->getId() === null) {
106
            $em->persist($meeting);
107
        }
108
109
        // 4) Persist a ConferenceRecording if recording_url is present
110
        if (!empty($payload['recording_url'])) {
111
            $rec = new ConferenceRecording();
112
            $rec
113
                ->setMeeting($meeting)
114
                ->setFormatType($payload['format_type'] ?? 'unknown')
115
                ->setResourceUrl($payload['recording_url']);
116
            $em->persist($rec);
117
        }
118
119
        // 5) Always persist the ConferenceActivity event
120
        if (isset($payload['participant_id'])) {
121
122
            $user = $em->find(User::class, (int)$payload['participant_id']);
123
            if ($user !== null) {
124
                $act = new ConferenceActivity();
125
                $act->setParticipant($user);
126
                $act->setMeeting($meeting);
127
128
                // map inAt/outAt either via explicit fields or via action+timestamp
129
                if (isset($payload['in_at'])) {
130
                    $act->setInAt(new \DateTime($payload['in_at']));
131
                } elseif (($payload['action'] ?? '') === 'join') {
132
                    $act->setInAt(new \DateTime($payload['timestamp'] ?? 'now'));
133
                }
134
135
                if (isset($payload['out_at'])) {
136
                    $act->setOutAt(new \DateTime($payload['out_at']));
137
                } elseif (($payload['action'] ?? '') === 'leave') {
138
                    $act->setOutAt(new \DateTime($payload['timestamp'] ?? 'now'));
139
                }
140
141
                // other activity fields
142
                if (isset($payload['close'])) {
143
                    $act->setClose((bool)$payload['close']);
144
                }
145
                if (isset($payload['type'])) {
146
                    $act->setType($payload['type']);
147
                }
148
                if (isset($payload['event'])) {
149
                    $act->setEvent($payload['event']);
150
                }
151
                if (isset($payload['activity_data'])) {
152
                    $act->setActivityData($payload['activity_data']);
153
                }
154
                if (isset($payload['signature_file'])) {
155
                    $act->setSignatureFile($payload['signature_file']);
156
                }
157
                if (isset($payload['signed_at'])) {
158
                    $act->setSignedAt(new \DateTime($payload['signed_at']));
159
                }
160
161
                $em->persist($act);
162
            }
163
        }
164
165
        // 6) Flush everything in one transaction
166
        $em->flush();
167
168
        return new Response('OK', Response::HTTP_OK);
169
    }
170
}
171