prefix . 'aicomo_moderation_history'; // ? Updated table name // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->replace( $table_name, [ 'comment_id' => $comment_ID, 'action' => $result['decision'], 'ai_confidence' => $result['confidence'], ], ['%d', '%s', '%f'] ); // Clear the cached data after writing to keep it fresh wp_cache_delete('aicomo_moderation_history', 'aicomo'); // ? Updated cache key wp_send_json_success($result); } add_action('wp_ajax_aicomo_analyze_comment', 'aicomo_ajax_analyze_comment'); // ? Updated AJAX action name /** * AJAX handler for fetching moderation status */ function aicomo_ajax_fetch_status() { // ? Proper nonce validation with unslash and sanitize if ( !isset($_POST['security']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['security'])), 'aicomo_nonce_action') ) { wp_send_json_error('Invalid nonce. Access denied.'); wp_die(); } // ? Check User Permissions if (!current_user_can('manage_options')) { wp_send_json_error('Unauthorized access.'); wp_die(); } global $wpdb; $table_name = $wpdb->prefix . 'ai_moderation_history'; // ? Updated table name $cache_key = 'ai_moderation_history'; // ? Updated cache key $cache_group = 'ai_moderator'; // Try fetching from cache $results = wp_cache_get($cache_key, $cache_group); if (false === $results) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $results = $wpdb->get_results("SELECT comment_id, action, ai_confidence FROM {$table_name}"); // Cache results if available if (!empty($results)) { wp_cache_set($cache_key, $results, $cache_group, 3600); } } if (empty($results)) { wp_send_json_success([]); wp_die(); } // Format response $response = []; foreach ($results as $row) { $response[intval($row->comment_id)] = [ 'decision' => !empty($row->action) ? esc_html($row->action) : esc_html__('Pending Analysis', 'ai-powered-comment-moderator'), 'confidence' => isset($row->ai_confidence) ? esc_html(round(floatval($row->ai_confidence), 2) . '%') : esc_html__('N/A', 'ai-powered-comment-moderator'), ]; } wp_send_json_success($response); wp_die(); } add_action('wp_ajax_aicomo_fetch_moderation_status', 'aicomo_ajax_fetch_status'); // ? Updated AJAX action name /** * AJAX handler for automatic moderation */ function aicomo_ajax_auto_moderate() { // Must match the exact nonce string 'aicomo_nonce_action' check_ajax_referer('aicomo_nonce_action', 'security'); if (!current_user_can('manage_options')) { wp_send_json_error('Unauthorized'); } // Validate comment_id from POST if (!isset($_POST['comment_id']) || !is_numeric($_POST['comment_id'])) { wp_send_json_error('Invalid request'); } $comment_ID = intval($_POST['comment_id']); $result = aicomo_moderate_comment($comment_ID); if (isset($result['error'])) { wp_send_json_error($result['error']); } // Persist the decision in the database global $wpdb; $table_name = $wpdb->prefix . 'ai_moderation_history'; // ? Updated table name // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->replace( $table_name, [ 'comment_id' => $comment_ID, 'action' => $result['decision'], 'ai_confidence' => $result['confidence'], ], ['%d', '%s', '%f'] ); // Clear the cache after writing wp_cache_delete('ai_moderation_history', 'aicomo'); // ? Updated cache key wp_send_json_success($result); } add_action('wp_ajax_aicomo_auto_moderate_comment', 'aicomo_ajax_auto_moderate'); // ? Updated AJAX action name