Automattic\WooCommerce\Vendor\GraphQL\Utils

AST::valueFromASTpublic staticWC 1.0

Produces a PHP value given a Automattic\WooCommerce\Vendor\GraphQL Value AST.

A Automattic\WooCommerce\Vendor\GraphQL type must be provided, which will be used to interpret different Automattic\WooCommerce\Vendor\GraphQL Value literals.

Returns null when the value could not be validly coerced according to the provided type.

Automattic\WooCommerce\Vendor\GraphQL Value PHP Value
Input Object Assoc Array
List Array
Boolean Boolean
String String
Int / Float Int / Float
Enum Value Mixed
Null Value null

Method of the class: AST{}

No Hooks.

Returns

Mixed.

Usage

$result = AST::valueFromAST( ?ValueNode $valueNode, $type, ?array $variables, ?Schema $schema );
?ValueNode $valueNode(required)
.
$type(Type) (required)
.
?array $variables
.
Default: null
?Schema $schema
.
Default: null

AST::valueFromAST() code WC 10.9.1

public static function valueFromAST(?ValueNode $valueNode, Type $type, ?array $variables = null, ?Schema $schema = null)
{
    $undefined = Utils::undefined();

    if ($valueNode === null) {
        // When there is no AST, then there is also no value.
        // Importantly, this is different from returning the Automattic\WooCommerce\Vendor\GraphQL null value.
        return $undefined;
    }

    if ($type instanceof NonNull) {
        if ($valueNode instanceof NullValueNode) {
            // Invalid: intentionally return no value.
            return $undefined;
        }

        return self::valueFromAST($valueNode, $type->getWrappedType(), $variables, $schema);
    }

    if ($valueNode instanceof NullValueNode) {
        // This is explicitly returning the value null.
        return null;
    }

    if ($valueNode instanceof VariableNode) {
        $variableName = $valueNode->name->value;

        if ($variables === null || ! array_key_exists($variableName, $variables)) {
            // No valid return value.
            return $undefined;
        }

        // Note: This does no further checking that this variable is correct.
        // This assumes that this query has been validated and the variable
        // usage here is of the correct type.
        return $variables[$variableName];
    }

    if ($type instanceof ListOfType) {
        $itemType = $type->getWrappedType();

        if ($valueNode instanceof ListValueNode) {
            $coercedValues = [];
            $itemNodes = $valueNode->values;
            foreach ($itemNodes as $itemNode) {
                if (self::isMissingVariable($itemNode, $variables)) {
                    // If an array contains a missing variable, it is either coerced to
                    // null or if the item type is non-null, it considered invalid.
                    if ($itemType instanceof NonNull) {
                        // Invalid: intentionally return no value.
                        return $undefined;
                    }

                    $coercedValues[] = null;
                } else {
                    $itemValue = self::valueFromAST($itemNode, $itemType, $variables, $schema);
                    if ($undefined === $itemValue) {
                        // Invalid: intentionally return no value.
                        return $undefined;
                    }

                    $coercedValues[] = $itemValue;
                }
            }

            return $coercedValues;
        }

        $coercedValue = self::valueFromAST($valueNode, $itemType, $variables, $schema);
        if ($undefined === $coercedValue) {
            // Invalid: intentionally return no value.
            return $undefined;
        }

        return [$coercedValue];
    }

    if ($type instanceof InputObjectType) {
        if (! $valueNode instanceof ObjectValueNode) {
            // Invalid: intentionally return no value.
            return $undefined;
        }

        $coercedObj = [];
        $fields = $type->getFields();

        $fieldNodes = [];
        foreach ($valueNode->fields as $field) {
            $fieldNodes[$field->name->value] = $field;
        }

        foreach ($fields as $field) {
            $fieldName = $field->name;
            $fieldNode = $fieldNodes[$fieldName] ?? null;

            if ($fieldNode === null || self::isMissingVariable($fieldNode->value, $variables)) {
                if ($field->defaultValueExists()) {
                    $coercedObj[$fieldName] = $field->defaultValue;
                } elseif ($field->getType() instanceof NonNull) {
                    // Invalid: intentionally return no value.
                    return $undefined;
                }

                continue;
            }

            $fieldValue = self::valueFromAST(
                $fieldNode->value,
                $field->getType(),
                $variables,
                $schema,
            );

            if ($undefined === $fieldValue) {
                // Invalid: intentionally return no value.
                return $undefined;
            }

            $coercedObj[$fieldName] = $fieldValue;
        }

        return $type->parseValue($coercedObj);
    }

    if ($type instanceof EnumType) {
        try {
            return $type->parseLiteral($valueNode, $variables);
        } catch (\Throwable $error) {
            return $undefined;
        }
    }

    assert($type instanceof ScalarType, 'only remaining option');
    $typeName = $type->name;

    // Account for type loader returning a different scalar instance than
    // the built-in singleton used in field definitions. Resolve the actual
    // type from the schema to ensure the correct parseLiteral() is called.
    if ($schema !== null && Type::isBuiltInScalarName($typeName)) {
        $schemaType = $schema->getType($typeName);
        assert($schemaType instanceof ScalarType, "Schema must provide a ScalarType for built-in scalar \"{$typeName}\".");
        $type = $schemaType;
    }

    // Scalars fulfill parsing a literal value via parseLiteral().
    // Invalid values represent a failure to parse correctly, in which case
    // no value is returned.
    try {
        return $type->parseLiteral($valueNode, $variables);
    } catch (\Throwable $error) {
        return $undefined;
    }
}