Skip to content

Commit 274c583

Browse files
committed
Improve code to phpstan level 7
1 parent 363c964 commit 274c583

5 files changed

Lines changed: 107 additions & 68 deletions

File tree

phpstan.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
parameters:
2-
level: 6
2+
level: 7
33
paths:
44
- src/
55
- tests/

src/BigBlueButton.php

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ public function __construct(?string $baseUrl = null, ?string $secret = null, ?ar
8080
{
8181
// Keeping backward compatibility with older deployed versions
8282
// BBB_SECRET is the new variable name and have higher priority against the old named BBB_SECURITY_SALT
83-
$this->securitySecret = $secret ?: getenv('BBB_SECRET') ?: getenv('BBB_SECURITY_SALT');
84-
$this->bbbServerBaseUrl = $baseUrl ?: getenv('BBB_SERVER_BASE_URL');
83+
$this->securitySecret = $secret ?: getenv('BBB_SECRET') ?: getenv('BBB_SECURITY_SALT') ?: '';
84+
$this->bbbServerBaseUrl = $baseUrl ?: getenv('BBB_SERVER_BASE_URL') ?: '';
8585
$this->hashingAlgorithm = HashingAlgorithm::SHA_256;
8686
$this->urlBuilder = new UrlBuilder($this->securitySecret, $this->bbbServerBaseUrl, $this->hashingAlgorithm);
8787
$this->curlOpts = $opts['curl'] ?? [];
@@ -117,7 +117,7 @@ public function getCreateMeetingUrl(CreateMeetingParameters $createMeetingParams
117117
}
118118

119119
/**
120-
* @throws \RuntimeException
120+
* @throws BadResponseException|\RuntimeException
121121
*/
122122
public function createMeeting(CreateMeetingParameters $createMeetingParams): CreateMeetingResponse
123123
{
@@ -186,7 +186,7 @@ public function getIsMeetingRunningUrl(IsMeetingRunningParameters $meetingParams
186186
/**
187187
* @param mixed $meetingParams
188188
*
189-
* @throws \RuntimeException
189+
* @throws BadResponseException|\RuntimeException
190190
*/
191191
public function isMeetingRunning($meetingParams): IsMeetingRunningResponse
192192
{
@@ -201,7 +201,7 @@ public function getMeetingsUrl(): string
201201
}
202202

203203
/**
204-
* @throws \RuntimeException
204+
* @throws BadResponseException|\RuntimeException
205205
*/
206206
public function getMeetings(): GetMeetingsResponse
207207
{
@@ -410,65 +410,85 @@ public function buildUrl(string $method = '', string $params = '', bool $append
410410
*/
411411
private function sendRequest(string $url, string $payload = '', string $contentType = 'application/xml'): string
412412
{
413-
if (extension_loaded('curl')) {
414-
$ch = curl_init();
415-
if (!$ch) { // @phpstan-ignore-line
416-
throw new \RuntimeException('Unhandled curl error: ' . curl_error($ch));
417-
}
413+
if (!extension_loaded('curl')) {
414+
throw new \RuntimeException('Post XML data set but curl PHP module is not installed or not enabled.');
415+
}
416+
417+
$ch = curl_init();
418+
$cookieFile = tmpfile();
418419

419-
// Needed to store the JSESSIONID
420-
$cookieFile = tmpfile();
420+
if (!$ch) { // @phpstan-ignore-line
421+
throw new \RuntimeException('Unhandled curl error: ' . curl_error($ch));
422+
}
423+
424+
// JSESSIONID
425+
if ($cookieFile) {
421426
$cookieFilePath = stream_get_meta_data($cookieFile)['uri'];
427+
$cookies = file_get_contents($cookieFilePath);
422428

423-
foreach ($this->curlOpts as $opt => $value) {
424-
curl_setopt($ch, $opt, $value);
425-
}
426-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
427-
curl_setopt($ch, CURLOPT_ENCODING, 'UTF-8');
428-
curl_setopt($ch, CURLOPT_URL, $url);
429-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
430-
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
431-
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeOut);
432429
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFilePath);
433430
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFilePath);
434-
if (!empty($payload)) {
435-
curl_setopt($ch, CURLOPT_HEADER, 0);
436-
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
437-
curl_setopt($ch, CURLOPT_POST, 1);
438-
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
439-
curl_setopt($ch, CURLOPT_HTTPHEADER, [
440-
'Content-type: ' . $contentType,
441-
'Content-length: ' . mb_strlen($payload),
442-
]);
443-
}
444-
$data = curl_exec($ch);
445-
if (false === $data) {
446-
throw new \RuntimeException('Unhandled curl error: ' . curl_error($ch));
447-
}
448-
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
449-
if ($httpCode < 200 || $httpCode >= 300) {
450-
throw new BadResponseException('Bad response, HTTP code: ' . $httpCode);
451-
}
452-
curl_close($ch);
453-
unset($ch);
454431

455-
$cookies = file_get_contents($cookieFilePath);
456-
if (false !== mb_strpos($cookies, 'JSESSIONID')) {
457-
preg_match('/(?:JSESSIONID\s*)(?<JSESSIONID>.*)/', $cookies, $output_array);
458-
$this->setJSessionId($output_array['JSESSIONID']);
432+
if ($cookies) {
433+
if (false !== mb_strpos($cookies, 'JSESSIONID')) {
434+
preg_match('/(?:JSESSIONID\s*)(?<JSESSIONID>.*)/', $cookies, $output_array);
435+
$this->setJSessionId($output_array['JSESSIONID']);
436+
}
459437
}
438+
}
439+
440+
// PAYLOAD
441+
if (!empty($payload)) {
442+
curl_setopt($ch, CURLOPT_HEADER, 0);
443+
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
444+
curl_setopt($ch, CURLOPT_POST, 1);
445+
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
446+
curl_setopt($ch, CURLOPT_HTTPHEADER, [
447+
'Content-type: ' . $contentType,
448+
'Content-length: ' . mb_strlen($payload),
449+
]);
450+
}
460451

461-
return $data;
452+
// OTHERS
453+
foreach ($this->curlOpts as $opt => $value) {
454+
curl_setopt($ch, $opt, $value);
455+
}
456+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
457+
curl_setopt($ch, CURLOPT_ENCODING, 'UTF-8');
458+
curl_setopt($ch, CURLOPT_URL, $url);
459+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
460+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
461+
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeOut);
462+
463+
// EXECUTE and RESULT
464+
$data = curl_exec($ch);
465+
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
466+
467+
// ANALYSE
468+
if (false === $data) {
469+
throw new \RuntimeException('Unhandled curl error: ' . curl_error($ch));
462470
}
463471

464-
throw new \RuntimeException('Post XML data set but curl PHP module is not installed or not enabled.');
472+
if (is_bool($data)) {
473+
throw new \RuntimeException('Curl error: BOOL received, but STRING expected.');
474+
}
475+
476+
if ($httpCode < 200 || $httpCode >= 300) {
477+
throw new BadResponseException('Bad response, HTTP code: ' . $httpCode);
478+
}
479+
480+
// CLOSE AND UNSET
481+
curl_close($ch);
482+
unset($ch);
483+
484+
// RETURN
485+
return $data;
465486
}
466487

467488
/**
468489
* A private utility method used by other public methods to process XML responses.
469490
*
470-
* @throws BadResponseException
471-
* @throws \Exception
491+
* @throws BadResponseException|\Exception
472492
*/
473493
private function processXmlResponse(string $url, string $payload = '', string $contentType = 'application/xml'): \SimpleXMLElement
474494
{

src/Parameters/DocumentableTrait.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,7 @@ public function addPresentation(string $nameOrUrl, $content = null, ?string $fil
4949
return $this;
5050
}
5151

52-
/**
53-
* @return bool|string
54-
*/
55-
public function getPresentationsAsXML()
52+
public function getPresentationsAsXML(): string
5653
{
5754
$result = '';
5855

@@ -77,6 +74,10 @@ public function getPresentationsAsXML()
7774
$result = $xml->asXML();
7875
}
7976

77+
if (!is_string($result)) {
78+
throw new \RuntimeException('String expected, but ' . gettype($result) . ' received.');
79+
}
80+
8081
return $result;
8182
}
8283
}

tests/Responses/IsMeetingRunningResponseTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ public function testIsMeetingRunningResponseContent(): void
4444
{
4545
$this->assertEquals('SUCCESS', $this->running->getReturnCode());
4646
$this->assertTrue($this->running->isRunning());
47-
48-
$this->assertEquals('<?xmlversion="1.0"?><response><returncode>SUCCESS</returncode><running>true</running></response>', $this->minifyString($this->running->getRawXml()->asXML()));
47+
$xml = $this->running->getRawXml()->asXML();
48+
$this->assertIsString($xml);
49+
$this->assertEquals('<?xmlversion="1.0"?><response><returncode>SUCCESS</returncode><running>true</running></response>', $this->minifyString($xml));
4950
}
5051

5152
public function testIsMeetingRunningResponseTypes(): void

tests/TestCase.php

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -414,25 +414,42 @@ protected function getUpdateRecordingsParamsMock(array $params): UpdateRecording
414414
}
415415

416416
// Load fixtures
417-
418-
/**
419-
* @return false|\SimpleXMLElement
420-
*/
421-
protected function loadXmlFile(string $path)
417+
protected function loadXmlFile(string $path): \SimpleXMLElement
422418
{
423-
return simplexml_load_string(file_get_contents($path));
419+
$content = file_get_contents($path);
420+
421+
if (!$content) {
422+
throw new \RuntimeException('Content of file could not be loaded.');
423+
}
424+
425+
$xml = simplexml_load_string($content);
426+
427+
if (!$xml) {
428+
throw new \RuntimeException('Content could not be converted to XML.');
429+
}
430+
431+
return $xml;
424432
}
425433

426-
/**
427-
* @return false|string
428-
*/
429-
protected function loadJsonFile(string $path)
434+
protected function loadJsonFile(string $path): string
430435
{
431-
return file_get_contents($path);
436+
$content = file_get_contents($path);
437+
438+
if (!$content) {
439+
throw new \RuntimeException('Content of file could not be loaded.');
440+
}
441+
442+
return $content;
432443
}
433444

434445
protected function minifyString(string $string): string
435446
{
436-
return str_replace(["\r\n", "\r", "\n", "\t", ' '], '', $string);
447+
$minifiedString = str_replace(["\r\n", "\r", "\n", "\t", ' '], '', $string);
448+
449+
if (!is_string($minifiedString)) {
450+
throw new \RuntimeException('String expected, but not received.');
451+
}
452+
453+
return $minifiedString;
437454
}
438455
}

0 commit comments

Comments
 (0)