Changeset 3466837
- Timestamp:
- 02/22/2026 10:55:56 AM (5 weeks ago)
- Location:
- spamanvil
- Files:
-
- 12 edited
- 1 copied
-
tags/1.2.3 (copied) (copied from spamanvil/trunk)
-
tags/1.2.3/admin/class-spamanvil-admin.php (modified) (1 diff)
-
tags/1.2.3/includes/class-spamanvil-queue.php (modified) (3 diffs)
-
tags/1.2.3/languages/spamanvil-pt_BR.mo (modified) (previous)
-
tags/1.2.3/languages/spamanvil-pt_BR.po (modified) (1 diff)
-
tags/1.2.3/readme.txt (modified) (2 diffs)
-
tags/1.2.3/spamanvil.php (modified) (2 diffs)
-
trunk/admin/class-spamanvil-admin.php (modified) (1 diff)
-
trunk/includes/class-spamanvil-queue.php (modified) (3 diffs)
-
trunk/languages/spamanvil-pt_BR.mo (modified) (previous)
-
trunk/languages/spamanvil-pt_BR.po (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/spamanvil.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
spamanvil/tags/1.2.3/admin/class-spamanvil-admin.php
r3461590 r3466837 397 397 } 398 398 399 // Get all comments with 'hold' status. 400 $comments = get_comments( array( 'status' => 'hold', 'number' => 0 ) ); 401 402 if ( empty( $comments ) ) { 403 wp_send_json_success( array( 404 'enqueued' => 0, 405 'auto_spam' => 0, 406 'already_queued' => 0, 407 ) ); 408 } 409 410 // Get comment IDs already in the queue. 411 global $wpdb; 412 $queue_table = $wpdb->prefix . 'spamanvil_queue'; 413 $already_queued_ids = $wpdb->get_col( "SELECT comment_id FROM {$queue_table} WHERE status IN ('queued', 'processing', 'failed')" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- custom plugin table, table name from $wpdb->prefix. 414 415 $enqueued = 0; 416 $auto_spam = 0; 417 $already_queued = 0; 418 419 $heuristic_threshold = (int) get_option( 'spamanvil_heuristic_auto_spam', 95 ); 420 421 foreach ( $comments as $comment ) { 422 if ( in_array( (string) $comment->comment_ID, $already_queued_ids, true ) ) { 423 $already_queued++; 424 continue; 425 } 426 427 // Run heuristics. 428 $analysis = $this->heuristics->analyze( array( 429 'comment_content' => $comment->comment_content, 430 'comment_author' => $comment->comment_author, 431 'comment_author_email' => $comment->comment_author_email, 432 'comment_author_url' => $comment->comment_author_url, 433 ) ); 434 435 if ( $analysis['score'] >= $heuristic_threshold ) { 436 wp_spam_comment( $comment->comment_ID ); 437 $this->stats->increment( 'heuristic_blocked' ); 438 $this->stats->increment( 'comments_checked' ); 439 $this->stats->log_evaluation( array( 440 'comment_id' => $comment->comment_ID, 441 'score' => $analysis['score'], 442 'provider' => 'heuristics', 443 'model' => 'regex', 444 'reason' => 'Auto-blocked by heuristic analysis (scan pending)', 445 'heuristic_score' => $analysis['score'], 446 'heuristic_details' => $this->heuristics->format_for_prompt( $analysis ), 447 ) ); 448 449 $ip = get_comment_author_IP( $comment->comment_ID ); 450 if ( ! empty( $ip ) ) { 451 $this->ip_manager->record_spam_attempt( $ip ); 452 } 453 454 $auto_spam++; 455 } else { 456 $this->queue->enqueue( $comment->comment_ID, $analysis['score'] ); 457 $enqueued++; 458 } 459 } 399 // Count pending comments before scanning for the already_queued stat. 400 $pending_count = (int) wp_count_comments()->moderated; 401 402 // Capture stats before to compute auto_spam count. 403 $heuristic_before = $this->stats->get_total( 'heuristic_blocked' ); 404 405 $enqueued = $this->queue->auto_enqueue_pending( 0 ); // 0 = scan all (manual action). 406 407 $heuristic_after = $this->stats->get_total( 'heuristic_blocked' ); 408 $auto_spam = $heuristic_after - $heuristic_before; 409 $already_queued = max( 0, $pending_count - $enqueued - $auto_spam ); 460 410 461 411 // Trigger immediate cron run so the queue starts processing without waiting. -
spamanvil/tags/1.2.3/includes/class-spamanvil-queue.php
r3466819 r3466837 78 78 79 79 try { 80 $batch_size = (int) get_option( 'spamanvil_batch_size', 5 ); 80 $batch_size = (int) get_option( 'spamanvil_batch_size', 5 ); 81 $auto_enqueued = false; 81 82 82 83 // Loop through batches until queue is empty or time runs out. … … 85 86 86 87 if ( empty( $items ) ) { 88 // Queue is empty — try to auto-enqueue pending WordPress comments. 89 if ( ! $auto_enqueued && ! $force ) { 90 $auto_enqueued = true; 91 $newly_enqueued = $this->auto_enqueue_pending(); 92 if ( $newly_enqueued > 0 ) { 93 continue; // Re-enter loop to process newly enqueued items. 94 } 95 } 87 96 break; 88 97 } … … 645 654 } 646 655 656 /** 657 * Auto-enqueue pending WordPress comments that are not already in the queue. 658 * 659 * Scans for comments with 'hold' status, runs heuristics on each, and either 660 * auto-spams (high heuristic score) or enqueues for LLM analysis. 661 * 662 * @param int $limit Max comments to scan. 0 = unlimited. Default 100 (safe for cron). 663 * @return int Number of comments enqueued for LLM analysis. 664 */ 665 public function auto_enqueue_pending( $limit = 100 ) { 666 global $wpdb; 667 668 // Skip if no provider is configured — nothing to process. 669 if ( '' === get_option( 'spamanvil_primary_provider', '' ) ) { 670 return 0; 671 } 672 673 // Get comment IDs already in the queue (active statuses). 674 $already_queued_ids = $wpdb->get_col( 675 "SELECT comment_id FROM {$this->table} WHERE status IN ('queued', 'processing', 'failed', 'max_retries')" 676 ); 677 678 $comments = get_comments( array( 679 'status' => 'hold', 680 'number' => $limit, 681 ) ); 682 683 if ( empty( $comments ) ) { 684 return 0; 685 } 686 687 $enqueued = 0; 688 $heuristic_threshold = (int) get_option( 'spamanvil_heuristic_auto_spam', 95 ); 689 690 foreach ( $comments as $comment ) { 691 if ( in_array( (string) $comment->comment_ID, $already_queued_ids, true ) ) { 692 continue; 693 } 694 695 // Run heuristics. 696 $analysis = $this->heuristics->analyze( array( 697 'comment_content' => $comment->comment_content, 698 'comment_author' => $comment->comment_author, 699 'comment_author_email' => $comment->comment_author_email, 700 'comment_author_url' => $comment->comment_author_url, 701 ) ); 702 703 if ( $analysis['score'] >= $heuristic_threshold ) { 704 wp_spam_comment( $comment->comment_ID ); 705 $this->stats->increment( 'heuristic_blocked' ); 706 $this->stats->increment( 'comments_checked' ); 707 $this->stats->log_evaluation( array( 708 'comment_id' => $comment->comment_ID, 709 'score' => $analysis['score'], 710 'provider' => 'heuristics', 711 'model' => 'regex', 712 'reason' => 'Auto-blocked by heuristic analysis (auto-enqueue)', 713 'heuristic_score' => $analysis['score'], 714 'heuristic_details' => $this->heuristics->format_for_prompt( $analysis ), 715 ) ); 716 717 $ip = get_comment_author_IP( $comment->comment_ID ); 718 if ( ! empty( $ip ) ) { 719 $this->ip_manager->record_spam_attempt( $ip ); 720 } 721 } else { 722 $this->enqueue( $comment->comment_ID, $analysis['score'] ); 723 $enqueued++; 724 } 725 } 726 727 return $enqueued; 728 } 729 647 730 public function get_queue_status() { 648 731 global $wpdb; -
spamanvil/tags/1.2.3/languages/spamanvil-pt_BR.po
r3466819 r3466837 6 6 msgid "" 7 7 msgstr "" 8 "Project-Id-Version: SpamAnvil 1.2. 2\n"8 "Project-Id-Version: SpamAnvil 1.2.3\n" 9 9 "Report-Msgid-Bugs-To: https://software.amato.com.br/spamanvil-antispam-" 10 10 "plugin-for-wordpress/\n" -
spamanvil/tags/1.2.3/readme.txt
r3466819 r3466837 6 6 Tested up to: 6.9 7 7 Requires PHP: 7.4 8 Stable tag: 1.2. 28 Stable tag: 1.2.3 9 9 License: GPLv2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 215 215 == Changelog == 216 216 217 = 1.2.3 = 218 * Feature: Cron now automatically scans pending WordPress comments when the queue is empty — no manual "Scan Pending" click needed 219 217 220 = 1.2.2 = 218 221 * Feature: "Last automatic run" timestamp in Queue Status card shows when WP-Cron last processed the queue -
spamanvil/tags/1.2.3/spamanvil.php
r3466819 r3466837 4 4 * Plugin URI: https://software.amato.com.br/spamanvil-antispam-plugin-for-wordpress/ 5 5 * Description: Blocks comment spam using AI/LLM services with support for multiple providers, async processing, and intelligent heuristics. 6 * Version: 1.2. 26 * Version: 1.2.3 7 7 * Requires at least: 5.8 8 8 * Requires PHP: 7.4 … … 19 19 } 20 20 21 define( 'SPAMANVIL_VERSION', '1.2. 2' );21 define( 'SPAMANVIL_VERSION', '1.2.3' ); 22 22 define( 'SPAMANVIL_DB_VERSION', '1.0.0' ); 23 23 define( 'SPAMANVIL_PLUGIN_FILE', __FILE__ ); -
spamanvil/trunk/admin/class-spamanvil-admin.php
r3461590 r3466837 397 397 } 398 398 399 // Get all comments with 'hold' status. 400 $comments = get_comments( array( 'status' => 'hold', 'number' => 0 ) ); 401 402 if ( empty( $comments ) ) { 403 wp_send_json_success( array( 404 'enqueued' => 0, 405 'auto_spam' => 0, 406 'already_queued' => 0, 407 ) ); 408 } 409 410 // Get comment IDs already in the queue. 411 global $wpdb; 412 $queue_table = $wpdb->prefix . 'spamanvil_queue'; 413 $already_queued_ids = $wpdb->get_col( "SELECT comment_id FROM {$queue_table} WHERE status IN ('queued', 'processing', 'failed')" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- custom plugin table, table name from $wpdb->prefix. 414 415 $enqueued = 0; 416 $auto_spam = 0; 417 $already_queued = 0; 418 419 $heuristic_threshold = (int) get_option( 'spamanvil_heuristic_auto_spam', 95 ); 420 421 foreach ( $comments as $comment ) { 422 if ( in_array( (string) $comment->comment_ID, $already_queued_ids, true ) ) { 423 $already_queued++; 424 continue; 425 } 426 427 // Run heuristics. 428 $analysis = $this->heuristics->analyze( array( 429 'comment_content' => $comment->comment_content, 430 'comment_author' => $comment->comment_author, 431 'comment_author_email' => $comment->comment_author_email, 432 'comment_author_url' => $comment->comment_author_url, 433 ) ); 434 435 if ( $analysis['score'] >= $heuristic_threshold ) { 436 wp_spam_comment( $comment->comment_ID ); 437 $this->stats->increment( 'heuristic_blocked' ); 438 $this->stats->increment( 'comments_checked' ); 439 $this->stats->log_evaluation( array( 440 'comment_id' => $comment->comment_ID, 441 'score' => $analysis['score'], 442 'provider' => 'heuristics', 443 'model' => 'regex', 444 'reason' => 'Auto-blocked by heuristic analysis (scan pending)', 445 'heuristic_score' => $analysis['score'], 446 'heuristic_details' => $this->heuristics->format_for_prompt( $analysis ), 447 ) ); 448 449 $ip = get_comment_author_IP( $comment->comment_ID ); 450 if ( ! empty( $ip ) ) { 451 $this->ip_manager->record_spam_attempt( $ip ); 452 } 453 454 $auto_spam++; 455 } else { 456 $this->queue->enqueue( $comment->comment_ID, $analysis['score'] ); 457 $enqueued++; 458 } 459 } 399 // Count pending comments before scanning for the already_queued stat. 400 $pending_count = (int) wp_count_comments()->moderated; 401 402 // Capture stats before to compute auto_spam count. 403 $heuristic_before = $this->stats->get_total( 'heuristic_blocked' ); 404 405 $enqueued = $this->queue->auto_enqueue_pending( 0 ); // 0 = scan all (manual action). 406 407 $heuristic_after = $this->stats->get_total( 'heuristic_blocked' ); 408 $auto_spam = $heuristic_after - $heuristic_before; 409 $already_queued = max( 0, $pending_count - $enqueued - $auto_spam ); 460 410 461 411 // Trigger immediate cron run so the queue starts processing without waiting. -
spamanvil/trunk/includes/class-spamanvil-queue.php
r3466819 r3466837 78 78 79 79 try { 80 $batch_size = (int) get_option( 'spamanvil_batch_size', 5 ); 80 $batch_size = (int) get_option( 'spamanvil_batch_size', 5 ); 81 $auto_enqueued = false; 81 82 82 83 // Loop through batches until queue is empty or time runs out. … … 85 86 86 87 if ( empty( $items ) ) { 88 // Queue is empty — try to auto-enqueue pending WordPress comments. 89 if ( ! $auto_enqueued && ! $force ) { 90 $auto_enqueued = true; 91 $newly_enqueued = $this->auto_enqueue_pending(); 92 if ( $newly_enqueued > 0 ) { 93 continue; // Re-enter loop to process newly enqueued items. 94 } 95 } 87 96 break; 88 97 } … … 645 654 } 646 655 656 /** 657 * Auto-enqueue pending WordPress comments that are not already in the queue. 658 * 659 * Scans for comments with 'hold' status, runs heuristics on each, and either 660 * auto-spams (high heuristic score) or enqueues for LLM analysis. 661 * 662 * @param int $limit Max comments to scan. 0 = unlimited. Default 100 (safe for cron). 663 * @return int Number of comments enqueued for LLM analysis. 664 */ 665 public function auto_enqueue_pending( $limit = 100 ) { 666 global $wpdb; 667 668 // Skip if no provider is configured — nothing to process. 669 if ( '' === get_option( 'spamanvil_primary_provider', '' ) ) { 670 return 0; 671 } 672 673 // Get comment IDs already in the queue (active statuses). 674 $already_queued_ids = $wpdb->get_col( 675 "SELECT comment_id FROM {$this->table} WHERE status IN ('queued', 'processing', 'failed', 'max_retries')" 676 ); 677 678 $comments = get_comments( array( 679 'status' => 'hold', 680 'number' => $limit, 681 ) ); 682 683 if ( empty( $comments ) ) { 684 return 0; 685 } 686 687 $enqueued = 0; 688 $heuristic_threshold = (int) get_option( 'spamanvil_heuristic_auto_spam', 95 ); 689 690 foreach ( $comments as $comment ) { 691 if ( in_array( (string) $comment->comment_ID, $already_queued_ids, true ) ) { 692 continue; 693 } 694 695 // Run heuristics. 696 $analysis = $this->heuristics->analyze( array( 697 'comment_content' => $comment->comment_content, 698 'comment_author' => $comment->comment_author, 699 'comment_author_email' => $comment->comment_author_email, 700 'comment_author_url' => $comment->comment_author_url, 701 ) ); 702 703 if ( $analysis['score'] >= $heuristic_threshold ) { 704 wp_spam_comment( $comment->comment_ID ); 705 $this->stats->increment( 'heuristic_blocked' ); 706 $this->stats->increment( 'comments_checked' ); 707 $this->stats->log_evaluation( array( 708 'comment_id' => $comment->comment_ID, 709 'score' => $analysis['score'], 710 'provider' => 'heuristics', 711 'model' => 'regex', 712 'reason' => 'Auto-blocked by heuristic analysis (auto-enqueue)', 713 'heuristic_score' => $analysis['score'], 714 'heuristic_details' => $this->heuristics->format_for_prompt( $analysis ), 715 ) ); 716 717 $ip = get_comment_author_IP( $comment->comment_ID ); 718 if ( ! empty( $ip ) ) { 719 $this->ip_manager->record_spam_attempt( $ip ); 720 } 721 } else { 722 $this->enqueue( $comment->comment_ID, $analysis['score'] ); 723 $enqueued++; 724 } 725 } 726 727 return $enqueued; 728 } 729 647 730 public function get_queue_status() { 648 731 global $wpdb; -
spamanvil/trunk/languages/spamanvil-pt_BR.po
r3466819 r3466837 6 6 msgid "" 7 7 msgstr "" 8 "Project-Id-Version: SpamAnvil 1.2. 2\n"8 "Project-Id-Version: SpamAnvil 1.2.3\n" 9 9 "Report-Msgid-Bugs-To: https://software.amato.com.br/spamanvil-antispam-" 10 10 "plugin-for-wordpress/\n" -
spamanvil/trunk/readme.txt
r3466819 r3466837 6 6 Tested up to: 6.9 7 7 Requires PHP: 7.4 8 Stable tag: 1.2. 28 Stable tag: 1.2.3 9 9 License: GPLv2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 215 215 == Changelog == 216 216 217 = 1.2.3 = 218 * Feature: Cron now automatically scans pending WordPress comments when the queue is empty — no manual "Scan Pending" click needed 219 217 220 = 1.2.2 = 218 221 * Feature: "Last automatic run" timestamp in Queue Status card shows when WP-Cron last processed the queue -
spamanvil/trunk/spamanvil.php
r3466819 r3466837 4 4 * Plugin URI: https://software.amato.com.br/spamanvil-antispam-plugin-for-wordpress/ 5 5 * Description: Blocks comment spam using AI/LLM services with support for multiple providers, async processing, and intelligent heuristics. 6 * Version: 1.2. 26 * Version: 1.2.3 7 7 * Requires at least: 5.8 8 8 * Requires PHP: 7.4 … … 19 19 } 20 20 21 define( 'SPAMANVIL_VERSION', '1.2. 2' );21 define( 'SPAMANVIL_VERSION', '1.2.3' ); 22 22 define( 'SPAMANVIL_DB_VERSION', '1.0.0' ); 23 23 define( 'SPAMANVIL_PLUGIN_FILE', __FILE__ );
Note: See TracChangeset
for help on using the changeset viewer.