├── .gitignore
├── .scrutinizer.yml
├── .travis.yml
├── CHANGELOG.md
├── README.md
├── composer.json
├── phpunit.xml
├── src
├── Concerns
│ ├── MessagesAttributes.php
│ └── ValidatesAttributes.php
├── Exceptions
│ └── ValidationException.php
├── Validator.php
└── messages
│ └── en.php
└── tests
└── ValidatorTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | vendor
3 | composer.lock
4 | .buildpath
5 | .settings
6 | .project
7 | bin
8 | /nbproject/*
9 | *.iml
10 | .idea
11 | .php_cs.cache
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | filter:
2 | paths:
3 | - 'src/*'
4 | excluded_paths:
5 | - 'tests/*'
6 | dependency_paths:
7 | - 'vendor/'
8 |
9 |
10 | build:
11 | environment:
12 | php:
13 | version: '7.1'
14 |
15 | checks:
16 | php:
17 | remove_extra_empty_lines: true
18 | remove_php_closing_tag: true
19 | remove_trailing_whitespace: true
20 | fix_use_statements:
21 | remove_unused: true
22 | preserve_multiple: false
23 | preserve_blanklines: true
24 | order_alphabetically: true
25 | fix_php_opening_tag: true
26 | fix_linefeed: true
27 | fix_line_ending: true
28 | fix_identation_4spaces: true
29 | fix_doc_comments: true
30 |
31 | tools:
32 | external_code_coverage:
33 | timeout: 600
34 | runs: 1
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - '7.1'
5 | - '7.2'
6 |
7 |
8 |
9 | install: composer install
10 |
11 | script: vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover
12 |
13 | after_script:
14 | - wget https://scrutinizer-ci.com/ocular.phar
15 | - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog For runner/validator
2 |
3 | ## [1.0.0] - 2018-12-25
4 |
5 | ### Added
6 | - 增加可引入自定义语言包
7 | - 增加自定义错误消息
8 |
9 | ### Changed
10 | - 拆分 validate 及消息处理为 trait
11 | - extend 的 callback 类作用域取消绑定到 Validator 示例. validate 函数参数增加传入 Validator 实例
12 | - validate 从 protected 改为 publish
13 |
14 | ## [v1.0.1] - 2019-03-04
15 | ### Added
16 | - 增加支持通过魔术方法调用扩展规则
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
Validator
2 |
3 | Lightweight Validation Like Laravel
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ## 使用
16 | ```php
17 | 'https://github.com/RunnerLee',
31 | ];
32 | $rule = [
33 | 'blog' => 'required|url',
34 | ];
35 | $validator = new Validator($data, $rule);
36 |
37 | var_dump($validator->validate()); // output: true
38 |
39 | // 获取错误消息
40 | $validator->messages();
41 | ```
42 |
43 | ## 内置验证规则
44 | * `accept`:字段的取值范围必须是:yes、on、'1'、1、true 中的一个
45 | * `numeric`:字段的值必须是数字(包括整形和浮点数)
46 | * `integer`:字段的值必须是整形
47 | * `float`:字段的值必须是浮点型
48 | * `size`:字段的值必须为指定长度
49 | * `url`:字段的值必须是合法的 url 类型
50 | * `boolean`:字段的值必须是布尔类型
51 | * `confirm`:字段的值必须与指定值相等
52 | * `date`:字段的值必须是一个合法的日期
53 | * `email`:字段的值必须是一个合法的 email
54 | * `required`:必须包含该字段
55 | * `requiredWith`:如果指定的字段中的任意一个有值且不为空,则此字段为必填
56 | * `requiredWithout`:如果缺少任意一个指定的字段,则此字段为必填
57 | * `requiredIf`:如果指定的其它字段(anotherfield)等于任何一个 value 时,此字段为必填
58 | * `array`:字段的值必须是数组类型
59 | * `string`:字段的值必须是字符串类型
60 | * `min`:字段的值必须大于等于指定值
61 | * `max`:字段的值必须小于等于指定值
62 | * `range`:字段的值长度必须指定范围内,包含 min 和 max。
63 | * `regex`:字段的值必须匹配指定的正则表达式
64 | * `in`:字段的值必须在指定的数组内
65 | * `ip`:字段的值必须是一个合法的 ip
66 | * `dateFormat`:字段的值必须是一个合法的 date format 格式。参考:http://php.net/manual/en/datetime.createfromformat.php
67 | * `dateBefore`:字段的值必须小于给定时间。给定时间值非时间戳格式,而是 date/time 字符串,如:10 September 2000
68 | * `dateAfter`:字段的值必须大于给定时间。时间值格式同上。
69 | * `json`:字段的值必须是一个合法的 JSON 格式
70 |
71 | ## Note
72 |
73 | #### 关于空字符串
74 | 如果传入一个数组:
75 |
76 | ```php
77 | $data = [
78 | 'foo' => '',
79 | ];
80 | ```
81 |
82 | 同时规则设置为:
83 | ```php
84 | $rules= [
85 | 'foo' => 'string',
86 | ];
87 | ```
88 |
89 | 此时校验结果会是通过的. 也就是说 `validator` 不会把 `''` 当作 `null` 处理.
90 |
91 |
92 | ## 参考
93 | [https://github.com/vlucas/valitron](https://github.com/vlucas/valitron)
94 |
95 | [https://github.com/illuminate/validation](https://github.com/illuminate/validation)
96 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "runner/validator",
3 | "license": "MIT",
4 | "description": "",
5 | "authors": [
6 | {
7 | "name": "runnerlee",
8 | "email": "runnerleer@gmail.com"
9 | }
10 | ],
11 | "require": {
12 | "php": ">=5.6",
13 | "ext-mbstring": "*"
14 | },
15 | "require-dev": {
16 | "phpunit/phpunit": "^5.0",
17 | "phpstan/phpstan": "^0.10.6"
18 | },
19 | "autoload": {
20 | "psr-4": {
21 | "Runner\\Validator\\": "src/"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ./tests/
16 |
17 |
18 |
19 |
20 | src
21 |
22 | src/Exceptions
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/Concerns/MessagesAttributes.php:
--------------------------------------------------------------------------------
1 | templates = require $file;
19 | $this->templates = array_merge($this->templates, self::$extensionTemplates);
20 |
21 | foreach ($customMessage as $rule => $template) {
22 | $this->templates[self::formatRuleName($rule)] = $template;
23 | }
24 | }
25 |
26 | /**
27 | * @param string $rule
28 | * @param string $field
29 | * @param array $parameters
30 | *
31 | * @return string
32 | */
33 | protected function buildMessage($rule, $field, array $parameters = [])
34 | {
35 | if (!isset($this->templates[$rule])) {
36 | return "{$field} field check failed";
37 | }
38 | array_unshift($parameters, "{$field} {$this->templates[$rule]}");
39 |
40 | try {
41 | return sprintf(...$parameters);
42 | } catch (Exception $e) {
43 | return "{$field} filed check failed";
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Concerns/ValidatesAttributes.php:
--------------------------------------------------------------------------------
1 | getSize($field, $value) === $size;
80 | }
81 |
82 | /**
83 | * @param $field
84 | * @param $value
85 | * @param array $parameters
86 | * @param Validator $validator
87 | *
88 | * @return bool
89 | */
90 | public function validateUrl($field, $value, array $parameters, Validator $validator)
91 | {
92 | return false !== filter_var($value, FILTER_VALIDATE_URL);
93 | }
94 |
95 | /**
96 | * @param $field
97 | * @param $value
98 | * @param array $parameters
99 | * @param Validator $validator
100 | *
101 | * @return bool
102 | */
103 | public function validateBoolean($field, $value, array $parameters, Validator $validator)
104 | {
105 | return in_array($value, [true, false, 0, 1, '0', '1'], true);
106 | }
107 |
108 | /**
109 | * @param $field
110 | * @param $value
111 | * @param array $parameters
112 | * @param Validator $validator
113 | *
114 | * @return bool
115 | */
116 | public function validateConfirm($field, $value, array $parameters, Validator $validator)
117 | {
118 | return $value === $this->data[$parameters[0]];
119 | }
120 |
121 | /**
122 | * @param $field
123 | * @param $value
124 | * @param array $parameters
125 | * @param Validator $validator
126 | *
127 | * @return bool
128 | */
129 | public function validateDate($field, $value, array $parameters, Validator $validator)
130 | {
131 | return false !== strtotime($value);
132 | }
133 |
134 | /**
135 | * 邮箱地址
136 | *
137 | * @param $field
138 | * @param $value
139 | * @param array $parameters
140 | * @param Validator $validator
141 | *
142 | * @return bool
143 | */
144 | public function validateEmail($field, $value, array $parameters, Validator $validator)
145 | {
146 | return false !== filter_var($value, FILTER_VALIDATE_EMAIL);
147 | }
148 |
149 | /**
150 | * @param $field
151 | * @param $value
152 | * @param array $parameters
153 | * @param Validator $validator
154 | *
155 | * @return bool
156 | */
157 | public function validateRequired($field, $value, array $parameters, Validator $validator)
158 | {
159 | return !is_null($value);
160 | }
161 |
162 | /**
163 | * @param $field
164 | * @param $value
165 | * @param array $parameters
166 | * @param Validator $validator
167 | *
168 | * @return bool
169 | */
170 | public function validateRequiredWith($field, $value, array $parameters, Validator $validator)
171 | {
172 | return !is_null($value) || !array_key_exists($parameters[0], $this->data);
173 | }
174 |
175 | /**
176 | * @param $field
177 | * @param $value
178 | * @param array $parameters
179 | * @param Validator $validator
180 | *
181 | * @return bool
182 | */
183 | public function validateRequiredWithout($field, $value, array $parameters, Validator $validator)
184 | {
185 | return !is_null($value) || array_key_exists($parameters[0], $this->data);
186 | }
187 |
188 | /**
189 | * @param $field
190 | * @param $value
191 | * @param array $parameters
192 | * @param Validator $validator
193 | *
194 | * @return bool
195 | */
196 | public function validateRequiredIf($field, $value, array $parameters, Validator $validator)
197 | {
198 | $otherField = array_shift($parameters);
199 |
200 | return !is_null($value) || (
201 | !array_key_exists($otherField, $this->data) || false === array_search($this->data[$otherField], $parameters)
202 | );
203 | }
204 |
205 | /**
206 | * @param $field
207 | * @param $value
208 | * @param array $parameters
209 | * @param Validator $validator
210 | *
211 | * @return bool
212 | */
213 | public function validateRequiredUnless($field, $value, array $parameters, Validator $validator)
214 | {
215 | $otherField = array_shift($parameters);
216 |
217 | return !is_null($value) || (
218 | !array_key_exists($otherField, $this->data) || false !== array_search($this->data[$otherField], $parameters)
219 | );
220 | }
221 |
222 | /**
223 | * @param $field
224 | * @param $value
225 | * @param array $parameters
226 | *
227 | * @return bool
228 | */
229 | public function validateArray($field, $value, array $parameters, Validator $validator)
230 | {
231 | return is_array($value);
232 | }
233 |
234 | /**
235 | * @param $field
236 | * @param $value
237 | * @param array $parameters
238 | * @param Validator $validator
239 | *
240 | * @return bool
241 | */
242 | public function validateString($field, $value, array $parameters, Validator $validator)
243 | {
244 | return is_string($value);
245 | }
246 |
247 | /**
248 | * @param $field
249 | * @param $value
250 | * @param array $parameters
251 | * @param Validator $validator
252 | *
253 | * @return bool
254 | */
255 | public function validateNullable($field, $value, array $parameters, Validator $validator)
256 | {
257 | return true;
258 | }
259 |
260 | /**
261 | * @param $field
262 | * @param $value
263 | * @param array $parameters
264 | * @param Validator $validator
265 | *
266 | * @return bool
267 | */
268 | public function validateMin($field, $value, array $parameters, Validator $validator)
269 | {
270 | return $this->getSize($field, $value) >= $parameters[0];
271 | }
272 |
273 | /**
274 | * @param $field
275 | * @param $value
276 | * @param array $parameters
277 | * @param Validator $validator
278 | *
279 | * @return bool
280 | */
281 | public function validateMax($field, $value, array $parameters, Validator $validator)
282 | {
283 | return $this->getSize($field, $value) <= $parameters[0];
284 | }
285 |
286 | /**
287 | * @param $field
288 | * @param $value
289 | * @param array $parameters
290 | * @param Validator $validator
291 | *
292 | * @return bool
293 | */
294 | public function validateRange($field, $value, array $parameters, Validator $validator)
295 | {
296 | $size = $this->getSize($field, $value);
297 | if (!isset($parameters[0])) {
298 | return false;
299 | }
300 | if (isset($parameters[1])) {
301 | if ('' === $parameters[0]) {
302 | if ('' === $parameters[1]) {
303 | return false;
304 | }
305 |
306 | return $size <= $parameters[1];
307 | }
308 | if ('' === $parameters[1]) {
309 | return $size >= $parameters[0];
310 | }
311 |
312 | return $size >= $parameters[0] && $size <= $parameters[1];
313 | }
314 |
315 | return '' === $parameters[0] ? false : ($size >= $parameters[0]);
316 | }
317 |
318 | /**
319 | * @param $field
320 | * @param $value
321 | * @param array $parameters
322 | * @param Validator $validator
323 | *
324 | * @return bool
325 | */
326 | public function validateRegex($field, $value, array $parameters, Validator $validator)
327 | {
328 | return (bool) preg_match($parameters[0], $value);
329 | }
330 |
331 | /**
332 | * @param $field
333 | * @param $value
334 | * @param array $parameters
335 | * @param Validator $validator
336 | *
337 | * @return bool
338 | */
339 | public function validateIn($field, $value, array $parameters, Validator $validator)
340 | {
341 | return in_array($value, $parameters, true);
342 | }
343 |
344 | /**
345 | * @param $field
346 | * @param $value
347 | * @param array $parameters
348 | * @param Validator $validator
349 | *
350 | * @return bool
351 | */
352 | public function validateIp($field, $value, array $parameters, Validator $validator)
353 | {
354 | return false !== filter_var($value, FILTER_VALIDATE_IP);
355 | }
356 |
357 | /**
358 | * @param $field
359 | * @param $value
360 | * @param array $parameters
361 | * @param Validator $validator
362 | *
363 | * @return bool
364 | */
365 | public function validateDateFormat($field, $value, array $parameters, Validator $validator)
366 | {
367 | return !(bool) date_parse_from_format($parameters[0], $value)['error_count'];
368 | }
369 |
370 | /**
371 | * @param $field
372 | * @param $value
373 | * @param array $parameters
374 | * @param Validator $validator
375 | *
376 | * @return bool
377 | */
378 | public function validateDateBefore($field, $value, array $parameters, Validator $validator)
379 | {
380 | return strtotime($value) < strtotime($parameters[0]);
381 | }
382 |
383 | /**
384 | * @param $field
385 | * @param $value
386 | * @param array $parameters
387 | * @param Validator $validator
388 | *
389 | * @return bool
390 | */
391 | public function validateDateAfter($field, $value, array $parameters, Validator $validator)
392 | {
393 | return strtotime($value) > strtotime($parameters[0]);
394 | }
395 |
396 | /**
397 | * @param $field
398 | * @param $value
399 | * @param array $parameters
400 | * @param Validator $validator
401 | *
402 | * @return bool
403 | */
404 | public function validateJson($field, $value, array $parameters, Validator $validator)
405 | {
406 | return is_array(json_decode($value, true));
407 | }
408 |
409 | /**
410 | * @param $field
411 | * @param $value
412 | * @param array $parameters
413 | * @param Validator $validator
414 | *
415 | * @return bool
416 | */
417 | public function validateDiff($field, $value, array $parameters, Validator $validator)
418 | {
419 | $specifyField = array_shift($parameters);
420 |
421 | return array_key_exists($specifyField, $this->data) && $value !== $this->data[$specifyField];
422 | }
423 |
424 | /**
425 | * @param $field
426 | * @param $value
427 | *
428 | * @return int|float
429 | */
430 | public function getSize($field, $value)
431 | {
432 | switch (true) {
433 | case isset($this->ruleGroups[$field]['String']) && is_string($value):
434 | return strlen($value);
435 | case is_array($value):
436 | return count($value);
437 | case false !== $temp = filter_var($value, FILTER_VALIDATE_INT):
438 | return $temp;
439 | case false !== $temp = filter_var($value, FILTER_VALIDATE_FLOAT):
440 | return $temp;
441 | default:
442 | return mb_strlen($value);
443 | }
444 | }
445 | }
446 |
--------------------------------------------------------------------------------
/src/Exceptions/ValidationException.php:
--------------------------------------------------------------------------------
1 | data = $data;
62 | $this->parseRules($rules);
63 | $this->loadMessageTemplate($file, $customMessages);
64 | }
65 |
66 | /**
67 | * @param $name
68 | * @param $callback
69 | * @param bool $isForce
70 | * @param string $message
71 | */
72 | public static function addExtension($name, $callback, $isForce = false, $message = null)
73 | {
74 | $name = self::formatRuleName($name);
75 |
76 | self::$extensions[$name] = $callback;
77 |
78 | $isForce && self::$forceRules[] = $name;
79 |
80 | !empty($message) && (static::$extensionTemplates[$name] = $message);
81 | }
82 |
83 | /**
84 | * @return bool
85 | */
86 | public function validate()
87 | {
88 | foreach ($this->ruleGroups as $field => $rules) {
89 | if ($this->hasField($field)) {
90 | $value = $this->getField($field);
91 | foreach ($rules as $rule => $parameters) {
92 | if (!$this->runValidateRule($rule, $field, $value, $parameters)) {
93 | $this->messages[$field][$rule] = $this->buildMessage($rule, $field, $parameters);
94 | }
95 | }
96 | } elseif ($forceRules = array_intersect(self::$forceRules, array_keys($rules))) {
97 | foreach ($forceRules as $rule) {
98 | if (!$this->runValidateRule($rule, $field, null, $rules[$rule])) {
99 | $this->messages[$field][$rule] = $this->buildMessage($rule, $field, $rules[$rule]);
100 | }
101 | }
102 | }
103 | }
104 |
105 | return 0 === count($this->messages);
106 | }
107 |
108 | /**
109 | * @return array
110 | */
111 | public function fails()
112 | {
113 | return array_keys($this->messages);
114 | }
115 |
116 | /**
117 | * @return array
118 | */
119 | public function messages()
120 | {
121 | return $this->messages;
122 | }
123 |
124 | /**
125 | * @return array
126 | */
127 | public function data()
128 | {
129 | return $this->data;
130 | }
131 |
132 | /**
133 | * @param array $ruleGroups
134 | */
135 | protected function parseRules(array $ruleGroups)
136 | {
137 | $map = [];
138 | foreach ($ruleGroups as $field => $rules) {
139 | foreach (explode('|', $rules) as $rule) {
140 | list($rule, $parameters) = explode(':', (false === strpos($rule, ':') ? ($rule.':') : $rule), 2);
141 | !isset($map[$rule]) && $map[$rule] = self::formatRuleName($rule);
142 | $rule = $map[$rule];
143 | $this->ruleGroups[$field][$rule] = ('' === $parameters ? [] : explode(',', $parameters));
144 | }
145 | }
146 | }
147 |
148 | /**
149 | * @param $name
150 | *
151 | * @return string
152 | */
153 | protected static function formatRuleName($name)
154 | {
155 | return implode(
156 | '',
157 | array_map(
158 | function ($value) {
159 | return ucfirst($value);
160 | },
161 | explode('_', $name)
162 | )
163 | );
164 | }
165 |
166 | /**
167 | * @param string $field
168 | *
169 | * @return bool
170 | */
171 | protected function hasField($field)
172 | {
173 | $field = explode('.', $field);
174 | $item = array_shift($field);
175 | if (!array_key_exists($item, $this->data)) {
176 | return false;
177 | }
178 | $value = $this->data[$item];
179 |
180 | foreach ($field as $item) {
181 | if (!array_key_exists($item, $value)) {
182 | return false;
183 | }
184 | $value = $value[$item];
185 | }
186 |
187 | return true;
188 | }
189 |
190 | /**
191 | * @param string $field
192 | *
193 | * @return mixed
194 | */
195 | protected function getField($field)
196 | {
197 | $field = explode('.', $field);
198 | $item = array_shift($field);
199 | $value = $this->data[$item];
200 | foreach ($field as $item) {
201 | $value = $value[$item];
202 | }
203 |
204 | return $value;
205 | }
206 |
207 | /**
208 | * @param $field
209 | * @param $value
210 | * @param $rule
211 | * @param array $parameters
212 | *
213 | * @return bool
214 | */
215 | protected function runValidateRule($rule, $field, $value, array $parameters = [])
216 | {
217 | $callback = array_key_exists($rule, self::$extensions) ? self::$extensions[$rule] : [$this, "validate{$rule}"];
218 |
219 | return (bool) call_user_func($callback, $field, $value, $parameters, $this);
220 | }
221 |
222 | public function __call($method, $arguments)
223 | {
224 | $rule = self::formatRuleName(substr($method, 8));
225 |
226 | if (!isset(self::$extensions[$rule])) {
227 | throw new BadMethodCallException(sprintf('Method %s::%s does not exists', static::class, $method));
228 | }
229 |
230 | return $this->runValidateRule($rule, ...$arguments);
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/src/messages/en.php:
--------------------------------------------------------------------------------
1 | 'is required',
10 | 'Accepted' => 'must be accepted',
11 | 'Numeric' => 'must be numeric',
12 | 'Integer' => 'must be an integer',
13 | 'Float' => 'must be a float',
14 | 'Size' => "'s size must be %s",
15 | 'Min' => 'must be at least %d',
16 | 'Max' => 'must be no more than %d',
17 | 'In' => 'contains invalid value',
18 | 'Ip' => 'is not a valid IP address',
19 | 'Email' => 'is not a valid email address',
20 | 'Url' => 'is not a valid URL',
21 | 'Regex' => 'contains invalid characters',
22 | 'Date' => 'is not a valid date',
23 | 'DateFormat' => "must be date with format '%s'",
24 | 'Boolean' => 'must be a boolean',
25 | 'Range' => 'must be between %d and %d characters',
26 | 'Confirm' => 'must be same as %s field',
27 | 'Array' => 'must be an array',
28 | 'String' => 'must be a string',
29 | 'Json' => 'must be a json string',
30 | ];
31 |
--------------------------------------------------------------------------------
/tests/ValidatorTest.php:
--------------------------------------------------------------------------------
1 | assertArrayHasKey($field, $validator->data());
15 |
16 | return false !== array_search($value, ['google', 'bing']);
17 | });
18 |
19 | $validator = new Validator($this->getData(), $this->getRules());
20 |
21 | $this->assertSame(true, $validator->validate());
22 | $this->assertSame($this->getData(), $validator->data());
23 |
24 | $data = [
25 | 'range_a' => '1.4',
26 | 'range_b' => '1.4',
27 | 'channel_range' => 'baidu',
28 | ];
29 |
30 | $validator = new Validator(
31 | $data,
32 | [
33 | 'do_not_has_field' => 'required|size:1',
34 | 'range_a' => 'range',
35 | 'range_b' => 'range:,',
36 | 'channel_range' => 'channel_range',
37 | ]
38 | );
39 |
40 | $this->assertSame(false, $validator->validate());
41 | $this->assertSame($data, $validator->data());
42 | $this->assertSame([
43 | 'do_not_has_field',
44 | 'range_a',
45 | 'range_b',
46 | 'channel_range',
47 | ], $validator->fails());
48 | }
49 |
50 | public function testMessage()
51 | {
52 | $data = [
53 | 'data' => 'demo',
54 | ];
55 | $rules = [
56 | 'data' => 'size:3',
57 | ];
58 | $validator = new Validator($data, $rules);
59 |
60 | $this->assertSame(false, $validator->validate());
61 | $this->assertSame("data 's size must be 3", $validator->messages()['data']['Size']);
62 |
63 | Validator::addExtension(
64 | 'testing',
65 | function () {
66 | return false;
67 | },
68 | false,
69 | 'is testing'
70 | );
71 |
72 | $validator = new Validator(
73 | [
74 | 'a' => 'b',
75 | ],
76 | [
77 | 'a' => 'testing',
78 | ]
79 | );
80 |
81 | $this->assertSame(false, $validator->validate());
82 | $this->assertSame(
83 | [
84 | 'a' => [
85 | 'Testing' => 'a is testing',
86 | ],
87 | ],
88 | $validator->messages()
89 | );
90 | }
91 |
92 | public function testAddExtension()
93 | {
94 | Validator::addExtension('runner', function () {
95 | return true;
96 | });
97 |
98 | $data = [
99 | 'a' => 'string',
100 | ];
101 |
102 | $validator = new Validator($data, [
103 | 'a' => 'runner'
104 | ]);
105 |
106 | $this->assertSame(true, $validator->validate());
107 |
108 | $this->assertSame(true, $validator->validateRunner('a', 'a', []));
109 |
110 | $validator = new Validator($data, [
111 | 'a' => 'demo',
112 | ]);
113 |
114 | $this->expectException(BadMethodCallException::class);
115 | $validator->validate();
116 | }
117 |
118 | public function testReplaceMessage()
119 | {
120 | $validator = new Validator(
121 | [
122 | 'runnerlee' => 'hhh',
123 | ],
124 | [
125 | 'runnerlee' => 'integer',
126 | ],
127 | [
128 | 'integer' => 'is the most handsome man',
129 | ]
130 | );
131 | $validator->validate();
132 |
133 | $this->assertSame(
134 | [
135 | 'runnerlee' => [
136 | 'Integer' => 'runnerlee is the most handsome man',
137 | ],
138 | ],
139 | $validator->messages()
140 | );
141 | }
142 |
143 | protected function getRules()
144 | {
145 | return [
146 | 'data' => 'size:4',
147 | 'url' => 'url',
148 | 'array' => 'required|array|min:1',
149 | 'array.hello' => 'numeric',
150 | 'accept' => 'accept',
151 | 'integer' => 'integer',
152 | 'boolean' => 'boolean',
153 | 'string' => 'string',
154 | 'confirm' => 'confirm:string',
155 | 'date' => 'date',
156 | 'email' => 'email',
157 | 'numeric_string' => 'string|size:6',
158 | 'block_reason' => 'string|required_with:is_blocked',
159 | 'channel' => 'required|channel_range',
160 | 'diff_beta' => 'diff:diff_alpha',
161 | 'json' => 'json',
162 | 'ip' => 'ip',
163 | 'in' => 'in:a,b,c',
164 | 'float' => 'required_unless:channel,baidu|float|size:1.44|min:1.44|max:1.44',
165 | 'sub_arr.demo' => 'size:3',
166 | 'without_alpha' => 'required_without:without_beta|required_if:channel,google',
167 | 'nullable' => 'nullable',
168 | 'range_a' => 'range:1,1.5',
169 | 'range_b' => 'range:,1.5',
170 | 'range_c' => 'range:1,',
171 | 'range_g' => 'range:1',
172 | 'regex' => 'regex:#\w+#',
173 | 'date_format' => 'date_format:Y-m-d',
174 | 'date_before' => 'date_before:2018-01-02',
175 | 'date_after' => 'date_after:2017-12-31',
176 | ];
177 | }
178 |
179 | protected function getData()
180 | {
181 | return [
182 | 'data' => 'demo',
183 | 'url' => 'http://runnerlee.com',
184 | 'array' => [
185 | 'hello' => '1.1',
186 | ],
187 | 'accept' => 'on',
188 | 'integer' => '1',
189 | 'boolean' => 0,
190 | 'string' => 'hello world',
191 | 'confirm' => 'hello world',
192 | 'date' => '1995-09-06',
193 | 'email' => 'runnerleer@gmail.com',
194 | 'numeric_string' => '123456',
195 | 'is_blocked' => 'no',
196 | 'block_reason' => '123',
197 | 'channel' => 'google',
198 | 'diff_alpha' => 'hello',
199 | 'diff_beta' => 'world',
200 | 'json' => '{"a":"b"}',
201 | 'ip' => '127.0.0.1',
202 | 'in' => 'a',
203 | 'float' => '1.44',
204 | 'sub_arr' => [],
205 | 'without_alpha' => 'a',
206 | 'range_a' => '1.5',
207 | 'range_b' => '1.5',
208 | 'range_c' => '1.5',
209 | 'range_e' => '1.5',
210 | 'range_f' => '1.5',
211 | 'range_g' => '3',
212 | 'regex' => '123abc',
213 | 'date_format' => '2018-01-01',
214 | 'date_before' => '2018-01-01',
215 | 'date_after' => '2018-01-01',
216 | 'nullable' => null,
217 | ];
218 | }
219 | }
220 |
--------------------------------------------------------------------------------