API / Minn\Rest / Schema

Schema final readonly class

Minn\Rest\Schema · public/minn/src/Minn/Rest/Schema.php · 503 lines

JSON-schema handling the way the REST API's argument validation does it: validate a value against a schema (a Refusal names what failed), sanitise it into the schema's type, filter a response by context, and the type tests the schema vocabulary needs. Behaviour pinned by contracts/fixtures/api/rest.json.

Constants and properties

privateTYPES = array ( 0 => 'array', 1 => 'object', 2 => 'string', 3 => 'number', 4 => 'integer', 5 => 'boolean', 6 => 'null', )
constKEYWORDS = array ( 0 => 'title', 1 => 'description', 2 => 'default', 3 => 'type', 4 => 'format', 5 => 'enum', 6 => 'items', 7 => 'properties', 8 => 'additionalProperties', 9 => 'patternProperties', 10 => 'minProperties', 11 => 'maxProperties', 12 => 'minimum', 13 => 'maximum', 14 => 'exclusiveMinimum', 15 => 'exclusiveMaximum', 16 => 'multipleOf', 17 => 'minLength', 18 => 'maxLength', 19 => 'pattern', 20 => 'minItems', 21 => 'maxItems', 22 => 'uniqueItems', 23 => 'anyOf', 24 => 'oneOf', )

Every keyword a route schema may carry, in the reference's order; the endpoint subset drops the three descriptive ones.

privateENDPOINT_KEYWORDS = array ( 0 => 'type', 1 => 'format', 2 => 'enum', 3 => 'items', 4 => 'properties', 5 => 'additionalProperties', 6 => 'patternProperties', 7 => 'minProperties', 8 => 'maxProperties', 9 => 'minimum', 10 => 'maximum', 11 => 'exclusiveMinimum', 12 => 'exclusiveMaximum', 13 => 'multipleOf', 14 => 'minLength', 15 => 'maxLength', 16 => 'pattern', 17 => 'minItems', 18 => 'maxItems', 19 => 'uniqueItems', 20 => 'anyOf', 21 => 'oneOf', )

An object schema that names its properties forbids the others unless it says otherwise, all the way down.

privatereadonly Closure $email

Promoted from the constructor.

privatereadonly Closure $number

Promoted from the constructor.

privatereadonly Closure $format

Promoted from the constructor.

Public

new__construct(Closure $email, Closure $number, Closure $format)#
$emailClosure(string): boolthe email test, so the reference's is_email filter applies
$numberClosure(int|float): stringthe localised number formatter for messages
$formatClosure(string, mixed): mixedthe sanitiser for a string format (hex-color, email, uri, ...)
methodvalidate(mixed $value, array $args, string $param = ''): Minn\Runtime\Refusal|true#

Whether a value satisfies a schema, or the reference's refusal.

methodchoices(): Minn\Rest\SchemaChoices#

A schema's anyOf and oneOf: which of their schemas a value matches, and the refusal when not as wanted.

methodvalidateAs(string $type, mixed $value, array $args, string $param): Minn\Runtime\Refusal|true#

One type's own checks, as the per-type validators run them: a number's bounds before an integer's wholeness, and no enum or format.

methodvalidateEnum(mixed $value, array $args, string $param): Minn\Runtime\Refusal|true#

Whether a value is one of the schema's enum, coerced to the schema's type first when it names one.

methodsanitize(mixed $value, array $args, string $param = ''): mixed#

A value coerced to its schema's types.

methodfilterByContext(mixed $data, array $schema, string $context): mixed#

Drops the properties whose schema does not list the context; an array whose items do not is emptied.

methodanyMatching(mixed $value, array $args, string $param): ?array#

The first anyOf branch the value validates against.

staticendpointArgs(array $schema, bool $creatable): array#

The argument map a route derives from an item schema: every writable property with the default validators, its keywords, defaults and required flags on the create route only, and any arg_options overrides.

staticcastEmptyObjects(mixed $value, array $schema): mixed#

A value with each empty array the schema calls an object made one (it encodes as {}), through properties, additional properties, list items and the value as a whole (probe rest-view-config).

$schemaarray<string, mixed>
staticcloseObjects(array $schema): array#

The schema with additionalProperties closed on every object.

Internals 10

Private and protected methods: how the class does its work. Not a contract; they change whenever the code is tidied.

privatevalidateInteger(mixed $value, array $args, string $param): ?Minn\Runtime\Refusal#

Numeric, within bounds and a multiple, then whole; null when the integer passes. A value that is not numeric names the schema's own type, empty when the schema names none (the reference words it "p is not of type .").

privatevalidateString(mixed $value, array $args, string $param): ?Minn\Runtime\Refusal#

Length and pattern; null when the string passes.

privatevalidateNumber(mixed $value, array $args, string $param): ?Minn\Runtime\Refusal#

Bounds and multipleOf; null when the number passes.

privatevalidateArray(mixed $value, array $args, string $param): ?Minn\Runtime\Refusal#
privatefirstMissing(array $args, array $value): ?string#

The first property an object schema requires and the value lacks. A list under 'required' (draft 4) wins; without one, each property's own 'required' => true (draft 3) counts.

privatevalidateObject(mixed $value, array $args, string $param): ?Minn\Runtime\Refusal#
privatevalidateFormat(mixed $value, string $format, string $param): ?Minn\Runtime\Refusal#
privatevalidateBounds(mixed $value, array $args, string $param): ?Minn\Runtime\Refusal#
privateenum(mixed $value, array $enum, string $param): Minn\Runtime\Refusal|true#
privatewrongType(string $param, string $type): Minn\Runtime\Refusal#