PluginProbe
Zoho ZeptoMail / 3.2.0
Zoho ZeptoMail v3.2.0
trunk 1.0.1 1.0.2 1.0.3 1.0.4 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 3.0.1 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.2.0 3.2.1 3.2.2 3.2.3 All 35 releases
transmail / transMail.php

transMail.php in Zoho ZeptoMail 3.2.0, at transMail.php

1,458 lines 63.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Zoho ZeptoMail
4 Version: 3.2.0
5 Plugin URI: https://zeptomail.zoho.com/
6 Author: Zoho Mail
7 Author URI: https://www.zoho.com/zeptomail/
8 Description: Configure your Zoho ZeptoMail account to send email from your WordPress site.
9 Text Domain: ZeptoMail
10 Domain Path: /languages
11 */
12 /*
13 Copyright (c) 2015, ZOHO CORPORATION
14 All rights reserved.
15
16 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
17
18 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
19
20 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24 define('TRANSMAIL_PLUGIN_VERSION', '3.2.0');
25
26 function transmail_plugin_update_check() {
27 if ( ( ! get_option( 'transmail_plugin_version' ) || get_option( 'transmail_plugin_version' ) < '3.2.0' ) ) {
28 ztm_plugin_migration_logic();
29 ztm_plugin_activate();
30 update_option('transmail_plugin_version', TRANSMAIL_PLUGIN_VERSION);
31 }
32 }
33 add_action('plugins_loaded', 'transmail_plugin_update_check');
34
35 require_once plugin_dir_path( __FILE__ ) . 'includes/class-transmail-helper.php';
36
37 function ztm_zmplugin_script() {
38 wp_enqueue_style( 'zm_zohoTransMail_style', plugin_dir_url( __FILE__ ) . 'assets/css/style.css', false, '1.0.0' );
39 wp_enqueue_script('jquery');
40 wp_enqueue_script('my-plugin-script', plugin_dir_url(__FILE__) . 'index.js', array('jquery'), '1.0', true);
41 wp_localize_script('my-plugin-script', 'myAjax', array(
42 'ajaxurl' => admin_url('admin-ajax.php'),
43 'nonce' => wp_create_nonce('transmail_failed_email_nonce')
44 ));
45 wp_localize_script('my-plugin-script', 'transmailPluginData', array(
46 'plugin_url' => plugins_url('', __FILE__),
47 ));
48 }
49
50 add_action( 'admin_enqueue_scripts', 'ztm_zmplugin_script');
51
52 function zohoTransMail_deactivate() {
53 //--------------Clear the credentials once deactivated-------------------
54 global $wpdb;
55 delete_option('transmail_max_log_limit');
56 delete_option('transmail_additional_mail_agents');
57 delete_option('transmail_test_mail_case');
58 delete_option('transmail_connection_status');
59 delete_option('transmail_content_type');
60 delete_option('transmail_domain_name');
61 delete_option('transmail_mail_agents_count');
62
63 $table_name = $wpdb->prefix . 'transmail_failed_emails';
64 $wpdb->query("DROP TABLE IF EXISTS {$table_name}");
65
66 }
67
68 register_deactivation_hook( __FILE__, 'zohoTransMail_deactivate');
69
70
71
72 function transmail_integ_settings() {
73 add_menu_page (
74 'Welcome to ZeptoMail by Zoho Mail',
75 'Zoho ZeptoMail',
76 'manage_options',
77 'transmail-settings',
78 'transmail_settings_callback' ,
79 'dashicons-email'
80 );
81 add_submenu_page (
82 'transmail-settings',
83 'ZeptoMail by Zoho Mail',
84 'Configure Account',
85 'manage_options',
86 'transmail-settings',
87 'transmail_settings_callback'
88 );
89 add_submenu_page (
90 'transmail-settings',
91 'Send Mail - ZeptoMail by Zoho Mail',
92 'Send test email',
93 'manage_options',
94 'transmail-send-mail',
95 'transmail_send_mail_callback'
96 );
97 add_submenu_page (
98 'transmail-settings',
99 'Send Mail - ZeptoMail by Zoho Mail',
100 'Failed logs',
101 'manage_options',
102 'transmail-failed-logs',
103 'transmail_faild_mail_callback'
104 );
105 }
106
107 function ztm_plugin_activate() {
108 try {
109 global $wpdb;
110
111 $table_name = $wpdb->prefix . 'transmail_failed_emails';
112 $charset_collate = $wpdb->get_charset_collate();
113
114 $sql = "CREATE TABLE $table_name (
115 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
116 email_address VARCHAR(255) NOT NULL,
117 email_subject VARCHAR(255) NOT NULL,
118 email_body LONGTEXT NOT NULL,
119 headers TEXT NOT NULL,
120 failed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
121 retry_count INT(11) NOT NULL DEFAULT 0,
122 error_code VARCHAR(255) DEFAULT NULL,
123 error_description VARCHAR(255) DEFAULT NULL,
124 attachment_files TEXT DEFAULT NULL,
125 attachments TINYINT(1) NOT NULL DEFAULT 0,
126 PRIMARY KEY (id)
127 ) $charset_collate;";
128
129 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
130 dbDelta( $sql );
131 }
132 catch(Exception $e) {
133 error_log("error occured while activate plugin");
134 }
135 }
136 register_activation_hook(__FILE__, 'ztm_plugin_activate');
137
138
139 function ztm_plugin_migration_logic() {
140 $old_from_name = get_option('transmail_from_name');
141 $old_from_email_id = get_option('transmail_from_email_id');
142 $old_send_mail_token = base64_decode(get_option('transmail_send_mail_token'));
143
144 if ($old_from_name || $old_from_email_id || $old_send_mail_token) {
145 $mail_agents = array(
146 $old_from_email_id => array(
147 array(
148 "fromName" => $old_from_name,
149 "Token" => $old_send_mail_token,
150 "isDefault" => true
151 )
152 )
153 );
154
155 $json_string = json_encode($mail_agents);
156 update_option('transmail_additional_mail_agents', base64_encode($json_string), false);
157
158 delete_option('transmail_from_name');
159 delete_option('transmail_from_email_id');
160 delete_option('transmail_send_mail_token');
161 }
162 }
163
164 function transmail_admin_notice__success() {
165
166 if (! get_option( 'zmail_plugin_installed' ) ) {
167 ?>
168
169 <div class="notice notice-info is-dismissible" style="display: flex; align-items: center;">
170 <img src="<?php echo esc_url(plugins_url('assets/images/zeptomail.svg',__FILE__)) ?>" title="Zoho" alt="Zoho" width="140" style="margin-right: 10px;">
171
172 <p style="margin: 0;">
173 <?php _e('No more worrying about failed emails. Our latest update allows you to easily retry failed deliveries. Check it out in our plugin settings!', 'my-plugin-textdomain'); ?>
174 </p>
175 </div>
176 <?php
177 update_option( 'zmail_plugin_installed', true );
178 }
179
180 }
181 add_action( 'admin_notices', 'transmail_admin_notice__success' );
182
183 function transmail_faild_mail_callback() {
184 $json_string = get_option('transmail_additional_mail_agents');
185
186 $array = json_decode(base64_decode($json_string), true);
187
188 $connection_details = get_option('transmail_connection_status');
189 $connection_status = json_decode($connection_details, true);
190 $connected_emails = [];
191
192 $connected = false;
193 if (is_array($array) && count($array) > 0) {
194 $keys = array_keys($array);
195 if ($connection_status) {
196 foreach ($keys as $email) {
197 $isConnected = true;
198 foreach ($connection_status as $connection) {
199 if (isset($connection['email']) && $connection['email'] === $email) {
200 $isConnected = false;
201 break;
202 }
203 }
204
205 if ($isConnected) {
206 $connected_emails[] = $email;
207 }
208 }
209 }
210 else {
211 $connected = true;
212 }
213 }
214
215 // if((empty($connected_emails) && !$connected)){
216 // echo '<div class="error"><p><strong>'.esc_html__('Please configure your account to retry failed email.').'</strong></p></div>'."\n";
217 // }
218
219
220
221 $length = 0;
222 if (is_array($array)) {
223 $length = count($array);
224 }
225
226 if($length > 0){
227 if((empty($connected_emails) && !$connected)){
228 echo '<div class="error"><p><strong>'.esc_html__('Please configure your account to retry failed email.').'</strong></p></div>'."\n";
229 }
230 if(is_admin() || current_user_can('administrator'))
231 {
232 global $wpdb;
233 $table_name = $wpdb->prefix . 'transmail_failed_emails';
234
235 $results = $wpdb->get_results("SELECT * FROM $table_name", ARRAY_A);
236
237 ?>
238 <head>
239 <meta charset="UTF-8">
240 <title>Zoho Mail</title>
241 </head>
242 <form method="post" enctype="multipart/form-data" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
243 <?php wp_nonce_field('transmail_send_mail_nonce'); ?>
244 <body>
245 <div class="zm-page">
246 <div class="zm-page-header">
247 <img src=<?php echo esc_url(plugins_url('assets/images/zeptomail.svg',__FILE__))?> title="Zoho" alt="Zoho" width="162">
248 </div>
249 <div class="zm-page-content">
250 <div class="zm-page-content-title-wrapper">
251 <h3 class="zm-page-content-title">Email logs - Failed emails</h3>
252 </div>
253 <div>
254 <p class="zm-page-content-text">View the logs for emails that could not be delivered using the Zoho ZeptoMail plugin. You can retry delivery of these emails from here.</p>
255 </br></div>
256 <div class="zm-page-content-table-wrapper">
257 <table class="zm-page-content-table">
258 <thead class="zm-page-content-table-header">
259 <tr>
260 <th></th>
261 <th>Time</th>
262 <th>To address</th>
263 <th>Subject</th>
264 <th>Message</th>
265 <th>Attachments</th>
266 <th>Error code</th>
267 <th>Error description</th>
268 <th></th>
269 <th>
270 <div class="zm-page-content-failed-log-filter">
271 <svg id="Layer_2" data-name="Layer 2" width="14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:none;}</style></defs><path id="_07" data-name=" 07" d="M14.05,1.06H2a1,1,0,0,0-.8,1.58L5.82,7.8a.82.82,0,0,1,.2.5V14a1,1,0,0,0,1,1,.7.7,0,0,0,.49-.2l2-1.58a1,1,0,0,0,.49-.9v-4c0-.2,0-.4.2-.5l4.66-5.16a1,1,0,0,0-.79-1.58ZM9.39,7.11h0A2,2,0,0,0,9,8.3v4H9L7,14V8.3a2,2,0,0,0-.4-1.19h0L2.05,2.05H14Z"/><rect class="cls-1" x="1" y="1" width="14" height="14" width="16px;"/></svg>
272 <div class="zm-page-content-failed-log-filter-list-wrapper">
273 <ul class="zm-page-content-failed-log-filter-list">
274 <li class="zm-page-content-failed-log-filter-list-item" data-filter="ALL">ALL</li>
275 <li class="zm-page-content-failed-log-filter-list-item" data-filter="SERR_157">SERR_157</li>
276 <li class="zm-page-content-failed-log-filter-list-item" data-filter="SM_111">SM_111</li>
277 <li class="zm-page-content-failed-log-filter-list-item" data-filter="SM_147">SM_147</li>
278 </ul>
279 </div>
280 </div>
281 </th>
282 </tr>
283 </thead>
284 <tbody class="zm-page-content-table-body" id="data-table">
285 <?php
286 if ($results) {
287 foreach ($results as $row) {
288 ?>
289 <tr id="row-<?php echo $row['id']; ?>">
290 <td>
291 <div class="zm-page-content-table-row-checkbox">
292 <input type="checkbox" class="row-checkbox" data-id="<?php echo $row['id']; ?>">
293 </div>
294 </td>
295 <td><div class="zm-page-content-table-msg"><?php echo $row['failed_at'] ?></div></td>
296 <td><div class="zm-page-content-table-msg"><?php echo $row['email_address'] ?></div></td>
297 <td><div class="zm-page-content-table-msgs"><?php echo $row['email_subject'] ?></div></td>
298 <td class="zm-page-content-table-tdd"><div class="zm-page-content-table-msgs"><?php echo $row['email_body'] ?></div></td>
299 <td>
300 <div class="zm-page-content-table-msg">
301 <?php
302 if ($row['attachments'] == 0) {
303 echo 'No files';
304 } else {
305 $attachment_files_raw = $row['attachment_files'];
306 $attachment_paths = json_decode($attachment_files_raw, true);
307
308 $att_count = 0;
309 if (!empty($attachment_paths) && is_array($attachment_paths)) {
310 foreach ($attachment_paths as $attachment) {
311 $att_count++;
312 }
313 }
314 //else {
315 // error_log("list No attachments available.");
316 //}
317
318 if($att_count > 0) {
319 ?><span><?php echo $att_count;?> Attachments</span>
320 <i title="File does not exist. The attachment may be unavailable or missing during retry." style="color:red;">&#9432;</i>
321 <?php
322 }
323 else {
324 echo "No files";
325 }
326 }
327 ?>
328 </div>
329 </td>
330 <td><div class="zm-page-content-table-msg"><?php echo $row['error_code'] ?></div></td>
331 <td><div class="zm-page-content-table-msg"><?php echo $row['error_description'] ?></div></td>
332 <td>
333 <button class="retry-button no-border no-background" title="Resend log" data-id="<?php echo $row['id']; ?>"
334 <?php if(empty($connected_emails) && !$connected): ?>
335 disabled
336 <?php endif; ?>>
337 <svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" style="width:16px;" fill="#264DED">
338 <path d="M2,8a.5.5,0,1,1-1,0A7,7,0,0,1,13,3.12V1.55a.5.5,0,0,1,1,0v3a.5.5,0,0,1-.5.49h-3a.5.5,0,0,1,0-1h2A6,6,0,0,0,2,8Zm12.41-.5A.5.5,0,0,0,14,8,6,6,0,0,1,3.54,12h2a.5.5,0,0,0,0-1h-3a.5.5,0,0,0-.5.49v3a.5.5,0,0,0,1,0V12.88A7,7,0,0,0,15,8a.5.5,0,0,0-.5-.5Z"/></svg>
339 </button>
340 </td>
341 <td>
342 <button class="delete-button no-border no-background" title="Delete log" data-id="<?php echo $row['id']; ?>">
343 <div class="zm-page-content-trash-icon">
344 <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
345 viewBox="0 0 14 14" style="width:16px;" fill="#777777" style="enable-background:new 0 0 14 14;" xml:space="preserve" fill="#777777">
346 <path d="M12.5,2H10V1.6C10,0.7,9.3,0,8.5,0H5.5C4.7,0,4,0.7,4,1.6V2H1.5C1.2,2,1,2.2,1,2.5S1.2,3,1.5,3H2v8.8C2,13.1,3.3,14,4.4,14
347 h5.1c1.1,0,2.4-0.9,2.4-2.2V3h0.5C12.8,3,13,2.8,13,2.5S12.8,2,12.5,2z M5,1.6C5,1.3,5.2,1,5.5,1h2.9C8.8,1,9,1.3,9,1.6V2H5V1.6z
348 M11,11.8c0,0.7-0.8,1.2-1.4,1.2H4.4C3.8,13,3,12.4,3,11.8V3h8V11.8z M5,9.5v-4C5,5.2,5.2,5,5.5,5S6,5.2,6,5.5v4
349 C6,9.8,5.8,10,5.5,10S5,9.8,5,9.5z M8,9.5v-4C8,5.2,8.2,5,8.5,5S9,5.2,9,5.5v4C9,9.8,8.8,10,8.5,10S8,9.8,8,9.5z"/>
350 </svg>
351 </div>
352 </button>
353 </td>
354 </tr>
355 <?php } }
356 else {
357 ?>
358 <tr>
359 <td></td>
360 <td></td>
361 <td></td>
362 <td></td>
363 <td></td>
364 <td>No failed logs found</td>
365 <td></td>
366 <td></td>
367 <td></td>
368 <td></td>
369 </tr><?php
370 }?>
371 </tbody>
372 </table>
373 </div>
374 </div>
375 </div>
376 </body>
377 </form>
378 <?php
379 }
380 }
381 else {
382 echo '<div class="error"><p><strong>'.__('Configure Your Account').'</strong></p></div>'."\n";
383 }
384
385 }
386
387 function send_test_email($fromEmail, $fromName, $token) {
388 $to = $fromEmail;
389 $subject = 'ZeptoMail plugin for WordPress - Test Email';
390 $message = '<html><body><p>Hello,</p><br><br><p>We\'re glad you\'re using our ZeptoMail plugin. This is a test email to verify your configuration details.
391 Thank you for choosing ZeptoMail for your transactional email needs.<p><br><br>Team ZeptoMail</body></html>';
392
393 $headers = array(
394 'From: ' . $fromName . ' <' . $fromEmail . '>',
395 'Authorization' => $token,
396 'User-Agent' => 'Zepto_WordPress',
397 'Content-Type: text/html; charset=UTF-8'
398 );
399 $sent = wp_mail($to, $subject, $message, $headers, null);
400 return $sent;
401 }
402
403 function update_log_limit($transmail_max_log_limit) {
404 global $wpdb;
405 $table_name = $wpdb->prefix . 'transmail_failed_emails';
406
407 $row_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
408
409 $row_count = (int) $row_count;
410
411 $max_log_count = $transmail_max_log_limit;
412 if ($row_count > $max_log_count) {
413 $limit = $row_count - $max_log_count + 1;
414
415 $ids_to_delete = $wpdb->get_col(
416 $wpdb->prepare(
417 "SELECT id FROM $table_name ORDER BY id ASC LIMIT %d",
418 $limit
419 )
420 );
421
422 if (!empty($ids_to_delete)) {
423 $ids_placeholder = implode(',', array_fill(0, count($ids_to_delete), '%d'));
424 $deleted = $wpdb->query(
425 $wpdb->prepare(
426 "DELETE FROM $table_name WHERE id IN ($ids_placeholder)",
427 ...$ids_to_delete
428 )
429 );
430 /*
431 if ($deleted !== false) {
432 error_log("Successfully deleted " . $limit . " old records.");
433 } else {
434 error_log("Failed to delete old records.");
435 }*/
436 }
437 }
438 }
439
440 function transmail_settings_callback() {
441
442 if (isset($_POST['transmail_submit']) && !empty($_POST)) {
443 $nonce = sanitize_text_field($_REQUEST['_wpnonce']);
444 if (!wp_verify_nonce($nonce, 'transmail_settings_nonce')) {
445 echo '<div class="error"><p><strong>'.esc_html__('Reload the page again').'</strong></p></div>'."\n";
446 } else {
447 $transmail_domain_name = sanitize_text_field($_POST['transmail_domain_name']);
448 $transmail_content_type = sanitize_text_field($_POST['transmail_content_type']);
449 $transmail_max_log_limit = absint($_POST['transmail_max_log_limit']);
450 if ( $transmail_max_log_limit < 1 ) {
451 $transmail_max_log_limit = 1;
452 } elseif ( $transmail_max_log_limit > 100 ) {
453 $transmail_max_log_limit = 100;
454 }
455 }
456 update_option('transmail_content_type',$transmail_content_type, false);
457 update_option('transmail_domain_name',$transmail_domain_name, false);
458 update_option( 'transmail_max_log_limit', $transmail_max_log_limit );
459
460 update_log_limit($transmail_max_log_limit);
461
462
463 $tempDataCount = isset($_POST['tempDataCount']) ? intval($_POST['tempDataCount']) : 0;
464 $defaultData = isset($_POST['defaultData']) ? intval($_POST['defaultData']) : 1;
465
466 $temp_data = isset($_POST['tempData']) ? $_POST['tempData'] : array();
467 //error_log("tempda: " . print_r($temp_data, true));
468
469 $temp_data = json_decode($temp_data);
470
471 //error_log("tempda: " . print_r($temp_data, true));
472 //error_log("defaultData: " . $defaultData);
473
474 $json_data = array();
475 $errors = array();
476 for ($i = 1; $i <= $tempDataCount; $i++) {
477 $fromName = isset($_POST["transmail_from_name_$i"]) ? sanitize_text_field($_POST["transmail_from_name_$i"]) : '';
478 $fromEmail = isset($_POST["transmail_from_email_id_$i"]) ? sanitize_email($_POST["transmail_from_email_id_$i"]) : '';
479 $token = isset($_POST["transmail_send_mail_token_$i"]) ? sanitize_text_field($_POST["transmail_send_mail_token_$i"]) : '';
480
481 if ($fromEmail) {
482 $json_data[$fromEmail][] = array(
483 "fromName" => $fromName,
484 "Token" => $token,
485 "isDefault" => $defaultData == $i ? true : false
486 );
487
488 if (!send_test_email($fromEmail, $fromName, $token)) {
489 $data = json_decode(get_option('transmail_test_mail_case'));
490 if($data != ''){
491 $message= ''.$data->error->details[0]->message;
492 $reason = '';
493 if(!empty($data->error)) {
494 if(!empty($data->error->details[0]->message) && strcmp($data->error->details[0]->message,"Invalid API Token found") == 0 ) {
495 $reason = "Invalid API Token found";
496 }
497 if(!empty($data->error->details[0]->target) && strcmp($data->error->details[0]->target,"from") == 0 ) {
498 $reason = "Invalid From address";
499 }
500 $errors[] = array(
501 'email' => $fromEmail,
502 'field' => "transmail_from_email_id_$i",
503 'message' => 'Configuration Failed for :' . esc_html($fromEmail),
504 'reason' => $reason
505 );
506 }
507 } else {
508 $errors[] = array(
509 'email' => $fromEmail,
510 'field' => "transmail_from_email_id_$i",
511 'message' => 'Configuration Failed for :' . esc_html($fromEmail),
512 'reason' => 'Internal Server Error'
513 );
514 }
515 }
516 }
517 }
518 $json_string = json_encode($json_data);
519
520 echo '<div class="updated"><p><strong>'.esc_html__('Plugin Configuration Settings has been saved successfully!').'</strong></p></div>'."\n";
521
522 $json_error_data = json_encode($errors);
523 update_option('transmail_connection_status', $json_error_data, false);
524 update_option('transmail_additional_mail_agents',base64_encode($json_string), false);
525 }
526
527 global $wpdb;
528 $option_name = 'transmail_additional_mail_agents';
529 $table_name = $wpdb->prefix . 'options';
530 $result = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM $table_name WHERE option_name = %s", $option_name));
531 if ($result !== null && $result !== '') {
532 $mail_agents = json_decode(base64_decode($result), true);
533 $length = count($mail_agents);
534
535 update_option('transmail_mail_agents_count', $length, false);
536 }else {
537 $mail_agents = false;
538 }
539 $connection_details = get_option('transmail_connection_status');
540 $connection_status = json_decode($connection_details, true);
541 ?>
542 <head>
543 <meta charset="UTF-8">
544 <title>ZeptoMail by Zoho Mail</title>
545 </head>
546 <body>
547 <?php
548 $temp_data = [];
549
550 if ($mail_agents) {
551 $mail_agents_keys = array_keys($mail_agents);
552 $mail_agents_values = array_values($mail_agents);
553
554 for ($i = 0; $i < count($mail_agents_keys); $i++) {
555 $email = $mail_agents_keys[$i];
556 $agents = $mail_agents_values[$i];
557
558 foreach ($agents as $index => $agent) {
559 $isConnected = true;
560 $reason = '';
561 if ($connection_status) {
562 foreach ($connection_status as $connection) {
563 if (isset($connection['email']) && $connection['email'] === $email) {
564 $isConnected = false;
565 $reason = $connection['reason'];
566 break;
567 }
568 }
569 }
570
571 $temp_data[] = [
572 'fromName' => $agent['fromName'],
573 'fromEmail' => $email,
574 'token' => $agent['Token'],
575 "isDefault" => isset($agent['isDefault']) ? $agent['isDefault'] : false,
576 'isConnected' => $isConnected,
577 'reason' => $reason,
578 ];
579 }
580 }
581 }
582
583 echo '<script type="text/javascript">';
584 echo 'var tempData = ' . json_encode($temp_data) . ';';
585 echo '</script>';
586 ?>
587 <form method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>" onsubmit="return validateForm()">
588 <?php wp_nonce_field('transmail_settings_nonce'); ?>
589 <div class="zm-page">
590 <div class="zm-page-header">
591 <img src=<?php echo esc_url(plugins_url('assets/images/zeptomail.svg',__FILE__))?> title="Zoho" alt="Zoho" width="162" style="margin-right: 15px;">
592 </div>
593 <div class="zm-page-content">
594 <div class="zm-page-content-title-wrapper">
595 <h3 class="zm-page-content-title">Welcome to Zoho ZeptoMail!</h3>
596 <p class="zm-page-content-text">Thank you for choosing Zoho ZeptoMail as your transactional email sending service. Read our <a class="zm_a" href=<?php echo esc_url("https://www.zoho.com/zeptomail/help/wordpress-plugin.html")?> target="_blank">help documentation</a> to know about our plugin in detail.</p>
597 </div>
598 <div class="form-row-wrapper">
599 <div class="form-row">
600 <label class="form--label">Where is your account hosted?</label>
601 <select class="form--input form--input--select" name="transmail_domain_name">
602 <option value="zoho.com" <?php if(get_option('transmail_domain_name') == "zoho.com") {?> selected="true"<?php } ?>>zeptomail.zoho.com</option>
603 <option value="zoho.eu" <?php if(get_option('transmail_domain_name') == "zoho.eu") {?> selected="true"<?php } ?>>zeptomail.zoho.eu</option>
604 <option value="zoho.in" <?php if(get_option('transmail_domain_name') == "zoho.in") {?> selected="true"<?php }?>>zeptomail.zoho.in</option>
605 <option value="zoho.com.cn" <?php if(get_option('transmail_domain_name') == "zoho.com.cn") {?>selected="true"<?php }?>>zeptomail.zoho.com.cn</option>
606 <option value="zoho.com.au" <?php if(get_option('transmail_domain_name') == "zoho.com.au"){?>selected="true"<?php }?>>zeptomail.zoho.com.au</option>
607 <option value="zohocloud.ca" <?php if(get_option('transmail_domain_name') == "zohocloud.ca"){?>selected="true"<?php }?>>zeptomail.zohocloud.ca</option>
608 <option value="zoho.sa" <?php if(get_option('transmail_domain_name') == "zoho.sa"){?>selected="true"<?php }?>>zeptomail.zoho.sa</option>
609 </select><br>
610 <small class="form-text">The region where your ZeptoMail account is hosted. The URL displayed on logging in.</small>
611 </div>
612 <div class="form-row">
613 <label class="form--label">Email format </label>
614 <select class="form--input form--input--select" name="transmail_content_type">
615 <option value="plaintext" <?php if(get_option('transmail_content_type') == "plaintext") {?> selected="true"<?php } ?>>Plaintext</option>
616 <option value="html" <?php if(get_option('transmail_content_type') == "html") {?> selected="true"<?php } ?>>HTML</option>
617 </select><br>
618 <small class="form-text">The preferred format for the body of your email.</small>
619 </div>
620 <div id="mail-agents">
621 <br>
622 <div class="form-row-group">
623 <div class="form-row-group-title">
624 <label class="form--label" style="width:158px" title="The sender name displayed on the emails sent from the plugin."> From Name</label></div>
625 <div class="form-row-group-title">
626 <label class="form--label" style="width:158px" title="The email address that will be used to send emails."> From address</label></div>
627 <div class="form-row-group-title">
628 <label class="form--label" style="width:158px" title="Send mail token generated in the relevant Mail Agent in ZeptoMail."> Send mail token</label></div>
629 </div>
630 <div id="form-container"></div>
631 </div>
632 <div class="form-row">
633 <h3 style="
634 margin-block: 0 12px;
635 font-size: 14px;
636 ">Logs limit</h3>
637 <label style="font-size: 14px;">Only keep &nbsp;<input type="number" name="transmail_max_log_limit" value="<?php echo esc_attr( get_option('transmail_max_log_limit', 50) ); ?>" min="1" font-size="14px" max="100" maxlength="3" required spellcheck="false" style="
638 padding-inline-end: 0;
639 border: 1px solid #E2E2E2;
640 outline: none;
641 width: 60px;
642 font-size: 14px;
643 ">&nbsp; recent logs
644 </label></div>
645 <input type="hidden" name="tempDataCount" id="tempDataCount" value="0">
646 <input type="hidden" name="tempData" id="tempData" value=''>
647 <input type="hidden" name="defaultData" id="defaultData" value="1">
648 <div class="form-row form-row-btn">
649 <input type="submit" name="transmail_submit" id="transmail_submit" class="btn" value="Save and test configuration"/>
650 </div>
651 </div>
652 </div>
653 </div>
654 </form>
655 </body>
656 <?php
657
658
659 }
660 add_action('admin_menu','transmail_integ_settings');
661
662
663 function transmail_send_mail_callback() {
664 $json_string = get_option('transmail_additional_mail_agents');
665
666 $array = json_decode(base64_decode($json_string), true);
667
668 $connection_details = get_option('transmail_connection_status');
669 $connection_status = json_decode($connection_details, true);
670 $connected_emails = [];
671
672 $connected = false;
673 if(is_array($array) && count($array) > 0){
674 $keys = array_keys($array);
675
676 if ($connection_status) {
677 foreach ($keys as $email) {
678 $isConnected = true;
679 foreach ($connection_status as $connection) {
680 if (isset($connection['email']) && $connection['email'] === $email) {
681 $isConnected = false;
682 break;
683 }
684 }
685 if ($isConnected) {
686 $connected_emails[] = $email;
687 }
688 }
689 } else {
690 $connected = true;
691 foreach ($keys as $email) {
692 $connected_emails[] = $email;
693 }
694 }
695 }
696
697 if ((!empty($connected_emails) || $connected) && is_array($array)) {
698 $length = count($array);
699 if($length > 0) {
700 if(is_admin() || current_user_can('administrator')) {
701 if(isset($_POST['transmail_send_mail_submit']) && !empty($_POST)){
702 $nonce = sanitize_text_field($_REQUEST['_wpnonce']);
703 if (!wp_verify_nonce($nonce, 'transmail_send_mail_nonce')) {
704 echo '<div class="error"><p><strong>'.esc_html__('Reload the page again').'</strong></p></div>'."\n";
705 } else {
706 if($length < 1){
707 echo '<div class="error"><p><strong>'.esc_html__('Account not Configured').'</strong></p></div>'."\n";
708 }
709 $from_address = sanitize_email($_POST['transmail_test_from_address']);
710 $toAddressTest = sanitize_email($_POST['transmail_to_address']);
711 $subjectTest = sanitize_text_field($_POST['transmail_subject']);
712 $contentTest = sanitize_text_field($_POST['transmail_content']);
713
714 $json_string = get_option('transmail_additional_mail_agents');
715
716 $json_data = json_decode(base64_decode($json_string), true);
717
718 $keys = array_keys($json_data);
719
720 if (isset($keys) && isset($keys[$from_address])) {
721 $result['fromName'] = $keys[$from_address]['fromName'];
722 $result['Token'] = $keys[$from_address]['Token'];
723 }
724
725 $headers = array('From: ' . $from_address);
726
727 if(wp_mail($toAddressTest,$subjectTest,$contentTest, $headers, null)) {
728 echo '<div class="updated"><p><strong>'.esc_html__('Mail Sent Successfully').'</strong></p></div>'."\n";
729 } else {
730 $data = json_decode(get_option('transmail_test_mail_case'));
731 $message= ''.$data->error->details[0]->message;
732 $reason = '';
733 $errors = array();
734 if(!empty($data->error)) {
735 if(!empty($data->error->details[0]->message) && strcmp($data->error->details[0]->message,"Invalid API Token found") == 0 ) {
736 $reason = "Invalid API Token found";
737 }
738 if(!empty($data->error->details[0]->target) && strcmp($data->error->details[0]->target,"from") == 0 ) {
739 $reason = "Invalid From address";
740 } else if(!empty($data->error->details[0]->message)){
741 $reason = $data->error->details[0]->message;
742 }
743 $errors[] = array(
744 'field' => $from_address,
745 'message' => 'Configuration Failed for :' . esc_html($from_address),
746 'reason' => $reason
747 );
748 }
749 echo '<div class="error"><p><strong>'.esc_html__('Mail Sending Failed').'</strong></p></div>'."\n";
750 foreach ($errors as $error) {
751 echo '<div class="error"><p><strong>Error: '.esc_html($error['reason']).'</strong></p></div>'."\n";
752 }
753 }
754 }
755 }
756 }
757 } else {
758 echo "The decoded value is not an array.";
759 }
760
761 ?>
762 <head>
763 <meta charset="UTF-8">
764 <title>Zoho Mail</title>
765 </head>
766
767 <form method="post" enctype="multipart/form-data" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
768 <?php wp_nonce_field('transmail_send_mail_nonce'); ?>
769 <body>
770 <div class="zm-page">
771 <div class="zm-page-header">
772 <img src=<?php echo esc_url(plugins_url('assets/images/zeptomail.svg',__FILE__))?> title="Zoho" alt="Zoho" width="162">
773 </div>
774 <div class="zm-page-content">
775 <div class="zm-page-content-title-wrapper">
776 <h3 class="zm-page-content-title">Send test email</h3>
777 <p class="zm-page-content-text">Test email sending from the Zoho ZeptoMail plugin by sending a test email to the recipient of your choice.</p>
778 </div>
779
780 <div class="form-row-wrapper">
781 <div class="form-row">
782 <label class="form--label">From address</label>
783 <select class="form--input" name="transmail_test_from_address" required="required">
784 <?php
785 if (!empty($connected_emails)) {
786 foreach ($connected_emails as $email) {
787 echo '<option value="' . esc_attr($email) . '">' . esc_html($email) . '</option>';
788 }
789 } else {
790 echo '<option value="">No account configured</option>';
791 }
792 ?>
793 </select>
794 </div>
795 <div class="form-row">
796 <label class="form--label">To address</label>
797 <input type="text" class="form--input" name="transmail_to_address" required = "required" />
798 </div>
799 <div class="form-row">
800 <label class="form--label">Subject</label>
801 <textarea type="text" class="form--input" id="input-subject" name="transmail_subject" placeholder="Enter the subject"></textarea>
802 </div>
803 <div class="form-row">
804 <label class="form--label">Content</label>
805 <textarea type="text" class="form--input" id="input-content" name="transmail_content" placeholder="Enter/paste the content"></textarea>
806 </div>
807 <div class="form-row form-row-btn"> <input type="submit" class = "btn" name="transmail_send_mail_submit" id="transmail_send_mail_submit" value="<?php _e('Send test email');?>">
808 </div>
809 </div>
810 </div>
811 </div>
812 </body>
813 </form>
814 <?php
815 }
816 else {
817 echo '<div class="error"><p><strong>'.__('Configure Your Account').'</strong></p></div>'."\n";
818 }
819 }
820
821
822 function insert_failed_email($from_address, $email_address, $email_subject, $email_body, $responseArray, $attachments = array()) {
823 global $wpdb;
824 $table_name = $wpdb->prefix . 'transmail_failed_emails';
825
826
827 $errorCode = $responseArray[0]['code'];
828 $errorMessage = $responseArray[0]['message'];
829
830 $attachment_paths = !empty($attachments) ? json_encode($attachments) : '';
831
832 $wpdb->insert(
833 $table_name,
834 array(
835 'headers' => $from_address,
836 'email_address' => $email_address,
837 'email_subject' => $email_subject,
838 'email_body' => $email_body,
839 'attachments' => !empty($attachments)? 1: 0,
840 'error_code' => $errorCode,
841 'error_description' => $errorMessage,
842 'attachment_files' => $attachment_paths
843 ),
844 array(
845 '%s',
846 '%s',
847 '%s',
848 '%s',
849 '%d',
850 '%s',
851 '%s',
852 '%s'
853 )
854 );
855
856 $row_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
857
858 $row_count = (int) $row_count;
859
860 $max_log_count = intval(get_option('transmail_max_log_limit', 100));
861 if ($row_count > $max_log_count) {
862 $limit = $row_count - $max_log_count;
863
864 $ids_to_delete = $wpdb->get_col(
865 $wpdb->prepare(
866 "SELECT id FROM $table_name ORDER BY id ASC LIMIT %d",
867 $limit
868 )
869 );
870
871 if (!empty($ids_to_delete)) {
872 $ids_placeholder = implode(',', array_fill(0, count($ids_to_delete), '%d'));
873 $deleted = $wpdb->query(
874 $wpdb->prepare(
875 "DELETE FROM $table_name WHERE id IN ($ids_placeholder)",
876 ...$ids_to_delete
877 )
878 );
879 /*
880 if ($deleted !== false) {
881 error_log("Successfully deleted " . $limit . " old records.");
882 } else {
883 error_log("Failed to delete old records.");
884 }*/
885 }
886 }
887 }
888
889
890 if(!function_exists('wp_mail')) {
891 function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {
892
893 $atts = apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) );
894
895 if ( isset( $atts['to'] ) ) {
896 $to = $atts['to'];
897 }
898 if ( !is_array( $to ) ) {
899 $to = explode( ',', $to );
900 }
901 if ( isset( $atts['subject'] ) ) {
902 $subject = $atts['subject'];
903 }
904 if ( isset( $atts['message'] ) ) {
905 $message = $atts['message'];
906 }
907 if ( isset( $atts['headers'] ) ) {
908 $headers = $atts['headers'];
909 } else {
910 $headers = '';
911 }
912 if ( isset( $atts['attachments'] ) ) {
913 $attachments = $atts['attachments'];
914 }
915 if (!is_array($attachments)) {
916 $attachments = $attachments ? array($attachments) : array();
917 }
918 foreach ($attachments as &$attachment) {
919 $attachment = str_replace("\r\n", "\n", $attachment);
920 }
921
922 $attachments = implode("\n", $attachments);
923
924 $content_type = null;
925 $cc = $bcc = $reply_to = array();
926 $dynamicFrom = array();
927 $from_email = '';
928 if ( empty( $headers ) ) {
929 $headers = array('');
930 } else {
931
932 if ( !is_array( $headers ) ) {
933 $tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) );
934 } else {
935 $tempheaders = $headers;
936 }
937
938 if (is_array($tempheaders)) {
939 $headerString = implode("\n", $tempheaders);
940 } else {
941 $headerString = (string) $tempheaders;
942 }
943
944 //error_log("Header value:\n" . $headerString);
945
946
947 // Iterate through the raw headers
948 foreach ( (array) $tempheaders as $header ) {
949 if ( strpos($header, ':') === false ) {
950 if ( false !== stripos( $header, 'boundary=' ) ) {
951 $parts = preg_split('/boundary=/i', trim( $header ) );
952 $boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) );
953 }
954 continue;
955 }
956 // Explode them out
957 list( $name, $content ) = explode( ':', trim( $header ), 2 );
958
959 // Cleanup crew
960 $name = trim( $name );
961 $content = trim( $content );
962 $content_type = null;
963 $from = array();
964 //$from_email = '';
965 if (stripos($name, 'content-type') !== false) {
966 $name = 'content-type';
967 }
968 switch ( strtolower($name) ) {
969 case 'content-type':
970 if ( strpos( $content, ';' ) !== false ) {
971 list( $type, $charset_content ) = explode( ';', $content );
972 $content_type = trim( $type );
973 if ( false !== stripos( $charset_content, 'charset=' ) ) {
974 $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset_content ) );
975 } elseif ( false !== stripos( $charset_content, 'boundary=' ) ) {
976 $boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset_content ) );
977 $charset = '';
978 }
979 // Avoid setting an empty $content_type.
980 } elseif ( '' !== trim( $content ) ) {
981 $content_type = trim( $content );
982 }
983 break;
984 case 'cc':
985 $cc = array_merge( (array) $cc, explode( ',', $content ) );
986 break;
987 case 'bcc':
988 $bcc = array_merge( (array) $bcc, explode( ',', $content ) );
989 break;
990 case 'reply-to':
991 $reply_to = array_merge( (array) $reply_to, explode( ',', $content ) );
992 break;
993 case 'from':
994 $dynamicFrom = array_merge( (array) $from, explode( ',', $content ) );
995
996 $bracket_pos = strpos( $content, '<' );
997 if ( false !== $bracket_pos ) {
998 // Text before the bracketed email is the "From" name.
999 if ( $bracket_pos > 0 ) {
1000 $from_name = substr( $content, 0, $bracket_pos );
1001 $from_name = str_replace( '"', '', $from_name );
1002 $from_name = trim( $from_name );
1003 }
1004
1005 $from_email = substr( $content, $bracket_pos + 1 );
1006 $from_email = str_replace( '>', '', $from_email );
1007 $from_email = trim( $from_email );
1008
1009 // Avoid setting an empty $from_email.
1010 } elseif ( '' !== trim( $content ) ) {
1011 $from_email = trim( $content );
1012 //echo '<div class="error"><p><strong> '.esc_html__('there is no lessthan char').''.$content.'</strong></p></div>'."\n";
1013 //echo '<div class="error"><p><strong> '.$from_email.'</strong></p></div>'."\n";
1014 }
1015 //echo '<div class="error"><p><strong> from name is '.esc_html__($from_name).'</strong></p></div>'."\n";
1016 break;
1017 default:
1018 $headers[trim( $name )] = trim( $content );
1019 break;
1020 }
1021 }
1022 }
1023
1024 //echo '<div class="error"><p><strong>'.esc_html__('inside wp-mail function()').'</strong></p></div>'."\n";
1025 $content_type = apply_filters( 'wp_mail_content_type', $content_type );
1026 $data = array();
1027 $token = '';
1028 $fromAddress = array();
1029 if (!empty($from_name)) {
1030 $fromAddress['name'] = $from_name;
1031 } else {
1032 //echo "inside else part of from address:";
1033 $json_string = get_option('transmail_additional_mail_agents');
1034
1035 // Decode JSON string back into array
1036 $json_data = json_decode(base64_decode($json_string), true);
1037
1038
1039 // Use the data as needed
1040 //print_r($json_data);
1041
1042 $keys = array_keys($json_data);
1043
1044 //echo "json_Data: " .$json_string;
1045
1046
1047 // Check if the key exists and extract the details
1048 if (isset($keys) && isset($keys[$from_email])) {
1049 //echo " inside the from email";
1050 $fromAddress['name'] = $keys[$from_email]['fromName'];
1051 }
1052 //$fromAddress['name'] = get_option('transmail_from_name');
1053 }
1054 //error_log('keys form:'.$fromAddress['name']);
1055
1056 if (!empty($dynamicFrom))
1057 {
1058 $dynpos = false;
1059 $dynpos = strpos($dynamicFrom[0], '<');
1060 if($dynpos !== false) {
1061 $dynad = substr($dynamicFrom[0], $dynpos+1, strlen($dynamicFrom[0])-$dynpos-2);
1062 $dynfrom['address'] = sanitize_email($dynad);
1063 //echo '<div class="error"><p><strong>dynform'.esc_html__($dynfrom['address']).'</strong></p></div>'."\n";
1064 if($dynpos >0) {
1065 $dynfrom['name'] = substr($dynamicFrom[0],0,$dynpos-1);
1066 $fromAddress['name'] = $dynfrom['name'];
1067 }
1068 $fromAddress['address'] = $dynfrom['address'];
1069 }
1070 else if(!empty($dynamicFrom[0])) {
1071 $fromAddress['address'] = $dynamicFrom[0];
1072 }
1073
1074 //echo '<div class="error"><p><strong>'.esc_html__('dynamicForm is not empty').'</strong></p></div>'."\n";
1075 //echo '<div class="error"><p><strong>'.esc_html__($dynamicFrom[0]).'</strong></p></div>'."\n";
1076 }
1077 else {
1078 $fromAddress['address'] = get_option('transmail_from_email_id');
1079 echo '<div class="error"><p><strong>'.esc_html__('dynamicForm is empty').'</strong></p></div>'."\n";
1080 echo '<div class="error"><p><strong>dynam 0 fromaddreess'.esc_html__($fromAddress['address']).'</strong></p></div>'."\n";
1081 }
1082 //echo '<div class="error"><p><strong>from address' . esc_html($fromAddress['address']) . '</strong></p></div>' . "\n";
1083
1084 // Retrieve the JSON string from the 'transmail_additional_mail_agents' option
1085 $json_string = get_option('transmail_additional_mail_agents');
1086
1087 // Decode the JSON string into a PHP associative array
1088 $email_agents = json_decode(base64_decode($json_string), true);
1089 if (isset($headers['Authorization'])) {
1090 $token = $headers['Authorization'];
1091 }
1092 else if (is_array($email_agents)) {
1093 // Define the email ID you want to get the token for
1094 $target_email = $fromAddress['address'];
1095
1096 // Check if the target email exists in the array
1097 if (isset($email_agents[$target_email])) {
1098 // Iterate over the details array to get the token
1099 foreach ($email_agents[$target_email] as $detail) {
1100
1101 //echo 'From Name: ' . esc_html($detail['fromName']) . '<br>';
1102 //echo 'Token: ' . esc_html($detail['Token']) . '<br>';
1103 if ( !isset( $fromAddress['name'] ) || empty( $fromAddress['name'] ) ) {
1104 $fromAddress['name'] = $detail['fromName'];
1105 }
1106 $token = $detail['Token'];
1107 }
1108 } else {
1109 //echo 'Email not found in the data.';
1110
1111 foreach ($email_agents as $details) {
1112 if (!empty($details)) {
1113 $first_entry = reset($details);
1114 $token = $first_entry['Token'];
1115 break; // Exit the loop after setting the token
1116 }
1117 }
1118
1119 if ($token) {
1120 //echo 'Email not found in the data. Using the first available token:<br>';
1121 //echo 'Token: ' . esc_html($token) . '<br>';
1122 } else {
1123 echo 'No tokens available in the data.';
1124 }
1125 }
1126 }
1127 //error_log('from name:'. $fromAddress['name']);
1128 /*
1129 if($fromAddress['address'] !== get_option('transmail_from_email_id')){
1130
1131 } else {
1132 echo 'Failed to decode JSON or no data found.';
1133 }
1134
1135 } else {
1136 $token = base64_decode(get_option('transmail_send_mail_token'));
1137 echo '<div class="error"><p><strong>other than default' . esc_html($token) . '</strong></p></div>' . "\n";
1138
1139 }*/
1140 $data['from'] = $fromAddress;
1141
1142 if (!empty($data['from']['address'])) {
1143 //echo '<div class="error"><p><strong>' . esc_html($data['from']['address']) . '</strong></p></div>' . "\n";
1144 } else {
1145 //echo '<div class="error"><p><strong>from address empty</strong></p></div>' . "\n";
1146 }
1147
1148 $zmbccs = array();
1149 $zmbcc = array();
1150 $zmbce = array();
1151 if (!empty($bcc)) {
1152 $count = 0;
1153 foreach($bcc as $bc) {
1154 $zmbcc['address'] = $bc;
1155 $zmbce['email_address'] = $zmbcc;
1156 $zmbccs[$count] = $zmbce;
1157 $count = $count + 1;
1158 }
1159 $data['bcc'] = $zmbccs;
1160 }
1161
1162 if(!empty($reply_to)) {
1163 $replyTos = array();
1164 $replyTo = array();
1165 $rte = array();
1166 $count = 0;
1167 foreach($reply_to as $reply) {
1168 $pos = strpos($reply, '<');
1169 if($pos !== false) {
1170 $ad = substr($reply, $pos+1, strlen($reply)-$pos-2);
1171 $replyTo['address'] = $ad;
1172 $replyTo['name'] = substr($reply,0,$pos-1);
1173 } else {
1174 $replyTo['address'] = $reply;
1175 }
1176 $replyTos[$count] = $replyTo;
1177 $count = $count + 1;
1178 }
1179 $data['reply_to'] = $replyTos;
1180 }
1181 $data['subject'] = $subject;
1182
1183 if(!empty($to) && is_array($to)) {
1184 $tos = array();
1185 $count = 0;
1186 foreach($to as $t) {
1187 $toa = array();
1188 $toe = array();
1189 $pos = strpos($t, '<');
1190 if($pos !== false) {
1191 $ad = substr($t, $pos+1, strlen($t)-$pos-2);
1192 $toa['address'] = sanitize_email($ad);
1193 $toa['name'] = substr($t,0,$pos-1);
1194 } else {
1195 $toa['address'] = sanitize_email($t);
1196 }
1197 $toe['email_address'] = $toa;
1198 $tos[$count] = $toe;
1199 $count = $count + 1;
1200 }
1201 $data['to'] = $tos;
1202 } else {
1203 $toa = array();
1204 $tos = array();
1205 $toa['address'] = $to;
1206 $tos[0] = $toa;
1207 $data['to'] = $to;
1208 }
1209 $attachmentJSONArr = array();
1210 $attachment_paths = array();
1211 if (!empty($attachments)) {
1212 if (!is_array($attachments)) {
1213 $attachments = explode("\n", $attachments);
1214 }
1215 $count = 0;
1216
1217 foreach ($attachments as $attfile) {
1218 if (file_exists($attfile)) {
1219 $attachmentupload = array(
1220 'name' => basename($attfile),
1221 'mime_type' => mime_content_type($attfile),
1222 'content' => base64_encode(file_get_contents($attfile))
1223 );
1224 $attachmentJSONArr[$count] = $attachmentupload;
1225 $relative_path = str_replace(ABSPATH, '', $attfile); // Remove absolute path part
1226 $attachment_paths[] = $relative_path;
1227 $count = $count + 1;
1228 } else {
1229 error_log("Attachment file does not exist: " . $attfile);
1230 }
1231 }
1232
1233 //error_log("attachments: " . json_encode($attachmentJSONArr, JSON_PRETTY_PRINT));
1234 $data['attachments'] = $attachmentJSONArr;
1235 }
1236 $files = isset($data['attachments']) ? $data['attachments'] : array();
1237 $attachedFiles = array();
1238
1239 // Iterate over the attachment data
1240 foreach ($files as $fileData) {
1241 // Assuming 'name' is the file path stored in the attachment data
1242 $attachedFiles[] = $fileData['name'];
1243 }
1244
1245 if( $content_type == 'text/html' || get_option('transmail_content_type') == 'html') {
1246 $data['htmlbody'] = $message;
1247 } else {
1248 $data['textbody'] = $message;
1249 }
1250
1251
1252
1253 //echo '<div class="error"><p><strong> token is ' . esc_html($token) . '</strong></p></div>' . "\n";
1254 $headers1 = array(
1255 'Authorization' => $token,
1256 'User-Agent' => 'Zepto_WordPress'
1257 );
1258
1259 $data_string = json_encode($headers1);
1260
1261 $data_string = json_encode($data);
1262 $args = array(
1263 'body' => $data_string,
1264 'headers' => $headers1,
1265 'method' => 'POST'
1266 );
1267 $domainName = get_option('transmail_domain_name');
1268 if (strpos($domainName, 'zoho') === false) {
1269 $domainName = 'zoho.'.$domainName;
1270 }
1271 $urlToSend = Transmail_Helper::getZeptoMailUrlForDomain($domainName).'/v1.1/email';
1272 $responseSending = wp_remote_post( $urlToSend, $args );
1273 $http_code = wp_remote_retrieve_response_code($responseSending);
1274 $responseBody = wp_remote_retrieve_body( $responseSending );
1275
1276 // echo "respbpody: " . $responseBody;
1277
1278
1279 // if ( is_wp_error( $responseSending ) ) {
1280 // echo 'Error: ' . $responseSending->get_error_message();
1281 // } else {
1282 // echo '<pre>';
1283 // print_r( $responseSending );
1284 // echo '</pre>';
1285 // }
1286
1287 if(!is_wp_error( $responseSending )) {
1288 update_option('transmail_test_mail_case', $responseSending['body'], false);
1289 }
1290
1291
1292 //error_log("responsesending body data: ". $responseSending['body']);
1293 //echo "responsesending body data: ". $responseSending['body'];
1294
1295
1296 $responseBody = wp_remote_retrieve_body($responseSending);
1297 $responseData = json_decode($responseBody);
1298
1299 //error_log("response data: ". $responseBody);
1300 $mail_data = array(
1301 'to' => $to,
1302 'subject' => $subject,
1303 'message' => $message,
1304 'headers' => $headers1,
1305 'attachments' => $attachments
1306 );
1307
1308 if($http_code == '200' || $http_code == '201') {
1309 //echo "http codE: " .$http_code;
1310 //do_action( 'wp_mail_succeeded', $mail_data );
1311 //wp_send_json_success(array('status' => 'mail_sent', 'message' => 'Email sent successfully.'));
1312 return true;
1313 } else {
1314 update_option('transmail_test_mail_case', $responseSending['body'], false);
1315 //echo "http codE: " .$http_code;
1316 // Decode the JSON string into an associative array
1317 $responseArray = json_decode($responseBody, true);
1318
1319 if($responseSending['body'] != '') {
1320 //echo "resp array: " . $responseArray;
1321 // Check if the response data was decoded successfully and contains the expected structure
1322 if (isset($responseArray['error']['details'][0]['code']) && isset($responseArray['error']['details'][0]['message'])) {
1323 $errorCode = $responseArray['error']['details'][0]['code'];
1324 $errorMessage = $responseArray['error']['details'][0]['message'];
1325 //echo "to address: " . $to[0] . PHP_EOL;
1326 $attachment_paths_json = !empty($attachment_paths) ? $attachment_paths : '';
1327 insert_failed_email($from_email,$to[0], $subject, $message, $responseArray['error']['details'], $attachment_paths_json);
1328 }
1329 }
1330 return false;
1331 }
1332
1333
1334
1335
1336 if (is_object($responseData) && isset($responseData->error)) {
1337 $details = $responseData->error->details;
1338 if (is_array($details) && isset($details[0]->message)) {
1339 $message = $details[0]->message;
1340 } else {
1341 $message = "Error details are not available.";
1342 }
1343 } else {
1344 $message = "Error property is not present in the response.";
1345 }
1346
1347
1348
1349
1350 do_action( 'wp_mail_failed', new WP_Error( 'wp_mail_failed', $message, $mail_data ) );
1351 return false;
1352
1353 }
1354 }
1355
1356 add_action('wp_ajax_retry_failed_email', 'retry_failed_email');
1357
1358 function retry_failed_email() {
1359 global $wpdb;
1360
1361 check_ajax_referer('transmail_failed_email_nonce', 'nonce');
1362
1363 $id = isset($_POST['id']) ? intval($_POST['id']) : 0;
1364
1365 if ($id > 0) {
1366 $table_name = $wpdb->prefix . 'transmail_failed_emails';
1367 $record = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $id));
1368
1369 if ($record) {
1370 $headers = array(
1371 'From' => $record->headers,
1372 'User-Agent' => 'Zepto_WordPress',
1373 'Content-Type: text/html; charset=UTF-8'
1374 );
1375 $attachments = array();
1376 $attachment_files_raw = $record->attachment_files;
1377 if($record->attachment_files){
1378 $attachment_paths = json_decode($attachment_files_raw, true);
1379
1380 if (!empty($attachment_paths) && is_array($attachment_paths)) {
1381 foreach ($attachment_paths as $attachment) {
1382 if (file_exists($attachment)) {
1383 $attachments[] = $attachment;
1384 }
1385 else {
1386 error_log("Attachment file does not exist: " . $attachment);
1387 }
1388 }
1389 }
1390 }
1391 $headers = array('From: ' . $record->headers);
1392 $email_sent = wp_mail($record->email_address, $record->email_subject, $record->email_body, $headers, $attachments);
1393
1394 if ($email_sent) {
1395 wp_send_json_success();
1396
1397 } else {
1398 wp_send_json_error('Failed to retry email.');
1399 }
1400 } else {
1401 wp_send_json_error('Invalid ID.');
1402 }
1403 wp_die();
1404 }
1405 }
1406
1407
1408 add_action('wp_ajax_delete_failed_email', 'delete_failed_email');
1409
1410 function delete_failed_email() {
1411 check_ajax_referer('transmail_failed_email_nonce', 'nonce');
1412
1413 global $wpdb;
1414 $table_name = $wpdb->prefix . 'transmail_failed_emails';
1415
1416 $id = intval($_POST['id']);
1417
1418 $deleted = $wpdb->delete($table_name, array('id' => $id), array('%d'));
1419
1420 if ($deleted !== false) {
1421 wp_send_json_success();
1422 } else {
1423 wp_send_json_error();
1424 }
1425
1426 wp_die();
1427 }
1428
1429 add_action('wp_ajax_delete_selected_logs', 'handle_delete_selected_logs');
1430
1431 function handle_delete_selected_logs() {
1432 check_ajax_referer('transmail_failed_email_nonce', 'nonce');
1433
1434 global $wpdb;
1435 $table_name = $wpdb->prefix . 'transmail_failed_emails';
1436
1437 $ids = isset($_POST['ids']) ? json_decode(stripslashes($_POST['ids'])) : array();
1438
1439 $ids = array_map('intval', $ids);
1440
1441 $deleted = $wpdb->query(
1442 $wpdb->prepare(
1443 "DELETE FROM $table_name WHERE id IN (" . implode(',', array_fill(0, count($ids), '%d')) . ")",
1444 ...$ids
1445 )
1446 );
1447
1448 if ($deleted !== false) {
1449 wp_send_json_success();
1450 } else {
1451 wp_send_json_error();
1452 }
1453
1454 wp_die();
1455 }
1456
1457
1458