Automattic\WooCommerce\Vendor\GraphQL\Validator\Rules

QuerySecurityRule::collectFieldASTsAndDefsprotectedWC 1.0

Given a selectionSet, adds all fields in that selection to the passed in map of fields, and returns it at the end.

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.

Method of the class: QuerySecurityRule{}

No Hooks.

Returns

null. Nothing (null).

Usage

// protected - for code of main (parent) or child class
$result = $this->collectFieldASTsAndDefs( $context, ?Type $parentType, $selectionSet, ?\ArrayObject $visitedFragmentNames, ?\ArrayObject $astAndDefs ): \ArrayObject;
$context(QueryValidationContext) (required)
.
?Type $parentType(required)
.
$selectionSet(SelectionSetNode) (required)
.
?\ArrayObject $visitedFragmentNames
.
Default: null
?\ArrayObject $astAndDefs
.
Default: null

Notes

QuerySecurityRule::collectFieldASTsAndDefs() code WC 10.9.1

protected function collectFieldASTsAndDefs(
    QueryValidationContext $context,
    ?Type $parentType,
    SelectionSetNode $selectionSet,
    ?\ArrayObject $visitedFragmentNames = null,
    ?\ArrayObject $astAndDefs = null
): \ArrayObject {
    $visitedFragmentNames ??= new \ArrayObject();
    $astAndDefs ??= new \ArrayObject();

    foreach ($selectionSet->selections as $selection) {
        if ($selection instanceof FieldNode) {
            $fieldName = $selection->name->value;

            $fieldDef = null;
            if ($parentType instanceof HasFieldsType) {
                $schemaMetaFieldDef = Introspection::schemaMetaFieldDef();
                $typeMetaFieldDef = Introspection::typeMetaFieldDef();
                $typeNameMetaFieldDef = Introspection::typeNameMetaFieldDef();

                $queryType = $context->getSchema()->getQueryType();

                if ($fieldName === $schemaMetaFieldDef->name && $queryType === $parentType) {
                    $fieldDef = $schemaMetaFieldDef;
                } elseif ($fieldName === $typeMetaFieldDef->name && $queryType === $parentType) {
                    $fieldDef = $typeMetaFieldDef;
                } elseif ($fieldName === $typeNameMetaFieldDef->name) {
                    $fieldDef = $typeNameMetaFieldDef;
                } elseif ($parentType->hasField($fieldName)) {
                    $fieldDef = $parentType->getField($fieldName);
                }
            }

            $responseName = $this->getFieldName($selection);
            $responseContext = $astAndDefs[$responseName] ??= new \ArrayObject();
            $responseContext[] = [$selection, $fieldDef];
        } elseif ($selection instanceof InlineFragmentNode) {
            $typeCondition = $selection->typeCondition;
            $fragmentParentType = $typeCondition === null
                ? $parentType
                : AST::typeFromAST([$context->getSchema(), 'getType'], $typeCondition);
            $astAndDefs = $this->collectFieldASTsAndDefs(
                $context,
                $fragmentParentType,
                $selection->selectionSet,
                $visitedFragmentNames,
                $astAndDefs
            );
        } elseif ($selection instanceof FragmentSpreadNode) {
            $fragName = $selection->name->value;

            if (isset($visitedFragmentNames[$fragName])) {
                continue;
            }
            $visitedFragmentNames[$fragName] = true;

            $fragment = $context->getFragment($fragName);
            if ($fragment === null) {
                continue;
            }

            $astAndDefs = $this->collectFieldASTsAndDefs(
                $context,
                AST::typeFromAST([$context->getSchema(), 'getType'], $fragment->typeCondition),
                $fragment->selectionSet,
                $visitedFragmentNames,
                $astAndDefs
            );
        }
    }

    return $astAndDefs;
}