Skip to content

Commit 73d6ae6

Browse files
authored
Merge pull request #2897 from jreklund/validation-placeholders-again
Make validation placeholders always available
2 parents b83f16c + 5a81997 commit 73d6ae6

5 files changed

Lines changed: 432 additions & 300 deletions

File tree

system/Model.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,10 +1439,6 @@ public function validate($data): bool
14391439
return true;
14401440
}
14411441

1442-
// Replace any placeholders (i.e. {id}) in the rules with
1443-
// the value found in $data, if exists.
1444-
$rules = $this->fillPlaceholders($rules, $data);
1445-
14461442
$this->validation->setRules($rules, $this->validationMessages);
14471443
$valid = $this->validation->run($data, null, $this->DBGroup);
14481444

@@ -1495,6 +1491,10 @@ protected function cleanValidationRules(array $rules, array $data = null): array
14951491
*
14961492
* 'required|is_unique[users,email,id,13]'
14971493
*
1494+
* @codeCoverageIgnore
1495+
*
1496+
* @deprecated use fillPlaceholders($rules, $data) from Validation instead
1497+
*
14981498
* @param array $rules
14991499
* @param array $data
15001500
*

system/Validation/Validation.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ public function run(array $data = null, string $group = null, string $db_group =
155155
return false;
156156
}
157157

158+
// Replace any placeholders (i.e. {id}) in the rules with
159+
// the value found in $data, if exists.
160+
$this->rules = $this->fillPlaceholders($this->rules, $data);
161+
158162
// Need this for searching arrays in validation.
159163
helper('array');
160164

@@ -603,6 +607,64 @@ public function loadRuleGroup(string $group = null)
603607
return $this->rules;
604608
}
605609

610+
//--------------------------------------------------------------------
611+
612+
/**
613+
* Replace any placeholders within the rules with the values that
614+
* match the 'key' of any properties being set. For example, if
615+
* we had the following $data array:
616+
*
617+
* [ 'id' => 13 ]
618+
*
619+
* and the following rule:
620+
*
621+
* 'required|is_unique[users,email,id,{id}]'
622+
*
623+
* The value of {id} would be replaced with the actual id in the form data:
624+
*
625+
* 'required|is_unique[users,email,id,13]'
626+
*
627+
* @param array $rules
628+
* @param array $data
629+
*
630+
* @return array
631+
*/
632+
protected function fillPlaceholders(array $rules, array $data): array
633+
{
634+
$replacements = [];
635+
636+
foreach ($data as $key => $value)
637+
{
638+
$replacements["{{$key}}"] = $value;
639+
}
640+
641+
if (! empty($replacements))
642+
{
643+
foreach ($rules as &$rule)
644+
{
645+
if (is_array($rule))
646+
{
647+
foreach ($rule as &$row)
648+
{
649+
// Should only be an `errors` array
650+
// which doesn't take placeholders.
651+
if (is_array($row))
652+
{
653+
continue;
654+
}
655+
656+
$row = strtr($row, $replacements);
657+
}
658+
continue;
659+
}
660+
661+
$rule = strtr($rule, $replacements);
662+
}
663+
}
664+
665+
return $rules;
666+
}
667+
606668
//--------------------------------------------------------------------
607669
//--------------------------------------------------------------------
608670
// Errors

tests/system/Validation/UniqueRulesTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,35 @@ public function testIsUniqueIgnoresParams()
112112
}
113113

114114
//--------------------------------------------------------------------
115+
116+
/**
117+
* @group DatabaseLive
118+
*/
119+
public function testIsUniqueIgnoresParamsPlaceholders()
120+
{
121+
$this->hasInDatabase('user', [
122+
'name' => 'Derek',
123+
'email' => 'derek@world.co.uk',
124+
'country' => 'GB',
125+
]);
126+
127+
$db = Database::connect();
128+
$row = $db->table('user')
129+
->limit(1)
130+
->get()
131+
->getRow();
132+
133+
$data = [
134+
'id' => $row->id,
135+
'email' => 'derek@world.co.uk',
136+
];
137+
138+
$this->validation->setRules([
139+
'email' => "is_unique[user.email,id,{id}]",
140+
]);
141+
142+
$this->assertTrue($this->validation->run($data));
143+
}
144+
145+
//--------------------------------------------------------------------
115146
}

0 commit comments

Comments
 (0)