Passed
Pull Request — 5.1 (#1777)
by
unknown
07:58
created

Validate::allowIp()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
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~2018 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
12
namespace think;
13
14
use think\exception\ClassNotFoundException;
15
use think\validate\ValidateRule;
16
17
class Validate
1 ignored issue
show
Coding Style introduced by
Missing class doc comment
Loading history...
18
{
19
20
    /**
21
     * 自定义验证类型
22
     * @var array
23
     */
24
    protected static $type = [];
25
26
    /**
27
     * 验证类型别名
28
     * @var array
29
     */
30
    protected $alias = [
31
        '>' => 'gt', '>=' => 'egt', '<' => 'lt', '<=' => 'elt', '=' => 'eq', 'same' => 'eq',
32
    ];
33
34
    /**
35
     * 当前验证规则
36
     * @var array
37
     */
38
    protected $rule = [];
39
40
    /**
41
     * 验证提示信息
42
     * @var array
43
     */
44
    protected $message = [];
45
46
    /**
47
     * 验证字段描述
48
     * @var array
49
     */
50
    protected $field = [];
51
52
    /**
53
     * 默认规则提示
54
     * @var array
55
     */
56
    protected static $typeMsg = [
57
        'require'     => ':attribute require',
58
        'must'        => ':attribute must',
59
        'number'      => ':attribute must be numeric',
60
        'integer'     => ':attribute must be integer',
61
        'float'       => ':attribute must be float',
62
        'boolean'     => ':attribute must be bool',
63
        'email'       => ':attribute not a valid email address',
64
        'mobile'      => ':attribute not a valid mobile',
65
        'array'       => ':attribute must be a array',
66
        'accepted'    => ':attribute must be yes,on or 1',
67
        'date'        => ':attribute not a valid datetime',
68
        'file'        => ':attribute not a valid file',
69
        'image'       => ':attribute not a valid image',
70
        'alpha'       => ':attribute must be alpha',
71
        'alphaNum'    => ':attribute must be alpha-numeric',
72
        'alphaDash'   => ':attribute must be alpha-numeric, dash, underscore',
73
        'activeUrl'   => ':attribute not a valid domain or ip',
74
        'chs'         => ':attribute must be chinese',
75
        'chsAlpha'    => ':attribute must be chinese or alpha',
76
        'chsAlphaNum' => ':attribute must be chinese,alpha-numeric',
77
        'chsDash'     => ':attribute must be chinese,alpha-numeric,underscore, dash',
78
        'url'         => ':attribute not a valid url',
79
        'ip'          => ':attribute not a valid ip',
80
        'dateFormat'  => ':attribute must be dateFormat of :rule',
81
        'in'          => ':attribute must be in :rule',
82
        'notIn'       => ':attribute be notin :rule',
83
        'between'     => ':attribute must between :1 - :2',
84
        'notBetween'  => ':attribute not between :1 - :2',
85
        'length'      => 'size of :attribute must be :rule',
86
        'max'         => 'max size of :attribute must be :rule',
87
        'min'         => 'min size of :attribute must be :rule',
88
        'after'       => ':attribute cannot be less than :rule',
89
        'before'      => ':attribute cannot exceed :rule',
90
        'afterWith'   => ':attribute cannot be less than :rule',
91
        'beforeWith'  => ':attribute cannot exceed :rule',
92
        'expire'      => ':attribute not within :rule',
93
        'allowIp'     => 'access IP is not allowed',
94
        'denyIp'      => 'access IP denied',
95
        'confirm'     => ':attribute out of accord with :2',
96
        'different'   => ':attribute cannot be same with :2',
97
        'egt'         => ':attribute must greater than or equal :rule',
98
        'gt'          => ':attribute must greater than :rule',
99
        'elt'         => ':attribute must less than or equal :rule',
100
        'lt'          => ':attribute must less than :rule',
101
        'eq'          => ':attribute must equal :rule',
102
        'unique'      => ':attribute has exists',
103
        'regex'       => ':attribute not conform to the rules',
104
        'method'      => 'invalid Request method',
105
        'token'       => 'invalid token',
106
        'fileSize'    => 'filesize not match',
107
        'fileExt'     => 'extensions to upload is not allowed',
108
        'fileMime'    => 'mimetype to upload is not allowed',
109
    ];
110
111
    /**
112
     * 当前验证场景
113
     * @var array
114
     */
115
    protected $currentScene = null;
116
117
    /**
118
     * Filter_var 规则
119
     * @var array
120
     */
121
    protected $filter = [
122
        'email'   => FILTER_VALIDATE_EMAIL,
123
        'ip'      => [FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6],
124
        'integer' => FILTER_VALIDATE_INT,
125
        'url'     => FILTER_VALIDATE_URL,
126
        'macAddr' => FILTER_VALIDATE_MAC,
127
        'float'   => FILTER_VALIDATE_FLOAT,
128
    ];
129
130
    /**
131
     * 内置正则验证规则
132
     * @var array
133
     */
134
    protected $defaultRegex = [
135
        'alphaDash'   => '/^[A-Za-z0-9\-\_]+$/',
136
        'chs'         => '/^[\x{4e00}-\x{9fa5}]+$/u',
137
        'chsAlpha'    => '/^[\x{4e00}-\x{9fa5}a-zA-Z]+$/u',
138
        'chsAlphaNum' => '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9]+$/u',
139
        'chsDash'     => '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\_\-]+$/u',
140
        'mobile'      => '/^1[3-9][0-9]\d{8}$/',
141
        'idCard'      => '/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$)/',
142
        'zip'         => '/\d{6}/',
143
    ];
144
145
    /**
146
     * 验证场景定义
147
     * @var array
148
     */
149
    protected $scene = [];
150
151
    /**
152
     * 验证失败错误信息
153
     * @var array
154
     */
155
    protected $error = [];
156
157
    /**
158
     * 是否批量验证
159
     * @var bool
160
     */
161
    protected $batch = false;
162
163
    /**
164
     * 场景需要验证的规则
165
     * @var array
166
     */
167
    protected $only = [];
168
169
    /**
170
     * 场景需要移除的验证规则
171
     * @var array
172
     */
173
    protected $remove = [];
174
175
    /**
176
     * 场景需要追加的验证规则
177
     * @var array
178
     */
179
    protected $append = [];
180
181
    /**
182
     * 验证正则定义
183
     * @var array
184
     */
185
    protected $regex = [];
186
187
    /**
188
     * 架构函数
189
     * @access public
190
     * @param  array $rules 验证规则
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
191
     * @param  array $message 验证提示信息
192
     * @param  array $field 验证字段描述信息
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
193
     */
194
    public function __construct(array $rules = [], array $message = [], array $field = [])
195
    {
196
        $this->rule    = $rules + $this->rule;
197
        $this->message = array_merge($this->message, $message);
198
        $this->field   = array_merge($this->field, $field);
199
    }
200
201
    /**
202
     * 创建一个验证器类
203
     * @access public
204
     * @param  array $rules 验证规则
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
205
     * @param  array $message 验证提示信息
206
     * @param  array $field 验证字段描述信息
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
207
     * @return Validate
208
     */
209
    public static function make(array $rules = [], array $message = [], array $field = [])
210
    {
211
        return new self($rules, $message, $field);
212
    }
213
214
    /**
215
     * 添加字段验证规则
216
     * @access protected
217
     * @param  string|array  $name  字段名称或者规则数组
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
218
     * @param  mixed         $rule  验证规则或者字段描述信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
219
     * @return $this
220
     */
221
    public function rule($name, $rule = '')
222
    {
223
        if (is_array($name)) {
224
            $this->rule = $name + $this->rule;
225
            if (is_array($rule)) {
226
                $this->field = array_merge($this->field, $rule);
227
            }
228
        } else {
229
            $this->rule[$name] = $rule;
230
        }
231
232
        return $this;
233
    }
234
235
    /**
236
     * 注册扩展验证(类型)规则
237
     * @access public
238
     * @param  string    $type  验证规则类型
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 2 found
Loading history...
239
     * @param  mixed     $callback callback方法(或闭包)
240
     * @return void
241
     */
242
    public static function extend($type, $callback = null)
243
    {
244
        if (is_array($type)) {
0 ignored issues
show
introduced by
The condition is_array($type) is always false.
Loading history...
245
            self::$type = array_merge(self::$type, $type);
246
        } else {
247
            self::$type[$type] = $callback;
248
        }
249
    }
250
251
    /**
252
     * 设置验证规则的默认提示信息
253
     * @access public
254
     * @param  string|array  $type  验证规则类型名称或者数组
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
255
     * @param  string        $msg  验证提示信息
256
     * @return void
257
     */
258
    public static function setTypeMsg($type, $msg = null)
259
    {
260
        if (is_array($type)) {
261
            self::$typeMsg = array_merge(self::$typeMsg, $type);
262
        } else {
263
            self::$typeMsg[$type] = $msg;
264
        }
265
    }
266
267
    /**
268
     * 设置提示信息
269
     * @access public
270
     * @param  string|array  $name  字段名称
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 2 found
Loading history...
271
     * @param  string        $message 提示信息
272
     * @return Validate
273
     */
274
    public function message($name, $message = '')
275
    {
276
        if (is_array($name)) {
277
            $this->message = array_merge($this->message, $name);
278
        } else {
279
            $this->message[$name] = $message;
280
        }
281
282
        return $this;
283
    }
284
285
    /**
286
     * 设置验证场景
287
     * @access public
288
     * @param  string  $name  场景名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
289
     * @return $this
290
     */
291
    public function scene($name)
292
    {
293
        // 设置当前场景
294
        $this->currentScene = $name;
0 ignored issues
show
Documentation Bug introduced by
It seems like $name of type string is incompatible with the declared type array of property $currentScene.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
295
296
        return $this;
297
    }
298
299
    /**
300
     * 判断是否存在某个验证场景
301
     * @access public
302
     * @param  string $name 场景名
303
     * @return bool
304
     */
305
    public function hasScene($name)
306
    {
307
        return isset($this->scene[$name]) || method_exists($this, 'scene' . $name);
308
    }
309
310
    /**
311
     * 设置批量验证
312
     * @access public
313
     * @param  bool $batch  是否批量验证
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
314
     * @return $this
315
     */
316
    public function batch($batch = true)
317
    {
318
        $this->batch = $batch;
319
320
        return $this;
321
    }
322
323
    /**
324
     * 指定需要验证的字段列表
325
     * @access public
326
     * @param  array $fields  字段名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
327
     * @return $this
328
     */
329
    public function only($fields)
330
    {
331
        $this->only = $fields;
332
333
        return $this;
334
    }
335
336
    /**
337
     * 移除某个字段的验证规则
338
     * @access public
339
     * @param  string|array  $field  字段名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
340
     * @param  mixed         $rule   验证规则 null 移除所有规则
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 3 found
Loading history...
341
     * @return $this
342
     */
343
    public function remove($field, $rule = null)
344
    {
345
        if (is_array($field)) {
346
            foreach ($field as $key => $rule) {
347
                if (is_int($key)) {
348
                    $this->remove($rule);
349
                } else {
350
                    $this->remove($key, $rule);
351
                }
352
            }
353
        } else {
354
            if (is_string($rule)) {
355
                $rule = explode('|', $rule);
356
            }
357
358
            $this->remove[$field] = $rule;
359
        }
360
361
        return $this;
362
    }
363
364
    /**
365
     * 追加某个字段的验证规则
366
     * @access public
367
     * @param  string|array  $field  字段名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
368
     * @param  mixed         $rule   验证规则
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 3 found
Loading history...
369
     * @return $this
370
     */
371
    public function append($field, $rule = null)
372
    {
373
        if (is_array($field)) {
374
            foreach ($field as $key => $rule) {
375
                $this->append($key, $rule);
376
            }
377
        } else {
378
            if (is_string($rule)) {
379
                $rule = explode('|', $rule);
380
            }
381
382
            $this->append[$field] = $rule;
383
        }
384
385
        return $this;
386
    }
387
388
    /**
389
     * 数据自动验证
390
     * @access public
391
     * @param  array     $data  数据
392
     * @param  mixed     $rules  验证规则
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
393
     * @param  string    $scene 验证场景
394
     * @return bool
395
     */
396
    public function check($data, $rules = [], $scene = '')
397
    {
398
        $this->error = [];
399
400
        if (empty($rules)) {
401
            // 读取验证规则
402
            $rules = $this->getRules();
403
        }
404
405
        // 获取场景定义
406
        $this->getScene($scene);
407
408
        foreach ($this->append as $key => $rule) {
409
            if (!isset($rules[$key])) {
410
                $rules[$key] = $rule;
411
            }
412
        }
413
414
        foreach ($rules as $key => $rule) {
415
            // field => 'rule1|rule2...' field => ['rule1','rule2',...]
416
            if (strpos($key, '|')) {
417
                // 字段|描述 用于指定属性名称
418
                list($key, $title) = explode('|', $key);
419
            } else {
420
                $title = isset($this->field[$key]) ? $this->field[$key] : $key;
421
            }
422
423
            // 场景检测
424
            if (!empty($this->only) && !in_array($key, $this->only)) {
425
                continue;
426
            }
427
428
            // 获取数据 支持多维数组
429
            $value = $this->getDataValue($data, $key);
430
431
            // 字段验证
432
            if ($rule instanceof \Closure) {
433
                $result = call_user_func_array($rule, [$value, $data, $title, $this]);
434
            } elseif ($rule instanceof ValidateRule) {
435
                //  验证因子
436
                $result = $this->checkItem($key, $value, $rule->getRule(), $data, $rule->getTitle() ?: $title, $rule->getMsg());
437
            } else {
438
                $result = $this->checkItem($key, $value, $rule, $data, $title);
439
            }
440
441
            if (true !== $result) {
442
                // 没有返回true 则表示验证失败
443
                if (!empty($this->batch)) {
444
                    // 批量验证
445
                    if (is_array($result)) {
446
                        $this->error = array_merge($this->error, $result);
447
                    } else {
448
                        $this->error[$key] = $result;
449
                    }
450
                } else {
451
                    $this->error = $result;
452
                    return false;
453
                }
454
            }
455
        }
456
457
        return !empty($this->error) ? false : true;
458
    }
459
460
    /**
461
     * 根据验证规则验证数据
462
     * @access public
463
     * @param  mixed     $value 字段值
464
     * @param  mixed     $rules 验证规则
465
     * @return bool
466
     */
467
    public function checkRule($value, $rules)
468
    {
469
        if ($rules instanceof \Closure) {
470
            return call_user_func_array($rules, [$value]);
471
        } elseif ($rules instanceof ValidateRule) {
472
            $rules = $rules->getRule();
473
        } elseif (is_string($rules)) {
474
            $rules = explode('|', $rules);
475
        }
476
477
        foreach ($rules as $key => $rule) {
478
            if ($rule instanceof \Closure) {
479
                $result = call_user_func_array($rule, [$value]);
480
            } else {
481
                // 判断验证类型
482
                list($type, $rule) = $this->getValidateType($key, $rule);
483
484
                $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type];
485
486
                $result = call_user_func_array($callback, [$value, $rule]);
487
            }
488
489
            if (true !== $result) {
490
                return $result;
491
            }
492
        }
493
494
        return true;
495
    }
496
497
    /**
498
     * 验证单个字段规则
499
     * @access protected
500
     * @param  string    $field  字段名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
501
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
502
     * @param  mixed     $rules  验证规则
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
503
     * @param  array     $data  数据
504
     * @param  string    $title  字段描述
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
505
     * @param  array     $msg  提示信息
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 2 found
Loading history...
506
     * @return mixed
507
     */
508
    protected function checkItem($field, $value, $rules, $data, $title = '', $msg = [])
509
    {
510
        if (isset($this->remove[$field]) && true === $this->remove[$field] && empty($this->append[$field])) {
511
            // 字段已经移除 无需验证
512
            return true;
513
        }
514
515
        // 支持多规则验证 require|in:a,b,c|... 或者 ['require','in'=>'a,b,c',...]
516
        if (is_string($rules)) {
517
            $rules = explode('|', $rules);
518
        }
519
520
        if (isset($this->append[$field])) {
521
            // 追加额外的验证规则
522
            $rules = array_unique(array_merge($rules, $this->append[$field]));
523
        }
524
525
        $i      = 0;
526
        $result = true;
527
528
        foreach ($rules as $key => $rule) {
529
            if ($rule instanceof \Closure) {
530
                $result = call_user_func_array($rule, [$value, $data]);
531
                $info   = is_numeric($key) ? '' : $key;
532
            } else {
533
                // 判断验证类型
534
                list($type, $rule, $info) = $this->getValidateType($key, $rule);
535
536
                if (isset($this->append[$field]) && in_array($info, $this->append[$field])) {
537
538
                } elseif (array_key_exists($field, $this->remove) && (null === $this->remove[$field] || in_array($info, $this->remove[$field]))) {
539
                    // 规则已经移除
540
                    $i++;
541
                    continue;
542
                }
543
544
                // 验证类型
545
                if (isset(self::$type[$type])) {
546
                    $result = call_user_func_array(self::$type[$type], [$value, $rule, $data, $field, $title]);
547
                } elseif ('must' == $info || 0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) {
548
                    // 验证数据
549
                    $result = call_user_func_array([$this, $type], [$value, $rule, $data, $field, $title]);
550
                } else {
551
                    $result = true;
552
                }
553
            }
554
555
            if (false === $result) {
556
                // 验证失败 返回错误信息
557
                if (!empty($msg[$i])) {
558
                    $message = $msg[$i];
559
                    if (is_string($message) && strpos($message, '{%') === 0) {
560
                        $message = facade\Lang::get(substr($message, 2, -1));
561
                    }
562
                } else {
563
                    $message = $this->getRuleMsg($field, $title, $info, $rule);
564
                }
565
566
                return $message;
567
            } elseif (true !== $result) {
568
                // 返回自定义错误信息
569
                if (is_string($result) && false !== strpos($result, ':')) {
570
                    $result = str_replace(':attribute', $title, $result);
571
572
                    if (strpos($result, ':rule') && is_scalar($rule)) {
573
                        $msg = str_replace(':rule', (string) $rule, $result);
0 ignored issues
show
Unused Code introduced by
The assignment to $msg is dead and can be removed.
Loading history...
574
                    }
575
                }
576
577
                return $result;
578
            }
579
            $i++;
580
        }
581
582
        return $result;
583
    }
584
585
    /**
586
     * 获取当前验证类型及规则
587
     * @access public
588
     * @param  mixed     $key
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
589
     * @param  mixed     $rule
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
590
     * @return array
591
     */
592
    protected function getValidateType($key, $rule)
593
    {
594
        // 判断验证类型
595
        if (!is_numeric($key)) {
596
            return [$key, $rule, $key];
597
        }
598
599
        if (strpos($rule, ':')) {
600
            list($type, $rule) = explode(':', $rule, 2);
601
            if (isset($this->alias[$type])) {
602
                // 判断别名
603
                $type = $this->alias[$type];
604
            }
605
            $info = $type;
606
        } elseif (method_exists($this, $rule)) {
607
            $type = $rule;
608
            $info = $rule;
609
            $rule = '';
610
        } else {
611
            $type = 'is';
612
            $info = $rule;
613
        }
614
615
        return [$type, $rule, $info];
616
    }
617
618
    /**
619
     * 验证是否和某个字段的值一致
620
     * @access public
621
     * @param  mixed     $value 字段值
622
     * @param  mixed     $rule  验证规则
623
     * @param  array     $data  数据
624
     * @param  string    $field 字段名
625
     * @return bool
626
     */
627
    public function confirm($value, $rule, $data = [], $field = '')
628
    {
629
        if ('' == $rule) {
630
            if (strpos($field, '_confirm')) {
631
                $rule = strstr($field, '_confirm', true);
632
            } else {
633
                $rule = $field . '_confirm';
634
            }
635
        }
636
637
        return $this->getDataValue($data, $rule) === $value;
638
    }
639
640
    /**
641
     * 验证是否和某个字段的值是否不同
642
     * @access public
643
     * @param  mixed $value 字段值
644
     * @param  mixed $rule  验证规则
645
     * @param  array $data  数据
646
     * @return bool
647
     */
648
    public function different($value, $rule, $data = [])
649
    {
650
        return $this->getDataValue($data, $rule) != $value;
651
    }
652
653
    /**
654
     * 验证是否大于等于某个值
655
     * @access public
656
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
657
     * @param  mixed     $rule  验证规则
658
     * @param  array     $data  数据
659
     * @return bool
660
     */
661
    public function egt($value, $rule, $data = [])
662
    {
663
        return $value >= $this->getDataValue($data, $rule);
664
    }
665
666
    /**
667
     * 验证是否大于某个值
668
     * @access public
669
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
670
     * @param  mixed     $rule  验证规则
671
     * @param  array     $data  数据
672
     * @return bool
673
     */
674
    public function gt($value, $rule, $data)
675
    {
676
        return $value > $this->getDataValue($data, $rule);
677
    }
678
679
    /**
680
     * 验证是否小于等于某个值
681
     * @access public
682
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
683
     * @param  mixed     $rule  验证规则
684
     * @param  array     $data  数据
685
     * @return bool
686
     */
687
    public function elt($value, $rule, $data = [])
688
    {
689
        return $value <= $this->getDataValue($data, $rule);
690
    }
691
692
    /**
693
     * 验证是否小于某个值
694
     * @access public
695
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
696
     * @param  mixed     $rule  验证规则
697
     * @param  array     $data  数据
698
     * @return bool
699
     */
700
    public function lt($value, $rule, $data = [])
701
    {
702
        return $value < $this->getDataValue($data, $rule);
703
    }
704
705
    /**
706
     * 验证是否等于某个值
707
     * @access public
708
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
709
     * @param  mixed     $rule  验证规则
710
     * @return bool
711
     */
712
    public function eq($value, $rule)
713
    {
714
        return $value == $rule;
715
    }
716
717
    /**
718
     * 必须验证
719
     * @access public
720
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
721
     * @param  mixed     $rule  验证规则
722
     * @return bool
723
     */
724
    public function must($value, $rule = null)
725
    {
726
        return !empty($value) || '0' == $value;
727
    }
728
729
    /**
730
     * 验证字段值是否为有效格式
731
     * @access public
732
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
733
     * @param  string    $rule  验证规则
734
     * @param  array     $data  验证数据
735
     * @return bool
736
     */
737
    public function is($value, $rule, $data = [])
738
    {
739
        switch (Loader::parseName($rule, 1, false)) {
740
            case 'require':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
741
                // 必须
742
                $result = !empty($value) || '0' == $value;
743
                break;
744
            case 'accepted':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
745
                // 接受
746
                $result = in_array($value, ['1', 'on', 'yes']);
747
                break;
748
            case 'date':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
749
                // 是否是一个有效日期
750
                $result = false !== strtotime($value);
751
                break;
752
            case 'activeUrl':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
753
                // 是否为有效的网址
754
                $result = checkdnsrr($value);
755
                break;
756
            case 'boolean':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
757
            case 'bool':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
758
                // 是否为布尔值
759
                $result = in_array($value, [true, false, 0, 1, '0', '1'], true);
760
                break;
761
            case 'number':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
762
                $result = ctype_digit((string) $value);
763
                break;
764
            case 'alphaNum':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
765
                $result = ctype_alnum($value);
766
                break;
767
            case 'array':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
768
                // 是否为数组
769
                $result = is_array($value);
770
                break;
771
            case 'file':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
772
                $result = $value instanceof File;
773
                break;
774
            case 'image':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
775
                $result = $value instanceof File && in_array($this->getImageType($value->getRealPath()), [1, 2, 3, 6]);
776
                break;
777
            case 'token':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
778
                $result = $this->token($value, '__token__', $data);
779
                break;
780
            default:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
781
                if (isset(self::$type[$rule])) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
782
                    // 注册的验证规则
783
                    $result = call_user_func_array(self::$type[$rule], [$value]);
784
                } elseif (function_exists('ctype_' . $rule)) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
785
                    // ctype验证规则
786
                    $ctypeFun = 'ctype_' . $rule;
787
                    $result   = $ctypeFun($value);
788
                } elseif (isset($this->filter[$rule])) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
789
                    // Filter_var验证规则
790
                    $result = $this->filter($value, $this->filter[$rule]);
791
                } else {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
792
                    // 正则验证
793
                    $result = $this->regex($value, $rule);
794
                }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
795
        }
796
797
        return $result;
798
    }
799
800
    // 判断图像类型
801
    protected function getImageType($image)
0 ignored issues
show
Coding Style introduced by
You must use "/**" style comments for a function comment
Loading history...
802
    {
803
        if (function_exists('exif_imagetype')) {
804
            return exif_imagetype($image);
805
        }
806
807
        try {
808
            $info = getimagesize($image);
809
            return $info ? $info[2] : false;
810
        } catch (\Exception $e) {
811
            return false;
812
        }
813
    }
814
815
    /**
816
     * 验证是否为合格的域名或者IP 支持A,MX,NS,SOA,PTR,CNAME,AAAA,A6, SRV,NAPTR,TXT 或者 ANY类型
817
     * @access public
818
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
819
     * @param  mixed     $rule  验证规则
820
     * @return bool
821
     */
822
    public function activeUrl($value, $rule = 'MX')
823
    {
824
        if (!in_array($rule, ['A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY'])) {
825
            $rule = 'MX';
826
        }
827
828
        return checkdnsrr($value, $rule);
829
    }
830
831
    /**
832
     * 验证是否有效IP
833
     * @access public
834
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
835
     * @param  mixed     $rule  验证规则 ipv4 ipv6
836
     * @return bool
837
     */
838
    public function ip($value, $rule = 'ipv4')
839
    {
840
        if (!in_array($rule, ['ipv4', 'ipv6'])) {
841
            $rule = 'ipv4';
842
        }
843
844
        return $this->filter($value, [FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4]);
845
    }
846
847
    /**
848
     * 验证上传文件后缀
849
     * @access public
850
     * @param  mixed     $file  上传文件
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
851
     * @param  mixed     $rule  验证规则
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
852
     * @return bool
853
     */
854
    public function fileExt($file, $rule)
855
    {
856
        if (is_array($file)) {
857
            foreach ($file as $item) {
858
                if (!($item instanceof File) || !$item->checkExt($rule)) {
859
                    return false;
860
                }
861
            }
862
            return true;
863
        } elseif ($file instanceof File) {
864
            return $file->checkExt($rule);
865
        }
866
867
        return false;
868
    }
869
870
    /**
871
     * 验证上传文件类型
872
     * @access public
873
     * @param  mixed     $file  上传文件
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
874
     * @param  mixed     $rule  验证规则
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
875
     * @return bool
876
     */
877
    public function fileMime($file, $rule)
878
    {
879
        if (is_array($file)) {
880
            foreach ($file as $item) {
881
                if (!($item instanceof File) || !$item->checkMime($rule)) {
882
                    return false;
883
                }
884
            }
885
            return true;
886
        } elseif ($file instanceof File) {
887
            return $file->checkMime($rule);
888
        }
889
890
        return false;
891
    }
892
893
    /**
894
     * 验证上传文件大小
895
     * @access public
896
     * @param  mixed     $file  上传文件
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
897
     * @param  mixed     $rule  验证规则
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
898
     * @return bool
899
     */
900
    public function fileSize($file, $rule)
901
    {
902
        if (is_array($file)) {
903
            foreach ($file as $item) {
904
                if (!($item instanceof File) || !$item->checkSize($rule)) {
905
                    return false;
906
                }
907
            }
908
            return true;
909
        } elseif ($file instanceof File) {
910
            return $file->checkSize($rule);
911
        }
912
913
        return false;
914
    }
915
916
    /**
917
     * 验证图片的宽高及类型
918
     * @access public
919
     * @param  mixed     $file  上传文件
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
920
     * @param  mixed     $rule  验证规则
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
921
     * @return bool
922
     */
923
    public function image($file, $rule)
924
    {
925
        if (!($file instanceof File)) {
926
            return false;
927
        }
928
929
        if ($rule) {
930
            $rule = explode(',', $rule);
931
932
            list($width, $height, $type) = getimagesize($file->getRealPath());
933
934
            if (isset($rule[2])) {
935
                $imageType = strtolower($rule[2]);
936
937
                if ('jpeg' == $imageType) {
938
                    $imageType = 'jpg';
939
                }
940
941
                if (image_type_to_extension($type, false) != $imageType) {
942
                    return false;
943
                }
944
            }
945
946
            list($w, $h) = $rule;
947
948
            return $w == $width && $h == $height;
949
        }
950
951
        return in_array($this->getImageType($file->getRealPath()), [1, 2, 3, 6]);
952
    }
953
954
    /**
955
     * 验证请求类型
956
     * @access public
957
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
958
     * @param  mixed     $rule  验证规则
959
     * @return bool
960
     */
961
    public function method($value, $rule)
962
    {
963
        $method = Container::get('request')->method();
964
        return strtoupper($rule) == $method;
965
    }
966
967
    /**
968
     * 验证时间和日期是否符合指定格式
969
     * @access public
970
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
971
     * @param  mixed     $rule  验证规则
972
     * @return bool
973
     */
974
    public function dateFormat($value, $rule)
975
    {
976
        $info = date_parse_from_format($rule, $value);
977
        return 0 == $info['warning_count'] && 0 == $info['error_count'];
978
    }
979
980
    /**
981
     * 验证是否唯一
982
     * @access public
983
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
984
     * @param  mixed     $rule  验证规则 格式:数据表,字段名,排除ID,主键名
985
     * @param  array     $data  数据
986
     * @param  string    $field  验证字段名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
987
     * @return bool
988
     */
989
    public function unique($value, $rule, $data, $field)
990
    {
991
        if (is_string($rule)) {
992
            $rule = explode(',', $rule);
993
        }
994
995
        if (false !== strpos($rule[0], '\\')) {
996
            // 指定模型类
997
            $db = new $rule[0];
998
        } else {
999
            try {
1000
                $db = Container::get('app')->model($rule[0]);
1001
            } catch (ClassNotFoundException $e) {
1002
                $db = Db::name($rule[0]);
1003
            }
1004
        }
1005
1006
        $key = isset($rule[1]) ? $rule[1] : $field;
1007
1008
        if (strpos($key, '^')) {
1009
            // 支持多个字段验证
1010
            $fields = explode('^', $key);
1011
            foreach ($fields as $key) {
1012
                if (isset($data[$key])) {
1013
                    $map[] = [$key, '=', $data[$key]];
1014
                }
1015
            }
1016
        } elseif (strpos($key, '=')) {
1017
            parse_str($key, $map);
1018
        } elseif (isset($data[$field])) {
1019
            $map[] = [$key, '=', $data[$field]];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$map was never initialized. Although not strictly required by PHP, it is generally a good practice to add $map = array(); before regardless.
Loading history...
1020
        } else {
1021
            $map = [];
1022
        }
1023
1024
        $pk = !empty($rule[3]) ? $rule[3] : $db->getPk();
1025
1026
        if (is_string($pk)) {
1027
            if (isset($rule[2])) {
1028
                $map[] = [$pk, '<>', $rule[2]];
1029
            } elseif (isset($data[$pk])) {
1030
                $map[] = [$pk, '<>', $data[$pk]];
1031
            }
1032
        }
1033
1034
        if ($db->where($map)->field($pk)->find()) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $map does not seem to be defined for all execution paths leading up to this point.
Loading history...
1035
            return false;
1036
        }
1037
1038
        return true;
1039
    }
1040
1041
    /**
1042
     * 使用行为类验证
1043
     * @access public
1044
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1045
     * @param  mixed     $rule  验证规则
1046
     * @param  array     $data  数据
1047
     * @return mixed
1048
     */
1049
    public function behavior($value, $rule, $data)
1050
    {
1051
        return Container::get('hook')->exec($rule, $data);
1052
    }
1053
1054
    /**
1055
     * 使用filter_var方式验证
1056
     * @access public
1057
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1058
     * @param  mixed     $rule  验证规则
1059
     * @return bool
1060
     */
1061
    public function filter($value, $rule)
1062
    {
1063
        if (is_string($rule) && strpos($rule, ',')) {
1064
            list($rule, $param) = explode(',', $rule);
1065
        } elseif (is_array($rule)) {
1066
            $param = isset($rule[1]) ? $rule[1] : null;
1067
            $rule  = $rule[0];
1068
        } else {
1069
            $param = null;
1070
        }
1071
1072
        return false !== filter_var($value, is_int($rule) ? $rule : filter_id($rule), $param);
1073
    }
1074
1075
    /**
1076
     * 验证某个字段等于某个值的时候必须
1077
     * @access public
1078
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1079
     * @param  mixed     $rule  验证规则
1080
     * @param  array     $data  数据
1081
     * @return bool
1082
     */
1083
    public function requireIf($value, $rule, $data)
1084
    {
1085
        list($field, $val) = explode(',', $rule);
1086
1087
        if ($this->getDataValue($data, $field) == $val) {
1088
            return !empty($value) || '0' == $value;
1089
        }
1090
1091
        return true;
1092
    }
1093
1094
    /**
1095
     * 通过回调方法验证某个字段是否必须
1096
     * @access public
1097
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1098
     * @param  mixed     $rule  验证规则
1099
     * @param  array     $data  数据
1100
     * @return bool
1101
     */
1102
    public function requireCallback($value, $rule, $data)
1103
    {
1104
        $result = call_user_func_array([$this, $rule], [$value, $data]);
1105
1106
        if ($result) {
1107
            return !empty($value) || '0' == $value;
1108
        }
1109
1110
        return true;
1111
    }
1112
1113
    /**
1114
     * 验证某个字段有值的情况下必须
1115
     * @access public
1116
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1117
     * @param  mixed     $rule  验证规则
1118
     * @param  array     $data  数据
1119
     * @return bool
1120
     */
1121
    public function requireWith($value, $rule, $data)
1122
    {
1123
        $val = $this->getDataValue($data, $rule);
1124
1125
        if (!empty($val)) {
1126
            return !empty($value) || '0' == $value;
1127
        }
1128
1129
        return true;
1130
    }
1131
1132
    /**
1133
     * 验证是否在范围内
1134
     * @access public
1135
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1136
     * @param  mixed     $rule  验证规则
1137
     * @return bool
1138
     */
1139
    public function in($value, $rule)
1140
    {
1141
        return in_array($value, is_array($rule) ? $rule : explode(',', $rule));
1142
    }
1143
1144
    /**
1145
     * 验证是否不在某个范围
1146
     * @access public
1147
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1148
     * @param  mixed     $rule  验证规则
1149
     * @return bool
1150
     */
1151
    public function notIn($value, $rule)
1152
    {
1153
        return !in_array($value, is_array($rule) ? $rule : explode(',', $rule));
1154
    }
1155
1156
    /**
1157
     * between验证数据
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
1158
     * @access public
1159
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1160
     * @param  mixed     $rule  验证规则
1161
     * @return bool
1162
     */
1163
    public function between($value, $rule)
1164
    {
1165
        if (is_string($rule)) {
1166
            $rule = explode(',', $rule);
1167
        }
1168
        list($min, $max) = $rule;
1169
1170
        return $value >= $min && $value <= $max;
1171
    }
1172
1173
    /**
1174
     * 使用notbetween验证数据
1175
     * @access public
1176
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1177
     * @param  mixed     $rule  验证规则
1178
     * @return bool
1179
     */
1180
    public function notBetween($value, $rule)
1181
    {
1182
        if (is_string($rule)) {
1183
            $rule = explode(',', $rule);
1184
        }
1185
        list($min, $max) = $rule;
1186
1187
        return $value < $min || $value > $max;
1188
    }
1189
1190
    /**
1191
     * 验证数据长度
1192
     * @access public
1193
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1194
     * @param  mixed     $rule  验证规则
1195
     * @return bool
1196
     */
1197
    public function length($value, $rule)
1198
    {
1199
        if (is_array($value)) {
1200
            $length = count($value);
1201
        } elseif ($value instanceof File) {
1202
            $length = $value->getSize();
1203
        } else {
1204
            $length = mb_strlen((string) $value);
1205
        }
1206
1207
        if (strpos($rule, ',')) {
1208
            // 长度区间
1209
            list($min, $max) = explode(',', $rule);
1210
            return $length >= $min && $length <= $max;
1211
        }
1212
1213
        // 指定长度
1214
        return $length == $rule;
1215
    }
1216
1217
    /**
1218
     * 验证数据最大长度
1219
     * @access public
1220
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1221
     * @param  mixed     $rule  验证规则
1222
     * @return bool
1223
     */
1224
    public function max($value, $rule)
1225
    {
1226
        if (is_array($value)) {
1227
            $length = count($value);
1228
        } elseif ($value instanceof File) {
1229
            $length = $value->getSize();
1230
        } else {
1231
            $length = mb_strlen((string) $value);
1232
        }
1233
1234
        return $length <= $rule;
1235
    }
1236
1237
    /**
1238
     * 验证数据最小长度
1239
     * @access public
1240
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1241
     * @param  mixed     $rule  验证规则
1242
     * @return bool
1243
     */
1244
    public function min($value, $rule)
1245
    {
1246
        if (is_array($value)) {
1247
            $length = count($value);
1248
        } elseif ($value instanceof File) {
1249
            $length = $value->getSize();
1250
        } else {
1251
            $length = mb_strlen((string) $value);
1252
        }
1253
1254
        return $length >= $rule;
1255
    }
1256
1257
    /**
1258
     * 验证日期
1259
     * @access public
1260
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1261
     * @param  mixed     $rule  验证规则
1262
     * @param  array     $data  数据
1263
     * @return bool
1264
     */
1265
    public function after($value, $rule, $data)
1266
    {
1267
        return strtotime($value) >= strtotime($rule);
1268
    }
1269
1270
    /**
1271
     * 验证日期
1272
     * @access public
1273
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1274
     * @param  mixed     $rule  验证规则
1275
     * @param  array     $data  数据
1276
     * @return bool
1277
     */
1278
    public function before($value, $rule, $data)
1279
    {
1280
        return strtotime($value) <= strtotime($rule);
1281
    }
1282
1283
    /**
1284
     * 验证日期字段
1285
     * @access protected
1286
     * @param mixed     $value  字段值
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1287
     * @param mixed     $rule  验证规则
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
1288
     * @param array     $data  数据
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
1289
     * @return bool
1290
     */
1291
    protected function afterWith($value, $rule, $data)
1292
    {
1293
        $rule = $this->getDataValue($data, $rule);
1294
        return !is_null($rule) && strtotime($value) >= strtotime($rule);
1295
    }
1296
1297
    /**
1298
     * 验证日期字段
1299
     * @access protected
1300
     * @param mixed     $value  字段值
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1301
     * @param mixed     $rule  验证规则
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
1302
     * @param array     $data  数据
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
1303
     * @return bool
1304
     */
1305
    protected function beforeWith($value, $rule, $data)
1306
    {
1307
        $rule = $this->getDataValue($data, $rule);
1308
        return !is_null($rule) && strtotime($value) <= strtotime($rule);
1309
    }
1310
1311
    /**
1312
     * 验证有效期
1313
     * @access public
1314
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1315
     * @param  mixed     $rule  验证规则
1316
     * @return bool
1317
     */
1318
    public function expire($value, $rule)
1319
    {
1320
        if (is_string($rule)) {
1321
            $rule = explode(',', $rule);
1322
        }
1323
1324
        list($start, $end) = $rule;
1325
1326
        if (!is_numeric($start)) {
1327
            $start = strtotime($start);
1328
        }
1329
1330
        if (!is_numeric($end)) {
1331
            $end = strtotime($end);
1332
        }
1333
1334
        return $_SERVER['REQUEST_TIME'] >= $start && $_SERVER['REQUEST_TIME'] <= $end;
1335
    }
1336
1337
    /**
1338
     * 验证IP许可
1339
     * @access public
1340
     * @param  string    $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1341
     * @param  mixed     $rule  验证规则
1342
     * @return mixed
1343
     */
1344
    public function allowIp($value, $rule)
1345
    {
1346
        return in_array($value, is_array($rule) ? $rule : explode(',', $rule));
1347
    }
1348
1349
    /**
1350
     * 验证IP禁用
1351
     * @access public
1352
     * @param  string    $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1353
     * @param  mixed     $rule  验证规则
1354
     * @return mixed
1355
     */
1356
    public function denyIp($value, $rule)
1357
    {
1358
        return !in_array($value, is_array($rule) ? $rule : explode(',', $rule));
1359
    }
1360
1361
    /**
1362
     * 使用正则验证数据
1363
     * @access public
1364
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1365
     * @param  mixed     $rule  验证规则 正则规则或者预定义正则名
1366
     * @return bool
1367
     */
1368
    public function regex($value, $rule)
1369
    {
1370
        if (isset($this->regex[$rule])) {
1371
            $rule = $this->regex[$rule];
1372
        } elseif (isset($this->defaultRegex[$rule])) {
1373
            $rule = $this->defaultRegex[$rule];
1374
        }
1375
1376
        if (0 !== strpos($rule, '/') && !preg_match('/\/[imsU]{0,4}$/', $rule)) {
1377
            // 不是正则表达式则两端补上/
1378
            $rule = '/^' . $rule . '$/';
1379
        }
1380
1381
        return is_scalar($value) && 1 === preg_match($rule, (string) $value);
1382
    }
1383
1384
    /**
1385
     * 验证表单令牌
1386
     * @access public
1387
     * @param  mixed     $value  字段值
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1388
     * @param  mixed     $rule  验证规则
1389
     * @param  array     $data  数据
1390
     * @return bool
1391
     */
1392
    public function token($value, $rule, $data)
1393
    {
1394
        $rule    = !empty($rule) ? $rule : '__token__';
1395
        $session = Container::get('session');
1396
1397
        if (!isset($data[$rule]) || !$session->has($rule)) {
1398
            // 令牌数据无效
1399
            return false;
1400
        }
1401
1402
        // 令牌验证
1403
        if (isset($data[$rule]) && $session->get($rule) === $data[$rule]) {
1404
            // 防止重复提交
1405
            $session->delete($rule); // 验证完成销毁session
1406
            return true;
1407
        }
1408
1409
        // 开启TOKEN重置
1410
        $session->delete($rule);
1411
1412
        return false;
1413
    }
1414
1415
    // 获取错误信息
1416
    public function getError()
0 ignored issues
show
Coding Style introduced by
You must use "/**" style comments for a function comment
Loading history...
1417
    {
1418
        return $this->error;
1419
    }
1420
1421
    /**
1422
     * 获取数据值
1423
     * @access protected
1424
     * @param  array     $data  数据
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1425
     * @param  string    $key  数据标识 支持多维
1426
     * @return mixed
1427
     */
1428
    protected function getDataValue($data, $key)
1429
    {
1430
        if (is_numeric($key)) {
1431
            $value = $key;
1432
        } elseif (strpos($key, '.')) {
1433
            // 支持多维数组验证
1434
            foreach (explode('.', $key) as $key) {
0 ignored issues
show
introduced by
$key is overwriting one of the parameters of this function.
Loading history...
1435
                if (!isset($data[$key])) {
1436
                    $value = null;
1437
                    break;
1438
                }
1439
                $value = $data = $data[$key];
1440
            }
1441
        } else {
1442
            $value = isset($data[$key]) ? $data[$key] : null;
1443
        }
1444
1445
        return $value;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $value does not seem to be defined for all execution paths leading up to this point.
Loading history...
1446
    }
1447
1448
    /**
1449
     * 获取验证规则的错误提示信息
1450
     * @access protected
1451
     * @param  string    $attribute  字段英文名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1452
     * @param  string    $title  字段描述名
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 2 found
Loading history...
1453
     * @param  string    $type  验证规则名称
0 ignored issues
show
Coding Style introduced by
Expected 6 spaces after parameter name; 2 found
Loading history...
1454
     * @param  mixed     $rule  验证规则数据
0 ignored issues
show
Coding Style introduced by
Expected 6 spaces after parameter name; 2 found
Loading history...
1455
     * @return string
1456
     */
1457
    protected function getRuleMsg($attribute, $title, $type, $rule)
1458
    {
1459
        $lang = Container::get('lang');
1460
1461
        if (isset($this->message[$attribute . '.' . $type])) {
1462
            $msg = $this->message[$attribute . '.' . $type];
1463
        } elseif (isset($this->message[$attribute][$type])) {
1464
            $msg = $this->message[$attribute][$type];
1465
        } elseif (isset($this->message[$attribute])) {
1466
            $msg = $this->message[$attribute];
1467
        } elseif (isset(self::$typeMsg[$type])) {
1468
            $msg = self::$typeMsg[$type];
1469
        } elseif (0 === strpos($type, 'require')) {
1470
            $msg = self::$typeMsg['require'];
1471
        } else {
1472
            $msg = $title . $lang->get('not conform to the rules');
1473
        }
1474
1475
        if (!is_string($msg)) {
1476
            return $msg;
1477
        }
1478
1479
        if (0 === strpos($msg, '{%')) {
1480
            $msg = $lang->get(substr($msg, 2, -1));
1481
        } elseif ($lang->has($msg)) {
1482
            $msg = $lang->get($msg);
1483
        }
1484
1485
        if (is_scalar($rule) && false !== strpos($msg, ':')) {
1486
            // 变量替换
1487
            if (is_string($rule) && strpos($rule, ',')) {
1488
                $array = array_pad(explode(',', $rule), 3, '');
1489
            } else {
1490
                $array = array_pad([], 3, '');
1491
            }
1492
            $msg = str_replace(
1493
                [':attribute', ':1', ':2', ':3'],
1494
                [$title, $array[0], $array[1], $array[2]],
1495
                $msg);
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 12 spaces, but found 16.
Loading history...
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
1496
            if (strpos($msg, ':rule')) {
1497
                $msg = str_replace(':rule', (string) $rule, $msg);
1498
            }
1499
        }
1500
1501
        return $msg;
1502
    }
1503
1504
    /**
1505
     * 获取数据验证的场景
1506
     * @access protected
1507
     * @param  string $scene  验证场景
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1508
     * @return void
1509
     */
1510
    protected function getScene($scene = '')
1511
    {
1512
        if (empty($scene)) {
1513
            // 读取指定场景
1514
            $scene = $this->currentScene;
1515
        }
1516
1517
        if (empty($scene)) {
1518
            return;
1519
        }
1520
1521
        $this->only = $this->append = $this->remove = [];
1522
1523
        if (method_exists($this, 'scene' . $scene)) {
0 ignored issues
show
Bug introduced by
Are you sure $scene of type array|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

1523
        if (method_exists($this, 'scene' . /** @scrutinizer ignore-type */ $scene)) {
Loading history...
1524
            call_user_func([$this, 'scene' . $scene]);
1525
        } elseif (isset($this->scene[$scene])) {
1526
            // 如果设置了验证适用场景
1527
            $scene = $this->scene[$scene];
1528
1529
            if (is_string($scene)) {
1530
                $scene = explode(',', $scene);
1531
            }
1532
1533
            $this->only = $scene;
1534
        }
1535
    }
1536
1537
    /**
1538
     * 动态方法 直接调用is方法进行验证
1539
     * @access public
1540
     * @param  string $method  方法名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1541
     * @param  array $args  调用参数
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 2 found
Loading history...
1542
     * @return bool
1543
     */
1544
    public function __call($method, $args)
1545
    {
1546
        if ('is' == strtolower(substr($method, 0, 2))) {
1547
            $method = substr($method, 2);
1548
        }
1549
1550
        array_push($args, lcfirst($method));
1551
1552
        return call_user_func_array([$this, 'is'], $args);
1553
    }
1554
    
1555
    /**
1556
     * 获取当前的验证规则
1557
     * @access protected
1558
     * @return array
1559
     */
1560
    protected function getRules(){
0 ignored issues
show
Coding Style introduced by
Opening brace should be on a new line
Loading history...
1561
        return $this->rule;
1562
    }
1563
}
1564