Skip to content

Commit

Permalink
update - validation only provided elements
Browse files Browse the repository at this point in the history
According to codeigniter4#1559 I write some code which allows to filter validationRules to that elements which are provided in $data.

----

Allows to filter validation rules to only that elements which are in $data passed to update method
If you'd like to check only fields passed in $data during update just call:
$this->update($your_id, $your_data, true);


if there is 5 rules in your $validation_rules and  only two of them in $your_data array then only that two elements will be checked in validation process if you pass true as a 3rd arg (if you don't provide it or set to false then update will check every rule as is now). 

Useful: i.e. you want to only update user nickname or password instead of passing all user attributes.
  • Loading branch information
nowackipawel authored Nov 30, 2018
1 parent 1680e90 commit 946c9ae
Showing 1 changed file with 32 additions and 13 deletions.
45 changes: 32 additions & 13 deletions system/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -683,20 +683,16 @@ public function insertBatch($set = null, $escape = null, $batchSize = 100, $test
* Updates a single record in $this->table. If an object is provided,
* it will attempt to convert it into an array.
*
* @param integer|array|string $id
* @param array|object $data
* @param integer|array|string $id
* @param array|object $data
* @param boolean $validation_filter - will validate only data which are in $data
*
* @return boolean
*/
public function update($id = null, $data = null)
public function update($id = null, $data = null, bool $validation_filter = false)
{
$escape = null;

if (is_numeric($id))
{
$id = [$id];
}

if (empty($data))
{
$data = $this->tempData['data'] ?? null;
Expand All @@ -723,7 +719,7 @@ public function update($id = null, $data = null)
// Validate data before saving.
if ($this->skipValidation === false)
{
if ($this->validate($data) === false)
if ($this->validate($data, $validation_filter) === false)
{
return false;
}
Expand Down Expand Up @@ -752,9 +748,30 @@ public function update($id = null, $data = null)

$builder = $this->builder();

if ($id)
if (is_numeric($id) || (!empty($id) && is_string($id)))
{
$builder = $builder->whereIn($this->table . '.' . $this->primaryKey, $id);
$builder = $builder->where($this->table.'.'.$this->primaryKey, $id);
}
elseif (!empty($id) && is_array($id))
{
if(array_keys($id) === range(0, count($id) -1))
{
$builder = $builder->whereIn($this->table.'.'.$this->primaryKey, $id);
}
else
{
foreach ($id as $key => $value)
{
if(!empty($value) && is_array($value))
{
$builder = $builder->whereIn($this->table.'.'.$key, $value);
}
else
{
$builder = $builder->where($this->table.'.'.$key, $value);
}
}
}
}

// Must use the set() method to ensure objects get converted to arrays
Expand Down Expand Up @@ -1235,10 +1252,11 @@ public function skipValidation(bool $skip = true)
* specified in the class property, $validationRules.
*
* @param array $data
* @param bool $validation_filter
*
* @return boolean
*/
public function validate($data): bool
public function validate($data, bool $validation_filter = false): bool
{
if ($this->skipValidation === true || empty($this->validationRules) || empty($data))
{
Expand All @@ -1260,9 +1278,10 @@ public function validate($data): bool
}
else
{
$validation_rules = $validation_filter ? array_intersect_key($this->validationRules, $data) : $this->validationRules;
// Replace any placeholders (i.e. {id}) in the rules with
// the value found in $data, if exists.
$rules = $this->fillPlaceholders($this->validationRules, $data);
$rules = $this->fillPlaceholders($validation_rules, $data);

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

0 comments on commit 946c9ae

Please sign in to comment.