dashboards = $dashboards; $this->payloads = $payloads; } /** * Hooks route registration. */ public function register(): void { add_action( 'rest_api_init', array( $this, 'register_routes' ) ); } /** * Registers the route. */ public function register_routes(): void { register_rest_route( self::NAMESPACE, '/dashboards/(?P[^/]+)', array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_dashboard' ), // Deliberately public: dashboards are meant for anonymous displays. Access is limited by // the unguessable key, the enabled state and the payload whitelist, not by login. 'permission_callback' => '__return_true', ) ); } /** * Serves a dashboard. * * @param \WP_REST_Request $request Request. */ public function get_dashboard( \WP_REST_Request $request ): \WP_REST_Response { $dashboard = $this->dashboards->find_by_key( (string) $request->get_param( 'key' ) ); if ( null === $dashboard ) { return self::with_headers( new \WP_REST_Response( array( 'code' => 'not_found' ), 404 ) ); } $payload = $this->payloads->build( $dashboard, time() ); $etag = '"' . substr( hash( 'sha256', (string) wp_json_encode( $payload ) ), 0, 32 ) . '"'; if ( self::etag_matches( (string) $request->get_header( 'if_none_match' ), $etag ) ) { return self::with_headers( new \WP_REST_Response( null, 304 ), $etag ); } return self::with_headers( new \WP_REST_Response( $payload, 200 ), $etag ); } /** * Adds the headers every response carries. * * @param \WP_REST_Response $response Response. * @param string $etag Entity tag, if any. */ private static function with_headers( \WP_REST_Response $response, string $etag = '' ): \WP_REST_Response { $response->header( 'Cache-Control', 'no-cache' ); $response->header( 'X-Robots-Tag', 'noindex' ); if ( '' !== $etag ) { $response->header( 'ETag', $etag ); } return $response; } /** * Whether an If-None-Match header matches an entity tag. Weak validators are accepted. * * @param string $header If-None-Match value. * @param string $etag Current entity tag. */ private static function etag_matches( string $header, string $etag ): bool { foreach ( explode( ',', $header ) as $candidate ) { $candidate = trim( $candidate ); if ( '*' === $candidate || preg_replace( '#^W/#', '', $candidate ) === $etag ) { return true; } } return false; } }