Skip to content

Commit fd21876

Browse files
committed
Show only one error message per validated attribute
1 parent 3e3ac64 commit fd21876

File tree

2 files changed

+71
-109
lines changed

2 files changed

+71
-109
lines changed

src/UniqueTranslationValidator.php

Lines changed: 27 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,37 @@ public function validate($attribute, $value, $parameters, $validator)
2727
return true;
2828
}
2929

30-
$this->addErrorsToValidator($validator, $parameters, $name, $locale);
30+
$this->setMissingErrorMessages($validator, $name, $locale);
3131

3232
return false;
3333
}
3434

35+
/**
36+
* Set any missing (custom) error messages for our validation rule.
37+
*
38+
* @param \Illuminate\Validation\Validator $validator
39+
* @param string $name
40+
* @param string $locale
41+
*
42+
* @return void
43+
*/
44+
protected function setMissingErrorMessages($validator, $name, $locale)
45+
{
46+
$rule = 'unique_translation';
47+
48+
$keys = [
49+
"{$name}.{$rule}",
50+
"{$name}.*.{$rule}",
51+
"{$name}.{$locale}.{$rule}",
52+
];
53+
54+
foreach ($keys as $key) {
55+
if ( ! array_key_exists($key, $validator->customMessages)) {
56+
$validator->customMessages[$key] = trans('validation.unique');
57+
}
58+
}
59+
}
60+
3561
/**
3662
* Get the attribute name and locale.
3763
*
@@ -237,72 +263,4 @@ protected function addWhere($query, $key, $extraValue)
237263
$query->where($key, $extraValue);
238264
}
239265
}
240-
241-
/**
242-
* Add error messages to the validator.
243-
*
244-
* @param \Illuminate\Validation\Validator $validator
245-
* @param array $parameters
246-
* @param string $name
247-
* @param string $locale
248-
*
249-
* @return void
250-
*/
251-
protected function addErrorsToValidator($validator, $parameters, $name, $locale)
252-
{
253-
$rule = 'unique_translation';
254-
$message = $this->getFormattedMessage($validator, $rule, $parameters, $name, $locale);
255-
256-
$validator->errors()
257-
->add($name, $message)
258-
->add("{$name}.{$locale}", $message);
259-
}
260-
261-
/**
262-
* Get the formatted error message.
263-
*
264-
* This will format the placeholders:
265-
* e.g. "post_slug" will become "post slug".
266-
*
267-
* @param \Illuminate\Validation\Validator $validator
268-
* @param string $rule
269-
* @param array $parameters
270-
* @param string $name
271-
* @param string $locale
272-
*
273-
* @return string
274-
*/
275-
protected function getFormattedMessage($validator, $rule, $parameters, $name, $locale)
276-
{
277-
$message = $this->getMessage($validator, $rule, $name, $locale);
278-
279-
return $validator->makeReplacements($message, $name, $rule, $parameters);
280-
}
281-
282-
/**
283-
* Get any custom message from the validator or return a default message.
284-
*
285-
* @param \Illuminate\Validation\Validator $validator
286-
* @param string $rule
287-
* @param string $name
288-
* @param string $locale
289-
*
290-
* @return string
291-
*/
292-
protected function getMessage($validator, $rule, $name, $locale)
293-
{
294-
$keys = [
295-
"{$name}.{$rule}",
296-
"{$name}.*.{$rule}",
297-
"{$name}.{$locale}.{$rule}",
298-
];
299-
300-
foreach ($keys as $key) {
301-
if (array_key_exists($key, $validator->customMessages)) {
302-
return $validator->customMessages[$key];
303-
}
304-
}
305-
306-
return trans('validation.unique');
307-
}
308266
}

tests/ValidationMessageTest.php

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,28 @@ public function it_returns_a_default_error_message_when_validating_a_single_tran
1616
'name' => ['en' => 'existing-name-en'],
1717
]);
1818

19+
$formAttributes = [
20+
'form_slug' => 'existing-slug-en',
21+
'form_name' => 'existing-name-en',
22+
];
23+
1924
$rules = [
2025
'form_slug' => "{$this->rule}:{$this->table},slug",
2126
'form_name' => UniqueTranslationRule::for($this->table, 'name'),
2227
];
2328

24-
$validation = Validator::make([
25-
'form_slug' => 'existing-slug-en',
26-
'form_name' => 'existing-name-en',
27-
], $rules);
28-
2929
$expectedSlugError = trans('validation.unique', ['attribute' => 'form slug']);
3030
$expectedNameError = trans('validation.unique', ['attribute' => 'form name']);
3131

3232
$this->assertNotEmpty($expectedSlugError);
3333
$this->assertNotEmpty($expectedNameError);
3434

35-
$this->assertEquals($expectedSlugError, $validation->errors()->first('form_slug'));
36-
$this->assertEquals($expectedNameError, $validation->errors()->first('form_name'));
35+
$validation = Validator::make($formAttributes, $rules);
3736

38-
$this->assertEquals($expectedSlugError, $validation->errors()->first('form_slug.en'));
39-
$this->assertEquals($expectedNameError, $validation->errors()->first('form_name.en'));
37+
$this->assertEquals([
38+
'form_slug' => [$expectedSlugError],
39+
'form_name' => [$expectedNameError],
40+
], $validation->errors()->messages());
4041
}
4142

4243
/** @test */
@@ -47,27 +48,28 @@ public function it_returns_a_default_error_message_when_validating_an_array()
4748
'name' => ['en' => 'existing-name-en'],
4849
]);
4950

51+
$formAttributes = [
52+
'form_slug' => ['en' => 'existing-slug-en'],
53+
'form_name' => ['en' => 'existing-name-en'],
54+
];
55+
5056
$rules = [
5157
'form_slug.*' => "{$this->rule}:{$this->table},slug",
5258
'form_name.*' => UniqueTranslationRule::for($this->table, 'name'),
5359
];
5460

55-
$validation = Validator::make([
56-
'form_slug' => ['en' => 'existing-slug-en'],
57-
'form_name' => ['en' => 'existing-name-en'],
58-
], $rules);
59-
60-
$expectedSlugError = trans('validation.unique', ['attribute' => 'form slug']);
61-
$expectedNameError = trans('validation.unique', ['attribute' => 'form name']);
61+
$expectedSlugError = trans('validation.unique', ['attribute' => 'form_slug.en']);
62+
$expectedNameError = trans('validation.unique', ['attribute' => 'form_name.en']);
6263

6364
$this->assertNotEmpty($expectedSlugError);
6465
$this->assertNotEmpty($expectedNameError);
6566

66-
$this->assertEquals($expectedSlugError, $validation->errors()->first('form_slug'));
67-
$this->assertEquals($expectedNameError, $validation->errors()->first('form_name'));
67+
$validation = Validator::make($formAttributes, $rules);
6868

69-
$this->assertEquals($expectedSlugError, $validation->errors()->first('form_slug.en'));
70-
$this->assertEquals($expectedNameError, $validation->errors()->first('form_name.en'));
69+
$this->assertEquals([
70+
'form_slug.en' => [$expectedSlugError],
71+
'form_name.en' => [$expectedNameError],
72+
], $validation->errors()->messages());
7173
}
7274

7375
/** @test */
@@ -78,6 +80,11 @@ public function it_returns_a_custom_error_message_when_validating_a_single_trans
7880
'name' => ['en' => 'existing-name-en'],
7981
]);
8082

83+
$formAttributes = [
84+
'form_slug' => 'existing-slug-en',
85+
'form_name' => 'existing-name-en',
86+
];
87+
8188
$rules = [
8289
'form_slug' => "{$this->rule}:{$this->table},slug",
8390
'form_name' => UniqueTranslationRule::for($this->table, 'name'),
@@ -88,19 +95,15 @@ public function it_returns_a_custom_error_message_when_validating_a_single_trans
8895
"form_name.{$this->rule}" => 'Custom name message for :attribute.',
8996
];
9097

91-
$validation = Validator::make([
92-
'form_slug' => 'existing-slug-en',
93-
'form_name' => 'existing-name-en',
94-
], $rules, $messages);
95-
9698
$expectedSlugError = 'Custom slug message for form slug.';
9799
$expectedNameError = 'Custom name message for form name.';
98100

99-
$this->assertEquals($expectedSlugError, $validation->errors()->first('form_slug'));
100-
$this->assertEquals($expectedNameError, $validation->errors()->first('form_name'));
101+
$validation = Validator::make($formAttributes, $rules, $messages);
101102

102-
$this->assertEquals($expectedSlugError, $validation->errors()->first('form_slug.en'));
103-
$this->assertEquals($expectedNameError, $validation->errors()->first('form_name.en'));
103+
$this->assertEquals([
104+
'form_slug' => [$expectedSlugError],
105+
'form_name' => [$expectedNameError],
106+
], $validation->errors()->messages());
104107
}
105108

106109
/** @test */
@@ -111,6 +114,11 @@ public function it_returns_a_custom_error_message_when_validating_an_array()
111114
'name' => ['en' => 'existing-name-en'],
112115
]);
113116

117+
$formAttributes = [
118+
'form_slug' => ['en' => 'existing-slug-en'],
119+
'form_name' => ['en' => 'existing-name-en'],
120+
];
121+
114122
$rules = [
115123
'form_slug.*' => "{$this->rule}:{$this->table},slug",
116124
'form_name.*' => UniqueTranslationRule::for($this->table, 'name'),
@@ -121,18 +129,14 @@ public function it_returns_a_custom_error_message_when_validating_an_array()
121129
"form_name.*.{$this->rule}" => 'Custom name message for :attribute.',
122130
];
123131

124-
$validation = Validator::make([
125-
'form_slug' => ['en' => 'existing-slug-en'],
126-
'form_name' => ['en' => 'existing-name-en'],
127-
], $rules, $messages);
128-
129-
$expectedSlugError = 'Custom slug message for form slug.';
130-
$expectedNameError = 'Custom name message for form name.';
132+
$expectedSlugError = 'Custom slug message for form_slug.en.';
133+
$expectedNameError = 'Custom name message for form_name.en.';
131134

132-
$this->assertEquals($expectedSlugError, $validation->errors()->first('form_slug'));
133-
$this->assertEquals($expectedNameError, $validation->errors()->first('form_name'));
135+
$validation = Validator::make($formAttributes, $rules, $messages);
134136

135-
$this->assertEquals($expectedSlugError, $validation->errors()->first('form_slug.en'));
136-
$this->assertEquals($expectedNameError, $validation->errors()->first('form_name.en'));
137+
$this->assertEquals([
138+
'form_slug.en' => [$expectedSlugError],
139+
'form_name.en' => [$expectedNameError],
140+
], $validation->errors()->messages());
137141
}
138142
}

0 commit comments

Comments
 (0)