withAggregates($builder, $args, $this->getSelection($resolveInfo), $type); $this->filter($builder, $args, $type); $this->sort($builder, $args); $this->constrainEagerLoads($builder, $resolveInfo, $type); return $this->paginate($builder, $args); } public function search(Builder $builder, array $args, BaseType $type, ResolveInfo $resolveInfo): Paginator { $criteria = new Criteria(Arr::get($args, 'search')); $searchBuilder = Search::getSearch($builder->getModel(), $criteria); $eloquentCallback = function (Builder $builder) use ($args, $type, $resolveInfo): void { $this->withAggregates($builder, $args, $this->getSelection($resolveInfo), $type); $this->filter($builder, $args, $type); $this->sort($builder, $args); $this->constrainEagerLoads($builder, $resolveInfo, $type); }; // Note: First for searching must not be too high. $first = min(100, Arr::get($args, 'first')); $page = Arr::get($args, 'page', 1); Validator::make(['first' => $first], [ 'first' => ['required', 'integer', 'min:1', new FirstArgumentRule()], ])->validate(); /** @var array $sorts */ $sorts = Arr::get($args, SortArgument::ARGUMENT, []); $sortsRaw = []; foreach ($sorts as $sort) { $criterion = $sort->getSortCriteria(); $column = $criterion->getColumn(); $direction = $criterion->getDirection(); $isString = $criterion->isStringField(); if ($criterion instanceof RelationSortCriteria) { $sortsRaw[$column] = [ 'direction' => $direction->value, 'isString' => $isString, 'relation' => $criterion->getRelation(), ]; } else { $sortsRaw[$column] = [ 'direction' => $direction, 'isString' => $isString, ]; } } return $searchBuilder->search($eloquentCallback, $first, $page, $sortsRaw); } }