Skip to content

Commit efcadb4

Browse files
authored
Fixed bug that exclude cannot not work when using validation. (#7427)
1 parent cc5e620 commit efcadb4

File tree

4 files changed

+106
-17
lines changed

4 files changed

+106
-17
lines changed

publish/en/validation.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@
5858
'email' => 'The :attribute must be a valid email address.',
5959
'ends_with' => 'The :attribute must end with one of the following: :values.',
6060
'enum' => 'The selected :attribute is invalid.',
61+
'exclude' => 'The :attribute field is excluded.',
62+
'exclude_if' => 'The :attribute field is excluded when :other is :value.',
63+
'exclude_unless' => 'The :attribute field is excluded unless :other is in :values.',
64+
'exclude_with' => 'The :attribute field is excluded when :values is present.',
65+
'exclude_without' => 'The :attribute field is excluded when :values is not present.',
6166
'exists' => 'The selected :attribute is invalid.',
6267
'extensions' => 'The :attribute must have one of the following extensions: :values.',
6368
'file' => 'The :attribute must be a file.',
@@ -133,11 +138,6 @@
133138
'required_with_all' => 'The :attribute field is required when :values is present.',
134139
'required_without' => 'The :attribute field is required when :values is not present.',
135140
'required_without_all' => 'The :attribute field is required when none of :values are present.',
136-
'exclude' => 'The :attribute field is excluded.',
137-
'exclude_if' => 'The :attribute field is excluded when :other is :value.',
138-
'exclude_unless' => 'The :attribute field is excluded unless :other is in :values.',
139-
'exclude_with' => 'The :attribute field is excluded when :values is present.',
140-
'exclude_without' => 'The :attribute field is excluded when :values is not present.',
141141
'same' => 'The :attribute and :other must match.',
142142
'size' => [
143143
'numeric' => 'The :attribute must be :size.',
@@ -172,6 +172,7 @@
172172
'string' => 'The :attribute must be between :min and :max characters when :other is :value.',
173173
'array' => 'The :attribute must have between :min and :max items when :other is :value.',
174174
],
175+
175176
/*
176177
|--------------------------------------------------------------------------
177178
| Custom Validation Language Lines

publish/zh_CN/validation.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@
4848
'dimensions' => ':attribute 具有无效的图片尺寸',
4949
'distinct' => ':attribute 字段具有重复值',
5050
'email' => ':attribute 必须是一个合法的电子邮件地址',
51+
'exclude' => ':attribute 字段是被排除的',
52+
'exclude_if' => '当 :other 为 :value 时,排除 :attribute 字段',
53+
'exclude_unless' => '除非 :other 是在 :values 中,否则排除 :attribute 字段',
54+
'exclude_with' => '当 :values 存在时,排除 :attribute 字段',
55+
'exclude_without' => '当 :values 不存在时,排除 :attribute 字段',
5156
'exists' => '选定的 :attribute 是无效的',
5257
'file' => ':attribute 必须是一个文件',
5358
'filled' => ':attribute 的字段是必填的',
@@ -111,11 +116,6 @@
111116
'required_with_all' => ':attribute 字段是必须的当 :values 是存在的',
112117
'required_without' => ':attribute 字段是必须的当 :values 是不存在的',
113118
'required_without_all' => ':attribute 字段是必须的当 没有一个 :values 是存在的',
114-
'exclude' => ':attribute 字段是被排除的',
115-
'exclude_if' => '当 :other 为 :value 时,排除 :attribute 字段',
116-
'exclude_unless' => '除非 :other 是在 :values 中,否则排除 :attribute 字段',
117-
'exclude_with' => '当 :values 存在时,排除 :attribute 字段',
118-
'exclude_without' => '当 :values 不存在时,排除 :attribute 字段',
119119
'same' => ':attribute 和 :other 必须匹配',
120120
'size' => [
121121
'numeric' => ':attribute 必须是 :size',
@@ -148,6 +148,7 @@
148148
'string' => '当 :other 为 :value 时 :attribute 必须介于 :min - :max 个字符之间',
149149
'array' => '当 :other 为 :value 时 :attribute 必须只有 :min - :max 个单元',
150150
],
151+
151152
/*
152153
|--------------------------------------------------------------------------
153154
| Custom Validation Language Lines

src/Validator.php

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,19 +136,21 @@ class Validator implements ValidatorContract
136136
* The validation rules that imply the field is required.
137137
*/
138138
protected array $implicitRules = [
139-
'Required', 'Filled', 'Missing', 'MissingIf', 'MissingUnless', 'MissingWith',
140-
'MissingWithAll', 'RequiredWith', 'RequiredWithAll', 'RequiredWithout', 'RequiredWithoutAll',
141-
'RequiredIf', 'RequiredUnless', 'Accepted', 'AcceptedIf', 'Declined', 'DeclinedIf', 'Present',
139+
'Accepted', 'AcceptedIf', 'Declined', 'DeclinedIf', 'Filled', 'Missing', 'MissingIf',
140+
'MissingUnless', 'MissingWith', 'MissingWithAll', 'Present', 'Required', 'RequiredIf',
141+
'RequiredUnless', 'RequiredWith', 'RequiredWithAll', 'RequiredWithout',
142+
'RequiredWithoutAll',
142143
];
143144

144145
/**
145146
* The validation rules which depend on other fields as parameters.
146147
*/
147148
protected array $dependentRules = [
148-
'AcceptedIf', 'DeclinedIf', 'RequiredWith', 'RequiredWithAll', 'RequiredWithout',
149-
'RequiredWithoutAll', 'RequiredIf', 'RequiredUnless', 'Confirmed', 'Same', 'Different',
150-
'Unique', 'Before', 'After', 'BeforeOrEqual', 'AfterOrEqual', 'Gt', 'Lt', 'Gte', 'Lte',
151-
'Prohibits', 'ExcludeIf', 'ExcludeUnless', 'ExcludeWith', 'ExcludeWithout', 'MissingIf', 'MissingUnless', 'MissingWith', 'MissingWithAll',
149+
'After', 'AfterOrEqual', 'AcceptedIf', 'Before', 'BeforeOrEqual', 'Confirmed',
150+
'DeclinedIf', 'Different', 'ExcludeIf', 'ExcludeUnless', 'ExcludeWith', 'ExcludeWithout',
151+
'Gt', 'Gte', 'Lt', 'Lte', 'MissingIf', 'MissingUnless', 'MissingWith', 'MissingWithAll',
152+
'Prohibits', 'RequiredIf', 'RequiredUnless', 'RequiredWith', 'RequiredWithAll', 'RequiredWithout',
153+
'RequiredWithoutAll', 'Same', 'Unique',
152154
];
153155

154156
/**
@@ -277,6 +279,12 @@ public function passes(): bool
277279
}
278280
}
279281

282+
foreach ($this->rules as $attribute => $rules) {
283+
if ($this->shouldBeExcluded($attribute)) {
284+
$this->removeAttribute($attribute);
285+
}
286+
}
287+
280288
// Here we will spin through all of the "after" hooks on this validator and
281289
// fire them off. This gives the callbacks a chance to perform all kinds
282290
// of other validation that needs to get wrapped up in this operation.
@@ -773,6 +781,15 @@ protected function shouldBeExcluded(string $attribute): bool
773781
return false;
774782
}
775783

784+
/**
785+
* Remove the given attribute.
786+
*/
787+
protected function removeAttribute(string $attribute): void
788+
{
789+
Arr::forget($this->data, $attribute);
790+
Arr::forget($this->rules, $attribute);
791+
}
792+
776793
/**
777794
* Add the given attribute to the list of excluded attributes.
778795
*/

tests/Cases/ValidationValidatorTest.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5509,55 +5509,101 @@ public function testValidateExclude()
55095509
$trans = $this->getIlluminateArrayTranslator();
55105510
$v = new Validator($trans, [], ['name' => 'exclude|required']);
55115511
$this->assertTrue($v->passes());
5512+
$this->assertSame([], $v->validated());
55125513

55135514
$v = new Validator($trans, ['name' => ''], ['name' => 'exclude|required']);
55145515
$this->assertTrue($v->passes());
5516+
$this->assertSame([], $v->validated());
55155517

55165518
$v = new Validator($trans, ['name' => 'foo'], ['name' => 'exclude|integer']);
55175519
$this->assertTrue($v->passes());
5520+
$this->assertSame([], $v->validated());
55185521

55195522
$file = new SplFileInfo('');
55205523
$v = new Validator($trans, ['name' => $file], ['name' => 'exclude|required']);
55215524
$this->assertTrue($v->passes());
5525+
$this->assertSame([], $v->validated());
55225526

55235527
$file = new SplFileInfo(__FILE__);
55245528
$v = new Validator($trans, ['name' => $file], ['name' => 'exclude|required']);
55255529
$this->assertTrue($v->passes());
5530+
$this->assertSame([], $v->validated());
55265531

55275532
$file = new SplFileInfo(__FILE__);
55285533
$file2 = new SplFileInfo(__FILE__);
55295534
$v = new Validator($trans, ['files' => [$file, $file2]], ['files.0' => 'exclude|required', 'files.1' => 'exclude|required']);
55305535
$this->assertTrue($v->passes());
5536+
$this->assertSame([], $v->validated());
55315537

55325538
$v = new Validator($trans, ['files' => [$file, $file2]], ['files' => 'exclude|required']);
55335539
$this->assertTrue($v->passes());
5540+
$this->assertSame([], $v->validated());
5541+
}
5542+
5543+
public function testExcludeBeforeADependentRule()
5544+
{
5545+
$validator = new Validator(
5546+
$this->getIlluminateArrayTranslator(),
5547+
[
5548+
'profile_id' => null,
5549+
'type' => 'denied',
5550+
],
5551+
[
5552+
'type' => ['required', 'string', 'exclude'],
5553+
'profile_id' => ['nullable', 'required_if:type,profile', 'integer'],
5554+
],
5555+
);
5556+
5557+
$this->assertTrue($validator->passes());
5558+
$this->assertSame(['profile_id' => null], $validator->validated());
5559+
5560+
$validator = new Validator(
5561+
$this->getIlluminateArrayTranslator(),
5562+
[
5563+
'profile_id' => null,
5564+
'type' => 'profile',
5565+
],
5566+
[
5567+
'type' => ['required', 'string', 'exclude'],
5568+
'profile_id' => ['nullable', 'required_if:type,profile', 'integer'],
5569+
],
5570+
);
5571+
5572+
$this->assertFalse($validator->passes());
5573+
$this->assertSame(['profile_id' => ['validation.required_if']], $validator->getMessageBag()->getMessages());
55345574
}
55355575

55365576
public function testValidateExcludeIf()
55375577
{
55385578
$trans = $this->getIlluminateArrayTranslator();
55395579
$v = new Validator($trans, ['first' => 'taylor'], ['last' => 'exclude_if:first,biz|required']);
55405580
$this->assertTrue($v->fails());
5581+
$this->assertSame(['last' => ['validation.required']], $v->messages()->toArray());
55415582

55425583
$trans = $this->getIlluminateArrayTranslator();
55435584
$v = new Validator($trans, ['first' => 'taylor', 'last' => 'otwell'], ['last' => 'exclude_if:first,taylor|integer']);
55445585
$this->assertTrue($v->passes());
5586+
$this->assertSame([], $v->validated());
55455587

55465588
$trans = $this->getIlluminateArrayTranslator();
55475589
$v = new Validator($trans, ['first' => 'taylor', 'last' => 'otwell'], ['last' => 'exclude_if:first,taylor,dayle|integer']);
55485590
$this->assertTrue($v->passes());
5591+
$this->assertSame([], $v->validated());
55495592

55505593
$trans = $this->getIlluminateArrayTranslator();
55515594
$v = new Validator($trans, ['first' => 'dayle', 'last' => 'rees'], ['last' => 'exclude_if:first,taylor,dayle|integer']);
55525595
$this->assertTrue($v->passes());
5596+
$this->assertSame([], $v->validated());
55535597

55545598
$trans = $this->getIlluminateArrayTranslator();
55555599
$v = new Validator($trans, ['foo' => true], ['bar' => 'exclude_if:foo,true|required']);
55565600
$this->assertTrue($v->passes());
5601+
$this->assertSame([], $v->validated());
55575602

55585603
$trans = $this->getIlluminateArrayTranslator();
55595604
$v = new Validator($trans, ['foo' => true], ['bar' => 'exclude_if:foo,false|required']);
55605605
$this->assertTrue($v->fails());
5606+
$this->assertSame(['bar' => ['validation.required']], $v->messages()->toArray());
55615607

55625608
// error message when passed multiple values (exclude_if:foo,bar,baz)
55635609
$trans = $this->getIlluminateArrayTranslator();
@@ -5572,22 +5618,27 @@ public function testValidateExcludeUnless()
55725618
$trans = $this->getIlluminateArrayTranslator();
55735619
$v = new Validator($trans, ['first' => 'sven'], ['last' => 'exclude_unless:first,taylor|required']);
55745620
$this->assertTrue($v->passes());
5621+
$this->assertSame([], $v->validated());
55755622

55765623
$trans = $this->getIlluminateArrayTranslator();
55775624
$v = new Validator($trans, ['first' => 'taylor'], ['last' => 'exclude_unless:first,taylor|required']);
55785625
$this->assertTrue($v->fails());
5626+
$this->assertSame(['last' => ['validation.required']], $v->messages()->toArray());
55795627

55805628
$trans = $this->getIlluminateArrayTranslator();
55815629
$v = new Validator($trans, ['first' => 'sven', 'last' => 'wittevrongel'], ['last' => 'exclude_unless:first,taylor|integer']);
55825630
$this->assertTrue($v->passes());
5631+
$this->assertSame([], $v->validated());
55835632

55845633
$trans = $this->getIlluminateArrayTranslator();
55855634
$v = new Validator($trans, ['first' => 'taylor'], ['last' => 'exclude_unless:first,taylor,sven|required']);
55865635
$this->assertTrue($v->fails());
5636+
$this->assertSame(['last' => ['validation.required']], $v->messages()->toArray());
55875637

55885638
$trans = $this->getIlluminateArrayTranslator();
55895639
$v = new Validator($trans, ['first' => 'sven'], ['last' => 'exclude_unless:first,taylor,sven|required']);
55905640
$this->assertTrue($v->fails());
5641+
$this->assertSame(['last' => ['validation.required']], $v->messages()->toArray());
55915642

55925643
// error message when passed multiple values (exclude_unless:foo,bar,baz)
55935644
$trans = $this->getIlluminateArrayTranslator();
@@ -5602,80 +5653,99 @@ public function testValidateExcludeWith()
56025653
$trans = $this->getIlluminateArrayTranslator();
56035654
$v = new Validator($trans, [], ['last' => 'exclude_with:first|required']);
56045655
$this->assertFalse($v->passes());
5656+
$this->assertSame(['last' => ['validation.required']], $v->messages()->toArray());
56055657

56065658
$v = new Validator($trans, ['last' => ''], ['last' => 'exclude_with:first|required']);
56075659
$this->assertFalse($v->passes());
5660+
$this->assertSame(['last' => ['validation.required']], $v->messages()->toArray());
56085661

56095662
$v = new Validator($trans, ['first' => 'biz'], ['last' => 'exclude_with:first|required']);
56105663
$this->assertTrue($v->passes());
5664+
$this->assertSame([], $v->validated());
56115665

56125666
$v = new Validator($trans, ['first' => 'Taylor', 'last' => 'Otwell'], ['last' => 'exclude_with:first|required']);
56135667
$this->assertTrue($v->passes());
5668+
$this->assertSame([], $v->validated());
56145669

56155670
$file = new SplFileInfo(__FILE__);
56165671
$v = new Validator($trans, ['file' => $file, 'foo' => ''], ['foo' => 'exclude_with:file|required']);
56175672
$this->assertTrue($v->passes());
5673+
$this->assertSame([], $v->validated());
56185674

56195675
$file = new SplFileInfo(__FILE__);
56205676
$foo = new SplFileInfo(__FILE__);
56215677
$v = new Validator($trans, ['file' => $file, 'foo' => $foo], ['foo' => 'exclude_with:file|required']);
56225678
$this->assertTrue($v->passes());
5679+
$this->assertSame([], $v->validated());
56235680

56245681
$file = new SplFileInfo(__FILE__);
56255682
$foo = new SplFileInfo('');
56265683
$v = new Validator($trans, ['file' => $file, 'foo' => $foo], ['foo' => 'exclude_with:file|required']);
56275684
$this->assertTrue($v->passes());
5685+
$this->assertSame([], $v->validated());
56285686
}
56295687

56305688
public function testValidateExcludeWithout()
56315689
{
56325690
$trans = $this->getIlluminateArrayTranslator();
56335691
$v = new Validator($trans, ['first' => ''], ['last' => 'exclude_without:first|required']);
56345692
$this->assertTrue($v->passes());
5693+
$this->assertSame([], $v->validated());
56355694

56365695
$v = new Validator($trans, ['first' => '', 'last' => ''], ['last' => 'exclude_without:first|required']);
56375696
$this->assertTrue($v->passes());
5697+
$this->assertSame([], $v->validated());
56385698

56395699
$v = new Validator($trans, ['first' => 'bar'], ['last' => 'exclude_without:first|required']);
56405700
$this->assertFalse($v->passes());
5701+
$this->assertSame(['last' => ['validation.required']], $v->messages()->toArray());
56415702

56425703
$v = new Validator($trans, [], ['last' => 'exclude_without:first|required']);
56435704
$this->assertTrue($v->passes());
5705+
$this->assertSame([], $v->validated());
56445706

56455707
$v = new Validator($trans, ['first' => 'Taylor', 'last' => 'Otwell'], ['last' => 'exclude_without:first|required']);
56465708
$this->assertTrue($v->passes());
5709+
$this->assertSame(['last' => 'Otwell'], $v->validated());
56475710

56485711
$v = new Validator($trans, ['last' => 'Otwell'], ['last' => 'exclude_without:first']);
56495712
$this->assertTrue($v->passes());
5713+
$this->assertSame([], $v->validated());
56505714

56515715
$file = new SplFileInfo(__FILE__);
56525716
$v = new Validator($trans, ['file' => $file], ['foo' => 'exclude_without:file|required']);
56535717
$this->assertFalse($v->passes());
5718+
$this->assertSame([], $v->validated());
56545719

56555720
$file = new SplFileInfo(__FILE__);
56565721
$foo = new SplFileInfo('');
56575722
$v = new Validator($trans, ['file' => $file, 'foo' => $foo], ['foo' => 'exclude_without:file|required']);
56585723
$this->assertFalse($v->passes());
5724+
$this->assertSame(['foo' => ['validation.required']], $v->messages()->toArray());
56595725

56605726
$file = new SplFileInfo(__FILE__);
56615727
$foo = new SplFileInfo(__FILE__);
56625728
$v = new Validator($trans, ['file' => $file, 'foo' => $foo], ['foo' => 'exclude_without:file|required']);
56635729
$this->assertTrue($v->passes());
5730+
$this->assertArrayHasKey('foo', $v->validated());
56645731

56655732
$file = new SplFileInfo('');
56665733
$foo = new SplFileInfo(__FILE__);
56675734
$v = new Validator($trans, ['file' => $file, 'foo' => $foo], ['foo' => 'exclude_without:file|required']);
56685735
$this->assertTrue($v->passes());
5736+
$this->assertSame([], $v->validated());
56695737

56705738
$file = new SplFileInfo(__FILE__);
56715739
$foo = new SplFileInfo('');
56725740
$v = new Validator($trans, ['file' => $file, 'foo' => $foo], ['foo' => 'exclude_without:file|required']);
56735741
$this->assertTrue($v->fails());
5742+
$this->assertSame(['foo' => ['validation.required']], $v->messages()->toArray());
56745743

56755744
$file = new SplFileInfo('');
56765745
$foo = new SplFileInfo('');
56775746
$v = new Validator($trans, ['file' => $file, 'foo' => $foo], ['foo' => 'exclude_without:file']);
56785747
$this->assertTrue($v->passes());
5748+
$this->assertSame([], $v->validated());
56795749
}
56805750

56815751
protected function getTranslator()

0 commit comments

Comments
 (0)