Automattic\WooCommerce\Api\Infrastructure

ResolverHelpers::compute_preauthorizedpublic staticWC 1.0

Compute the value _preauthorized would carry for the given command and principal (the AND of the autodiscovered authorization attributes' authorize() outcomes).

Lets code-API callers (and tests) ask "would this command's attribute-based authorization grant access to this principal?" without going through the GraphQL pipeline.

Note that it returns true when the command has no authorization attributes (in that case the command's own authorize() method, if any, is the sole guard; and consulting it requires running the command, which this helper deliberately doesn't do).

Note: this provides the attribute-level authorization only. A command with both attributes and an authorize() method composes the two via the _preauthorized infrastructure parameter; this helper returns the value that _preauthorized would carry, not the final authorize() outcome.

Scope is class-level (queries / mutations). Field-level authorization lives on output-type / input-type properties and is enforced inside the generated resolvers. To inspect a field's declared authorization from code, walk \Automattic\WooCommerce\Api\Utils\SchemaHandle::find_metadata() and read the authorization slice on each row.

Method of the class: ResolverHelpers{}

No Hooks.

Returns

null. Nothing (null).

Usage

$result = ResolverHelpers::compute_preauthorized( $command_fqcn, $principal ): bool;
$command_fqcn(string) (required)
Fully-qualified command class name.
$principal(object) (required)
The resolved principal. Anonymous requests are represented by a sentinel principal (e.g. Principal{} whose underlying WP_User has ID=0), not by null.

ResolverHelpers::compute_preauthorized() code WC 10.9.1

public static function compute_preauthorized( string $command_fqcn, object $principal ): bool {
	if ( ! class_exists( $command_fqcn ) ) {
		throw new \InvalidArgumentException(
			sprintf( 'Class %s does not exist.', esc_html( $command_fqcn ) )
		);
	}
	$ref    = new \ReflectionClass( $command_fqcn );
	$direct = self::collect_authorization_instances( $ref );
	$usages = $direct;
	if ( empty( $usages ) ) {
		// No direct attribute — collect from the entire ancestor tree:
		// the parent chain plus each ancestor's traits and interfaces
		// (recursively). All inherited sources contribute as peers; the
		// only thing direct attributes shadow is the inherited tree as a
		// whole. Mirrors
		// {@see \Automattic\WooCommerce\Api\Infrastructure\DesignTime\ApiBuilder::resolve_authorization()}.
		$visited = array();
		$stack   = array_merge(
			$ref->getParentClass() ? array( $ref->getParentClass() ) : array(),
			$ref->getTraits(),
			$ref->getInterfaces(),
		);
		while ( ! empty( $stack ) ) {
			$source = array_shift( $stack );
			$name   = $source->getName();
			if ( in_array( $name, $visited, true ) ) {
				continue;
			}
			$visited[] = $name;
			$usages    = array_merge( $usages, self::collect_authorization_instances( $source ) );
			if ( false !== $source->getParentClass() ) {
				$stack[] = $source->getParentClass();
			}
			$stack = array_merge( $stack, $source->getTraits(), $source->getInterfaces() );
		}
	}

	$query_metadata = self::harvest_class_metadata( $ref );

	foreach ( $usages as $instance ) {
		$auth_method = new \ReflectionMethod( $instance, 'authorize' );
		$call_args   = self::build_authorize_call_args(
			$auth_method,
			$principal,
			array( 'query' => $query_metadata ),
			array(),
			null
		);
		$result      = $instance->authorize( ...$call_args );
		if ( ! $result ) {
			return false;
		}
	}
	return true;
}