Passed
Push — 8.0 ( 10c471...ab147a )
by liu
02:34
created

Resource::extend()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 2
rs 10
c 1
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: liu21st <[email protected]>
10
// +----------------------------------------------------------------------
11
declare(strict_types=1);
12
13
namespace think\route;
14
15
use Closure;
16
use think\Container;
17
use think\Route;
18
19
/**
20
 * 资源路由类
21
 */
22
class Resource extends RuleGroup
23
{
24
    /**
25
     * REST方法定义
26
     * @var array
27
     */
28
    protected $rest = [];
29
30
    /**
31
     * 模型绑定
32
     * @var array
33
     */
34
    protected $model = [];
35
36
    /**
37
     * 数据验证
38
     * @var array
39
     */
40
    protected $validate = [];
41
42
    /**
43
     * 中间件
44
     * @var array
45
     */
46
    protected $middleware = [];
47
48
    /**
49
     * 扩展规则
50
     * @var Closure
51
     */
52
    protected $extend;
53
54
    /**
55
     * 架构函数
56
     * @access public
57
     * @param  Route         $router     路由对象
58
     * @param  RuleGroup     $parent     上级对象
59
     * @param  string        $name       资源名称
60
     * @param  string        $route      路由地址
61
     * @param  array         $rest       资源定义
62
     */
63
    public function __construct(Route $router, ?RuleGroup $parent = null, string $name = '', string $route = '', array $rest = [])
64
    {
65
        $name           = ltrim($name, '/');
66
        $this->router   = $router;
67
        $this->parent   = $parent;
68
        $this->rule     = $name;
69
        $this->route    = $route;
70
        $this->name     = str_contains($name, '.') ? strstr($name, '.', true) : $name;
71
72
        $this->setFullName();
73
74
        // 资源路由默认为完整匹配
75
        $this->option['complete_match'] = true;
76
77
        $this->rest = $rest;
78
79
        if ($this->parent) {
80
            $this->domain = $this->parent->getDomain();
81
            $this->parent->addRuleItem($this);
82
        }
83
    }
84
85
    public function extend(Closure $extend)
86
    {
87
        $this->extend = $extend;
88
        return $this;
89
    }
90
91
    /**
92
     * 生成资源路由规则
93
     * @access public
94
     * @param  mixed $rule 路由规则
95
     * @return void
96
     */
97
    public function parseGroupRule($rule): void
98
    {
99
        $option = $this->option;
100
        $origin = $this->router->getGroup();
101
        $this->router->setGroup($this);
102
103
        if (str_contains($rule, '.')) {
104
            // 注册嵌套资源路由
105
            $array = explode('.', $rule);
106
            $last  = array_pop($array);
107
            $item  = [];
108
109
            foreach ($array as $val) {
110
                $item[] = $val . '/<' . ($option['var'][$val] ?? $val . '_id') . '>';
111
            }
112
113
            $rule = implode('/', $item) . '/' . $last;
114
        }
115
116
        $prefix = substr($rule, strlen($this->name) + 1);
117
118
        // 注册资源路由
119
        foreach ($this->rest as $key => $val) {
120
            if ((isset($option['only']) && !in_array($key, $option['only']))
121
                || (isset($option['except']) && in_array($key, $option['except']))
122
            ) {
123
                continue;
124
            }
125
126
            if (isset($last) && str_contains($val[1], '<id>') && isset($option['var'][$last])) {
127
                $val[1] = str_replace('<id>', '<' . $option['var'][$last] . '>', $val[1]);
128
            } elseif (str_contains($val[1], '<id>') && isset($option['var'][$rule])) {
129
                $val[1] = str_replace('<id>', '<' . $option['var'][$rule] . '>', $val[1]);
130
            }
131
132
            $ruleItem = $this->addRule(trim($prefix . $val[1], '/'), $this->route . '/' . $val[2], $val[0]);
0 ignored issues
show
Bug introduced by
Are you sure $this->route of type Closure|string can be used in concatenation? ( Ignorable by Annotation )

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

132
            $ruleItem = $this->addRule(trim($prefix . $val[1], '/'), /** @scrutinizer ignore-type */ $this->route . '/' . $val[2], $val[0]);
Loading history...
133
134
            foreach (['model', 'validate', 'middleware', 'pattern'] as $name) {
135
                if (isset($this->$name[$key])) {
136
                    call_user_func_array([$ruleItem, $name], (array) $this->$name[$key]);
137
                }
138
            }
139
        }
140
141
        if ($this->extend) {
142
            Container::getInstance()->invokeFunction($this->extend);
143
        }
144
145
        $this->router->setGroup($origin);
146
        $this->hasParsed = true;
147
    }
148
149
    /**
150
     * 设置资源允许
151
     * @access public
152
     * @param  array $only 资源允许
153
     * @return $this
154
     */
155
    public function only(array $only)
156
    {
157
        return $this->setOption('only', $only);
158
    }
159
160
    /**
161
     * 设置资源排除
162
     * @access public
163
     * @param  array $except 排除资源
164
     * @return $this
165
     */
166
    public function except(array $except)
167
    {
168
        return $this->setOption('except', $except);
169
    }
170
171
    /**
172
     * 设置资源路由的变量
173
     * @access public
174
     * @param  array $vars 资源变量
175
     * @return $this
176
     */
177
    public function vars(array $vars)
178
    {
179
        return $this->setOption('var', $vars);
180
    }
181
182
    /**
183
     * 绑定资源验证
184
     * @access public
185
     * @param  array|string $name 资源类型或者验证信息
186
     * @param  array|string $validate 验证信息
187
     * @return $this
188
     */
189
    public function withValidate(array|string $name, array|string $validate = [])
190
    {
191
        if (is_array($name)) {
0 ignored issues
show
introduced by
The condition is_array($name) is always true.
Loading history...
192
            $this->validate = array_merge($this->validate, $name);
193
        } else {
194
            $this->validate[$name] = $validate;
195
        }
196
197
        return $this;
198
    }
199
200
    /**
201
     * 绑定资源模型
202
     * @access public
203
     * @param  array|string $name 资源类型或者模型绑定
204
     * @param  array|string $model 模型绑定
205
     * @return $this
206
     */
207
    public function withModel(array|string $name, array|string $model = [])
208
    {
209
        if (is_array($name)) {
0 ignored issues
show
introduced by
The condition is_array($name) is always true.
Loading history...
210
            $this->model = array_merge($this->model, $name);
211
        } else {
212
            $this->model[$name] = $model;
213
        }
214
215
        return $this;
216
    }
217
218
    /**
219
     * 绑定资源中间件
220
     * @access public
221
     * @param  array|string $name 资源类型或者中间件定义
222
     * @param  array|string $middleware 中间件定义
223
     * @return $this
224
     */
225
    public function withMiddleware(array|string $name, array|string $middleware = [])
226
    {
227
        if (is_array($name)) {
0 ignored issues
show
introduced by
The condition is_array($name) is always true.
Loading history...
228
            $this->middleware = array_merge($this->middleware, $name);
229
        } else {
230
            $this->middleware[$name] = $middleware;
231
        }
232
233
        return $this;
234
    }
235
236
    /**
237
     * rest方法定义和修改
238
     * @access public
239
     * @param  array|string  $name 方法名称
240
     * @param  array|bool    $resource 资源
241
     * @return $this
242
     */
243
    public function rest(array|string $name, array|bool $resource = [])
244
    {
245
        if (is_array($name)) {
0 ignored issues
show
introduced by
The condition is_array($name) is always true.
Loading history...
246
            $this->rest = $resource ? $name : array_merge($this->rest, $name);
247
        } else {
248
            $this->rest[$name] = $resource;
249
        }
250
251
        return $this;
252
    }
253
}
254