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;
}