MetadataController
in package
Hand-written controller that contributes the `_apiMetadata` root query field and the supporting `MetadataEntry`, `MetadataTarget`, `MetadataValue` and `AuthEntry` types to the generated schema.
The autogenerated RootQueryType references this controller alongside the
autogenerated query resolvers, so the field appears on the root Query
type without any special wiring at the controller level. The resolver
delegates to {@see} for the schema walk and
filter application, then reshapes the rows so each entry is exposed as the
{ name, value } pair that MetadataEntry expects. Authorization
descriptors (each row's authorization list) pass through unchanged.
Access is gated by {@see}; once allowed, the returned content is principal-independent — the full declared shape of the schema, irrespective of who is calling.
Table of Contents
- FIELD_NAME = '_apiMetadata'
- GraphQL field name used on the root `Query` type.
- $auth_entry_type : ObjectType|null
- Memoised `AuthEntry` output type — describes one authorization attribute attached to a schema target.
- $entry_type : ObjectType|null
- Memoised `MetadataEntry` output type.
- $target_type : ObjectType|null
- Memoised `MetadataTarget` output type.
- $value_scalar : CustomScalarType|null
- Memoised `MetadataValue` scalar type.
- get_field_definition() : array<string, mixed>
- Field definition for the root `_apiMetadata` query, in the shape the autogenerated `RootQueryType` expects (same as every autogenerated resolver's `get_field_definition()`).
- resolve() : array<int, array<string, mixed>>
- Resolver for the `_apiMetadata` root field. Signature matches the engine's resolver contract; `$root` is unused here (root operations have no parent). `$context` is read for the principal so the `can_query_metadata` ladder can run.
- build_metadata_query_authorization_error() : Error
- Build the GraphQL error thrown when `_apiMetadata` is queried by a principal that cannot. Mirrors {@see ResolverHelpers::build_authorization_error()}'s UNAUTHORIZED / FORBIDDEN distinction so clients can branch on `extensions.code` the same way they do for field-level denies.
- can_query_metadata() : bool
- Whether the principal may run the `_apiMetadata` query.
- get_auth_entry_type() : ObjectType
- The `AuthEntry` output type — one authorization attribute attached to a target. Carries the attribute's short class name and the scalar args supplied at the usage site.
- get_entry_type() : ObjectType
- The `MetadataEntry` output type, lazily built and cached.
- get_target_type() : ObjectType
- The `MetadataTarget` output type, lazily built and cached.
- get_value_scalar() : CustomScalarType
- The `MetadataValue` custom scalar, accepting any GraphQL-compatible scalar.
Constants
FIELD_NAME
GraphQL field name used on the root `Query` type.
public
mixed
FIELD_NAME
= '_apiMetadata'
Properties
$auth_entry_type
Memoised `AuthEntry` output type — describes one authorization attribute attached to a schema target.
private
static ObjectType|null
$auth_entry_type
= null
$entry_type
Memoised `MetadataEntry` output type.
private
static ObjectType|null
$entry_type
= null
$target_type
Memoised `MetadataTarget` output type.
private
static ObjectType|null
$target_type
= null
$value_scalar
Memoised `MetadataValue` scalar type.
private
static CustomScalarType|null
$value_scalar
= null
Methods
get_field_definition()
Field definition for the root `_apiMetadata` query, in the shape the autogenerated `RootQueryType` expects (same as every autogenerated resolver's `get_field_definition()`).
public
static get_field_definition() : array<string, mixed>
Return values
array<string, mixed> —resolve()
Resolver for the `_apiMetadata` root field. Signature matches the engine's resolver contract; `$root` is unused here (root operations have no parent). `$context` is read for the principal so the `can_query_metadata` ladder can run.
public
static resolve(array<string|int, mixed>|null $root, array<string|int, mixed> $args, mixed $context, ResolveInfo $info) : array<int, array<string, mixed>>
Parameters
- $root : array<string|int, mixed>|null
-
The engine passes null for root resolvers.
- $args : array<string|int, mixed>
-
GraphQL arguments (
name,type,field,attribute). - $context : mixed
-
Per-request context — an ArrayObject wrapping {
principal,_query_metadata}. - $info : ResolveInfo
-
Carries the schema instance to walk.
Tags
Return values
array<int, array<string, mixed>> —build_metadata_query_authorization_error()
Build the GraphQL error thrown when `_apiMetadata` is queried by a principal that cannot. Mirrors {@see ResolverHelpers::build_authorization_error()}'s UNAUTHORIZED / FORBIDDEN distinction so clients can branch on `extensions.code` the same way they do for field-level denies.
private
static build_metadata_query_authorization_error(object|null $principal) : Error
Parameters
- $principal : object|null
-
The resolved principal (null when principal resolution failed).
Return values
Error —can_query_metadata()
Whether the principal may run the `_apiMetadata` query.
private
static can_query_metadata(object|null $principal) : bool
Tri-tier ladder, deliberately fail-closed:
- If the principal declares
can_query_metadata(): bool, use it. Plugins distinguish metadata-query access from native introspection access by declaring this method. - Else if the principal declares
can_introspect(): bool, fall back to it — one switch then gates both metadata and introspection, which is the common case. - Else (neither method declared) deny. Plugin authors that don't opt their principal in get a locked-down endpoint rather than leaking schema shape and gate descriptors by default.
The principal-derived decision is then passed through the {@see 'woocommerce_graphql_can_query_metadata'} filter so sites can grant or revoke access without subclassing the principal — useful for per-request rules (specific IPs, headers, query parameters, etc.).
Fail-closed contract: null principal denies before the filter is
consulted; either method's return is checked with === true; any
throw from the principal method or the filter denies; the filter
must likewise return strictly true to allow.
Parameters
- $principal : object|null
-
The resolved principal, or null when principal resolution failed.
Return values
bool —get_auth_entry_type()
The `AuthEntry` output type — one authorization attribute attached to a target. Carries the attribute's short class name and the scalar args supplied at the usage site.
private
static get_auth_entry_type() : ObjectType
Return values
ObjectType —get_entry_type()
The `MetadataEntry` output type, lazily built and cached.
private
static get_entry_type() : ObjectType
Return values
ObjectType —get_target_type()
The `MetadataTarget` output type, lazily built and cached.
private
static get_target_type() : ObjectType
Return values
ObjectType —get_value_scalar()
The `MetadataValue` custom scalar, accepting any GraphQL-compatible scalar.
private
static get_value_scalar() : CustomScalarType
The autogenerated scalar template hard-codes acceptance of string
literals only, so this scalar is hand-built rather than going through
ApiBuilder. parseLiteral walks the AST node types and parseValue
accepts the already-decoded PHP scalar that variables-mode delivers.
