Skip to content

Commit 446aa0b

Browse files
authored
Merge pull request #8639 from kenjis/improve-validation-error-msg
refactor: improve Validation Placeholder error message
2 parents 5211abf + 56990e6 commit 446aa0b

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

system/Validation/Validation.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,9 @@ protected function fillPlaceholders(array $rules, array $data): array
790790
// Check if the validation rule for the placeholder exists
791791
if ($placeholderRules === null) {
792792
throw new LogicException(
793-
'No validation rules for the placeholder: ' . $field
793+
'No validation rules for the placeholder: "' . $field
794+
. '". You must set the validation rules for the field.'
795+
. ' See <https://codeigniter4.github.io/userguide/libraries/validation.html#validation-placeholders>.'
794796
);
795797
}
796798

tests/system/Validation/StrictRules/DatabaseRelatedRulesTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Config\Database;
1818
use Config\Services;
1919
use InvalidArgumentException;
20+
use LogicException;
2021
use Tests\Support\Validation\TestRules;
2122

2223
/**
@@ -139,6 +140,34 @@ public function testIsUniqueWithIgnoreValuePlaceholder(): void
139140
$this->assertTrue($this->validation->run($data));
140141
}
141142

143+
public function testIsUniqueWithPlaceholderAndNoValidationRulesForIt(): void
144+
{
145+
$this->expectException(LogicException::class);
146+
$this->expectExceptionMessage('No validation rules for the placeholder: "id". You must set the validation rules for the field.');
147+
148+
$this->hasInDatabase('user', [
149+
'name' => 'Derek',
150+
'email' => '[email protected]',
151+
'country' => 'GB',
152+
]);
153+
154+
$row = Database::connect()
155+
->table('user')
156+
->limit(1)
157+
->get()
158+
->getRow();
159+
160+
$data = [
161+
'id' => $row->id,
162+
'email' => '[email protected]',
163+
];
164+
165+
$this->validation->setRules([
166+
'email' => 'is_unique[user.email,id,{id}]',
167+
]);
168+
$this->validation->run($data);
169+
}
170+
142171
public function testIsUniqueByManualRun(): void
143172
{
144173
Database::connect()

user_guide_src/source/libraries/validation.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,15 +517,18 @@ Validation Placeholders
517517
=======================
518518

519519
The Validation class provides a simple method to replace parts of your rules based on data that's being passed into it. This
520-
sounds fairly obscure but can be especially handy with the ``is_unique`` validation rule. Placeholders are simply
520+
sounds fairly obscure but can be especially handy with the ``is_unique`` validation rule.
521+
522+
Placeholders are simply
521523
the name of the field (or array key) that was passed in as ``$data`` surrounded by curly brackets. It will be
522524
replaced by the **value** of the matched incoming field. An example should clarify this:
523525

524526
.. literalinclude:: validation/020.php
525527
:lines: 2-
526528

527-
.. note:: Since v4.3.5, you must set the validation rules for the placeholder
528-
field (the ``id`` field in the sample code above) for security.
529+
.. warning:: Since v4.3.5, you must set the validation rules for the placeholder
530+
field (the ``id`` field in the sample code above) for security reasons. Because
531+
attackers can send any data to your application.
529532

530533
In this set of rules, it states that the email address should be unique in the database, except for the row
531534
that has an id matching the placeholder's value. Assuming that the form POST data had the following:

0 commit comments

Comments
 (0)