alias(), $fieldName, $nullable); } /** * Eager load the aggregate value for the query builder. */ public function shouldAggregate(array $args, array $selection, BaseType $type): bool { // If the field is being requested. if (Arr::has($selection, $this->name())) { return true; } // If the sorting is requesting an aggregate function. /** @var array $sorts */ $sorts = Arr::get($args, 'sort', []); foreach ($sorts as $sort) { if ($sort->getSortCriteria()->getColumn() === $this->alias()) { return true; } } // If the filtering is requesting an aggregate function. $filterCriteria = FilterCriteria::parse($type, $args); foreach ($filterCriteria as $filterCriterion) { if ($filterCriterion instanceof WhereConditionsFilterCriteria) { $this->filterableFields = new FilterableColumns($type)->getValues(); foreach ($filterCriterion->getFilterValues() as $filterValue) { if ($this->recursiveWhere($filterValue)) { return true; } } } } return false; } /** * Eager load the aggregate value for the query builder. */ public function with(Builder $builder): Builder { return $builder->withAggregate($this->relation, $this->aggregateColumn, $this->function->value); } /** * Eager load the aggregate value for the query builder. */ public function load(Model $model): Model { return $model->loadAggregate($this->relation, $this->aggregateColumn, $this->function->value); } /** * Resolve the field. * * @param Model $root */ public function resolve($root, array $args, $context, ResolveInfo $resolveInfo): mixed { return $root->getAttribute($this->alias()); } public function alias(): string { return Str::of($this->relation) ->snake() ->append('_') ->append($this->function->value) ->when($this->aggregateColumn !== '*', fn (Stringable $string) => $string->append('_')->append($this->aggregateColumn)) ->__toString(); } private function recursiveWhere(array $value): bool { $fieldName = Arr::get($value, 'field'); $fieldValue = Arr::get($value, 'value'); if (filled($fieldName) && filled($fieldValue)) { $field = $this->filterableFields->get($fieldName); if ($field instanceof Field && $field->name() === $this->name()) { return true; } } if ($and = Arr::get($value, 'AND')) { foreach ($and as $andSolo) { if ($this->recursiveWhere($andSolo)) { return true; } } } if ($or = Arr::get($value, 'OR')) { foreach ($or as $orSolo) { if ($this->recursiveWhere($orSolo)) { return true; } } } return false; } }