Skip to content

Commit b989676

Browse files
authored
Merge pull request #59 from rakit/58-fix-unexpected-get-valid-data
Fixes #58
2 parents 4c9261b + b39e98c commit b989676

File tree

5 files changed

+127
-28
lines changed

5 files changed

+127
-28
lines changed

src/Attribute.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ public function isArrayAttribute()
124124
return count($this->getKeyIndexes()) > 0;
125125
}
126126

127+
public function isUsingDotNotation()
128+
{
129+
return strpos($this->getKey(), '.') !== false;
130+
}
131+
127132
public function resolveSiblingKey($key)
128133
{
129134
$indexes = $this->getKeyIndexes();
@@ -165,4 +170,4 @@ public function getAlias()
165170
return $this->alias;
166171
}
167172

168-
}
173+
}

src/Helper.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,36 @@ public static function arraySet(&$target, $key, $value, $overwrite = true)
158158
return $target;
159159
}
160160

161+
162+
/**
163+
* Unset an item on an array or object using dot notation.
164+
*
165+
* @param mixed $target
166+
* @param string|array $key
167+
* @return mixed
168+
*/
169+
public static function arrayUnset(&$target, $key)
170+
{
171+
if (!is_array($target)) {
172+
return $target;
173+
}
174+
175+
$segments = is_array($key) ? $key : explode('.', $key);
176+
$segment = array_shift($segments);
177+
178+
if ($segment == '*') {
179+
$target = [];
180+
} elseif ($segments) {
181+
if (array_key_exists($segment, $target)) {
182+
static::arrayUnset($target[$segment], $segments);
183+
}
184+
} elseif (array_key_exists($segment, $target)) {
185+
unset($target[$segment]);
186+
}
187+
188+
return $target;
189+
}
190+
161191
/**
162192
* Get snake_case format from given string
163193
*
@@ -171,7 +201,7 @@ public static function snakeCase($value, $delimiter = '_')
171201
$value = preg_replace('/\s+/u', '', ucwords($value));
172202
$value = strtolower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value));
173203
}
174-
204+
175205
return $value;
176206
}
177207

src/Validation.php

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Validation
2020
protected $aliases = [];
2121

2222
protected $messageSeparator = ':';
23-
23+
2424
protected $validData = [];
2525
protected $invalidData = [];
2626

@@ -72,7 +72,7 @@ protected function validateAttribute(Attribute $attribute)
7272
}
7373

7474
$attributeKey = $attribute->getKey();
75-
$rules = $attribute->getRules();
75+
$rules = $attribute->getRules();
7676

7777
$value = $this->getValue($attributeKey);
7878
$isEmptyValue = $this->isEmptyValue($value);
@@ -92,7 +92,7 @@ protected function validateAttribute(Attribute $attribute)
9292
if ($isEmptyValue AND $this->ruleIsOptional($attribute, $ruleValidator)) {
9393
continue;
9494
}
95-
95+
9696
if (!$valid) {
9797
$isValid = false;
9898
$this->addError($attribute, $value, $ruleValidator);
@@ -254,8 +254,8 @@ protected function isEmptyValue($value)
254254

255255
protected function ruleIsOptional(Attribute $attribute, Rule $rule)
256256
{
257-
return false === $attribute->isRequired() AND
258-
false === $rule->isImplicit() AND
257+
return false === $attribute->isRequired() AND
258+
false === $rule->isImplicit() AND
259259
false === $rule instanceof Required;
260260
}
261261

@@ -288,14 +288,14 @@ protected function resolveMessage(Attribute $attribute, $value, Rule $validator)
288288
];
289289

290290
if ($primaryAttribute) {
291-
// insert primaryAttribute keys
291+
// insert primaryAttribute keys
292292
// $message_keys = [
293293
// $attributeKey.$this->messageSeparator.$ruleKey,
294294
// >> here [1] <<
295295
// $attributeKey,
296296
// >> and here [3] <<
297297
// $ruleKey
298-
// ];
298+
// ];
299299
$primaryAttributeKey = $primaryAttribute->getKey();
300300
array_splice($message_keys, 1, 0, $primaryAttributeKey.$this->messageSeparator.$ruleKey);
301301
array_splice($message_keys, 3, 0, $primaryAttributeKey);
@@ -359,7 +359,7 @@ protected function resolveRules($rules)
359359
foreach($rules as $i => $rule) {
360360
if (empty($rule)) continue;
361361
$params = [];
362-
362+
363363
if (is_string($rule)) {
364364
list($rulename, $params) = $this->parseRule($rule);
365365
$validator = call_user_func_array($validatorFactory, array_merge([$rulename], $params));
@@ -446,7 +446,7 @@ protected function resolveInputAttributes(array $inputs)
446446
$resolvedInputs = [];
447447
foreach($inputs as $key => $rules) {
448448
$exp = explode(':', $key);
449-
449+
450450
if (count($exp) > 1) {
451451
// set attribute alias
452452
$this->aliases[$exp[0]] = $exp[1];
@@ -457,16 +457,17 @@ protected function resolveInputAttributes(array $inputs)
457457

458458
return $resolvedInputs;
459459
}
460-
460+
461461
public function getValidatedData() {
462462
return array_merge($this->validData, $this->invalidData);
463463
}
464464

465465
protected function setValidData(Attribute $attribute, $value)
466466
{
467467
$key = $attribute->getKey();
468-
if ($attribute->isArrayAttribute()) {
469-
Helper::arraySet($this->validData, $key, $value);
468+
if ($attribute->isArrayAttribute() || $attribute->isUsingDotNotation()) {
469+
Helper::arraySet($this->validData, $key, $value);
470+
Helper::arrayUnset($this->invalidData, $key);
470471
} else {
471472
$this->validData[$key] = $value;
472473
}
@@ -480,8 +481,9 @@ public function getValidData()
480481
protected function setInvalidData(Attribute $attribute, $value)
481482
{
482483
$key = $attribute->getKey();
483-
if ($attribute->isArrayAttribute()) {
484-
Helper::arraySet($this->invalidData, $key, $value);
484+
if ($attribute->isArrayAttribute() || $attribute->isUsingDotNotation()) {
485+
Helper::arraySet($this->invalidData, $key, $value);
486+
Helper::arrayUnset($this->validData, $key);
485487
} else {
486488
$this->invalidData[$key] = $value;
487489
}

tests/HelperTest.php

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function testArrayGet()
4242
$this->assertEquals(Helper::arrayGet($array, 'foo.bar'), $array['foo']['bar']);
4343
$this->assertEquals(Helper::arrayGet($array, 'foo.bar.baz'), $array['foo']['bar']['baz']);
4444
$this->assertEquals(Helper::arrayGet($array, 'one.two.three'), 123);
45-
45+
4646
$this->assertNull(Helper::arrayGet($array, 'foo.bar.baz.qux'));
4747
$this->assertNull(Helper::arrayGet($array, 'one.two'));
4848
}
@@ -89,7 +89,7 @@ public function testArraySet()
8989

9090
Helper::arraySet($array, 'comments.*.id', null, false);
9191
Helper::arraySet($array, 'comments.*.x.y', 1, false);
92-
92+
9393
$this->assertEquals($array, [
9494
'comments' => [
9595
['id' => null, 'text' => 'foo', 'x' => ['y' => 1]],
@@ -99,4 +99,34 @@ public function testArraySet()
9999
]);
100100
}
101101

102+
public function testArrayUnset()
103+
{
104+
$array = [
105+
'users' => [
106+
'one' => 'user_one',
107+
'two' => 'user_two',
108+
],
109+
'stuffs' => [1, 'two', ['three'], null, false, true],
110+
'message' => "lorem ipsum",
111+
];
112+
113+
Helper::arrayUnset($array, 'users.one');
114+
$this->assertEquals($array, [
115+
'users' => [
116+
'two' => 'user_two',
117+
],
118+
'stuffs' => [1, 'two', ['three'], null, false, true],
119+
'message' => "lorem ipsum",
120+
]);
121+
122+
Helper::arrayUnset($array, 'stuffs.*');
123+
$this->assertEquals($array, [
124+
'users' => [
125+
'two' => 'user_two',
126+
],
127+
'stuffs' => [],
128+
'message' => "lorem ipsum",
129+
]);
130+
}
131+
102132
}

tests/ValidatorTest.php

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public function testRequiredUploadedFile()
7676
$validation = $this->validator->validate([
7777
'file' => $empty_file
7878
], [
79-
'file' => 'required|uploaded_file'
79+
'file' => 'required|uploaded_file'
8080
]);
8181

8282
$errors = $validation->errors();
@@ -97,20 +97,20 @@ public function testOptionalUploadedFile()
9797
$validation = $this->validator->validate([
9898
'file' => $empty_file
9999
], [
100-
'file' => 'uploaded_file'
100+
'file' => 'uploaded_file'
101101
]);
102102
$this->assertTrue($validation->passes());
103103
}
104104

105105
/**
106106
* @dataProvider getSamplesMissingKeyFromUploadedFileValue
107-
*/
107+
*/
108108
public function testMissingKeyUploadedFile($uploaded_file)
109109
{
110110
$validation = $this->validator->validate([
111111
'file' => $uploaded_file
112112
], [
113-
'file' => 'required|uploaded_file'
113+
'file' => 'required|uploaded_file'
114114
]);
115115

116116
$errors = $validation->errors();
@@ -335,7 +335,7 @@ public function testAfterRule()
335335

336336
$this->assertFalse($validator2->passes());
337337
}
338-
338+
339339
public function testNewValidationRuleCanBeAdded()
340340
{
341341

@@ -735,7 +735,7 @@ public function testUsingDefaults()
735735
'is_enabled' => '1',
736736
'is_published' => 'invalid-value'
737737
]);
738-
738+
739739
// Getting only valid data
740740
$validData = $validation->getValidData();
741741
$this->assertEquals($validData, [
@@ -914,13 +914,22 @@ public function testGetValidData()
914914
'something',
915915
916916
],
917+
'stuffs' => [
918+
'one' => '1',
919+
'two' => '2',
920+
'three' => 'three',
921+
],
917922
'thing' => 'exists',
918923
], [
919924
'thing' => 'required',
920925
'items.*.product_id' => 'required|numeric',
921926
'emails.*' => 'required|email',
922927
'items.*.qty' => 'required|numeric',
923-
'something' => 'default:on|required|in:on,off'
928+
'something' => 'default:on|required|in:on,off',
929+
'stuffs' => 'required|array',
930+
'stuffs.one' => 'required|numeric',
931+
'stuffs.two' => 'required|numeric',
932+
'stuffs.three' => 'required|numeric',
924933
]);
925934

926935
$validData = $validation->getValidData();
@@ -936,8 +945,15 @@ public function testGetValidData()
936945
937946
],
938947
'thing' => 'exists',
939-
'something' => 'on'
948+
'something' => 'on',
949+
'stuffs' => [
950+
'one' => '1',
951+
'two' => '2',
952+
]
940953
], $validData);
954+
955+
$stuffs = $validData['stuffs'];
956+
$this->assertFalse(isset($stuffs['three']));
941957
}
942958

943959
public function testGetInvalidData()
@@ -954,13 +970,22 @@ public function testGetInvalidData()
954970
'something',
955971
956972
],
973+
'stuffs' => [
974+
'one' => '1',
975+
'two' => '2',
976+
'three' => 'three',
977+
],
957978
'thing' => 'exists',
958979
], [
959980
'thing' => 'required',
960981
'items.*.product_id' => 'required|numeric',
961982
'emails.*' => 'required|email',
962983
'items.*.qty' => 'required|numeric',
963-
'something' => 'required|in:on,off'
984+
'something' => 'required|in:on,off',
985+
'stuffs' => 'required|array',
986+
'stuffs.one' => 'numeric',
987+
'stuffs.two' => 'numeric',
988+
'stuffs.three' => 'numeric',
964989
]);
965990

966991
$invalidData = $validation->getInvalidData();
@@ -974,8 +999,15 @@ public function testGetInvalidData()
974999
'emails' => [
9751000
1 => 'something'
9761001
],
977-
'something' => null
1002+
'something' => null,
1003+
'stuffs' => [
1004+
'three' => 'three',
1005+
]
9781006
], $invalidData);
1007+
1008+
$stuffs = $invalidData['stuffs'];
1009+
$this->assertFalse(isset($stuffs['one']));
1010+
$this->assertFalse(isset($stuffs['two']));
9791011
}
9801012

9811013
}

0 commit comments

Comments
 (0)