Skip to content

Commit f639fac

Browse files
committed
fix: preserve null values in Validation::getValidated()
1 parent 8ca64a9 commit f639fac

File tree

4 files changed

+60
-4
lines changed

4 files changed

+60
-4
lines changed

system/Validation/DotArrayFilter.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ private static function filter(array $indexes, array $array): array
6262
// Get the current index
6363
$currentIndex = array_shift($indexes);
6464

65-
// If the current index doesn't exist and is not a wildcard, return an empty array
66-
if (! isset($array[$currentIndex]) && $currentIndex !== '*') {
65+
// If the current index doesn't exist and is not a wildcard, return an empty array.
66+
// Use array_key_exists() so explicit null values are preserved.
67+
if ($currentIndex !== '*' && ! array_key_exists($currentIndex, $array)) {
6768
return [];
6869
}
6970

@@ -88,9 +89,9 @@ private static function filter(array $indexes, array $array): array
8889
return $result;
8990
}
9091

91-
// If this is the last index, return the value
92+
// If this is the last index, return the value as-is, including null.
9293
if ($indexes === []) {
93-
return [$currentIndex => $array[$currentIndex] ?? []];
94+
return [$currentIndex => $array[$currentIndex]];
9495
}
9596

9697
// If the current value is an array, recursively filter it

tests/system/Validation/DotArrayFilterTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,15 @@ public function testRunReturnOrderedIndices(): void
197197

198198
$this->assertSame($data, $result);
199199
}
200+
201+
public function testRunPreservesNullValue(): void
202+
{
203+
$data = [
204+
'foo' => null,
205+
];
206+
207+
$result = DotArrayFilter::run(['foo'], $data);
208+
209+
$this->assertSame(['foo' => null], $result);
210+
}
200211
}

tests/system/Validation/ValidationTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,49 @@ public function testJsonInput(): void
901901
service('superglobals')->unsetServer('CONTENT_TYPE');
902902
}
903903

904+
/**
905+
* @param array<string, string> $rules
906+
* @param array<string, mixed> $expectedValidated
907+
*/
908+
#[DataProvider('provideGetValidatedWithNullValue')]
909+
public function testGetValidatedWithNullValue(
910+
array $rules,
911+
bool $expectedResult,
912+
array $expectedValidated,
913+
): void {
914+
$data = [
915+
'role' => null,
916+
];
917+
918+
$result = $this->validation->setRules($rules)->run($data);
919+
920+
$this->assertSame($expectedResult, $result);
921+
$this->assertSame($expectedValidated, $this->validation->getValidated());
922+
$this->assertSame($expectedResult ? [] : ['role'], array_keys($this->validation->getErrors()));
923+
}
924+
925+
/**
926+
* @return iterable<string, array{
927+
* 0: array<string, string>,
928+
* 1: bool,
929+
* 2: array<string, mixed>
930+
* }>
931+
*/
932+
public static function provideGetValidatedWithNullValue(): iterable
933+
{
934+
yield 'permit_empty preserves null' => [
935+
['role' => 'permit_empty|string'],
936+
true,
937+
['role' => null],
938+
];
939+
940+
yield 'string fails on null' => [
941+
['role' => 'string'],
942+
false,
943+
[],
944+
];
945+
}
946+
904947
public function testJsonInputInvalid(): void
905948
{
906949
$this->expectException(HTTPException::class);

user_guide_src/source/changelogs/v4.7.3.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Bugs Fixed
3434

3535
- **Autoloader:** Fixed a bug where ``Autoloader::unregister()`` (used during tests) silently failed to remove handlers from the SPL autoload stack, causing closures to accumulate permanently.
3636
- **Common:** Fixed a bug where the ``command()`` helper function did not properly clean up output buffers, which could lead to risky tests when exceptions were thrown.
37+
- **Validation:** Fixed a bug where ``Validation::getValidated()`` dropped fields whose validated value was explicitly ``null``.
3738

3839
See the repo's
3940
`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_

0 commit comments

Comments
 (0)