Skip to content

Commit 3cc029e

Browse files
committed
CHERRY-PICK: [13.x] Add support for SortDirection enum to collections and Arr (#59859)
* Add PHP 8.6 polyfill to Collection * Update Collection methods to support SortDirection enum * Update Arr methods to support SortDirection enum
1 parent c4e9a37 commit 3cc029e

5 files changed

Lines changed: 53 additions & 20 deletions

File tree

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"symfony/mime": "^8.0.0",
5757
"symfony/polyfill-php84": "^1.33",
5858
"symfony/polyfill-php85": "^1.33",
59+
"symfony/polyfill-php86": "^1.36",
5960
"symfony/process": "^7.4.5 || ^8.0.5",
6061
"symfony/routing": "^8.0.0",
6162
"symfony/uid": "^8.0.0",

src/Illuminate/Collections/Arr.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use InvalidArgumentException;
1212
use JsonSerializable;
1313
use Random\Randomizer;
14+
use SortDirection;
1415
use Traversable;
1516
use WeakMap;
1617

@@ -1090,7 +1091,7 @@ public static function sole($array, ?callable $callback = null)
10901091
* @template TValue
10911092
*
10921093
* @param iterable<TKey, TValue> $array
1093-
* @param callable|string|null|array<int, (callable(TValue, TValue): -1|0|1)|array{string, 'asc'|'desc'}> $callback
1094+
* @param callable|string|null|array<int, (callable(TValue, TValue): -1|0|1)|array{string, SortDirection|'asc'|'desc'}> $callback
10941095
* @return array<TKey, TValue>
10951096
*/
10961097
public static function sort($array, $callback = null)
@@ -1121,7 +1122,7 @@ public static function sortDesc($array, $callback = null)
11211122
*
11221123
* @param array<TKey, TValue> $array
11231124
* @param int-mask-of<SORT_REGULAR|SORT_NUMERIC|SORT_STRING|SORT_LOCALE_STRING|SORT_NATURAL|SORT_FLAG_CASE> $options
1124-
* @param bool $descending
1125+
* @param SortDirection|bool $descending
11251126
* @return array<TKey, TValue>
11261127
*/
11271128
public static function sortRecursive($array, $options = SORT_REGULAR, $descending = false)
@@ -1133,13 +1134,15 @@ public static function sortRecursive($array, $options = SORT_REGULAR, $descendin
11331134
}
11341135

11351136
if (! array_is_list($array)) {
1136-
$descending
1137-
? krsort($array, $options)
1138-
: ksort($array, $options);
1137+
match ($descending) {
1138+
false, SortDirection::Ascending => ksort($array, $options),
1139+
true, SortDirection::Descending => krsort($array, $options),
1140+
};
11391141
} else {
1140-
$descending
1141-
? rsort($array, $options)
1142-
: sort($array, $options);
1142+
match ($descending) {
1143+
false, SortDirection::Ascending => sort($array, $options),
1144+
true, SortDirection::Descending => rsort($array, $options),
1145+
};
11431146
}
11441147

11451148
return $array;
@@ -1158,7 +1161,7 @@ public static function sortRecursive($array, $options = SORT_REGULAR, $descendin
11581161
*/
11591162
public static function sortRecursiveDesc($array, $options = SORT_REGULAR)
11601163
{
1161-
return static::sortRecursive($array, $options, true);
1164+
return static::sortRecursive($array, $options, SortDirection::Descending);
11621165
}
11631166

11641167
/**

src/Illuminate/Collections/Collection.php

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Illuminate\Support\Traits\Macroable;
1010
use Illuminate\Support\Traits\TransformsToResourceCollection;
1111
use InvalidArgumentException;
12+
use SortDirection;
1213
use stdClass;
1314
use Traversable;
1415

@@ -1566,7 +1567,7 @@ public function sortDesc($options = SORT_REGULAR)
15661567
*
15671568
* @param array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string $callback
15681569
* @param int $options
1569-
* @param bool $descending
1570+
* @param SortDirection|bool $descending
15701571
* @return static
15711572
*/
15721573
public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
@@ -1586,8 +1587,10 @@ public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
15861587
$results[$key] = $callback($value, $key);
15871588
}
15881589

1589-
$descending ? arsort($results, $options)
1590-
: asort($results, $options);
1590+
match ($descending) {
1591+
false, SortDirection::Ascending => asort($results, $options),
1592+
true, SortDirection::Descending => arsort($results, $options),
1593+
};
15911594

15921595
// Once we have sorted all of the keys in the array, we will loop through them
15931596
// and grab the corresponding model so we can set the underlying items list
@@ -1616,15 +1619,18 @@ protected function sortByMany(array $comparisons = [], int $options = SORT_REGUL
16161619

16171620
$prop = $comparison[0];
16181621

1619-
$ascending = Arr::get($comparison, 1, true) === true ||
1620-
Arr::get($comparison, 1, true) === 'asc';
1622+
$direction = match (Arr::get($comparison, 1, true)) {
1623+
true, 'asc', SortDirection::Ascending => SortDirection::Ascending,
1624+
false, 'desc', SortDirection::Descending => SortDirection::Descending,
1625+
default => SortDirection::Descending, // for backwards compatibility
1626+
};
16211627

16221628
if (! is_string($prop) && is_callable($prop)) {
16231629
$result = $prop($a, $b);
16241630
} else {
16251631
$values = [data_get($a, $prop), data_get($b, $prop)];
16261632

1627-
if (! $ascending) {
1633+
if ($direction === SortDirection::Descending) {
16281634
$values = array_reverse($values);
16291635
}
16301636

@@ -1669,7 +1675,7 @@ public function sortByDesc($callback, $options = SORT_REGULAR)
16691675
foreach ($callback as $index => $key) {
16701676
$comparison = Arr::wrap($key);
16711677

1672-
$comparison[1] = 'desc';
1678+
$comparison[1] = SortDirection::Descending;
16731679

16741680
$callback[$index] = $comparison;
16751681
}
@@ -1682,14 +1688,17 @@ public function sortByDesc($callback, $options = SORT_REGULAR)
16821688
* Sort the collection keys.
16831689
*
16841690
* @param int $options
1685-
* @param bool $descending
1691+
* @param SortDirection|bool $descending
16861692
* @return static
16871693
*/
16881694
public function sortKeys($options = SORT_REGULAR, $descending = false)
16891695
{
16901696
$items = $this->items;
16911697

1692-
$descending ? krsort($items, $options) : ksort($items, $options);
1698+
match ($descending) {
1699+
false, SortDirection::Ascending => ksort($items, $options),
1700+
true, SortDirection::Descending => krsort($items, $options),
1701+
};
16931702

16941703
return new static($items);
16951704
}
@@ -1702,7 +1711,7 @@ public function sortKeys($options = SORT_REGULAR, $descending = false)
17021711
*/
17031712
public function sortKeysDesc($options = SORT_REGULAR)
17041713
{
1705-
return $this->sortKeys($options, true);
1714+
return $this->sortKeys($options, SortDirection::Descending);
17061715
}
17071716

17081717
/**

src/Illuminate/Collections/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"illuminate/conditionable": "^14.0",
1919
"illuminate/contracts": "^14.0",
2020
"illuminate/macroable": "^14.0",
21-
"symfony/polyfill-php85": "^1.33"
21+
"symfony/polyfill-php85": "^1.33",
22+
"symfony/polyfill-php86": "^1.36"
2223
},
2324
"suggest": {
2425
"illuminate/http": "Required to convert collections to API resources (^14.0).",

tests/Support/SupportCollectionTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
2424
use PHPUnit\Framework\TestCase;
2525
use ReflectionClass;
26+
use SortDirection;
2627
use stdClass;
2728
use Symfony\Component\VarDumper\VarDumper;
2829
use UnexpectedValueException;
@@ -2063,6 +2064,16 @@ public function testSortBy($collection)
20632064

20642065
$this->assertEquals(['dayle', 'taylor'], array_values($data->all()));
20652066

2067+
$data = new $collection(['dayle', 'taylor']);
2068+
$data = $data->sortBy(
2069+
function ($x) {
2070+
return $x;
2071+
},
2072+
SORT_REGULAR,
2073+
SortDirection::Descending);
2074+
2075+
$this->assertEquals(['taylor', 'dayle'], array_values($data->all()));
2076+
20662077
$data = new $collection(['dayle', 'taylor']);
20672078
$data = $data->sortByDesc(function ($x) {
20682079
return $x;
@@ -2153,6 +2164,14 @@ public function testSortByMany($collection)
21532164
$data = $data->sortBy([['item', 'desc']]);
21542165
$this->assertEquals($data->pluck('item')->toArray(), $expected);
21552166

2167+
rsort($expected);
2168+
$data = $data->sortBy([['item', false]]);
2169+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2170+
2171+
rsort($expected);
2172+
$data = $data->sortBy([['item', SortDirection::Descending]]);
2173+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2174+
21562175
sort($expected, SORT_STRING);
21572176
$data = $data->sortBy(['item'], SORT_STRING);
21582177
$this->assertEquals($data->pluck('item')->toArray(), $expected);

0 commit comments

Comments
 (0)