Passed
Push — master ( 5dbfd9...75219d )
by Ghazi
01:47
created

BigBlueButton::getInsertDocumentUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
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-2023 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\Enum\HashingAlgorithm;
25
use BigBlueButton\Exceptions\BadResponseException;
26
use BigBlueButton\Parameters\CreateMeetingParameters;
27
use BigBlueButton\Parameters\DeleteRecordingsParameters;
28
use BigBlueButton\Parameters\EndMeetingParameters;
29
use BigBlueButton\Parameters\GetMeetingInfoParameters;
30
use BigBlueButton\Parameters\GetRecordingsParameters;
31
use BigBlueButton\Parameters\GetRecordingTextTracksParameters;
32
use BigBlueButton\Parameters\HooksCreateParameters;
33
use BigBlueButton\Parameters\HooksDestroyParameters;
34
use BigBlueButton\Parameters\InsertDocumentParameters;
35
use BigBlueButton\Parameters\IsMeetingRunningParameters;
36
use BigBlueButton\Parameters\JoinMeetingParameters;
37
use BigBlueButton\Parameters\PublishRecordingsParameters;
38
use BigBlueButton\Parameters\PutRecordingTextTrackParameters;
39
use BigBlueButton\Parameters\UpdateRecordingsParameters;
40
use BigBlueButton\Responses\ApiVersionResponse;
41
use BigBlueButton\Responses\CreateMeetingResponse;
42
use BigBlueButton\Responses\DeleteRecordingsResponse;
43
use BigBlueButton\Responses\EndMeetingResponse;
44
use BigBlueButton\Responses\GetMeetingInfoResponse;
45
use BigBlueButton\Responses\GetMeetingsResponse;
46
use BigBlueButton\Responses\GetRecordingsResponse;
47
use BigBlueButton\Responses\GetRecordingTextTracksResponseResponse;
0 ignored issues
show
Bug introduced by
The type BigBlueButton\Responses\...tTracksResponseResponse 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...
48
use BigBlueButton\Responses\HooksCreateResponse;
49
use BigBlueButton\Responses\HooksDestroyResponse;
50
use BigBlueButton\Responses\HooksListResponse;
51
use BigBlueButton\Responses\InsertDocumentResponse;
52
use BigBlueButton\Responses\IsMeetingRunningResponse;
53
use BigBlueButton\Responses\JoinMeetingResponse;
54
use BigBlueButton\Responses\PublishRecordingsResponse;
55
use BigBlueButton\Responses\PutRecordingTextTrackResponse;
56
use BigBlueButton\Responses\UpdateRecordingsResponse;
57
use BigBlueButton\Util\UrlBuilder;
58
59
/**
60
 * Class BigBlueButton.
61
 */
62
class BigBlueButton
63
{
64
    protected $securitySecret;
65
    protected $bbbServerBaseUrl;
66
    protected $urlBuilder;
67
    protected $jSessionId;
68
69
    protected $hashingAlgorithm;
70
71
    protected $curlopts = [];
72
    protected $timeOut  = 10;
73
74
    /**
75
     * BigBlueButton constructor.
76
     *
77
     * @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...
78
     * @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...
79
     * @param null|mixed $opts
80
     */
81
    public function __construct($baseUrl = null, $secret = null, $opts = null)
82
    {
83
        // Keeping backward compatibility with older deployed versions
84
        // BBB_SECRET is the new variable name and have higher priority against the old named BBB_SECURITY_SALT
85
        $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...
86
        $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...
87
        $this->hashingAlgorithm = HashingAlgorithm::SHA_256;
88
        $this->urlBuilder       = new UrlBuilder($this->securitySecret, $this->bbbServerBaseUrl, $this->hashingAlgorithm);
89
        $this->curlopts         = $opts['curl'] ?? [];
90
    }
91
92
    public function setHashingAlgorithm(string $hashingAlgorithm): void
93
    {
94
        $this->hashingAlgorithm = $hashingAlgorithm;
95
        $this->urlBuilder->setHashingAlgorithm($hashingAlgorithm);
96
    }
97
98
    /**
99
     * @return ApiVersionResponse
100
     *
101
     * @throws \RuntimeException
102
     */
103
    public function getApiVersion()
104
    {
105
        $xml = $this->processXmlResponse($this->urlBuilder->buildUrl());
106
107
        return new ApiVersionResponse($xml);
108
    }
109
110
    // __________________ BBB ADMINISTRATION METHODS _________________
111
    /* The methods in the following section support the following categories of the BBB API:
112
    -- create
113
    -- join
114
    -- end
115
    -- insertDocument
116
    */
117
118
    /**
119
     * @param CreateMeetingParameters $createMeetingParams
120
     *
121
     * @return string
122
     */
123
    public function getCreateMeetingUrl($createMeetingParams)
124
    {
125
        return $this->urlBuilder->buildUrl(ApiMethod::CREATE, $createMeetingParams->getHTTPQuery());
126
    }
127
128
    /**
129
     * @param CreateMeetingParameters $createMeetingParams
130
     *
131
     * @return CreateMeetingResponse
132
     *
133
     * @throws \RuntimeException
134
     */
135
    public function createMeeting($createMeetingParams)
136
    {
137
        $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

137
        $xml = $this->processXmlResponse($this->getCreateMeetingUrl($createMeetingParams), /** @scrutinizer ignore-type */ $createMeetingParams->getPresentationsAsXML());
Loading history...
138
139
        return new CreateMeetingResponse($xml);
140
    }
141
142
    /**
143
     * @param $joinMeetingParams JoinMeetingParameters
144
     *
145
     * @return string
146
     */
147
    public function getJoinMeetingURL($joinMeetingParams)
148
    {
149
        return $this->urlBuilder->buildUrl(ApiMethod::JOIN, $joinMeetingParams->getHTTPQuery());
150
    }
151
152
    /**
153
     * @param $joinMeetingParams JoinMeetingParameters
154
     *
155
     * @return JoinMeetingResponse
156
     *
157
     * @throws \RuntimeException
158
     */
159
    public function joinMeeting($joinMeetingParams)
160
    {
161
        $xml = $this->processXmlResponse($this->getJoinMeetingURL($joinMeetingParams));
162
163
        return new JoinMeetingResponse($xml);
164
    }
165
166
    /**
167
     * @param $endParams EndMeetingParameters
168
     *
169
     * @return string
170
     */
171
    public function getEndMeetingURL($endParams)
172
    {
173
        return $this->urlBuilder->buildUrl(ApiMethod::END, $endParams->getHTTPQuery());
174
    }
175
176
    /**
177
     * @param $endParams EndMeetingParameters
178
     *
179
     * @return EndMeetingResponse
180
     *
181
     * @throws \RuntimeException
182
     *
183
     * */
184
    public function endMeeting($endParams)
185
    {
186
        $xml = $this->processXmlResponse($this->getEndMeetingURL($endParams));
187
188
        return new EndMeetingResponse($xml);
189
    }
190
191
    /**
192
     * @param CreateMeetingParameters $createMeetingParams
193
     *
194
     * @return string
195
     */
196
    public function getInsertDocumentUrl($createMeetingParams)
197
    {
198
        return $this->urlBuilder->buildUrl(ApiMethod::INSERT_DOCUMENT, $createMeetingParams->getHTTPQuery());
199
    }
200
201
    /**
202
     * @param $insertDocumentParams InsertDocumentParameters
203
     *
204
     * @return InsertDocumentResponse
205
     *
206
     * @throws \RuntimeException
207
     */
208
    public function insertDocument($insertDocumentParams)
209
    {
210
        $xml = $this->processXmlResponse($this->getInsertDocumentUrl($insertDocumentParams), $insertDocumentParams->getPresentationsAsXML());
211
212
        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\Responses\InsertDocumentResponse.
Loading history...
213
    }
214
215
    // __________________ BBB MONITORING METHODS _________________
216
    /* The methods in the following section support the following categories of the BBB API:
217
    -- isMeetingRunning
218
    -- getMeetings
219
    -- getMeetingInfo
220
    */
221
222
    /**
223
     * @param $meetingParams IsMeetingRunningParameters
224
     *
225
     * @return string
226
     */
227
    public function getIsMeetingRunningUrl($meetingParams)
228
    {
229
        return $this->urlBuilder->buildUrl(ApiMethod::IS_MEETING_RUNNING, $meetingParams->getHTTPQuery());
230
    }
231
232
    /**
233
     * @param mixed $meetingParams
234
     *
235
     * @return IsMeetingRunningResponse
236
     *
237
     * @throws \RuntimeException
238
     */
239
    public function isMeetingRunning($meetingParams)
240
    {
241
        $xml = $this->processXmlResponse($this->getIsMeetingRunningUrl($meetingParams));
242
243
        return new IsMeetingRunningResponse($xml);
244
    }
245
246
    /**
247
     * @return string
248
     */
249
    public function getMeetingsUrl()
250
    {
251
        return $this->urlBuilder->buildUrl(ApiMethod::GET_MEETINGS);
252
    }
253
254
    /**
255
     * @return GetMeetingsResponse
256
     *
257
     * @throws \RuntimeException
258
     */
259
    public function getMeetings()
260
    {
261
        $xml = $this->processXmlResponse($this->getMeetingsUrl());
262
263
        return new GetMeetingsResponse($xml);
264
    }
265
266
    /**
267
     * @param $meetingParams GetMeetingInfoParameters
268
     *
269
     * @return string
270
     */
271
    public function getMeetingInfoUrl($meetingParams)
272
    {
273
        return $this->urlBuilder->buildUrl(ApiMethod::GET_MEETING_INFO, $meetingParams->getHTTPQuery());
274
    }
275
276
    /**
277
     * @param $meetingParams GetMeetingInfoParameters
278
     *
279
     * @throws \RuntimeException
280
     */
281
    public function getMeetingInfo($meetingParams)
282
    {
283
        $xml = $this->processXmlResponse($this->getMeetingInfoUrl($meetingParams));
284
285
        return new GetMeetingInfoResponse($xml);
286
    }
287
288
    // __________________ BBB RECORDING METHODS _________________
289
    /* The methods in the following section support the following categories of the BBB API:
290
    -- getRecordings
291
    -- publishRecordings
292
    -- deleteRecordings
293
    */
294
295
    /**
296
     * @param $recordingsParams GetRecordingsParameters
297
     *
298
     * @return string
299
     */
300
    public function getRecordingsUrl($recordingsParams)
301
    {
302
        return $this->urlBuilder->buildUrl(ApiMethod::GET_RECORDINGS, $recordingsParams->getHTTPQuery());
303
    }
304
305
    /**
306
     * @param mixed $recordingParams
307
     *
308
     * @throws \RuntimeException
309
     */
310
    public function getRecordings($recordingParams)
311
    {
312
        $xml = $this->processXmlResponse($this->getRecordingsUrl($recordingParams));
313
314
        return new GetRecordingsResponse($xml);
315
    }
316
317
    /**
318
     * @param $recordingParams PublishRecordingsParameters
319
     *
320
     * @return string
321
     */
322
    public function getPublishRecordingsUrl($recordingParams)
323
    {
324
        return $this->urlBuilder->buildUrl(ApiMethod::PUBLISH_RECORDINGS, $recordingParams->getHTTPQuery());
325
    }
326
327
    /**
328
     * @param $recordingParams PublishRecordingsParameters
329
     *
330
     * @throws \RuntimeException
331
     */
332
    public function publishRecordings($recordingParams)
333
    {
334
        $xml = $this->processXmlResponse($this->getPublishRecordingsUrl($recordingParams));
335
336
        return new PublishRecordingsResponse($xml);
337
    }
338
339
    /**
340
     * @param $recordingParams DeleteRecordingsParameters
341
     *
342
     * @return string
343
     */
344
    public function getDeleteRecordingsUrl($recordingParams)
345
    {
346
        return $this->urlBuilder->buildUrl(ApiMethod::DELETE_RECORDINGS, $recordingParams->getHTTPQuery());
347
    }
348
349
    /**
350
     * @param $recordingParams DeleteRecordingsParameters
351
     *
352
     * @return DeleteRecordingsResponse
353
     *
354
     * @throws \RuntimeException
355
     */
356
    public function deleteRecordings($recordingParams)
357
    {
358
        $xml = $this->processXmlResponse($this->getDeleteRecordingsUrl($recordingParams));
359
360
        return new DeleteRecordingsResponse($xml);
361
    }
362
363
    /**
364
     * @param $recordingParams UpdateRecordingsParameters
365
     *
366
     * @return string
367
     */
368
    public function getUpdateRecordingsUrl($recordingParams)
369
    {
370
        return $this->urlBuilder->buildUrl(ApiMethod::UPDATE_RECORDINGS, $recordingParams->getHTTPQuery());
371
    }
372
373
    /**
374
     * @param $recordingParams UpdateRecordingsParameters
375
     *
376
     * @throws \RuntimeException
377
     */
378
    public function updateRecordings($recordingParams)
379
    {
380
        $xml = $this->processXmlResponse($this->getUpdateRecordingsUrl($recordingParams));
381
382
        return new UpdateRecordingsResponse($xml);
383
    }
384
385
    /**
386
     * @param $getRecordingTextTracksParameters GetRecordingTextTracksParameters
387
     *
388
     * @return string
389
     */
390
    public function getRecordingTextTracksUrl($getRecordingTextTracksParameters)
391
    {
392
        return $this->urlBuilder->buildUrl(ApiMethod::GET_RECORDING_TEXT_TRACKS, $getRecordingTextTracksParameters->getHTTPQuery());
393
    }
394
395
    /**
396
     * @param $getRecordingTextTracksParams GetRecordingTextTracksParameters
397
     *
398
     * @return GetRecordingTextTracksResponseResponse
399
     */
400
    public function getRecordingTextTracks($getRecordingTextTracksParams)
401
    {
402
        $json = $this->processJsonResponse($this->getRecordingTextTracksUrl($getRecordingTextTracksParams));
403
404
        return new GetRecordingTextTracksResponseResponse($json);
405
    }
406
407
    /**
408
     * @param $putRecordingTextTrackParams PutRecordingTextTrackParameters
409
     *
410
     * @return string
411
     */
412
    public function getPutRecordingTextTrackUrl(PutRecordingTextTrackParameters $putRecordingTextTrackParams)
413
    {
414
        return $this->urlBuilder->buildUrl(ApiMethod::PUT_RECORDING_TEXT_TRACK, $putRecordingTextTrackParams->getHTTPQuery());
415
    }
416
417
    /**
418
     * @param $putRecordingTextTrackParams PutRecordingTextTrackParameters
419
     *
420
     * @return PutRecordingTextTrackResponse
421
     */
422
    public function putRecordingTextTrack($putRecordingTextTrackParams)
423
    {
424
        $json = $this->processJsonResponse($this->getPutRecordingTextTrackUrl($putRecordingTextTrackParams));
425
426
        return new PutRecordingTextTrackResponse($json);
427
    }
428
429
    // ____________________ WEB HOOKS METHODS ___________________
430
431
    /**
432
     * @param $hookCreateParams HooksCreateParameters
433
     *
434
     * @return string
435
     */
436
    public function getHooksCreateUrl($hookCreateParams)
437
    {
438
        return $this->urlBuilder->buildUrl(ApiMethod::HOOKS_CREATE, $hookCreateParams->getHTTPQuery());
439
    }
440
441
    /**
442
     * @param mixed $hookCreateParams
443
     *
444
     * @return HooksCreateResponse
445
     */
446
    public function hooksCreate($hookCreateParams)
447
    {
448
        $xml = $this->processXmlResponse($this->getHooksCreateUrl($hookCreateParams));
449
450
        return new HooksCreateResponse($xml);
451
    }
452
453
    /**
454
     * @return string
455
     */
456
    public function getHooksListUrl()
457
    {
458
        return $this->urlBuilder->buildUrl(ApiMethod::HOOKS_LIST);
459
    }
460
461
    /**
462
     * @return HooksListResponse
463
     */
464
    public function hooksList()
465
    {
466
        $xml = $this->processXmlResponse($this->getHooksListUrl());
467
468
        return new HooksListResponse($xml);
469
    }
470
471
    /**
472
     * @param $hooksDestroyParams HooksDestroyParameters
473
     *
474
     * @return string
475
     */
476
    public function getHooksDestroyUrl($hooksDestroyParams)
477
    {
478
        return $this->urlBuilder->buildUrl(ApiMethod::HOOKS_DESTROY, $hooksDestroyParams->getHTTPQuery());
479
    }
480
481
    /**
482
     * @param mixed $hooksDestroyParams
483
     *
484
     * @return HooksDestroyResponse
485
     */
486
    public function hooksDestroy($hooksDestroyParams)
487
    {
488
        $xml = $this->processXmlResponse($this->getHooksDestroyUrl($hooksDestroyParams));
489
490
        return new HooksDestroyResponse($xml);
491
    }
492
493
    // ____________________ SPECIAL METHODS ___________________
494
    /**
495
     * @return string
496
     */
497
    public function getJSessionId()
498
    {
499
        return $this->jSessionId;
500
    }
501
502
    /**
503
     * @param string $jSessionId
504
     */
505
    public function setJSessionId($jSessionId)
506
    {
507
        $this->jSessionId = $jSessionId;
508
    }
509
510
    /**
511
     * @param array $curlopts
512
     */
513
    public function setCurlOpts($curlopts)
514
    {
515
        $this->curlopts = $curlopts;
516
    }
517
518
    /**
519
     * Set Curl Timeout (Optional), Default 10 Seconds.
520
     *
521
     * @param int $TimeOutInSeconds
522
     *
523
     * @return static
524
     */
525
    public function setTimeOut($TimeOutInSeconds)
526
    {
527
        $this->timeOut = $TimeOutInSeconds;
528
529
        return $this;
530
    }
531
532
    /**
533
     * Public accessor for buildUrl.
534
     *
535
     * @param string $method
536
     * @param string $params
537
     * @param bool   $append
538
     *
539
     * @return string
540
     */
541
    public function buildUrl($method = '', $params = '', $append = true)
542
    {
543
        return $this->urlBuilder->buildUrl($method, $params, $append);
544
    }
545
546
    // ____________________ INTERNAL CLASS METHODS ___________________
547
548
    /**
549
     * A private utility method used by other public methods to request HTTP responses.
550
     *
551
     * @param string $url
552
     * @param string $payload
553
     * @param string $contentType
554
     *
555
     * @return string
556
     *
557
     * @throws \RuntimeException
558
     */
559
    private function sendRequest($url, $payload = '', $contentType = 'application/xml')
560
    {
561
        if (extension_loaded('curl')) {
562
            $ch = curl_init();
563
            if (!$ch) {
564
                throw new \RuntimeException('Unhandled curl error: ' . curl_error($ch));
565
            }
566
567
            // Needed to store the JSESSIONID
568
            $cookiefile     = tmpfile();
569
            $cookiefilepath = stream_get_meta_data($cookiefile)['uri'];
570
571
            foreach ($this->curlopts as $opt => $value) {
572
                curl_setopt($ch, $opt, $value);
573
            }
574
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
575
            curl_setopt($ch, CURLOPT_ENCODING, 'UTF-8');
576
            curl_setopt($ch, CURLOPT_URL, $url);
577
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
578
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
579
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeOut);
580
            curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiefilepath);
581
            curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefilepath);
582
            if (!empty($payload)) {
583
                curl_setopt($ch, CURLOPT_HEADER, 0);
584
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
585
                curl_setopt($ch, CURLOPT_POST, 1);
586
                curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
587
                curl_setopt($ch, CURLOPT_HTTPHEADER, [
588
                    'Content-type: ' . $contentType,
589
                    'Content-length: ' . mb_strlen($payload),
590
                ]);
591
            }
592
            $data = curl_exec($ch);
593
            if (false === $data) {
594
                throw new \RuntimeException('Unhandled curl error: ' . curl_error($ch));
595
            }
596
            $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
597
            if ($httpcode < 200 || $httpcode >= 300) {
598
                throw new BadResponseException('Bad response, HTTP code: ' . $httpcode);
599
            }
600
            curl_close($ch);
601
            unset($ch);
602
603
            $cookies = file_get_contents($cookiefilepath);
604
            if (false !== mb_strpos($cookies, 'JSESSIONID')) {
605
                preg_match('/(?:JSESSIONID\s*)(?<JSESSIONID>.*)/', $cookies, $output_array);
606
                $this->setJSessionId($output_array['JSESSIONID']);
607
            }
608
609
            return $data;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $data also could return the type true which is incompatible with the documented return type string.
Loading history...
610
        }
611
612
        throw new \RuntimeException('Post XML data set but curl PHP module is not installed or not enabled.');
613
    }
614
615
    /**
616
     * A private utility method used by other public methods to process XML responses.
617
     *
618
     * @param string $url
619
     * @param string $payload
620
     * @param string $contentType
621
     *
622
     * @return \SimpleXMLElement
623
     */
624
    private function processXmlResponse($url, $payload = '', $contentType = 'application/xml')
625
    {
626
        return new \SimpleXMLElement($this->sendRequest($url, $payload, $contentType));
627
    }
628
629
    /**
630
     * A private utility method used by other public methods to process json responses.
631
     */
632
    private function processJsonResponse(string $url, string $payload = '', string $contentType = 'application/json')
633
    {
634
        return $this->sendRequest($url, $payload, $contentType);
635
    }
636
}
637