| 1 |
<?php |
| 2 |
|
| 3 |
/* *************************************************************** |
| 4 |
Options Page |
| 5 |
**************************************************************** */ |
| 6 |
|
| 7 |
function wdm_wpma_actionlinks ( $actions ) { |
| 8 |
$links = array( |
| 9 |
'<a href="'.admin_url('admin.php?page=wdm_wpma_mail_queue').'">Settings</a>', |
| 10 |
'<a href="'.admin_url('admin.php?page=wdm_wpma_mail_queue-tab-log').'">Log</a>', |
| 11 |
'<a href="'.admin_url('admin.php?page=wdm_wpma_mail_queue-tab-queue').'">Queue</a>', |
| 12 |
'<a href="'.admin_url('admin.php?page=wdm_wpma_mail_queue-tab-faq').'">FAQs</a>', |
| 13 |
); |
| 14 |
return array_merge($actions,$links ); |
| 15 |
} |
| 16 |
add_filter('plugin_action_links_mail-queue/mail-queue.php','wdm_wpma_actionlinks'); |
| 17 |
|
| 18 |
// Options Page |
| 19 |
function wdm_wpma_settings_page_menuitem() { |
| 20 |
add_menu_page('Mail Queue','Mail Queue','manage_options','wdm_wpma_mail_queue','wdm_wpma_settings_page','data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTc4IiBoZWlnaHQ9IjE3OCIgdmlld0JveD0iMCAwIDE3OCAxNzgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNzguNzI0MSA1LjI1MzA5Qzc2LjkwNzQgNC43MDgxIDc0Ljk0MDEgNS4wNTQxMyA3My40MTg0IDYuMTg2MjlDNzEuODk2OCA3LjMxODQ1IDcxIDkuMTAzNDEgNzEgMTEuMDAwMVYxNjdDNzEgMTY4Ljg5NyA3MS44OTY4IDE3MC42ODIgNzMuNDE4NCAxNzEuODE0Qzc0Ljk0MDEgMTcyLjk0NiA3Ni45MDc0IDE3My4yOTIgNzguNzI0MSAxNzIuNzQ3TDE1OC43MjQgMTQ4Ljc0N0MxNjEuMjYyIDE0Ny45ODYgMTYzIDE0NS42NSAxNjMgMTQzVjM1QzE2MyAzMi4zNTA0IDE2MS4yNjIgMzAuMDE0NSAxNTguNzI0IDI5LjI1MzFMNzguNzI0MSA1LjI1MzA5Wk04NS43ODg3IDIyLjM4NDZDODcuNzg1NCAyMS40Mzk0IDkwLjE3MDMgMjIuMjkxOSA5MS4xMTU0IDI0LjI4ODdMMTIyLjg1MiA5MS4zMzc4TDE0My4zMzQgNDQuNDAwMkMxNDQuMjE3IDQyLjM3NTUgMTQ2LjU3NSA0MS40NTAzIDE0OC42IDQyLjMzMzhDMTUwLjYyNSA0My4yMTc0IDE1MS41NSA0NS41NzUgMTUwLjY2NiA0Ny41OTk4TDEyNi42NjYgMTAyLjZDMTI2LjAzOSAxMDQuMDM3IDEyNC42MjkgMTA0Ljk3NiAxMjMuMDYxIDEwNUMxMjEuNDkzIDEwNS4wMjQgMTIwLjA1NiAxMDQuMTI5IDExOS4zODUgMTAyLjcxMUw4My44ODQ2IDI3LjcxMTNDODIuOTM5NCAyNS43MTQ2IDgzLjc5MTkgMjMuMzI5NyA4NS43ODg3IDIyLjM4NDZaIiBmaWxsPSIjYTdhYWFkIi8+CjxwYXRoIGQ9Ik00OSAxM0M1Mi4zMTM3IDEzIDU1IDE1LjY4NjMgNTUgMTlWMTU5QzU1IDE2Mi4zMTQgNTIuMzEzNyAxNjUgNDkgMTY1QzQ1LjY4NjMgMTY1IDQzIDE2Mi4zMTQgNDMgMTU5VjE5QzQzIDE1LjY4NjMgNDUuNjg2MyAxMyA0OSAxM1oiIGZpbGw9IiNhN2FhYWQiLz4KPHBhdGggZD0iTTIxIDIxQzI0LjMxMzcgMjEgMjcgMjMuNjg2MyAyNyAyN1YxNTFDMjcgMTU0LjMxNCAyNC4zMTM3IDE1NyAyMSAxNTdDMTcuNjg2MyAxNTcgMTUgMTU0LjMxNCAxNSAxNTFWMjdDMTUgMjMuNjg2MyAxNy42ODYzIDIxIDIxIDIxWiIgZmlsbD0iI2E3YWFhZCIvPgo8L3N2Zz4='); |
| 21 |
add_submenu_page('wdm_wpma_mail_queue','Settings','Settings','manage_options','wdm_wpma_mail_queue','wdm_wpma_settings_page'); |
| 22 |
add_submenu_page('wdm_wpma_mail_queue','Log','Log','manage_options','wdm_wpma_mail_queue-tab-log','wdm_wpma_settings_page'); |
| 23 |
add_submenu_page('wdm_wpma_mail_queue','Queue','Queue','manage_options','wdm_wpma_mail_queue-tab-queue','wdm_wpma_settings_page'); |
| 24 |
add_submenu_page('wdm_wpma_mail_queue','FAQ','FAQ','manage_options','wdm_wpma_mail_queue-tab-faq','wdm_wpma_settings_page'); |
| 25 |
if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) { |
| 26 |
add_submenu_page('wdm_wpma_mail_queue','Cron Information','Cron Information','manage_options','wdm_wpma_mail_queue-tab-croninfo','wdm_wpma_settings_page'); |
| 27 |
} |
| 28 |
} |
| 29 |
add_action('admin_menu','wdm_wpma_settings_page_menuitem'); |
| 30 |
|
| 31 |
function wdm_wpma_settings_page_assets () { |
| 32 |
$screen = get_current_screen(); |
| 33 |
if ( preg_match( '#wdm_wpma_mail_queue#', $screen->base ) ) { |
| 34 |
wp_enqueue_style( 'wdm_wpma_style', plugins_url( 'assets/css/admin.css', __FILE__ ) ); |
| 35 |
wp_enqueue_script( 'wdm_wpma_script', plugins_url( 'assets/js/wdm-wpma-admin.js', __FILE__ ), [ 'jquery' ], false, true ); |
| 36 |
} |
| 37 |
} |
| 38 |
add_action( 'admin_enqueue_scripts', 'wdm_wpma_settings_page_assets' ); |
| 39 |
|
| 40 |
// Options Page Settings |
| 41 |
function wdm_wpma_settings_page() { |
| 42 |
|
| 43 |
// Only Admins |
| 44 |
if ( ! current_user_can( 'manage_options' ) ) { return; } |
| 45 |
|
| 46 |
// Settings |
| 47 |
global $wdm_wpma_options; |
| 48 |
|
| 49 |
// Get the active tab from the $_GET param |
| 50 |
$default_tab = null; |
| 51 |
$tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : $default_tab; |
| 52 |
|
| 53 |
echo '<div class="wrap">'; |
| 54 |
|
| 55 |
// Options Header |
| 56 |
echo '<h1 class="wdm-wpma-title"><img class="wdm-wpma-logo" src="'.esc_url(plugins_url('assets/img/mail-queue-logo-wordmark.svg', __FILE__)).'" alt="Mail Queue" width="308" height="56" /></h1>'; |
| 57 |
|
| 58 |
$tab = sanitize_key($_GET['page']); |
| 59 |
if ($tab != 'wdm_wpma_mail_queue-tab-croninfo' ) { |
| 60 |
if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) { |
| 61 |
echo '<div class="notice notice-warning notice-large">'; |
| 62 |
$url = esc_url(get_option('siteurl').'/wp-cron.php'); |
| 63 |
echo '<p><strong>Please note:</strong><br />Your normal WP Cron is disabled. Please make sure you\'re running the Cron manually by calling <a href="'.$url.'" target="_blank">'.$url.'</a> every couple of minutes.</p>'; |
| 64 |
echo '<p><a href="?page=wdm_wpma_mail_queue-tab-croninfo">More information</a></p>'; |
| 65 |
echo '</div>'; |
| 66 |
} |
| 67 |
} |
| 68 |
wdm_wpma_settings_page_navi($tab); // Tabs |
| 69 |
|
| 70 |
// Options Page Content |
| 71 |
if ($tab == 'wdm_wpma_mail_queue') { |
| 72 |
echo '<form action="options.php" method="post">'; |
| 73 |
settings_fields('wdm_wpma_settings'); |
| 74 |
do_settings_sections('wdm_wpma_settings_page'); |
| 75 |
submit_button(); |
| 76 |
echo '</form>'; |
| 77 |
} else if ($tab == 'wdm_wpma_mail_queue-tab-log') { |
| 78 |
echo '<form method="post">'; |
| 79 |
$logtable = new wdm_wpma_Log_Table(); |
| 80 |
$logtable->prepare_items(); |
| 81 |
$logtable->display(); |
| 82 |
echo '</form>'; |
| 83 |
} else if ($tab == 'wdm_wpma_mail_queue-tab-queue') { |
| 84 |
|
| 85 |
if (isset($_GET['addtestmail'])) { |
| 86 |
global $wpdb; |
| 87 |
$tableName = $wpdb->prefix.$wdm_wpma_options['tableName']; |
| 88 |
$data = array( |
| 89 |
'timestamp'=>current_time('mysql',false), |
| 90 |
'recipient'=>$wdm_wpma_options['email'], |
| 91 |
'subject'=>'Testmail #'.time(), |
| 92 |
'message'=>'This is just a test email send by the Mail Queue plugin.', |
| 93 |
'status' => 'queue' |
| 94 |
); |
| 95 |
$wpdb->insert($tableName,$data); |
| 96 |
} |
| 97 |
|
| 98 |
$next_cron_timestamp = wp_next_scheduled('wp_mail_queue_hook'); |
| 99 |
if ($next_cron_timestamp) { |
| 100 |
if ($next_cron_timestamp > time()) { |
| 101 |
echo '<div class="notice notice-success"><p>Next Sending will be triggered in '.esc_html(human_time_diff($next_cron_timestamp)).' at '.esc_html(wp_date('H:i',$next_cron_timestamp)).'.</p></div>'; |
| 102 |
} |
| 103 |
} else { |
| 104 |
echo '<div class="notice notice-error"><p>The Queue is not enabled at the moment. Enable it in the <a href="admin.php?page=wdm_wpma_mail_queue">Settings</a>.</p></div>'; |
| 105 |
} |
| 106 |
|
| 107 |
echo '<form method="post" action="admin.php?page=wdm_wpma_mail_queue-tab-queue">'; |
| 108 |
$queuetable = new wdm_wpma_Log_Table(); |
| 109 |
$queuetable->prepare_items(); |
| 110 |
$queuetable->display(); |
| 111 |
echo '</form>'; |
| 112 |
} else if ($tab == 'wdm_wpma_mail_queue-tab-faq') { |
| 113 |
echo '<div class="wdm-wpma-box">'; |
| 114 |
echo '<h3>How does this Plugin work?</h3>'; |
| 115 |
echo '<p>If enabled this plugin intercepts the <a target="_blank" href="https://developer.wordpress.org/reference/functions/wp_mail/"><i>wp_mail()</i></a> function. Instead of sending the mails directly, it stores them in the database and sends them step by step with a delay during the <i>WP Cron</i>.</p>'; |
| 116 |
echo '<p>Current state: '; |
| 117 |
if ($wdm_wpma_options['enabled'] == '1') { |
| 118 |
echo '<b class="wdm-wpma-ok">The plugin is enabled</b> All Mails sent through <a target="_blank" href="https://developer.wordpress.org/reference/functions/wp_mail/"><i>wp_mail()</i></a> are delayed by the <a href="admin.php?page=wdm_wpma_mail_queue-tab-queue">Queue</a>.'; |
| 119 |
} else { |
| 120 |
echo '<b>The plugin is disabled</b>. The plugin has no impact at the moment, no Mails inside the Queue are going to be sent.'; |
| 121 |
} |
| 122 |
echo '</p>'; |
| 123 |
echo '</div>'; |
| 124 |
echo '<div class="wdm-wpma-box">'; |
| 125 |
echo '<h3>Does this plugin change the way <b>HOW</b> emails are sent?</h3>'; |
| 126 |
echo '<p>No, don\'t worry. This plugin only affects <b>WHEN</b> emails are sent, not how. It delays the sending (by the Queue), nonetheless all emails are sent through the standard <a target="_blank" href="https://developer.wordpress.org/reference/functions/wp_mail/"><i>wp_mail()</i></a> function.</p>'; |
| 127 |
echo '<p>If you use SMTP for sending, or an external service like Mailgun, everything will still work as expected.</p>'; |
| 128 |
echo '</div>'; |
| 129 |
echo '<div class="wdm-wpma-box">'; |
| 130 |
echo '<h3>Does this plugin work, if I have a Caching Plugin installed? E.g. <i>W3 Total Cache</i> or similar?</h3>'; |
| 131 |
echo '<p>If you\'re using a Caching plugin like <i>W3 Total Cache</i>, <i>WP Rocket</i> or any other caching solution which generates static html-files and serves them to visitors, you\'ll have to make sure you\'re calling the <a href="'.esc_url(get_option('siteurl')).'/wp-cron.php" target="_blank">wp-cron file</a> manually every couple of minutes.</p>'; |
| 132 |
echo '<p>Otherwise your normal WP Cron wouldn\'t be called as often as it should be and scheduled messages would be sent with big delays.</p>'; |
| 133 |
echo '</div>'; |
| 134 |
echo '<div class="wdm-wpma-box">'; |
| 135 |
echo '<h3>What about Proxy-Caching, e.g. NGINX?</h3>'; |
| 136 |
echo '<p>Same situation here. Please make sure you\'re calling the <a href="'.esc_url(get_option('siteurl')).'/wp-cron.php" target="_blank">WordPress Cron</a> by an external service or your webhoster every couple of minutes.</p>'; |
| 137 |
echo '</div>'; |
| 138 |
echo '<div class="wdm-wpma-box">'; |
| 139 |
echo '<h3>My form builder supports attachments. What about them?</h3>'; |
| 140 |
echo '<p>You are covered. All attachments are stored temporarily in the queue until they are sent along with their corresponding emails.</p>'; |
| 141 |
echo '</div>'; |
| 142 |
echo '<div class="wdm-wpma-box">'; |
| 143 |
echo '<h3>What are Queue alerts?</h3>'; |
| 144 |
echo '<p>This is a simple and effective way to improve the security of your WordPress installation.</p><p>Imagine: In case your website is sending spam through <a target="_blank" href="https://developer.wordpress.org/reference/functions/wp_mail/"><i>wp_mail()</i></a>, the email Queue would fill up very quickly preventing your website from sending so many spam emails at once. This gives you time and avoids a lot of trouble.</p><p>Queue Alerts warn you, if the Queue is longer than usal. You decide at which point you want to be alerted. So you get the chance to have a look if there might be something wrong on the website.</p>'; |
| 145 |
echo '<p>Current state: '; |
| 146 |
if ($wdm_wpma_options['alert_enabled'] == '1') { |
| 147 |
echo '<b class="wdm-wpma-ok">Alerts are enabled</b> If more than '.esc_html($wdm_wpma_options['email_amount']).' emails are waiting in the Queue, WordPress will sent an alert email to <i>'.esc_html($wdm_wpma_options['email']).'</i>.'; |
| 148 |
} else { |
| 149 |
echo '<b>Alerting is disabled</b>. No alerts will be sent.'; |
| 150 |
} |
| 151 |
echo '</p>'; |
| 152 |
echo '<p>Please note: This plugin will only send one alert every six hours.</p>'; |
| 153 |
echo '</div>'; |
| 154 |
|
| 155 |
echo '<div class="wdm-wpma-box">'; |
| 156 |
echo '<h3>Can I add emails with a high priority to the queue?</h3>'; |
| 157 |
echo '<p>Yes, you can add the custom <i>`X-Mail-Queue-Prio`</i> header set to <i>`High`</i> to your email. High priority emails will be sent through the standard Mail Queue sending cycle but before all normal emails lacking a priority header in the queue.</p>'; |
| 158 |
echo '<p><b>Example 1 (add priority to Woocommerce emails):</b></p>'; |
| 159 |
echo '<pre><code>add_filter(\'woocommerce_mail_callback_params\',function ( $array ) { |
| 160 |
$prio_header = \'X-Mail-Queue-Prio: High\'; |
| 161 |
$array[3] .= $prio_header."\\r\\n"; |
| 162 |
return $array; |
| 163 |
},10,1);</code></pre>'; |
| 164 |
echo '<p><b>Example 2 (add priority to Contact Form 7 form emails):</b></p>'; |
| 165 |
echo '<p>When editing a form in Contact Form 7 just add an additional line to the <i>`Additional Headers`</i> field under the <i>`Mail`</i> tab panel.</p>'; |
| 166 |
echo '<pre><code>X-Mail-Queue-Prio: High</code></pre>'; |
| 167 |
echo '<p><b>Example 3 (add priority to WordPress reset password emails):</b></p>'; |
| 168 |
echo '<pre><code>add_filter(\'retrieve_password_notification_email\', function ($defaults, $key,$user_ login, $user_data) { |
| 169 |
$prio_header = \'X-Mail-Queue-Prio: High\'; |
| 170 |
if (is_array($defaults[\'headers\'])) { |
| 171 |
$defaults[\'headers\'][] = $prio_header; |
| 172 |
} else { |
| 173 |
$defaults[\'headers\'] .= $defaults[\'headers\'] ? "\r\n" : \'\'; |
| 174 |
$defaults[\'headers\'] .= $prio_header; |
| 175 |
} |
| 176 |
$return $defaults; |
| 177 |
}, 10, 4);</code></pre>'; |
| 178 |
echo '</div>'; |
| 179 |
|
| 180 |
echo '<div class="wdm-wpma-box">'; |
| 181 |
echo '<h3>Can I send emails <i>instantly</i> without going through the queue?</h3>'; |
| 182 |
echo '<p>Yes, this is possible (if you absolutely need to do this).</p>'; |
| 183 |
echo '<p>For this you can add the custom <i>`X-Mail-Queue-Prio`</i> header set to <i>`Instant`</i> to your email. These emails are sent instantly circumventing the mail queue. They still appear in the Mail Queue log flagged as `instant`.</p>'; |
| 184 |
echo '<p>Mind that this is a potential security risk and should be considered carefully. Please use only as an exception.</p>'; |
| 185 |
echo '<p><b>Example 1 (instantly send Woocommerce emails):</b></p>'; |
| 186 |
echo '<pre><code>add_filter(\'woocommerce_mail_callback_params\',function ( $array ) { |
| 187 |
$prio_header = \'X-Mail-Queue-Prio: Instant\'; |
| 188 |
$array[3] .= $prio_header."\\r\\n"; |
| 189 |
return $array; |
| 190 |
},10,1);</code></pre>'; |
| 191 |
echo '<p><b>Example 2 (instantly send Contact Form 7 form emails):</b></p>'; |
| 192 |
echo '<p>When editing a form in Contact Form 7 just add an additional line to the <i>`Additional Headers`</i> field under the <i>`Mail`</i> tab panel.</p>'; |
| 193 |
echo '<pre><code>X-Mail-Queue-Prio: Instant</code></pre>'; |
| 194 |
echo '<p><b>Example 3 (instantly send WordPress reset password emails):</b></p>'; |
| 195 |
echo '<pre><code>add_filter(\'retrieve_password_notification_email\', function ($defaults, $key,$user_ login, $user_data) { |
| 196 |
$prio_header = \'X-Mail-Queue-Prio: Instant\'; |
| 197 |
if (is_array($defaults[\'headers\'])) { |
| 198 |
$defaults[\'headers\'][] = $prio_header; |
| 199 |
} else { |
| 200 |
$defaults[\'headers\'] .= $defaults[\'headers\'] ? "\r\n" : \'\'; |
| 201 |
$defaults[\'headers\'] .= $prio_header; |
| 202 |
} |
| 203 |
$return $defaults; |
| 204 |
}, 10, 4);</code></pre>'; |
| 205 |
echo '</div>'; |
| 206 |
|
| 207 |
echo '<div class="wdm-wpma-box">'; |
| 208 |
echo '<h3>Want to put a test email into the Queue?</h3>'; |
| 209 |
echo '<p><a class="button" href="admin.php?page=wdm_wpma_mail_queue-tab-queue&addtestmail">Sure! Put a Test Email for '.esc_html($wdm_wpma_options['email']).' into the Queue</a></p>'; |
| 210 |
echo '</div>'; |
| 211 |
|
| 212 |
} else if ($tab == 'wdm_wpma_mail_queue-tab-croninfo') { |
| 213 |
echo '<div class="wdm-wpma-box">'; |
| 214 |
echo '<h3>Information: Your common WP Cron is disabled</h3>'; |
| 215 |
echo '<p>It look\'s like you deactived the WP Cron by <i>define( \' DISABLE_WP_CRON \' , true )</i>.</p>'; |
| 216 |
$url = esc_url(get_option('siteurl').'/wp-cron.php'); |
| 217 |
echo '<p>In general, this is no problem at all. We just want to remind you to make sure you\'re running the Cron manually by calling <a href="'.$url.'" target="_blank">'.$url.'</a> every couple of minutes.</p>'; |
| 218 |
echo '</div>'; |
| 219 |
|
| 220 |
|
| 221 |
if (function_exists('_get_cron_array')) { |
| 222 |
$next_tasks = _get_cron_array(); |
| 223 |
if ($next_tasks) { |
| 224 |
$tasks_in_past = false; |
| 225 |
$tasks_of_mailqueue_in_past = false; |
| 226 |
foreach($next_tasks as $key => $val) { |
| 227 |
if (time() > intval($key) + intval($wdm_wpma_options['queue_interval'])) { |
| 228 |
if (array_keys($val)[0] == 'wp_mail_queue_hook') { $tasks_of_mailqueue_in_past = intval($key); } |
| 229 |
$tasks_in_past = true; |
| 230 |
} |
| 231 |
} |
| 232 |
if ($tasks_in_past) { |
| 233 |
echo '<div class="wdm-wpma-box">'; |
| 234 |
echo '<h3>Attention: It seams that your WP Cron is not running. There are some jobs waiting to be completed.</h3>'; |
| 235 |
if ($tasks_of_mailqueue_in_past) { |
| 236 |
echo '<p><body>The Queue wasn\'t been able to be executed since '.esc_html(human_time_diff($tasks_of_mailqueue_in_past,time())).'.</b></p>'; |
| 237 |
} |
| 238 |
echo '</div>'; |
| 239 |
} |
| 240 |
} |
| 241 |
} |
| 242 |
|
| 243 |
|
| 244 |
} |
| 245 |
|
| 246 |
echo '</div>'; |
| 247 |
|
| 248 |
} |
| 249 |
|
| 250 |
if(!class_exists('WP_List_Table')){ |
| 251 |
require_once( ABSPATH . 'wp-admin/includes/screen.php' ); |
| 252 |
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); |
| 253 |
} |
| 254 |
|
| 255 |
class wdm_wpma_Log_Table extends WP_List_Table { |
| 256 |
|
| 257 |
function get_log() { |
| 258 |
global $wpdb, $wdm_wpma_options; |
| 259 |
$tableName = $wpdb->prefix.$wdm_wpma_options['tableName']; |
| 260 |
return $wpdb->get_results("SELECT * FROM `$tableName` WHERE `status` != 'queue' AND `status` != 'high' ORDER BY `timestamp` DESC",'ARRAY_A'); |
| 261 |
} |
| 262 |
|
| 263 |
function get_queue() { |
| 264 |
global $wpdb, $wdm_wpma_options; |
| 265 |
$tableName = $wpdb->prefix.$wdm_wpma_options['tableName']; |
| 266 |
return $wpdb->get_results("SELECT * FROM `$tableName` WHERE `status` = 'queue' OR `status` = 'high' ORDER BY `status` ASC, `timestamp` ASC",'ARRAY_A'); |
| 267 |
} |
| 268 |
|
| 269 |
function get_columns() { |
| 270 |
$columns = array( |
| 271 |
'id' => '<label><span class="screen-reader-text">Select all</span><input class="wdm-wpma-select-all" type="checkbox"></label>', |
| 272 |
'timestamp' => 'Time', |
| 273 |
'status' => 'Status', |
| 274 |
'recipient' => 'Recipient', |
| 275 |
'subject' => 'Subject', |
| 276 |
'message' => 'Message', |
| 277 |
'headers' => 'Headers', |
| 278 |
'attachments' => 'Attachments', |
| 279 |
); |
| 280 |
return $columns; |
| 281 |
} |
| 282 |
|
| 283 |
public function prepare_items() { |
| 284 |
$type = sanitize_key($_GET['page']); |
| 285 |
$columns = $this->get_columns(); |
| 286 |
$hidden = array(); |
| 287 |
$sortable = array(); |
| 288 |
$this->_column_headers = array($columns, $hidden, $sortable); |
| 289 |
$this->process_bulk_action(); |
| 290 |
if ($type == 'wdm_wpma_mail_queue-tab-log') { |
| 291 |
$data = $this->get_log(); |
| 292 |
} else if ($type == 'wdm_wpma_mail_queue-tab-queue') { |
| 293 |
$data = $this->get_queue(); |
| 294 |
} |
| 295 |
if ($data && is_array($data)) { |
| 296 |
$perPage = 50; |
| 297 |
$currentPage = $this->get_pagenum(); |
| 298 |
$totalItems = count($data); |
| 299 |
$this->set_pagination_args( array( |
| 300 |
'total_items' => $totalItems, |
| 301 |
'per_page' => $perPage |
| 302 |
) ); |
| 303 |
$data = array_slice($data,(($currentPage-1)*$perPage),$perPage); |
| 304 |
} |
| 305 |
$this->items = $data; |
| 306 |
} |
| 307 |
|
| 308 |
public function column_default( $item, $column_name ) { |
| 309 |
switch( $column_name ) { |
| 310 |
case 'timestamp': |
| 311 |
case 'subject': |
| 312 |
case 'info': |
| 313 |
return esc_html( maybe_unserialize($item[$column_name]) ); |
| 314 |
break; |
| 315 |
case 'recipient': |
| 316 |
case 'headers': |
| 317 |
$return = maybe_unserialize($item[$column_name]); |
| 318 |
if (is_array($return)) { |
| 319 |
return esc_html( implode(',',$return) ); |
| 320 |
} else { |
| 321 |
return esc_html( $return ); |
| 322 |
} |
| 323 |
break; |
| 324 |
case 'attachments': |
| 325 |
$return = maybe_unserialize($item[$column_name]); |
| 326 |
//var_dump($return); |
| 327 |
if (is_array($return)) { |
| 328 |
$betterreturn = array(); |
| 329 |
foreach($return as $item) { |
| 330 |
array_push($betterreturn,basename($item)); |
| 331 |
} |
| 332 |
return esc_html( implode('<br />',$betterreturn) ); |
| 333 |
} else { |
| 334 |
return esc_html( basename($return) ); |
| 335 |
} |
| 336 |
break; |
| 337 |
case 'status': |
| 338 |
$info = isset( $item[ 'info' ] ) && $item[ 'info' ] ? $item[ 'info' ] : ''; |
| 339 |
if ( $item[$column_name] === 'alert' ) { |
| 340 |
$alertData = json_decode($info,/*associative*/true); |
| 341 |
if ( $alertData ) { |
| 342 |
$info = '<strong>Emails in queue</strong>: '.esc_html($alertData['in_queue']); |
| 343 |
$info .= '<br /><strong>Queue settings</strong>: Send max '.esc_html($alertData['queue_amount']).' email(s) every '.esc_html($alertData['queue_interval']/60).' minute(s).'; |
| 344 |
$info .= '<br /><strong>Alert settings</strong>: Send alert if more than '.esc_html($alertData['email_amount']).' email(s) in the queue.'; |
| 345 |
} else { |
| 346 |
$info = ''; |
| 347 |
} |
| 348 |
} |
| 349 |
$htmlInfo = $info ? '<span class="wdm-wpma-info">'.$info.'</span>' : ''; |
| 350 |
$cssStatus = $htmlInfo ? ' wdm-wpma-status-has-info' : ''; |
| 351 |
return '<span class="wdm-wpma-status wdm-wpma-status-'.sanitize_title($item[$column_name]).esc_html($cssStatus).'">'.$item[$column_name].$htmlInfo.'</span>'; |
| 352 |
break; |
| 353 |
case 'message': |
| 354 |
$message = $item[$column_name]; |
| 355 |
|
| 356 |
if ( $message ) { |
| 357 |
$messageLen = strlen($message); |
| 358 |
// Split html emails into parts and extract plain text preview |
| 359 |
$parts = explode( '<body', $message ); |
| 360 |
$is_html = count( $parts ) > 1; |
| 361 |
if ( $is_html ) { |
| 362 |
if ( count( $parts ) > 1 ) { |
| 363 |
$header = $parts[ 0 ]; |
| 364 |
$body = '<body'.$parts[ 1 ]; |
| 365 |
} else { |
| 366 |
$header = ''; |
| 367 |
$body = $parts[ 0 ]; |
| 368 |
} |
| 369 |
$parts = explode( '</body>', $body ); |
| 370 |
if ( count( $parts ) > 1 ) { |
| 371 |
$body = $parts[ 0 ].'</body>'; |
| 372 |
$footer = $parts[ 1 ]; |
| 373 |
} else { |
| 374 |
$body = $parts[ 0 ]; |
| 375 |
$footer = ''; |
| 376 |
} |
| 377 |
if ( !function_exists( 'convert_html_to_text' ) ) { |
| 378 |
require_once __DIR__.'/lib/html2text/html2text.php'; |
| 379 |
} |
| 380 |
$text = convert_html_to_text( $body ); |
| 381 |
} else { |
| 382 |
$text = $message; |
| 383 |
$header = ''; |
| 384 |
$body = ''; |
| 385 |
$footer = ''; |
| 386 |
} |
| 387 |
$message = ''; |
| 388 |
$message .= '<details class="wdm-wpma-email-source-meta" open><summary>Text</summary><pre class="wdm-wpma-email-plain-text">'.esc_html( $text ).'</pre></details>'; |
| 389 |
$message .= $header ? '<details class="wdm-wpma-email-source-meta"><summary>HTML Header</summary><pre>'.esc_html( $header ).'</pre></details>' : ''; |
| 390 |
$message .= $body ? '<details class="wdm-wpma-email-source-meta"><summary>HTML Body</summary><pre>'.esc_html( $body ).'</pre></details>' : ''; |
| 391 |
$message .= $footer ? '<details class="wdm-wpma-email-source-meta"><summary>HTML Footer</summary><pre>'.esc_html( $footer ).'</pre></details>' : ''; |
| 392 |
|
| 393 |
$return = '<details>'; |
| 394 |
$return .= '<summary class="wdm-wpma-view-source">View message <i>('.esc_html($messageLen).' bytes)</i></summary>'; |
| 395 |
$return .= '<div class="wdm-wpma-email-source">'.wp_kses_post($message).'</div>'; |
| 396 |
$return .= '</details>'; |
| 397 |
} else { |
| 398 |
$return = '<em>Empty</em>'; |
| 399 |
} |
| 400 |
return $return; |
| 401 |
break; |
| 402 |
case 'id': |
| 403 |
return '<input type="checkbox" name="id[]" value="'.esc_attr($item[$column_name]).'" />'; |
| 404 |
break; |
| 405 |
default: |
| 406 |
return print_r( $item, true ) ; //Show the whole array for troubleshooting purposes |
| 407 |
} |
| 408 |
} |
| 409 |
|
| 410 |
public function get_bulk_actions() { |
| 411 |
if (isset($_GET['page']) && $_GET['page'] == 'wdm_wpma_mail_queue-tab-queue') { |
| 412 |
$actions = array( |
| 413 |
'delete' => __( 'Delete') |
| 414 |
); |
| 415 |
} else { |
| 416 |
$actions = array( |
| 417 |
'delete' => __( 'Delete'), |
| 418 |
'resend' => __( 'Resend'), |
| 419 |
); |
| 420 |
} |
| 421 |
|
| 422 |
return $actions; |
| 423 |
} |
| 424 |
|
| 425 |
public function process_bulk_action() { |
| 426 |
|
| 427 |
// security check! |
| 428 |
if ( isset( $_POST['_wpnonce'] ) && ! empty( $_POST['_wpnonce'] ) ) { |
| 429 |
$nonce = sanitize_key( $_POST['_wpnonce'] ); |
| 430 |
$action = 'bulk-' . $this->_args['plural']; |
| 431 |
if ( ! wp_verify_nonce( $nonce, $action ) ) |
| 432 |
wp_die( 'Nope! Security check failed!' ); |
| 433 |
} |
| 434 |
|
| 435 |
// get IDs |
| 436 |
$request_ids = isset( $_REQUEST['id'] ) ? wp_parse_id_list( wp_unslash( $_REQUEST['id'] ) ) : array(); |
| 437 |
if ( empty( $request_ids ) ) { return; } |
| 438 |
|
| 439 |
global $wpdb, $wdm_wpma_options; |
| 440 |
$tableName = $wpdb->prefix.$wdm_wpma_options['tableName']; |
| 441 |
|
| 442 |
switch ( $this->current_action() ) { |
| 443 |
case 'delete': |
| 444 |
foreach($request_ids as $id) { |
| 445 |
$wpdb->delete($tableName,array('id'=>intval($id)),'%d'); |
| 446 |
} |
| 447 |
break; |
| 448 |
case 'resend': |
| 449 |
foreach($request_ids as $id) { |
| 450 |
$count_resend = 0; |
| 451 |
$count_error = 0; |
| 452 |
$maildata = $wpdb->get_row("SELECT * FROM `$tableName` WHERE `id` = '$id'"); |
| 453 |
if (!$maildata->attachments || $maildata->attachments == '') { |
| 454 |
$count_resend++; |
| 455 |
$data = array( |
| 456 |
'timestamp'=> current_time('mysql',false), |
| 457 |
'recipient'=> $maildata->recipient, |
| 458 |
'subject'=> $maildata->subject, |
| 459 |
'message'=> $maildata->message, |
| 460 |
'status' => 'queue', |
| 461 |
'attachments' => '', |
| 462 |
'headers' => $maildata->headers, |
| 463 |
); |
| 464 |
$wpdb->insert($tableName,$data); |
| 465 |
} else { |
| 466 |
$count_error++; |
| 467 |
$notice = '<div class="notice notice-error is-dismissible">'; |
| 468 |
$notice .= '<p><b>Sorry, your email to '.$maildata->recipient.' can\'t be sent again.</b></p>'; |
| 469 |
$notice .= '<p>The email used to have attachments, which are not available anymore. Only emails without attachments can be resend.</p>'; |
| 470 |
$notice .= '</div>'; |
| 471 |
echo $notice; |
| 472 |
} |
| 473 |
} |
| 474 |
if ($count_error == 0 && $count_resend > 0) { |
| 475 |
wp_redirect('admin.php?page=wdm_wpma_mail_queue-tab-queue'); |
| 476 |
exit; |
| 477 |
} else if ($count_error > 0 && $count_resend > 0) { |
| 478 |
$notice = '<div class="notice notice-success is-dismissible">'; |
| 479 |
$notice .= '<p>The other emails have been put again into the <a href="admin.php?page=wdm_wpma_mail_queue-tab-queue">Queue</a>.</p>'; |
| 480 |
$notice .= '</div>'; |
| 481 |
echo $notice; |
| 482 |
} |
| 483 |
break; |
| 484 |
} |
| 485 |
|
| 486 |
return; |
| 487 |
|
| 488 |
} |
| 489 |
|
| 490 |
} |
| 491 |
|
| 492 |
function wdm_wpma_settings_page_navi($tab) { |
| 493 |
echo '<nav class="nav-tab-wrapper">'; |
| 494 |
echo '<a href="?page=wdm_wpma_mail_queue" class="nav-tab'; if($tab==='wdm_wpma_mail_queue') { echo ' nav-tab-active'; } echo '">Settings</a>'; |
| 495 |
echo '<a href="?page=wdm_wpma_mail_queue-tab-log" class="nav-tab'; if($tab==='wdm_wpma_mail_queue-tab-log') { echo ' nav-tab-active'; } echo '">Log</a>'; |
| 496 |
echo '<a href="?page=wdm_wpma_mail_queue-tab-queue" class="nav-tab'; if($tab==='wdm_wpma_mail_queue-tab-queue') { echo ' nav-tab-active'; } echo '">Queue</a>'; |
| 497 |
echo '<a href="?page=wdm_wpma_mail_queue-tab-faq" class="nav-tab'; if($tab==='wdm_wpma_mail_queue-tab-faq') { echo ' nav-tab-active'; } echo '">FAQ</a>'; |
| 498 |
if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) { |
| 499 |
echo '<a href="?page=wdm_wpma_mail_queue-tab-croninfo" class="nav-tab'; if($tab==='wdm_wpma_mail_queue-tab-croninfo') { echo ' nav-tab-active'; } echo '">Cron Information</a>'; |
| 500 |
} |
| 501 |
echo '</nav>'; |
| 502 |
} |
| 503 |
|
| 504 |
function wdm_wpma_settings_init() { |
| 505 |
global $wdm_wpma_options; |
| 506 |
register_setting('wdm_wpma_settings','wdm_wpma_settings'); |
| 507 |
add_settings_section('wdm_wpma_settings_section','',null,'wdm_wpma_settings_page'); |
| 508 |
add_settings_field('wdm_wpma_status','Queue + Log enabled','wdm_wpma_render_option_status','wdm_wpma_settings_page','wdm_wpma_settings_section'); |
| 509 |
add_settings_field('wdm_wpma_queue','Queue','wdm_wpma_render_option_queue','wdm_wpma_settings_page','wdm_wpma_settings_section'); |
| 510 |
add_settings_field('wdm_wpma_log','Log','wdm_wpma_render_option_log','wdm_wpma_settings_page','wdm_wpma_settings_section'); |
| 511 |
add_settings_field('wdm_wpma_alert_status','Alert enabled','wdm_wpma_render_option_alert_status','wdm_wpma_settings_page','wdm_wpma_settings_section'); |
| 512 |
add_settings_field('wdm_wpma_sensitivity','Alert Sensitivity','wdm_wpma_render_option_sensitivity','wdm_wpma_settings_page','wdm_wpma_settings_section'); |
| 513 |
} |
| 514 |
add_action('admin_init','wdm_wpma_settings_init'); |
| 515 |
|
| 516 |
function wdm_wpma_render_option_status() { |
| 517 |
global $wdm_wpma_options; |
| 518 |
if ($wdm_wpma_options['enabled'] == '1') { |
| 519 |
echo '<input type="checkbox" name="wdm_wpma_settings[enabled]" value="1" checked />'; |
| 520 |
} else { |
| 521 |
echo '<input type="checkbox" name="wdm_wpma_settings[enabled]" value="1" /> <span class="wdm-wpma-warning"> ← Check this to enable the Queue. </span> Otherwise this plugin won\'t have any effect on your website.'; |
| 522 |
} |
| 523 |
} |
| 524 |
|
| 525 |
function wdm_wpma_render_option_alert_status() { |
| 526 |
global $wdm_wpma_options; |
| 527 |
if ($wdm_wpma_options['alert_enabled'] == '1') { |
| 528 |
echo '<input type="checkbox" name="wdm_wpma_settings[alert_enabled]" value="1" checked />'; |
| 529 |
} else { |
| 530 |
echo '<input type="checkbox" name="wdm_wpma_settings[alert_enabled]" value="1" />'; |
| 531 |
} |
| 532 |
} |
| 533 |
|
| 534 |
function wdm_wpma_render_option_queue() { |
| 535 |
global $wdm_wpma_options; |
| 536 |
if ($wdm_wpma_options['queue_interval_unit'] == 'seconds') { |
| 537 |
$number = intval($wdm_wpma_options['queue_interval']); |
| 538 |
} else { |
| 539 |
$number = intval($wdm_wpma_options['queue_interval']) / 60; |
| 540 |
} |
| 541 |
|
| 542 |
echo 'Send max. <input name="wdm_wpma_settings[queue_amount]" type="number" min="1" value="'.esc_attr($wdm_wpma_options['queue_amount']).'" /> email(s) every <input name="wdm_wpma_settings[queue_interval]" type="number" min="1" value="'.esc_attr($number).'" />'; |
| 543 |
|
| 544 |
if ($wdm_wpma_options['queue_interval_unit'] == 'seconds') { |
| 545 |
echo '<select name="wdm_wpma_settings[queue_interval_unit]"><option value="minutes">minute(s)</option><option selected value="seconds">second(s)</option></select>'; |
| 546 |
} else { |
| 547 |
echo '<select name="wdm_wpma_settings[queue_interval_unit]"><option selected value="minutes">minute(s)</option><option value="seconds">second(s)</option></select>'; |
| 548 |
} |
| 549 |
|
| 550 |
echo ' by <i><a href="https://developer.wordpress.org/plugins/cron/" target="_blank">WP Cron</a></i>. '; |
| 551 |
|
| 552 |
} |
| 553 |
|
| 554 |
function wdm_wpma_render_option_log() { |
| 555 |
global $wdm_wpma_options; |
| 556 |
echo 'Delete Log entries older than <input name="wdm_wpma_settings[clear_queue]" type="number" min="1" value="'.esc_attr(intval($wdm_wpma_options['clear_queue']) / 24).'" /> days.'; |
| 557 |
} |
| 558 |
|
| 559 |
function wdm_wpma_render_option_sensitivity() { |
| 560 |
global $wdm_wpma_options; |
| 561 |
echo 'Send alert to <input type="text" name="wdm_wpma_settings[email]" value="'.esc_attr(sanitize_email($wdm_wpma_options['email'])).'" /> if more than <input name="wdm_wpma_settings[email_amount]" type="number" min="1" value="'.esc_attr(intval($wdm_wpma_options['email_amount'])).'" /> email(s) in the <a href="admin.php?page=wdm_wpma_mail_queue-tab-queue">Queue</a>.'; |
| 562 |
} |
| 563 |
|
| 564 |
|
| 565 |
/* *************************************************************** |
| 566 |
Alert WordPress User if last email in log could not be sent |
| 567 |
**************************************************************** */ |
| 568 |
function wdm_wpma_checkLogForErrors() { |
| 569 |
|
| 570 |
global $wpdb,$wdm_wpma_options; |
| 571 |
if ($wdm_wpma_options['enabled'] != '1') { return; } |
| 572 |
|
| 573 |
$tableName = $wpdb->prefix.$wdm_wpma_options['tableName']; |
| 574 |
$last_mail = $wpdb->get_row("SELECT * FROM `$tableName` WHERE `status` != 'queue' ORDER BY `id` DESC",'ARRAY_A'); |
| 575 |
if (!$last_mail) { return; } |
| 576 |
|
| 577 |
if ($last_mail['status'] == 'error') { |
| 578 |
if (current_user_can('manage_options')) { |
| 579 |
$notice = '<div class="notice notice-error is-dismissible">'; |
| 580 |
$notice .= '<h1>Attention: Your website has problems sending e-mails</h1>'; |
| 581 |
$notice .= '<p>This is an important message from your <i>Mail Queue</i> plugin. Please take a look at your <a href="admin.php?page=wdm_wpma_mail_queue-tab-log">Mail Log</a>. The last email(s) couldn\'t be sent properly.</p>'; |
| 582 |
$notice .= '<p>Last error message was: <b>'.$last_mail['info'].'</b></p>'; |
| 583 |
$notice .= '</div>'; |
| 584 |
echo $notice; |
| 585 |
} else if (current_user_can('edit_posts')) { |
| 586 |
$notice = '<div class="notice notice-error is-dismissible">'; |
| 587 |
$notice .= '<h1>Attention: Your website has problems sending e-mails</h1>'; |
| 588 |
$notice .= '<p>Please contact your Administrator. It seems that WordPress is not able to send emails.</p>'; |
| 589 |
$notice .= '<p>Last error message: <b>'.$last_mail['info'].'</b></p>'; |
| 590 |
$notice .= '</div>'; |
| 591 |
echo $notice; |
| 592 |
} |
| 593 |
} |
| 594 |
} |
| 595 |
add_action('admin_notices', 'wdm_wpma_checkLogForErrors'); |