src/Utils/Value.php
public static function coerceValue($value, InputType $type, $blameNode = null, ?array $path = null)
    {
        if ($type instanceof NonNull) {
            if ($value === null) {
                return self::ofErrors([
                    self::coercionError(
                        sprintf('Expected non-nullable type %s not to be null', $type),
                        $blameNode,
                        $path
                    ),
                ]);
            }

            return self::coerceValue($value, $type->getWrappedType(), $blameNode, $path);
        }

        if ($value === null) {
            // Explicitly return the value null.
            return self::ofValue(null);
        }

        if ($type instanceof ScalarType) {
            // Scalars determine if a value is valid via parseValue(), which can
            // throw to indicate failure. If it throws, maintain a reference to
            // the original error.
            try {
                return self::ofValue($type->parseValue($value));
            } catch (Exception $error) {
                return self::ofErrors([
                    self::coercionError(
                        sprintf('Expected type %s', $type->name),
                        $blameNode,
                        $path,
                        $error->getMessage(),
                        $error
                    ),
                ]);
            } catch (Throwable $error) {
                return self::ofErrors([
                    self::coercionError(
                        sprintf('Expected type %s', $type->name),
                        $blameNode,
                        $path,
                        $error->getMessage(),
                        $error
                    ),
                ]);
            }
        }

        if ($type instanceof EnumType) {
            if (is_string($value)) {
                $enumValue = $type->getValue($value);
                if ($enumValue) {
                    return self::ofValue($enumValue->value);
                }
            }

            $suggestions = Utils::suggestionList(
                Utils::printSafe($value),
                array_map(
                    static function ($enumValue) {
                        return $enumValue->name;
                    },
                    $type->getValues()
                )
            );

            $didYouMean = $suggestions
                ? 'did you mean ' . Utils::orList($suggestions) . '?'
                : null;

            return self::ofErrors([
                self::coercionError(
                    sprintf('Expected type %s', $type->name),
                    $blameNode,
                    $path,
                    $didYouMean
                ),
            ]);
        }

        if ($type instanceof ListOfType) {
            $itemType = $type->getWrappedType();
            if (is_array($value) || $value instanceof Traversable) {
                $errors       = [];
                $coercedValue = [];
                foreach ($value as $index => $itemValue) {
                    $coercedItem = self::coerceValue(
                        $itemValue,
                        $itemType,
                        $blameNode,
                        self::atPath($path, $index)
                    );
                    if ($coercedItem['errors']) {
                        $errors = self::add($errors, $coercedItem['errors']);
                    } else {
                        $coercedValue[] = $coercedItem['value'];
                    }
                }

                return $errors ? self::ofErrors($errors) : self::ofValue($coercedValue);
            }
            // Lists accept a non-list value as a list of one.
            $coercedItem = self::coerceValue($value, $itemType, $blameNode);

            return $coercedItem['errors'] ? $coercedItem : self::ofValue([$coercedItem['value']]);
        }

        if ($type instanceof InputObjectType) {
            if (! is_object($value) && ! is_array($value) && ! $value instanceof Traversable) {
                return self::ofErrors([
                    self::coercionError(
                        sprintf('Expected type %s to be an object', $type->name),
                        $blameNode,
                        $path
                    ),
                ]);
            }

            $errors       = [];
            $coercedValue = [];
            $fields       = $type->getFields();
            foreach ($fields as $fieldName => $field) {
                if (array_key_exists($fieldName, $value)) {
                    $fieldValue   = $value[$fieldName];
                    $coercedField = self::coerceValue(
                        $fieldValue,
                        $field->getType(),
                        $blameNode,
                        self::atPath($path, $fieldName)
                    );
                    if ($coercedField['errors']) {
                        $errors = self::add($errors, $coercedField['errors']);
                    } else {
                        $coercedValue[$fieldName] = $coercedField['value'];
                    }
                } elseif ($field->defaultValueExists()) {
                    $coercedValue[$fieldName] = $field->defaultValue;
                } elseif ($field->getType() instanceof NonNull) {
                    $fieldPath = self::printPath(self::atPath($path, $fieldName));
                    $errors    = self::add(
                        $errors,
                        self::coercionError(
                            sprintf(
                                'Field %s of required type %s was not provided',
                                $fieldPath,
                                $field->type->toString()
                            ),
                            $blameNode
                        )
                    );
                }
            }

            // Ensure every provided field is defined.
            foreach ($value as $fieldName => $field) {
                if (array_key_exists($fieldName, $fields)) {
                    continue;
                }

                $suggestions = Utils::suggestionList(
                    $fieldName,
                    array_keys($fields)
                );
                $didYouMean  = $suggestions
                    ? 'did you mean ' . Utils::orList($suggestions) . '?'
                    : null;
                $errors      = self::add(
                    $errors,
                    self::coercionError(
                        sprintf('Field "%s" is not defined by type %s', $fieldName, $type->name),
                        $blameNode,
                        $path,
                        $didYouMean
                    )
                );
            }

            return $errors ? self::ofErrors($errors) : self::ofValue($coercedValue);
        }

        throw new Error(sprintf('Unexpected type %s', $type->name));
    }
public static function coerceValue($value, InputType $type, $blameNode = null, ?array $path = null)
    {
        if ($type instanceof NonNull) {
            if ($value === null) {
                return self::ofErrors([
                    self::coercionError(
                        sprintf('Expected non-nullable type %s not to be null', $type),
                        $blameNode,
                        $path
                    ),
                ]);
            }

            return self::coerceValue($value, $type->getWrappedType(), $blameNode, $path);
        }

        if ($value === null) {
            // Explicitly return the value null.
            return self::ofValue(null);
        }

        if ($type instanceof ScalarType) {
            // Scalars determine if a value is valid via parseValue(), which can
            // throw to indicate failure. If it throws, maintain a reference to
            // the original error.
            try {
                return self::ofValue($type->parseValue($value));
            } catch (Exception $error) {
                return self::ofErrors([
                    self::coercionError(
                        sprintf('Expected type %s', $type->name),
                        $blameNode,
                        $path,
                        $error->getMessage(),
                        $error
                    ),
                ]);
            } catch (Throwable $error) {
                return self::ofErrors([
                    self::coercionError(
                        sprintf('Expected type %s', $type->name),
                        $blameNode,
                        $path,
                        $error->getMessage(),
                        $error
                    ),
                ]);
            }
        }

        if ($type instanceof EnumType) {
            if (is_string($value)) {
                $enumValue = $type->getValue($value);
                if ($enumValue) {
                    return self::ofValue($enumValue->value);
                }
            }

            $suggestions = Utils::suggestionList(
                Utils::printSafe($value),
                array_map(
                    static function ($enumValue) {
                        return $enumValue->name;
                    },
                    $type->getValues()
                )
            );

            $didYouMean = $suggestions
                ? 'did you mean ' . Utils::orList($suggestions) . '?'
                : null;

            return self::ofErrors([
                self::coercionError(
                    sprintf('Expected type %s', $type->name),
                    $blameNode,
                    $path,
                    $didYouMean
                ),
            ]);
        }

        if ($type instanceof ListOfType) {
            $itemType = $type->getWrappedType();
            if (is_array($value) || $value instanceof Traversable) {
                $errors       = [];
                $coercedValue = [];
                foreach ($value as $index => $itemValue) {
                    $coercedItem = self::coerceValue(
                        $itemValue,
                        $itemType,
                        $blameNode,
                        self::atPath($path, $index)
                    );
                    if ($coercedItem['errors']) {
                        $errors = self::add($errors, $coercedItem['errors']);
                    } else {
                        $coercedValue[] = $coercedItem['value'];
                    }
                }

                return $errors ? self::ofErrors($errors) : self::ofValue($coercedValue);
            }
            // Lists accept a non-list value as a list of one.
            $coercedItem = self::coerceValue($value, $itemType, $blameNode);

            return $coercedItem['errors'] ? $coercedItem : self::ofValue([$coercedItem['value']]);
        }

        if ($type instanceof InputObjectType) {
            if (! is_object($value) && ! is_array($value) && ! $value instanceof Traversable) {
                return self::ofErrors([
                    self::coercionError(
                        sprintf('Expected type %s to be an object', $type->name),
                        $blameNode,
                        $path
                    ),
                ]);
            }

            $errors       = [];
            $coercedValue = [];
            $fields       = $type->getFields();
            foreach ($fields as $fieldName => $field) {
                if (array_key_exists($fieldName, $value)) {
                    $fieldValue   = $value[$fieldName];
                    $coercedField = self::coerceValue(
                        $fieldValue,
                        $field->getType(),
                        $blameNode,
                        self::atPath($path, $fieldName)
                    );
                    if ($coercedField['errors']) {
                        $errors = self::add($errors, $coercedField['errors']);
                    } else {
                        $coercedValue[$fieldName] = $coercedField['value'];
                    }
                } elseif ($field->defaultValueExists()) {
                    $coercedValue[$fieldName] = $field->defaultValue;
                } elseif ($field->getType() instanceof NonNull) {
                    $fieldPath = self::printPath(self::atPath($path, $fieldName));
                    $errors    = self::add(
                        $errors,
                        self::coercionError(
                            sprintf(
                                'Field %s of required type %s was not provided',
                                $fieldPath,
                                $field->type->toString()
                            ),
                            $blameNode
                        )
                    );
                }
            }

            // Ensure every provided field is defined.
            foreach ($value as $fieldName => $field) {
                if (array_key_exists($fieldName, $fields)) {
                    continue;
                }

                $suggestions = Utils::suggestionList(
                    $fieldName,
                    array_keys($fields)
                );
                $didYouMean  = $suggestions
                    ? 'did you mean ' . Utils::orList($suggestions) . '?'
                    : null;
                $errors      = self::add(
                    $errors,
                    self::coercionError(
                        sprintf('Field "%s" is not defined by type %s', $fieldName, $type->name),
                        $blameNode,
                        $path,
                        $didYouMean
                    )
                );
            }

            return $errors ? self::ofErrors($errors) : self::ofValue($coercedValue);
        }

        throw new Error(sprintf('Unexpected type %s', $type->name));
    }
public static function coerceValue ( $ value , InputType $ type , $ blameNode = null , ? array $ path = null ) { if ( $ type instanceof NonNull ) { if ( $ value === null ) { return self :: ofErrors ( [ self :: coercionError ( sprintf ( 'Expected non-nullable type %s not to be null' , $ type ) , $ blameNode , $ path ) , ] ) ; } return self :: coerceValue ( $ value , $ type -> getWrappedType ( ) , $ blameNode , $ path ) ; } if ( $ value === null ) { // Explicitly return the value null. return self :: ofValue ( null ) ; } if ( $ type instanceof ScalarType ) { // Scalars determine if a value is valid via parseValue(), which can // throw to indicate failure. If it throws, maintain a reference to // the original error. try { return self :: ofValue ( $ type -> parseValue ( $ value ) ) ; } catch ( Exception $ error ) { return self :: ofErrors ( [ self :: coercionError ( sprintf ( 'Expected type %s' , $ type -> name ) , $ blameNode , $ path , $ error -> getMessage ( ) , $ error ) , ] ) ; } catch ( Throwable $ error ) { return self :: ofErrors ( [ self :: coercionError ( sprintf ( 'Expected type %s' , $ type -> name ) , $ blameNode , $ path , $ error -> getMessage ( ) , $ error ) , ] ) ; } } if ( $ type instanceof EnumType ) { if ( is_string ( $ value ) ) { $ enumValue = $ type -> getValue ( $ value ) ; if ( $ enumValue ) { return self :: ofValue ( $ enumValue -> value ) ; } } $ suggestions = Utils :: suggestionList ( Utils :: printSafe ( $ value ) , array_map ( static function ( $ enumValue ) { return $ enumValue -> name ; } , $ type -> getValues ( ) ) ) ; $ didYouMean = $ suggestions ? 'did you mean ' . Utils :: orList ( $ suggestions ) . '?' : null ; return self :: ofErrors ( [ self :: coercionError ( sprintf ( 'Expected type %s' , $ type -> name ) , $ blameNode , $ path , $ didYouMean ) , ] ) ; } if ( $ type instanceof ListOfType ) { $ itemType = $ type -> getWrappedType ( ) ; if ( is_array ( $ value ) || $ value instanceof Traversable ) { $ errors = [ ] ; $ coercedValue = [ ] ; foreach ( $ value as $ index => $ itemValue ) { $ coercedItem = self :: coerceValue ( $ itemValue , $ itemType , $ blameNode , self :: atPath ( $ path , $ index ) ) ; if ( $ coercedItem [ 'errors' ] ) { $ errors = self :: add ( $ errors , $ coercedItem [ 'errors' ] ) ; } else { $ coercedValue [ ] = $ coercedItem [ 'value' ] ; } } return $ errors ? self :: ofErrors ( $ errors ) : self :: ofValue ( $ coercedValue ) ; } // Lists accept a non-list value as a list of one. $ coercedItem = self :: coerceValue ( $ value , $ itemType , $ blameNode ) ; return $ coercedItem [ 'errors' ] ? $ coercedItem : self :: ofValue ( [ $ coercedItem [ 'value' ] ] ) ; } if ( $ type instanceof InputObjectType ) { if ( ! is_object ( $ value ) && ! is_array ( $ value ) && ! $ value instanceof Traversable ) { return self :: ofErrors ( [ self :: coercionError ( sprintf ( 'Expected type %s to be an object' , $ type -> name ) , $ blameNode , $ path ) , ] ) ; } $ errors = [ ] ; $ coercedValue = [ ] ; $ fields = $ type -> getFields ( ) ; foreach ( $ fields as $ fieldName => $ field ) { if ( array_key_exists ( $ fieldName , $ value ) ) { $ fieldValue = $ value [ $ fieldName ] ; $ coercedField = self :: coerceValue ( $ fieldValue , $ field -> getType ( ) , $ blameNode , self :: atPath ( $ path , $ fieldName ) ) ; if ( $ coercedField [ 'errors' ] ) { $ errors = self :: add ( $ errors , $ coercedField [ 'errors' ] ) ; } else { $ coercedValue [ $ fieldName ] = $ coercedField [ 'value' ] ; } } elseif ( $ field -> defaultValueExists ( ) ) { $ coercedValue [ $ fieldName ] = $ field -> defaultValue ; } elseif ( $ field -> getType ( ) instanceof NonNull ) { $ fieldPath = self :: printPath ( self :: atPath ( $ path , $ fieldName ) ) ; $ errors = self :: add ( $ errors , self :: coercionError ( sprintf ( 'Field %s of required type %s was not provided' , $ fieldPath , $ field -> type -> toString ( ) ) , $ blameNode ) ) ; } } // Ensure every provided field is defined. foreach ( $ value as $ fieldName => $ field ) { if ( array_key_exists ( $ fieldName , $ fields ) ) { continue ; } $ suggestions = Utils :: suggestionList ( $ fieldName , array_keys ( $ fields ) ) ; $ didYouMean = $ suggestions ? 'did you mean ' . Utils :: orList ( $ suggestions ) . '?' : null ; $ errors = self :: add ( $ errors , self :: coercionError ( sprintf ( 'Field "%s" is not defined by type %s' , $ fieldName , $ type -> name ) , $ blameNode , $ path , $ didYouMean ) ) ; } return $ errors ? self :: ofErrors ( $ errors ) : self :: ofValue ( $ coercedValue ) ; } throw new Error ( sprintf ( 'Unexpected type %s' , $ type -> name ) ) ; }
Given a type and any value, return a runtime value coerced to match the type.

@param mixed[] $path
Given a type and any value return a runtime value coerced to match the type .