Completed
Push — master ( edcf20...3ec6c0 )
by Marcel
03:05 queued 01:22
created

src/WebSockets/Channels/PresenceChannel.php (3 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace BeyondCode\LaravelWebSockets\WebSockets\Channels;
4
5
use stdClass;
6
use Ratchet\ConnectionInterface;
7
8
class PresenceChannel extends Channel
9
{
10
    protected $users = [];
11
12
    public function getUsers(): array
13
    {
14
        return $this->users;
15
    }
16
17
    /*
18
     * @link https://pusher.com/docs/pusher_protocol#presence-channel-events
19
     */
20
    public function subscribe(ConnectionInterface $connection, stdClass $payload)
21
    {
22
        $this->verifySignature($connection, $payload);
23
24
        $this->saveConnection($connection);
25
26
        $channelData = json_decode($payload->channel_data);
27
        $this->users[$connection->socketId] = $channelData;
0 ignored issues
show
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...
28
29
        // Send the success event
30
        $connection->send(json_encode([
31
            'event' => 'pusher_internal:subscription_succeeded',
32
            'channel' => $this->channelName,
33
            'data' => json_encode($this->getChannelData()),
34
        ]));
35
36
        $this->broadcastToOthers($connection, [
37
            'event' => 'pusher_internal:member_added',
38
            'channel' => $this->channelName,
39
            'data' => json_encode($channelData),
40
        ]);
41
    }
42
43
    public function unsubscribe(ConnectionInterface $connection)
44
    {
45
        parent::unsubscribe($connection);
46
47
        if (! isset($this->users[$connection->socketId])) {
0 ignored issues
show
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...
48
            return;
49
        }
50
51
        $this->broadcastToOthers($connection, [
52
            'event' => 'pusher_internal:member_removed',
53
            'channel' => $this->channelName,
54
            'data' => json_encode([
55
                'user_id' => $this->users[$connection->socketId]->user_id,
0 ignored issues
show
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...
56
            ]),
57
        ]);
58
59
        unset($this->users[$connection->socketId]);
60
    }
61
62
    protected function getChannelData(): array
63
    {
64
        return [
65
            'presence' => [
66
                'ids' => $this->getUserIds(),
67
                'hash' => $this->getHash(),
68
                'count' => count($this->users),
69
            ],
70
        ];
71
    }
72
73
    public function toArray(): array
74
    {
75
        return array_merge(parent::toArray(), [
76
            'user_count' => count($this->users),
77
        ]);
78
    }
79
80
    protected function getUserIds(): array
81
    {
82
        $userIds = array_map(function ($channelData) {
83
            return (string) $channelData->user_id;
84
        }, $this->users);
85
86
        return array_values($userIds);
87
    }
88
89
    protected function getHash(): array
90
    {
91
        $hash = [];
92
93
        foreach ($this->users as $socketId => $channelData) {
94
            $hash[$channelData->user_id] = $channelData->user_info;
95
        }
96
97
        return $hash;
98
    }
99
}
100