diff --git a/composer.json b/composer.json index caa161380767..2aa4d769d05e 100644 --- a/composer.json +++ b/composer.json @@ -56,6 +56,7 @@ "symfony/mime": "^8.0.0", "symfony/polyfill-php84": "^1.33", "symfony/polyfill-php85": "^1.33", + "symfony/polyfill-php86": "^1.36", "symfony/process": "^7.4.5 || ^8.0.5", "symfony/routing": "^8.0.0", "symfony/uid": "^8.0.0", diff --git a/src/Illuminate/Collections/Arr.php b/src/Illuminate/Collections/Arr.php index bc41efa81724..f0ccbea7f2ea 100644 --- a/src/Illuminate/Collections/Arr.php +++ b/src/Illuminate/Collections/Arr.php @@ -11,6 +11,7 @@ use InvalidArgumentException; use JsonSerializable; use Random\Randomizer; +use SortDirection; use Traversable; use WeakMap; @@ -1090,7 +1091,7 @@ public static function sole($array, ?callable $callback = null) * @template TValue * * @param iterable $array - * @param callable|string|null|array $callback + * @param callable|string|null|array $callback * @return array */ public static function sort($array, $callback = null) @@ -1121,7 +1122,7 @@ public static function sortDesc($array, $callback = null) * * @param array $array * @param int-mask-of $options - * @param bool $descending + * @param SortDirection|bool $descending * @return array */ public static function sortRecursive($array, $options = SORT_REGULAR, $descending = false) @@ -1133,13 +1134,15 @@ public static function sortRecursive($array, $options = SORT_REGULAR, $descendin } if (! array_is_list($array)) { - $descending - ? krsort($array, $options) - : ksort($array, $options); + match ($descending) { + false, SortDirection::Ascending => ksort($array, $options), + true, SortDirection::Descending => krsort($array, $options), + }; } else { - $descending - ? rsort($array, $options) - : sort($array, $options); + match ($descending) { + false, SortDirection::Ascending => sort($array, $options), + true, SortDirection::Descending => rsort($array, $options), + }; } return $array; @@ -1158,7 +1161,7 @@ public static function sortRecursive($array, $options = SORT_REGULAR, $descendin */ public static function sortRecursiveDesc($array, $options = SORT_REGULAR) { - return static::sortRecursive($array, $options, true); + return static::sortRecursive($array, $options, SortDirection::Descending); } /** diff --git a/src/Illuminate/Collections/Collection.php b/src/Illuminate/Collections/Collection.php index fb0304f6f49c..63309608f9f3 100644 --- a/src/Illuminate/Collections/Collection.php +++ b/src/Illuminate/Collections/Collection.php @@ -9,6 +9,7 @@ use Illuminate\Support\Traits\Macroable; use Illuminate\Support\Traits\TransformsToResourceCollection; use InvalidArgumentException; +use SortDirection; use stdClass; use Traversable; @@ -1566,7 +1567,7 @@ public function sortDesc($options = SORT_REGULAR) * * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options - * @param bool $descending + * @param SortDirection|bool $descending * @return static */ public function sortBy($callback, $options = SORT_REGULAR, $descending = false) @@ -1586,8 +1587,10 @@ public function sortBy($callback, $options = SORT_REGULAR, $descending = false) $results[$key] = $callback($value, $key); } - $descending ? arsort($results, $options) - : asort($results, $options); + match ($descending) { + false, SortDirection::Ascending => asort($results, $options), + true, SortDirection::Descending => arsort($results, $options), + }; // Once we have sorted all of the keys in the array, we will loop through them // and grab the corresponding model so we can set the underlying items list @@ -1616,15 +1619,17 @@ protected function sortByMany(array $comparisons = [], int $options = SORT_REGUL $prop = $comparison[0]; - $ascending = Arr::get($comparison, 1, true) === true || - Arr::get($comparison, 1, true) === 'asc'; + $direction = match (Arr::get($comparison, 1, SortDirection::Ascending)) { + 'asc', SortDirection::Ascending => SortDirection::Ascending, + 'desc', SortDirection::Descending => SortDirection::Descending, + }; if (! is_string($prop) && is_callable($prop)) { $result = $prop($a, $b); } else { $values = [data_get($a, $prop), data_get($b, $prop)]; - if (! $ascending) { + if ($direction === SortDirection::Descending) { $values = array_reverse($values); } @@ -1669,7 +1674,7 @@ public function sortByDesc($callback, $options = SORT_REGULAR) foreach ($callback as $index => $key) { $comparison = Arr::wrap($key); - $comparison[1] = 'desc'; + $comparison[1] = SortDirection::Descending; $callback[$index] = $comparison; } @@ -1682,14 +1687,17 @@ public function sortByDesc($callback, $options = SORT_REGULAR) * Sort the collection keys. * * @param int $options - * @param bool $descending + * @param SortDirection|bool $descending * @return static */ public function sortKeys($options = SORT_REGULAR, $descending = false) { $items = $this->items; - $descending ? krsort($items, $options) : ksort($items, $options); + match ($descending) { + false, SortDirection::Ascending => ksort($items, $options), + true, SortDirection::Descending => krsort($items, $options), + }; return new static($items); } @@ -1702,7 +1710,7 @@ public function sortKeys($options = SORT_REGULAR, $descending = false) */ public function sortKeysDesc($options = SORT_REGULAR) { - return $this->sortKeys($options, true); + return $this->sortKeys($options, SortDirection::Descending); } /** diff --git a/src/Illuminate/Collections/composer.json b/src/Illuminate/Collections/composer.json index 6d0200009c31..ac335ab4fa31 100644 --- a/src/Illuminate/Collections/composer.json +++ b/src/Illuminate/Collections/composer.json @@ -18,7 +18,8 @@ "illuminate/conditionable": "^14.0", "illuminate/contracts": "^14.0", "illuminate/macroable": "^14.0", - "symfony/polyfill-php85": "^1.33" + "symfony/polyfill-php85": "^1.33", + "symfony/polyfill-php86": "^1.36" }, "suggest": { "illuminate/http": "Required to convert collections to API resources (^14.0).", diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index b8f811409c35..37c0fdaad93d 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -23,6 +23,7 @@ use PHPUnit\Framework\Attributes\IgnoreDeprecations; use PHPUnit\Framework\TestCase; use ReflectionClass; +use SortDirection; use stdClass; use Symfony\Component\VarDumper\VarDumper; use UnexpectedValueException; @@ -2063,6 +2064,16 @@ public function testSortBy($collection) $this->assertEquals(['dayle', 'taylor'], array_values($data->all())); + $data = new $collection(['dayle', 'taylor']); + $data = $data->sortBy( + function ($x) { + return $x; + }, + SORT_REGULAR, + SortDirection::Descending); + + $this->assertEquals(['taylor', 'dayle'], array_values($data->all())); + $data = new $collection(['dayle', 'taylor']); $data = $data->sortByDesc(function ($x) { return $x; @@ -2153,6 +2164,14 @@ public function testSortByMany($collection) $data = $data->sortBy([['item', 'desc']]); $this->assertEquals($data->pluck('item')->toArray(), $expected); + rsort($expected); + $data = $data->sortBy([['item', false]]); + $this->assertEquals($data->pluck('item')->toArray(), $expected); + + rsort($expected); + $data = $data->sortBy([['item', SortDirection::Descending]]); + $this->assertEquals($data->pluck('item')->toArray(), $expected); + sort($expected, SORT_STRING); $data = $data->sortBy(['item'], SORT_STRING); $this->assertEquals($data->pluck('item')->toArray(), $expected);