Completed
Push — master ( 8a3e89...c85ec3 )
by Alexandru
01:15
created

Channel::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace BeyondCode\LaravelWebSockets\WebSockets\Channels;
4
5
use BeyondCode\LaravelWebSockets\Dashboard\DashboardLogger;
6
use BeyondCode\LaravelWebSockets\WebSockets\Exceptions\InvalidSignature;
7
use Illuminate\Support\Str;
8
use Ratchet\ConnectionInterface;
9
use stdClass;
10
11
class Channel
12
{
13
    /** @var string */
14
    protected $channelName;
15
16
    /** @var \Ratchet\ConnectionInterface[] */
17
    protected $subscribedConnections = [];
18
19
    public function __construct(string $channelName)
20
    {
21
        $this->channelName = $channelName;
22
    }
23
24
    public function getName(): string
25
    {
26
        return $this->channelName;
27
    }
28
29
    public function hasConnections(): bool
30
    {
31
        return count($this->subscribedConnections) > 0;
32
    }
33
34
    public function getSubscribedConnections(): array
35
    {
36
        return $this->subscribedConnections;
37
    }
38
39
    protected function verifySignature(ConnectionInterface $connection, stdClass $payload)
40
    {
41
        $signature = "{$connection->socketId}:{$this->channelName}";
0 ignored issues
show
Bug introduced by
Accessing socketId on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
42
43
        if (isset($payload->channel_data)) {
44
            $signature .= ":{$payload->channel_data}";
45
        }
46
47
        if (Str::after($payload->auth, ':') !== hash_hmac('sha256', $signature, $connection->app->secret)) {
0 ignored issues
show
Bug introduced by
Accessing app on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
48
            throw new InvalidSignature();
49
        }
50
    }
51
52
    /*
53
     * @link https://pusher.com/docs/pusher_protocol#presence-channel-events
54
     */
55
    public function subscribe(ConnectionInterface $connection, stdClass $payload)
56
    {
57
        $this->saveConnection($connection);
58
59
        $connection->send(json_encode([
60
            'event' => 'pusher_internal:subscription_succeeded',
61
            'channel' => $this->channelName,
62
        ]));
63
    }
64
65
    public function unsubscribe(ConnectionInterface $connection)
66
    {
67
        unset($this->subscribedConnections[$connection->socketId]);
68
69
        if (! $this->hasConnections()) {
70
            DashboardLogger::vacated($connection, $this->channelName);
71
        }
72
    }
73
74
    protected function saveConnection(ConnectionInterface $connection)
75
    {
76
        $hadConnectionsPreviously = $this->hasConnections();
77
78
        $this->subscribedConnections[$connection->socketId] = $connection;
0 ignored issues
show
Bug introduced by
Accessing socketId on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
79
80
        if (! $hadConnectionsPreviously) {
81
            DashboardLogger::occupied($connection, $this->channelName);
82
        }
83
84
        DashboardLogger::subscribed($connection, $this->channelName);
85
    }
86
87
    public function broadcast($payload)
88
    {
89
        foreach ($this->subscribedConnections as $connection) {
90
            $connection->send(json_encode($payload));
91
        }
92
    }
93
94
    public function broadcastToOthers(ConnectionInterface $connection, $payload)
95
    {
96
        $this->broadcastToEveryoneExcept($payload, $connection->socketId);
0 ignored issues
show
Bug introduced by
Accessing socketId on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
97
    }
98
99
    public function broadcastToEveryoneExcept($payload, ?string $socketId = null)
100
    {
101
        if (is_null($socketId)) {
102
            return $this->broadcast($payload);
103
        }
104
105
        foreach ($this->subscribedConnections as $connection) {
106
            if ($connection->socketId !== $socketId) {
0 ignored issues
show
Bug introduced by
Accessing socketId on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
107
                $connection->send(json_encode($payload));
108
            }
109
        }
110
    }
111
112
    public function toArray(): array
113
    {
114
        return [
115
            'occupied' => count($this->subscribedConnections) > 0,
116
            'subscription_count' => count($this->subscribedConnections),
117
        ];
118
    }
119
}
120