2025-01-23 00:45:59 +01:00

76 lines
1.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\QueryRequestModifiers;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Validator;
/**
* @template C of Model
* @template D of OrderableDTO
*/
trait Orderable
{
/**
* @param Builder<C> $query
* @param ?OrderableDTO<D> $orderDef
* @return Builder<C>
*/
protected function applyOrderable(Builder $query, ?OrderableDTO $orderDef): Builder
{
if ($orderDef !== null) {
$query->orderBy($orderDef->getColumn(), $orderDef->getDirection()->value);
}
return $query;
}
/**
* @param class-string<D> $className
* @return D|null
*/
protected function makeOrderableFromRequest(FormRequest $request, string $className): ?object
{
$keys = $request->all(self::keys());
if (!isset($keys['order']) || !isset($keys['direction'])) {
return null;
}
$validator = Validator::make($keys, $this->validateRules());
if ($validator->fails()) {
// this should never happen... Invalid request
throw new \InvalidArgumentException($validator->errors()->first());
}
$column = $keys['order'];
$direction = $keys['direction'];
return call_user_func([$className, 'createFromValues'], $column, SortDirection::from($direction));
}
/**
* @return array<string, string>
*/
public function validateRules(): array
{
return [
'order' => 'sometimes|string|in:title',
'direction' => 'sometimes|string|in:asc,desc',
];
}
/**
* @return array<int, string>
*/
protected static function keys(): array
{
return ['order', 'direction'];
}
}