Completed
Push — 6.0 ( aeaeca...ae21de )
by liu
02:43
created

Middleware::buildMiddleware()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 28
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
cc 7
eloc 14
nc 16
nop 2
dl 0
loc 28
ccs 0
cts 15
cp 0
crap 56
rs 8.8333
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
1 ignored issue
show
Coding Style introduced by
You must use "/**" style comments for a file comment
Loading history...
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: Slince <[email protected]>
10
// +----------------------------------------------------------------------
11
declare (strict_types = 1);
12
13
namespace think;
14
15
use InvalidArgumentException;
16
use LogicException;
17
use think\exception\HttpResponseException;
18
19
/**
20
 * 中间件管理类
21
 */
5 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
22
class Middleware
23
{
24
    /**
25
     * 中间件执行队列
26
     * @var array
27
     */
28
    protected $queue = [];
29
30
    /**
31
     * 配置
32
     * @var array
33
     */
34
    protected $config = [];
35
36
    /**
37
     * 应用对象
38
     * @var App
39
     */
40
    protected $app;
41
42 7
    public function __construct(array $config = [])
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
43
    {
44 7
        $this->config = array_merge($this->config, $config);
45 7
    }
46
47 7
    public static function __make(App $app, Config $config)
2 ignored issues
show
Coding Style introduced by
Missing doc comment for function __make()
Loading history...
Coding Style introduced by
Method name "Middleware::__make" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
Coding Style introduced by
Public method name "Middleware::__make" must not be prefixed with an underscore
Loading history...
48
    {
49 7
        return (new static($config->get('middleware')))->setApp($app);
0 ignored issues
show
Bug introduced by
It seems like $config->get('middleware') can also be of type null; however, parameter $config of think\Middleware::__construct() does only seem to accept array, 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

49
        return (new static(/** @scrutinizer ignore-type */ $config->get('middleware')))->setApp($app);
Loading history...
50
    }
51
52
    public function setConfig(array $config): void
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function setConfig()
Loading history...
53
    {
54
        $this->config = array_merge($this->config, $config);
55
    }
56
57
    /**
58
     * 设置应用对象
59
     * @access public
60
     * @param  App  $app
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
61
     * @return $this
62
     */
63 7
    public function setApp(App $app)
64
    {
65 7
        $this->app = $app;
66 7
        return $this;
67
    }
68
69
    /**
70
     * 导入中间件
71
     * @access public
72
     * @param  array  $middlewares
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
73
     * @param  string $type  中间件类型
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter name; 2 found
Loading history...
74
     * @return void
75
     */
76 7
    public function import(array $middlewares = [], string $type = 'route'): void
77
    {
78 7
        foreach ($middlewares as $middleware) {
79
            $this->add($middleware, $type);
80
        }
81 7
    }
82
83
    /**
84
     * 注册中间件
85
     * @access public
86
     * @param  mixed  $middleware
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
87
     * @param  string $type  中间件类型
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter name; 2 found
Loading history...
88
     * @return void
89
     */
90
    public function add($middleware, string $type = 'route'): void
91
    {
92
        if (is_null($middleware)) {
93
            return;
94
        }
95
96
        $middleware = $this->buildMiddleware($middleware, $type);
97
98
        if ($middleware) {
99
            $this->queue[$type][] = $middleware;
100
        }
101
    }
102
103
    /**
104
     * 注册控制器中间件
105
     * @access public
106
     * @param  mixed  $middleware
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
107
     * @return void
108
     */
109
    public function controller($middleware): void
110
    {
111
        $this->add($middleware, 'controller');
112
    }
113
114
    /**
115
     * 移除中间件
116
     * @access public
117
     * @param  mixed  $middleware
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
118
     * @param  string $type  中间件类型
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter name; 2 found
Loading history...
119
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
120
    public function unshift($middleware, string $type = 'route')
121
    {
122
        if (is_null($middleware)) {
123
            return;
124
        }
125
126
        $middleware = $this->buildMiddleware($middleware, $type);
127
128
        if (!empty($middleware)) {
129
            array_unshift($this->queue[$type], $middleware);
130
        }
131
    }
132
133
    /**
134
     * 获取注册的中间件
135
     * @access public
136
     * @param  string $type  中间件类型
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
137
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
138
    public function all(string $type = 'route'): array
139
    {
140
        return $this->queue[$type] ?? [];
141
    }
142
143
    /**
144
     * 中间件调度
145
     * @access public
146
     * @param  Request  $request
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
147
     * @param  string   $type  中间件类型
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 2 found
Loading history...
148
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
149
    public function dispatch(Request $request, string $type = 'route')
150
    {
151
        return call_user_func($this->resolve($type), $request);
152
    }
153
154
    /**
155
     * 解析中间件
156
     * @access protected
157
     * @param  mixed  $middleware
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
158
     * @param  string $type  中间件类型
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter name; 2 found
Loading history...
159
     * @return array
160
     */
161
    protected function buildMiddleware($middleware, string $type = 'route'): array
162
    {
163
        if (is_array($middleware)) {
164
            list($middleware, $param) = $middleware;
165
        }
166
167
        if ($middleware instanceof \Closure) {
168
            return [$middleware, $param ?? null];
169
        }
170
171
        if (!is_string($middleware)) {
172
            throw new InvalidArgumentException('The middleware is invalid');
173
        }
174
175
        if (isset($this->config[$middleware])) {
176
            $middleware = $this->config[$middleware];
177
        }
178
179
        if (is_array($middleware)) {
180
            $this->import($middleware, $type);
181
            return [];
182
        }
183
184
        if (strpos($middleware, ':')) {
185
            list($middleware, $param) = explode(':', $middleware, 2);
186
        }
187
188
        return [[$middleware, 'handle'], $param ?? null];
189
    }
190
191
    protected function resolve(string $type = 'route')
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function resolve()
Loading history...
192
    {
193
        return function (Request $request) use ($type) {
194
            $middleware = array_shift($this->queue[$type]);
195
196
            if (null === $middleware) {
197
                throw new InvalidArgumentException('The queue was exhausted, with no response returned');
198
            }
199
200
            list($call, $param) = $middleware;
201
202
            if (is_array($call) && is_string($call[0])) {
203
                $call = [$this->app->make($call[0]), $call[1]];
204
            }
205
206
            try {
207
                $response = $this->app->invoke($call, [$request, $this->resolve($type), $param]);
208
            } catch (HttpResponseException $exception) {
209
                $response = $exception->getResponse();
210
            }
211
212
            if (!$response instanceof Response) {
213
                throw new LogicException('The middleware must return Response instance');
214
            }
215
216
            return $response;
217
        };
218
    }
219
220
}
221