// ... existing code ... * Plugin Name: DMP Châu Âu - Giám Sát IP & Chẩn Đoán Click Tặc Bằng AI (Chế Độ Thuần Ghi Nhận) * Plugin URI: https://dmpchauau.com * Description: Bộ ghi nhật ký thụ động (Passive Logger) 100%: Ghi nhận IP và tham số quảng cáo (gclid, fbclid, utm), xuất báo cáo CSV và tích hợp AI Gemini Flash để chẩn đoán trong 7 ngày gần nhất. Tự động dọn dẹp bản ghi cũ để tối ưu cơ sở dữ liệu. * Version: 1.2.0 * Author: Dược Mỹ Phẩm Châu Âu * License: GPL2 * Text Domain: dmp-fraud-guard */ if ( ! defined( 'ABSPATH' ) ) { exit; // Chống truy cập trực tiếp } if ( ! class_exists( 'DMP_Anti_Fraud_Guard' ) ) { class DMP_Anti_Fraud_Guard { private static $instance = null; private $table_name; public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } public function __construct() { global $wpdb; $this->table_name = $wpdb->prefix . 'dmp_click_logs'; // Kích hoạt & cài đặt bảng cơ sở dữ liệu register_activation_hook( __FILE__, array( $this, 'create_database_table' ) ); register_deactivation_hook( __FILE__, array( $this, 'clear_scheduled_cron' ) ); // Menu quản trị add_action( 'admin_menu', array( $this, 'register_admin_menu' ) ); add_action( 'admin_init', array( $this, 'register_settings' ) ); // Ghi nhận IP truy cập ở Frontend (Hoạt động hoàn toàn thụ động) add_action( 'wp', array( $this, 'log_visitor_click' ) ); // Xử lý xuất file CSV add_action( 'admin_init', array( $this, 'handle_csv_export' ) ); // AJAX: Phân tích Click Tặc bằng AI Gemini add_action( 'wp_ajax_dmp_ai_diagnose_clicks', array( $this, 'ajax_diagnose_clicks_with_ai' ) ); // AJAX: Dọn sạch nhật ký cũ add_action( 'wp_ajax_dmp_clear_click_logs', array( $this, 'ajax_clear_click_logs' ) ); // Tự động dọn dẹp các bản ghi cũ hơn 7 ngày bằng WP-Cron add_action( 'dmp_fraud_daily_prune_logs', array( $this, 'prune_expired_logs' ) ); if ( ! wp_next_scheduled( 'dmp_fraud_daily_prune_logs' ) ) { wp_schedule_event( time() + 3600, 'daily', 'dmp_fraud_daily_prune_logs' ); } } public function clear_scheduled_cron() { wp_clear_scheduled_hook( 'dmp_fraud_daily_prune_logs' ); } // ... existing code ... public function register_settings() { register_setting( 'dmp_fraud_settings_group', 'dmp_fraud_enabled', array( 'sanitize_callback' => 'sanitize_text_field', 'default' => 'yes' ) ); register_setting( 'dmp_fraud_settings_group', 'dmp_fraud_gemini_api_key', array( 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ) ); register_setting( 'dmp_fraud_settings_group', 'dmp_fraud_ignore_bots', array( 'sanitize_callback' => 'sanitize_text_field', 'default' => 'yes' ) ); register_setting( 'dmp_fraud_settings_group', 'dmp_fraud_retention_days', array( 'sanitize_callback' => 'absint', 'default' => 7 ) ); } /** * TỰ ĐỘNG DỌN DẸP BẢN GHI CŨ HƠN 7 NGÀY * Giúp cơ sở dữ liệu luôn nhẹ nhàng, bảo toàn hiệu năng hosting */ public function prune_expired_logs() { global $wpdb; $retention_days = (int) get_option( 'dmp_fraud_retention_days', 7 ); if ( $retention_days < 1 ) { $retention_days = 7; } $wpdb->query( $wpdb->prepare( "DELETE FROM {$this->table_name} WHERE created_at < DATE_SUB(NOW(), INTERVAL %d DAY)", $retention_days ) ); } // ... existing code ... public function handle_csv_export() { if ( ! isset( $_POST['dmp_export_action'] ) || 'export_csv' !== $_POST['dmp_export_action'] ) { return; } if ( ! current_user_can( 'manage_options' ) ) { wp_die( 'Bạn không có quyền xuất dữ liệu.' ); } check_admin_referer( 'dmp_export_nonce', 'dmp_nonce' ); global $wpdb; $filter_type = isset( $_POST['export_filter'] ) ? sanitize_text_field( $_POST['export_filter'] ) : '7days_all'; $where_clauses = array(); if ( '7days_all' === $filter_type ) { $where_clauses[] = "created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)"; } elseif ( '7days_ads' === $filter_type ) { $where_clauses[] = "created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)"; $where_clauses[] = "(ad_campaign != '' OR gclid != '')"; } elseif ( 'ads_only' === $filter_type ) { $where_clauses[] = "(ad_campaign != '' OR gclid != '')"; } $where_sql = ! empty( $where_clauses ) ? implode( ' AND ', $where_clauses ) : '1=1'; $rows = $wpdb->get_results( "SELECT * FROM {$this->table_name} WHERE {$where_sql} ORDER BY id DESC LIMIT 25000", ARRAY_A ); $filename = 'dmpchauau_traffic_7days_' . date( 'Y-m-d_H-i' ) . '.csv'; if ( ob_get_level() ) { ob_end_clean(); } header( 'Content-Type: text/csv; charset=UTF-8' ); header( 'Content-Disposition: attachment; filename="' . $filename . '"' ); header( 'Pragma: no-cache' ); header( 'Expires: 0' ); $output = fopen( 'php://output', 'w' ); // Đính kèm UTF-8 BOM để Excel hiển thị đúng dấu tiếng Việt fprintf( $output, chr(0xEF) . chr(0xBB) . chr(0xBF) ); fputcsv( $output, array( 'Mã Bản Ghi', 'Địa Chỉ IP', 'Thời Gian', 'Kênh Chiến Dịch', 'Mã Quảng Cáo (gclid)', 'Loại Thiết Bị', 'Trang Đã Xem', 'Nguồn Giới Thiệu (Referer)', 'Trình Duyệt (User Agent)' ) ); foreach ( $rows as $r ) { fputcsv( $output, array( $r['id'], $r['ip_address'], $r['created_at'], $r['ad_campaign'], $r['gclid'], $r['device_type'], $r['visited_url'], $r['referer_url'], $r['user_agent'], ) ); } fclose( $output ); exit; } public function ajax_diagnose_clicks_with_ai() { check_ajax_referer( 'dmp_ai_guard_nonce', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'Không có quyền truy cập.' ); } global $wpdb; // Lấy danh sách 20 IP có tần suất tương tác cao nhất trong 7 ngày qua $suspicious_ips = $wpdb->get_results( " SELECT ip_address, COUNT(*) as click_count, COUNT(DISTINCT visited_url) as unique_pages, GROUP_CONCAT(DISTINCT ad_campaign SEPARATOR ', ') as campaigns, MAX(created_at) as last_seen, MIN(created_at) as first_seen, SUBSTRING(user_agent, 1, 80) as ua_sample, device_type FROM {$this->table_name} WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) GROUP BY ip_address ORDER BY click_count DESC LIMIT 20 ", ARRAY_A ); if ( empty( $suspicious_ips ) ) { wp_send_json_error( 'Chưa có đủ dữ liệu truy cập trong 7 ngày qua để phân tích.' ); } $apiKey = trim( get_option( 'dmp_fraud_gemini_api_key', '' ) ); $apiUrl = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={$apiKey}"; $systemPrompt = "Bạn là chuyên gia phân tích dữ liệu lưu lượng truy cập và gian lận quảng cáo (Ad Fraud / Click Fraud Prevention) cho website thương mại điện tử DMP Châu Âu (dmpchauau.com). Plugin này là bộ ghi nhật ký thụ động (Passive Logger), không chặn khách hàng thật. Nhiệm vụ của bạn: Dựa vào các thống kê IP trong vòng 7 ngày gần nhất được cung cấp (tổng số click, khoảng cách thời gian giữa các click, tốc độ click/phút, kênh quảng cáo, loại thiết bị, User-Agent), hãy chẩn đoán và phân loại rõ ràng: 1. Đánh giá xác suất click tặc hoặc bot phá hoại (🔴 Nguy cơ cao / 🟡 Cảnh báo nghi vấn / 🟢 Khách hàng thật xem nhiều sản phẩm). 2. Tóm tắt phân tích hành vi cho từng IP nổi bật trong chu kỳ 7 ngày. 3. Cung cấp danh sách các IP nghi vấn nhất để quản trị viên có thể chủ động nhập vào mục loại trừ IP (Negative IP Exclusions) của chiến dịch Google Ads nếu họ muốn. Trả về bằng tiếng Việt rõ ràng, súc tích, định dạng Markdown trực quan."; $ip_data_summary = "Dữ liệu các địa chỉ IP có số lượt click cao nhất trong 7 ngày qua trên dmpchauau.com:\n"; foreach ( $suspicious_ips as $idx => $item ) { $span_seconds = max( 1, strtotime( $item['last_seen'] ) - strtotime( $item['first_seen'] ) ); $clicks_per_minute = round( ( $item['click_count'] / ( $span_seconds / 60 ) ), 2 ); $ip_data_summary .= sprintf( "[%d] IP: %s | Click: %d | Số trang: %d | Kênh: %s | Thiết bị: %s | Tần suất: %s đến %s (~%s click/phút) | UA: %s\n", $idx + 1, $item['ip_address'], $item['click_count'], $item['unique_pages'], $item['campaigns'] ?: 'Truy cập tự nhiên', $item['device_type'], $item['first_seen'], $item['last_seen'], $clicks_per_minute, $item['ua_sample'] ); } $userQuery = "Hãy phân tích chi tiết dữ liệu IP trong 7 ngày qua và đưa ra chẩn đoán:\n" . $ip_data_summary; // ... existing code ... public function render_admin_page() { global $wpdb; // Thống kê tổng quan trong 7 ngày gần nhất $total_clicks_7d = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$this->table_name} WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)" ); $total_ips_7d = (int) $wpdb->get_var( "SELECT COUNT(DISTINCT ip_address) FROM {$this->table_name} WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)" ); $ad_clicks_7d = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$this->table_name} WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) AND (ad_campaign != '' OR gclid != '')" ); // 25 bản ghi gần đây nhất $recent_logs = $wpdb->get_results( "SELECT * FROM {$this->table_name} WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) ORDER BY id DESC LIMIT 25", ARRAY_A ); // Top IP tương tác nhiều nhất trong 7 ngày qua $top_repeat_ips_7d = $wpdb->get_results( " SELECT ip_address, COUNT(*) as clicks, MAX(ad_campaign) as last_camp, MAX(created_at) as last_click FROM {$this->table_name} WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) GROUP BY ip_address HAVING clicks >= 5 ORDER BY clicks DESC LIMIT 8 ", ARRAY_A ); $enabled = get_option( 'dmp_fraud_enabled', 'yes' ); $api_key = get_option( 'dmp_fraud_gemini_api_key', '' ); $ignore_bot = get_option( 'dmp_fraud_ignore_bots', 'yes' ); $retention_days = (int) get_option( 'dmp_fraud_retention_days', 7 ); ?>
Hoạt động thụ động 100%: Ghi nhận & phân tích lưu lượng trong vòng 7 ngày gần nhất. Tự động thanh lọc các bản ghi cũ để giữ hosting nhẹ nhàng.