OpenVidu   A
last analyzed

Complexity

Total Complexity 40

Size/Duplication

Total Lines 306
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 114
c 4
b 0
f 0
dl 0
loc 306
rs 9.2
wmc 40

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A createSession() 0 5 1
A getActiveSessions() 0 6 2
A getRecording() 0 10 3
A sendSignal() 0 16 5
A setClient() 0 3 1
A client() 0 20 2
A stopRecording() 0 18 5
A getRecordings() 0 13 3
A getSession() 0 6 2
A deleteRecording() 0 15 4
A existsSession() 0 3 1
B startRecording() 0 34 10

How to fix   Complexity   

Complex Class

Complex classes like OpenVidu 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 OpenVidu, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace SquareetLabs\LaravelOpenVidu;
4
5
use Exception;
6
use GuzzleHttp\Client;
7
use GuzzleHttp\RequestOptions;
8
use Illuminate\Support\Facades\Cache;
9
use Psr\SimpleCache\InvalidArgumentException;
10
use SquareetLabs\LaravelOpenVidu\Builders\RecordingBuilder;
11
use SquareetLabs\LaravelOpenVidu\Enums\Uri;
12
use SquareetLabs\LaravelOpenVidu\Exceptions\OpenViduException;
13
use SquareetLabs\LaravelOpenVidu\Exceptions\OpenViduProblemWithBodyParameterException;
14
use SquareetLabs\LaravelOpenVidu\Exceptions\OpenViduRecordingNotFoundException;
15
use SquareetLabs\LaravelOpenVidu\Exceptions\OpenViduRecordingResolutionException;
16
use SquareetLabs\LaravelOpenVidu\Exceptions\OpenViduRecordingStatusException;
17
use SquareetLabs\LaravelOpenVidu\Exceptions\OpenViduServerRecordingIsDisabledException;
18
use SquareetLabs\LaravelOpenVidu\Exceptions\OpenViduSessionCantRecordingException;
19
use SquareetLabs\LaravelOpenVidu\Exceptions\OpenViduSessionHasNotConnectedParticipantsException;
20
use SquareetLabs\LaravelOpenVidu\Exceptions\OpenViduSessionNotFoundException;
21
22
/**
23
 * Class OpenVidu
24
 * @package App\SquareetLabs\LaravelOpenVidu
25
 */
26
class OpenVidu
27
{
28
    /**
29
     * @var Client
30
     */
31
    private $client;
32
33
    /**
34
     * @var
35
     */
36
    private $config;
37
38
39
    /**
40
     * SmsUp constructor.
41
     * @param  array  $config
42
     */
43
    public function __construct(array $config)
44
    {
45
        $this->config = $config;
46
    }
47
48
    /**
49
     * @param  SessionProperties|null  $properties
50
     * @return Session
51
     * @throws Exceptions\OpenViduException
52
     */
53
    public function createSession(?SessionProperties $properties = null): Session
54
    {
55
        $session = new Session($this->client(), null, $properties);
56
        Cache::store('openvidu')->forever($session->getSessionId(), $session->toJson());
57
        return $session;
58
    }
59
60
    /**
61
     * @return Client
62
     */
63
    private function client(): Client
64
    {
65
        if ($this->client) {
66
            return $this->client;
67
        }
68
69
        $client = new Client([
70
            'headers' => [
71
                'Content-Type' => 'application/json',
72
                'Accept' => 'application/json',
73
            ],
74
            'auth' => [
75
                $this->config['app'], $this->config['secret']
76
            ],
77
            'base_uri' => $this->config['domain'] . ':' . $this->config['port'],
78
            'debug' => $this->config['debug'],
79
            'http_errors' => false,
80
            'verify' => false
81
        ]);
82
        return $client;
83
    }
84
85
    /**
86
     * @param  Client  $client
87
     */
88
    public function setClient(Client $client)
89
    {
90
        $this->client = $client;
91
    }
92
93
    /**
94
     * Starts the recording of a {@see Session}
95
     * @param  RecordingProperties  $properties
96
     * @return Recording
97
     * @throws OpenViduException
98
     * @throws OpenViduRecordingResolutionException
99
     * @throws OpenViduServerRecordingIsDisabledException
100
     * @throws OpenViduSessionCantRecordingException
101
     * @throws OpenViduSessionHasNotConnectedParticipantsException
102
     * @throws OpenViduSessionNotFoundException
103
     * @throws InvalidArgumentException
104
     * @throws Exceptions\OpenViduInvalidArgumentException
105
     */
106
    public function startRecording(RecordingProperties $properties): Recording
107
    {
108
        $activeSession = $this->getSession($properties->session());
109
        if ($activeSession->isBeingRecorded()) {
110
            $lastRecordingId = $activeSession->getLastRecordingId();
111
            if (!$lastRecordingId) {
112
                throw new OpenViduSessionCantRecordingException("The session is not configured for using media routed or has recording problems");
113
            }
114
            return $this->getRecording($lastRecordingId);
115
        }
116
        $response = $this->client()->post(Uri::RECORDINGS_START, [
117
            RequestOptions::JSON => $properties->toArray() ?? null
118
        ]);
119
        switch ($response->getStatusCode()) {
120
            case 200:
121
                $recording = RecordingBuilder::build(json_decode($response->getBody()->getContents(), true));
122
123
                if ($activeSession != null) {
124
                    $activeSession->setIsBeingRecorded(true);
125
                    $activeSession->setLastRecordingId($recording->getId());
126
                }
127
                return $recording;
128
            case 404:
129
                throw new OpenViduSessionNotFoundException();
130
            case 406:
131
                throw new OpenViduSessionHasNotConnectedParticipantsException();
132
            case 409:
133
                throw new OpenViduSessionCantRecordingException("The session is not configured for using media routed or it is already being recorded");
134
            case 422:
135
                throw new OpenViduRecordingResolutionException();
136
            case 501:
137
                throw new OpenViduServerRecordingIsDisabledException();
138
            default:
139
                throw new OpenViduException("Invalid response status code " . $response->getStatusCode(), $response->getStatusCode());
140
        }
141
    }
142
143
    /**
144
     * Gets an existing {@see Session}
145
     * @param  string  $sessionId
146
     * @return Session
147
     * @throws OpenViduException
148
     * @throws OpenViduSessionNotFoundException
149
     * @throws InvalidArgumentException
150
     */
151
    public function getSession(string $sessionId): Session
152
    {
153
        if (Cache::store('openvidu')->has($sessionId)) {
154
            return (new Session($this->client(), $sessionId))->fromJson(Cache::store('openvidu')->get($sessionId));
155
        }
156
        throw new OpenViduSessionNotFoundException();
157
    }
158
159
    /**
160
     * Gets an existing {@see Recording}
161
     * @param  string  $recordingId  The `id` property of the {@see Recording} you want to retrieve
162
     * @return Recording
163
     * @throws Exceptions\OpenViduInvalidArgumentException
164
     * @throws OpenViduException
165
     * @throws OpenViduRecordingNotFoundException
166
     */
167
    public function getRecording(string $recordingId): Recording
168
    {
169
        $response = $this->client()->get(Uri::RECORDINGS_URI . '/' . $recordingId);
170
        switch ($response->getStatusCode()) {
171
            case 200:
172
                return RecordingBuilder::build(json_decode($response->getBody()->getContents(), true));
173
            case 404:
174
                throw new OpenViduRecordingNotFoundException();
175
            default:
176
                throw new OpenViduException("Invalid response status code " . $response->getStatusCode(), $response->getStatusCode());
177
        }
178
    }
179
180
    /**
181
     * Check if exists {@see Session}
182
     * @param  string  $sessionId
183
     * @return bool
184
     * @throws InvalidArgumentException
185
     */
186
    public function existsSession(string $sessionId): bool
187
    {
188
        return Cache::store('openvidu')->has($sessionId);
189
    }
190
191
    /**
192
     * Stops the recording of a {@see Session}
193
     * @param  string  $recordingId  The `id` property of the {@see Recording} you want to stop
194
     * @return Recording
195
     * @throws OpenViduException
196
     * @throws OpenViduRecordingNotFoundException
197
     * @throws OpenViduRecordingStatusException
198
     * @throws OpenViduSessionNotFoundException
199
     * @throws InvalidArgumentException
200
     * @throws Exceptions\OpenViduInvalidArgumentException
201
     */
202
    public function stopRecording(string $recordingId): Recording
203
    {
204
        $response = $this->client()->post(Uri::RECORDINGS_STOP . '/' . $recordingId);
205
        switch ($response->getStatusCode()) {
206
            case 200:
207
                $recording = RecordingBuilder::build(json_decode($response->getBody()->getContents(), true));
208
                $activeSession = $this->getSession($recording->getSessionId());
209
                if ($activeSession != null) {
210
                    $activeSession->setIsBeingRecorded(false);
211
                    $activeSession->setLastRecordingId($recordingId);
212
                }
213
                return $recording;
214
            case 404:
215
                throw new OpenViduRecordingNotFoundException();
216
            case 406:
217
                throw new OpenViduRecordingStatusException("The recording has `starting` status. Wait until `started` status before stopping the recording.");
218
            default:
219
                throw new OpenViduException("Invalid response status code " . $response->getStatusCode(), $response->getStatusCode());
220
        }
221
    }
222
223
    /**
224
     * Gets an array with all existing recordings
225
     * @return array
226
     * @throws OpenViduException
227
     * @throws Exceptions\OpenViduInvalidArgumentException
228
     */
229
    public function getRecordings(): array
230
    {
231
        $recordings = [];
232
        $response = $this->client()->get(Uri::RECORDINGS_URI);
233
        switch ($response->getStatusCode()) {
234
            case 200:
235
                $items = json_decode($response->getBody()->getContents(), true);
236
                foreach ($items as $item) {
237
                    $recordings[] = RecordingBuilder::build($item);
238
                }
239
                return $recordings;
240
            default:
241
                throw new OpenViduException("Invalid response status code " . $response->getStatusCode(), $response->getStatusCode());
242
        }
243
    }
244
245
246
    /**
247
     * Deletes a {@see Recording}. The recording must have status `stopped`, `ready` or `failed`
248
     * @param  string  $recordingId  The `id` property of the {@see Recording} you want to delete
249
     * @return bool
250
     * @throws OpenViduException
251
     * @throws OpenViduRecordingNotFoundException
252
     * @throws OpenViduRecordingStatusException
253
     */
254
    public function deleteRecording(string $recordingId): bool
255
    {
256
        $response = $this->client()->delete(Uri::RECORDINGS_URI . '/' . $recordingId);
257
258
        switch ($response->getStatusCode()) {
259
            case 200:
260
                return true;
261
            case 404:
262
                throw new OpenViduRecordingNotFoundException();
263
                break;
264
            case 409:
265
                throw new OpenViduRecordingStatusException("The recording has `started` status. Stop it before deletion.");
266
                break;
267
            default:
268
                throw new OpenViduException("Invalid response status code " . $response->getStatusCode(), $response->getStatusCode());
269
        }
270
    }
271
272
    /**
273
     * Returns the list of active sessions. <strong>This value will remain unchanged
274
     * since the last time method {@link SquareetLabs\LaravelOpenVidu#fetch()}
275
     * was called</strong>. Exceptions to this rule are:
276
     * <ul>
277
     * <li>Calling {@see Session::fetch} updates that
278
     * specific Session status</li>
279
     * <li>Calling {@see Session::close()} automatically
280
     * removes the Session from the list of active Sessions</li>
281
     * <li>Calling
282
     * {@see Session::forceDisconnect(string)}
283
     * automatically updates the inner affected connections for that specific
284
     * Session</li>
285
     * <li>Calling {@see Session::forceUnpublish(string)}
286
     * also automatically updates the inner affected connections for that specific
287
     * Session</li>
288
     * <li>Calling {@see OpenVidu::startRecording(string)}
289
     * and {@see LaravelOpenVidu::stopRecording(string)}
290
     * automatically updates the recording status of the Session
291
     * </ul>
292
     * <br>
293
     * To get the list of active sessions with their current actual value, you must
294
     * call first {@see OpenVidu::fetch()} and then
295
     * {@see OpenVidu::getActiveSessions()}
296
     * @throws OpenViduException
297
     */
298
    public function getActiveSessions(): array
299
    {
300
        try {
301
            return Cache::store('openvidu')->getAll();
302
        } catch (Exception $e) {
303
            throw new OpenViduException("Make sure you have correctly configured the openvidu cache driver.", 500);
304
        }
305
    }
306
307
    /**
308
     * Sends signal to session with given SignalProperties
309
     * @param  SignalProperties  $properties
310
     * @return bool
311
     * @throws OpenViduException
312
     * @throws OpenViduProblemWithBodyParameterException
313
     * @throws OpenViduSessionHasNotConnectedParticipantsException
314
     * @throws OpenViduSessionNotFoundException
315
     */
316
    public function sendSignal(SignalProperties $properties): bool
317
    {
318
        $response = $this->client()->post(Uri::SIGNAL_URI, [
319
            RequestOptions::JSON => $properties->toArray() ?? null
320
        ]);
321
        switch ($response->getStatusCode()) {
322
            case 200:
323
                return true;
324
            case 400:
325
                throw new OpenViduProblemWithBodyParameterException();
326
            case 404:
327
                throw new OpenViduSessionNotFoundException();
328
            case 406:
329
                throw new OpenViduSessionHasNotConnectedParticipantsException();
330
            default:
331
                throw new OpenViduException("Invalid response status code " . $response->getStatusCode(), $response->getStatusCode());
332
        }
333
    }
334
}
335
336