Automattic\WooCommerce\Vendor\GraphQL\Utils
Value::coerceInputValue │ public static │ WC 1.0
Coerce the given value to match the given Automattic\WooCommerce\Vendor\GraphQL Input Type.
Returns either a value which is valid for the provided type, or a list of encountered coercion errors.
Method of the class: Value{}
No Hooks.
Returns
null. Nothing (null).
Usage
$result = Value::coerceInputValue( $value, $type, ?array $path, ?Schema $schema ): array;
- $value(mixed) (required)
- .
- $type(InputType&Type) (required)
- .
- ?array $path
- .
Default:null - ?Schema $schema
- .
Default:null
Value::coerceInputValue() Value::coerceInputValue code WC 11.1.2
public static function coerceInputValue($value, InputType $type, ?array $path = null, ?Schema $schema = null): array
{
if ($type instanceof NonNull) {
if ($value === null) {
return self::ofErrors([
CoercionError::make("Expected non-nullable type \"{$type}\" not to be null.", $path, $value),
]);
}
// @phpstan-ignore-next-line wrapped type is known to be input type after schema validation
return self::coerceInputValue($value, $type->getWrappedType(), $path, $schema);
}
if ($value === null) {
// Explicitly return the value null.
return self::ofValue(null);
}
// 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 parseValue() is called.
if ($schema !== null && Type::isBuiltInScalar($type)) {
$schemaType = $schema->getType($type->name);
assert($schemaType instanceof ScalarType, "Schema must provide a ScalarType for built-in scalar \"{$type->name}\".");
$type = $schemaType;
}
if ($type instanceof ScalarType || $type instanceof EnumType) {
try {
return self::ofValue($type->parseValue($value));
} catch (\Throwable $error) {
if (
$error instanceof Error
|| ($error instanceof ClientAware && $error->isClientSafe())
) {
return self::ofErrors([
CoercionError::make($error->getMessage(), $path, $value, $error),
]);
}
return self::ofErrors([
CoercionError::make("Expected type \"{$type->name}\".", $path, $value, $error),
]);
}
}
if ($type instanceof ListOfType) {
$itemType = $type->getWrappedType();
assert($itemType instanceof InputType, 'known through schema validation');
if (is_iterable($value)) {
$errors = [];
$coercedValue = [];
foreach ($value as $index => $itemValue) {
$coercedItem = self::coerceInputValue(
$itemValue,
$itemType,
[...$path ?? [], $index],
$schema,
);
if (isset($coercedItem['errors'])) {
$errors = self::add($errors, $coercedItem['errors']);
} else {
$coercedValue[] = $coercedItem['value'];
}
}
return $errors === []
? self::ofValue($coercedValue)
: self::ofErrors($errors);
}
// Lists accept a non-list value as a list of one.
$coercedItem = self::coerceInputValue($value, $itemType, null, $schema);
return isset($coercedItem['errors'])
? $coercedItem
: self::ofValue([$coercedItem['value']]);
}
assert($type instanceof InputObjectType, 'we handled all other cases at this point');
if ($value instanceof \stdClass) {
// Cast objects to associative array before checking the fields.
// Note that the coerced value will be an array.
$value = (array) $value;
} elseif (! is_array($value)) {
return self::ofErrors([
CoercionError::make("Expected type \"{$type->name}\" to be an object.", $path, $value),
]);
}
$errors = [];
$coercedValue = [];
$fields = $type->getFields();
foreach ($fields as $fieldName => $field) {
if (array_key_exists($fieldName, $value)) {
$fieldValue = $value[$fieldName];
$coercedField = self::coerceInputValue(
$fieldValue,
$field->getType(),
[...$path ?? [], $fieldName],
$schema,
);
if (isset($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) {
$errors = self::add(
$errors,
CoercionError::make("Field \"{$fieldName}\" of required type \"{$field->getType()->toString()}\" was not provided.", $path, $value)
);
}
}
// Ensure every provided field is defined.
foreach ($value as $fieldName => $field) {
if (array_key_exists($fieldName, $fields)) {
continue;
}
$suggestions = Utils::suggestionList(
(string) $fieldName,
array_keys($fields)
);
$message = "Field \"{$fieldName}\" is not defined by type \"{$type->name}\"."
. ($suggestions === []
? ''
: ' Did you mean ' . Utils::quotedOrList($suggestions) . '?');
$errors = self::add(
$errors,
CoercionError::make($message, $path, $value)
);
}
// Validate OneOf constraints if this is a OneOf input type
if ($type->isOneOf()) {
$providedFieldCount = count($coercedValue);
$nullFieldName = null;
if ($providedFieldCount !== 1) {
$errors = self::add(
$errors,
CoercionError::make("OneOf input object \"{$type->name}\" must specify exactly one field.", $path, $value)
);
} else {
foreach ($coercedValue as $fieldName => $fieldValue) {
if ($fieldValue === null) {
$nullFieldName = $fieldName;
}
}
if ($nullFieldName !== null) {
$errors = self::add(
$errors,
CoercionError::make("OneOf input object \"{$type->name}\" field \"{$nullFieldName}\" must be non-null.", $path, $value)
);
}
}
}
return $errors === []
? self::ofValue($type->parseValue($coercedValue))
: self::ofErrors($errors);
}