Completed
Push — master ( 8af72d...6a45d4 )
by Timo
04:44 queued 01:52
created

SessionMonitor::setList()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Tidal\WampWatch;
4
5
/*
6
 * Copyright 2015 Timo.
7
 *
8
 * For the full copyright and license information, please view the LICENSE file
9
 * that was distributed with this source code.
10
 */
11
12
use Evenement\EventEmitterInterface;
13
use Tidal\WampWatch\ClientSessionInterface as ClientSession;
14
15
/**
16
 * Description of SessionMonitor.
17
 *
18
 * @author Timo
19
 */
20
class SessionMonitor implements MonitorInterface, EventEmitterInterface
21
{
22
    use
23
        MonitorTrait {
24
            start as doStart;
25
            stop as doStop;
26
        }
27
28
    const SESSION_JOIN_TOPIC = 'wamp.session.on_join';
29
    const SESSION_LEAVE_TOPIC = 'wamp.session.on_leave';
30
    const SESSION_COUNT_TOPIC = 'wamp.session.count';
31
    const SESSION_LIST_TOPIC = 'wamp.session.list';
32
    const SESSION_INFO_TOPIC = 'wamp.session.get';
33
34
35
    protected $sessionIds = [];
36
37
    /**
38
     * Constructor.
39
     *
40
     * @param ClientSession $session
41
     */
42
    public function __construct(ClientSession $session)
43
    {
44
        $this->setClientSession($session);
45
    }
46
47
    /**
48
     * Start the monitor.
49
     *
50
     * @return bool
51
     */
52
    public function start()
53
    {
54
        $this->once('list', function () {
55
            $this->doStart();
56
        });
57
        $this->startSubscriptions();
58
        $this->retrieveSessionIds();
59
60
        return true;
61
    }
62
63
    /**
64
     * Stop the monitor.
65
     * Returns boolean wether the monitor could be started.
66
     *
67
     * @return bool
68
     */
69
    public function stop()
70
    {
71
        $this->stopSubscriptions();
72
        $this->doStop();
73
74
        return true;
75
    }
76
77
    /**
78
     * Retrieves the session-info for given sessionId
79
     * and populates it in via given callback.
80
     *
81
     * @param          $sessionId
82
     * @param callable $callback
83
     *
84
     * @return mixed
85
     */
86
    public function getSessionInfo($sessionId, callable $callback)
87
    {
88
        return $this->session->call(self::SESSION_INFO_TOPIC, [$sessionId])->then(
89
            function ($res) use ($callback) {
90
                $this->emit('info', [$res[0]]);
91
                $callback($res[0]);
92
            },
93
            function ($error) {
94
                $this->emit('error', [$error]);
95
            }
96
        );
97
    }
98
99
    /**
100
     * Retrieves the Ids of the sessions currently
101
     * registered on the wamp-router in the monitor's realm
102
     * and populates the data via given callback,.
103
     *
104
     * @param callable $callback
105
     *
106
     * @return mixed
107
     */
108
    public function getSessionIds(callable $callback)
109
    {
110
        if (!count($this->sessionIds)) {
111
            $this->retrieveSessionIds($callback);
112
        } else {
113
            $callback($this->sessionIds);
114
        }
115
    }
116
117
    /**
118
     * Initializes the subscription to the meta-events.
119
     */
120
    protected function startSubscriptions()
121
    {
122 View Code Duplication
        $this->session->subscribe(self::SESSION_JOIN_TOPIC, function ($res) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
123
            $sessionInfo = $res[0];
124
            $sessionId = $sessionInfo->session;
125
            if ((array_search($sessionId, $this->sessionIds)) === false) {
126
                $this->sessionIds[] = $sessionId;
127
                $this->emit('join', [$sessionInfo]);
128
            }
129
        });
130 View Code Duplication
        $this->session->subscribe(self::SESSION_LEAVE_TOPIC, function ($res) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
            // @bug : wamp.session.on_leave is bugged as of crossbar.io 0.11.0
132
            // will provide sessionID when Browser closes/reloads,
133
            // but not when calling connection.close();
134
            $sessionId = $res[0];
135
            if (($key = array_search($sessionId, $this->sessionIds)) !== false) {
136
                unset($this->sessionIds[$key]);
137
                $this->emit('leave', [$sessionId]);
138
            }
139
        });
140
    }
141
142
    /**
143
     * Unsubscribes from the meta-events.
144
     */
145
    protected function stopSubscriptions()
146
    {
147
        Util::unsubscribe($this->session, self::SESSION_JOIN_TOPIC);
0 ignored issues
show
Documentation introduced by
$this->session is of type object<Tidal\WampWatch\ClientSessionInterface>, but the function expects a object<Thruway\ClientSession>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Unused Code introduced by
The call to Util::unsubscribe() has too many arguments starting with self::SESSION_JOIN_TOPIC.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
148
        Util::unsubscribe($this->session, self::SESSION_LEAVE_TOPIC);
0 ignored issues
show
Documentation introduced by
$this->session is of type object<Tidal\WampWatch\ClientSessionInterface>, but the function expects a object<Thruway\ClientSession>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Unused Code introduced by
The call to Util::unsubscribe() has too many arguments starting with self::SESSION_LEAVE_TOPIC.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
149
    }
150
151
    /**
152
     * Retrieves the list of current sessionIds on the router.
153
     *
154
     * @param callable|null $callback
155
     */
156
    protected function retrieveSessionIds(callable $callback = null)
157
    {
158
        $this->session->call(self::SESSION_LIST_TOPIC, [])->then(
159
            function ($res) use ($callback) {
160
                // remove our own sessionID from the tracked sessions
161
                $sessionIds = $this->removeOwnSessionId($res[0]);
162
                $this->setList($sessionIds);
163
                $this->emit('list', [$this->getList()]);
164
                if ($callback !== null) {
165
                    $callback($this->sessionIds);
166
                }
167
            },
168
            function ($error) {
169
                $this->emit('error', [$error]);
170
            }
171
        );
172
    }
173
174
    protected function setList($list)
175
    {
176
        $this->sessionIds = $list;
177
    }
178
179
    protected function getList()
180
    {
181
        return $this->sessionIds;
182
    }
183
184
    /**
185
     * remove the sessionID of the Monitor from the list.
186
     *
187
     * @param array $sessionsIds
188
     *
189
     * @return mixed
190
     */
191
    protected function removeOwnSessionId(array $sessionsIds)
192
    {
193
        $key = array_search($this->session->getSessionId(), $sessionsIds);
194
        if ($key >= 0) {
195
            unset($sessionsIds[$key]);
196
        }
197
198
        return $sessionsIds;
199
    }
200
}
201