GraphQL\Validator\Rules\AbstractQuerySecurity::collectFieldASTsAndDefs PHP Method

collectFieldASTsAndDefs() protected method

Note: This is not the same as execution's collectFields because at static time we do not know what object type will be used, so we unconditionally spread in all fragments.
See also: GraphQL\Validator\Rules\OverlappingFieldsCanBeMerged
protected collectFieldASTsAndDefs ( ValidationContext $context, Type | null $parentType, SelectionSetNode $selectionSet, ArrayObject $visitedFragmentNames = null, ArrayObject $astAndDefs = null ) : ArrayObject
$context GraphQL\Validator\ValidationContext
$parentType GraphQL\Type\Definition\Type | null
$selectionSet GraphQL\Language\AST\SelectionSetNode
$visitedFragmentNames ArrayObject
$astAndDefs ArrayObject
return ArrayObject
    protected function collectFieldASTsAndDefs(ValidationContext $context, $parentType, SelectionSetNode $selectionSet, \ArrayObject $visitedFragmentNames = null, \ArrayObject $astAndDefs = null)
    {
        $_visitedFragmentNames = $visitedFragmentNames ?: new \ArrayObject();
        $_astAndDefs = $astAndDefs ?: new \ArrayObject();
        foreach ($selectionSet->selections as $selection) {
            switch ($selection->kind) {
                case NodeKind::FIELD:
                    /* @var FieldNode $selection */
                    $fieldName = $selection->name->value;
                    $fieldDef = null;
                    if ($parentType && method_exists($parentType, 'getFields')) {
                        $tmp = $parentType->getFields();
                        $schemaMetaFieldDef = Introspection::schemaMetaFieldDef();
                        $typeMetaFieldDef = Introspection::typeMetaFieldDef();
                        $typeNameMetaFieldDef = Introspection::typeNameMetaFieldDef();
                        if ($fieldName === $schemaMetaFieldDef->name && $context->getSchema()->getQueryType() === $parentType) {
                            $fieldDef = $schemaMetaFieldDef;
                        } elseif ($fieldName === $typeMetaFieldDef->name && $context->getSchema()->getQueryType() === $parentType) {
                            $fieldDef = $typeMetaFieldDef;
                        } elseif ($fieldName === $typeNameMetaFieldDef->name) {
                            $fieldDef = $typeNameMetaFieldDef;
                        } elseif (isset($tmp[$fieldName])) {
                            $fieldDef = $tmp[$fieldName];
                        }
                    }
                    $responseName = $this->getFieldName($selection);
                    if (!isset($_astAndDefs[$responseName])) {
                        $_astAndDefs[$responseName] = new \ArrayObject();
                    }
                    // create field context
                    $_astAndDefs[$responseName][] = [$selection, $fieldDef];
                    break;
                case NodeKind::INLINE_FRAGMENT:
                    /* @var InlineFragmentNode $selection */
                    $_astAndDefs = $this->collectFieldASTsAndDefs($context, TypeInfo::typeFromAST($context->getSchema(), $selection->typeCondition), $selection->selectionSet, $_visitedFragmentNames, $_astAndDefs);
                    break;
                case NodeKind::FRAGMENT_SPREAD:
                    /* @var FragmentSpreadNode $selection */
                    $fragName = $selection->name->value;
                    if (empty($_visitedFragmentNames[$fragName])) {
                        $_visitedFragmentNames[$fragName] = true;
                        $fragment = $context->getFragment($fragName);
                        if ($fragment) {
                            $_astAndDefs = $this->collectFieldASTsAndDefs($context, TypeInfo::typeFromAST($context->getSchema(), $fragment->typeCondition), $fragment->selectionSet, $_visitedFragmentNames, $_astAndDefs);
                        }
                    }
                    break;
            }
        }
        return $_astAndDefs;
    }