prefix . 'aha_mail_smtp_logs'; $this->init_hooks(); } /** * Initialize hooks */ private function init_hooks() { add_action('wp_ajax_aha_mail_smtp_clear_logs', array($this, 'clear_logs_ajax')); add_action('wp_ajax_aha_mail_smtp_get_logs', array($this, 'get_logs_ajax')); add_action('wp_ajax_aha_mail_smtp_delete_log', array($this, 'delete_log_ajax')); add_action('wp_ajax_aha_mail_smtp_view_log', array($this, 'view_log_ajax')); // Schedule cleanup task if (!wp_next_scheduled('aha_mail_smtp_cleanup_logs')) { wp_schedule_event(time(), 'daily', 'aha_mail_smtp_cleanup_logs'); } add_action('aha_mail_smtp_cleanup_logs', array($this, 'cleanup_old_logs')); } /** * Log email */ public static function log_email($data) { if (!AHA_Mail_SMTP_Settings::get('enable_logging')) { return false; } // Validate input data if (!is_array($data)) { return false; } global $wpdb; // Check if table exists, create it if not if (!self::table_exists()) { self::create_table(); // If still doesn't exist, return false if (!self::table_exists()) { return false; } } $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; // Safely extract data with defaults $log_data = array( 'to_email' => isset($data['to_email']) ? sanitize_text_field($data['to_email']) : '', 'subject' => isset($data['subject']) ? sanitize_text_field($data['subject']) : '', 'message' => isset($data['message']) ? wp_kses_post($data['message']) : '', 'headers' => isset($data['headers']) ? sanitize_textarea_field($data['headers']) : '', 'attachments' => isset($data['attachments']) ? sanitize_text_field($data['attachments']) : '', 'status' => isset($data['status']) ? sanitize_text_field($data['status']) : 'pending', 'error_message' => isset($data['error_message']) ? sanitize_text_field($data['error_message']) : '', 'date_sent' => current_time('mysql') ); $result = $wpdb->insert($table_name, $log_data); return $result !== false; } /** * Check if logs table exists */ public static function table_exists() { global $wpdb; $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; return $wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name; } /** * Create logs table if it doesn't exist */ public static function create_table() { global $wpdb; $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id bigint(20) NOT NULL AUTO_INCREMENT, to_email varchar(255) NOT NULL, subject text NOT NULL, message longtext NOT NULL, headers text, attachments text, status varchar(20) NOT NULL DEFAULT 'pending', error_message text, date_sent datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY status (status), KEY date_sent (date_sent) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); return self::table_exists(); } /** * Get logs */ public static function get_logs($limit = 50, $offset = 0, $status = '') { global $wpdb; // Check if table exists, create it if not if (!self::table_exists()) { self::create_table(); // If still doesn't exist, return empty array if (!self::table_exists()) { return array(); } } $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; $where = ''; if (!empty($status)) { $where = $wpdb->prepare(' WHERE status = %s', $status); } $sql = $wpdb->prepare( "SELECT * FROM $table_name $where ORDER BY date_sent DESC LIMIT %d OFFSET %d", $limit, $offset ); $results = $wpdb->get_results($sql); // Return empty array on error instead of null return is_array($results) ? $results : array(); } /** * Get log by ID */ public static function get_log($id) { global $wpdb; $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; return $wpdb->get_row($wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id )); } /** * Delete log */ public static function delete_log($id) { global $wpdb; $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; return $wpdb->delete($table_name, array('id' => $id), array('%d')); } /** * Clear all logs */ public static function clear_all_logs() { global $wpdb; // Check if table exists if (!self::table_exists()) { return false; } $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; return $wpdb->query("TRUNCATE TABLE $table_name"); } /** * Get logs count */ public static function get_logs_count($status = '') { global $wpdb; // Check if table exists if (!self::table_exists()) { return 0; } $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; $where = ''; if (!empty($status)) { $where = $wpdb->prepare(' WHERE status = %s', $status); } $count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name $where"); return $count !== null ? (int) $count : 0; } /** * Get logs statistics */ public static function get_logs_stats() { global $wpdb; $stats = array( 'total' => 0, 'success' => 0, 'failed' => 0, 'pending' => 0 ); // Check if table exists if (!self::table_exists()) { return $stats; } $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; $results = $wpdb->get_results( "SELECT status, COUNT(*) as count FROM $table_name GROUP BY status" ); if (is_array($results)) { foreach ($results as $result) { $stats[$result->status] = (int) $result->count; $stats['total'] += (int) $result->count; } } return $stats; } /** * Cleanup old logs */ public function cleanup_old_logs() { global $wpdb; $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; // Delete logs older than 30 days $wpdb->query($wpdb->prepare( "DELETE FROM $table_name WHERE date_sent < %s", date('Y-m-d H:i:s', strtotime('-30 days')) )); // Keep only the latest 1000 logs $wpdb->query( "DELETE FROM $table_name WHERE id NOT IN ( SELECT id FROM ( SELECT id FROM $table_name ORDER BY date_sent DESC LIMIT 1000 ) as temp )" ); } /** * Clear logs via AJAX */ public function clear_logs_ajax() { // Verify nonce if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'aha_mail_smtp_admin')) { wp_send_json_error(__('Security check failed', 'aha-mail-smtp')); } // Check user capabilities if (!current_user_can('manage_options')) { wp_send_json_error(__('You do not have sufficient permissions', 'aha-mail-smtp')); } $result = self::clear_all_logs(); if ($result !== false) { wp_send_json_success(__('All logs cleared successfully!', 'aha-mail-smtp')); } else { wp_send_json_error(__('Failed to clear logs', 'aha-mail-smtp')); } } /** * Get logs via AJAX */ public function get_logs_ajax() { // Verify nonce if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'aha_mail_smtp_admin')) { wp_send_json_error(__('Security check failed', 'aha-mail-smtp')); } // Check user capabilities if (!current_user_can('manage_options')) { wp_send_json_error(__('You do not have sufficient permissions', 'aha-mail-smtp')); } $page = isset($_POST['page']) ? (int) $_POST['page'] : 1; $per_page = isset($_POST['per_page']) ? (int) $_POST['per_page'] : 20; $status = isset($_POST['status']) ? sanitize_text_field($_POST['status']) : ''; $offset = ($page - 1) * $per_page; $logs = self::get_logs($per_page, $offset, $status); $total = self::get_logs_count($status); $stats = self::get_logs_stats(); wp_send_json_success(array( 'logs' => $logs, 'total' => $total, 'stats' => $stats, 'page' => $page, 'per_page' => $per_page, 'total_pages' => ceil($total / $per_page) )); } /** * Delete log via AJAX */ public function delete_log_ajax() { // Verify nonce if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'aha_mail_smtp_admin')) { wp_send_json_error(__('Security check failed', 'aha-mail-smtp')); } // Check user capabilities if (!current_user_can('manage_options')) { wp_send_json_error(__('You do not have sufficient permissions', 'aha-mail-smtp')); } $log_id = (int) $_POST['log_id']; if (empty($log_id)) { wp_send_json_error(__('Invalid log ID', 'aha-mail-smtp')); } $result = self::delete_log($log_id); if ($result) { wp_send_json_success(__('Log deleted successfully!', 'aha-mail-smtp')); } else { wp_send_json_error(__('Failed to delete log', 'aha-mail-smtp')); } } /** * View log via AJAX */ public function view_log_ajax() { // Verify nonce if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'aha_mail_smtp_admin')) { wp_send_json_error(__('Security check failed', 'aha-mail-smtp')); } // Check user capabilities if (!current_user_can('manage_options')) { wp_send_json_error(__('You do not have sufficient permissions', 'aha-mail-smtp')); } $log_id = (int) $_POST['log_id']; if (empty($log_id)) { wp_send_json_error(__('Invalid log ID', 'aha-mail-smtp')); } $log = self::get_log($log_id); if (!$log) { wp_send_json_error(__('Log not found', 'aha-mail-smtp')); } wp_send_json_success($log); } /** * Export logs to CSV */ public static function export_logs_csv($status = '') { $logs = self::get_logs(1000, 0, $status); // Export up to 1000 logs if (empty($logs)) { return false; } $filename = 'aha-mail-smtp-logs-' . date('Y-m-d-H-i-s') . '.csv'; $filepath = wp_upload_dir()['path'] . '/' . $filename; $file = fopen($filepath, 'w'); // CSV headers fputcsv($file, array( 'ID', 'Date', 'To Email', 'Subject', 'Status', 'Error Message', 'Attachments' )); // CSV data foreach ($logs as $log) { fputcsv($file, array( $log->id, $log->date_sent, $log->to_email, $log->subject, $log->status, $log->error_message, $log->attachments )); } fclose($file); return array( 'filename' => $filename, 'filepath' => $filepath, 'url' => wp_upload_dir()['url'] . '/' . $filename ); } /** * Get recent activity */ public static function get_recent_activity($days = 7) { global $wpdb; $table_name = $wpdb->prefix . 'aha_mail_smtp_logs'; $results = $wpdb->get_results($wpdb->prepare( "SELECT DATE(date_sent) as date, status, COUNT(*) as count FROM $table_name WHERE date_sent >= %s GROUP BY DATE(date_sent), status ORDER BY date DESC", date('Y-m-d H:i:s', strtotime("-$days days")) )); $activity = array(); foreach ($results as $result) { if (!isset($activity[$result->date])) { $activity[$result->date] = array( 'success' => 0, 'failed' => 0, 'pending' => 0, 'total' => 0 ); } $activity[$result->date][$result->status] = (int) $result->count; $activity[$result->date]['total'] += (int) $result->count; } return $activity; } }