66
77class Ajax
88{
9+ /**
10+ * Handle AJAX tracking request with exit (for admin-ajax.php).
11+ * This wrapper calls process() and exits with the result.
12+ */
913 public static function handle ()
14+ {
15+ $ result = self ::process ();
16+ exit ($ result );
17+ }
18+
19+ /**
20+ * Process tracking request and return result (for REST API and other contexts).
21+ * Returns the tracking result without calling exit().
22+ *
23+ * @return string|int The tracking result (record ID with checksum, error code, or 0)
24+ */
25+ public static function process ()
1026 {
1127 $ remote_ip = isset ($ _SERVER ['REMOTE_ADDR ' ]) ? sanitize_text_field (wp_unslash ($ _SERVER ['REMOTE_ADDR ' ])) : '' ;
1228 if (!empty ($ remote_ip )) {
1329 $ key = 'slimstat_rl_ ' . md5 ($ remote_ip );
1430 $ hits_in_5s = (int ) get_transient ($ key );
1531 if ($ hits_in_5s >= 10 ) {
16- exit ( Utils::logError (429 ) );
32+ return Utils::logError (429 );
1733 }
1834
1935 set_transient ($ key , $ hits_in_5s + 1 , 5 );
2036 }
2137
2238 if ('on ' != \wp_slimstat::$ settings ['is_tracking ' ]) {
23- exit ( Utils::logError (204 ) );
39+ return Utils::logError (204 );
2440 }
2541
2642 $ id = 0 ;
@@ -67,7 +83,7 @@ public static function handle()
6783 // Security: Validate referer format
6884 if (false === $ parsed_ref ) {
6985 // Invalid referer format - reject request
70- exit ( Utils::logError (201 ) );
86+ return Utils::logError (201 );
7187 }
7288
7389 // Security: Validate host (if present) - allow external domains for referer
@@ -76,7 +92,7 @@ public static function handle()
7692 // Validate host format (prevent injection)
7793 if (!preg_match ('/^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$/ ' , $ parsed_ref ['host ' ])) {
7894 // Invalid host format - reject request
79- exit ( Utils::logError (201 ) );
95+ return Utils::logError (201 );
8096 }
8197 }
8298
@@ -94,13 +110,13 @@ public static function handle()
94110 if (!empty ($ data_js ['id ' ])) {
95111 $ data_js ['id ' ] = Utils::getValueWithoutChecksum ($ data_js ['id ' ]);
96112 if (false === $ data_js ['id ' ]) {
97- exit ( Utils::logError (101 ) );
113+ return Utils::logError (101 );
98114 }
99115
100116 $ stat ['id ' ] = intval ($ data_js ['id ' ]);
101117 if ($ stat ['id ' ] < 0 ) {
102118 do_action ('slimstat_track_exit_ ' . abs ($ stat ['id ' ]));
103- exit ( Utils::getValueWithChecksum ($ stat ['id ' ]) );
119+ return Utils::getValueWithChecksum ($ stat ['id ' ]);
104120 }
105121
106122 // Process IP according to consent status (cookie set only by consent upgrade handler)
@@ -137,7 +153,7 @@ public static function handle()
137153 // Security: Whitelist validation - only allow current site domain
138154 if (!$ is_allowed_host ($ parsed_resource ['host ' ])) {
139155 // Invalid host - reject request
140- exit ( Utils::logError (203 ) );
156+ return Utils::logError (203 );
141157 }
142158
143159 // Security: Validate path format (prevent path traversal attacks)
@@ -147,7 +163,7 @@ public static function handle()
147163 // Validate path contains only safe characters
148164 if (!preg_match ('#^[/\w\-\.~!* \'();:@&=+$,?#\[\]%]*$# ' , $ path )) {
149165 // Invalid path format - reject request
150- exit ( Utils::logError (203 ) );
166+ return Utils::logError (203 );
151167 }
152168
153169 // Extract path from resource URL
@@ -173,9 +189,9 @@ public static function handle()
173189 $ visitIdAssigned = Session::ensureVisitId (true );
174190 $ stat = \wp_slimstat::get_stat ();
175191
176- // Security: Validate visit_id exists - exit if generation failed
192+ // Security: Validate visit_id exists - return error if generation failed
177193 if (empty ($ stat ['visit_id ' ]) || $ stat ['visit_id ' ] <= 0 ) {
178- exit ( Utils::logError (500 ) );
194+ return Utils::logError (500 );
179195 }
180196
181197 $ stat = Utils::getClientInfo ($ data_js , $ stat );
@@ -244,7 +260,7 @@ public static function handle()
244260 $ stat ['id ' ] = intval ($ existing_record ->id );
245261 \wp_slimstat::set_stat ($ stat );
246262 $ GLOBALS ['wpdb ' ]->query ('COMMIT ' );
247- exit ( Utils::getValueWithChecksum ($ stat ['id ' ]) );
263+ return Utils::getValueWithChecksum ($ stat ['id ' ]);
248264 }
249265
250266 $ GLOBALS ['wpdb ' ]->query ('COMMIT ' );
@@ -290,7 +306,7 @@ public static function handle()
290306 $ resource = Utils::base64UrlDecode ($ data_js ['res ' ]);
291307 $ parsed_resource = parse_url ($ resource ?: '' );
292308 if (false === $ parsed_resource || empty ($ parsed_resource ['host ' ])) {
293- exit ( Utils::logError (203 ) );
309+ return Utils::logError (203 );
294310 }
295311
296312 if (!empty ($ parsed_resource ['path ' ]) && in_array (pathinfo ($ parsed_resource ['path ' ], PATHINFO_EXTENSION ), \wp_slimstat::string_to_array (\wp_slimstat::$ settings ['extensions_to_track ' ]))) {
@@ -333,22 +349,22 @@ public static function handle()
333349 if (!empty ($ data_js ['res ' ])) {
334350 $ stat ['resource ' ] = Utils::base64UrlDecode ($ data_js ['res ' ]);
335351 if (false === parse_url ($ stat ['resource ' ] ?: '' )) {
336- exit ( Utils::logError (203 ) );
352+ return Utils::logError (203 );
337353 }
338354 }
339355
340356 $ stat = Utils::getClientInfo ($ data_js , $ stat );
341357 if (!empty ($ data_js ['ci ' ])) {
342358 $ data_js ['ci ' ] = Utils::getValueWithoutChecksum ($ data_js ['ci ' ]);
343359 if (false === $ data_js ['ci ' ]) {
344- exit ( Utils::logError (102 ) );
360+ return Utils::logError (102 );
345361 }
346362
347363 $ decoded_ci = Utils::base64UrlDecode ($ data_js ['ci ' ]);
348364 $ content_info = json_decode ($ decoded_ci , true );
349365 // Security: Only accept JSON-encoded content info, reject serialized data
350366 if (empty ($ content_info ) || !is_array ($ content_info )) {
351- exit ( Utils::logError (103 ) );
367+ return Utils::logError (103 );
352368 }
353369
354370 foreach (['content_type ' , 'category ' , 'content_id ' , 'author ' ] as $ a_key ) {
@@ -378,10 +394,10 @@ public static function handle()
378394 }
379395
380396 if (empty ($ id )) {
381- exit ( 0 ) ;
397+ return 0 ;
382398 }
383399
384400 do_action ('slimstat_track_success ' );
385- exit ( Utils::getValueWithChecksum ($ id) );
401+ return Utils::getValueWithChecksum ($ id );
386402 }
387403}
0 commit comments