Skip to content

Commit fec487c

Browse files
[8.x] Add array_keys validation rule (#40720)
* Add contains all validation rule to assert an array or string contains all the required entries * lint * styleci lint changes * rename rule to array_keys and made rule fail when not an array * lint * Update ReplacesAttributes.php * Update ValidatesAttributes.php * formatting Co-authored-by: Taylor Otwell <[email protected]>
1 parent cf8b275 commit fec487c

File tree

3 files changed

+138
-0
lines changed

3 files changed

+138
-0
lines changed

src/Illuminate/Validation/Concerns/ReplacesAttributes.php

+18
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,24 @@ protected function replaceInArray($message, $attribute, $rule, $parameters)
200200
return str_replace(':other', $this->getDisplayableAttribute($parameters[0]), $message);
201201
}
202202

203+
/**
204+
* Replace all place-holders for the required_array_keys rule.
205+
*
206+
* @param string $message
207+
* @param string $attribute
208+
* @param string $rule
209+
* @param array $parameters
210+
* @return string
211+
*/
212+
protected function replaceRequiredArrayKeys($message, $attribute, $rule, $parameters)
213+
{
214+
foreach ($parameters as &$parameter) {
215+
$parameter = $this->getDisplayableValue($attribute, $parameter);
216+
}
217+
218+
return str_replace(':values', implode(', ', $parameters), $message);
219+
}
220+
203221
/**
204222
* Replace all place-holders for the mimetypes rule.
205223
*

src/Illuminate/Validation/Concerns/ValidatesAttributes.php

+23
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,29 @@ public function validateArray($attribute, $value, $parameters = [])
371371
return empty(array_diff_key($value, array_fill_keys($parameters, '')));
372372
}
373373

374+
/**
375+
* Validate that an array has all of the given keys.
376+
*
377+
* @param string $attribute
378+
* @param mixed $value
379+
* @param array $parameters
380+
* @return bool
381+
*/
382+
public function validateRequiredArrayKeys($attribute, $value, $parameters)
383+
{
384+
if (! is_array($value)) {
385+
return false;
386+
}
387+
388+
foreach ($parameters as $param) {
389+
if (! Arr::exists($value, $param)) {
390+
return false;
391+
}
392+
}
393+
394+
return true;
395+
}
396+
374397
/**
375398
* Validate the size of an attribute is between a set of values.
376399
*

tests/Validation/ValidationValidatorTest.php

+97
Original file line numberDiff line numberDiff line change
@@ -7019,6 +7019,103 @@ public function testFailOnFirstError()
70197019
$this->assertEquals($expectedFailOnFirstErrorEnableResult, $failOnFirstErrorEnable->getMessageBag()->getMessages());
70207020
}
70217021

7022+
public function testArrayKeysValidationPassedWhenHasKeys()
7023+
{
7024+
$trans = $this->getIlluminateArrayTranslator();
7025+
7026+
$data = [
7027+
'baz' => [
7028+
'foo' => 'bar',
7029+
'fee' => 'faa',
7030+
'laa' => 'lee',
7031+
],
7032+
];
7033+
7034+
$rules = [
7035+
'baz' => [
7036+
'array',
7037+
'required_array_keys:foo,fee,laa',
7038+
],
7039+
];
7040+
7041+
$validator = new Validator($trans, $data, $rules, [], []);
7042+
$this->assertTrue($validator->passes());
7043+
}
7044+
7045+
public function testArrayKeysValidationPassedWithPartialMatch()
7046+
{
7047+
$trans = $this->getIlluminateArrayTranslator();
7048+
7049+
$data = [
7050+
'baz' => [
7051+
'foo' => 'bar',
7052+
'fee' => 'faa',
7053+
'laa' => 'lee',
7054+
],
7055+
];
7056+
7057+
$rules = [
7058+
'baz' => [
7059+
'array',
7060+
'required_array_keys:foo,fee',
7061+
],
7062+
];
7063+
7064+
$validator = new Validator($trans, $data, $rules, [], []);
7065+
$this->assertTrue($validator->passes());
7066+
}
7067+
7068+
public function testArrayKeysValidationFailsWithMissingKey()
7069+
{
7070+
$trans = $this->getIlluminateArrayTranslator();
7071+
$trans->addLines(['validation.required_array_keys' => 'The :attribute field must contain entries for :values'], 'en');
7072+
7073+
$data = [
7074+
'baz' => [
7075+
'foo' => 'bar',
7076+
'fee' => 'faa',
7077+
'laa' => 'lee',
7078+
],
7079+
];
7080+
7081+
$rules = [
7082+
'baz' => [
7083+
'array',
7084+
'required_array_keys:foo,fee,boo,bar',
7085+
],
7086+
];
7087+
7088+
$validator = new Validator($trans, $data, $rules, [], []);
7089+
$this->assertFalse($validator->passes());
7090+
$this->assertSame(
7091+
'The baz field must contain entries for foo, fee, boo, bar',
7092+
$validator->messages()->first('baz')
7093+
);
7094+
}
7095+
7096+
public function testArrayKeysValidationFailsWithNotAnArray()
7097+
{
7098+
$trans = $this->getIlluminateArrayTranslator();
7099+
$trans->addLines(['validation.required_array_keys' => 'The :attribute field must contain entries for :values'], 'en');
7100+
7101+
$data = [
7102+
'baz' => 'no an array',
7103+
];
7104+
7105+
$rules = [
7106+
'baz' => [
7107+
'required_array_keys:foo,fee,boo,bar',
7108+
],
7109+
];
7110+
7111+
$validator = new Validator($trans, $data, $rules, [], []);
7112+
$this->assertFalse($validator->passes());
7113+
$this->assertSame(
7114+
'The baz field must contain entries for foo, fee, boo, bar',
7115+
$validator->messages()->first('baz')
7116+
);
7117+
}
7118+
70227119
protected function getTranslator()
70237120
{
70247121
return m::mock(TranslatorContract::class);

0 commit comments

Comments
 (0)