Find this useful? Enter your email to receive occasional updates for securing PHP code.
Signing you up...
Thank you for signing up!
PHP Decode
<?php declare(strict_types=1); namespace GraphQL\Utils; use GraphQL\Error\CoercionError;..
Decoded Output download
<?php declare(strict_types=1);
namespace GraphQL\Utils;
use GraphQL\Error\CoercionError;
use GraphQL\Error\Error;
use GraphQL\Error\InvariantViolation;
use GraphQL\Type\Definition\EnumType;
use GraphQL\Type\Definition\InputObjectType;
use GraphQL\Type\Definition\InputType;
use GraphQL\Type\Definition\ListOfType;
use GraphQL\Type\Definition\NonNull;
use GraphQL\Type\Definition\ScalarType;
use GraphQL\Type\Definition\Type;
/**
* @phpstan-type CoercedValue array{errors: null, value: mixed}
* @phpstan-type CoercedErrors array{errors: array<int, CoercionError>, value: null}
*
* @phpstan-import-type InputPath from CoercionError
*/
class Value
{
/**
* Coerce the given value to match the given GraphQL Input Type.
*
* Returns either a value which is valid for the provided type,
* or a list of encountered coercion errors.
*
* @param mixed $value
* @param InputType&Type $type
*
* @phpstan-param InputPath|null $path
*
* @phpstan-return CoercedValue|CoercedErrors
*
* @throws InvariantViolation
*/
public static function coerceInputValue($value, InputType $type, ?array $path = 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);
}
if ($value === null) {
// Explicitly return the value null.
return self::ofValue(null);
}
if ($type instanceof ScalarType || $type instanceof EnumType) {
// Scalars and Enums determine if a input 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 (\Throwable $error) {
if ($error instanceof Error) {
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]
);
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);
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],
);
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)
);
}
return $errors === []
? self::ofValue($type->parseValue($coercedValue))
: self::ofErrors($errors);
}
/**
* @param array<int, CoercionError> $errors
*
* @phpstan-return CoercedErrors
*/
private static function ofErrors(array $errors): array
{
return ['errors' => $errors, 'value' => null];
}
/**
* @param mixed $value any value
*
* @phpstan-return CoercedValue
*/
private static function ofValue($value): array
{
return ['errors' => null, 'value' => $value];
}
/**
* @param array<int, CoercionError> $errors
* @param CoercionError|array<int, CoercionError> $errorOrErrors
*
* @return array<int, CoercionError>
*/
private static function add(array $errors, $errorOrErrors): array
{
$moreErrors = is_array($errorOrErrors)
? $errorOrErrors
: [$errorOrErrors];
return array_merge($errors, $moreErrors);
}
}
?>
Did this file decode correctly?
Original Code
<?php declare(strict_types=1);
namespace GraphQL\Utils;
use GraphQL\Error\CoercionError;
use GraphQL\Error\Error;
use GraphQL\Error\InvariantViolation;
use GraphQL\Type\Definition\EnumType;
use GraphQL\Type\Definition\InputObjectType;
use GraphQL\Type\Definition\InputType;
use GraphQL\Type\Definition\ListOfType;
use GraphQL\Type\Definition\NonNull;
use GraphQL\Type\Definition\ScalarType;
use GraphQL\Type\Definition\Type;
/**
* @phpstan-type CoercedValue array{errors: null, value: mixed}
* @phpstan-type CoercedErrors array{errors: array<int, CoercionError>, value: null}
*
* @phpstan-import-type InputPath from CoercionError
*/
class Value
{
/**
* Coerce the given value to match the given GraphQL Input Type.
*
* Returns either a value which is valid for the provided type,
* or a list of encountered coercion errors.
*
* @param mixed $value
* @param InputType&Type $type
*
* @phpstan-param InputPath|null $path
*
* @phpstan-return CoercedValue|CoercedErrors
*
* @throws InvariantViolation
*/
public static function coerceInputValue($value, InputType $type, ?array $path = 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);
}
if ($value === null) {
// Explicitly return the value null.
return self::ofValue(null);
}
if ($type instanceof ScalarType || $type instanceof EnumType) {
// Scalars and Enums determine if a input 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 (\Throwable $error) {
if ($error instanceof Error) {
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]
);
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);
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],
);
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)
);
}
return $errors === []
? self::ofValue($type->parseValue($coercedValue))
: self::ofErrors($errors);
}
/**
* @param array<int, CoercionError> $errors
*
* @phpstan-return CoercedErrors
*/
private static function ofErrors(array $errors): array
{
return ['errors' => $errors, 'value' => null];
}
/**
* @param mixed $value any value
*
* @phpstan-return CoercedValue
*/
private static function ofValue($value): array
{
return ['errors' => null, 'value' => $value];
}
/**
* @param array<int, CoercionError> $errors
* @param CoercionError|array<int, CoercionError> $errorOrErrors
*
* @return array<int, CoercionError>
*/
private static function add(array $errors, $errorOrErrors): array
{
$moreErrors = is_array($errorOrErrors)
? $errorOrErrors
: [$errorOrErrors];
return array_merge($errors, $moreErrors);
}
}
Function Calls
None |
Stats
MD5 | 3b4ebbc85213f844292de3272f3ef4dd |
Eval Count | 0 |
Decode Time | 93 ms |