Passed
Pull Request — master (#189)
by Ghazi
10:24
created

BigBlueButton::setJSessionId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
/*
4
 * BigBlueButton open source conferencing system - https://www.bigbluebutton.org/.
5
 *
6
 * Copyright (c) 2016-2022 BigBlueButton Inc. and by respective authors (see below).
7
 *
8
 * This program is free software; you can redistribute it and/or modify it under the
9
 * terms of the GNU Lesser General Public License as published by the Free Software
10
 * Foundation; either version 3.0 of the License, or (at your option) any later
11
 * version.
12
 *
13
 * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
14
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15
 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License along
18
 * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
namespace BigBlueButton;
22
23
use BigBlueButton\Core\ApiMethod;
24
use BigBlueButton\Exceptions\BadResponseException;
25
use BigBlueButton\Parameters\CreateMeetingParameters;
26
use BigBlueButton\Parameters\DeleteRecordingsParameters;
27
use BigBlueButton\Parameters\EndMeetingParameters;
28
use BigBlueButton\Parameters\GetMeetingInfoParameters;
29
use BigBlueButton\Parameters\GetRecordingsParameters;
30
use BigBlueButton\Parameters\HooksCreateParameters;
31
use BigBlueButton\Parameters\HooksDestroyParameters;
32
use BigBlueButton\Parameters\InsertDocumentParameters;
33
use BigBlueButton\Parameters\IsMeetingRunningParameters;
34
use BigBlueButton\Parameters\JoinMeetingParameters;
35
use BigBlueButton\Parameters\PublishRecordingsParameters;
36
use BigBlueButton\Parameters\UpdateRecordingsParameters;
37
use BigBlueButton\Responses\ApiVersionResponse;
38
use BigBlueButton\Responses\CreateMeetingResponse;
39
use BigBlueButton\Responses\DeleteRecordingsResponse;
40
use BigBlueButton\Responses\EndMeetingResponse;
41
use BigBlueButton\Responses\GetMeetingInfoResponse;
42
use BigBlueButton\Responses\GetMeetingsResponse;
43
use BigBlueButton\Responses\GetRecordingsResponse;
44
use BigBlueButton\Responses\HooksCreateResponse;
45
use BigBlueButton\Responses\HooksDestroyResponse;
46
use BigBlueButton\Responses\HooksListResponse;
47
use BigBlueButton\Responses\IsMeetingRunningResponse;
48
use BigBlueButton\Responses\JoinMeetingResponse;
49
use BigBlueButton\Responses\PublishRecordingsResponse;
50
use BigBlueButton\Responses\UpdateRecordingsResponse;
51
use BigBlueButton\Util\UrlBuilder;
52
use SimpleXMLElement;
53
54
/**
55
 * Class BigBlueButton.
56
 */
57
class BigBlueButton
58
{
59
    protected $securitySecret;
60
    protected $bbbServerBaseUrl;
61
    protected $urlBuilder;
62
    protected $jSessionId;
63
    protected $timeOut = 10;
64
65
    /**
66
     * BigBlueButton constructor.
67
     *
68
     * @param null       $baseUrl
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $baseUrl is correct as it would always require null to be passed?
Loading history...
69
     * @param null       $secret
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $secret is correct as it would always require null to be passed?
Loading history...
70
     * @param null|mixed $opts
71
     */
72
    public function __construct($baseUrl = null, $secret = null, $opts = null)
73
    {
74
        // Keeping backward compatibility with older deployed versions
75
        // BBB_SECRET is the new variable name and have higher priority against the old named BBB_SECURITY_SALT
76
        $this->securitySecret   = $secret ?: getenv('BBB_SECRET') ?: getenv('BBB_SECURITY_SALT');
0 ignored issues
show
introduced by
$secret is of type null, thus it always evaluated to false.
Loading history...
77
        $this->bbbServerBaseUrl = $baseUrl ?: getenv('BBB_SERVER_BASE_URL');
0 ignored issues
show
introduced by
$baseUrl is of type null, thus it always evaluated to false.
Loading history...
78
        $this->urlBuilder       = new UrlBuilder($this->securitySecret, $this->bbbServerBaseUrl);
79
        $this->curlopts         = $opts['curl'] ?? [];
0 ignored issues
show
Bug Best Practice introduced by
The property curlopts does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
80
    }
81
82
    /**
83
     * @throws \RuntimeException
84
     *
85
     * @return ApiVersionResponse
86
     */
87
    public function getApiVersion()
88
    {
89
        $xml = $this->processXmlResponse($this->urlBuilder->buildUrl());
90
91
        return new ApiVersionResponse($xml);
92
    }
93
94
    // __________________ BBB ADMINISTRATION METHODS _________________
95
    /* The methods in the following section support the following categories of the BBB API:
96
    -- create
97
    -- join
98
    -- end
99
    -- insertDocument
100
    */
101
102
    /**
103
     * @param CreateMeetingParameters $createMeetingParams
104
     *
105
     * @return string
106
     */
107
    public function getCreateMeetingUrl($createMeetingParams)
108
    {
109
        return $this->urlBuilder->buildUrl(ApiMethod::CREATE, $createMeetingParams->getHTTPQuery());
110
    }
111
112
    /**
113
     * @param CreateMeetingParameters $createMeetingParams
114
     *
115
     * @throws \RuntimeException
116
     *
117
     * @return CreateMeetingResponse
118
     */
119
    public function createMeeting($createMeetingParams)
120
    {
121
        $xml = $this->processXmlResponse($this->getCreateMeetingUrl($createMeetingParams), $createMeetingParams->getPresentationsAsXML());
0 ignored issues
show
Bug introduced by
It seems like $createMeetingParams->getPresentationsAsXML() can also be of type true; however, parameter $payload of BigBlueButton\BigBlueButton::processXmlResponse() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

121
        $xml = $this->processXmlResponse($this->getCreateMeetingUrl($createMeetingParams), /** @scrutinizer ignore-type */ $createMeetingParams->getPresentationsAsXML());
Loading history...
122
123
        return new CreateMeetingResponse($xml);
124
    }
125
126
    /**
127
     * @param $joinMeetingParams JoinMeetingParameters
128
     *
129
     * @return string
130
     */
131
    public function getJoinMeetingURL($joinMeetingParams)
132
    {
133
        return $this->urlBuilder->buildUrl(ApiMethod::JOIN, $joinMeetingParams->getHTTPQuery());
134
    }
135
136
    /**
137
     * @param $joinMeetingParams JoinMeetingParameters
138
     *
139
     * @throws \RuntimeException
140
     *
141
     * @return JoinMeetingResponse
142
     */
143
    public function joinMeeting($joinMeetingParams)
144
    {
145
        $xml = $this->processXmlResponse($this->getJoinMeetingURL($joinMeetingParams));
146
147
        return new JoinMeetingResponse($xml);
148
    }
149
150
    /**
151
     * @param $endParams EndMeetingParameters
152
     *
153
     * @return string
154
     */
155
    public function getEndMeetingURL($endParams)
156
    {
157
        return $this->urlBuilder->buildUrl(ApiMethod::END, $endParams->getHTTPQuery());
158
    }
159
160
    /**
161
     * @param $endParams EndMeetingParameters
162
     *
163
     * @throws \RuntimeException
164
     *
165
     * @return EndMeetingResponse
166
     * */
167
    public function endMeeting($endParams)
168
    {
169
        $xml = $this->processXmlResponse($this->getEndMeetingURL($endParams));
170
171
        return new EndMeetingResponse($xml);
172
    }
173
174
    /**
175
     * @param CreateMeetingParameters $createMeetingParams
176
     *
177
     * @return string
178
     */
179
    public function getInsertDocumentUrl($createMeetingParams)
180
    {
181
        return $this->urlBuilder->buildUrl(ApiMethod::INSERT_DOCUMENT, $createMeetingParams->getHTTPQuery());
182
    }
183
184
    /**
185
     * @param InsertDocumentParameters $insertDocumentParams
186
     *
187
     * @throws \RuntimeException
188
     *
189
     * @return InsertDocumentResponse
0 ignored issues
show
Bug introduced by
The type BigBlueButton\InsertDocumentResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
190
     */
191
    public function insertDocument($insertDocumentParams)
192
    {
193
        $xml = $this->processXmlResponse($this->getInsertDocumentUrl($insertDocumentParams), $insertDocumentParams->getPresentationsAsXML());
0 ignored issues
show
Bug introduced by
$insertDocumentParams of type BigBlueButton\Parameters\InsertDocumentParameters is incompatible with the type BigBlueButton\Parameters\CreateMeetingParameters expected by parameter $createMeetingParams of BigBlueButton\BigBlueBut...:getInsertDocumentUrl(). ( Ignorable by Annotation )

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

193
        $xml = $this->processXmlResponse($this->getInsertDocumentUrl(/** @scrutinizer ignore-type */ $insertDocumentParams), $insertDocumentParams->getPresentationsAsXML());
Loading history...
Bug introduced by
It seems like $insertDocumentParams->getPresentationsAsXML() can also be of type true; however, parameter $payload of BigBlueButton\BigBlueButton::processXmlResponse() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

193
        $xml = $this->processXmlResponse($this->getInsertDocumentUrl($insertDocumentParams), /** @scrutinizer ignore-type */ $insertDocumentParams->getPresentationsAsXML());
Loading history...
194
195
        return new CreateMeetingResponse($xml);
0 ignored issues
show
Bug Best Practice introduced by
The expression return new BigBlueButton...teMeetingResponse($xml) returns the type BigBlueButton\Responses\CreateMeetingResponse which is incompatible with the documented return type BigBlueButton\InsertDocumentResponse.
Loading history...
196
    }
197
198
    // __________________ BBB MONITORING METHODS _________________
199
    /* The methods in the following section support the following categories of the BBB API:
200
    -- isMeetingRunning
201
    -- getMeetings
202
    -- getMeetingInfo
203
    */
204
205
    /**
206
     * @param $meetingParams IsMeetingRunningParameters
207
     *
208
     * @return string
209
     */
210
    public function getIsMeetingRunningUrl($meetingParams)
211
    {
212
        return $this->urlBuilder->buildUrl(ApiMethod::IS_MEETING_RUNNING, $meetingParams->getHTTPQuery());
213
    }
214
215
    /**
216
     * @param $meetingParams
217
     *
218
     * @throws \RuntimeException
219
     *
220
     * @return IsMeetingRunningResponse
221
     */
222
    public function isMeetingRunning($meetingParams)
223
    {
224
        $xml = $this->processXmlResponse($this->getIsMeetingRunningUrl($meetingParams));
225
226
        return new IsMeetingRunningResponse($xml);
227
    }
228
229
    /**
230
     * @return string
231
     */
232
    public function getMeetingsUrl()
233
    {
234
        return $this->urlBuilder->buildUrl(ApiMethod::GET_MEETINGS);
235
    }
236
237
    /**
238
     * @throws \RuntimeException
239
     *
240
     * @return GetMeetingsResponse
241
     */
242
    public function getMeetings()
243
    {
244
        $xml = $this->processXmlResponse($this->getMeetingsUrl());
245
246
        return new GetMeetingsResponse($xml);
247
    }
248
249
    /**
250
     * @param $meetingParams GetMeetingInfoParameters
251
     *
252
     * @return string
253
     */
254
    public function getMeetingInfoUrl($meetingParams)
255
    {
256
        return $this->urlBuilder->buildUrl(ApiMethod::GET_MEETING_INFO, $meetingParams->getHTTPQuery());
257
    }
258
259
    /**
260
     * @param $meetingParams GetMeetingInfoParameters
261
     *
262
     * @throws \RuntimeException
263
     *
264
     * @return GetMeetingInfoResponse
265
     */
266
    public function getMeetingInfo($meetingParams)
267
    {
268
        $xml = $this->processXmlResponse($this->getMeetingInfoUrl($meetingParams));
269
270
        return new GetMeetingInfoResponse($xml);
271
    }
272
273
    // __________________ BBB RECORDING METHODS _________________
274
    /* The methods in the following section support the following categories of the BBB API:
275
    -- getRecordings
276
    -- publishRecordings
277
    -- deleteRecordings
278
    */
279
280
    /**
281
     * @param $recordingsParams GetRecordingsParameters
282
     *
283
     * @return string
284
     */
285
    public function getRecordingsUrl($recordingsParams)
286
    {
287
        return $this->urlBuilder->buildUrl(ApiMethod::GET_RECORDINGS, $recordingsParams->getHTTPQuery());
288
    }
289
290
    /**
291
     * @param $recordingParams
292
     *
293
     * @throws \RuntimeException
294
     *
295
     * @return GetRecordingsResponse
296
     */
297
    public function getRecordings($recordingParams)
298
    {
299
        $xml = $this->processXmlResponse($this->getRecordingsUrl($recordingParams));
300
301
        return new GetRecordingsResponse($xml);
302
    }
303
304
    /**
305
     * @param $recordingParams PublishRecordingsParameters
306
     *
307
     * @return string
308
     */
309
    public function getPublishRecordingsUrl($recordingParams)
310
    {
311
        return $this->urlBuilder->buildUrl(ApiMethod::PUBLISH_RECORDINGS, $recordingParams->getHTTPQuery());
312
    }
313
314
    /**
315
     * @param $recordingParams PublishRecordingsParameters
316
     *
317
     * @throws \RuntimeException
318
     *
319
     * @return PublishRecordingsResponse
320
     */
321
    public function publishRecordings($recordingParams)
322
    {
323
        $xml = $this->processXmlResponse($this->getPublishRecordingsUrl($recordingParams));
324
325
        return new PublishRecordingsResponse($xml);
326
    }
327
328
    /**
329
     * @param $recordingParams DeleteRecordingsParameters
330
     *
331
     * @return string
332
     */
333
    public function getDeleteRecordingsUrl($recordingParams)
334
    {
335
        return $this->urlBuilder->buildUrl(ApiMethod::DELETE_RECORDINGS, $recordingParams->getHTTPQuery());
336
    }
337
338
    /**
339
     * @param $recordingParams DeleteRecordingsParameters
340
     *
341
     * @throws \RuntimeException
342
     *
343
     * @return DeleteRecordingsResponse
344
     */
345
    public function deleteRecordings($recordingParams)
346
    {
347
        $xml = $this->processXmlResponse($this->getDeleteRecordingsUrl($recordingParams));
348
349
        return new DeleteRecordingsResponse($xml);
350
    }
351
352
    /**
353
     * @param $recordingParams UpdateRecordingsParameters
354
     *
355
     * @return string
356
     */
357
    public function getUpdateRecordingsUrl($recordingParams)
358
    {
359
        return $this->urlBuilder->buildUrl(ApiMethod::UPDATE_RECORDINGS, $recordingParams->getHTTPQuery());
360
    }
361
362
    /**
363
     * @param $recordingParams UpdateRecordingsParameters
364
     *
365
     * @throws \RuntimeException
366
     *
367
     * @return UpdateRecordingsResponse
368
     */
369
    public function updateRecordings($recordingParams)
370
    {
371
        $xml = $this->processXmlResponse($this->getUpdateRecordingsUrl($recordingParams));
372
373
        return new UpdateRecordingsResponse($xml);
374
    }
375
376
    // ____________________ WEB HOOKS METHODS ___________________
377
378
    /**
379
     * @param $hookCreateParams HooksCreateParameters
380
     *
381
     * @return string
382
     */
383
    public function getHooksCreateUrl($hookCreateParams)
384
    {
385
        return $this->urlBuilder->buildUrl(ApiMethod::HOOKS_CREATE, $hookCreateParams->getHTTPQuery());
386
    }
387
388
    /**
389
     * @param $hookCreateParams
390
     *
391
     * @return HooksCreateResponse
392
     */
393
    public function hooksCreate($hookCreateParams)
394
    {
395
        $xml = $this->processXmlResponse($this->getHooksCreateUrl($hookCreateParams));
396
397
        return new HooksCreateResponse($xml);
398
    }
399
400
    /**
401
     * @return string
402
     */
403
    public function getHooksListUrl()
404
    {
405
        return $this->urlBuilder->buildUrl(ApiMethod::HOOKS_LIST);
406
    }
407
408
    /**
409
     * @return HooksListResponse
410
     */
411
    public function hooksList()
412
    {
413
        $xml = $this->processXmlResponse($this->getHooksListUrl());
414
415
        return new HooksListResponse($xml);
416
    }
417
418
    /**
419
     * @param $hooksDestroyParams HooksDestroyParameters
420
     *
421
     * @return string
422
     */
423
    public function getHooksDestroyUrl($hooksDestroyParams)
424
    {
425
        return $this->urlBuilder->buildUrl(ApiMethod::HOOKS_DESTROY, $hooksDestroyParams->getHTTPQuery());
426
    }
427
428
    /**
429
     * @param $hooksDestroyParams
430
     *
431
     * @return HooksDestroyResponse
432
     */
433
    public function hooksDestroy($hooksDestroyParams)
434
    {
435
        $xml = $this->processXmlResponse($this->getHooksDestroyUrl($hooksDestroyParams));
436
437
        return new HooksDestroyResponse($xml);
438
    }
439
440
    // ____________________ SPECIAL METHODS ___________________
441
    /**
442
     * @return string
443
     */
444
    public function getJSessionId()
445
    {
446
        return $this->jSessionId;
447
    }
448
449
    /**
450
     * @param string $jSessionId
451
     */
452
    public function setJSessionId($jSessionId)
453
    {
454
        $this->jSessionId = $jSessionId;
455
    }
456
457
    /**
458
     * @param array $curlopts
459
     */
460
    public function setCurlOpts($curlopts)
461
    {
462
        $this->curlopts = $curlopts;
0 ignored issues
show
Bug Best Practice introduced by
The property curlopts does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
463
    }
464
465
    /**
466
     * Set Curl Timeout (Optional), Default 10 Seconds.
467
     *
468
     * @param int $TimeOutInSeconds
469
     *
470
     * @return static
471
     */
472
    public function setTimeOut($TimeOutInSeconds)
473
    {
474
        $this->timeOut = $TimeOutInSeconds;
475
476
        return $this;
477
    }
478
479
    /**
480
     * Public accessor for buildUrl.
481
     *
482
     * @param string $method
483
     * @param string $params
484
     * @param bool   $append
485
     *
486
     * @return string
487
     */
488
    public function buildUrl($method = '', $params = '', $append = true)
489
    {
490
        return $this->urlBuilder->buildUrl($method, $params, $append);
491
    }
492
493
    // ____________________ INTERNAL CLASS METHODS ___________________
494
495
    /**
496
     * A private utility method used by other public methods to process XML responses.
497
     *
498
     * @param string $url
499
     * @param string $payload
500
     * @param string $contentType
501
     *
502
     * @throws \RuntimeException
503
     *
504
     * @return SimpleXMLElement
505
     */
506
    private function processXmlResponse($url, $payload = '', $contentType = 'application/xml')
507
    {
508
        if (extension_loaded('curl')) {
509
            $ch = curl_init();
510
            if (!$ch) {
511
                throw new \RuntimeException('Unhandled curl error: ' . curl_error($ch));
512
            }
513
514
            // Needed to store the JSESSIONID
515
            $cookiefile     = tmpfile();
516
            $cookiefilepath = stream_get_meta_data($cookiefile)['uri'];
517
518
            foreach ($this->curlopts as $opt => $value) {
519
                curl_setopt($ch, $opt, $value);
520
            }
521
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
522
            curl_setopt($ch, CURLOPT_ENCODING, 'UTF-8');
523
            curl_setopt($ch, CURLOPT_URL, $url);
524
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
525
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
526
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeOut);
527
            curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiefilepath);
528
            curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefilepath);
529
            if (!empty($payload)) {
530
                curl_setopt($ch, CURLOPT_HEADER, 0);
531
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
532
                curl_setopt($ch, CURLOPT_POST, 1);
533
                curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
534
                curl_setopt($ch, CURLOPT_HTTPHEADER, [
535
                    'Content-type: ' . $contentType,
536
                    'Content-length: ' . mb_strlen($payload),
537
                ]);
538
            }
539
            $data = curl_exec($ch);
540
            if (false === $data) {
541
                throw new \RuntimeException('Unhandled curl error: ' . curl_error($ch));
542
            }
543
            $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
544
            if ($httpcode < 200 || $httpcode >= 300) {
545
                throw new BadResponseException('Bad response, HTTP code: ' . $httpcode);
546
            }
547
            curl_close($ch);
548
            unset($ch);
549
550
            $cookies = file_get_contents($cookiefilepath);
551
            if (false !== mb_strpos($cookies, 'JSESSIONID')) {
552
                preg_match('/(?:JSESSIONID\s*)(?<JSESSIONID>.*)/', $cookies, $output_array);
553
                $this->setJSessionId($output_array['JSESSIONID']);
554
            }
555
556
            return new SimpleXMLElement($data);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type true; however, parameter $data of SimpleXMLElement::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

556
            return new SimpleXMLElement(/** @scrutinizer ignore-type */ $data);
Loading history...
557
        }
558
559
        throw new \RuntimeException('Post XML data set but curl PHP module is not installed or not enabled.');
560
    }
561
}
562