mirror of
https://github.com/AnimeThemes/animethemes-server.git
synced 2026-07-11 01:24:46 +02:00
156 lines
5.5 KiB
PHP
156 lines
5.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\GraphQL;
|
|
|
|
use GraphQL\Error\Error;
|
|
use GraphQL\Error\InvariantViolation;
|
|
use GraphQL\Executor\Values;
|
|
use GraphQL\Language\AST\FieldNode;
|
|
use GraphQL\Language\AST\FragmentSpreadNode;
|
|
use GraphQL\Language\AST\InlineFragmentNode;
|
|
use GraphQL\Language\AST\NamedTypeNode;
|
|
use GraphQL\Language\AST\SelectionSetNode;
|
|
use GraphQL\Type\Definition\HasFieldsType;
|
|
use GraphQL\Type\Definition\NamedType;
|
|
use GraphQL\Type\Definition\ResolveInfo as BaseResolveInfo;
|
|
use GraphQL\Type\Definition\Type;
|
|
use GraphQL\Type\Definition\UnionType;
|
|
use GraphQL\Type\Definition\WrappingType;
|
|
use GraphQL\Type\Introspection;
|
|
|
|
class ResolveInfo extends BaseResolveInfo
|
|
{
|
|
public function __construct(BaseResolveInfo $resolveInfo)
|
|
{
|
|
parent::__construct(
|
|
$resolveInfo->fieldDefinition,
|
|
$resolveInfo->fieldNodes,
|
|
$resolveInfo->parentType,
|
|
$resolveInfo->path,
|
|
$resolveInfo->schema,
|
|
$resolveInfo->fragments,
|
|
$resolveInfo->rootValue,
|
|
$resolveInfo->operation,
|
|
$resolveInfo->variableValues,
|
|
$resolveInfo->unaliasedPath
|
|
);
|
|
}
|
|
|
|
public function getFieldSelectionWithAliases(int $depth = 0): array
|
|
{
|
|
$fields = [];
|
|
|
|
foreach ($this->fieldNodes as $fieldNode) {
|
|
$selectionSet = $fieldNode->selectionSet;
|
|
if ($selectionSet !== null) {
|
|
$field = $this->parentType->getField($fieldNode->name->value);
|
|
$fieldType = $field->getType();
|
|
|
|
$fields = array_merge_recursive(
|
|
$fields,
|
|
$this->foldSelectionWithAlias($selectionSet, $depth, $fieldType)
|
|
);
|
|
}
|
|
}
|
|
|
|
return $fields;
|
|
}
|
|
|
|
/**
|
|
* @return array<string>
|
|
*
|
|
* @throws \Exception
|
|
* @throws Error
|
|
* @throws InvariantViolation
|
|
*/
|
|
protected function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $descend, Type $parentType): array
|
|
{
|
|
/** @var array<string, bool> $fields */
|
|
$fields = [];
|
|
|
|
if ($parentType instanceof WrappingType) {
|
|
$parentType = $parentType->getInnermostType();
|
|
}
|
|
|
|
foreach ($selectionSet->selections as $selection) {
|
|
if ($selection instanceof FieldNode) {
|
|
$fieldName = $selection->name->value;
|
|
$aliasName = $selection->alias->value ?? $fieldName;
|
|
|
|
if ($fieldName === Introspection::TYPE_NAME_FIELD_NAME) {
|
|
continue;
|
|
}
|
|
assert($parentType instanceof HasFieldsType, 'ensured by query validation');
|
|
|
|
$aliasInfo = &$fields[$fieldName][$aliasName];
|
|
|
|
$fieldDef = $parentType->getField($fieldName);
|
|
|
|
$aliasInfo['args'] = Values::getArgumentValues($fieldDef, $selection, $this->variableValues);
|
|
|
|
$fieldType = $fieldDef->getType();
|
|
|
|
$namedFieldType = $fieldType;
|
|
if ($namedFieldType instanceof WrappingType) {
|
|
$namedFieldType = $namedFieldType->getInnermostType();
|
|
}
|
|
|
|
$aliasInfo['type'] = $namedFieldType;
|
|
|
|
if ($descend <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$nestedSelectionSet = $selection->selectionSet;
|
|
if (! $nestedSelectionSet instanceof SelectionSetNode) {
|
|
continue;
|
|
}
|
|
|
|
if ($namedFieldType instanceof UnionType) {
|
|
$aliasInfo['unions'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend, $fieldType);
|
|
continue;
|
|
}
|
|
|
|
$aliasInfo['selectionSet'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend - 1, $fieldType);
|
|
} elseif ($selection instanceof FragmentSpreadNode) {
|
|
$spreadName = $selection->name->value;
|
|
$fragment = $this->fragments[$spreadName] ?? null;
|
|
if ($fragment === null) {
|
|
continue;
|
|
}
|
|
|
|
$fieldType = $this->schema->getType($fragment->typeCondition->name->value);
|
|
assert($fieldType instanceof Type, 'ensured by query validation');
|
|
|
|
$fields = array_merge(
|
|
$this->foldSelectionWithAlias($fragment->selectionSet, $descend, $fieldType),
|
|
$fields
|
|
);
|
|
} elseif ($selection instanceof InlineFragmentNode) {
|
|
$typeCondition = $selection->typeCondition;
|
|
$fieldType = $typeCondition instanceof NamedTypeNode
|
|
? $this->schema->getType($typeCondition->name->value)
|
|
: $parentType;
|
|
assert($fieldType instanceof Type, 'ensured by query validation');
|
|
|
|
if ($parentType instanceof UnionType) {
|
|
assert($fieldType instanceof NamedType, 'ensured by query validation');
|
|
$fieldTypeInfo = &$fields[$fieldType->name()];
|
|
$fieldTypeInfo['type'] = $fieldType;
|
|
$fieldTypeInfo['selectionSet'] = $this->foldSelectionWithAlias($selection->selectionSet, $descend, $fieldType);
|
|
continue;
|
|
}
|
|
|
|
$fields = array_merge(
|
|
$this->foldSelectionWithAlias($selection->selectionSet, $descend, $fieldType),
|
|
$fields
|
|
);
|
|
}
|
|
}
|
|
|
|
return $fields;
|
|
}
|
|
}
|