Skip to content

Commit 86a13f9

Browse files
authored
Merge pull request #73 from rakit/enhance-and-improve-messages
Enhance and improve messages
2 parents 67323e8 + 5329e92 commit 86a13f9

File tree

12 files changed

+364
-9
lines changed

12 files changed

+364
-9
lines changed

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,38 @@ $validation_a = $validator->make($dataset_a, [
267267
$validation_a->validate();
268268
```
269269

270+
## Translation
271+
272+
Translation is different with custom messages.
273+
Translation may needed when you use custom message for rule `in`, `not_in`, `mimes`, and `uploaded_file`.
274+
275+
For example if you use rule `in:1,2,3` we will set invalid message like "The Attribute only allows '1', '2', or '3'"
276+
where part "'1', '2', or '3'" is comes from ":allowed_values" tag.
277+
So if you have custom Indonesian message ":attribute hanya memperbolehkan :allowed_values",
278+
we will set invalid message like "Attribute hanya memperbolehkan '1', '2', or '3'" which is the "or" word is not part of Indonesian language.
279+
280+
So, to solve this problem, we can use translation like this:
281+
282+
```php
283+
// Set translation for words 'and' and 'or'.
284+
$validator->setTranslations([
285+
'and' => 'dan',
286+
'or' => 'atau'
287+
]);
288+
289+
// Set custom message for 'in' rule
290+
$validator->setMessage('in', ":attribute hanya memperbolehkan :allowed_values");
291+
292+
// Validate
293+
$validation = $validator->validate($inputs, [
294+
'nomor' => 'in:1,2,3'
295+
]);
296+
297+
$message = $validation->errors()->first('nomor'); // "Nomor hanya memperbolehkan '1', '2', atau '3'"
298+
```
299+
300+
> Actually, our built-in rules only use words 'and' and 'or' that you may need to translates.
301+
270302
## Working with Error Message
271303

272304
Errors messages are collected in `Rakit\Validation\ErrorBag` object that you can get it using `errors()` method.

src/Helper.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,49 @@ public static function snakeCase(string $value, string $delimiter = '_'): string
203203

204204
return $value;
205205
}
206+
207+
/**
208+
* Join string[] to string with given $separator and $lastSeparator.
209+
*
210+
* @param array $pieces
211+
* @param string $separator
212+
* @param string|null $lastSeparator
213+
* @return string
214+
*/
215+
public static function join(array $pieces, string $separator, string $lastSeparator = null): string
216+
{
217+
if (is_null($lastSeparator)) {
218+
$lastSeparator = $separator;
219+
}
220+
221+
$last = array_pop($pieces);
222+
223+
switch (count($pieces)) {
224+
case 0:
225+
return $last ?: '';
226+
case 1:
227+
return $pieces[0] . $lastSeparator . $last;
228+
default:
229+
return implode($separator, $pieces) . $lastSeparator . $last;
230+
}
231+
}
232+
233+
/**
234+
* Wrap string[] by given $prefix and $suffix
235+
*
236+
* @param array $strings
237+
* @param string $prefix
238+
* @param string|null $suffix
239+
* @return array
240+
*/
241+
public static function wraps(array $strings, string $prefix, string $suffix = null): array
242+
{
243+
if (is_null($suffix)) {
244+
$suffix = $prefix;
245+
}
246+
247+
return array_map(function ($str) use ($prefix, $suffix) {
248+
return $prefix . $str . $suffix;
249+
}, $strings);
250+
}
206251
}

src/Rule.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ abstract class Rule
2121
/** @var array */
2222
protected $params = [];
2323

24+
/** @var array */
25+
protected $paramsTexts = [];
26+
2427
/** @var array */
2528
protected $fillableParams = [];
2629

@@ -145,6 +148,28 @@ public function parameter(string $key)
145148
return isset($this->params[$key])? $this->params[$key] : null;
146149
}
147150

151+
/**
152+
* Set parameter text that can be displayed in error message using ':param_key'
153+
*
154+
* @param string $key
155+
* @param string $text
156+
* @return void
157+
*/
158+
public function setParameterText(string $key, string $text)
159+
{
160+
$this->paramsTexts[$key] = $text;
161+
}
162+
163+
/**
164+
* Get $paramsTexts
165+
*
166+
* @return array
167+
*/
168+
public function getParametersTexts(): array
169+
{
170+
return $this->paramsTexts;
171+
}
172+
148173
/**
149174
* Check whether this rule is implicit
150175
*

src/Rules/In.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
namespace Rakit\Validation\Rules;
44

5+
use Rakit\Validation\Helper;
56
use Rakit\Validation\Rule;
67

78
class In extends Rule
89
{
910

1011
/** @var string */
11-
protected $message = "The :attribute is not allowing :value";
12+
protected $message = "The :attribute only allows :allowed_values";
1213

1314
/** @var bool */
1415
protected $strict = false;
@@ -49,7 +50,12 @@ public function check($value): bool
4950
{
5051
$this->requireParameters(['allowed_values']);
5152

52-
$allowed_values = $this->parameter('allowed_values');
53-
return in_array($value, $allowed_values, $this->strict);
53+
$allowedValues = $this->parameter('allowed_values');
54+
55+
$or = $this->validation ? $this->validation->getTranslation('or') : 'or';
56+
$allowedValuesText = Helper::join(Helper::wraps($allowedValues, "'"), ', ', ", {$or} ");
57+
$this->setParameterText('allowed_values', $allowedValuesText);
58+
59+
return in_array($value, $allowedValues, $this->strict);
5460
}
5561
}

src/Rules/Mimes.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22

33
namespace Rakit\Validation\Rules;
44

5-
use Rakit\Validation\Rule;
5+
use Rakit\Validation\Helper;
66
use Rakit\Validation\MimeTypeGuesser;
7+
use Rakit\Validation\Rule;
78

89
class Mimes extends Rule
910
{
1011
use Traits\FileTrait;
1112

1213
/** @var string */
13-
protected $message = "The :attribute file type is not allowed";
14+
protected $message = "The :attribute file type must be :allowed_types";
1415

1516
/** @var string|int */
1617
protected $maxSize = null;
@@ -60,6 +61,11 @@ public function check($value): bool
6061
{
6162
$allowedTypes = $this->parameter('allowed_types');
6263

64+
if ($allowedTypes) {
65+
$or = $this->validation ? $this->validation->getTranslation('or') : 'or';
66+
$this->setParameterText('allowed_types', Helper::join(Helper::wraps($allowedTypes, "'"), ', ', ", {$or} "));
67+
}
68+
6369
// below is Required rule job
6470
if (!$this->isValueFromUploadedFiles($value) or $value['error'] == UPLOAD_ERR_NO_FILE) {
6571
return true;

src/Rules/NotIn.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
namespace Rakit\Validation\Rules;
44

5+
use Rakit\Validation\Helper;
56
use Rakit\Validation\Rule;
67

78
class NotIn extends Rule
89
{
910

1011
/** @var string */
11-
protected $message = "The :attribute is not allowing :value";
12+
protected $message = "The :attribute is not allowing :disallowed_values";
1213

1314
/** @var bool */
1415
protected $strict = false;
@@ -48,7 +49,13 @@ public function strict($strict = true)
4849
public function check($value): bool
4950
{
5051
$this->requireParameters(['disallowed_values']);
52+
5153
$disallowedValues = (array) $this->parameter('disallowed_values');
54+
55+
$and = $this->validation ? $this->validation->getTranslation('and') : 'and';
56+
$disallowedValuesText = Helper::join(Helper::wraps($disallowedValues, "'"), ', ', ", {$and} ");
57+
$this->setParameterText('disallowed_values', $disallowedValuesText);
58+
5259
return !in_array($value, $disallowedValues, $this->strict);
5360
}
5461
}

src/Rules/UploadedFile.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class UploadedFile extends Rule implements BeforeValidate
1212
use Traits\FileTrait, Traits\SizeTrait;
1313

1414
/** @var string */
15-
protected $message = "The :attribute is not valid";
15+
protected $message = "The :attribute is not valid uploaded file";
1616

1717
/** @var string|int */
1818
protected $maxSize = null;
@@ -133,6 +133,11 @@ public function check($value): bool
133133
$maxSize = $this->parameter('max_size');
134134
$allowedTypes = $this->parameter('allowed_types');
135135

136+
if ($allowedTypes) {
137+
$or = $this->validation ? $this->validation->getTranslation('or') : 'or';
138+
$this->setParameterText('allowed_types', Helper::join(Helper::wraps($allowedTypes, "'"), ', ', ", {$or} "));
139+
}
140+
136141
// below is Required rule job
137142
if (!$this->isValueFromUploadedFiles($value) or $value['error'] == UPLOAD_ERR_NO_FILE) {
138143
return true;
@@ -150,13 +155,15 @@ public function check($value): bool
150155
if ($minSize) {
151156
$bytesMinSize = $this->getBytesSize($minSize);
152157
if ($value['size'] < $bytesMinSize) {
158+
$this->setMessage('The :attribute file is too small, minimum size is :min_size');
153159
return false;
154160
}
155161
}
156162

157163
if ($maxSize) {
158164
$bytesMaxSize = $this->getBytesSize($maxSize);
159165
if ($value['size'] > $bytesMaxSize) {
166+
$this->setMessage('The :attribute file is too large, maximum size is :max_size');
160167
return false;
161168
}
162169
}
@@ -167,6 +174,7 @@ public function check($value): bool
167174
unset($guesser);
168175

169176
if (!in_array($ext, $allowedTypes)) {
177+
$this->setMessage('The :attribute file type must be :allowed_types');
170178
return false;
171179
}
172180
}

src/Traits/TranslationsTrait.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace Rakit\Validation\Traits;
4+
5+
trait TranslationsTrait
6+
{
7+
8+
/** @var array */
9+
protected $translations = [];
10+
11+
/**
12+
* Given $key and $translation to set translation
13+
*
14+
* @param mixed $key
15+
* @param mixed $translation
16+
* @return void
17+
*/
18+
public function setTranslation(string $key, string $translation)
19+
{
20+
$this->translations[$key] = $translation;
21+
}
22+
23+
/**
24+
* Given $translations and set multiple translations
25+
*
26+
* @param array $translations
27+
* @return void
28+
*/
29+
public function setTranslations(array $translations)
30+
{
31+
$this->translations = array_merge($this->translations, $translations);
32+
}
33+
34+
/**
35+
* Given translation from given $key
36+
*
37+
* @param string $key
38+
* @return string
39+
*/
40+
public function getTranslation(string $key): string
41+
{
42+
return array_key_exists($key, $this->translations) ? $this->translations[$key] : $key;
43+
}
44+
45+
/**
46+
* Get all $translations
47+
*
48+
* @return array
49+
*/
50+
public function getTranslations(): array
51+
{
52+
return $this->translations;
53+
}
54+
}

src/Validation.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
class Validation
1111
{
12+
use Traits\TranslationsTrait;
1213

1314
/** @var mixed */
1415
protected $validator;
@@ -386,7 +387,7 @@ protected function resolveAttributeName(Attribute $attribute): string
386387
protected function resolveMessage(Attribute $attribute, $value, Rule $validator): string
387388
{
388389
$primaryAttribute = $attribute->getPrimaryAttribute();
389-
$params = $validator->getParameters();
390+
$params = array_merge($validator->getParameters(), $validator->getParametersTexts());
390391
$attributeKey = $attribute->getKey();
391392
$ruleKey = $validator->getKey();
392393
$alias = $attribute->getAlias() ?: $this->resolveAttributeName($attribute);

src/Validator.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44

55
class Validator
66
{
7+
use Traits\TranslationsTrait;
78

89
/** @var array */
910
protected $messages = [];
1011

12+
/** @var translations */
13+
protected $translations = [];
14+
1115
/** @var array */
1216
protected $validators = [];
1317

@@ -102,7 +106,10 @@ public function validate(array $inputs, array $rules, array $messages = []): Val
102106
public function make(array $inputs, array $rules, array $messages = []): Validation
103107
{
104108
$messages = array_merge($this->messages, $messages);
105-
return new Validation($this, $inputs, $rules, $messages);
109+
$validation = new Validation($this, $inputs, $rules, $messages);
110+
$validation->setTranslations($this->getTranslations());
111+
112+
return $validation;
106113
}
107114

108115
/**

0 commit comments

Comments
 (0)