Completed
Push — master ( db6d79...ec96ca )
by Marcel
01:29
created

ArrayChannelManager::findOrCreate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
c 0
b 0
f 0
rs 9.9332
cc 2
nc 2
nop 2
1
<?php
2
3
namespace BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManagers;
4
5
use Ratchet\ConnectionInterface;
6
use BeyondCode\LaravelWebSockets\WebSockets\Channels\Channel;
7
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
8
use BeyondCode\LaravelWebSockets\WebSockets\Channels\PrivateChannel;
9
use BeyondCode\LaravelWebSockets\WebSockets\Channels\PresenceChannel;
10
11
class ArrayChannelManager implements ChannelManager
12
{
13
    /** @var string */
14
    protected $appId;
15
16
    /** @var array */
17
    protected $channels = [];
18
19
    public function findOrCreate(string $appId, string $channelName): Channel
20
    {
21
        if (! isset($this->channels[$appId][$channelName])) {
22
            $channelClass = $this->determineChannelClass($channelName);
23
24
            $this->channels[$appId][$channelName] = new $channelClass($channelName);
25
        }
26
27
        return $this->channels[$appId][$channelName];
28
    }
29
30
    public function find(string $appId, string $channelName): ?Channel
31
    {
32
        return $this->channels[$appId][$channelName] ?? null;
33
    }
34
35
    protected function determineChannelClass(string $channelName): string
36
    {
37
        if (starts_with($channelName, 'private-')) {
38
            return PrivateChannel::class;
39
        }
40
41
        if (starts_with($channelName, 'presence-')) {
42
            return PresenceChannel::class;
43
        }
44
45
        return Channel::class;
46
    }
47
48
    public function getChannels(string $appId): array
49
    {
50
        return $this->channels[$appId] ?? [];
51
    }
52
53
    public function getConnectionCount(string $appId): int
54
    {
55
        return collect($this->getChannels($appId))
56
            ->sum(function ($channel) {
57
                return count($channel->getSubscribedConnections());
58
            });
59
    }
60
61
    public function removeFromAllChannels(ConnectionInterface $connection)
62
    {
63
        if (! isset($connection->app)) {
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...
64
            return;
65
        }
66
67
        /*
68
         * Remove the connection from all channels.
69
         */
70
        collect(array_get($this->channels, $connection->app->id, []))->each->unsubscribe($connection);
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...
71
72
        /*
73
         * Unset all channels that have no connections so we don't leak memory.
74
         */
75
        collect(array_get($this->channels, $connection->app->id, []))
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...
76
            ->reject->hasConnections()
77
                    ->each(function (Channel $channel, string $channelName) use ($connection) {
78
                        unset($this->channels[$connection->app->id][$channelName]);
79
                    });
80
81
        if (count(array_get($this->channels, $connection->app->id, [])) === 0) {
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...
82
            unset($this->channels[$connection->app->id]);
83
        }
84
    }
85
}
86