Completed
Pull Request — master (#401)
by
unknown
01:21
created

PresenceChannel::updateUserInfo()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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