Skip to content

Commit eda462a

Browse files
committed
feat: add dot array syntax support
1 parent a0cacb4 commit eda462a

File tree

4 files changed

+95
-19
lines changed

4 files changed

+95
-19
lines changed

system/Validation/Rules.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace CodeIgniter\Validation;
1313

14+
use CodeIgniter\Helpers\Array\ArrayHelper;
1415
use Config\Database;
1516
use InvalidArgumentException;
1617

@@ -443,6 +444,10 @@ public function field_exists(
443444
?string $error = null,
444445
?string $field = null
445446
): bool {
447+
if (strpos($field, '.') !== false) {
448+
return ArrayHelper::dotKeyExists($field, $data);
449+
}
450+
446451
return array_key_exists($field, $data);
447452
}
448453
}

system/Validation/StrictRules/Rules.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace CodeIgniter\Validation\StrictRules;
1515

16+
use CodeIgniter\Helpers\Array\ArrayHelper;
1617
use CodeIgniter\Validation\Rules as NonStrictRules;
1718
use Config\Database;
1819

@@ -419,6 +420,10 @@ public function field_exists(
419420
?string $error = null,
420421
?string $field = null
421422
): bool {
423+
if (strpos($field, '.') !== false) {
424+
return ArrayHelper::dotKeyExists($field, $data);
425+
}
426+
422427
return array_key_exists($field, $data);
423428
}
424429
}

system/Validation/Validation.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup
184184

185185
if ($values === []) {
186186
// We'll process the values right away if an empty array
187-
$this->processRules($field, $setup['label'] ?? $field, $values, $rules, $data);
187+
$this->processRules($field, $setup['label'] ?? $field, $values, $rules, $data, $field);
188188

189189
continue;
190190
}
@@ -196,7 +196,7 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup
196196
}
197197
} else {
198198
// Process single field
199-
$this->processRules($field, $setup['label'] ?? $field, $values, $rules, $data);
199+
$this->processRules($field, $setup['label'] ?? $field, $values, $rules, $data, $field);
200200
}
201201
}
202202

@@ -325,9 +325,13 @@ protected function processRules(
325325

326326
$found = true;
327327

328-
$passed = ($param === false && $rule !== 'field_exists')
329-
? $set->{$rule}($value, $error)
330-
: $set->{$rule}($value, $param, $data, $error, $field);
328+
if ($rule === 'field_exists') {
329+
$passed = $set->{$rule}($value, $param, $data, $error, $originalField);
330+
} else {
331+
$passed = ($param === false)
332+
? $set->{$rule}($value, $error)
333+
: $set->{$rule}($value, $param, $data, $error, $field);
334+
}
331335

332336
break;
333337
}

tests/system/Validation/RulesTest.php

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class RulesTest extends CIUnitTestCase
4747
protected function setUp(): void
4848
{
4949
parent::setUp();
50+
5051
$this->validation = new Validation((object) $this->config, Services::renderer());
5152
$this->validation->reset();
5253
}
@@ -863,32 +864,93 @@ public function testFieldExists(array $rules, array $data, bool $expected): void
863864

864865
public static function provideFieldExists(): iterable
865866
{
867+
// Do not use `foo`, because there is a lang file `Foo`, and
868+
// the error message may be messed up.
866869
yield from [
867-
[
868-
['foo' => 'field_exists'],
869-
['foo' => ''],
870+
'empty string' => [
871+
['fiz' => 'field_exists'],
872+
['fiz' => ''],
870873
true,
871874
],
872-
[
873-
['foo' => 'field_exists'],
874-
['foo' => null],
875+
'null' => [
876+
['fiz' => 'field_exists'],
877+
['fiz' => null],
875878
true,
876879
],
877-
[
878-
['foo' => 'field_exists'],
879-
['foo' => false],
880+
'false' => [
881+
['fiz' => 'field_exists'],
882+
['fiz' => false],
880883
true,
881884
],
882-
[
883-
['foo' => 'field_exists'],
884-
['foo' => []],
885+
'empty array' => [
886+
['fiz' => 'field_exists'],
887+
['fiz' => []],
885888
true,
886889
],
887-
[
888-
['foo' => 'field_exists'],
890+
'empty data' => [
891+
['fiz' => 'field_exists'],
889892
[],
890893
false,
891894
],
895+
'dot array syntax: true' => [
896+
['fiz.bar' => 'field_exists'],
897+
[
898+
'fiz' => ['bar' => null],
899+
],
900+
true,
901+
],
902+
'dot array syntax: false' => [
903+
['fiz.bar' => 'field_exists'],
904+
[],
905+
false,
906+
],
907+
'dot array syntax asterisk: true' => [
908+
['fiz.*.baz' => 'field_exists'],
909+
[
910+
'fiz' => [
911+
'bar' => [
912+
'baz' => null,
913+
],
914+
],
915+
],
916+
true,
917+
],
918+
'dot array syntax asterisk: false' => [
919+
['fiz.*.baz' => 'field_exists'],
920+
[
921+
'fiz' => [
922+
'bar' => [
923+
'baz' => null,
924+
],
925+
'hoge' => [
926+
// 'baz' is missing.
927+
],
928+
],
929+
],
930+
false,
931+
],
892932
];
893933
}
934+
935+
public function testFieldExistsErrorMessage(): void
936+
{
937+
$this->validation->setRules(['fiz.*.baz' => 'field_exists']);
938+
$data = [
939+
'fiz' => [
940+
'bar' => [
941+
'baz' => null,
942+
],
943+
'hoge' => [
944+
// 'baz' is missing.
945+
],
946+
],
947+
];
948+
949+
$this->assertFalse($this->validation->run($data));
950+
$this->assertSame(
951+
// This errror message is not perfect.
952+
['fiz.bar.baz' => 'The fiz.*.baz field must exist.'],
953+
$this->validation->getErrors()
954+
);
955+
}
894956
}

0 commit comments

Comments
 (0)