wpdb = $wpdb; $this->table_name = $wpdb->prefix . 'atk_ai_logs'; // Single known table name } public function insert_log( $user_id, $action, $action_name, $action_type, $action_status, $url = '' ) { // Don't save IP on Disabled option $atk_options = get_option('atk_options'); $ip_log_disabled = isset( $atk_options['atk_no_ip'] ) ? esc_attr( $atk_options['atk_no_ip'] ) : 0; $utils = new AtkUtils(); $action_url = ! empty( $url ) ? $url : $utils::get_current_url(); $real_ip = $utils::get_user_ip( true ); $user_ip = ( $ip_log_disabled == 1 ) ? '' : $utils::get_user_ip(); // Event recording must not wait on remote location services or scan historical logs. $ip_location = $ip_log_disabled == 1 ? '' : AtkGeoLocation::geolocate_ip( $real_ip, false ); $ip_location_json = ! empty( $ip_location ) ? wp_json_encode( $ip_location ) : ''; // Ensure action_name is never null if ( is_null( $action_name ) ) { $action_name = 'Other'; } // Sanitize logger inputs $action_name = wp_kses_post( $action_name ); // strip disallowed HTML $action_type = wp_kses_post( $action_type ); // strip disallowed HTML $action_status = sanitize_text_field( $action_status ); // clean status/text $action_url = esc_url_raw( $action_url ); // clean URL $data = array( 'user_id' => $user_id, 'action' => $action, 'action_name' => $action_name, 'action_type' => $action_type, 'user_ip_address'=> $user_ip, 'ip_location' => $ip_location_json, 'action_url' => $action_url, 'created_date' => current_time( 'mysql', 1 ), 'updated_date' => current_time( 'mysql', 1 ), ); // Formats of the columns $format = array( '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ); // 1) Prevent duplicate logs within the last 3 seconds $threshold_time = gmdate( 'Y-m-d H:i:s', time() - 3 ); // 2) Table name as a literal variable (PHPCS sees this as a constant string). $table_name = $this->table_name; // one known table // 3) Build the query using placeholders for all user-based values // phpcs:ignore WordPress.DB $query = $this->wpdb->prepare( "SELECT log_id FROM %i WHERE user_id = %d AND action = %s AND action_name = %s AND action_type = %s AND user_ip_address = %s AND action_url = %s AND created_date >= %s ORDER BY created_date DESC LIMIT 1", array( $table_name, $user_id, $action, $action_name, $action_type, $user_ip, $action_url, $threshold_time, ) ); // phpcs:ignore WordPress.DB $existing = $this->wpdb->get_row( $query ); if ( $existing ) { // Return existing log ID to avoid duplicate entry return $existing->log_id; } // 4) Use $wpdb->insert() for the new record $this->wpdb->insert( $table_name, $data, $format ); // 5) Trigger Email Notification $notification = new Atk_Admin_Notifications(); $notification->send_activity_notification_email( strtolower( $action ), $action_status, $user_id ); return $this->wpdb->insert_id; // Returns the ID of the inserted row } }