$sortByColumns * * @throws ClientValidationException * @throws InvalidArgumentException */ public function handleBuilder(QueryBuilder|EloquentBuilder|Relation $builder, $sortByColumns): QueryBuilder|EloquentBuilder|Relation { $sortableColumns = json_decode($this->directiveArgValue('columns'), true); foreach ($sortByColumns as $column) { $direction = SortableColumns::resolveSortDirection($column)->value; $sortByColumnValue = Str::remove('_DESC', $column); $sortByColumnInput = Arr::first($sortableColumns, fn ($sortByColumn) => $sortByColumn['value'] === $sortByColumnValue); $column = Arr::get($sortByColumnInput, 'column'); $sortType = SortType::from(Arr::get($sortByColumnInput, 'sortType')); if ($sortType === SortType::ROOT) { $builder->orderBy($column, $direction); } if ($sortType === SortType::AGGREGATE) { $relation = Arr::get($sortByColumnInput, 'relation'); if ($relation === null) { throw new InvalidArgumentException("The 'relation' argument is required for the @{$this->name()} directive with aggregate sort type."); } $builder->withAggregate([ "$relation as {$relation}_value" => function ($query) use ($direction) { $query->orderBy('value', $direction); }, ], 'value'); $builder->orderBy("{$relation}_value", $direction); } } return $builder; } }