Skip to content

Commit

Permalink
Merge pull request #4184 from paulbalandan/if-exist-validation
Browse files Browse the repository at this point in the history
new array helper: array_flatten_with_dots
  • Loading branch information
paulbalandan committed Jan 29, 2021
2 parents a2de32f + d4f6ca8 commit 49520c7
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 56 deletions.
46 changes: 38 additions & 8 deletions system/Helpers/array_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,11 @@ function array_deep_search($key, array $array)
* Both arrays of objects and arrays of array can be sorted.
*
* Example:
* array_sort_by_multiple_keys($players,
* [
* 'team.hierarchy' => SORT_ASC,
* 'position' => SORT_ASC,
* 'name' => SORT_STRING,
* ]
* );
* array_sort_by_multiple_keys($players, [
* 'team.hierarchy' => SORT_ASC,
* 'position' => SORT_ASC,
* 'name' => SORT_STRING,
* ]);
*
* The '.' dot operator in the column name indicates a deeper array or
* object level. In principle, any number of sublevels could be used,
Expand Down Expand Up @@ -180,7 +178,7 @@ function array_sort_by_multiple_keys(array &$array, array $sortColumns): bool
{
$carry[$index] = $object->$keySegment;
}

continue;
}

Expand All @@ -200,3 +198,35 @@ function array_sort_by_multiple_keys(array &$array, array $sortColumns): bool
return array_multisort(...$tempArray);
}
}

if (! function_exists('array_flatten_with_dots'))
{
/**
* Flatten a multidimensional array using dots as separators.
*
* @param iterable $array The multi-dimensional array
* @param string $id Something to initially prepend to the flattened keys
*
* @return array The flattened array
*/
function array_flatten_with_dots(iterable $array, string $id = ''): array
{
$flattened = [];

foreach ($array as $key => $value)
{
$newKey = $id . $key;

if (is_array($value))
{
$flattened = array_merge($flattened, array_flatten_with_dots($value, $newKey . '.'));
}
else
{
$flattened[$newKey] = $value;
}
}

return $flattened;
}
}
11 changes: 6 additions & 5 deletions system/Validation/Validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public function check($value, string $rule, array $errors = []): bool
* @param string|null $label
* @param string|array $value Value to be validated, can be a string or an array
* @param array|null $rules
* @param array $data // All of the fields to check.
* @param array $data All of the fields to check.
*
* @return boolean
*/
Expand All @@ -213,15 +213,16 @@ protected function processRules(string $field, string $label = null, $value, $ru
throw new InvalidArgumentException('You must supply the parameter: data.');
}

// If the if_exist rule is defined...
if (in_array('if_exist', $rules, true))
{
// and the current field does not exists in the input data
// we can return true. Ignoring all other rules to this field.
if (! array_key_exists($field, $data))
// If the if_exist rule is defined
// and the current field does not exist in the input data
// we can return true, ignoring all other rules to this field.
if (! array_key_exists($field, array_flatten_with_dots($data)))
{
return true;
}

// Otherwise remove the if_exist rule and continue the process
$rules = array_diff($rules, ['if_exist']);
}
Expand Down
111 changes: 104 additions & 7 deletions tests/system/Helpers/ArrayHelperTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<?php namespace CodeIgniter\Helpers;
<?php

class ArrayHelperTest extends \CodeIgniter\Test\CIUnitTestCase
namespace CodeIgniter\Helpers;

use CodeIgniter\Test\CIUnitTestCase;

class ArrayHelperTest extends CIUnitTestCase
{
protected function setUp(): void
{
Expand Down Expand Up @@ -182,7 +186,8 @@ public function testArraySortByMultipleKeysWithArray($data, $sortColumns, $expec
public function testArraySortByMultipleKeysWithObjects($data, $sortColumns, $expected)
{
// Morph to objects
foreach($data as $index => $dataSet){
foreach ($data as $index => $dataSet)
{
$data[$index] = (object) $dataSet;
}

Expand Down Expand Up @@ -228,19 +233,17 @@ public function testArraySortByMultipleKeysFailsInconsistentArraySizes($data)
{
$this->expectException('ValueError');
}

$this->expectExceptionMessage('Array sizes are inconsistent');

$sortColumns = [
'team.orders' => SORT_ASC,
'positions' => SORT_ASC,
];

$success = array_sort_by_multiple_keys($data, $sortColumns);
array_sort_by_multiple_keys($data, $sortColumns);
}

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

public static function deepSearchProvider()
{
return [
Expand Down Expand Up @@ -319,4 +322,98 @@ public static function sortByMultipleKeysProvider()
],
];
}

/**
* @dataProvider arrayFlattenProvider
*
* @param iterable $input
* @param iterable $expected
*
* @return void
*/
public function testArrayFlattening($input, $expected): void
{
$this->assertSame($expected, array_flatten_with_dots($input));
}

public function arrayFlattenProvider(): iterable
{
yield 'normal' => [
[
'id' => '12',
'user' => [
'first_name' => 'john',
'last_name' => 'smith',
'age' => '26 years',
],
],
[
'id' => '12',
'user.first_name' => 'john',
'user.last_name' => 'smith',
'user.age' => '26 years',
],
];

yield 'many-levels' => [
[
'foo' => 1,
'bar' => [
'bax' => [
'baz' => 2,
'biz' => 3,
],
],
'baz' => [
'fizz' => 4,
],
],
[
'foo' => 1,
'bar.bax.baz' => 2,
'bar.bax.biz' => 3,
'baz.fizz' => 4,
],
];

yield 'with-empty-arrays' => [
[
'foo' => 'bar',
'baz' => [],
'bar' => [
'fizz' => 'buzz',
'nope' => 'yeah',
'why' => [],
],
],
[
'foo' => 'bar',
'bar.fizz' => 'buzz',
'bar.nope' => 'yeah',
],
];

yield 'with-mixed-empty' => [
[
'foo' => 1,
'' => [
'bar' => 2,
'baz' => 3,
],
0 => [
'fizz' => 4,
],
1 => [
'buzz' => 5,
],
],
[
'foo' => 1,
'.bar' => 2,
'.baz' => 3,
'0.fizz' => 4,
'1.buzz' => 5,
],
];
}
}
41 changes: 31 additions & 10 deletions tests/system/Validation/RulesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,17 @@ public function ifExistProvider()
[],
true,
],
// Testing for multi-dimensional data
[
['foo.bar' => 'if_exist|required'],
['foo' => ['bar' => '']],
false,
],
[
['foo.bar' => 'if_exist|required'],
['foo' => []],
true,
],
];
}

Expand Down Expand Up @@ -1496,10 +1507,15 @@ public function inListProvider()
public function testRequiredWith($field, $check, $expected = false)
{
$data = [
'foo' => 'bar',
'bar' => 'something',
'baz' => null,
'array' => ['nonEmptyField1'=>'value1','nonEmptyField2'=>'value2', 'emptyField1'=>null, 'emptyField2'=>null],
'foo' => 'bar',
'bar' => 'something',
'baz' => null,
'array' => [
'nonEmptyField1' => 'value1',
'nonEmptyField2' => 'value2',
'emptyField1' => null,
'emptyField2' => null,
],
];

$this->validation->setRules([
Expand Down Expand Up @@ -1578,10 +1594,15 @@ public function requiredWithProvider()
public function testRequiredWithout($field, $check, $expected = false)
{
$data = [
'foo' => 'bar',
'bar' => 'something',
'baz' => null,
'array' => ['nonEmptyField1'=>'value1','nonEmptyField2'=>'value2', 'emptyField1'=>null, 'emptyField2'=>null],
'foo' => 'bar',
'bar' => 'something',
'baz' => null,
'array' => [
'nonEmptyField1' => 'value1',
'nonEmptyField2' => 'value2',
'emptyField1' => null,
'emptyField2' => null,
],
];

$this->validation->setRules([
Expand Down Expand Up @@ -1636,11 +1657,11 @@ public function requiredWithoutProvider()
'array.nonEmptyField2',
true,
],
[
[
'array.nonEmptyField1',
'array.nonEmptyField2',
true,
],
],
];
}

Expand Down
Loading

0 comments on commit 49520c7

Please sign in to comment.