rl-warmup-plugin/includes/class-rl-mailwarmer-db-helper.php

314 lines
No EOL
12 KiB
PHP

<?php
class RL_MailWarmer_DB_Helper {
private static $conversations_table = 'rl_mailwarmer_conversations';
private static $messages_table = 'rl_mailwarmer_messages';
private static $backups_table = 'rl_mailwarmer_dns_backups';
private static $health_reports_table = 'rl_mailwarmer_health_reports';
/**
* Create necessary database tables.
*/
public static function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// Conversation table
$conversation_sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}" . self::$conversations_table . "` (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
campaign_id BIGINT(20) UNSIGNED NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
status VARCHAR(20) DEFAULT 'new' NOT NULL,
first_message_timestamp DATETIME DEFAULT NULL,
prompt LONGTEXT DEFAULT NULL,
conversation_steps LONGTEXT DEFAULT NULL,
PRIMARY KEY (id),
KEY campaign_id_idx (campaign_id),
KEY status_idx (status),
KEY first_message_timestamp_idx (first_message_timestamp)
) $charset_collate;";
// Message table
$message_sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}" . self::$messages_table . "` (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
campaign_id BIGINT(20) UNSIGNED NOT NULL,
conversation_id BIGINT(20) UNSIGNED NOT NULL,
scheduled_for_timestamp DATETIME NOT NULL,
status ENUM('pending', 'in_progress', 'sent', 'failed') NOT NULL DEFAULT 'pending',
from_email VARCHAR(255) NOT NULL,
to_email TEXT NOT NULL,
cc TEXT NULL,
subject VARCHAR(255) NOT NULL,
body LONGTEXT NOT NULL,
PRIMARY KEY (id),
INDEX scheduled_idx (scheduled_for_timestamp, status),
INDEX conversation_id_idx (conversation_id),
INDEX campaign_id_idx (campaign_id)
) $charset_collate;";
// Backup table
$backup_sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}" . self::$backups_table . "` (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
domain_id BIGINT UNSIGNED NOT NULL,
record_name VARCHAR(255) NOT NULL,
record_type VARCHAR(50) NOT NULL,
record_content LONGTEXT NOT NULL,
created_at DATETIME NOT NULL,
INDEX (domain_id),
INDEX (record_name),
INDEX (record_type)
) $charset_collate;";
// Backup table
$health_report_sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}" . self::$health_reports_table . "` (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
domain_id BIGINT UNSIGNED NOT NULL,
report_content LONGTEXT NOT NULL,
created_at DATETIME NOT NULL,
last_checked DATETIME NOT NULL,
INDEX (domain_id)
) $charset_collate;";
// DNS Backup table
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta($conversation_sql);
dbDelta($message_sql);
dbDelta($backup_sql);
dbDelta($health_report_sql);
}
/**
* Insert a conversation record.
*/
public static function insert_conversation($conversation_data) {
global $wpdb;
// $wpdb->insert(
// "{$wpdb->prefix}" . self::$conversations_table,
// [
// 'campaign_id' => $campaign_id,
// 'conversation_steps' => json_encode($conversation_steps),
// 'prompt' => $prompt,
// ],
// ['%d', '%s', '%s']
// );
$wpdb->insert("{$wpdb->prefix}" . self::$conversations_table, $conversation_data);
return $wpdb->insert_id;
}
/**
* Insert a message record.
*/
public static function insert_message($message_data) {
global $wpdb;
// log_to_file("insert_message - Message body: $body");
// $wpdb->insert(
// "{$wpdb->prefix}rl_mailwarmer_message",
// [
// 'campaign_id' => $campaign_id,
// 'conversation_id' => $conversation_id,
// 'scheduled_for_timestamp' => $scheduled_for,
// 'status' => 'pending',
// 'from_email' => $from_email,
// 'to_email' => $to_email,
// 'cc' => $cc,
// 'subject' => $subject,
// 'body' => $body,
// 'first_message' => $first_message ? 1 : 0,
// ],
// ['%d', '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d']
// );
$wpdb->insert("{$wpdb->prefix}" . self::$messages_table, $message_data);
return $wpdb->insert_id;
}
/**
* Fetch pending messages.
*/
public static function fetch_pending_messages($limit = 100) {
global $wpdb;
$sql = $wpdb->prepare(
"SELECT * FROM `{$wpdb->prefix}" . self::$messages_table . "`
WHERE scheduled_for_timestamp <= %s AND status = 'pending'
LIMIT %d",
current_time('mysql'),
$limit
);
return $wpdb->get_results($sql, ARRAY_A);
}
// Get Message Counts
public static function get_message_counts_by_date($campaign_id) {
global $wpdb;
$messages_table = $wpdb->prefix . self::$messages_table;
$results = $wpdb->get_results(
$wpdb->prepare(
"SELECT
DATE(scheduled_for_timestamp) AS message_date,
COUNT(*) AS message_count
FROM
$messages_table
WHERE
campaign_id = %d
GROUP BY
DATE(scheduled_for_timestamp)
ORDER BY
message_date ASC",
$campaign_id
),
ARRAY_A
);
return $results;
}
/**
* Insert DNS backups into the database.
*
* @param mixed $domain The domain ID or post object.
* @param array $records The DNS records to back up.
* @return bool True on success, false on failure.
*/
public static function insert_dns_backup($domain, $record) {
global $wpdb;
$backups_table = $wpdb->prefix . 'rl_mailwarmer_dns_backups';
$domain_post = is_object($domain) ? $domain : RL_MailWarmer_Domain_Helper::get_domain_post($domain);
if (!$domain_post) {
throw new Exception(__('Invalid domain specified.', 'rl-mailwarmer'));
}
// log_to_file("insert_dns_backup - Attemting to backup record: ", $record);
$existing = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM $backups_table WHERE domain_id = %d AND record_name = %s AND record_type = %s ORDER BY created_at DESC LIMIT 1",
$domain_post->ID,
$record['name'],
$record['type']
),
ARRAY_A
);
if ($existing && $existing['record_content'] === $record['content']) {
// log_to_file("insert_dns_backup - New & Old content are the same. Skipping insert and returning TRUE");
// return true;
return $existing['id'];
// continue; // Skip unchanged records
}
try {
$wpdb->insert($backups_table, [
'domain_id' => $domain_post->ID,
'record_name' => $record['name'],
'record_type' => $record['type'],
'record_content' => $record['content'],
'created_at' => current_time('mysql'),
]);
} catch (Exception $e) {
error_log(__('insert_dns_backup - Failed to insert new DNS backup record: ', 'rl-mailwarmer') . $e->getMessage());
}
return $wpdb->insert_id;
// return true;
}
/**
* Insert health report backups into the database.
*
* @param mixed $domain The domain ID or post object.
* @param array $records The DNS records to back up.
* @return bool True on success, false on failure.
*/
public static function insert_health_report_backup($domain, $report) {
global $wpdb;
$health_reports_table = $wpdb->prefix . 'rl_mailwarmer_health_reports';
$domain_post = is_object($domain) ? $domain : RL_MailWarmer_Domain_Helper::get_domain_post($domain);
if (!$domain_post) {
throw new Exception(__('Invalid domain specified.', 'rl-mailwarmer'));
}
// log_to_file("insert_health_report_backup - Attempting to save health report for {$domain_post->post_title}: ");
try {
// log_to_file("insert_health_report_backup - Fetching existing rows.");
$existing = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM $health_reports_table WHERE domain_id = %d ORDER BY created_at DESC LIMIT 1",
$domain_post->ID
),
ARRAY_A
);
// log_to_file("insert_health_report_backup - Done fetching existing rows.");
if ($existing && $existing['report_content'] === $report) {
// log_to_file("insert_health_report_backup - New & Old content are the same. Skipping insert and returning ID of existing record");
// Prepare the data
$data = [
'last_checked' => current_time('mysql'), // Save the JSON response as a string
];
$where = [
'id' => $existing['id'],
];
// Update the database
try {
$result = $wpdb->update(
$health_reports_table,
$data,
$where,
['%s'],
['%d']
);
} catch (Exception $e) {
log_to_file("insert_health_report_backup - Error updating existing database entry.");
throw new Exception(__('insert_health_report_backup - Error updating existing database entry: ', 'rl-mailwarmer') . $e->getMessage());
}
return $existing['id'];
// continue; // Skip unchanged records
}
} catch (Exception $e) {
log_to_file("insert_health_report_backup - Error fetching existing rows.");
throw new Exception(__('insert_health_report_backup - Unable to fetch existing records: ', 'rl-mailwarmer') . $e->getMessage());
}
try {
$current_time = current_time('mysql');
$data = [
'domain_id' => $domain_post->ID,
'report_content' => $report,
'created_at' => $current_time,
'last_checked' => $current_time,
];
$result = $wpdb->insert(
$health_reports_table,
$data
);
if ($result === false) {
return new WP_Error('db_update_failed', __('Failed to update the conversation steps.', 'rl-mailwarmer'));
}
return $result;
} catch (Exception $e) {
throw new Exception(__('insert_health_report_backup - Failed to insert new health report record: ', 'rl-mailwarmer') . $e->getMessage());
// error_log(__('insert_dns_backup - Failed to insert new health report record: ', 'rl-mailwarmer') . $e->getMessage());
}
return false;
}
}