Skip to content

Commit 661dfee

Browse files
committed
feat: add closure validation rule
1 parent 8ad43f5 commit 661dfee

2 files changed

Lines changed: 37 additions & 3 deletions

File tree

system/Validation/Validation.php

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

1212
namespace CodeIgniter\Validation;
1313

14+
use Closure;
1415
use CodeIgniter\HTTP\IncomingRequest;
1516
use CodeIgniter\HTTP\RequestInterface;
1617
use CodeIgniter\Validation\Exceptions\ValidationException;
@@ -195,7 +196,7 @@ public function check($value, string $rule, array $errors = []): bool
195196
*
196197
* @param array|string $value
197198
* @param array|null $rules
198-
* @param array $data The array of data to validate, with `DBGroup`.
199+
* @param array|null $data The array of data to validate, with `DBGroup`.
199200
* @param string|null $originalField The original asterisk field name like "foo.*.bar".
200201
*/
201202
protected function processRules(
@@ -277,7 +278,7 @@ protected function processRules(
277278
$rules = array_diff($rules, ['permit_empty']);
278279
}
279280

280-
foreach ($rules as $rule) {
281+
foreach ($rules as $i => $rule) {
281282
$isCallable = is_callable($rule);
282283

283284
$passed = false;
@@ -333,7 +334,7 @@ protected function processRules(
333334

334335
// @phpstan-ignore-next-line $error may be set by rule methods.
335336
$this->errors[$field] = $error ?? $this->getErrorMessage(
336-
$rule,
337+
$this->isClosure($rule) ? $i : $rule,
337338
$field,
338339
$label,
339340
$param,
@@ -348,6 +349,14 @@ protected function processRules(
348349
return true;
349350
}
350351

352+
/**
353+
* @param Closure|string $rule
354+
*/
355+
private function isClosure($rule): bool
356+
{
357+
return $rule instanceof Closure;
358+
}
359+
351360
/**
352361
* Is the array a string list `list<string>`?
353362
*/

tests/system/Validation/ValidationTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,31 @@ public function testRunDoesTheBasics(): void
204204
$this->assertFalse($this->validation->run($data));
205205
}
206206

207+
public function testClosureRule(): void
208+
{
209+
$this->validation->setRules(
210+
[
211+
'foo' => ['required', static fn ($value) => $value === 'abc'],
212+
],
213+
[
214+
// Errors
215+
'foo' => [
216+
// Specify the array key for the closure rule.
217+
1 => 'The value is not "abc"',
218+
],
219+
],
220+
);
221+
222+
$data = ['foo' => 'xyz'];
223+
$return = $this->validation->run($data);
224+
225+
$this->assertFalse($return);
226+
$this->assertSame(
227+
['foo' => 'The value is not "abc"'],
228+
$this->validation->getErrors()
229+
);
230+
}
231+
207232
/**
208233
* @see https://github.com/codeigniter4/CodeIgniter4/issues/5368
209234
*

0 commit comments

Comments
 (0)