Skip to content

Commit

Permalink
Merge pull request #2897 from jreklund/validation-placeholders-again
Browse files Browse the repository at this point in the history
Make validation placeholders always available
  • Loading branch information
lonnieezell authored May 1, 2020
2 parents b83f16c + 5a81997 commit 73d6ae6
Show file tree
Hide file tree
Showing 5 changed files with 432 additions and 300 deletions.
8 changes: 4 additions & 4 deletions system/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -1439,10 +1439,6 @@ public function validate($data): bool
return true;
}

// Replace any placeholders (i.e. {id}) in the rules with
// the value found in $data, if exists.
$rules = $this->fillPlaceholders($rules, $data);

$this->validation->setRules($rules, $this->validationMessages);
$valid = $this->validation->run($data, null, $this->DBGroup);

Expand Down Expand Up @@ -1495,6 +1491,10 @@ protected function cleanValidationRules(array $rules, array $data = null): array
*
* 'required|is_unique[users,email,id,13]'
*
* @codeCoverageIgnore
*
* @deprecated use fillPlaceholders($rules, $data) from Validation instead
*
* @param array $rules
* @param array $data
*
Expand Down
62 changes: 62 additions & 0 deletions system/Validation/Validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ public function run(array $data = null, string $group = null, string $db_group =
return false;
}

// Replace any placeholders (i.e. {id}) in the rules with
// the value found in $data, if exists.
$this->rules = $this->fillPlaceholders($this->rules, $data);

// Need this for searching arrays in validation.
helper('array');

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

//--------------------------------------------------------------------

/**
* Replace any placeholders within the rules with the values that
* match the 'key' of any properties being set. For example, if
* we had the following $data array:
*
* [ 'id' => 13 ]
*
* and the following rule:
*
* 'required|is_unique[users,email,id,{id}]'
*
* The value of {id} would be replaced with the actual id in the form data:
*
* 'required|is_unique[users,email,id,13]'
*
* @param array $rules
* @param array $data
*
* @return array
*/
protected function fillPlaceholders(array $rules, array $data): array
{
$replacements = [];

foreach ($data as $key => $value)
{
$replacements["{{$key}}"] = $value;
}

if (! empty($replacements))
{
foreach ($rules as &$rule)
{
if (is_array($rule))
{
foreach ($rule as &$row)
{
// Should only be an `errors` array
// which doesn't take placeholders.
if (is_array($row))
{
continue;
}

$row = strtr($row, $replacements);
}
continue;
}

$rule = strtr($rule, $replacements);
}
}

return $rules;
}

//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Errors
Expand Down
31 changes: 31 additions & 0 deletions tests/system/Validation/UniqueRulesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,35 @@ public function testIsUniqueIgnoresParams()
}

//--------------------------------------------------------------------

/**
* @group DatabaseLive
*/
public function testIsUniqueIgnoresParamsPlaceholders()
{
$this->hasInDatabase('user', [
'name' => 'Derek',
'email' => '[email protected]',
'country' => 'GB',
]);

$db = Database::connect();
$row = $db->table('user')
->limit(1)
->get()
->getRow();

$data = [
'id' => $row->id,
'email' => '[email protected]',
];

$this->validation->setRules([
'email' => "is_unique[user.email,id,{id}]",
]);

$this->assertTrue($this->validation->run($data));
}

//--------------------------------------------------------------------
}
Loading

0 comments on commit 73d6ae6

Please sign in to comment.