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

PresenceChannel::getUserIds()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
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 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
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...
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
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...
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
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...
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