This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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 BZIon\Socket; |
||
4 | |||
5 | use BZIon\Event\EventSubscriber; |
||
6 | use Player; |
||
7 | use Ratchet\ConnectionInterface; |
||
8 | use Ratchet\MessageComponentInterface; |
||
9 | use React\EventLoop\LoopInterface; |
||
10 | use Symfony\Component\Console\Output\OutputInterface; |
||
11 | |||
12 | class EventPusher implements MessageComponentInterface |
||
13 | { |
||
14 | /** |
||
15 | * The connected clients |
||
16 | * @var \SplObjectStorage |
||
17 | */ |
||
18 | protected $clients; |
||
19 | |||
20 | /** |
||
21 | * The event subscriber |
||
22 | * @var EventSubscriber |
||
23 | */ |
||
24 | protected $subscriber; |
||
25 | |||
26 | /** |
||
27 | * The event loop |
||
28 | * @var LoopInterface |
||
29 | */ |
||
30 | protected $loop; |
||
31 | |||
32 | /** |
||
33 | * The console output |
||
34 | * @var OutputInterface|null |
||
35 | */ |
||
36 | protected $output; |
||
37 | |||
38 | /** |
||
39 | * Max pong time and interval between pings in seconds |
||
40 | * @var int |
||
41 | */ |
||
42 | const KEEP_ALIVE = 300; |
||
43 | |||
44 | /** |
||
45 | * Create a new event pusher handler |
||
46 | */ |
||
47 | public function __construct(LoopInterface $loop, OutputInterface $output = null) |
||
48 | { |
||
49 | $this->loop = $loop; |
||
50 | $this->output = $output; |
||
51 | |||
52 | $this->clients = new \SplObjectStorage(); |
||
53 | $this->subscriber = \Service::getContainer()->get('kernel.subscriber.bzion_subscriber'); |
||
54 | |||
55 | // Ping timer |
||
56 | $loop->addPeriodicTimer(self::KEEP_ALIVE, array($this, 'ping')); |
||
57 | } |
||
58 | |||
59 | /** |
||
60 | * Open the connection |
||
61 | * @param ConnectionInterface $conn |
||
62 | */ |
||
63 | public function onOpen(ConnectionInterface $conn) |
||
64 | { |
||
65 | // Find which player opened the connection |
||
66 | $conn->Player = Player::get($conn->Session->get('playerId')); |
||
0 ignored issues
–
show
Accessing
Session 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
![]() |
|||
67 | |||
68 | $conn->pong = true; |
||
0 ignored issues
–
show
Accessing
pong 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
![]() |
|||
69 | |||
70 | // Store the new connection to send messages to later |
||
71 | $this->clients->attach($conn); |
||
72 | |||
73 | $this->log( |
||
74 | sprintf( |
||
75 | "<fg=cyan>Client #{$conn->resourceId} connected from {$conn->remoteAddress}\t ({$conn->Player->getUsername()})</>", |
||
0 ignored issues
–
show
Accessing
resourceId 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
![]() Accessing
remoteAddress 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
![]() Accessing
Player 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
![]() |
|||
76 | $conn->resourceId, |
||
0 ignored issues
–
show
Accessing
resourceId 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
![]() |
|||
77 | $conn->remoteAddress, |
||
0 ignored issues
–
show
Accessing
remoteAddress 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
![]() |
|||
78 | $conn->Player->getUsername() |
||
0 ignored issues
–
show
Accessing
Player 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
![]() |
|||
79 | ), OutputInterface::VERBOSITY_VERBOSE |
||
80 | ); |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * Send a message as a client |
||
85 | * @param ConnectionInterface $from |
||
86 | * @param mixed $msg |
||
87 | */ |
||
88 | public function onMessage(ConnectionInterface $from, $msg) |
||
89 | { |
||
90 | $this->log("Received message from #{$from->resourceId}"); |
||
0 ignored issues
–
show
Accessing
resourceId 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
![]() |
|||
91 | |||
92 | // Record the reception of the message to prevent a ping timeout |
||
93 | $from->pong = true; |
||
0 ignored issues
–
show
Accessing
pong 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
![]() |
|||
94 | } |
||
95 | |||
96 | /** |
||
97 | * Close a connection |
||
98 | * @param ConnectionInterface $conn |
||
99 | */ |
||
100 | public function onClose(ConnectionInterface $conn) |
||
101 | { |
||
102 | // The connection is closed, remove it, as we can no longer send it messages |
||
103 | $this->clients->detach($conn); |
||
104 | |||
105 | $this->log( |
||
106 | sprintf( |
||
107 | "<fg=yellow>Client #{$conn->resourceId} disconnected from {$conn->remoteAddress}\t ({$conn->Player->getUsername()})</>", |
||
0 ignored issues
–
show
Accessing
resourceId 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
![]() Accessing
remoteAddress 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
![]() Accessing
Player 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
![]() |
|||
108 | $conn->resourceId, |
||
0 ignored issues
–
show
Accessing
resourceId 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
![]() |
|||
109 | $conn->remoteAddress, |
||
0 ignored issues
–
show
Accessing
remoteAddress 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
![]() |
|||
110 | $conn->Player->getUsername() |
||
0 ignored issues
–
show
Accessing
Player 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
![]() |
|||
111 | ), OutputInterface::VERBOSITY_VERBOSE |
||
112 | ); |
||
113 | } |
||
114 | |||
115 | /** |
||
116 | * Action to call on an error |
||
117 | */ |
||
118 | public function onError(ConnectionInterface $conn, \Exception $e) |
||
119 | { |
||
120 | echo "An error has occurred: {$e->getMessage()}\n"; |
||
121 | |||
122 | $conn->close(); |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * Pushes or emails a new private message to the user |
||
127 | * |
||
128 | * @param array $event The event data we received from the web server |
||
129 | */ |
||
130 | private function onMessageServerEvent($event) |
||
131 | { |
||
132 | // A list of players who received a message so that we can e-mail the |
||
133 | // ones who didn't |
||
134 | $received = array(); |
||
135 | |||
136 | $conversation = \Conversation::get($event->data->conversation); |
||
137 | |||
138 | $conversationMembers = $conversation->getPlayerIds(); |
||
139 | |||
140 | foreach ($this->clients as $client) { |
||
141 | $player = $client->Player; |
||
142 | |||
143 | if (!in_array($player->getId(), $conversationMembers)) { |
||
144 | // Don't notify that player, he doesn't belong in the conversation |
||
145 | continue; |
||
146 | } |
||
147 | |||
148 | $event->notification_count = $player->countUnreadNotifications(); |
||
149 | $event->message_count = $player->countUnreadMessages(); |
||
150 | |||
151 | $this->send($client, $event); |
||
152 | $received[] = $player->getId(); |
||
153 | } |
||
154 | |||
155 | // Send e-mails |
||
156 | foreach ($event->data->recipients as $recipient) { |
||
157 | // Only send an email to users who aren't currently logged in |
||
158 | if (!in_array($recipient, $received)) { |
||
159 | $this->log("<fg=green>E-mailing player {$recipient->getId()} ({$recipient->getUsername()})</>"); |
||
160 | |||
161 | $this->subscriber->sendEmails( |
||
162 | 'New message received', |
||
163 | array($recipient), |
||
164 | 'message', |
||
165 | array('message' => \Message::get($event->data->message)) |
||
166 | ); |
||
167 | } |
||
168 | } |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Pushes or emails a new notification to the user |
||
173 | * |
||
174 | * @param array $event The event data we received from the web server |
||
175 | */ |
||
176 | private function onNotificationServerEvent($event) |
||
177 | { |
||
178 | $notification = \Notification::get($event->data->notification); |
||
179 | |||
180 | // Whether we've notified that player in real time - if he isn't online |
||
181 | // at the moment, we'll send an e-mail to him |
||
182 | $active = false; |
||
183 | |||
184 | foreach ($this->clients as $client) { |
||
185 | if ($client->Player->getId() == $event->data->receiver) { |
||
186 | $this->send($client, $event); |
||
187 | $active = true; |
||
188 | } |
||
189 | } |
||
190 | |||
191 | if (!$active) { |
||
192 | $player = $notification->getReceiver(); |
||
193 | $this->log("<fg=green>E-mailing player {$player->getId()} ({$player->getUsername()})</>"); |
||
194 | |||
195 | $this->subscriber->emailNotification($notification); |
||
196 | } |
||
197 | } |
||
198 | |||
199 | /** |
||
200 | * Send some data to the client |
||
201 | * |
||
202 | * @param ConnectionInterface $client The client that will receive the data |
||
203 | * @param array $data The data to send |
||
204 | */ |
||
205 | protected function send(ConnectionInterface $client, $data) |
||
206 | { |
||
207 | $this->log("<fg=green>Notifying #{$client->resourceId} ({$client->Player->getUsername()})</>"); |
||
0 ignored issues
–
show
Accessing
resourceId 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
![]() Accessing
Player 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
![]() |
|||
208 | |||
209 | $data->notification_count = $client->Player->countUnreadNotifications(); |
||
0 ignored issues
–
show
Accessing
Player 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
![]() |
|||
210 | $data->message_count = $client->Player->countUnreadMessages(); |
||
0 ignored issues
–
show
Accessing
Player 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
![]() |
|||
211 | |||
212 | $client->send(json_encode(array('event' => $data))); |
||
213 | } |
||
214 | |||
215 | /** |
||
216 | * Action to call when the server notifies us about something |
||
217 | * @param string $event JSON'ified string we'll receive from the webserver |
||
218 | */ |
||
219 | public function onServerEvent($event) |
||
220 | { |
||
221 | $event = $event->event; |
||
222 | |||
223 | switch ($event->type) { |
||
224 | case 'message': |
||
225 | $this->log("New message received", OutputInterface::VERBOSITY_VERY_VERBOSE); |
||
226 | $this->onMessageServerEvent($event); |
||
227 | break; |
||
228 | case 'notification': |
||
229 | $this->log("New notification received", OutputInterface::VERBOSITY_VERY_VERBOSE); |
||
230 | $this->onNotificationServerEvent($event); |
||
231 | break; |
||
232 | default: |
||
233 | $this->log("Generic message received", OutputInterface::VERBOSITY_VERY_VERBOSE); |
||
234 | foreach ($this->clients as $client) { |
||
235 | $this->send($client, $event); |
||
236 | } |
||
237 | } |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * Log a debugging message to the console |
||
242 | * |
||
243 | * @param string $message The message to log |
||
244 | * @param int $level The output verbosity level of the message |
||
245 | */ |
||
246 | private function log($message, $level = OutputInterface::VERBOSITY_DEBUG) |
||
247 | { |
||
248 | if (!$this->output) { |
||
249 | return; |
||
250 | } |
||
251 | |||
252 | if ($level <= $this->output->getVerbosity()) { |
||
253 | $this->output->writeln($message); |
||
254 | } |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * Send a ping message to all clients and kick those who didn't respond |
||
259 | */ |
||
260 | public function ping() |
||
261 | { |
||
262 | $this->log("Sending pings"); |
||
263 | |||
264 | foreach ($this->clients as $client) { |
||
265 | if (!$client->pong) { |
||
266 | $this->log("Dropping #{$client->resourceId}"); |
||
267 | |||
268 | $client->close(); |
||
269 | continue; |
||
270 | } |
||
271 | |||
272 | $this->log("Pinging #{$client->resourceId}"); |
||
273 | $client->send('ping'); |
||
274 | $client->pong = false; |
||
275 | } |
||
276 | } |
||
277 | } |
||
278 |
If you access a property on an interface, you most likely code against a concrete implementation of the interface.
Available Fixes
Adding an additional type check:
Changing the type hint: