query = $query; } /** * Class identifier used by `woocommerce_rest_api_get_rest_namespaces`. * * Distinct from the URL namespace, because the filter keys one class per * value and sibling controllers share the URL namespace. * * @return string * * @since 11.3.0 */ protected function get_rest_api_namespace(): string { return 'wc-push-notifications-step-logs'; } /** * Registers the routes. * * @return void * * @since 11.3.0 */ public function register_routes(): void { register_rest_route( $this->route_namespace, $this->rest_base . '/site', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => fn ( WP_REST_Request $request ) => $this->run( $request, 'get_site' ), 'permission_callback' => array( $this, 'authorize_as_from_wpcom' ), 'args' => $this->get_range_args(), ), ) ); register_rest_route( $this->route_namespace, $this->rest_base . '/notifications/(?P[a-z_]+)/(?P\d+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => fn ( WP_REST_Request $request ) => $this->run( $request, 'get_notification' ), 'permission_callback' => array( $this, 'authorize_as_from_wpcom' ), 'args' => array_merge( array( 'type' => array( 'type' => 'string', 'required' => true, 'enum' => array_keys( Notification::NOTIFICATION_CLASSES ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ), 'resource_id' => array( 'type' => 'integer', 'required' => true, 'minimum' => 1, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ), ), $this->get_range_args() ), ), ) ); register_rest_route( $this->route_namespace, $this->rest_base . '/tokens/(?P\d+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => fn ( WP_REST_Request $request ) => $this->run( $request, 'get_token' ), 'permission_callback' => array( $this, 'authorize_as_from_wpcom' ), 'args' => array_merge( array( 'token_id' => array( 'type' => 'integer', 'required' => true, 'minimum' => 1, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ), ), $this->get_range_args() ), ), ) ); register_rest_route( $this->route_namespace, $this->rest_base . '/users/(?P\d+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => fn ( WP_REST_Request $request ) => $this->run( $request, 'get_user' ), 'permission_callback' => array( $this, 'authorize_as_from_wpcom' ), 'args' => array_merge( array( 'user_id' => array( 'type' => 'integer', 'required' => true, 'minimum' => 1, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ), ), $this->get_range_args() ), ), ) ); } /** * Handles the notification journey request. * * @param WP_REST_Request $request The request object. * @phpstan-param WP_REST_Request> $request * @return WP_REST_Response * * @since 11.3.0 */ protected function get_notification( WP_REST_Request $request ): WP_REST_Response { list( $from, $to ) = $this->get_range( $request ); return new WP_REST_Response( $this->query->for_notification( (string) $request->get_param( 'type' ), (int) $request->get_param( 'resource_id' ), $from, $to, $this->get_limit( $request ) ) ); } /** * Handles the whole-store request. * * @param WP_REST_Request $request The request object. * @phpstan-param WP_REST_Request> $request * @return WP_REST_Response * * @since 11.3.0 */ protected function get_site( WP_REST_Request $request ): WP_REST_Response { list( $from, $to ) = $this->get_range( $request ); return new WP_REST_Response( $this->query->for_site( $from, $to, $this->get_limit( $request ) ) ); } /** * Handles the device request. * * @param WP_REST_Request $request The request object. * @phpstan-param WP_REST_Request> $request * @return WP_REST_Response * * @since 11.3.0 */ protected function get_token( WP_REST_Request $request ): WP_REST_Response { list( $from, $to ) = $this->get_range( $request ); return new WP_REST_Response( $this->query->for_token( (int) $request->get_param( 'token_id' ), $from, $to, $this->get_limit( $request ) ) ); } /** * Handles the user request. * * @param WP_REST_Request $request The request object. * @phpstan-param WP_REST_Request> $request * @return WP_REST_Response * * @since 11.3.0 */ protected function get_user( WP_REST_Request $request ): WP_REST_Response { list( $from, $to ) = $this->get_range( $request ); return new WP_REST_Response( $this->query->for_user( (int) $request->get_param( 'user_id' ), $from, $to, $this->get_limit( $request ) ) ); } /** * The `from` and `to` arguments every route accepts, as Unix timestamps. * * @return array */ private function get_range_args(): array { return array( 'limit' => array( 'description' => __( 'Rows to return, newest first. A page carries every row of its last second, so it can exceed this.', 'woocommerce' ), 'type' => 'integer', 'default' => self::DEFAULT_LIMIT, 'minimum' => 1, 'maximum' => self::MAX_LIMIT, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ), 'from' => array( 'description' => __( 'Earliest Unix timestamp to include. Defaults to 48 hours before `to`, and is clamped to 90 days before it.', 'woocommerce' ), 'type' => 'integer', 'minimum' => 0, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ), 'to' => array( 'description' => __( 'Latest Unix timestamp to include. Defaults to now.', 'woocommerce' ), 'type' => 'integer', 'minimum' => 0, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ), ); } /** * The page size the request asked for, or the default. * * @param WP_REST_Request $request The request object. * @phpstan-param WP_REST_Request> $request * @return int */ private function get_limit( WP_REST_Request $request ): int { $limit = (int) $request->get_param( 'limit' ); return $limit > 0 ? $limit : self::DEFAULT_LIMIT; } /** * Resolves the requested time range, applying the defaults. * * @param WP_REST_Request $request The request object. * @phpstan-param WP_REST_Request> $request * @return array{0: int, 1: int} */ private function get_range( WP_REST_Request $request ): array { $to = (int) $request->get_param( 'to' ); $from = (int) $request->get_param( 'from' ); if ( $to <= 0 ) { $to = time(); } if ( $from <= 0 ) { $from = $to - self::DEFAULT_RANGE_SECONDS; } $from = min( $from, $to ); return array( max( $from, $to - self::MAX_RANGE_SECONDS ), $to ); } }