diff --git a/includes/class-spotmap-ingest.php b/includes/class-spotmap-ingest.php index 65563c9..41e04d8 100644 --- a/includes/class-spotmap-ingest.php +++ b/includes/class-spotmap-ingest.php @@ -180,12 +180,23 @@ public static function handle_osmand(WP_REST_Request $request): WP_REST_Response */ public static function handle_teltonika(WP_REST_Request $request): WP_REST_Response { + // Log everything we have before any validation so we can see what Teltonika actually sends. + $raw_body = $request->get_body(); + $key_raw = $request->get_param('key') ?? ''; + $key_masked = strlen($key_raw) > 4 ? substr($key_raw, 0, 4) . str_repeat('*', strlen($key_raw) - 4) : '(empty)'; + $ct = $request->get_content_type(); + self::log_ingest_event( 'teltonika', 'request_received', [ - 'method' => $request->get_method(), - 'has_key' => $request->get_param('key') !== null, + 'method' => $request->get_method(), + 'content_type' => is_array($ct) ? ($ct['value'] ?? '') : (string) $ct, + 'key_masked' => $key_masked, + 'query_params' => array_diff_key($request->get_query_params(), [ 'key' => '' ]), + 'body_length' => strlen($raw_body), + 'body_raw' => substr($raw_body, 0, 2000), + 'json_parsed' => $request->get_json_params(), ] ); @@ -211,10 +222,25 @@ public static function handle_teltonika(WP_REST_Request $request): WP_REST_Respo // 2. Build payload from wrapped JSON body. $payload = self::build_teltonika_payload($request); if ($payload === null) { - self::log_ingest_event('teltonika', 'invalid_payload', self::feed_context($feed)); + $body_raw = $request->get_body(); + self::log_ingest_event( + 'teltonika', + 'invalid_payload', + self::feed_context($feed) + [ + 'body_length' => strlen($body_raw), + 'body_raw' => substr($body_raw, 0, 500), + 'json_params' => $request->get_json_params(), + ] + ); return new WP_REST_Response([ 'error' => 'Invalid payload. Expected wrapped JSON body: {"": {"latitude":…, "longitude":…, "timestamp":…}}.' ], 400); } + self::log_ingest_event( + 'teltonika', + 'payload_parsed', + self::feed_context($feed) + [ 'payload_keys' => array_keys($payload), 'payload' => $payload ] + ); + // 3. Validate required fields. if (! isset($payload['latitude'], $payload['longitude'], $payload['timestamp'])) { self::log_ingest_event( @@ -392,7 +418,14 @@ private static function is_unsubstituted($value): bool */ private static function build_teltonika_payload(WP_REST_Request $request): ?array { + // get_json_params() only works when Content-Type is application/json. + // Teltonika sends application/x-www-form-urlencoded despite the body being JSON, + // so fall back to decoding the raw body directly. $body = $request->get_json_params(); + if (! is_array($body) || empty($body)) { + $raw = $request->get_body(); + $body = $raw !== '' ? json_decode($raw, true) : null; + } if (! is_array($body) || empty($body)) { return null; } @@ -424,20 +457,18 @@ private static function feed_context(array $feed): array */ private static function log_ingest_event(string $provider, string $event, array $context = []): void { - if (! defined('WP_DEBUG') || ! WP_DEBUG) { + if (! defined('WP_DEBUG_LOG') || ! WP_DEBUG_LOG) { return; } - $timestamp = gmdate('c'); $line = sprintf( - '[%s] [spotmap ingest] provider=%s event=%s context=%s', - $timestamp, + '[spotmap] provider=%s event=%s context=%s', $provider, $event, wp_json_encode($context) ); - // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error - trigger_error($line, E_USER_NOTICE); + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log + error_log($line); } } diff --git a/package.json b/package.json index faca147..fa008ee 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "packages-update": "wp-scripts packages-update", "version:bump": "node scripts/bump-version.js", "plugin-zip": "npm run build && wp-scripts plugin-zip && node -e \"const fs=require('fs');const v=fs.readFileSync('spotmap.php','utf8').match(/Version:\\s+(\\S+)/)[1];fs.renameSync('spotmap.zip',`spotmap-${v}.zip`);console.log(`Created spotmap-${v}.zip`);\"", - "composer": "wp-env run cli --env-cwd=wp-content/plugins/Spotmap composer" + "composer": "wp-env run cli --env-cwd=wp-content/plugins/Spotmap -- composer" }, "overrides": { "serialize-javascript": "^7.0.3", @@ -92,3 +92,4 @@ "babel-plugin-istanbul": "^8.0.0" } } +