WebsocketNegotiator::resolveUrl()   B
last analyzed

Complexity

Conditions 7
Paths 8

Size

Total Lines 34
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
c 1
b 0
f 0
dl 0
loc 34
rs 8.8333
cc 7
nc 8
nop 3
1
<?php
2
3
4
namespace PortlandLabs\Slackbot\Slack\Rtm;
5
6
7
use CL\Slack\Exception\SlackException;
8
use PortlandLabs\Slackbot\Slack\Api\Payload\RtmConnectPayload;
9
use PortlandLabs\Slackbot\Slack\Api\Payload\RtmConnectPayloadResponse;
10
use PortlandLabs\Slackbot\Slack\Api\Client;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, PortlandLabs\Slackbot\Slack\Rtm\Client. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
11
use Psr\Log\LoggerAwareTrait;
12
use Psr\Log\LoggerInterface;
13
14
class WebsocketNegotiator
15
{
16
17
    use LoggerAwareTrait;
18
19
    public function __construct(LoggerInterface $logger)
20
    {
21
        $this->setLogger($logger);
22
    }
23
24
    /**
25
     * Get a URI for Slack's RTM Api
26
     *
27
     * @param Client $client
28
     * @param int $retries The number of times to retry before giving up. Pass 0 for none, -1 for infinite
29
     * @param int $maxWait
30
     *
31
     * @return RtmConnectPayloadResponse|null
32
     *
33
     * @throws \GuzzleHttp\Exception\GuzzleException
34
     */
35
    public function resolveUrl(Client $client, $retries = -1, $maxWait = 60): ?RtmConnectPayloadResponse
36
    {
37
        $tries = 0;
38
        $payload = new RtmConnectPayload();
39
        $wait = 5;
40
        $result = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
41
42
        try {
43
            retry:
44
            $result = $client->send($payload);
45
        } catch (SlackException $e) {
46
            $this->logger->debug('Error connecting to RTM: ' . $e->getMessage());
0 ignored issues
show
Bug introduced by
The method debug() does not exist on null. ( Ignorable by Annotation )

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

46
            $this->logger->/** @scrutinizer ignore-call */ 
47
                           debug('Error connecting to RTM: ' . $e->getMessage());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
47
            // Ignore slack errors, retries should handle this
48
        }
49
50
        // Handle retrying the connection. This prevents excessive retries or our process manager dieing on us
51
        if (!$result || !$result instanceof RtmConnectPayloadResponse) {
0 ignored issues
show
introduced by
$result is of type CL\Slack\Payload\PayloadResponseInterface, thus it always evaluated to true.
Loading history...
52
            if ($retries > 0 || $retries < 0) {
53
                $retries--;
54
                $tries++;
55
56
                $this->logger->debug('Error connecting to RTM, waiting ' . $wait . ' seconds then retrying...');
57
58
                // Sleep for the intended wait time
59
                sleep($wait);
60
61
                // Double the wait time, or hit the max wait time
62
                $wait = min($wait * 2, $maxWait);
63
                goto retry;
64
            }
65
        }
66
67
        if ($result instanceof RtmConnectPayloadResponse) {
68
            return $result;
69
        }
70
    }
71
}