Passed
Push — master ( e0b916...9184fe )
by Albert
06:29 queued 04:25
created

Pusher::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 8
dl 0
loc 19
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace SwooleTW\Http\Websocket;
4
5
use SwooleTW\Http\Server\Facades\Server;
6
7
/**
8
 * Class Pusher
9
 */
10
class Pusher
11
{
12
    /**
13
     * @var \Swoole\Websocket\Server
14
     */
15
    protected $server;
16
17
    /**
18
     * @var int
19
     */
20
    protected $opcode;
21
22
    /**
23
     * @var int
24
     */
25
    protected $sender;
26
27
    /**
28
     * @var array
29
     */
30
    protected $descriptors;
31
32
    /**
33
     * @var bool
34
     */
35
    protected $broadcast;
36
37
    /**
38
     * @var bool
39
     */
40
    protected $assigned;
41
42
    /**
43
     * @var string
44
     */
45
    protected $event;
46
47
    /**
48
     * @var string|null
49
     */
50
    protected $message;
51
52
    /**
53
     * Push constructor.
54
     *
55
     * @param int $opcode
56
     * @param int $sender
57
     * @param array $descriptors
58
     * @param bool $broadcast
59
     * @param bool $assigned
60
     * @param string $event
61
     * @param string|null $message
62
     * @param \Swoole\Websocket\Server
63
     */
64
    protected function __construct(
65
        int $opcode,
66
        int $sender,
67
        array $descriptors,
68
        bool $broadcast,
69
        bool $assigned,
70
        string $event,
71
        string $message = null,
72
        $server
73
    )
74
    {
75
        $this->opcode = $opcode;
76
        $this->sender = $sender;
77
        $this->descriptors = $descriptors;
78
        $this->broadcast = $broadcast;
79
        $this->assigned = $assigned;
80
        $this->event = $event;
81
        $this->message = $message;
82
        $this->server = $server;
83
    }
84
85
    /**
86
     * Static constructor
87
     *
88
     * @param array $data
89
     * @param \Swoole\Websocket\Server $server
90
     *
91
     * @return \SwooleTW\Http\Websocket\Push
92
     */
93
    public static function make(array $data, $server)
94
    {
95
        return new static(
0 ignored issues
show
Bug Best Practice introduced by
The expression return new static($data[...age'] ?? null, $server) returns the type SwooleTW\Http\Websocket\Pusher which is incompatible with the documented return type SwooleTW\Http\Websocket\Push.
Loading history...
96
            $data['opcode'] ?? 1,
97
            $data['sender'] ?? 0,
98
            $data['fds'] ?? [],
99
            $data['broadcast'] ?? false,
100
            $data['assigned'] ?? false,
101
            $data['event'] ?? null,
0 ignored issues
show
Bug introduced by
It seems like $data['event'] ?? null can also be of type null; however, parameter $event of SwooleTW\Http\Websocket\Pusher::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

101
            /** @scrutinizer ignore-type */ $data['event'] ?? null,
Loading history...
102
            $data['message'] ?? null,
103
            $server
104
        );
105
    }
106
107
    /**
108
     * @return int
109
     */
110
    public function getOpcode(): int
111
    {
112
        return $this->opcode;
113
    }
114
115
    /**
116
     * @return int
117
     */
118
    public function getSender(): int
119
    {
120
        return $this->sender;
121
    }
122
123
    /**
124
     * @return array
125
     */
126
    public function getDescriptors(): array
127
    {
128
        return $this->descriptors;
129
    }
130
131
    /**
132
     * @param int $descriptor
133
     *
134
     * @return self
135
     */
136
    public function addDescriptor($descriptor): self
137
    {
138
        return $this->addDescriptors([$descriptor]);
139
    }
140
141
    /**
142
     * @param array $descriptors
143
     *
144
     * @return self
145
     */
146
    public function addDescriptors(array $descriptors): self
147
    {
148
        $this->descriptors = array_values(
149
            array_unique(
150
                array_merge($this->descriptors, $descriptors)
151
            )
152
        );
153
154
        return $this;
155
    }
156
157
    /**
158
     * @param int $descriptor
159
     *
160
     * @return bool
161
     */
162
    public function hasDescriptor(int $descriptor): bool
163
    {
164
        return in_array($descriptor, $this->descriptors);
165
    }
166
167
    /**
168
     * @return bool
169
     */
170
    public function isBroadcast(): bool
171
    {
172
        return $this->broadcast;
173
    }
174
175
    /**
176
     * @return bool
177
     */
178
    public function isAssigned(): bool
179
    {
180
        return $this->assigned;
181
    }
182
183
    /**
184
     * @return string
185
     */
186
    public function getEvent(): string
187
    {
188
        return $this->event;
189
    }
190
191
    /**
192
     * @return string|null
193
     */
194
    public function getMessage(): ?string
195
    {
196
        return $this->message;
197
    }
198
199
    /**
200
     * @return \Swoole\Websocket\Server
201
     */
202
    public function getServer()
203
    {
204
        return $this->server;
205
    }
206
207
    /**
208
     * @return bool
209
     */
210
    public function shouldBroadcast(): bool
211
    {
212
        return $this->broadcast && empty($this->descriptors) && ! $this->assigned;
213
    }
214
215
    /**
216
     * Check if it's a websocket fd.
217
     *
218
     * @param int $fd
219
     *
220
     * @return bool
221
     */
222
    public function isServerWebsocket(int $fd): bool
223
    {
224
        return $this->server->connection_info($fd)['websocket_status'] ?? false;
225
    }
226
227
    /**
228
     * Returns all descriptors that are websocket
229
     *
230
     * @param \Swoole\Connection\Iterator $descriptors
231
     *
232
     * @return array
233
     */
234
    protected function getWebsocketConnections(): array
235
    {
236
        return array_filter(iterator_to_array($this->server->connections), function ($fd) {
237
            return $this->isServerWebsocket($fd);
238
        });
239
    }
240
241
    /**
242
     * @param int $fd
243
     *
244
     * @return bool
245
     */
246
    public function shouldPushToDescriptor(int $fd): bool
247
    {
248
        return $this->server->exist($fd)
249
            && ($this->broadcast && $this->sender !== (int) $fd);
250
    }
251
252
    /**
253
     * Push message to related descriptors
254
     *
255
     * @param mixed $payload
256
     *
257
     * @return void
258
     */
259
    public function push($payload): void
260
    {
261
        // attach sender if not broadcast
262
        if (! $this->broadcast && $this->sender && ! $this->hasDescriptor($this->sender)) {
263
            $this->addDescriptor($this->sender);
264
        }
265
266
        // check if to broadcast to other clients
267
        if ($this->shouldBroadcast()) {
268
            $this->addDescriptors($this->getWebsocketConnections());
269
        }
270
271
        // push message to designated fds
272
        foreach ($this->descriptors as $descriptor) {
273
            if ($this->shouldPushToDescriptor($descriptor)) {
274
                $this->server->push($descriptor, $payload, $this->opcode);
0 ignored issues
show
Bug introduced by
$this->opcode of type integer is incompatible with the type boolean expected by parameter $binary_data of Swoole\WebSocket\Server::push(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

274
                $this->server->push($descriptor, $payload, /** @scrutinizer ignore-type */ $this->opcode);
Loading history...
275
            }
276
        }
277
    }
278
}