Implement AI-powered conversation generation and improved campaign timeline management
- Add OpenAI integration for realistic email conversation generation - Enhance campaign timeline algorithm with natural distribution patterns - Improve message handling with Symfony Mailer components - Add conversation blueprint system for structured email threads - Implement visual timeline with heatmap for campaign tracking 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
cc6dc646b2
commit
de40085318
11 changed files with 2031 additions and 1360 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -19,15 +19,18 @@ class RL_MailWarmer_DB_Helper {
|
|||
$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,
|
||||
email_account_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,
|
||||
ai_response LONGTEXT DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY campaign_id_idx (campaign_id),
|
||||
KEY status_idx (status),
|
||||
KEY first_message_timestamp_idx (first_message_timestamp)
|
||||
KEY first_message_timestamp_idx (first_message_timestamp),
|
||||
INDEX email_account_id_idx (email_account_id)
|
||||
) $charset_collate;";
|
||||
|
||||
// Message table
|
||||
|
|
@ -35,6 +38,7 @@ class RL_MailWarmer_DB_Helper {
|
|||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
campaign_id BIGINT(20) UNSIGNED NOT NULL,
|
||||
conversation_id BIGINT(20) UNSIGNED NOT NULL,
|
||||
email_account_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,
|
||||
|
|
@ -45,7 +49,8 @@ class RL_MailWarmer_DB_Helper {
|
|||
PRIMARY KEY (id),
|
||||
INDEX scheduled_idx (scheduled_for_timestamp, status),
|
||||
INDEX conversation_id_idx (conversation_id),
|
||||
INDEX campaign_id_idx (campaign_id)
|
||||
INDEX campaign_id_idx (campaign_id),
|
||||
INDEX email_account_id_idx (email_account_id)
|
||||
) $charset_collate;";
|
||||
|
||||
// Backup table
|
||||
|
|
@ -85,21 +90,37 @@ class RL_MailWarmer_DB_Helper {
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a conversation record.
|
||||
*
|
||||
* @param int $conversation_id The ID of the conversation to update.
|
||||
* @param array $update_data An associative array of columns and values to update.
|
||||
*
|
||||
* @return int|false The number of rows updated, or false on error.
|
||||
*/
|
||||
public static function update_conversation($conversation_id, $update_data) {
|
||||
global $wpdb;
|
||||
|
||||
// Ensure that $conversation_id is a valid integer
|
||||
if (!is_int($conversation_id) || $conversation_id <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update the table with the provided data
|
||||
$updated = $wpdb->update(
|
||||
"{$wpdb->prefix}" . self::$conversations_table,
|
||||
$update_data,
|
||||
['id' => $conversation_id] // WHERE clause
|
||||
);
|
||||
|
||||
return $updated !== false ? $updated : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a message record.
|
||||
*/
|
||||
|
|
@ -129,6 +150,99 @@ class RL_MailWarmer_DB_Helper {
|
|||
return $wpdb->insert_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all conversations and messages for a given campaign ID.
|
||||
*
|
||||
* @param int $campaign_id The ID of the campaign.
|
||||
*/
|
||||
public static function delete_all_conversations_messages($campaign_id) {
|
||||
global $wpdb;
|
||||
|
||||
// Ensure campaign_id is an integer
|
||||
$campaign_id = (int) $campaign_id;
|
||||
|
||||
$conversations_table = $wpdb->prefix . self::$conversations_table;
|
||||
$messages_table = $wpdb->prefix . self::$messages_table;
|
||||
|
||||
// Delete messages
|
||||
$delete_messages_result = $wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $messages_table WHERE campaign_id = %d",
|
||||
$campaign_id
|
||||
)
|
||||
);
|
||||
log_to_file("delete_all_conversations_messages - delete_messages_result: ", $delete_messages_result);
|
||||
|
||||
// Delete conversations
|
||||
$delete_conversations_result = $wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $conversations_table WHERE campaign_id = %d",
|
||||
$campaign_id
|
||||
)
|
||||
);
|
||||
log_to_file("delete_all_conversations_messages - delete_conversations_result: ", $delete_conversations_result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all future conversations and messages for a given campaign ID.
|
||||
*
|
||||
* @param int $campaign_id The ID of the campaign.
|
||||
*/
|
||||
public static function delete_future_conversations_messages($campaign_id) {
|
||||
global $wpdb;
|
||||
|
||||
$conversations_table = $wpdb->prefix . self::$conversations_table;
|
||||
$messages_table = $wpdb->prefix . self::$messages_table;
|
||||
$current_time = current_time('mysql');
|
||||
|
||||
// Delete future messages
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $messages_table WHERE campaign_id = %d AND scheduled_for_timestamp > %s",
|
||||
$campaign_id,
|
||||
$current_time
|
||||
)
|
||||
);
|
||||
|
||||
// Delete future conversations
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $conversations_table WHERE campaign_id = %d AND first_message_timestamp > %s",
|
||||
$campaign_id,
|
||||
$current_time
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all conversations and messages older than X days.
|
||||
*
|
||||
* @param int $days The number of days.
|
||||
*/
|
||||
public static function delete_old_conversations_messages($days) {
|
||||
global $wpdb;
|
||||
|
||||
$conversations_table = $wpdb->prefix . self::$conversations_table;
|
||||
$messages_table = $wpdb->prefix . self::$messages_table;
|
||||
$threshold_date = date('Y-m-d H:i:s', strtotime("-$days days"));
|
||||
|
||||
// Delete old messages
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $messages_table WHERE scheduled_for_timestamp < %s",
|
||||
$threshold_date
|
||||
)
|
||||
);
|
||||
|
||||
// Delete old conversations
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $conversations_table WHERE first_message_timestamp < %s",
|
||||
$threshold_date
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch pending messages.
|
||||
|
|
|
|||
|
|
@ -115,20 +115,30 @@ class RL_MailWarmer_Domain_Helper {
|
|||
}
|
||||
|
||||
$domain_name = $domain_post->post_title;
|
||||
$credentials = self::get_cloudflare_credentials($domain_post);
|
||||
try {
|
||||
$credentials = self::get_cloudflare_credentials($domain_post);
|
||||
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(__('get_cloudflare_client - Failed to find CloudFlare zone: ', 'rl-mailwarmer') . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$client = new \GuzzleHttp\Client([
|
||||
'base_uri' => 'https://api.cloudflare.com/client/v4/',
|
||||
'domain' => $domain_name,
|
||||
'api_email' => $credentials['api_email'],
|
||||
'api_key' => $credentials['api_key'],
|
||||
'zone_id' => $credentials['zone_id'],
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
]);
|
||||
return $client;
|
||||
if ($credentials) {
|
||||
$client = new \GuzzleHttp\Client([
|
||||
'base_uri' => 'https://api.cloudflare.com/client/v4/',
|
||||
'domain' => $domain_name,
|
||||
'api_email' => $credentials['api_email'],
|
||||
'api_key' => $credentials['api_key'],
|
||||
'zone_id' => $credentials['zone_id'],
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
]);
|
||||
return $client;
|
||||
} else {
|
||||
log_to_file("get_cloudflare_client - Unable to get cloudflare client for $domain_post->post_title");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -326,18 +336,36 @@ class RL_MailWarmer_Domain_Helper {
|
|||
|
||||
$client = self::get_cloudflare_client($domain);
|
||||
// $zone_id = self::get_cloudflare_zone_id($client, $credentials, $domain_post->post_title);
|
||||
$dns_records = self::fetch_dns_records($client);
|
||||
// log_to_file("generate_domain_report - All Records: ", $dns_records);
|
||||
|
||||
$report = [
|
||||
'domain_health' => self::check_domain_registration($domain_name),
|
||||
'a_record' => self::check_a_record($dns_records),
|
||||
'mx_record' => self::check_mx_record($dns_records),
|
||||
'spf_record' => self::check_spf_record($dns_records),
|
||||
'dkim_records' => self::check_dkim_record($dns_records),
|
||||
'dmarc_record' => self::check_dmarc_record($dns_records),
|
||||
'blacklists' => self::check_blacklists($domain_name),
|
||||
];
|
||||
if ($client) {
|
||||
$dns_records = self::fetch_dns_records($client);
|
||||
log_to_file("generate_domain_report - All Records: ", $dns_records);
|
||||
|
||||
|
||||
|
||||
if (isset($dns_records[0])) {
|
||||
$report = [
|
||||
'domain_health' => self::check_domain_registration($domain_name),
|
||||
'a_record' => self::check_a_record($dns_records),
|
||||
'mx_record' => self::check_mx_record($dns_records),
|
||||
'spf_record' => self::check_spf_record($dns_records),
|
||||
'dkim_records' => self::check_dkim_record($dns_records),
|
||||
'dmarc_record' => self::check_dmarc_record($dns_records),
|
||||
'blacklists' => self::check_blacklists($domain_name),
|
||||
];
|
||||
} else {
|
||||
$report = [
|
||||
'domain_health' => self::check_domain_registration($domain_name),
|
||||
'blacklists' => self::check_blacklists($domain_name),
|
||||
];
|
||||
}
|
||||
} else {
|
||||
log_to_file("generate_domain_report - Unable to connect to CloudFlare for $domain_name");
|
||||
$report = [
|
||||
'domain_health' => self::check_domain_registration($domain_name),
|
||||
'blacklists' => self::check_blacklists($domain_name),
|
||||
];
|
||||
}
|
||||
|
||||
// log_to_file("generate_domain_report - Health Report for $domain_name: ", $report);
|
||||
|
||||
|
|
@ -439,13 +467,13 @@ class RL_MailWarmer_Domain_Helper {
|
|||
*/
|
||||
private static function check_a_record($dns_records)
|
||||
{
|
||||
$domain_name = $dns_records[0]['zone_name'];
|
||||
$domain_name = $dns_records[0]['name'];
|
||||
// log_to_file("check_a_record - Running check_mx_record for $domain_name");
|
||||
|
||||
foreach ($dns_records as $record) {
|
||||
// Check if the record matches the criteria
|
||||
// log_to_file("check_a_record - DNS Record: ", $record);
|
||||
if ( ($record['zone_name'] === $record['name']) && ($record['type'] === 'A') ) {
|
||||
if ( ($record['name'] === $domain_name) && ($record['type'] === 'A') ) {
|
||||
$ip = $record['content'];
|
||||
$http_status = self::get_http_status($domain_name);
|
||||
|
||||
|
|
@ -501,12 +529,12 @@ class RL_MailWarmer_Domain_Helper {
|
|||
*/
|
||||
private static function check_mx_record($dns_records)
|
||||
{
|
||||
$domain_name = $dns_records[0]['zone_name'];
|
||||
$domain_name = $dns_records[0]['name'];
|
||||
// log_to_file("check_mx_record - Running check_mx_record for $domain_name");
|
||||
|
||||
foreach ($dns_records as $record) {
|
||||
// Check if the record matches the criteria
|
||||
if ( ($record['zone_name'] === $domain_name) && ($record['type'] === 'MX') ) {
|
||||
if ( ($record['name'] === $domain_name) && ($record['type'] === 'MX') ) {
|
||||
$host = $record['content'];
|
||||
$ptr_record = gethostbyaddr(gethostbyname($host));
|
||||
|
||||
|
|
@ -546,7 +574,7 @@ class RL_MailWarmer_Domain_Helper {
|
|||
log_to_file("update_mx_record - Searching for existing record");
|
||||
// throw new Exception('Failed to fetch existing DNS records from CloudFlare.');
|
||||
|
||||
foreach ($dns_records['result'] as $record) {
|
||||
foreach ($dns_records as $record) {
|
||||
if ($record['content'] === $content && $record['priority'] === $priority) {
|
||||
$existing_record_id = $record['id'];
|
||||
log_to_file("update_mx_record - Matching record found");
|
||||
|
|
@ -579,14 +607,14 @@ class RL_MailWarmer_Domain_Helper {
|
|||
|
||||
log_to_file("update_mx_record - Attempting to update record");
|
||||
$response = self::update_dns_record($domain_post->ID, $domain_post->post_title, 'MX', $domain_post->post_title, $content, $ttl, $priority);
|
||||
$result = json_decode($response->getBody(), true);
|
||||
// $result = json_decode($response->getBody(), true);
|
||||
log_to_file("update_mx_record - Result: ", $result);
|
||||
|
||||
if (!$result['success']) {
|
||||
throw new Exception('Failed to update or create the MX record in CloudFlare.');
|
||||
}
|
||||
// if (!$result['success']) {
|
||||
// throw new Exception('Failed to update or create the MX record in CloudFlare.');
|
||||
// }
|
||||
|
||||
return $result; // Return the CloudFlare response
|
||||
return $response; // Return the CloudFlare response
|
||||
} catch (Exception $e) {
|
||||
log_to_file('update_mx_record - Error in update_mx_record: ' . $e->getMessage());
|
||||
return 'Error: ' . $e->getMessage();
|
||||
|
|
@ -602,7 +630,7 @@ class RL_MailWarmer_Domain_Helper {
|
|||
*/
|
||||
private static function check_spf_record($dns_records)
|
||||
{
|
||||
$domain_name = $dns_records[0]['zone_name'];
|
||||
$domain_name = $dns_records[0]['name'];
|
||||
// log_to_file("check_spf_record - Running check_spf_record for $domain_name");
|
||||
|
||||
foreach ($dns_records as $record) {
|
||||
|
|
@ -705,7 +733,7 @@ class RL_MailWarmer_Domain_Helper {
|
|||
*/
|
||||
private static function check_dmarc_record($dns_records)
|
||||
{
|
||||
$domain_name = $dns_records[0]['zone_name'];
|
||||
$domain_name = $dns_records[0]['name'];
|
||||
// log_to_file("check_dmarc_record - Running check_dmarc_record for $domain_name");
|
||||
|
||||
foreach ($dns_records as $record) {
|
||||
|
|
@ -821,8 +849,7 @@ class RL_MailWarmer_Domain_Helper {
|
|||
'TXT',
|
||||
$name,
|
||||
$wrapped_content,
|
||||
$existing_record['ttl'],
|
||||
$credentials
|
||||
$existing_record['ttl']
|
||||
);
|
||||
} else {
|
||||
return self::update_dns_record(
|
||||
|
|
@ -832,7 +859,6 @@ class RL_MailWarmer_Domain_Helper {
|
|||
$name,
|
||||
$wrapped_content,
|
||||
3600, // Default TTL
|
||||
$credentials
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -848,7 +874,7 @@ class RL_MailWarmer_Domain_Helper {
|
|||
*/
|
||||
private static function check_dkim_record($dns_records, $selectors = [])
|
||||
{
|
||||
$domain_name = $dns_records[0]['zone_name'];
|
||||
$domain_name = $dns_records[0]['name'];
|
||||
// log_to_file("check_dkim_record - Running check_dkim_record for $domain_name");
|
||||
|
||||
$dkim_records = [];
|
||||
|
|
@ -1072,7 +1098,28 @@ class RL_MailWarmer_Domain_Helper {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
$results['dkim'] = 'No servers selected for the domain.';
|
||||
log_to_file("fix_deliverability_dns_issues - No servers selected for the domain. Choosing system default.");
|
||||
$server = get_field('defaut_mailferno_mx', 'option');
|
||||
$server_id = $server->ID;
|
||||
$selector = get_field('dkim_selector', $server_id);
|
||||
$value = get_field('dkim_value', $server_id);
|
||||
if ($selector && $value) {
|
||||
$dkim_record = $findRecord($dns_records, "{$selector}._domainkey", true);
|
||||
if (!$dkim_record) {
|
||||
try {
|
||||
$dkim_result = self::update_dkim_record($domain_post, $selector, 'add', $value);
|
||||
$results['dkim'][$selector] = $dkim_result
|
||||
? "DKIM record for selector '{$selector}' added successfully."
|
||||
: "Failed to add DKIM record for selector '{$selector}'.";
|
||||
} catch (Exception $e) {
|
||||
$results['dkim'][$selector] = 'Error: ' . $e->getMessage();
|
||||
}
|
||||
} else {
|
||||
$results['dkim'][$selector] = "DKIM record for selector '{$selector}' already exists.";
|
||||
}
|
||||
} else {
|
||||
$results['dkim'][$server_id] = 'Missing DKIM selector or value for server: ' . $server_id;
|
||||
}
|
||||
}
|
||||
|
||||
// DMARC
|
||||
|
|
|
|||
|
|
@ -149,23 +149,25 @@ class RL_MailWarmer_Email_Helper
|
|||
*/
|
||||
public static function check_mail_login($email_account, $protocol = null)
|
||||
{
|
||||
log_to_file("check_mail_login - Email account id: {$email_account}");
|
||||
// log_to_file("check_mail_login - Email account id: {$email_account}");
|
||||
// Get the post object
|
||||
$post = is_numeric($email_account) ? get_post($email_account) : $email_account;
|
||||
if (!$post || $post->post_type !== 'email-account') {
|
||||
// log_to_file("check_mail_login - Not an email account post-type");
|
||||
return new WP_Error('invalid_post', __('Invalid email account post.', 'rl-mailwarmer'));
|
||||
}
|
||||
|
||||
// Fetch email provider and override defaults with saved values
|
||||
$email_provider_id = get_post_meta($post->ID, 'email_provider', true);
|
||||
// log_to_file("check_mail_login - ");
|
||||
// log_to_file("check_mail_login - email_provider_id: {$email_provider_id}");
|
||||
|
||||
// log_to_file("check_mail_login - Email Provider ID $email_provider_id");
|
||||
// log_to_file("check_mail_login - Email Provider ID $email_provider_id");
|
||||
$defaults = $email_provider_id ? self::get_provider_defaults($email_provider_id) : [];
|
||||
// log_to_file("check_mail_login - Email Provider Defaults: ", $defaults);
|
||||
// log_to_file("check_mail_login - Email Provider Defaults: ", $defaults);
|
||||
|
||||
// Fetch saved settings
|
||||
$saved_settings = [
|
||||
'email_address' => $post->post_title,
|
||||
'full_name' => get_post_meta($post->ID, 'full_name', true),
|
||||
'email_signature' => get_post_meta($post->ID, 'email_signature', true),
|
||||
'mail_password' => get_post_meta($post->ID, 'mail_password', true),
|
||||
|
|
@ -180,22 +182,22 @@ class RL_MailWarmer_Email_Helper
|
|||
// Merge saved settings with defaults
|
||||
$settings = array_merge($defaults, array_filter($saved_settings));
|
||||
|
||||
// log_to_file("check_mail_login - Using settings: ", $settings);
|
||||
// log_to_file("check_mail_login - Using settings: ", $settings);
|
||||
|
||||
$results = [];
|
||||
|
||||
// Validate IMAP connection if required
|
||||
if ($protocol === null || strtoupper($protocol) === 'IMAP') {
|
||||
$imap_result = self::validate_imap_connection($post->post_title, $settings);
|
||||
// log_to_file("check_mail_login - IMAP Result for " . $post->post_title . ": ", $imap_result);
|
||||
$imap_result = self::validate_imap_connection($settings);
|
||||
// log_to_file("check_mail_login - IMAP Result for " . $post->post_title . ": ", $imap_result);
|
||||
$results['IMAP'] = $imap_result ? __('SUCCESS', 'rl-mailwarmer') : $imap_result->get_error_message();
|
||||
update_post_meta($post->ID, 'imap_status', $results['IMAP']);
|
||||
}
|
||||
|
||||
// Validate SMTP connection if required
|
||||
if ($protocol === null || strtoupper($protocol) === 'SMTP') {
|
||||
$smtp_result = self::validate_smtp_connection($post->post_title, $settings);
|
||||
// log_to_file("check_mail_login - SMTP Result for " . $post->post_title . ": ", $imap_result);
|
||||
$smtp_result = self::validate_smtp_connection($settings, true);
|
||||
// log_to_file("check_mail_login - SMTP Result for " . $post->post_title . ": ", $smtp_result);
|
||||
$results['SMTP'] = $smtp_result ? __('SUCCESS', 'rl-mailwarmer') : $smtp_result->get_error_message();
|
||||
update_post_meta($post->ID, 'smtp_status', $results['SMTP']);
|
||||
}
|
||||
|
|
@ -223,34 +225,40 @@ class RL_MailWarmer_Email_Helper
|
|||
/**
|
||||
* Validate an IMAP connection for an email account.
|
||||
*
|
||||
* @param string $email The email address.
|
||||
* @param array $settings The server settings (imap_server, imap_port, imap_password).
|
||||
* @param array $settings The server settings (email_account, imap_server, imap_port, imap_password).
|
||||
* @return bool True if the connection is successful, false otherwise.
|
||||
*/
|
||||
private static function validate_imap_connection($email, $settings)
|
||||
public static function validate_imap_connection($settings)
|
||||
{
|
||||
if ( empty($settings['imap_server']) || empty($settings['imap_port']) ) {
|
||||
if ( empty($settings['email_address']) || empty($settings['mail_password']) || empty($settings['imap_server']) || empty($settings['imap_port']) ) {
|
||||
// log_to_file("validate_imap_connection - Incomplete connection information");
|
||||
return false; // Missing required settings
|
||||
}
|
||||
|
||||
if (!empty($settings['imap_password'])) {
|
||||
$password = $settings['imap_password'];
|
||||
} else {
|
||||
$password = $settings['mail_password'];
|
||||
}
|
||||
$password = $settings['mail_password'];
|
||||
$email = $settings['email_address'];
|
||||
|
||||
// log_to_file("validate_imap_connection - Checking IMAP connection for {$email} using: ", $settings);
|
||||
|
||||
$imap_server = '{' . $settings['imap_server'] . ':' . $settings['imap_port'] . '/imap/ssl}';
|
||||
|
||||
// log_to_file("validate_imap_connection - Trying to open stream for {$email} : {$password} @ {$imap_server}");
|
||||
// Try connecting to the IMAP server
|
||||
$imap_stream = @imap_open(
|
||||
'{' . $settings['imap_server'] . ':' . $settings['imap_port'] . '/imap/ssl}',
|
||||
$imap_server,
|
||||
$email,
|
||||
$password
|
||||
);
|
||||
|
||||
if ($imap_stream) {
|
||||
// log_to_file("validate_imap_connection - Stream opened. Closing!");
|
||||
imap_close($imap_stream); // Close connection if successful
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// log_to_file("validate_imap_connection - Unable to open stream");
|
||||
|
||||
return false; // Connection failed
|
||||
}
|
||||
|
||||
|
|
@ -262,21 +270,21 @@ class RL_MailWarmer_Email_Helper
|
|||
* @param array $settings The server settings (smtp_server, smtp_port, smtp_password).
|
||||
* @return bool True if the connection is successful, false otherwise.
|
||||
*/
|
||||
private static function validate_smtp_connection($email, $settings)
|
||||
public static function validate_smtp_connection($settings, $send_test_email = false)
|
||||
{
|
||||
if (empty($settings['smtp_server']) || empty($settings['smtp_port']) ) {
|
||||
|
||||
if ( empty($settings['email_address']) || empty($settings['mail_password']) || empty($settings['smtp_server']) || empty($settings['smtp_port']) ) {
|
||||
// log_to_file("validate_smtp_connection - Incomplete connection information");
|
||||
return false; // Missing required settings
|
||||
}
|
||||
$email = $settings['email_address'];
|
||||
$password = $settings['mail_password'];
|
||||
// log_to_file("validate_smtp_connection - Settings for {$email}: ", $settings);
|
||||
|
||||
if (!empty($settings['smtp_password'])) {
|
||||
$password = $settings['smtp_password'];
|
||||
} else {
|
||||
$password = $settings['mail_password'];
|
||||
}
|
||||
|
||||
$signature = str_replace('\n', PHP_EOL, $settings['email_signature']);
|
||||
$test_to_email = "ruben@redlotusaustin.com";
|
||||
$email_body = "This is a test email to verify SMTP connection for {$email}\n\n{$signature}";
|
||||
$email_body = "<p>This is a test email to verify SMTP connection for {$email}\n\n{$signature}</p><br /><br /><span style='font-size:0.5rem;'>MFTID-0000000000000000</span>";
|
||||
|
||||
try {
|
||||
// Create the SMTP transport
|
||||
|
|
@ -298,8 +306,10 @@ class RL_MailWarmer_Email_Helper
|
|||
->to($test_to_email)
|
||||
->subject('SMTP Connection Test for ' . $email)
|
||||
->html($email_body);
|
||||
|
||||
$mailer->send($test_email);
|
||||
|
||||
if ($send_test_email) {
|
||||
$mailer->send($test_email);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
|
|
@ -374,7 +384,7 @@ class RL_MailWarmer_Email_Helper
|
|||
'email_provider' => $mailferno_default_email_provider,
|
||||
],
|
||||
]);
|
||||
log_to_file("generate_random_accounts - Added email account to local server: $post_id");
|
||||
// log_to_file("generate_random_accounts - Added email account to local server: $post_id");
|
||||
|
||||
if ($post_id && !is_wp_error($post_id)) {
|
||||
$generated_accounts[] = [
|
||||
|
|
@ -383,16 +393,16 @@ class RL_MailWarmer_Email_Helper
|
|||
'password' => $random_password,
|
||||
'post_id' => $post_id,
|
||||
];
|
||||
log_to_file("generate_random_accounts - {$first_name} {$last_name}\t{$email_address}\t{$random_password}");
|
||||
// log_to_file("generate_random_accounts - {$first_name} {$last_name}\t{$email_address}\t{$random_password}");
|
||||
$add_account_result = self::modify_email_account_on_server($post_id, 'create');
|
||||
log_to_file("generate_random_accounts - Result of attempting to add account to remote server: ", $add_account_result);
|
||||
// log_to_file("generate_random_accounts - Result of attempting to add account to remote server: ", $add_account_result);
|
||||
|
||||
if ( isset($add_account_result['errors']) ) {
|
||||
log_to_file("generate_random_accounts - Error modifying account on remote server: ", $add_account_result['errors']);
|
||||
// log_to_file("generate_random_accounts - Error modifying account on remote server: ", $add_account_result['errors']);
|
||||
} else {
|
||||
log_to_file("generate_random_accounts - Added $email_address to remote server: ", $add_account_result);
|
||||
// log_to_file("generate_random_accounts - Added $email_address to remote server: ", $add_account_result);
|
||||
$login_test_results = self::check_mail_login($post_id);
|
||||
log_to_file("generate_random_accounts - Login test results: ", $login_test_results);
|
||||
// log_to_file("generate_random_accounts - Login test results: ", $login_test_results);
|
||||
}
|
||||
} else {
|
||||
error_log('Failed to create email-account post: ' . print_r($post_id, true));
|
||||
|
|
@ -537,7 +547,7 @@ class RL_MailWarmer_Email_Helper
|
|||
} else {
|
||||
return new WP_Error('invalid_action', __('Invalid action specified.', 'rl-mailwarmer'));
|
||||
}
|
||||
log_to_file("modify_email_account_on_server - SSH Command: ", $command);
|
||||
// log_to_file("modify_email_account_on_server - SSH Command: ", $command);
|
||||
|
||||
// Execute the command via SSH
|
||||
// $ssh = new phpseclib\Net\SSH2($server_ip);
|
||||
|
|
@ -550,7 +560,7 @@ class RL_MailWarmer_Email_Helper
|
|||
} else {
|
||||
// Fallback to password-based authentication
|
||||
// $key = $server_password;
|
||||
log_to_file("modify_email_account_on_server - Server $$server_id ssh_private_key empty");
|
||||
// log_to_file("modify_email_account_on_server - Server $$server_id ssh_private_key empty");
|
||||
return new WP_Error('ssh_login_failed', __('No private key found!', 'rl-mailwarmer'));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,13 @@
|
|||
*/
|
||||
|
||||
use Symfony\Component\Mime\Email;
|
||||
use Symfony\Component\Mime\Address;
|
||||
use Symfony\Component\Mailer\Mailer;
|
||||
use Symfony\Component\Mailer\Transport\Transport;
|
||||
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
|
||||
use PhpImap\Mailbox;
|
||||
use phpseclib3\Net\SSH2;
|
||||
use phpseclib3\Crypt\PublicKeyLoader;
|
||||
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
|
|
@ -23,47 +26,176 @@ class RL_MailWarmer_Message_Handler {
|
|||
public static function process_pending_messages() {
|
||||
// log_to_file("process_pending_messages - Running");
|
||||
global $wpdb;
|
||||
$results = [
|
||||
'success' => 0,
|
||||
'failure' => 0,
|
||||
];
|
||||
|
||||
// Fetch the next 100 pending messages with scheduled timestamps in the past
|
||||
$table_name = $wpdb->prefix . 'rl_mailwarmer_messages';
|
||||
$messages = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM $table_name WHERE status = %s AND scheduled_for_timestamp < %s ORDER BY scheduled_for_timestamp ASC LIMIT 1",
|
||||
'pending',
|
||||
"SELECT * FROM $table_name WHERE status = %s AND scheduled_for_timestamp < %s ORDER BY scheduled_for_timestamp ASC LIMIT 10",
|
||||
'scheduled',
|
||||
current_time('mysql')
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
|
||||
if (empty($messages)) {
|
||||
// log_to_file("process_pending_messages - messages empty");
|
||||
return;
|
||||
}
|
||||
// if (empty($messages)) {
|
||||
// // log_to_file("process_pending_messages - messages empty");
|
||||
// return;
|
||||
// }
|
||||
|
||||
foreach ($messages as $message) {
|
||||
// log_to_file("==========================================================");
|
||||
try {
|
||||
if (!empty($message['first_message']) && $message['first_message']) {
|
||||
// log_to_file("process_pending_messages - trying send_message");
|
||||
$messages_count = count($messages);
|
||||
if ($messages_count > 0) {
|
||||
action_log("process_pending_messages - Processing {$messages_count} messages" );
|
||||
|
||||
foreach ($messages as $message) {
|
||||
log_to_file("==========================================================");
|
||||
try {
|
||||
// if (!empty($message['first_message']) && $message['first_message']) {
|
||||
// log_to_file("process_pending_messages - trying send_message");
|
||||
// $result = self::send_message($message);
|
||||
// } else {
|
||||
// log_to_file("process_pending_messages - trying reply_message");
|
||||
// $result = self::reply_message($message);
|
||||
// }
|
||||
log_to_file("process_pending_messages - trying send_message for {$message['id']} from {$message['from_email']} to ", $message['to_email']);
|
||||
$result = self::send_message($message);
|
||||
} else {
|
||||
// log_to_file("process_pending_messages - trying reply_message");
|
||||
$result = self::reply_message($message);
|
||||
}
|
||||
|
||||
// Update message status to 'completed' on success
|
||||
if ($result) {
|
||||
self::update_message_status($message['id'], 'completed');
|
||||
} else {
|
||||
// Update message status to 'sent' on success
|
||||
if ($result) {
|
||||
self::update_message_status($message['id'], 'sent');
|
||||
$results['success']++;
|
||||
log_to_file("process_pending_messages - Success sending message: {$message['id']}");
|
||||
action_log("process_pending_messages - Sent email {$message['id']} from {$message['from_email']} to ", $message['to_email']);
|
||||
} else {
|
||||
self::update_message_status($message['id'], 'failed');
|
||||
log_to_file("process_pending_messages - Error sending message: {$message['id']}");
|
||||
$results['failure']++;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Handle errors gracefully and log them
|
||||
log_to_file('process_pending_messages - Error processing message ID ' . $message['id'] . ': ' . $e->getMessage());
|
||||
self::update_message_status($message['id'], 'failed');
|
||||
$results['failure']++;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Handle errors gracefully and log them
|
||||
log_to_file('Error processing message ID ' . $message['id'] . ': ' . $e->getMessage());
|
||||
self::update_message_status($message['id'], 'failed');
|
||||
// sleep(3);
|
||||
}
|
||||
sleep(3);
|
||||
log_to_file("process_pending_messages - Results: ", $results);
|
||||
action_log("process_pending_messages - Finished processing {$messages_count} messages with {$results['success']} sent and {$results['failure']} failures");
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the first message in a conversation.
|
||||
*
|
||||
* @param array $message The message details.
|
||||
* @return bool True if the message is sent successfully, false otherwise.
|
||||
* @throws Exception If required fields are missing or an error occurs during sending.
|
||||
*/
|
||||
public static function send_message($message) {
|
||||
// log_to_file("send_message - Running");
|
||||
// log_to_file("send_message - Message: ", $message);
|
||||
|
||||
// Prepare email data and connection info
|
||||
$email_data = self::prepare_email_data($message);
|
||||
|
||||
// log_to_file("send_message - Email Data: ", $email_data);
|
||||
|
||||
// Extract connection info
|
||||
$connection_info = $email_data['connection_info'];
|
||||
if (!empty($connection_info['smtp_password'])) {
|
||||
$password = $connection_info['smtp_password'];
|
||||
} else {
|
||||
$password = $connection_info['mail_password'];
|
||||
}
|
||||
|
||||
// Check required fields
|
||||
if (empty($email_data['to']) || empty($email_data['from']) || empty($email_data['subject']) || empty($email_data['text_body'])) {
|
||||
|
||||
// log_to_file("send_message - Missing required fields for sending the email");
|
||||
throw new Exception(__('Missing required fields for sending the email.', 'rl-mailwarmer'));
|
||||
}
|
||||
|
||||
// Create the SMTP transport
|
||||
try {
|
||||
// log_to_file("send_message - Creating Transport");
|
||||
// Create the SMTP transport
|
||||
$transport = new Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport(
|
||||
$connection_info['smtp_server'],
|
||||
$connection_info['smtp_port']
|
||||
);
|
||||
|
||||
// Set authentication details
|
||||
$transport->setUsername($email_data['from']);
|
||||
$transport->setPassword($password);
|
||||
|
||||
$to_addresses = $email_data['to'];
|
||||
if (!is_array($to_addresses)) {
|
||||
$to_addresses = json_decode($to_addresses, true);
|
||||
}
|
||||
$to_addresses_type = gettype($to_addresses);
|
||||
// log_to_file("send_message - To ({$to_addresses_type}): ", $to_addresses);
|
||||
|
||||
// Create the mailer
|
||||
$mailer = new Symfony\Component\Mailer\Mailer($transport);
|
||||
|
||||
// Send an email
|
||||
|
||||
$email_message = (new Symfony\Component\Mime\Email())
|
||||
->from(new Address($email_data['from'], $email_data['name']))
|
||||
->to(...$to_addresses)
|
||||
->subject($email_data['subject'])
|
||||
->text($email_data['text_body'])
|
||||
->html($email_data['html_body']);
|
||||
|
||||
// Add headers
|
||||
$campaign_tracking_id = $email_data['campaign_tracking_id'];
|
||||
// $previous_message_id = $message['previous_message_id'];
|
||||
// if ($previous_message_id) {
|
||||
// $campaign_tracking_id .= '-' . $previous_message_id;
|
||||
// }
|
||||
$email_message->getHeaders()->addTextHeader('X-MFTID', $campaign_tracking_id);
|
||||
// log_to_file("send_message - Creating email with MFTID: {$campaign_tracking_id}");
|
||||
|
||||
// log_to_file("send_message - Trying to send email.");
|
||||
$smtp_result = $mailer->send($email_message);
|
||||
|
||||
// log_to_file("send_message - Message sent!", $smtp_result);
|
||||
return true;
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
log_to_file("send_message - Error sending email {$message['id']}: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function search_email_by_x_mftid($imap_stream, $imap_server, $campaign_tracking_id) {
|
||||
$folders = imap_list($imap_stream, $imap_server, '*');
|
||||
$result = ['folder' => null, 'email' => null];
|
||||
|
||||
$search_term = '/X\-MFTID: ' . preg_quote($campaign_tracking_id, '/') . '.+/i';
|
||||
log_to_file("search_email_by_x_mftid - search term: {$search_term}");
|
||||
|
||||
foreach ($folders as $folder) {
|
||||
$decoded_folder = imap_utf7_decode($folder);
|
||||
// log_to_file("search_email_by_x_mftid - decoded_folder: ", $decoded_folder);
|
||||
|
||||
$status = imap_status($imap_stream, $decoded_folder, SA_MESSAGES);
|
||||
if ($status->messages > 0) {
|
||||
log_to_file("search_email_by_x_mftid - Searching {$decoded_folder}");
|
||||
$emails = imap_search($imap_stream, 'TEXT "' . $campaign_tracking_id . '"', SE_UID);
|
||||
if ($emails) {
|
||||
$result['folder'] = $decoded_folder;
|
||||
$result['email'] = $emails;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -90,6 +222,7 @@ class RL_MailWarmer_Message_Handler {
|
|||
|
||||
// Fetch connection details
|
||||
// log_to_file("prepare_email_data - Getting connection info");
|
||||
$full_name = get_post_meta($from_post_id, 'full_name', true);
|
||||
$mail_password = get_post_meta($from_post_id, 'mail_password', true);
|
||||
$email_provider_id = get_post_meta($from_post_id, 'email_provider', true);
|
||||
$connection_info = RL_MailWarmer_Email_Helper::get_provider_defaults($email_provider_id);
|
||||
|
|
@ -107,16 +240,27 @@ class RL_MailWarmer_Message_Handler {
|
|||
|
||||
// Handle recipients
|
||||
// log_to_file("prepare_email_data - Handling recipients");
|
||||
$to_emails = is_array($message['to_email']) ? $message['to_email'] : explode(',', $message['to_email']);
|
||||
$cc_emails = is_array($message['cc']) ? $message['cc'] : explode(',', $message['cc']);
|
||||
// $to_emails = json_decode();
|
||||
$to_emails = is_array($message['to_email']) ? $message['to_email'] : json_decode($message['to_email']);
|
||||
$cc_emails = is_array($message['cc']) ? $message['cc'] : json_decode($message['cc']);
|
||||
|
||||
$campaign_tracking_id = $message['campaign_tracking_id'] . '-' . $message['id'];
|
||||
$previous_message_id = $message['previous_message_id'];
|
||||
$text_body = $message['body'] . "\n\n" . $campaign_tracking_id;
|
||||
$html_body = $message['body'] . "<br /><br /><span style='font-size:0.5rem;'>{$campaign_tracking_id}</span>";
|
||||
|
||||
return [
|
||||
'id' => $message['id'],
|
||||
'connection_info' => $connection_info,
|
||||
'to' => array_filter(array_map('trim', $to_emails)),
|
||||
'cc' => array_filter(array_map('trim', $cc_emails)),
|
||||
'to' => array_filter(array_map('trim', array_map('stripslashes', $to_emails))),
|
||||
'cc' => array_filter(array_map('trim', array_map('stripslashes', $cc_emails))),
|
||||
'subject' => $message['subject'],
|
||||
'body' => $message['body'],
|
||||
'text_body' => $text_body,
|
||||
'html_body' => $html_body,
|
||||
'from' => $message['from_email'],
|
||||
'name' => $full_name,
|
||||
'campaign_tracking_id' => $campaign_tracking_id,
|
||||
'previous_message_id' => $previous_message_id,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -163,351 +307,228 @@ class RL_MailWarmer_Message_Handler {
|
|||
);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Reply to an email message.
|
||||
// *
|
||||
// * @param array $message The message details.
|
||||
// * @return bool True if the message is replied to successfully, false otherwise.
|
||||
// * @throws Exception If required fields are missing or an error occurs.
|
||||
// */
|
||||
// public static function reply_message($message) {
|
||||
// // Prepare email data and connection info
|
||||
// $email_data = self::prepare_email_data($message);
|
||||
// log_to_file("reply_message - Email Data: ", $email_data);
|
||||
|
||||
// // Validate required fields
|
||||
// if (empty($email_data['to']) || empty($email_data['from']) || empty($email_data['subject']) || empty($email_data['text_body'])) {
|
||||
// throw new Exception(__('Missing required fields for replying to the email.', 'rl-mailwarmer'));
|
||||
// }
|
||||
|
||||
// // Extract connection info
|
||||
// $connection_info = $email_data['connection_info'];
|
||||
// $emails = '';
|
||||
|
||||
|
||||
/**
|
||||
* Send the first message in a conversation.
|
||||
*
|
||||
* @param array $message The message details.
|
||||
* @return bool True if the message is sent successfully, false otherwise.
|
||||
* @throws Exception If required fields are missing or an error occurs during sending.
|
||||
*/
|
||||
public static function send_message($message) {
|
||||
// log_to_file("send_message - Running");
|
||||
// log_to_file("send_message - Message: ", $message);
|
||||
// try {
|
||||
// // log_to_file("reply_message - Trying to reply via IMAP {$connection_info['imap_server']}:{$connection_info['imap_port']}");
|
||||
// // $imap = new \PhpImap\Mailbox(
|
||||
// // sprintf('{%s:%s/imap/ssl}', $connection_info['imap_server'], $connection_info['imap_port']),
|
||||
// // $connection_info['username'],
|
||||
// // $connection_info['mail_password'],
|
||||
// // null,
|
||||
// // 'UTF-8'
|
||||
// // );
|
||||
|
||||
// Prepare email data and connection info
|
||||
$email_data = self::prepare_email_data($message);
|
||||
// // $imap->checkMailbox();
|
||||
|
||||
// log_to_file("send_message - Email Data: ", $email_data);
|
||||
|
||||
// Extract connection info
|
||||
$connection_info = $email_data['connection_info'];
|
||||
|
||||
// Check required fields
|
||||
if (empty($email_data['to']) || empty($email_data['from']) || empty($email_data['subject']) || empty($email_data['body'])) {
|
||||
throw new Exception(__('Missing required fields for sending the email.', 'rl-mailwarmer'));
|
||||
}
|
||||
|
||||
// Create the SMTP transport
|
||||
// log_to_file("send_message - Creating Transport");
|
||||
$transport = new Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport(
|
||||
$connection_info['smtp_server'],
|
||||
$connection_info['smtp_port']
|
||||
);
|
||||
|
||||
// Set authentication details
|
||||
$transport->setUsername($connection_info['username']);
|
||||
$transport->setPassword($connection_info['mail_password']);
|
||||
|
||||
// Create the mailer
|
||||
$mailer = new Symfony\Component\Mailer\Mailer($transport);
|
||||
|
||||
// Build the email
|
||||
// log_to_file("send_message - Building Mail");
|
||||
$email = (new Email())
|
||||
->from($email_data['from'])
|
||||
->to(...$email_data['to'])
|
||||
->subject($email_data['subject'])
|
||||
->html($email_data['body']);
|
||||
|
||||
// Add CCs if present
|
||||
if (!empty($email_data['cc'])) {
|
||||
$email->cc(...$email_data['cc']);
|
||||
}
|
||||
|
||||
// Attempt to send the email
|
||||
// log_to_file("send_message - Trying to send");
|
||||
try {
|
||||
$mailer->send($email);
|
||||
log_to_file("send_message - Successfully sent SMTP mail from ", $email_data['from']);
|
||||
return true; // Email sent successfully
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
error_log('Error sending email: ' . $e->getMessage());
|
||||
return false; // Sending failed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reply to an email message.
|
||||
*
|
||||
* @param array $message The message details.
|
||||
* @return bool True if the message is replied to successfully, false otherwise.
|
||||
* @throws Exception If required fields are missing or an error occurs.
|
||||
*/
|
||||
public static function reply_message($message) {
|
||||
// Prepare email data and connection info
|
||||
$email_data = self::prepare_email_data($message);
|
||||
// log_to_file("reply_message - Email Data: ", $email_data);
|
||||
|
||||
// Extract connection info
|
||||
$connection_info = $email_data['connection_info'];
|
||||
|
||||
// Validate required fields
|
||||
if (empty($email_data['to']) || empty($email_data['from']) || empty($email_data['subject']) || empty($email_data['body'])) {
|
||||
throw new Exception(__('Missing required fields for replying to the email.', 'rl-mailwarmer'));
|
||||
}
|
||||
|
||||
// Attempt to find the original email via IMAP
|
||||
// // // Search for the email with the matching subject
|
||||
// // log_to_file("reply_message - Searching for message with X-MFTID");
|
||||
// // $emails = $imap->searchMailbox('HEADER X-MFTID "' . addslashes($email_data['campaign_tracking_id']) . '"');
|
||||
|
||||
|
||||
|
||||
// // Attempt to find the original email and reply via IMAP
|
||||
// try {
|
||||
// $imap = new \PhpImap\Mailbox(
|
||||
// sprintf('{%s:%d/imap/ssl}', $connection_info['imap_server'], $connection_info['imap_port']),
|
||||
// $connection_info['imap_username'],
|
||||
// $connection_info['imap_password'],
|
||||
// null,
|
||||
// 'UTF-8'
|
||||
// );
|
||||
// $password = $connection_info['mail_password'];
|
||||
// $email = $connection_info['username'];
|
||||
|
||||
// log_to_file("reply_message - Trying to reply via IMAP for {$email} using: ", $connection_info);
|
||||
|
||||
// // Search for the email with the matching subject
|
||||
// $emails = $imap->searchMailbox('SUBJECT "' . addslashes($email_data['subject']) . '"');
|
||||
// if (!empty($emails)) {
|
||||
// // Fetch the email data
|
||||
// $original_email = $imap->getMail($emails[0]);
|
||||
// $imap_server = '{' . $connection_info['imap_server'] . ':' . $connection_info['imap_port'] . '/imap/ssl}';
|
||||
|
||||
// // Prepare and send the reply via IMAP
|
||||
// $imap->reply(
|
||||
// $emails[0],
|
||||
// $email_data['body'],
|
||||
// ['from' => $email_data['from'], 'cc' => $email_data['cc']]
|
||||
// );
|
||||
// log_to_file("reply_message - Trying to open stream for {$email} : {$password} @ {$imap_server}");
|
||||
// // Try connecting to the IMAP server
|
||||
// $imap_stream = @imap_open(
|
||||
// $imap_server,
|
||||
// $email,
|
||||
// $password
|
||||
// );
|
||||
|
||||
// return true; // Reply sent successfully via IMAP
|
||||
// }
|
||||
// if ($imap_stream) {
|
||||
// log_to_file("reply_message - IMAP stream opened.");
|
||||
// $imap_search_result = self::search_email_by_x_mftid($imap_stream, $imap_server, $email_data['campaign_tracking_id']);
|
||||
// if ($imap_search_result['folder']) {
|
||||
// log_to_file("reply_message - Email with X-MFTID found in folder: {$imap_search_result['folder']}");
|
||||
// log_to_file("reply_message - Email: ", $imap_search_result['email']);
|
||||
// // $emails = $imap_search_result['email'];
|
||||
// // Continue with reply logic
|
||||
// } else {
|
||||
// log_to_file("No email found with X-MFTID: " . $email_data['campaign_tracking_id']);
|
||||
// }
|
||||
// imap_close($imap_stream);
|
||||
// }
|
||||
|
||||
|
||||
// if (!empty($emails)) {
|
||||
|
||||
|
||||
try {
|
||||
// log_to_file("reply_message - Trying to reply via IMAP");
|
||||
$imap = new \PhpImap\Mailbox(
|
||||
sprintf('{%s:%d/imap/ssl}', $connection_info['imap_server'], $connection_info['imap_port']),
|
||||
$connection_info['username'],
|
||||
$connection_info['mail_password'],
|
||||
null,
|
||||
'UTF-8'
|
||||
);
|
||||
// // Fetch the email data
|
||||
// $original_email = $imap->getMail($emails[0]);
|
||||
// log_to_file("reply_message - Message found!");
|
||||
// // log_to_file("reply_message - IMAP Message: ", $original_email);
|
||||
|
||||
// Search for the email with the matching subject
|
||||
// log_to_file("reply_message - Searching for message");
|
||||
$emails = $imap->searchMailbox('SUBJECT "' . addslashes($email_data['subject']) . '"');
|
||||
if (!empty($emails)) {
|
||||
// // Step 2: Send the reply via SMTP
|
||||
// $transport = new Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport(
|
||||
// $connection_info['smtp_server'],
|
||||
// $connection_info['smtp_port']
|
||||
// );
|
||||
|
||||
// // Set authentication details
|
||||
// $transport->setUsername($connection_info['username']);
|
||||
// $transport->setPassword($connection_info['mail_password']);
|
||||
// $to_addresses = $email_data['to'];
|
||||
// if (!is_array($to_addresses)) {
|
||||
// $to_addresses = json_decode($to_addresses, true);
|
||||
// }
|
||||
|
||||
// $mailer = new Mailer($transport);
|
||||
|
||||
// $reply_email = (new Email())
|
||||
// ->from(new Address($email_data['from'], $email_data['name']))
|
||||
// ->to(...$to_addresses)
|
||||
// ->subject('Re: ' . $original_email->subject)
|
||||
// ->text($email_data['text_body'])
|
||||
// ->html($email_data['html_body']);
|
||||
|
||||
// // Add headers
|
||||
// $campaign_tracking_id = $email_data['campaign_tracking_id'];
|
||||
// $reply_email->getHeaders()->addTextHeader('X-MFTID', $campaign_tracking_id);
|
||||
|
||||
// // Add headers for threading
|
||||
// $headers = $reply_email->getHeaders();
|
||||
// $headers->addTextHeader('In-Reply-To', $original_email->messageId);
|
||||
// $headers->addTextHeader('References', trim($original_email->headers->references . ' ' . $original_email->messageId));
|
||||
|
||||
// // ->addHeader('In-Reply-To', $original_email->messageId)
|
||||
// // ->addHeader('References', trim($original_email->headers->references . ' ' . $original_email->messageId));
|
||||
|
||||
// // if (!empty($email_data['cc'])) {
|
||||
// // $reply_email->cc(...$email_data['cc']);
|
||||
// // }
|
||||
|
||||
// $mailer->send($reply_email);
|
||||
|
||||
// log_to_file("reply_message - Successfully sent IMAP/SMTP reply from ", $email_data['from']);
|
||||
|
||||
// // Step 3: Upload the reply to the Sent folder
|
||||
// $imap_stream = imap_open(
|
||||
// sprintf('{%s:%d/imap/ssl}', $connection_info['imap_server'], $connection_info['imap_port']),
|
||||
// $connection_info['username'],
|
||||
// $connection_info['mail_password']
|
||||
// );
|
||||
|
||||
// $raw_message = $reply_email->toString(); // Convert the Email object to raw MIME format
|
||||
// imap_append($imap_stream, sprintf('{%s}/Sent', $connection_info['imap_server']), $raw_message);
|
||||
|
||||
// imap_close($imap_stream);
|
||||
|
||||
// // Create the reply headers
|
||||
// // $reply_headers = [
|
||||
// // 'In-Reply-To' => $original_email->messageId,
|
||||
// // 'References' => trim($original_email->headers->references . ' ' . $original_email->messageId),
|
||||
// // ];
|
||||
|
||||
// // // Construct the reply body
|
||||
// // $reply_body = $email_data['body'] . "\n\n" .
|
||||
// // 'On ' . $original_email->date . ', ' . $original_email->fromName . ' <' . $original_email->fromAddress . '> wrote:' . "\n" .
|
||||
// // $original_email->textPlain;
|
||||
|
||||
// // // Send the reply via IMAP
|
||||
// // log_to_file("reply_message - Sending message via IMAP");
|
||||
// // $imap->addMessageToSentFolder(
|
||||
// // 'To: ' . implode(', ', $email_data['to']) . "\r\n" .
|
||||
// // 'Cc: ' . implode(', ', $email_data['cc']) . "\r\n" .
|
||||
// // 'Subject: Re: ' . $original_email->subject . "\r\n" .
|
||||
// // 'From: ' . $email_data['from'] . "\r\n" .
|
||||
// // 'In-Reply-To: ' . $reply_headers['In-Reply-To'] . "\r\n" .
|
||||
// // 'References: ' . $reply_headers['References'] . "\r\n" .
|
||||
// // "\r\n" .
|
||||
// // $reply_body
|
||||
// // );
|
||||
// // log_to_file("reply_message - Done message via IMAP");
|
||||
|
||||
// // $mailer = new Mailer($transport);
|
||||
// // $mailer->send($reply);
|
||||
|
||||
// return true; // Reply sent successfully
|
||||
// } else {
|
||||
// log_to_file("reply_message - Unable to reply via IMAP. Falling back to SMTP");
|
||||
// }
|
||||
// } catch (Exception $e) {
|
||||
// log_to_file('reply_message - IMAP Error: ' . $e->getMessage());
|
||||
// }
|
||||
|
||||
// // Fallback to SMTP if IMAP fails
|
||||
// try {
|
||||
// log_to_file("reply_message - Falling back to SMTP");
|
||||
|
||||
// $result = self::send_message($message);
|
||||
// return $result;
|
||||
// // $to_addresses = $email_data['to'];
|
||||
// // if (!is_array($to_addresses)) {
|
||||
// // $to_addresses = json_decode($to_addresses, true);
|
||||
// // }
|
||||
// // log_to_file("reply_message - Creating SMTP message");
|
||||
|
||||
// // $smtp_reply = (new Email())
|
||||
// // ->from(new Address($email_data['from'], $email_data['name']))
|
||||
// // ->to(...$to_addresses)
|
||||
// // ->subject($email_data['subject'])
|
||||
// // ->text($email_data['text_body'])
|
||||
// // ->html($email_data['html_body']);
|
||||
|
||||
// // // Add headers
|
||||
// // $campaign_tracking_id = $email_data['campaign_tracking_id'];
|
||||
// // $smtp_reply->getHeaders()->addTextHeader('X-MFTID', $campaign_tracking_id);
|
||||
|
||||
// // // Add CCs if present
|
||||
// // // if (!empty($email_data['cc'])) {
|
||||
// // // $smtp_reply->cc(...$email_data['cc']);
|
||||
// // // }
|
||||
|
||||
// // // Create the SMTP transport
|
||||
// // log_to_file("reply_message - Creating SMTP transport");
|
||||
|
||||
// // $transport = new Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport(
|
||||
// // $connection_info['smtp_server'],
|
||||
// // $connection_info['smtp_port']
|
||||
// // );
|
||||
|
||||
// // // Set authentication details
|
||||
// // $transport->setUsername($connection_info['username']);
|
||||
// // $transport->setPassword($connection_info['mail_password']);
|
||||
|
||||
// // // Create the mailer
|
||||
// // log_to_file("reply_message - Creating SMTP mailer");
|
||||
// // $mailer = new Symfony\Component\Mailer\Mailer($transport);
|
||||
// // $smtp_result = $mailer->send($smtp_reply);
|
||||
// // log_to_file("reply_message - Sent reply via fallback SMTP from {$email_data['from']}:", $smtp_result);
|
||||
// // // log_to_file('reply_message - SMTP Send Success (?)');
|
||||
|
||||
// // Fallback SMTP reply sent successfully
|
||||
// } catch (Exception $e) {
|
||||
// log_to_file('reply_message - SMTP Error: ' . $e->getMessage());
|
||||
// return false; // Reply failed
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// Fetch the email data
|
||||
$original_email = $imap->getMail($emails[0]);
|
||||
// log_to_file("reply_message - Message found!");
|
||||
// log_to_file("reply_message - IMAP Message: ", $original_email);
|
||||
|
||||
// Step 2: Send the reply via SMTP
|
||||
$transport = new Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport(
|
||||
$connection_info['smtp_server'],
|
||||
$connection_info['smtp_port']
|
||||
);
|
||||
|
||||
// Set authentication details
|
||||
$transport->setUsername($connection_info['username']);
|
||||
$transport->setPassword($connection_info['mail_password']);
|
||||
|
||||
$mailer = new Mailer($transport);
|
||||
|
||||
$reply_email = (new Email())
|
||||
->from($email_data['from'])
|
||||
->to(...$email_data['to'])
|
||||
->subject('Re: ' . $original_email->subject)
|
||||
->html($email_data['body']);
|
||||
|
||||
// Add headers for threading
|
||||
$headers = $reply_email->getHeaders();
|
||||
$headers->addTextHeader('In-Reply-To', $original_email->messageId);
|
||||
$headers->addTextHeader('References', trim($original_email->headers->references . ' ' . $original_email->messageId));
|
||||
|
||||
// ->addHeader('In-Reply-To', $original_email->messageId)
|
||||
// ->addHeader('References', trim($original_email->headers->references . ' ' . $original_email->messageId));
|
||||
|
||||
if (!empty($email_data['cc'])) {
|
||||
$reply_email->cc(...$email_data['cc']);
|
||||
}
|
||||
|
||||
$mailer->send($reply_email);
|
||||
|
||||
log_to_file("reply_message - Successfully sent IMAP/SMTP reply from ", $email_data['from']);
|
||||
|
||||
// Step 3: Upload the reply to the Sent folder
|
||||
$imap_stream = imap_open(
|
||||
sprintf('{%s:%d/imap/ssl}', $connection_info['imap_server'], $connection_info['imap_port']),
|
||||
$connection_info['username'],
|
||||
$connection_info['mail_password']
|
||||
);
|
||||
|
||||
$raw_message = $reply_email->toString(); // Convert the Email object to raw MIME format
|
||||
imap_append($imap_stream, sprintf('{%s}/Sent', $connection_info['imap_server']), $raw_message);
|
||||
|
||||
imap_close($imap_stream);
|
||||
|
||||
// Create the reply headers
|
||||
// $reply_headers = [
|
||||
// 'In-Reply-To' => $original_email->messageId,
|
||||
// 'References' => trim($original_email->headers->references . ' ' . $original_email->messageId),
|
||||
// ];
|
||||
|
||||
// // Construct the reply body
|
||||
// $reply_body = $email_data['body'] . "\n\n" .
|
||||
// 'On ' . $original_email->date . ', ' . $original_email->fromName . ' <' . $original_email->fromAddress . '> wrote:' . "\n" .
|
||||
// $original_email->textPlain;
|
||||
|
||||
// // Send the reply via IMAP
|
||||
// log_to_file("reply_message - Sending message via IMAP");
|
||||
// $imap->addMessageToSentFolder(
|
||||
// 'To: ' . implode(', ', $email_data['to']) . "\r\n" .
|
||||
// 'Cc: ' . implode(', ', $email_data['cc']) . "\r\n" .
|
||||
// 'Subject: Re: ' . $original_email->subject . "\r\n" .
|
||||
// 'From: ' . $email_data['from'] . "\r\n" .
|
||||
// 'In-Reply-To: ' . $reply_headers['In-Reply-To'] . "\r\n" .
|
||||
// 'References: ' . $reply_headers['References'] . "\r\n" .
|
||||
// "\r\n" .
|
||||
// $reply_body
|
||||
// );
|
||||
// log_to_file("reply_message - Done message via IMAP");
|
||||
|
||||
// $mailer = new Mailer($transport);
|
||||
// $mailer->send($reply);
|
||||
|
||||
return true; // Reply sent successfully
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
log_to_file('IMAP Error: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// Fallback to SMTP if IMAP fails
|
||||
try {
|
||||
// log_to_file("reply_message - Falling back to SMTP");
|
||||
$smtp_reply = (new Email())
|
||||
->from($email_data['from'])
|
||||
->to(...$email_data['to'])
|
||||
->subject($email_data['subject'])
|
||||
->html($email_data['body']);
|
||||
|
||||
// Add CCs if present
|
||||
if (!empty($email_data['cc'])) {
|
||||
$smtp_reply->cc(...$email_data['cc']);
|
||||
}
|
||||
|
||||
// Create the SMTP transport
|
||||
$transport = new Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport(
|
||||
$connection_info['smtp_server'],
|
||||
$connection_info['smtp_port']
|
||||
);
|
||||
|
||||
// Set authentication details
|
||||
$transport->setUsername($connection_info['username']);
|
||||
$transport->setPassword($connection_info['mail_password']);
|
||||
|
||||
// Create the mailer
|
||||
$mailer = new Symfony\Component\Mailer\Mailer($transport);
|
||||
$mailer->send($smtp_reply);
|
||||
log_to_file("reply_message - Sent reply via fallback SMTP from ", $email_data['from']);
|
||||
// log_to_file('reply_message - SMTP Send Success (?)');
|
||||
|
||||
return true; // Fallback SMTP reply sent successfully
|
||||
} catch (Exception $e) {
|
||||
log_to_file('reply_message - SMTP Error: ' . $e->getMessage());
|
||||
return false; // Reply failed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a metabox to the WP dashboard for monitoring and processing the message queue.
|
||||
*/
|
||||
add_action('wp_dashboard_setup', function () {
|
||||
wp_add_dashboard_widget(
|
||||
'rl_mailwarmer_message_queue',
|
||||
__('Message Queue', 'rl-mailwarmer'),
|
||||
'rl_mailwarmer_render_message_queue_widget'
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Render the Message Queue dashboard widget.
|
||||
*/
|
||||
function rl_mailwarmer_render_message_queue_widget() {
|
||||
global $wpdb;
|
||||
|
||||
// Count past-due messages
|
||||
$table_name = $wpdb->prefix . 'rl_mailwarmer_messages';
|
||||
$past_due_count = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM $table_name WHERE status = %s AND scheduled_for_timestamp < %s",
|
||||
'pending',
|
||||
current_time('mysql')
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
<div id="rl-mailwarmer-queue">
|
||||
<p><strong><?php esc_html_e('Past-Due Messages:', 'rl-mailwarmer'); ?></strong> <?php echo esc_html($past_due_count); ?></p>
|
||||
<button id="process-message-queue" class="button button-primary">
|
||||
<?php esc_html_e('Process Message Queue', 'rl-mailwarmer'); ?>
|
||||
</button>
|
||||
<div id="message-queue-result" style="margin-top: 10px;"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const button = document.getElementById('process-message-queue');
|
||||
const resultDiv = document.getElementById('message-queue-result');
|
||||
|
||||
button.addEventListener('click', function () {
|
||||
button.disabled = true;
|
||||
resultDiv.textContent = '<?php esc_html_e('Processing...', 'rl-mailwarmer'); ?>';
|
||||
|
||||
jQuery.post(ajaxurl, {
|
||||
action: 'rl_mailwarmer_process_message_queue',
|
||||
security: '<?php echo esc_js(wp_create_nonce('rl_mailwarmer_queue_nonce')); ?>'
|
||||
}, function (response) {
|
||||
button.disabled = false;
|
||||
|
||||
if (response.success) {
|
||||
console.log("Success");
|
||||
resultDiv.textContent = '<?php esc_html_e('Messages processed:', 'rl-mailwarmer'); ?> ' + response.data.processed_count;
|
||||
} else {
|
||||
console.log("Failure");
|
||||
resultDiv.textContent = '<?php esc_html_e('Error:', 'rl-mailwarmer'); ?> ' + response.data.message;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler to process the message queue.
|
||||
*/
|
||||
add_action('wp_ajax_rl_mailwarmer_process_message_queue', function () {
|
||||
// log_to_file("wp_ajax_rl_mailwarmer_process_message_queue - Running");
|
||||
// Verify nonce
|
||||
if (!check_ajax_referer('rl_mailwarmer_queue_nonce', 'security', false)) {
|
||||
wp_send_json_error(['message' => __('Invalid nonce.', 'rl-mailwarmer')]);
|
||||
}
|
||||
|
||||
// Ensure the user has permission
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error(['message' => __('Permission denied.', 'rl-mailwarmer')]);
|
||||
}
|
||||
|
||||
try {
|
||||
// Process pending messages
|
||||
// log_to_file("wp_ajax_rl_mailwarmer_process_message_queue - Trying process_pending_messages()");
|
||||
$processed_count = RL_MailWarmer_Message_Handler::process_pending_messages();
|
||||
|
||||
wp_send_json_success(['processed_count' => $processed_count]);
|
||||
} catch (Exception $e) {
|
||||
wp_send_json_error(['message' => $e->getMessage()]);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -153,3 +153,95 @@ add_action('wp_ajax_rl_delete_messages', function () {
|
|||
|
||||
wp_send_json_success(['message' => __('Messages deleted successfully.', 'rl-mailwarmer')]);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Add a metabox to the WP dashboard for monitoring and processing the message queue.
|
||||
*/
|
||||
add_action('wp_dashboard_setup', function () {
|
||||
wp_add_dashboard_widget(
|
||||
'rl_mailwarmer_message_queue',
|
||||
__('Message Queue', 'rl-mailwarmer'),
|
||||
'rl_mailwarmer_render_message_queue_widget'
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Render the Message Queue dashboard widget.
|
||||
*/
|
||||
function rl_mailwarmer_render_message_queue_widget() {
|
||||
global $wpdb;
|
||||
|
||||
// Count past-due messages
|
||||
$table_name = $wpdb->prefix . 'rl_mailwarmer_messages';
|
||||
$past_due_count = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM $table_name WHERE status = %s AND scheduled_for_timestamp < %s",
|
||||
'scheduled',
|
||||
current_time('mysql')
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
<div id="rl-mailwarmer-queue">
|
||||
<p><strong><?php esc_html_e('Past-Due Messages:', 'rl-mailwarmer'); ?></strong> <?php echo esc_html($past_due_count); ?></p>
|
||||
<button id="process-message-queue" class="button button-primary">
|
||||
<?php esc_html_e('Process Message Queue', 'rl-mailwarmer'); ?>
|
||||
</button>
|
||||
<div id="message-queue-result" style="margin-top: 10px;"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const button = document.getElementById('process-message-queue');
|
||||
const resultDiv = document.getElementById('message-queue-result');
|
||||
|
||||
button.addEventListener('click', function () {
|
||||
button.disabled = true;
|
||||
resultDiv.textContent = '<?php esc_html_e('Processing...', 'rl-mailwarmer'); ?>';
|
||||
|
||||
jQuery.post(ajaxurl, {
|
||||
action: 'rl_mailwarmer_process_message_queue',
|
||||
security: '<?php echo esc_js(wp_create_nonce('rl_mailwarmer_message_queue_nonce')); ?>'
|
||||
}, function (response) {
|
||||
button.disabled = false;
|
||||
|
||||
if (response.success) {
|
||||
console.log("Success");
|
||||
resultDiv.textContent = '<?php esc_html_e('Messages processed:', 'rl-mailwarmer'); ?> ' + response.data.success + ' with ' + response.data.failure + ' failures' ;
|
||||
} else {
|
||||
console.log("Failure");
|
||||
resultDiv.textContent = '<?php esc_html_e('Error:', 'rl-mailwarmer'); ?> ' + response.data.message;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler to process the message queue.
|
||||
*/
|
||||
add_action('wp_ajax_rl_mailwarmer_process_message_queue', function () {
|
||||
// log_to_file("wp_ajax_rl_mailwarmer_process_message_queue - Running");
|
||||
// Verify nonce
|
||||
if (!check_ajax_referer('rl_mailwarmer_message_queue_nonce', 'security', false)) {
|
||||
wp_send_json_error(['message' => __('Invalid nonce.', 'rl-mailwarmer')]);
|
||||
}
|
||||
|
||||
// Ensure the user has permission
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error(['message' => __('Permission denied.', 'rl-mailwarmer')]);
|
||||
}
|
||||
|
||||
try {
|
||||
// Process pending messages
|
||||
// log_to_file("wp_ajax_rl_mailwarmer_process_message_queue - Trying process_pending_messages()");
|
||||
$results = RL_MailWarmer_Message_Handler::process_pending_messages();
|
||||
|
||||
wp_send_json_success($results);
|
||||
} catch (Exception $e) {
|
||||
wp_send_json_error(['message' => $e->getMessage()]);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class PostTypeList {
|
|||
|
||||
public function __construct(string $post_type, array $labels = [], array $additional_query_args = []) {
|
||||
$this->post_type = $post_type;
|
||||
$this->items_per_page = isset($_GET['per_page']) ? intval($_GET['per_page']) : 10;
|
||||
$this->items_per_page = isset($_GET['per_page']) ? intval($_GET['per_page']) : 25;
|
||||
$this->paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
|
||||
|
||||
// Base query args
|
||||
|
|
@ -60,22 +60,22 @@ class PostTypeList {
|
|||
?>
|
||||
<div class="post-type-item">
|
||||
<div class="post-type-content">
|
||||
<a href="<?php //echo get_permalink(); ?>" class="post-type-name">
|
||||
<a href="<?php echo get_permalink(); ?>" class="post-type-name">
|
||||
<?php the_title(); ?>
|
||||
</a>
|
||||
<div class="row-actions">
|
||||
<span class="edit">
|
||||
<a href="<?php //echo $edit_url_base . $post_id; ?>">Edit</a> |
|
||||
<a href="<?php echo $edit_url_base . $post_id; ?>">Edit</a> |
|
||||
</span>
|
||||
<span class="trash">
|
||||
<?php //echo $this->get_delete_link($post_id); ?>
|
||||
<?php echo $this->get_delete_link($post_id); ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
<?php else : ?>
|
||||
<p><?php echo esc_html($this->labels['no_items']); ?></p>
|
||||
<p><?php echo $this->labels['no_items']; ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="page-nav">
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ class RL_MailWarmer_Scheduler {
|
|||
add_filter('cron_schedules', [__CLASS__, 'add_cron_timings']);
|
||||
|
||||
// Call local functions to call the remote classes, so we can debug cron jobs
|
||||
add_action('rl_mailwarmer_process_messages', [__CLASS__, 'process_pending_messages']);
|
||||
add_action('rl_mailwarmer_process_upcoming_conversations', [__CLASS__, 'process_upcoming_conversations']);
|
||||
add_action('rl_mailwarmer_process_messages', [__CLASS__, 'cron_process_pending_messages']);
|
||||
add_action('rl_mailwarmer_process_upcoming_conversations', [__CLASS__, 'cron_process_upcoming_conversations']);
|
||||
// add_action('rl_mailwarmer_process_messages', [RL_MailWarmer_Message_Handler::class, 'process_pending_messages']);
|
||||
// add_action('rl_mailwarmer_process_upcoming_conversations', [RL_MailWarmer_Conversation_Handler::class, 'process_upcoming_conversations']);
|
||||
|
||||
|
|
@ -79,16 +79,16 @@ class RL_MailWarmer_Scheduler {
|
|||
/**
|
||||
* Process pending messages by delegating to the Message Handler.
|
||||
*/
|
||||
public static function process_pending_messages() {
|
||||
// log_to_file("schedule_cron_jobs ====================== Running Cron to process messages ========================");
|
||||
// RL_MailWarmer_Message_Handler::process_pending_messages();
|
||||
public static function cron_process_pending_messages() {
|
||||
action_log("====================== Running Cron to process messages ========================");
|
||||
RL_MailWarmer_Message_Handler::process_pending_messages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process pending conversations by delegating to the Message Handler.
|
||||
*/
|
||||
public static function process_upcoming_conversations() {
|
||||
// log_to_file("schedule_cron_jobs ====================== Running Cron to process conversations ========================");
|
||||
// RL_MailWarmer_Message_Handler::process_upcoming_conversations();
|
||||
public static function cron_process_upcoming_conversations() {
|
||||
action_log("====================== Running Cron to process conversations ========================");
|
||||
RL_MailWarmer_Conversation_Handler::process_upcoming_conversations();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* Set the CUSTOM_DEBUG_LOG file in wp-config.php
|
||||
*
|
||||
*/
|
||||
function log_to_file($message, $data = false){
|
||||
function log_to_file($message, $data = null, $enable_backtrace = false) {
|
||||
if ($message) {
|
||||
$log_File = CUSTOM_DEBUG_LOG;
|
||||
|
||||
|
|
@ -21,13 +21,48 @@ function log_to_file($message, $data = false){
|
|||
|
||||
// Convert arrays and objects to JSON format
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$data = json_encode($data);
|
||||
$data = json_encode($data, JSON_PRETTY_PRINT);
|
||||
$message = $message . "\r\n" . $data;
|
||||
} else if ($data) {
|
||||
$message = $message . " " . $data;
|
||||
}
|
||||
|
||||
error_log("[$date] " . $message ."\r\n",3,$log_File);
|
||||
// Include backtrace information if enabled
|
||||
if ($enable_backtrace) {
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
$callingFunction = $backtrace[1]['function']; // Access the calling function name
|
||||
$backtrace_info = json_encode($backtrace, JSON_PRETTY_PRINT);
|
||||
$message .= "\r\nBacktrace:\r\n" . $backtrace_info;
|
||||
}
|
||||
|
||||
error_log("[$date] " . $message . "\r\n", 3, $log_File);
|
||||
}
|
||||
}
|
||||
|
||||
function action_log($message, $data = null, $enable_backtrace = false) {
|
||||
if ($message) {
|
||||
$log_File = ACTION_LOG;
|
||||
|
||||
$date = new DateTime('now', new DateTimeZone('America/Chicago'));
|
||||
$date = $date->format("Y/m/d h:i:s");
|
||||
|
||||
// Convert arrays and objects to JSON format
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$data = json_encode($data, JSON_PRETTY_PRINT);
|
||||
$message = $message . "\r\n" . $data;
|
||||
} else if ($data) {
|
||||
$message = $message . " " . $data;
|
||||
}
|
||||
|
||||
// Include backtrace information if enabled
|
||||
if ($enable_backtrace) {
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
$callingFunction = $backtrace[1]['function']; // Access the calling function name
|
||||
$backtrace_info = json_encode($backtrace, JSON_PRETTY_PRINT);
|
||||
$message .= "\r\nBacktrace:\r\n" . $backtrace_info;
|
||||
}
|
||||
|
||||
error_log("[$date] " . $message . "\r\n", 3, $log_File);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,13 +17,14 @@ jQuery(document).ready(function ($) {
|
|||
success: function (response) {
|
||||
console.log(response);
|
||||
if (response.success) {
|
||||
const timeline = response.data;
|
||||
let output = '<p>Timeline Generated:</p><ul>';
|
||||
$.each(timeline, function (date, volume) {
|
||||
output += `<li><strong>${date}:</strong> ${volume} emails</li>`;
|
||||
});
|
||||
output += '</ul>';
|
||||
$('#generate-timeline-result').html(output);
|
||||
console.log(response.data);
|
||||
// const timeline = response.data;
|
||||
// let output = '<p>Timeline Generated:</p><ul>';
|
||||
// $.each(timeline, function (date, volume) {
|
||||
// output += `<li><strong>${date}:</strong> ${volume} emails</li>`;
|
||||
// });
|
||||
// output += '</ul>';
|
||||
$('#generate-timeline-result').html(response.data);
|
||||
} else {
|
||||
$('#generate-timeline-result').html('<p>Error: ' + response.data + '</p>');
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue