namespace, '/' . $this->rest_base, [ [ 'methods' => WP_REST_Server::CREATABLE, 'callback' => [ $this, 'handle_request' ], ], ] ); } /** * Handles the incoming batch of tracking events. * * @param WP_REST_Request $request The incoming request object. * * @return WP_REST_Response */ public function handle_request( WP_REST_Request $request ): WP_REST_Response|WP_Error { $origin = $request->get_header( 'origin' ); $referer = $request->get_header( 'referer' ); $home_url_parts = wp_parse_url( home_url() ); $request_origin_host = $origin ? wp_parse_url( $origin, PHP_URL_HOST ) : ( $referer ? wp_parse_url( $referer, PHP_URL_HOST ) : '' ); if ( $request_origin_host !== $home_url_parts['host'] ) { return new \WP_Error( 'rest_forbidden_origin', __( 'Invalid request origin.', 'adpresso' ), [ 'status' => 403 ] ); } $payload = $this->parse_request_payload( $request ); $events = $payload['events'] ?? $payload; if ( ! is_array( $events ) || empty( $events ) ) { return new WP_REST_Response( null, 204 ); } $success = StatsManager::get_instance()->record_batch( $events ); if ( $success ) { // Acknowledge receipt with a 202 Accepted status. // This tells the client the data was received and is being processed. return new WP_REST_Response( [ 'status' => 'accepted' ], 202 ); } // If something went wrong in the StatsManager. return new WP_REST_Response( [ 'status' => 'error' ], 500 ); } /** * Robust JSON-/Body-Parser für WP REST. * Reihenfolge: * 1) get_json_params() * 2) Roh-Body als JSON parsen * 3) Body-Params (x-www-form-urlencoded / multipart) * 4) Querystring im Roh-Body (parse_str) * * @param WP_REST_Request $request * * @return array */ public function parse_request_payload( WP_REST_Request $request ): array { // hard upper limit against misuse $raw = $request->get_body(); if ( strlen( $raw ) > 256 * 1024 ) { return []; } // try to read WP JSON. $data = $request->get_json_params(); if ( is_array( $data ) && $data ) { return $data; } // Raw body. if ( $raw !== '' ) { // Remove BOM. if ( strncmp( $raw, "\xEF\xBB\xBF", 3 ) === 0 ) { $raw = substr( $raw, 3 ); } $tmp = json_decode( $raw, true ); if ( json_last_error() === JSON_ERROR_NONE && is_array( $tmp ) ) { return $tmp; } } // Fallback to body params. $data = $request->get_body_params(); if ( is_array( $data ) && $data ) { return $data; } // Some clients may send body string in the body. if ( $raw !== '' ) { parse_str( $raw, $tmp ); if ( is_array( $tmp ) && $tmp ) { return $tmp; } } return []; } }