controllerOverride = $controllerOverride; } /** * Register route and controller. * * @param ServiceProviderRegistry $registry Registry. */ public function register( ServiceProviderRegistry $registry ): void { $options = $this->resolveOptionStore( $registry ); $policy = $this->resolveCapabilityPolicy( $registry ); $registrar = $this->resolveRouteRegistrar( $registry ); $clicks = $this->resolveClickEventRepository( $registry ); $controller = $this->controllerOverride ?? new ClicksController( $options, $policy, new RestRequestAdapter(), null, null, $clicks ); $this->resolvedController = $controller; $registry->bind( self::BINDING_CONTROLLER, $controller ); $permissionCallback = static function ( $request = null ): bool { unset( $request ); return true; }; $registrar->add( new RouteDefinition( RestNamespace::FULL, '/clicks', RouteDefinition::METHOD_POST, ClicksController::ROUTE_TOKEN_WRITE, array(), $this->buildRouteCallback(), $permissionCallback ) ); } /** * No hooks; routes are appended at register time. * * @param HookRegistrar $hooks Hooks. */ public function boot( HookRegistrar $hooks ): void { unset( $hooks ); } /** * Build route callback. * * @phpstan-return Closure(mixed): mixed */ private function buildRouteCallback(): Closure { return function ( mixed $request ): mixed { if ( $this->resolvedController === null ) { throw new LogicException( 'ClicksServiceProvider route callback invoked before register() ran.' ); } $envelope = $this->resolvedController->record( $request ); $status = isset( $envelope[ ClicksController::META_HTTP_STATUS ] ) && is_int( $envelope[ ClicksController::META_HTTP_STATUS ] ) ? $envelope[ ClicksController::META_HTTP_STATUS ] : 200; unset( $envelope[ ClicksController::META_HTTP_STATUS ] ); if ( class_exists( '\\WP_REST_Response' ) ) { return new \WP_REST_Response( $envelope, $status ); } return array( 'data' => $envelope, 'status' => $status, ); }; } /** * Resolve option store. * * @param ServiceProviderRegistry $registry Registry. * * @throws LogicException When the binding is missing or invalid. */ private function resolveOptionStore( ServiceProviderRegistry $registry ): OptionStore { $key = PersistenceServiceProvider::BINDING_OPTION_STORE; if ( ! $registry->has( $key ) ) { throw new LogicException( 'ClicksServiceProvider requires PersistenceServiceProvider option store.' ); } $options = $registry->get( $key ); if ( ! $options instanceof OptionStore ) { throw new LogicException( 'ClicksServiceProvider expected OptionStore.' ); } return $options; } /** * Resolve optional click event repository. * * @param ServiceProviderRegistry $registry Registry. */ private function resolveClickEventRepository( ServiceProviderRegistry $registry ): ?ClickEventRepository { $key = PersistenceServiceProvider::BINDING_CLICK_EVENT_REPOSITORY; if ( ! $registry->has( $key ) ) { return null; } $repository = $registry->get( $key ); return $repository instanceof ClickEventRepository ? $repository : null; } /** * Resolve capability policy. * * @param ServiceProviderRegistry $registry Registry. * * @throws LogicException When the binding is missing or invalid. */ private function resolveCapabilityPolicy( ServiceProviderRegistry $registry ): CapabilityPolicy { $key = RestServiceProvider::BINDING_CAPABILITY_POLICY; if ( ! $registry->has( $key ) ) { throw new LogicException( 'ClicksServiceProvider requires RestServiceProvider capability policy.' ); } $policy = $registry->get( $key ); if ( ! $policy instanceof CapabilityPolicy ) { throw new LogicException( 'ClicksServiceProvider expected CapabilityPolicy.' ); } return $policy; } /** * Resolve route registrar. * * @param ServiceProviderRegistry $registry Registry. * * @throws LogicException When the binding is missing or invalid. */ private function resolveRouteRegistrar( ServiceProviderRegistry $registry ): RouteRegistrar { $key = RestServiceProvider::BINDING_ROUTE_REGISTRAR; if ( ! $registry->has( $key ) ) { throw new LogicException( 'ClicksServiceProvider requires RestServiceProvider route registrar.' ); } $registrar = $registry->get( $key ); if ( ! $registrar instanceof RouteRegistrar ) { throw new LogicException( 'ClicksServiceProvider expected RouteRegistrar.' ); } return $registrar; } }