/** * Given a type and any value, return a runtime value coerced to match the type. */ private static function coerceValue(Type $type, $value) { if ($type instanceof NonNull) { // Note: we're not checking that the result of coerceValue is non-null. // We only call this function after calling isValidValue. return self::coerceValue($type->getWrappedType(), $value); } if (null === $value) { return null; } if ($type instanceof ListOfType) { $itemType = $type->getWrappedType(); // TODO: support iterable input if (is_array($value)) { return array_map(function ($item) use($itemType) { return Values::coerceValue($itemType, $item); }, $value); } else { return [self::coerceValue($itemType, $value)]; } } if ($type instanceof InputObjectType) { $fields = $type->getFields(); $obj = []; foreach ($fields as $fieldName => $field) { $fieldValue = self::coerceValue($field->getType(), isset($value[$fieldName]) ? $value[$fieldName] : null); if (null === $fieldValue) { $fieldValue = $field->defaultValue; } if (null !== $fieldValue) { $obj[$fieldName] = $fieldValue; } } return $obj; } Utils::invariant($type instanceof ScalarType || $type instanceof EnumType, 'Must be input type'); return $type->parseValue($value); }
/** * Given a type and any value, return a runtime value coerced to match the type. */ private static function coerceValue(Type $type, $value) { $undefined = Utils::undefined(); if ($value === $undefined) { return $undefined; } if ($type instanceof NonNull) { if ($value === null) { // Intentionally return no value. return $undefined; } return self::coerceValue($type->getWrappedType(), $value); } if (null === $value) { return null; } if ($type instanceof ListOfType) { $itemType = $type->getWrappedType(); if (is_array($value) || $value instanceof \Traversable) { $coercedValues = []; foreach ($value as $item) { $itemValue = self::coerceValue($itemType, $item); if ($undefined === $itemValue) { // Intentionally return no value. return $undefined; } $coercedValues[] = $itemValue; } return $coercedValues; } else { $coercedValue = self::coerceValue($itemType, $value); if ($coercedValue === $undefined) { // Intentionally return no value. return $undefined; } return [$coercedValue]; } } if ($type instanceof InputObjectType) { $coercedObj = []; $fields = $type->getFields(); foreach ($fields as $fieldName => $field) { if (!array_key_exists($fieldName, $value)) { if ($field->defaultValueExists()) { $coercedObj[$fieldName] = $field->defaultValue; } else { if ($field->getType() instanceof NonNull) { // Intentionally return no value. return $undefined; } } continue; } $fieldValue = self::coerceValue($field->getType(), $value[$fieldName]); if ($fieldValue === $undefined) { // Intentionally return no value. return $undefined; } $coercedObj[$fieldName] = $fieldValue; } return $coercedObj; } if ($type instanceof LeafType) { $parsed = $type->parseValue($value); if (null === $parsed) { // null or invalid values represent a failure to parse correctly, // in which case no value is returned. return $undefined; } return $parsed; } throw new InvariantViolation('Must be input type'); }
/** * Check if value is valid using GraphQL Type * * @param array $value * @param Type $type * * @return boolean */ private function isValidValue($value, Type $type) { if ($type instanceof NonNull) { if (null === $value) { return false; } return $this->isValidValue($value, $type->getWrappedType()); } if ($value === null) { return true; } if ($type instanceof ListOfType) { $itemType = $type->getWrappedType(); if (is_array($value)) { foreach ($value as $item) { if (!$this->isValidValue($item, $itemType)) { return false; } } return true; } else { return $this->isValidValue($value, $itemType); } } if ($type instanceof InputObjectType) { if (!is_array($value)) { return false; } $fields = $type->getFields(); $fieldMap = []; foreach ($fields as $fieldName => $field) { if (!$this->isValidValue(isset($value[$fieldName]) ? $value[$fieldName] : null, $field->getType())) { return false; } $fieldMap[$field->name] = $field; } $diff = array_diff_key($value, $fieldMap); if (!empty($diff)) { return false; } return true; } Utils::invariant($type instanceof ScalarType || $type instanceof EnumType, 'Must be input type'); return null !== $type->parseValue($value); }
/** * Given a type and any value, return a runtime value coerced to match the type. */ private static function coerceValue(Type $type, $value) { if ($type instanceof NonNull) { // Note: we're not checking that the result of coerceValue is non-null. // We only call this function after calling isValidPHPValue. return self::coerceValue($type->getWrappedType(), $value); } if (null === $value) { return null; } if ($type instanceof ListOfType) { $itemType = $type->getWrappedType(); if (is_array($value) || $value instanceof \Traversable) { return Utils::map($value, function ($item) use($itemType) { return Values::coerceValue($itemType, $item); }); } else { return [self::coerceValue($itemType, $value)]; } } if ($type instanceof InputObjectType) { $fields = $type->getFields(); $obj = []; foreach ($fields as $fieldName => $field) { $fieldValue = self::coerceValue($field->getType(), isset($value[$fieldName]) ? $value[$fieldName] : null); if (null === $fieldValue) { $fieldValue = $field->defaultValue; } if (null !== $fieldValue) { $obj[$fieldName] = $fieldValue; } } return $obj; } if ($type instanceof LeafType) { return $type->parseValue($value); } throw new InvariantViolation('Must be input type'); }