Files
monica/app/Helpers/CollectionHelper.php
T
Misha Griffiths-PrasolovaandGitHub c3605babf9 fix: fix sortByCollator collection macro return keys (monicahq/chandler#556)
Fix to `sortByCollator` collection macro

Prevents results from being conformed to an object via Inertia rendering
2023-05-30 22:59:21 +02:00

80 lines
2.4 KiB
PHP

<?php
namespace App\Helpers;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
class CollectionHelper
{
/**
* Sort the collection using the given callback.
*/
public static function sortByCollator(Collection $collect, callable|string $callback, int $options = \Collator::SORT_STRING, bool $descending = false): Collection
{
$results = [];
$callback = static::valueRetriever($callback);
// First we will loop through the items and get the comparator from a callback
// function which we were given. Then, we will sort the returned values and
// and grab the corresponding values for the sorted keys from this array.
foreach ($collect->all() as $key => $value) {
$results[$key] = $callback($value, $key);
}
// Using Collator to sort the array, with locale-sensitive sort ordering support.
static::getCollator()->asort($results, $options);
if ($descending) {
$results = array_reverse($results);
}
// 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
// to the sorted version. Then we'll just return the collection instance.
foreach (array_keys($results) as $key) {
$results[$key] = $collect->get($key);
}
return new Collection(array_values($results));
}
/**
* Get a Collator object for the locale or current locale.
*/
public static function getCollator(?string $locale = null): \Collator
{
static $collators = [];
if (! $locale) {
$locale = App::getLocale();
}
if (! Arr::has($collators, $locale)) {
$collator = new \Collator($locale);
if (currentLang($locale) === 'fr') {
$collator->setAttribute(\Collator::FRENCH_COLLATION, \Collator::ON);
}
$collators[$locale] = $collator;
return $collator;
}
return $collators[$locale];
}
/**
* Get a value retrieving callback.
*/
protected static function valueRetriever(callable|string $value): callable
{
if (! is_string($value) && is_callable($value)) {
return $value;
}
return fn ($item) => data_get($item, $value);
}
}