Skip to content

Commit 0643115

Browse files
authored
feat: add new dot-path array helpers (#9990)
* feat: add new dot-syntax helper functions * optimize * add docs * add changelog * update tests
1 parent a7d3c65 commit 0643115

File tree

16 files changed

+1432
-119
lines changed

16 files changed

+1432
-119
lines changed

system/Helpers/Array/ArrayHelper.php

Lines changed: 342 additions & 34 deletions
Large diffs are not rendered by default.

system/Helpers/array_helper.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,72 @@ function dot_array_search(string $index, array $array)
2828
}
2929
}
3030

31+
if (! function_exists('dot_array_has')) {
32+
/**
33+
* Checks if an array key exists using dot syntax.
34+
*
35+
* @param array<array-key, mixed> $array
36+
*/
37+
function dot_array_has(string $index, array $array): bool
38+
{
39+
return ArrayHelper::dotHas($index, $array);
40+
}
41+
}
42+
43+
if (! function_exists('dot_array_set')) {
44+
/**
45+
* Sets an array value using dot syntax.
46+
*
47+
* @param array<array-key, mixed> $array
48+
*/
49+
function dot_array_set(array &$array, string $index, mixed $value): void
50+
{
51+
ArrayHelper::dotSet($array, $index, $value);
52+
}
53+
}
54+
55+
if (! function_exists('dot_array_unset')) {
56+
/**
57+
* Unsets an array value using dot syntax.
58+
*
59+
* @param array<array-key, mixed> $array
60+
*/
61+
function dot_array_unset(array &$array, string $index): bool
62+
{
63+
return ArrayHelper::dotUnset($array, $index);
64+
}
65+
}
66+
67+
if (! function_exists('dot_array_only')) {
68+
/**
69+
* Gets only the specified keys using dot syntax.
70+
*
71+
* @param array<array-key, mixed> $array
72+
* @param list<string>|string $indexes
73+
*
74+
* @return array<array-key, mixed>
75+
*/
76+
function dot_array_only(array $array, array|string $indexes): array
77+
{
78+
return ArrayHelper::dotOnly($array, $indexes);
79+
}
80+
}
81+
82+
if (! function_exists('dot_array_except')) {
83+
/**
84+
* Gets all keys except the specified ones using dot syntax.
85+
*
86+
* @param array<array-key, mixed> $array
87+
* @param list<string>|string $indexes
88+
*
89+
* @return array<array-key, mixed>
90+
*/
91+
function dot_array_except(array $array, array|string $indexes): array
92+
{
93+
return ArrayHelper::dotExcept($array, $indexes);
94+
}
95+
}
96+
3197
if (! function_exists('array_deep_search')) {
3298
/**
3399
* Returns the value of an element at a key in an array of uncertain depth.

system/Validation/Rules.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ public function field_exists(
460460
?string $field = null,
461461
): bool {
462462
if (str_contains($field, '.')) {
463-
return ArrayHelper::dotKeyExists($field, $data);
463+
return ArrayHelper::dotHas($field, $data);
464464
}
465465

466466
return array_key_exists($field, $data);

system/Validation/StrictRules/Rules.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function differs(
5252
}
5353

5454
if (str_contains($field, '.')) {
55-
if (! ArrayHelper::dotKeyExists($field, $data)) {
55+
if (! ArrayHelper::dotHas($field, $data)) {
5656
return false;
5757
}
5858
} elseif (! array_key_exists($field, $data)) {
@@ -245,7 +245,7 @@ public function matches(
245245
}
246246

247247
if (str_contains($field, '.')) {
248-
if (! ArrayHelper::dotKeyExists($field, $data)) {
248+
if (! ArrayHelper::dotHas($field, $data)) {
249249
return false;
250250
}
251251
} elseif (! array_key_exists($field, $data)) {
@@ -386,7 +386,7 @@ public function field_exists(
386386
?string $field = null,
387387
): bool {
388388
if (str_contains($field, '.')) {
389-
return ArrayHelper::dotKeyExists($field, $data);
389+
return ArrayHelper::dotHas($field, $data);
390390
}
391391

392392
return array_key_exists($field, $data);
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <admin@codeigniter.com>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\Helpers\Array;
15+
16+
use CodeIgniter\Exceptions\InvalidArgumentException;
17+
use CodeIgniter\Test\CIUnitTestCase;
18+
use PHPUnit\Framework\Attributes\Group;
19+
20+
/**
21+
* @internal
22+
*/
23+
#[Group('Others')]
24+
final class ArrayHelperDotHasTest extends CIUnitTestCase
25+
{
26+
private array $array = [
27+
'contacts' => [
28+
'friends' => [
29+
['name' => 'Fred Flinstone', 'age' => 20],
30+
['age' => 21], // 'name' key does not exist
31+
],
32+
],
33+
];
34+
35+
public function testDotHas(): void
36+
{
37+
$this->assertFalse(ArrayHelper::dotHas('', $this->array));
38+
$this->assertTrue(ArrayHelper::dotHas('contacts', $this->array));
39+
$this->assertFalse(ArrayHelper::dotHas('not', $this->array));
40+
$this->assertTrue(ArrayHelper::dotHas('contacts.friends', $this->array));
41+
$this->assertFalse(ArrayHelper::dotHas('not.friends', $this->array));
42+
$this->assertTrue(ArrayHelper::dotHas('contacts.friends.0.name', $this->array));
43+
$this->assertFalse(ArrayHelper::dotHas('contacts.friends.1.name', $this->array));
44+
}
45+
46+
public function testDotHasWithEndingWildCard(): void
47+
{
48+
$this->expectException(InvalidArgumentException::class);
49+
$this->expectExceptionMessage('You must set key right after "*". Invalid index: "contacts.*"');
50+
51+
$this->assertTrue(ArrayHelper::dotHas('contacts.*', $this->array));
52+
}
53+
54+
public function testDotHasWithDoubleWildCard(): void
55+
{
56+
$this->expectException(InvalidArgumentException::class);
57+
$this->expectExceptionMessage('You must set key right after "*". Invalid index: "contacts.*.*.age"');
58+
59+
$this->assertTrue(ArrayHelper::dotHas('contacts.*.*.age', $this->array));
60+
}
61+
62+
public function testDotHasWithWildCard(): void
63+
{
64+
$this->assertTrue(ArrayHelper::dotHas('*.friends', $this->array));
65+
$this->assertTrue(ArrayHelper::dotHas('contacts.friends.*.age', $this->array));
66+
$this->assertFalse(ArrayHelper::dotHas('contacts.friends.*.name', $this->array));
67+
$this->assertTrue(ArrayHelper::dotHas('*.friends.*.age', $this->array));
68+
$this->assertFalse(ArrayHelper::dotHas('*.friends.*.name', $this->array));
69+
$this->assertTrue(ArrayHelper::dotHas('contacts.*.0.age', $this->array));
70+
$this->assertTrue(ArrayHelper::dotHas('contacts.*.1.age', $this->array));
71+
$this->assertTrue(ArrayHelper::dotHas('contacts.*.0.name', $this->array));
72+
$this->assertFalse(ArrayHelper::dotHas('contacts.*.1.name', $this->array));
73+
}
74+
}

tests/system/Helpers/Array/ArrayHelperDotKeyExistsTest.php

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)