Skip to content

Commit c830d5f

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into 4.6
2 parents b837ab9 + 11d9721 commit c830d5f

File tree

7 files changed

+118
-49
lines changed

7 files changed

+118
-49
lines changed

rector.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector;
2424
use Rector\CodeQuality\Rector\If_\ShortenElseIfRector;
2525
use Rector\CodeQuality\Rector\If_\SimplifyIfElseToTernaryRector;
26-
use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector;
2726
use Rector\CodeQuality\Rector\Ternary\TernaryEmptyArrayArrayDimFetchToCoalesceRector;
28-
use Rector\CodeQuality\Rector\Ternary\UnnecessaryTernaryExpressionRector;
2927
use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector;
3028
use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector;
3129
use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
@@ -189,14 +187,12 @@
189187
ChangeNestedForeachIfsToEarlyContinueRector::class,
190188
ChangeIfElseValueAssignToEarlyReturnRector::class,
191189
CombineIfRector::class,
192-
SimplifyIfReturnBoolRector::class,
193190
InlineIfToExplicitIfRector::class,
194191
PreparedValueToEarlyReturnRector::class,
195192
ShortenElseIfRector::class,
196193
SimplifyIfElseToTernaryRector::class,
197194
UnusedForeachValueToArrayKeysRector::class,
198195
ChangeArrayPushToArrayAssignRector::class,
199-
UnnecessaryTernaryExpressionRector::class,
200196
RemoveErrorSuppressInTryCatchStmtsRector::class,
201197
FuncGetArgsToVariadicParamRector::class,
202198
MakeInheritedMethodVisibilitySameAsParentRector::class,
@@ -220,4 +216,4 @@
220216
// keep '\\' prefix string on string '\Foo\Bar'
221217
StringClassNameToClassConstantRector::SHOULD_KEEP_PRE_SLASH => true,
222218
])
223-
->withCodeQualityLevel(9);
219+
->withCodeQualityLevel(14);

system/Config/Services.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ public static function email($config = null, bool $getShared = true)
230230
return static::getSharedInstance('email', $config);
231231
}
232232

233-
if (empty($config) || ! (is_array($config) || $config instanceof EmailConfig)) {
233+
if (empty($config) || (! is_array($config) && ! $config instanceof EmailConfig)) {
234234
$config = config(EmailConfig::class);
235235
}
236236

system/Images/Handlers/ImageMagickHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function __construct($config = null)
4242
{
4343
parent::__construct($config);
4444

45-
if (! (extension_loaded('imagick') || class_exists(Imagick::class))) {
45+
if (! extension_loaded('imagick') && ! class_exists(Imagick::class)) {
4646
throw ImageException::forMissingExtension('IMAGICK'); // @codeCoverageIgnore
4747
}
4848

system/Session/Handlers/DatabaseHandler.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,9 @@ public function destroy($id): bool
282282
#[ReturnTypeWillChange]
283283
public function gc($max_lifetime)
284284
{
285-
$separator = ' ';
286-
$interval = implode($separator, ['', "{$max_lifetime} second", '']);
287-
288285
return $this->db->table($this->table)->where(
289286
'timestamp <',
290-
"now() - INTERVAL {$interval}",
287+
"now() - INTERVAL {$max_lifetime} second",
291288
false
292289
)->delete() ? 1 : $this->fail();
293290
}

system/Validation/DotArrayFilter.php

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ final class DotArrayFilter
2121
/**
2222
* Creates a new array with only the elements specified in dot array syntax.
2323
*
24-
* This code comes from the dot_array_search() function.
25-
*
2624
* @param array $indexes The dot array syntax pattern to use for filtering.
2725
* @param array $array The array to filter.
2826
*
@@ -33,20 +31,14 @@ public static function run(array $indexes, array $array): array
3331
$result = [];
3432

3533
foreach ($indexes as $index) {
36-
// See https://regex101.com/r/44Ipql/1
37-
$segments = preg_split(
38-
'/(?<!\\\\)\./',
39-
rtrim($index, '* '),
40-
0,
41-
PREG_SPLIT_NO_EMPTY
42-
);
43-
44-
$segments = array_map(
45-
static fn ($key) => str_replace('\.', '.', $key),
46-
$segments
47-
);
48-
49-
$result = array_replace_recursive($result, self::filter($segments, $array));
34+
$segments = preg_split('/(?<!\\\\)\./', $index, -1, PREG_SPLIT_NO_EMPTY);
35+
$segments = array_map(static fn ($key) => str_replace('\.', '.', $key), $segments);
36+
37+
$filteredArray = self::filter($segments, $array);
38+
39+
if ($filteredArray !== []) {
40+
$result = array_replace_recursive($result, $filteredArray);
41+
}
5042
}
5143

5244
return $result;
@@ -62,53 +54,54 @@ public static function run(array $indexes, array $array): array
6254
*/
6355
private static function filter(array $indexes, array $array): array
6456
{
65-
// If index is empty, returns empty array.
57+
// If there are no indexes left, return an empty array
6658
if ($indexes === []) {
6759
return [];
6860
}
6961

70-
// Grab the current index.
62+
// Get the current index
7163
$currentIndex = array_shift($indexes);
7264

65+
// If the current index doesn't exist and is not a wildcard, return an empty array
7366
if (! isset($array[$currentIndex]) && $currentIndex !== '*') {
7467
return [];
7568
}
7669

77-
// Handle Wildcard (*)
70+
// Handle the wildcard '*' at the current level
7871
if ($currentIndex === '*') {
79-
$answer = [];
72+
$result = [];
8073

74+
// Iterate over all keys at this level
8175
foreach ($array as $key => $value) {
82-
if (! is_array($value)) {
83-
continue;
84-
}
85-
86-
$result = self::filter($indexes, $value);
87-
88-
if ($result !== []) {
89-
$answer[$key] = $result;
76+
if ($indexes === []) {
77+
// If no indexes are left, capture the entire value
78+
$result[$key] = $value;
79+
} elseif (is_array($value)) {
80+
// If there are still indexes left, continue filtering recursively
81+
$filtered = self::filter($indexes, $value);
82+
if ($filtered !== []) {
83+
$result[$key] = $filtered;
84+
}
9085
}
9186
}
9287

93-
return $answer;
88+
return $result;
9489
}
9590

96-
// If this is the last index, make sure to return it now,
97-
// and not try to recurse through things.
91+
// If this is the last index, return the value
9892
if ($indexes === []) {
99-
return [$currentIndex => $array[$currentIndex]];
93+
return [$currentIndex => $array[$currentIndex] ?? []];
10094
}
10195

102-
// Do we need to recursively filter this value?
103-
if (is_array($array[$currentIndex]) && $array[$currentIndex] !== []) {
104-
$result = self::filter($indexes, $array[$currentIndex]);
96+
// If the current value is an array, recursively filter it
97+
if (is_array($array[$currentIndex])) {
98+
$filtered = self::filter($indexes, $array[$currentIndex]);
10599

106-
if ($result !== []) {
107-
return [$currentIndex => $result];
100+
if ($filtered !== []) {
101+
return [$currentIndex => $filtered];
108102
}
109103
}
110104

111-
// Otherwise, not found.
112105
return [];
113106
}
114107
}

tests/system/Validation/ValidationTest.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use CodeIgniter\Validation\Exceptions\ValidationException;
2323
use Config\App;
2424
use Config\Services;
25+
use Generator;
2526
use PHPUnit\Framework\Attributes\DataProvider;
2627
use PHPUnit\Framework\Attributes\Group;
2728
use PHPUnit\Framework\ExpectationFailedException;
@@ -1826,4 +1827,84 @@ public function testRuleWithAsteriskToMultiDimensionalArray(): void
18261827
$this->validation->getErrors()
18271828
);
18281829
}
1830+
1831+
/**
1832+
* @param array<string, mixed> $data
1833+
* @param array<string, string> $rules
1834+
* @param array<string, mixed> $expectedData
1835+
*
1836+
* @see https://github.com/codeigniter4/CodeIgniter4/issues/9219
1837+
*/
1838+
#[DataProvider('provideMultipleAsterisk')]
1839+
public function testRuleWithMultipleAsterisk(
1840+
array $data = [],
1841+
array $rules = [],
1842+
bool $expectedCheck = false,
1843+
array $expectedData = []
1844+
): void {
1845+
$this->validation->setRules($rules);
1846+
1847+
$this->assertSame($expectedCheck, $this->validation->run($data));
1848+
$this->assertSame($expectedData, $this->validation->getValidated());
1849+
}
1850+
1851+
public static function provideMultipleAsterisk(): Generator
1852+
{
1853+
yield 'success' => [
1854+
[
1855+
'dates' => [
1856+
23 => [
1857+
45 => 'Its Mee!',
1858+
],
1859+
],
1860+
'foo' => [
1861+
'bar' => [
1862+
'data' => [
1863+
'name' => 'John Doe',
1864+
'age' => 29,
1865+
'location' => 'Indonesia',
1866+
],
1867+
],
1868+
],
1869+
],
1870+
[
1871+
'dates.*.*' => 'required',
1872+
'foo.*.*.*' => 'required',
1873+
],
1874+
true,
1875+
[
1876+
'dates' => [
1877+
23 => [
1878+
45 => 'Its Mee!',
1879+
],
1880+
],
1881+
'foo' => [
1882+
'bar' => [
1883+
'data' => [
1884+
'name' => 'John Doe',
1885+
'age' => 29,
1886+
'location' => 'Indonesia',
1887+
],
1888+
],
1889+
],
1890+
],
1891+
];
1892+
1893+
yield 'failed' => [
1894+
[
1895+
'foo' => [
1896+
'bar' => [
1897+
'data' => [
1898+
'name' => '',
1899+
'age' => 29,
1900+
'location' => 'Indonesia',
1901+
],
1902+
],
1903+
],
1904+
],
1905+
['foo.*.*.*' => 'required'],
1906+
false,
1907+
[],
1908+
];
1909+
}
18291910
}

user_guide_src/source/changelogs/v4.5.6.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Bugs Fixed
3131
**********
3232
- **Session Library:** The session initialization debug message now uses the correct log type "debug" instead of "info".
3333

34+
- **Validation:** Fixed the `getValidated()` method that did not return valid data when validation rules used multiple asterisks.
35+
3436
See the repo's
3537
`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_
3638
for a complete list of bugs fixed.

0 commit comments

Comments
 (0)