Skip to content

Commit

Permalink
feat: add dot array syntax support
Browse files Browse the repository at this point in the history
  • Loading branch information
kenjis committed Nov 8, 2023
1 parent a0cacb4 commit eda462a
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 19 deletions.
5 changes: 5 additions & 0 deletions system/Validation/Rules.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace CodeIgniter\Validation;

use CodeIgniter\Helpers\Array\ArrayHelper;
use Config\Database;
use InvalidArgumentException;

Expand Down Expand Up @@ -443,6 +444,10 @@ public function field_exists(
?string $error = null,
?string $field = null
): bool {
if (strpos($field, '.') !== false) {
return ArrayHelper::dotKeyExists($field, $data);
}

return array_key_exists($field, $data);
}
}
5 changes: 5 additions & 0 deletions system/Validation/StrictRules/Rules.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace CodeIgniter\Validation\StrictRules;

use CodeIgniter\Helpers\Array\ArrayHelper;
use CodeIgniter\Validation\Rules as NonStrictRules;
use Config\Database;

Expand Down Expand Up @@ -419,6 +420,10 @@ public function field_exists(
?string $error = null,
?string $field = null
): bool {
if (strpos($field, '.') !== false) {
return ArrayHelper::dotKeyExists($field, $data);
}

return array_key_exists($field, $data);
}
}
14 changes: 9 additions & 5 deletions system/Validation/Validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup

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

continue;
}
Expand All @@ -196,7 +196,7 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup
}
} else {
// Process single field
$this->processRules($field, $setup['label'] ?? $field, $values, $rules, $data);
$this->processRules($field, $setup['label'] ?? $field, $values, $rules, $data, $field);
}
}

Expand Down Expand Up @@ -325,9 +325,13 @@ protected function processRules(

$found = true;

$passed = ($param === false && $rule !== 'field_exists')
? $set->{$rule}($value, $error)
: $set->{$rule}($value, $param, $data, $error, $field);
if ($rule === 'field_exists') {
$passed = $set->{$rule}($value, $param, $data, $error, $originalField);
} else {
$passed = ($param === false)
? $set->{$rule}($value, $error)
: $set->{$rule}($value, $param, $data, $error, $field);
}

break;
}
Expand Down
90 changes: 76 additions & 14 deletions tests/system/Validation/RulesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class RulesTest extends CIUnitTestCase
protected function setUp(): void
{
parent::setUp();

$this->validation = new Validation((object) $this->config, Services::renderer());
$this->validation->reset();
}
Expand Down Expand Up @@ -863,32 +864,93 @@ public function testFieldExists(array $rules, array $data, bool $expected): void

public static function provideFieldExists(): iterable
{
// Do not use `foo`, because there is a lang file `Foo`, and
// the error message may be messed up.
yield from [
[
['foo' => 'field_exists'],
['foo' => ''],
'empty string' => [
['fiz' => 'field_exists'],
['fiz' => ''],
true,
],
[
['foo' => 'field_exists'],
['foo' => null],
'null' => [
['fiz' => 'field_exists'],
['fiz' => null],
true,
],
[
['foo' => 'field_exists'],
['foo' => false],
'false' => [
['fiz' => 'field_exists'],
['fiz' => false],
true,
],
[
['foo' => 'field_exists'],
['foo' => []],
'empty array' => [
['fiz' => 'field_exists'],
['fiz' => []],
true,
],
[
['foo' => 'field_exists'],
'empty data' => [
['fiz' => 'field_exists'],
[],
false,
],
'dot array syntax: true' => [
['fiz.bar' => 'field_exists'],
[
'fiz' => ['bar' => null],
],
true,
],
'dot array syntax: false' => [
['fiz.bar' => 'field_exists'],
[],
false,
],
'dot array syntax asterisk: true' => [
['fiz.*.baz' => 'field_exists'],
[
'fiz' => [
'bar' => [
'baz' => null,
],
],
],
true,
],
'dot array syntax asterisk: false' => [
['fiz.*.baz' => 'field_exists'],
[
'fiz' => [
'bar' => [
'baz' => null,
],
'hoge' => [
// 'baz' is missing.
],
],
],
false,
],
];
}

public function testFieldExistsErrorMessage(): void
{
$this->validation->setRules(['fiz.*.baz' => 'field_exists']);
$data = [
'fiz' => [
'bar' => [
'baz' => null,
],
'hoge' => [
// 'baz' is missing.
],
],
];

$this->assertFalse($this->validation->run($data));
$this->assertSame(
// This errror message is not perfect.
['fiz.bar.baz' => 'The fiz.*.baz field must exist.'],
$this->validation->getErrors()
);
}
}

0 comments on commit eda462a

Please sign in to comment.