Completed
Push — master ( 7235dd...b44091 )
by Sergii
05:14
created

RouterTrait::prepareCallback()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5.2742

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 2
nop 1
dl 0
loc 13
ccs 7
cts 9
cp 0.7778
crap 5.2742
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 *
5
 * @author Donii Sergii <[email protected]>
6
 * Date: 10/25/17
7
 * Time: 11:57 AM
8
 */
9
10
namespace sonrac\WAMP\Routers;
11
12
use Thruway\ClientSession;
13
use Thruway\Peer\RouterInterface;
14
15
/**
16
 * Trait RouterTrait.
17
 * Base router trait.
18
 */
19
trait RouterTrait
20
{
21
    /**
22
     * Controllers list
23
     *
24
     * @var \sonrac\WAMP\Abstracts\WAMPControllerInterface[]
25
     *
26
     * @author Donii Sergii <[email protected]>
27
     */
28
    protected $controllers;
29
30
    /**
31
     * Router groups.
32
     *
33
     * @var null|array
34
     */
35
    protected $groups = null;
36
37
    /**
38
     * Main router
39
     *
40
     * @var null|\Thruway\Peer\RouterInterface|\sonrac\WAMP\Routers\Router
41
     *
42
     * @author Donii Sergii <[email protected]>
43
     */
44
    protected $router = null;
45
46
    /**
47
     * Route path prefix.
48
     *
49
     * @var string|null
50
     *
51
     * @author Donii Sergii <[email protected]>
52
     */
53
    private $prefix = null;
54
55
    /**
56
     * Controller namespace.
57
     *
58
     * @var string|null
59
     *
60
     * @author Donii Sergii <[email protected]>
61
     */
62
    private $groupControllerNamespace = null;
63
64
    /**
65
     * Middleware list.
66
     *
67
     * @var null|array
68
     *
69
     * @author Donii Sergii <[email protected]>
70
     */
71
    private $middleware = null;
72
73
    /**
74
     * Group routes.
75
     *
76
     * @param array    $config Group config
77
     * @param \Closure $runner Closure runner group
78
     *
79
     * @author Donii Sergii <[email protected]>
80
     */
81 2
    public function group(array $config, \Closure $runner)
82
    {
83 2
        $middleware = isset($config['middleware']) ? explode('|', $config['middleware']) : [];
84 2
        $namespace = isset($config['namespace']) ? $config['namespace'] : 'App\Controllers\WAMP';
85
86 2
        $this->groups[] = [
87 2
            'middleware' => $middleware,
88 2
            'namespace'  => $namespace,
89 2
            'prefix'     => isset($config['prefix']) ? $config['prefix'] : '',
90 2
            'callback'   => $runner,
91
        ];
92 2
    }
93
94
    /**
95
     * Parse groups
96
     *
97
     * @return \sonrac\WAMP\GroupsConfigInterface[]|\stdClass[]
98
     *
99
     * @author Donii Sergii <[email protected]>
100
     */
101 2
    public function parseGroups()
102
    {
103 2
        if (!is_array($this->groups) || !count($this->groups)) {
104 1
            return;
105
        }
106 1
        gc_enable();
107 1
        $callbacks = [];
108 1
        foreach ($this->groups as $group) {
109 1
            $this->prefix = $group['prefix'];
110 1
            $this->groupControllerNamespace = $group['namespace'];
111 1
            $this->middleware = $group['middleware'];
112 1
            $callbacks[] = $group['callback']($this->getClientSession(), $this->getClient());
113
        }
114
115 1
        $this->groups = null;
116 1
        unset($this->groups);
117 1
        $this->groups = [];
118
119 1
        $this->prefix = null;
120 1
        $this->groupControllerNamespace = null;
121
122 1
        gc_collect_cycles();
123 1
        gc_disable();
124
125 1
        return $callbacks;
126
    }
127
128
    /**
129
     * Get route groups
130
     *
131
     * @return null|\sonrac\WAMP\GroupsConfigInterface[]
132
     *
133
     * @author Donii Sergii <[email protected]>
134
     */
135 1
    public function getGroups()
136
    {
137 1
        return $this->groups;
138
    }
139
140
    /**
141
     * Get router
142
     *
143
     * @return mixed|null|\sonrac\WAMP\Contracts\WAMPRouterInterface|\sonrac\WAMP\Routers\Router|\Thruway\Peer\RouterInterface
144
     *
145
     * @author Donii Sergii <[email protected]>
146
     */
147 3
    public function getRouter()
148
    {
149 3
        return $this->router ?? $this->router = app()->wampRouter;
0 ignored issues
show
Bug introduced by
The function app was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

149
        return $this->router ?? $this->router = /** @scrutinizer ignore-call */ app()->wampRouter;
Loading history...
150
    }
151
152
    /**
153
     * Set router.
154
     *
155
     * @author Donii Sergii <[email protected]>
156
     */
157 2
    public function setRouter(RouterInterface $router)
158
    {
159 2
        $this->router = $router;
160 2
    }
161
162
    /**
163
     * Get client session.
164
     *
165
     * @return \Thruway\ClientSession
166
     *
167
     * @author Donii Sergii <[email protected]>
168
     */
169 2
    public function getClientSession()
170
    {
171 2
        return $this->getRouter()->getClient()->getSession();
0 ignored issues
show
Bug introduced by
The method getClient() does not exist on Thruway\Peer\RouterInterface. It seems like you code against a sub-type of Thruway\Peer\RouterInterface such as sonrac\WAMP\Routers\Router. ( Ignorable by Annotation )

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

171
        return $this->getRouter()->/** @scrutinizer ignore-call */ getClient()->getSession();
Loading history...
172
    }
173
174
    /**
175
     * Get client.
176
     *
177
     * @return \sonrac\WAMP\Client|\Thruway\Peer\ClientInterface
178
     *
179
     * @author Donii Sergii <[email protected]>
180
     */
181 1
    public function getClient()
182
    {
183 1
        return $this->getRouter()->getClient();
184
    }
185
186
    /**
187
     * Parse callback function
188
     *
189
     * @param string|\Closure $callback  Callback
190
     * @param null            $namespace Controller namespace
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $namespace is correct as it would always require null to be passed?
Loading history...
191
     *
192
     * @return \Closure
193
     *
194
     * @author Donii Sergii <[email protected]>
195
     */
196 3
    public function parseCallback($callback, $namespace = null)
197
    {
198 3
        if ($callback instanceof \Closure) {
199 2
            return $callback;
200
        }
201
202 2
        $namespace = $namespace ? $namespace.'\\' : '';
203
204 2
        $callback = explode('&', $callback);
205 2
        $self = $this;
206
207 2
        return function (ClientSession $clientSession) use ($callback, $namespace, $self) {
208
            if (count($callback) === 1) {
209
                return $this->{$callback[0]}($clientSession, $self->getClient());
210
            }
211
212
            if (!isset($this->controllers[$callback[0]])) {
213
                return $this->controllers[$callback[0]]->{$callback[1]}($clientSession, $this->getClient());
214
            }
215
216
            $className = class_exists($callback[0]) ? $callback[0] : $namespace.$callback[0];
217
218
            $this->controllers[$callback[0]] = app()->make($className);
0 ignored issues
show
Bug introduced by
The function app was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

218
            $this->controllers[$callback[0]] = /** @scrutinizer ignore-call */ app()->make($className);
Loading history...
219
220
            return $this->controllers[$callback[0]]->{$callback[1]}($clientSession, $self->getClient());
221 2
        };
222
    }
223
224
    /**
225
     * Prepare path.
226
     *
227
     * @param \Closure|string $callback Callback
228
     *
229
     * @return array
230
     *
231
     * @author Donii Sergii <[email protected]>
232
     */
233 1
    protected function prepareCallback($callback)
234
    {
235 1
        $namespace = $this->groupControllerNamespace ?? $this->getRouter()->getControllerNamespace();
0 ignored issues
show
Bug introduced by
The method getControllerNamespace() does not exist on Thruway\Peer\RouterInterface. It seems like you code against a sub-type of Thruway\Peer\RouterInterface such as sonrac\WAMP\Routers\Router. ( Ignorable by Annotation )

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

235
        $namespace = $this->groupControllerNamespace ?? $this->getRouter()->/** @scrutinizer ignore-call */ getControllerNamespace();
Loading history...
236 1
        if ($this->groupControllerNamespace && $this->groupControllerNamespace
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->groupControllerNamespace of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
237
            && is_string($callback) && count(explode('&', $callback)) === 2) {
238
            $callback = rtrim($namespace, '\\').$callback;
239
        }
240
241
        return [
242 1
            'prefix'     => $this->prefix,
243 1
            'namespace'  => $namespace,
244 1
            'callback'   => $this->parseCallback($callback, $namespace),
0 ignored issues
show
Bug introduced by
It seems like $namespace can also be of type string; however, parameter $namespace of sonrac\WAMP\Routers\RouterTrait::parseCallback() does only seem to accept null, 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

244
            'callback'   => $this->parseCallback($callback, /** @scrutinizer ignore-type */ $namespace),
Loading history...
245 1
            'middleware' => $this->middleware,
246
        ];
247
    }
248
}
249