Changeset 3463885
- Timestamp:
- 02/17/2026 10:57:15 PM (6 weeks ago)
- Location:
- fastcomments
- Files:
-
- 40 added
- 5 edited
-
tags/3.18.0 (added)
-
tags/3.18.0/.gitignore (added)
-
tags/3.18.0/LICENSE (added)
-
tags/3.18.0/README.md (added)
-
tags/3.18.0/README.txt (added)
-
tags/3.18.0/admin (added)
-
tags/3.18.0/admin/fastcomments-admin-advanced-settings-view.js (added)
-
tags/3.18.0/admin/fastcomments-admin-advanced-settings-view.php (added)
-
tags/3.18.0/admin/fastcomments-admin-manual-sync-view.js (added)
-
tags/3.18.0/admin/fastcomments-admin-manual-sync-view.php (added)
-
tags/3.18.0/admin/fastcomments-admin-setup-view.js (added)
-
tags/3.18.0/admin/fastcomments-admin-setup-view.php (added)
-
tags/3.18.0/admin/fastcomments-admin-sso-view.css (added)
-
tags/3.18.0/admin/fastcomments-admin-sso-view.js (added)
-
tags/3.18.0/admin/fastcomments-admin-sso-view.php (added)
-
tags/3.18.0/admin/fastcomments-admin-support-view.php (added)
-
tags/3.18.0/admin/fastcomments-admin-view.php (added)
-
tags/3.18.0/admin/fastcomments-admin.css (added)
-
tags/3.18.0/admin/fastcomments-admin.php (added)
-
tags/3.18.0/admin/images (added)
-
tags/3.18.0/admin/images/api.png (added)
-
tags/3.18.0/admin/images/crown.png (added)
-
tags/3.18.0/admin/images/css.png (added)
-
tags/3.18.0/admin/images/debugging.png (added)
-
tags/3.18.0/admin/images/download.png (added)
-
tags/3.18.0/admin/images/home.png (added)
-
tags/3.18.0/admin/images/logo-50.png (added)
-
tags/3.18.0/admin/images/logo.png (added)
-
tags/3.18.0/admin/images/settings.png (added)
-
tags/3.18.0/admin/images/support.png (added)
-
tags/3.18.0/admin/images/sync-status.png (added)
-
tags/3.18.0/admin/images/sync.png (added)
-
tags/3.18.0/core (added)
-
tags/3.18.0/core/FastCommentsIntegrationCore.php (added)
-
tags/3.18.0/core/FastCommentsWordPressIntegration.php (added)
-
tags/3.18.0/fastcomments-wordpress-plugin.php (added)
-
tags/3.18.0/public (added)
-
tags/3.18.0/public/fastcomments-public.php (added)
-
tags/3.18.0/public/fastcomments-widget-view.php (added)
-
tags/3.18.0/uninstall.php (added)
-
trunk/README.txt (modified) (2 diffs)
-
trunk/core/FastCommentsIntegrationCore.php (modified) (2 diffs)
-
trunk/core/FastCommentsWordPressIntegration.php (modified) (7 diffs)
-
trunk/fastcomments-wordpress-plugin.php (modified) (2 diffs)
-
trunk/public/fastcomments-public.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
fastcomments/trunk/README.txt
r3462221 r3463885 4 4 Requires at least: 4.6 5 5 Tested up to: 6.9.2 6 Stable tag: 3.1 7.06 Stable tag: 3.18.0 7 7 Requires PHP: 5.2.5 8 8 License: GPLv2 or later … … 84 84 == Changelog == 85 85 86 = 3.18.0 = 87 * Improved sync reliability: "Download FC to WP" now sends WP IDs back to FastComments, eliminating slow table scans on future syncs. 88 * Fixed duplicate comments when re-syncing after plugin reinstall. 89 * Sync mapping failures are now queued and automatically retried on the next cron tick. 90 * Improved error logging for failed comment inserts during sync. 91 86 92 = 3.17.0 = 87 93 * Admin theme update. -
fastcomments/trunk/core/FastCommentsIntegrationCore.php
r3436960 r3463885 194 194 // This removes the weird logic where each time a command is finished processing, we advance the fastcomments_stream_last_fetch_timestamp. 195 195 // The reason this logic is weird is the two things are relatively far from each other, potentially being bug prone. 196 $this->retryPendingIdMappings(); 196 197 $token = $this->getSettingValue('fastcomments_token'); 197 198 if ($token) { … … 423 424 } 424 425 426 /** 427 * Sends WP ID mappings back to FC so meta.wpId is set for O(1) lookups on future syncs. 428 * On failure, queues mappings for retry on next tick. 429 */ 430 public function sendCommentIdMappings($mappings) { 431 if (count($mappings) === 0) { 432 return; 433 } 434 $token = $this->getSettingValue('fastcomments_token'); 435 $patch_url = "$this->baseUrl/comment-ids?token=$token"; 436 $patch_response = $this->makeHTTPRequest('PATCH', $patch_url, json_encode(array('mappings' => $mappings))); 437 if ($patch_response->responseStatusCode !== 200) { 438 $this->log('warn', "Failed to send WP ID mappings back to FC (HTTP $patch_response->responseStatusCode), queuing for retry"); 439 $this->queueMappingsForRetry($mappings); 440 } 441 } 442 443 private function queueMappingsForRetry($mappings) { 444 $existing = $this->getSettingValue('fastcomments_pending_id_mappings'); 445 if ($existing) { 446 $existing = json_decode($existing, true); 447 if (!is_array($existing)) { 448 $existing = array(); 449 } 450 } else { 451 $existing = array(); 452 } 453 foreach ($mappings as $mapping) { 454 $existing[] = $mapping; 455 } 456 // Cap at 5000 to prevent unbounded growth 457 if (count($existing) > 5000) { 458 $existing = array_slice($existing, -5000); 459 } 460 $this->setSettingValue('fastcomments_pending_id_mappings', json_encode($existing)); 461 } 462 463 /** 464 * Retries any queued ID mappings that failed to send previously. 465 */ 466 public function retryPendingIdMappings() { 467 $pending = $this->getSettingValue('fastcomments_pending_id_mappings'); 468 if (!$pending) { 469 return; 470 } 471 $mappings = json_decode($pending, true); 472 if (!is_array($mappings) || count($mappings) === 0) { 473 $this->setSettingValue('fastcomments_pending_id_mappings', null); 474 return; 475 } 476 $this->log('debug', "Retrying " . count($mappings) . " pending ID mappings"); 477 $token = $this->getSettingValue('fastcomments_token'); 478 $patch_url = "$this->baseUrl/comment-ids?token=$token"; 479 // Send in batches of 500 (endpoint limit) 480 foreach (array_chunk($mappings, 500) as $batch) { 481 $patch_response = $this->makeHTTPRequest('PATCH', $patch_url, json_encode(array('mappings' => $batch))); 482 if ($patch_response->responseStatusCode !== 200) { 483 $this->log('warn', "Retry of pending ID mappings failed (HTTP $patch_response->responseStatusCode), will try again next tick"); 484 return; 485 } 486 } 487 $this->setSettingValue('fastcomments_pending_id_mappings', null); 488 $this->log('debug', "All pending ID mappings sent successfully"); 489 } 490 425 491 private function setSetupDone() { 426 492 /** -
fastcomments/trunk/core/FastCommentsWordPressIntegration.php
r3436960 r3463885 87 87 delete_option('fastcomments_comment_sent_count'); 88 88 delete_option('fastcomments_log_level'); 89 delete_option('fastcomments_pending_id_mappings'); 89 90 90 91 $timestamp = wp_next_scheduled('fastcomments_cron'); … … 192 193 } 193 194 195 /** 196 * Records a FC→WP mapping after inserting a comment during sync. 197 * Stores both the mapping table entry and the comment_meta. 198 */ 199 public function recordSyncMapping($fcId, $wpId) { 200 $this->addCommentIDMapEntry($fcId, $wpId); 201 update_comment_meta($wpId, 'fastcomments_id', $fcId); 202 } 203 194 204 private function addCommentIDMapEntry($fcId, $wpId) { 195 205 $this->log('debug', "addCommentIDMapEntry $fcId -> $wpId"); … … 235 245 } 236 246 247 /** 248 * Fallback lookup: find a WP comment via externalId or meta.wpId from the FC comment. 249 * Both are WP primary key lookups via get_comment() — O(1), not a table scan. 250 */ 251 private function getWPCommentIdFromFCComment($fc_comment) { 252 // Check meta.wpId first (set when WP sends IDs back after "Download FC → WP" sync — most recent) 253 if (isset($fc_comment->meta) && isset($fc_comment->meta->wpId) && is_numeric($fc_comment->meta->wpId)) { 254 $wp_comment = get_comment((int)$fc_comment->meta->wpId); 255 if ($wp_comment) { 256 $this->log('debug', "Found WP comment {$fc_comment->meta->wpId} for FC ID {$fc_comment->_id} via meta.wpId"); 257 return (int)$fc_comment->meta->wpId; 258 } 259 } 260 // Fall back to externalId (set when comments were originally uploaded from WP → FC) 261 if (isset($fc_comment->externalId) && is_numeric($fc_comment->externalId)) { 262 $wp_comment = get_comment((int)$fc_comment->externalId); 263 if ($wp_comment) { 264 $this->log('debug', "Found WP comment {$fc_comment->externalId} for FC ID {$fc_comment->_id} via externalId"); 265 return (int)$fc_comment->externalId; 266 } 267 } 268 return null; 269 } 270 237 271 public function makeHTTPRequest($method, $url, $body) { 238 272 // Use longer timeout for POST requests (comment uploads can take time with large batches) … … 324 358 325 359 $wp_id = $this->getWPCommentId($fc_comment->_id); 326 $wp_parent_id = isset($fc_comment->parentId) && $fc_comment->parentId ? $this->getWPCommentId($fc_comment->parentId) : 0; 360 361 // Fallback: use externalId or meta.wpId from the FC comment (O(1) primary key lookups) 362 if ($wp_id === null) { 363 $wp_id = $this->getWPCommentIdFromFCComment($fc_comment); 364 if ($wp_id !== null) { 365 // Re-populate the mapping table so future lookups use the fast path 366 $this->addCommentIDMapEntry($fc_comment->_id, $wp_id); 367 } 368 } 369 370 $parent_wp_id = isset($fc_comment->parentId) && $fc_comment->parentId ? $this->getWPCommentId($fc_comment->parentId) : null; 371 $wp_parent_id = $parent_wp_id ? $parent_wp_id : 0; 327 372 328 373 $wp_comment['comment_ID'] = is_numeric($wp_id) ? $wp_id : null; … … 388 433 public function handleEvents($events) { 389 434 $this->log('debug', "BEGIN handleEvents"); 435 $mappings = array(); 390 436 foreach ($events as $event) { 391 437 try { … … 421 467 $comment_id_or_false = wp_insert_comment($new_wp_comment); 422 468 if ($comment_id_or_false) { 423 $this-> addCommentIDMapEntry($fcId, $comment_id_or_false);424 update_comment_meta($comment_id_or_false, 'fastcomments_id', $eventData->comment->_id);469 $this->recordSyncMapping($fcId, $comment_id_or_false); 470 $mappings[] = array('fcId' => $fcId, 'wpId' => $comment_id_or_false); 425 471 $this->log('debug', "Saved $fcId (wp id $comment_id_or_false)"); 426 472 } else { … … 493 539 } 494 540 } 541 $this->sendCommentIdMappings($mappings); 495 542 $this->log('debug', "END handleEvents"); 496 543 } -
fastcomments/trunk/fastcomments-wordpress-plugin.php
r3462221 r3463885 4 4 Plugin URI: https://fastcomments.com 5 5 Description: A live, fast, privacy-focused commenting system with advanced spam prevention capabilities. 6 Version: 3.1 7.06 Version: 3.18.0 7 7 Author: winrid @ FastComments 8 8 License: GPL-2.0+ … … 14 14 } 15 15 16 $FASTCOMMENTS_VERSION = 3.1 70;16 $FASTCOMMENTS_VERSION = 3.180; 17 17 18 18 require_once plugin_dir_path(__FILE__) . 'admin/fastcomments-admin.php'; -
fastcomments/trunk/public/fastcomments-public.php
r2768101 r3463885 96 96 $count = count($get_comments_response->comments); 97 97 if ($count > 0) { 98 $mappings = array(); 98 99 foreach ($get_comments_response->comments as $comment) { 99 100 $wp_comment = $fastcomments->fc_to_wp_comment($comment, true); 100 if (!wp_update_comment($wp_comment)) { 101 wp_insert_comment($wp_comment); 101 if (is_numeric($wp_comment['comment_ID'])) { 102 // Existing comment found - update it 103 wp_update_comment($wp_comment); 104 update_comment_meta($wp_comment['comment_ID'], 'fastcomments_id', $comment->_id); 105 } else { 106 // No existing mapping found - insert new comment 107 unset($wp_comment['comment_ID']); 108 $new_id = wp_insert_comment($wp_comment); 109 if ($new_id > 0) { 110 $fastcomments->recordSyncMapping($comment->_id, $new_id); 111 $mappings[] = array('fcId' => $comment->_id, 'wpId' => $new_id); 112 } else { 113 $fastcomments->log('error', "Failed to insert WP comment for FC ID $comment->_id"); 114 } 102 115 } 103 116 } 117 $fastcomments->sendCommentIdMappings($mappings); 104 118 return new WP_REST_Response(array('status' => 'success', 'hasMore' => $get_comments_response->hasMore, 'totalCount' => $includeCount ? $get_comments_response->totalCount : null, 'count' => $count), 200); 105 119 } else {
Note: See TracChangeset
for help on using the changeset viewer.