Mailgun for WordPress - Version 1.8.7

Version Description

(2022-11-12): = - Fixed bug when field Override "From" Details was not updated

Download this release

Release Info

Developer omykhailenko
Plugin Icon 128x128 Mailgun for WordPress
Version 1.8.7
Comparing to
See all releases

Code changes from version 1.8.0 to 1.8.7

.gitignore CHANGED
@@ -1,3 +1,4 @@
1
  svn/
2
  .idea/
3
- docker-compose.yaml
 
1
  svn/
2
  .idea/
3
+ docker-compose.yaml
4
+ .git
CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
  Changelog
2
  =========
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  1.7.9 (2021-05-24)
5
  - API Key description
1
  Changelog
2
  =========
3
+ 1.8.7 (2022-11-12)
4
+ - Fixed bug when field `Override "From" Details` was not updated
5
+
6
+ 1.8.6 (2022-11-09)
7
+ - Version update
8
+
9
+ 1.8.5 (2022-09-21)
10
+ - Make code changes to have more optimized way to use Mailgun object in the code
11
+
12
+ 1.8.3 (2022-08-30)
13
+ - Plugin refactoring. Widget fixes for working with Legacy Widget Block. PHP8.0 support check
14
 
15
  1.7.9 (2021-05-24)
16
  - API Key description
includes/admin.php CHANGED
@@ -26,12 +26,18 @@ class MailgunAdmin extends Mailgun
26
  */
27
  private $defaults;
28
 
 
 
 
 
 
 
 
29
  /**
30
  * Setup backend functionality in WordPress.
31
  *
32
  * @return void
33
  *
34
- * @since 0.1
35
  */
36
  public function __construct()
37
  {
@@ -58,14 +64,13 @@ class MailgunAdmin extends Mailgun
58
  *
59
  * @return void
60
  *
61
- * @since 0.1
62
  */
63
  public function init()
64
  {
65
  $sitename = strtolower($_SERVER['SERVER_NAME']);
66
- if (substr($sitename, 0, 4) == 'www.'):
67
  $sitename = substr($sitename, 4);
68
- endif;
69
 
70
  $region = (defined('MAILGUN_REGION') && MAILGUN_REGION) ? MAILGUN_REGION : $this->get_option('region');
71
  $regionDefault = $region ?: 'us';
@@ -85,10 +90,10 @@ class MailgunAdmin extends Mailgun
85
  'override-from' => '0',
86
  'tag' => $sitename,
87
  );
88
- if (!$this->options):
89
  $this->options = $this->defaults;
90
  add_option('mailgun', $this->options);
91
- endif;
92
  }
93
 
94
  /**
@@ -96,11 +101,10 @@ class MailgunAdmin extends Mailgun
96
  *
97
  * @return void
98
  *
99
- * @since 0.1
100
  */
101
  public function admin_menu()
102
  {
103
- if (current_user_can('manage_options')):
104
  $this->hook_suffix = add_options_page(__('Mailgun', 'mailgun'), __('Mailgun', 'mailgun'),
105
  'manage_options', 'mailgun', array(&$this, 'options_page'));
106
  add_options_page(__('Mailgun Lists', 'mailgun'), __('Mailgun Lists', 'mailgun'), 'manage_options',
@@ -108,7 +112,7 @@ class MailgunAdmin extends Mailgun
108
  add_action("admin_print_scripts-{$this->hook_suffix}", array(&$this, 'admin_js'));
109
  add_filter("plugin_action_links_{$this->plugin_basename}", array(&$this, 'filter_plugin_actions'));
110
  add_action("admin_footer-{$this->hook_suffix}", array(&$this, 'admin_footer_js'));
111
- endif;
112
  }
113
 
114
  /**
@@ -116,7 +120,6 @@ class MailgunAdmin extends Mailgun
116
  *
117
  * @return void
118
  *
119
- * @since 0.1
120
  */
121
  public function admin_js()
122
  {
@@ -126,7 +129,6 @@ class MailgunAdmin extends Mailgun
126
  /**
127
  * Output JS to footer for enhanced admin page functionality.
128
  *
129
- * @since 0.1
130
  */
131
  public function admin_footer_js()
132
  {
@@ -194,14 +196,13 @@ class MailgunAdmin extends Mailgun
194
  *
195
  * @return void
196
  *
197
- * @since 0.1
198
  */
199
  public function options_page()
200
  {
201
- if (!@include 'options-page.php'):
202
  printf(__('<div id="message" class="updated fade"><p>The options page for the <strong>Mailgun</strong> plugin cannot be displayed. The file <strong>%s</strong> is missing. Please reinstall the plugin.</p></div>',
203
- 'mailgun'), dirname(__FILE__) . '/options-page.php');
204
- endif;
205
  }
206
 
207
  /**
@@ -209,14 +210,13 @@ class MailgunAdmin extends Mailgun
209
  *
210
  * @return void
211
  *
212
- * @since 0.1
213
  */
214
  public function lists_page()
215
  {
216
- if (!@include 'lists-page.php'):
217
  printf(__('<div id="message" class="updated fade"><p>The lists page for the <strong>Mailgun</strong> plugin cannot be displayed. The file <strong>%s</strong> is missing. Please reinstall the plugin.</p></div>',
218
- 'mailgun'), dirname(__FILE__) . '/lists-page.php');
219
- endif;
220
  }
221
 
222
  /**
@@ -226,7 +226,6 @@ class MailgunAdmin extends Mailgun
226
  *
227
  * @return void
228
  *
229
- * @since 0.1
230
  */
231
  public function admin_init()
232
  {
@@ -244,7 +243,6 @@ class MailgunAdmin extends Mailgun
244
  *
245
  * @return void
246
  *
247
- * @since 0.1
248
  */
249
  public function register_settings()
250
  {
@@ -258,9 +256,8 @@ class MailgunAdmin extends Mailgun
258
  *
259
  * @return array
260
  *
261
- * @since 0.1
262
  */
263
- public function validation($options)
264
  {
265
  $apiKey = trim($options['apiKey']);
266
  $username = trim($options['username']);
@@ -309,7 +306,6 @@ class MailgunAdmin extends Mailgun
309
  *
310
  * @return void
311
  *
312
- * @since 0.1
313
  */
314
  public function admin_notices()
315
  {
@@ -369,7 +365,6 @@ class MailgunAdmin extends Mailgun
369
  *
370
  * @return array
371
  *
372
- * @since 0.1
373
  */
374
  public function filter_plugin_actions($links)
375
  {
@@ -384,7 +379,7 @@ class MailgunAdmin extends Mailgun
384
  *
385
  * @return string
386
  *
387
- * @since 0.1
388
  */
389
  public function ajax_send_test()
390
  {
@@ -406,26 +401,25 @@ class MailgunAdmin extends Mailgun
406
  $secure = (defined('MAILGUN_SECURE') && MAILGUN_SECURE) ? MAILGUN_SECURE : $this->get_option('secure');
407
  $sectype = (defined('MAILGUN_SECTYPE') && MAILGUN_SECTYPE) ? MAILGUN_SECTYPE : $this->get_option('sectype');
408
 
409
- if ((bool)!$getRegion):
410
  mg_api_last_error(__("Region has not been selected", "mailgun"));
411
- else:
412
- if ($getRegion === 'us'):
413
  $region = __("U.S./North America", "mailgun");
414
- endif;
415
-
416
- if ($getRegion === "eu"):
417
  $region = __("Europe", "mailgun");
418
- endif;
419
- endif;
420
 
421
- if ((bool)$useAPI):
422
  $method = __('HTTP API', 'mailgun');
423
- else:
424
- $method = ((bool)$secure) ? __('Secure SMTP', 'mailgun') : __('Insecure SMTP', 'mailgun');
425
- if ((bool)$secure):
426
- $method = $method . sprintf(__(' via %s', 'mailgun'), $sectype);
427
- endif;
428
- endif;
429
 
430
  $admin_email = get_option('admin_email');
431
  $result = wp_mail(
@@ -433,54 +427,51 @@ class MailgunAdmin extends Mailgun
433
  __('Mailgun WordPress Plugin Test', 'mailgun'),
434
  sprintf(__("This is a test email generated by the Mailgun WordPress plugin.\n\nIf you have received this message, the requested test has succeeded.\n\nThe sending region is set to %s.\n\nThe method used to send this email was: %s.",
435
  'mailgun'), $region, $method),
436
- array('Content-Type: text/plain')
437
  );
438
 
439
- if ((bool)$useAPI):
440
- if (!function_exists('mg_api_last_error')):
441
- if (!include __DIR__ . '/wp-mail-api.php'):
442
  $this->deactivate_and_die(__DIR__ . '/wp-mail-api.php');
443
- endif;
444
- endif;
445
-
446
  $error_msg = mg_api_last_error();
447
- else:
448
- if (!function_exists('mg_smtp_last_error')):
449
- if (!include __DIR__ . '/wp-mail-smtp.php'):
450
  $this->deactivate_and_die(__DIR__ . '/wp-mail-smtp.php');
451
- endif;
452
- endif;
453
-
454
  $error_msg = mg_smtp_last_error();
455
- endif;
456
 
457
  // Admin Email is used as 'to' parameter, but in case of 'Test Configuration' this message is not clear for the user, so replaced with more appropriate one
458
- if (false !== strpos($error_msg, "'to'") && false !== strpos($error_msg, 'is not a valid')):
459
  $error_msg = sprintf(
460
  "Administration Email Address (%s) is not valid and can't be used for test, you can change it at General Setting page",
461
  $admin_email
462
  );
463
- endif;
464
 
465
- if ($result):
466
  die(
467
- json_encode(array(
468
- 'message' => __('Success', 'mailgun'),
469
- 'method' => $method,
470
- 'error' => __('Success', 'mailgun'),
471
- ), JSON_THROW_ON_ERROR)
472
  );
473
- else:
474
- // Error message will always be returned in case of failure, if not - connection wasn't successful
475
- $error_msg = $error_msg ? $error_msg : "Can't connect to Mailgun";
476
 
477
- die(
 
 
478
  json_encode(array(
479
  'message' => __('Failure', 'mailgun'),
480
  'method' => $method,
481
  'error' => $error_msg,
482
  ), JSON_THROW_ON_ERROR)
483
- );
484
- endif;
485
  }
486
  }
26
  */
27
  private $defaults;
28
 
29
+ /**
30
+ * @var array
31
+ */
32
+ protected $options = [];
33
+
34
+ protected $hook_suffix;
35
+
36
  /**
37
  * Setup backend functionality in WordPress.
38
  *
39
  * @return void
40
  *
 
41
  */
42
  public function __construct()
43
  {
64
  *
65
  * @return void
66
  *
 
67
  */
68
  public function init()
69
  {
70
  $sitename = strtolower($_SERVER['SERVER_NAME']);
71
+ if (substr($sitename, 0, 4) === 'www.') {
72
  $sitename = substr($sitename, 4);
73
+ }
74
 
75
  $region = (defined('MAILGUN_REGION') && MAILGUN_REGION) ? MAILGUN_REGION : $this->get_option('region');
76
  $regionDefault = $region ?: 'us';
90
  'override-from' => '0',
91
  'tag' => $sitename,
92
  );
93
+ if (!$this->options) {
94
  $this->options = $this->defaults;
95
  add_option('mailgun', $this->options);
96
+ }
97
  }
98
 
99
  /**
101
  *
102
  * @return void
103
  *
 
104
  */
105
  public function admin_menu()
106
  {
107
+ if (current_user_can('manage_options')) {
108
  $this->hook_suffix = add_options_page(__('Mailgun', 'mailgun'), __('Mailgun', 'mailgun'),
109
  'manage_options', 'mailgun', array(&$this, 'options_page'));
110
  add_options_page(__('Mailgun Lists', 'mailgun'), __('Mailgun Lists', 'mailgun'), 'manage_options',
112
  add_action("admin_print_scripts-{$this->hook_suffix}", array(&$this, 'admin_js'));
113
  add_filter("plugin_action_links_{$this->plugin_basename}", array(&$this, 'filter_plugin_actions'));
114
  add_action("admin_footer-{$this->hook_suffix}", array(&$this, 'admin_footer_js'));
115
+ }
116
  }
117
 
118
  /**
120
  *
121
  * @return void
122
  *
 
123
  */
124
  public function admin_js()
125
  {
129
  /**
130
  * Output JS to footer for enhanced admin page functionality.
131
  *
 
132
  */
133
  public function admin_footer_js()
134
  {
196
  *
197
  * @return void
198
  *
 
199
  */
200
  public function options_page()
201
  {
202
+ if (!@include 'options-page.php') {
203
  printf(__('<div id="message" class="updated fade"><p>The options page for the <strong>Mailgun</strong> plugin cannot be displayed. The file <strong>%s</strong> is missing. Please reinstall the plugin.</p></div>',
204
+ 'mailgun'), __DIR__ . '/options-page.php');
205
+ }
206
  }
207
 
208
  /**
210
  *
211
  * @return void
212
  *
 
213
  */
214
  public function lists_page()
215
  {
216
+ if (!@include 'lists-page.php') {
217
  printf(__('<div id="message" class="updated fade"><p>The lists page for the <strong>Mailgun</strong> plugin cannot be displayed. The file <strong>%s</strong> is missing. Please reinstall the plugin.</p></div>',
218
+ 'mailgun'), __DIR__ . '/lists-page.php');
219
+ }
220
  }
221
 
222
  /**
226
  *
227
  * @return void
228
  *
 
229
  */
230
  public function admin_init()
231
  {
243
  *
244
  * @return void
245
  *
 
246
  */
247
  public function register_settings()
248
  {
256
  *
257
  * @return array
258
  *
 
259
  */
260
+ public function validation(array $options)
261
  {
262
  $apiKey = trim($options['apiKey']);
263
  $username = trim($options['username']);
306
  *
307
  * @return void
308
  *
 
309
  */
310
  public function admin_notices()
311
  {
365
  *
366
  * @return array
367
  *
 
368
  */
369
  public function filter_plugin_actions($links)
370
  {
379
  *
380
  * @return string
381
  *
382
+ * @throws JsonException
383
  */
384
  public function ajax_send_test()
385
  {
401
  $secure = (defined('MAILGUN_SECURE') && MAILGUN_SECURE) ? MAILGUN_SECURE : $this->get_option('secure');
402
  $sectype = (defined('MAILGUN_SECTYPE') && MAILGUN_SECTYPE) ? MAILGUN_SECTYPE : $this->get_option('sectype');
403
 
404
+ if (!$getRegion) {
405
  mg_api_last_error(__("Region has not been selected", "mailgun"));
406
+ } else {
407
+ if ($getRegion === 'us') {
408
  $region = __("U.S./North America", "mailgun");
409
+ }
410
+ if ($getRegion === "eu") {
 
411
  $region = __("Europe", "mailgun");
412
+ }
413
+ }
414
 
415
+ if ($useAPI) {
416
  $method = __('HTTP API', 'mailgun');
417
+ } else {
418
+ $method = ($secure) ? __('Secure SMTP', 'mailgun') : __('Insecure SMTP', 'mailgun');
419
+ if ($secure) {
420
+ $method .= sprintf(__(' via %s', 'mailgun'), $sectype);
421
+ }
422
+ }
423
 
424
  $admin_email = get_option('admin_email');
425
  $result = wp_mail(
427
  __('Mailgun WordPress Plugin Test', 'mailgun'),
428
  sprintf(__("This is a test email generated by the Mailgun WordPress plugin.\n\nIf you have received this message, the requested test has succeeded.\n\nThe sending region is set to %s.\n\nThe method used to send this email was: %s.",
429
  'mailgun'), $region, $method),
430
+ ['Content-Type: text/plain']
431
  );
432
 
433
+ if ($useAPI) {
434
+ if (!function_exists('mg_api_last_error')) {
435
+ if (!include __DIR__ . '/wp-mail-api.php') {
436
  $this->deactivate_and_die(__DIR__ . '/wp-mail-api.php');
437
+ }
438
+ }
 
439
  $error_msg = mg_api_last_error();
440
+ } else {
441
+ if (!function_exists('mg_smtp_last_error')) {
442
+ if (!include __DIR__ . '/wp-mail-smtp.php') {
443
  $this->deactivate_and_die(__DIR__ . '/wp-mail-smtp.php');
444
+ }
445
+ }
 
446
  $error_msg = mg_smtp_last_error();
447
+ }
448
 
449
  // Admin Email is used as 'to' parameter, but in case of 'Test Configuration' this message is not clear for the user, so replaced with more appropriate one
450
+ if (false !== strpos($error_msg, "'to'") && false !== strpos($error_msg, 'is not a valid')) {
451
  $error_msg = sprintf(
452
  "Administration Email Address (%s) is not valid and can't be used for test, you can change it at General Setting page",
453
  $admin_email
454
  );
455
+ }
456
 
457
+ if ($result) {
458
  die(
459
+ json_encode(array(
460
+ 'message' => __('Success', 'mailgun'),
461
+ 'method' => $method,
462
+ 'error' => __('Success', 'mailgun'),
463
+ ), JSON_THROW_ON_ERROR)
464
  );
465
+ }
 
 
466
 
467
+ // Error message will always be returned in case of failure, if not - connection wasn't successful
468
+ $error_msg = $error_msg ?: "Can't connect to Mailgun";
469
+ die(
470
  json_encode(array(
471
  'message' => __('Failure', 'mailgun'),
472
  'method' => $method,
473
  'error' => $error_msg,
474
  ), JSON_THROW_ON_ERROR)
475
+ );
 
476
  }
477
  }
includes/lists-page.php CHANGED
@@ -19,7 +19,7 @@
19
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
  */
21
 
22
- global $mailgun;
23
 
24
  // check mailgun domain & api key
25
  $missing_error = '';
19
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
  */
21
 
22
+ $mailgun = Mailgun::getInstance();
23
 
24
  // check mailgun domain & api key
25
  $missing_error = '';
includes/mg-filter.php CHANGED
@@ -23,26 +23,28 @@
23
  /**
24
  * Tries several methods to get the MIME Content-Type of a file.
25
  *
26
- * @param string $filepath
27
- * @param string $default_type If all methods fail, fallback to $default_type
28
  *
29
- * @return string Content-Type
30
  *
31
- * @since 1.5.4
32
  */
33
- function get_mime_content_type($filepath, $default_type = 'text/plain')
34
  {
35
  if (function_exists('mime_content_type')) {
36
  return mime_content_type($filepath);
37
- } elseif (function_exists('finfo_file')) {
 
 
38
  $fi = finfo_open(FILEINFO_MIME_TYPE);
39
  $ret = finfo_file($fi, $filepath);
40
  finfo_close($fi);
41
 
42
  return $ret;
43
- } else {
44
- return $default_type;
45
  }
 
 
46
  }
47
 
48
  /**
@@ -59,16 +61,16 @@ function get_mime_content_type($filepath, $default_type = 'text/plain')
59
  * `$from_addr` before being returned. The filtered result is null-tested
60
  * before being returned.
61
  *
62
- * @return string
63
  *
64
- * @since 1.5.8
65
  */
66
  function mg_detect_from_name($from_name_header = null)
67
  {
68
  // Get options to avoid strict mode problems
69
  $mg_opts = get_option('mailgun');
70
- $mg_override_from = (isset($mg_opts['override-from'])) ? $mg_opts['override-from'] : null;
71
- $mg_from_name = (isset($mg_opts['from-name'])) ? $mg_opts['from-name'] : null;
72
 
73
  $from_name = null;
74
 
@@ -79,7 +81,7 @@ function mg_detect_from_name($from_name_header = null)
79
  } elseif (defined('MAILGUN_FROM_NAME') && MAILGUN_FROM_NAME) {
80
  $from_name = MAILGUN_FROM_NAME;
81
  } else {
82
- if (is_null($mg_from_name) || empty($mg_from_name)) {
83
  if (function_exists('get_current_site')) {
84
  $from_name = get_current_site()->site_name;
85
  } else {
@@ -96,7 +98,7 @@ function mg_detect_from_name($from_name_header = null)
96
  'wp_mail_from_name',
97
  $from_name
98
  );
99
- if (!is_null($filter_from_name) && !empty($filter_from_name)) {
100
  $from_name = $filter_from_name;
101
  }
102
  }
@@ -124,18 +126,18 @@ function mg_detect_from_name($from_name_header = null)
124
  * might appear to be another option but some hosts may refuse to
125
  * relay mail from an unknown domain.
126
  *
127
- * @link http://trac.wordpress.org/ticket/5007.
128
  *
129
- * @return string
130
  *
131
- * @since 1.5.8
132
  */
133
- function mg_detect_from_address($from_addr_header = null)
134
  {
135
  // Get options to avoid strict mode problems
136
  $mg_opts = get_option('mailgun');
137
- $mg_override_from = (isset($mg_opts['override-from'])) ? $mg_opts['override-from'] : null;
138
- $mg_from_addr = (isset($mg_opts['from-address'])) ? $mg_opts['from-address'] : null;
139
 
140
  $from_addr = null;
141
 
@@ -146,7 +148,7 @@ function mg_detect_from_address($from_addr_header = null)
146
  } elseif (defined('MAILGUN_FROM_ADDRESS') && MAILGUN_FROM_ADDRESS) {
147
  $from_addr = MAILGUN_FROM_ADDRESS;
148
  } else {
149
- if (is_null($mg_from_addr) || empty($mg_from_addr)) {
150
  if (function_exists('get_current_site')) {
151
  $sitedomain = get_current_site()->domain;
152
  } else {
@@ -156,7 +158,7 @@ function mg_detect_from_address($from_addr_header = null)
156
  }
157
  }
158
 
159
- $from_addr = 'wordpress@'.$sitedomain;
160
  } else {
161
  $from_addr = $mg_from_addr;
162
  }
@@ -193,19 +195,18 @@ function mg_detect_from_address($from_addr_header = null)
193
  * )
194
  * )
195
  *
196
- * @param string|array $headers
197
  *
198
- * @return array
199
  *
200
- * @since 1.5.8
201
  */
202
- function mg_parse_headers($headers = array())
203
  {
204
  if (empty($headers)) {
205
- return array();
206
  }
207
 
208
- $tmp = array();
209
  if (!is_array($headers)) {
210
  $tmp = explode("\n", str_replace("\r\n", "\n", $headers));
211
  } else {
@@ -219,7 +220,7 @@ function mg_parse_headers($headers = array())
219
  $boundary = null;
220
  $parts = null;
221
 
222
- foreach ((array) $tmp as $header) {
223
  // If this header does not contain a ':', is it a fold?
224
  if (false === strpos($header, ':')) {
225
  // Does this header have a boundary?
@@ -239,15 +240,15 @@ function mg_parse_headers($headers = array())
239
  $name = trim($name);
240
  $value = trim($value);
241
 
242
- if ( !isset($new_headers[$name]) ) {
243
  $new_headers[$name] = array();
244
  }
245
 
246
- array_push($new_headers[$name], array(
247
- 'value' => $value,
248
- 'boundary' => $boundary,
249
- 'parts' => $parts,
250
- ));
251
  }
252
  }
253
 
@@ -258,13 +259,13 @@ function mg_parse_headers($headers = array())
258
  * Takes a header array in the format produced by mg_parse_headers and
259
  * dumps them down in to a submittable header format.
260
  *
261
- * @param array $headers Headers to dump
262
  *
263
- * @return string String of \r\n separated headers
264
  *
265
- * @since 1.5.8
266
  */
267
- function mg_dump_headers($headers = null)
268
  {
269
  if (is_null($headers) || !is_array($headers)) {
270
  return '';
@@ -277,7 +278,7 @@ function mg_dump_headers($headers = null)
277
 
278
  foreach ($values as $content) {
279
  // XXX - Is it actually okay to discard `parts` and `boundary`?
280
- array_push($header_values, $content['value']);
281
  }
282
 
283
  $header_string .= sprintf("%s\r\n", implode(", ", $header_values));
@@ -290,18 +291,21 @@ function mg_dump_headers($headers = null)
290
  * Set the API endpoint based on the region selected.
291
  * Value can be "0" if not selected, "us" or "eu"
292
  *
293
- * @param string $getRegion Region value set either in config or Mailgun plugin settings.
294
  *
295
- * @return bool|string
296
  *
297
- * @since 1.5.12
298
  */
299
  function mg_api_get_region($getRegion)
300
  {
301
  switch ($getRegion) {
302
- case 'us': return 'https://api.mailgun.net/v3/';
303
- case 'eu': return 'https://api.eu.mailgun.net/v3/';
304
- default: return false;
 
 
 
305
  }
306
  }
307
 
@@ -309,17 +313,20 @@ function mg_api_get_region($getRegion)
309
  * Set the SMTP endpoint based on the region selected.
310
  * Value can be "0" if not selected, "us" or "eu"
311
  *
312
- * @param string $getRegion Region value set either in config or Mailgun plugin settings.
313
  *
314
- * @return bool|string
315
  *
316
- * @since 1.5.12
317
  */
318
  function mg_smtp_get_region($getRegion)
319
  {
320
  switch ($getRegion) {
321
- case 'us': return 'smtp.mailgun.org';
322
- case 'eu': return 'smtp.eu.mailgun.org';
323
- default: return false;
 
 
 
324
  }
325
  }
23
  /**
24
  * Tries several methods to get the MIME Content-Type of a file.
25
  *
26
+ * @param string $filepath
27
+ * @param string $default_type If all methods fail, fallback to $default_type
28
  *
29
+ * @return string Content-Type
30
  *
31
+ * @since 1.5.4
32
  */
33
+ function get_mime_content_type(string $filepath, string $default_type = 'text/plain'): string
34
  {
35
  if (function_exists('mime_content_type')) {
36
  return mime_content_type($filepath);
37
+ }
38
+
39
+ if (function_exists('finfo_file')) {
40
  $fi = finfo_open(FILEINFO_MIME_TYPE);
41
  $ret = finfo_file($fi, $filepath);
42
  finfo_close($fi);
43
 
44
  return $ret;
 
 
45
  }
46
+
47
+ return $default_type;
48
  }
49
 
50
  /**
61
  * `$from_addr` before being returned. The filtered result is null-tested
62
  * before being returned.
63
  *
64
+ * @return string
65
  *
66
+ * @since 1.5.8
67
  */
68
  function mg_detect_from_name($from_name_header = null)
69
  {
70
  // Get options to avoid strict mode problems
71
  $mg_opts = get_option('mailgun');
72
+ $mg_override_from = $mg_opts['override-from'] ?? null;
73
+ $mg_from_name = $mg_opts['from-name'] ?? null;
74
 
75
  $from_name = null;
76
 
81
  } elseif (defined('MAILGUN_FROM_NAME') && MAILGUN_FROM_NAME) {
82
  $from_name = MAILGUN_FROM_NAME;
83
  } else {
84
+ if (empty($mg_from_name)) {
85
  if (function_exists('get_current_site')) {
86
  $from_name = get_current_site()->site_name;
87
  } else {
98
  'wp_mail_from_name',
99
  $from_name
100
  );
101
+ if (!empty($filter_from_name)) {
102
  $from_name = $filter_from_name;
103
  }
104
  }
126
  * might appear to be another option but some hosts may refuse to
127
  * relay mail from an unknown domain.
128
  *
129
+ * @link http://trac.wordpress.org/ticket/5007.
130
  *
131
+ * @return string
132
  *
133
+ * @since 1.5.8
134
  */
135
+ function mg_detect_from_address($from_addr_header = null): string
136
  {
137
  // Get options to avoid strict mode problems
138
  $mg_opts = get_option('mailgun');
139
+ $mg_override_from = $mg_opts['override-from'] ?? null;
140
+ $mg_from_addr = $mg_opts['from-address'] ?? null;
141
 
142
  $from_addr = null;
143
 
148
  } elseif (defined('MAILGUN_FROM_ADDRESS') && MAILGUN_FROM_ADDRESS) {
149
  $from_addr = MAILGUN_FROM_ADDRESS;
150
  } else {
151
+ if (empty($mg_from_addr)) {
152
  if (function_exists('get_current_site')) {
153
  $sitedomain = get_current_site()->domain;
154
  } else {
158
  }
159
  }
160
 
161
+ $from_addr = 'wordpress@' . $sitedomain;
162
  } else {
163
  $from_addr = $mg_from_addr;
164
  }
195
  * )
196
  * )
197
  *
198
+ * @param string|array $headers
199
  *
200
+ * @return array
201
  *
202
+ * @since 1.5.8
203
  */
204
+ function mg_parse_headers($headers = []): array
205
  {
206
  if (empty($headers)) {
207
+ return [];
208
  }
209
 
 
210
  if (!is_array($headers)) {
211
  $tmp = explode("\n", str_replace("\r\n", "\n", $headers));
212
  } else {
220
  $boundary = null;
221
  $parts = null;
222
 
223
+ foreach ((array)$tmp as $header) {
224
  // If this header does not contain a ':', is it a fold?
225
  if (false === strpos($header, ':')) {
226
  // Does this header have a boundary?
240
  $name = trim($name);
241
  $value = trim($value);
242
 
243
+ if (!isset($new_headers[$name])) {
244
  $new_headers[$name] = array();
245
  }
246
 
247
+ $new_headers[$name][] = array(
248
+ 'value' => $value,
249
+ 'boundary' => $boundary,
250
+ 'parts' => $parts,
251
+ );
252
  }
253
  }
254
 
259
  * Takes a header array in the format produced by mg_parse_headers and
260
  * dumps them down in to a submittable header format.
261
  *
262
+ * @param array $headers Headers to dump
263
  *
264
+ * @return string String of \r\n separated headers
265
  *
266
+ * @since 1.5.8
267
  */
268
+ function mg_dump_headers($headers = null): string
269
  {
270
  if (is_null($headers) || !is_array($headers)) {
271
  return '';
278
 
279
  foreach ($values as $content) {
280
  // XXX - Is it actually okay to discard `parts` and `boundary`?
281
+ $header_values[] = $content['value'];
282
  }
283
 
284
  $header_string .= sprintf("%s\r\n", implode(", ", $header_values));
291
  * Set the API endpoint based on the region selected.
292
  * Value can be "0" if not selected, "us" or "eu"
293
  *
294
+ * @param string $getRegion Region value set either in config or Mailgun plugin settings.
295
  *
296
+ * @return bool|string
297
  *
298
+ * @since 1.5.12
299
  */
300
  function mg_api_get_region($getRegion)
301
  {
302
  switch ($getRegion) {
303
+ case 'us':
304
+ return 'https://api.mailgun.net/v3/';
305
+ case 'eu':
306
+ return 'https://api.eu.mailgun.net/v3/';
307
+ default:
308
+ return false;
309
  }
310
  }
311
 
313
  * Set the SMTP endpoint based on the region selected.
314
  * Value can be "0" if not selected, "us" or "eu"
315
  *
316
+ * @param string $getRegion Region value set either in config or Mailgun plugin settings.
317
  *
318
+ * @return bool|string
319
  *
320
+ * @since 1.5.12
321
  */
322
  function mg_smtp_get_region($getRegion)
323
  {
324
  switch ($getRegion) {
325
+ case 'us':
326
+ return 'smtp.mailgun.org';
327
+ case 'eu':
328
+ return 'smtp.eu.mailgun.org';
329
+ default:
330
+ return false;
331
  }
332
  }
includes/options-page.php CHANGED
@@ -1,49 +1,49 @@
1
  <?php
2
 
3
- /*
4
- * mailgun-wordpress-plugin - Sending mail from Wordpress using Mailgun
5
- * Copyright (C) 2016 Mailgun, et al.
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License along
18
- * with this program; if not, write to the Free Software Foundation, Inc.,
19
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
- */
21
 
22
- global $mailgun;
23
 
24
  $mailgun_domain_const = ((defined('MAILGUN_DOMAIN') && MAILGUN_DOMAIN) ? MAILGUN_DOMAIN : null);
25
- $mailgun_domain = $mailgun_domain_const ? $mailgun_domain_const : $this->get_option('domain');
26
 
27
  $mailgun_region_const = ((defined('MAILGUN_REGION') && MAILGUN_REGION) ? MAILGUN_REGION : null);
28
- $mailgun_region = $mailgun_region_const ? $mailgun_region_const : $this->get_option('region');
29
 
30
  $mailgun_api_key_const = ((defined('MAILGUN_APIKEY') && MAILGUN_APIKEY) ? MAILGUN_APIKEY : null);
31
- $mailgun_api_key = $mailgun_api_key_const ? $mailgun_api_key_const : $this->get_option('apiKey');
32
 
33
  $mailgun_username_const = ((defined('MAILGUN_USERNAME') && MAILGUN_USERNAME) ? MAILGUN_USERNAME : null);
34
- $mailgun_username = $mailgun_username_const ? $mailgun_username_const : $this->get_option('username');
35
 
36
  $mailgun_password_const = ((defined('MAILGUN_PASSWORD') && MAILGUN_PASSWORD) ? MAILGUN_PASSWORD : null);
37
- $mailgun_password = $mailgun_password_const ? $mailgun_password_const : $this->get_option('password');
38
 
39
  $mailgun_sectype_const = ((defined('MAILGUN_SECTYPE') && MAILGUN_SECTYPE) ? MAILGUN_SECTYPE : null);
40
- $mailgun_sectype = $mailgun_sectype_const ? $mailgun_sectype_const : $this->get_option('sectype');
41
 
42
  $mailgun_from_name_const = ((defined('MAILGUN_FROM_NAME') && MAILGUN_FROM_NAME) ? MAILGUN_FROM_NAME : null);
43
- $mailgun_from_name = $mailgun_from_name_const ? $mailgun_from_name_const : $this->get_option('from-name');
44
 
45
  $mailgun_from_address_const = ((defined('MAILGUN_FROM_ADDRESS') && MAILGUN_FROM_ADDRESS) ? MAILGUN_FROM_ADDRESS : null);
46
- $mailgun_from_address = $mailgun_from_address_const ? $mailgun_from_address_const : $this->get_option('from-address');
47
 
48
  $mailgun_secure_const = (defined('MAILGUN_SECURE') ? MAILGUN_SECURE : null);
49
  $mailgun_secure = !is_null($mailgun_secure_const) ? ((string)(1 * $mailgun_secure_const)) : $this->get_option('secure');
@@ -54,403 +54,405 @@ $icon = $mailgun->getAssetsPath() . 'icon-128x128.png';
54
 
55
  ?>
56
  <div class="wrap">
57
- <div id="icon-options-general" class="icon32"><br/></div>
58
- <span class="alignright">
59
  <a target="_blank" href="http://www.mailgun.com/">
60
- <img src="<?php echo $icon?>" alt="Mailgun" style="width:50px;"/>
61
  </a>
62
  </span>
63
- <h2><?php _e('Mailgun', 'mailgun'); ?></h2>
64
 
65
- <p>
66
- <?php
67
- $url = 'https://www.mailgun.com';
68
- $link = sprintf(
69
- wp_kses(
70
- __('A <a href="%1$s" target="%2$s">Mailgun</a> account is required to use this plugin and the Mailgun service.', 'mailgun'),
71
- array('a' => array(
72
- 'href' => array(),
73
- 'target' => array()
74
- )
75
- )
76
- ), esc_url($url), '_blank'
77
- );
78
- echo $link;
79
- ?>
80
- </p>
81
 
82
- <p>
83
- <?php
84
- $url = 'https://signup.mailgun.com/new/signup';
85
- $link = sprintf(
86
- wp_kses(
87
- __('If you need to register for an account, you can do so at <a href="%1$s" target="%2$s">Mailgun.com</a>.', 'mailgun'),
88
- array('a' => array(
89
- 'href' => array(),
90
- 'target' => array()
91
- )
92
- )
93
- ), esc_url($url), '_blank'
94
- );
95
- echo $link;
96
- ?>
97
- </p>
98
 
99
- <h3><?php _e('Configuration', 'mailgun'); ?></h3>
100
- <form id="mailgun-form" action="options.php" method="post">
101
- <?php settings_fields('mailgun'); ?>
102
 
103
- <table class="form-table">
104
- <tr valign="top">
105
- <th scope="row">
106
- <?php _e('Select Your Region', 'mailgun'); ?>
107
- </th>
108
- <td>
109
- <?php if ($mailgun_region_const): ?>
110
- <input type="hidden" name="mailgun[region]" value="<?php echo $mailgun_region ?>">
111
- <?php endif ?>
112
 
113
- <select id="mailgun-region" name="mailgun[region]" <?php echo $mailgun_region_const ? 'disabled="disabled"' : '' ?>>
114
- <option value="us"<?php selected('us', $mailgun_region); ?>><?php _e('U.S./North America', 'mailgun') ?></option>
115
- <option value="eu"<?php selected('eu', $mailgun_region); ?>><?php _e('Europe', 'mailgun') ?></option>
116
- </select>
117
- <p class="description">
118
- <?php
119
- _e('Choose a region - U.S./North America or Europe - from which to send email, and to store your customer data. Please note that your sending domain must be set up in whichever region you choose.', 'mailgun');
120
- ?>
121
- </p>
122
- </td>
123
- </tr>
124
- <tr valign="top">
125
- <th scope="row">
126
- <?php _e('Use HTTP API', 'mailgun'); ?>
127
- </th>
128
- <td>
129
- <?php if (!is_null($mailgun_use_api_const)): ?>
130
- <input type="hidden" name="mailgun[useAPI]" value="<?php echo $mailgun_use_api ?>">
131
- <?php endif ?>
 
132
 
133
- <select id="mailgun-api" name="mailgun[useAPI]" <?php echo !is_null($mailgun_use_api_const) ? 'disabled="disabled"' : '' ?>>
134
- <option value="1"<?php selected('1', $mailgun_use_api); ?>><?php _e('Yes', 'mailgun'); ?></option>
135
- <option value="0"<?php selected('0', $mailgun_use_api); ?>><?php _e('No', 'mailgun'); ?></option>
136
- </select>
137
- <p class="description">
138
- <?php
139
- _e('Set this to "No" if your server cannot make outbound HTTP connections or if emails are not being delivered. "No" will cause this plugin to use SMTP. Default "Yes".', 'mailgun');
140
- ?>
141
- </p>
142
- </td>
143
- </tr>
144
- <tr valign="top">
145
- <th scope="row">
146
- <?php _e('Mailgun Domain Name', 'mailgun'); ?>
147
- </th>
148
- <td>
149
- <input type="text" class="regular-text"
150
- name="mailgun[domain]"
151
- value="<?php esc_attr_e($mailgun_domain); ?>"
152
- placeholder="samples.mailgun.org"
153
- <?php echo $mailgun_domain_const ? 'readonly="readonly"' : '' ?>
154
- />
155
- <p class="description">
156
- <?php _e('Your Mailgun Domain Name.', 'mailgun'); ?>
157
- </p>
158
- </td>
159
- </tr>
160
- <tr valign="top" class="mailgun-api">
161
- <th scope="row">
162
- <?php _e('API Key', 'mailgun'); ?>
163
- </th>
164
- <td>
165
- <input type="text" class="regular-text" name="mailgun[apiKey]"
166
- value="<?php esc_attr_e($mailgun_api_key); ?>"
167
- placeholder="key-3ax6xnjp29jd6fds4gc373sgvjxteol0"
168
- <?php echo $mailgun_api_key_const ? 'readonly="readonly"' : '' ?>
169
- />
170
- <p class="description">
171
- <?php
172
- _e('Your Mailgun Private API key. For more information on where to find your Private API key, see <a target="_blank" href="https://help.mailgun.com/hc/en-us/articles/203380100-Where-Can-I-Find-My-API-Key-and-SMTP-Credentials-">here</a>', 'mailgun');
173
- ?>
174
- </p>
175
- </td>
176
- </tr>
177
- <tr valign="top" class="mailgun-smtp">
178
- <th scope="row">
179
- <?php _e('Username', 'mailgun'); ?>
180
- </th>
181
- <td>
182
- <input type="text" class="regular-text"
183
- name="mailgun[username]"
184
- value="<?php esc_attr_e($mailgun_username); ?>"
185
- placeholder="postmaster"
186
- <?php echo $mailgun_username_const ? 'readonly="readonly"' : '' ?>
187
- />
188
- <p class="description">
189
- <?php
190
- _e('Your Mailgun SMTP username. Only valid for use with SMTP.', 'mailgun');
191
- ?>
192
- </p>
193
- </td>
194
- </tr>
195
- <tr valign="top" class="mailgun-smtp">
196
- <th scope="row">
197
- <?php _e('Password', 'mailgun'); ?>
198
- </th>
199
- <td>
200
- <input type="text" class="regular-text"
201
- name="mailgun[password]"
202
- value="<?php esc_attr_e($mailgun_password); ?>"
203
- placeholder="my-password"
204
- <?php echo $mailgun_password_const ? 'readonly="readonly"' : '' ?>
205
- />
206
- <p class="description">
207
- <?php
208
- _e('Your Mailgun SMTP password that goes with the above username. Only valid for use with SMTP.', 'mailgun');
209
- ?>
210
- </p>
211
- </td>
212
- </tr>
213
- <tr valign="top" class="mailgun-smtp">
214
- <th scope="row">
215
- <?php _e('Use Secure SMTP', 'mailgun'); ?>
216
- </th>
217
- <td>
218
- <?php if (!is_null($mailgun_secure_const)): ?>
219
- <input type="hidden" name="mailgun[secure]" value="<?php echo $mailgun_secure ?>">
220
- <?php endif ?>
 
221
 
222
- <select name="mailgun[secure]" <?php echo !is_null($mailgun_secure_const) ? 'disabled="disabled"' : '' ?>>
223
- <option value="1"<?php selected('1', $mailgun_secure); ?>><?php _e('Yes', 'mailgun'); ?></option>
224
- <option value="0"<?php selected('0', $mailgun_secure); ?>><?php _e('No', 'mailgun'); ?></option>
225
- </select>
226
- <p class="description">
227
- <?php
228
- _e('Set this to "No" if your server cannot establish SSL SMTP connections or if emails are not being delivered. If you set this to "No" your password will be sent in plain text. Only valid for use with SMTP. Default "Yes".', 'mailgun');
229
- ?>
230
- </p>
231
- </td>
232
- </tr>
233
- <tr valign="top" class="mailgun-smtp">
234
- <th scope="row">
235
- <?php _e('Security Type', 'mailgun'); ?>
236
- </th>
237
- <td>
238
- <?php if ($mailgun_sectype_const): ?>
239
- <input type="hidden" name="mailgun[sectype]" value="<?php echo $mailgun_sectype ?>">
240
- <?php endif ?>
241
 
242
- <select name="mailgun[sectype]" <?php echo $mailgun_sectype_const ? 'disabled="disabled"' : '' ?>>
243
- <option value="ssl"<?php selected('ssl', $mailgun_sectype); ?>>SSL</option>
244
- <option value="tls"<?php selected('tls', $mailgun_sectype); ?>>TLS</option>
245
- </select>
246
- <p class="description">
247
- <?php
248
- _e('Leave this at "TLS" unless mail sending fails. This option only matters for Secure SMTP. Default "TLS".', 'mailgun');
249
- ?>
250
- </p>
251
- </td>
252
- </tr>
253
- <tr valign="top">
254
- <th scope="row">
255
- <?php _e('Click Tracking', 'mailgun'); ?>
256
- </th>
257
- <td>
258
- <select name="mailgun[track-clicks]">
259
- <option value="htmlonly"<?php selected('htmlonly', $this->get_option('track-clicks')); ?>><?php _e('HTML Only', 'mailgun'); ?></option>
260
- <option value="yes"<?php selected('yes', $this->get_option('track-clicks')); ?>><?php _e('Yes', 'mailgun'); ?></option>
261
- <option value="no"<?php selected('no', $this->get_option('track-clicks')); ?>><?php _e('No', 'mailgun'); ?></option>
262
- </select>
263
- <p class="description">
264
- <?php
265
- $url = 'https://documentation.mailgun.com/en/latest/user_manual.html#tracking-clicks';
266
- $link = sprintf(
267
- wp_kses(
268
- __('If enabled, Mailgun will track links. <a href="%1$s" target="%2$s">Open Tracking Documentation</a>.', 'mailgun'),
269
- array('a' => array(
270
- 'href' => array(),
271
- 'target' => array()
272
- )
273
- )
274
- ), esc_url($url), '_blank'
275
- );
276
- echo $link;
277
- ?>
278
- </p>
279
- </td>
280
- </tr>
281
- <tr valign="top">
282
- <th scope="row">
283
- <?php _e('Open Tracking', 'mailgun'); ?>
284
- </th>
285
- <td>
286
- <select name="mailgun[track-opens]">
287
- <option value="1"<?php selected('1', $this->get_option('track-opens')); ?>><?php _e('Yes', 'mailgun'); ?></option>
288
- <option value="0"<?php selected('0', $this->get_option('track-opens')); ?>><?php _e('No', 'mailgun'); ?></option>
289
- </select>
290
- <p class="description">
291
- <?php
292
- $url = 'https://documentation.mailgun.com/en/latest/user_manual.html#tracking-opens';
293
- $link = sprintf(
294
- wp_kses(
295
- __('If enabled, HTML messages will include an open tracking beacon. <a href="%1$s" target="%2$s">Open Tracking Documentation</a>.', 'mailgun'),
296
- array('a' => array(
297
- 'href' => array(),
298
- 'target' => array()
299
- )
300
- )
301
- ), esc_url($url), '_blank'
302
- );
303
- echo $link;
304
- ?>
305
- </p>
306
- </td>
307
- </tr>
308
- <tr valign="top">
309
- <th scope="row">
310
- <?php _e('From Address', 'mailgun'); ?>
311
- </th>
312
- <td>
313
- <input type="text"
314
- class="regular-text"
315
- name="mailgun[from-address]"
316
- value="<?php esc_attr_e($mailgun_from_address); ?>"
317
- placeholder="wordpress@mydomain.com"
318
- <?php echo $mailgun_from_address_const ? 'readonly="readonly"' : '' ?>
319
- />
320
- <p class="description">
321
- <?php
322
- _e('The &lt;address@mydomain.com&gt; part of the sender information (<code>"Excited User &lt;user@samples.mailgun.org&gt;"</code>). This address will appear as the `From` address on sent mail. <strong>It is recommended that the @mydomain portion matches your Mailgun sending domain.</strong>', 'mailgun');
323
- ?>
324
- </p>
325
- </td>
326
- </tr>
327
- <tr valign="top">
328
- <th scope="row">
329
- <?php _e('From Name', 'mailgun'); ?>
330
- </th>
331
- <td>
332
- <input type="text" class="regular-text"
333
- name="mailgun[from-name]"
334
- value="<?php esc_attr_e($mailgun_from_name); ?>"
335
- placeholder="WordPress"
336
- <?php echo $mailgun_from_name_const ? 'readonly="readonly"' : '' ?>
337
- />
338
- <p class="description">
339
- <?php
340
- _e('The "User Name" part of the sender information (<code>"Excited User &lt;user@samples.mailgun.org&gt;"</code>).', 'mailgun');
341
- ?>
342
- </p>
343
- </td>
344
- </tr>
345
- <tr valign="top">
346
- <th scope="row">
347
- <?php _e('Override "From" Details', 'mailgun'); ?>
348
- </th>
349
- <td>
350
- <select name="mailgun[override-from]">
351
- <option value="1"<?php selected('1', $this->get_option('override-from', null, '0')); ?>><?php _e('Yes', 'mailgun'); ?></option>
352
- <option value="0"<?php selected('0', $this->get_option('override-from', null, '0')); ?>><?php _e('No', 'mailgun'); ?></option>
353
- </select>
354
- <p class="description">
355
- <?php
356
- _e('If enabled, all emails will be sent with the above "From Name" and "From Address", regardless of values set by other plugins. Useful for cases where other plugins don\'t play nice with our "From Name" / "From Address" setting.', 'mailgun');
357
- ?>
358
- </p>
359
- </td>
360
- </tr>
361
- <tr valign="top">
362
- <th scope="row">
363
- <?php _e('Tag', 'mailgun'); ?>
364
- </th>
365
- <td>
366
- <input type="text" class="regular-text"
367
- name="mailgun[campaign-id]"
368
- value="<?php esc_attr_e($this->get_option('campaign-id')); ?>"
369
- placeholder="tag"
370
- />
371
- <p class="description">
372
- <?php
373
- _e('If added, this tag will exist on every outbound message. Statistics will be populated in the Mailgun Control Panel. Use a comma to define multiple tags. ', 'mailgun');
374
- _e('Learn more about', 'mailgun');
375
 
376
- $url1 = 'https://documentation.mailgun.com/en/latest/user_manual.html#tracking-messages';
377
- $url2 = 'https://documentation.mailgun.com/en/latest/user_manual.html#tagging';
378
- $link = sprintf(
379
- wp_kses(
380
- __('<a href="%1$s" target="%3$s">Tracking</a> and <a href="%2$s" target="%3$s">Tagging</a>', 'mailgun'),
381
- array('a' => array(
382
- 'href' => array(),
383
- 'target' => array()
384
- )
385
- )
386
- ), esc_url($url1), esc_url($url2), '_blank'
387
- );
388
- echo $link;
389
- ?>
390
- </p>
391
- </td>
392
- </tr>
393
- </table>
394
- <h3><?php _e('Lists', 'mailgun'); ?></h3>
395
- <table class="form-table">
396
- <tr valign="top">
397
- <th scope="row">
398
- <?php _e('Shortcode', 'mailgun'); ?>
399
- </th>
400
- <td>
401
- <div>
402
- <code>[mailgun id="<em>{mailgun list id}</em>" collect_name="true"]</code>
403
- </div>
404
- <div>
405
- <p class="description">
406
- <?php
407
- _e('Use the shortcode above to associate a widget instance with a mailgun list', 'mailgun');
408
- ?>
409
- </p>
410
- </div>
411
- </td>
412
- </tr>
413
- <tr valign="top">
414
- <th scope="row">
415
- <?php _e('Lists', 'mailgun'); ?>
416
- </th>
417
- <td>
418
- <?php
419
- $url = '?page=mailgun-lists';
420
 
421
- $link = sprintf(
422
- wp_kses(
423
- __('<a href="%1$s" target="%2$s">View available lists</a>.', 'mailgun'),
424
- array('a' => array(
425
- 'href' => array(),
426
- )
427
- )
428
- ), esc_url($url)
429
- );
430
- echo $link;
431
- ?>
432
- </td>
433
- </tr>
434
- </table>
435
- <p>
436
- <?php
437
- _e('Before attempting to test the configuration, please click "Save Changes".', 'mailgun');
438
- ?>
439
- </p>
440
- <p class="submit">
441
- <input type="submit"
442
- class="button-primary"
443
- value="<?php _e('Save Changes', 'mailgun'); ?>"
444
- />
445
- <input type="button"
446
- id="mailgun-test"
447
- class="button-secondary"
448
- value="<?php _e('Test Configuration', 'mailgun'); ?>"
449
- />
450
- </p>
451
 
452
- <p>
453
- <?php _e("The configuration test email will be sent to your site's administrative email address:", 'mailgun'); ?> <?php echo esc_html(get_option('admin_email'));?>
454
- </p>
455
- </form>
456
  </div>
1
  <?php
2
 
3
+ /*
4
+ * mailgun-wordpress-plugin - Sending mail from Wordpress using Mailgun
5
+ * Copyright (C) 2016 Mailgun, et al.
6
+ *
7
+ * This program is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
 
22
+ $mailgun = Mailgun::getInstance();
23
 
24
  $mailgun_domain_const = ((defined('MAILGUN_DOMAIN') && MAILGUN_DOMAIN) ? MAILGUN_DOMAIN : null);
25
+ $mailgun_domain = $mailgun_domain_const ?: $this->get_option('domain');
26
 
27
  $mailgun_region_const = ((defined('MAILGUN_REGION') && MAILGUN_REGION) ? MAILGUN_REGION : null);
28
+ $mailgun_region = $mailgun_region_const ?: $this->get_option('region');
29
 
30
  $mailgun_api_key_const = ((defined('MAILGUN_APIKEY') && MAILGUN_APIKEY) ? MAILGUN_APIKEY : null);
31
+ $mailgun_api_key = $mailgun_api_key_const ?: $this->get_option('apiKey');
32
 
33
  $mailgun_username_const = ((defined('MAILGUN_USERNAME') && MAILGUN_USERNAME) ? MAILGUN_USERNAME : null);
34
+ $mailgun_username = $mailgun_username_const ?: $this->get_option('username');
35
 
36
  $mailgun_password_const = ((defined('MAILGUN_PASSWORD') && MAILGUN_PASSWORD) ? MAILGUN_PASSWORD : null);
37
+ $mailgun_password = $mailgun_password_const ?: $this->get_option('password');
38
 
39
  $mailgun_sectype_const = ((defined('MAILGUN_SECTYPE') && MAILGUN_SECTYPE) ? MAILGUN_SECTYPE : null);
40
+ $mailgun_sectype = $mailgun_sectype_const ?: $this->get_option('sectype');
41
 
42
  $mailgun_from_name_const = ((defined('MAILGUN_FROM_NAME') && MAILGUN_FROM_NAME) ? MAILGUN_FROM_NAME : null);
43
+ $mailgun_from_name = $mailgun_from_name_const ?: $this->get_option('from-name');
44
 
45
  $mailgun_from_address_const = ((defined('MAILGUN_FROM_ADDRESS') && MAILGUN_FROM_ADDRESS) ? MAILGUN_FROM_ADDRESS : null);
46
+ $mailgun_from_address = $mailgun_from_address_const ?: $this->get_option('from-address');
47
 
48
  $mailgun_secure_const = (defined('MAILGUN_SECURE') ? MAILGUN_SECURE : null);
49
  $mailgun_secure = !is_null($mailgun_secure_const) ? ((string)(1 * $mailgun_secure_const)) : $this->get_option('secure');
54
 
55
  ?>
56
  <div class="wrap">
57
+ <div id="icon-options-general" class="icon32"><br/></div>
58
+ <span class="alignright">
59
  <a target="_blank" href="http://www.mailgun.com/">
60
+ <img src="<?php echo $icon ?>" alt="Mailgun" style="width:50px;"/>
61
  </a>
62
  </span>
63
+ <h2><?php _e('Mailgun', 'mailgun'); ?></h2>
64
 
65
+ <p>
66
+ <?php
67
+ $url = 'https://www.mailgun.com';
68
+ $link = sprintf(
69
+ wp_kses(
70
+ __('A <a href="%1$s" target="%2$s">Mailgun</a> account is required to use this plugin and the Mailgun service.', 'mailgun'),
71
+ array('a' => array(
72
+ 'href' => array(),
73
+ 'target' => array()
74
+ )
75
+ )
76
+ ), esc_url($url), '_blank'
77
+ );
78
+ echo $link;
79
+ ?>
80
+ </p>
81
 
82
+ <p>
83
+ <?php
84
+ $url = 'https://signup.mailgun.com/new/signup';
85
+ $link = sprintf(
86
+ wp_kses(
87
+ __('If you need to register for an account, you can do so at <a href="%1$s" target="%2$s">Mailgun.com</a>.', 'mailgun'),
88
+ array('a' => array(
89
+ 'href' => array(),
90
+ 'target' => array()
91
+ )
92
+ )
93
+ ), esc_url($url), '_blank'
94
+ );
95
+ echo $link;
96
+ ?>
97
+ </p>
98
 
99
+ <h3><?php _e('Configuration', 'mailgun'); ?></h3>
100
+ <form id="mailgun-form" action="options.php" method="post">
101
+ <?php settings_fields('mailgun'); ?>
102
 
103
+ <table class="form-table">
104
+ <tr valign="top">
105
+ <th scope="row">
106
+ <?php _e('Select Your Region', 'mailgun'); ?>
107
+ </th>
108
+ <td>
109
+ <?php if ($mailgun_region_const): ?>
110
+ <input type="hidden" name="mailgun[region]" value="<?php echo $mailgun_region ?>">
111
+ <?php endif ?>
112
 
113
+ <select id="mailgun-region"
114
+ name="mailgun[region]" <?php echo $mailgun_region_const ? 'disabled="disabled"' : '' ?>>
115
+ <option value="us"<?php selected('us', $mailgun_region); ?>><?php _e('U.S./North America', 'mailgun') ?></option>
116
+ <option value="eu"<?php selected('eu', $mailgun_region); ?>><?php _e('Europe', 'mailgun') ?></option>
117
+ </select>
118
+ <p class="description">
119
+ <?php
120
+ _e('Choose a region - U.S./North America or Europe - from which to send email, and to store your customer data. Please note that your sending domain must be set up in whichever region you choose.', 'mailgun');
121
+ ?>
122
+ </p>
123
+ </td>
124
+ </tr>
125
+ <tr valign="top">
126
+ <th scope="row">
127
+ <?php _e('Use HTTP API', 'mailgun'); ?>
128
+ </th>
129
+ <td>
130
+ <?php if (!is_null($mailgun_use_api_const)): ?>
131
+ <input type="hidden" name="mailgun[useAPI]" value="<?php echo $mailgun_use_api ?>">
132
+ <?php endif ?>
133
 
134
+ <select id="mailgun-api"
135
+ name="mailgun[useAPI]" <?php echo !is_null($mailgun_use_api_const) ? 'disabled="disabled"' : '' ?>>
136
+ <option value="1"<?php selected('1', $mailgun_use_api); ?>><?php _e('Yes', 'mailgun'); ?></option>
137
+ <option value="0"<?php selected('0', $mailgun_use_api); ?>><?php _e('No', 'mailgun'); ?></option>
138
+ </select>
139
+ <p class="description">
140
+ <?php
141
+ _e('Set this to "No" if your server cannot make outbound HTTP connections or if emails are not being delivered. "No" will cause this plugin to use SMTP. Default "Yes".', 'mailgun');
142
+ ?>
143
+ </p>
144
+ </td>
145
+ </tr>
146
+ <tr valign="top">
147
+ <th scope="row">
148
+ <?php _e('Mailgun Domain Name', 'mailgun'); ?>
149
+ </th>
150
+ <td>
151
+ <input type="text" class="regular-text"
152
+ name="mailgun[domain]"
153
+ value="<?php esc_attr_e($mailgun_domain); ?>"
154
+ placeholder="samples.mailgun.org"
155
+ <?php echo $mailgun_domain_const ? 'readonly="readonly"' : '' ?>
156
+ />
157
+ <p class="description">
158
+ <?php _e('Your Mailgun Domain Name.', 'mailgun'); ?>
159
+ </p>
160
+ </td>
161
+ </tr>
162
+ <tr valign="top" class="mailgun-api">
163
+ <th scope="row">
164
+ <?php _e('API Key', 'mailgun'); ?>
165
+ </th>
166
+ <td>
167
+ <input type="text" class="regular-text" name="mailgun[apiKey]"
168
+ value="<?php esc_attr_e($mailgun_api_key); ?>"
169
+ placeholder="key-3ax6xnjp29jd6fds4gc373sgvjxteol0"
170
+ <?php echo $mailgun_api_key_const ? 'readonly="readonly"' : '' ?>
171
+ />
172
+ <p class="description">
173
+ <?php
174
+ _e('Your Mailgun Private API key. For more information on where to find your Private API key, see <a target="_blank" href="https://help.mailgun.com/hc/en-us/articles/203380100-Where-Can-I-Find-My-API-Key-and-SMTP-Credentials-">here</a>', 'mailgun');
175
+ ?>
176
+ </p>
177
+ </td>
178
+ </tr>
179
+ <tr valign="top" class="mailgun-smtp">
180
+ <th scope="row">
181
+ <?php _e('Username', 'mailgun'); ?>
182
+ </th>
183
+ <td>
184
+ <input type="text" class="regular-text"
185
+ name="mailgun[username]"
186
+ value="<?php esc_attr_e($mailgun_username); ?>"
187
+ placeholder="postmaster"
188
+ <?php echo $mailgun_username_const ? 'readonly="readonly"' : '' ?>
189
+ />
190
+ <p class="description">
191
+ <?php
192
+ _e('Your Mailgun SMTP username. Only valid for use with SMTP.', 'mailgun');
193
+ ?>
194
+ </p>
195
+ </td>
196
+ </tr>
197
+ <tr valign="top" class="mailgun-smtp">
198
+ <th scope="row">
199
+ <?php _e('Password', 'mailgun'); ?>
200
+ </th>
201
+ <td>
202
+ <input type="text" class="regular-text"
203
+ name="mailgun[password]"
204
+ value="<?php esc_attr_e($mailgun_password); ?>"
205
+ placeholder="my-password"
206
+ <?php echo $mailgun_password_const ? 'readonly="readonly"' : '' ?>
207
+ />
208
+ <p class="description">
209
+ <?php
210
+ _e('Your Mailgun SMTP password that goes with the above username. Only valid for use with SMTP.', 'mailgun');
211
+ ?>
212
+ </p>
213
+ </td>
214
+ </tr>
215
+ <tr valign="top" class="mailgun-smtp">
216
+ <th scope="row">
217
+ <?php _e('Use Secure SMTP', 'mailgun'); ?>
218
+ </th>
219
+ <td>
220
+ <?php if (!is_null($mailgun_secure_const)): ?>
221
+ <input type="hidden" name="mailgun[secure]" value="<?php echo $mailgun_secure ?>">
222
+ <?php endif ?>
223
 
224
+ <select name="mailgun[secure]" <?php echo !is_null($mailgun_secure_const) ? 'disabled="disabled"' : '' ?>>
225
+ <option value="1"<?php selected('1', $mailgun_secure); ?>><?php _e('Yes', 'mailgun'); ?></option>
226
+ <option value="0"<?php selected('0', $mailgun_secure); ?>><?php _e('No', 'mailgun'); ?></option>
227
+ </select>
228
+ <p class="description">
229
+ <?php
230
+ _e('Set this to "No" if your server cannot establish SSL SMTP connections or if emails are not being delivered. If you set this to "No" your password will be sent in plain text. Only valid for use with SMTP. Default "Yes".', 'mailgun');
231
+ ?>
232
+ </p>
233
+ </td>
234
+ </tr>
235
+ <tr valign="top" class="mailgun-smtp">
236
+ <th scope="row">
237
+ <?php _e('Security Type', 'mailgun'); ?>
238
+ </th>
239
+ <td>
240
+ <?php if ($mailgun_sectype_const): ?>
241
+ <input type="hidden" name="mailgun[sectype]" value="<?php echo $mailgun_sectype ?>">
242
+ <?php endif ?>
243
 
244
+ <select name="mailgun[sectype]" <?php echo $mailgun_sectype_const ? 'disabled="disabled"' : '' ?>>
245
+ <option value="ssl"<?php selected('ssl', $mailgun_sectype); ?>>SSL</option>
246
+ <option value="tls"<?php selected('tls', $mailgun_sectype); ?>>TLS</option>
247
+ </select>
248
+ <p class="description">
249
+ <?php
250
+ _e('Leave this at "TLS" unless mail sending fails. This option only matters for Secure SMTP. Default "TLS".', 'mailgun');
251
+ ?>
252
+ </p>
253
+ </td>
254
+ </tr>
255
+ <tr valign="top">
256
+ <th scope="row">
257
+ <?php _e('Click Tracking', 'mailgun'); ?>
258
+ </th>
259
+ <td>
260
+ <select name="mailgun[track-clicks]">
261
+ <option value="htmlonly"<?php selected('htmlonly', $this->get_option('track-clicks')); ?>><?php _e('HTML Only', 'mailgun'); ?></option>
262
+ <option value="yes"<?php selected('yes', $this->get_option('track-clicks')); ?>><?php _e('Yes', 'mailgun'); ?></option>
263
+ <option value="no"<?php selected('no', $this->get_option('track-clicks')); ?>><?php _e('No', 'mailgun'); ?></option>
264
+ </select>
265
+ <p class="description">
266
+ <?php
267
+ $url = 'https://documentation.mailgun.com/en/latest/user_manual.html#tracking-clicks';
268
+ $link = sprintf(
269
+ wp_kses(
270
+ __('If enabled, Mailgun will track links. <a href="%1$s" target="%2$s">Open Tracking Documentation</a>.', 'mailgun'),
271
+ array('a' => array(
272
+ 'href' => array(),
273
+ 'target' => array()
274
+ )
275
+ )
276
+ ), esc_url($url), '_blank'
277
+ );
278
+ echo $link;
279
+ ?>
280
+ </p>
281
+ </td>
282
+ </tr>
283
+ <tr valign="top">
284
+ <th scope="row">
285
+ <?php _e('Open Tracking', 'mailgun'); ?>
286
+ </th>
287
+ <td>
288
+ <select name="mailgun[track-opens]">
289
+ <option value="1"<?php selected('1', $this->get_option('track-opens')); ?>><?php _e('Yes', 'mailgun'); ?></option>
290
+ <option value="0"<?php selected('0', $this->get_option('track-opens')); ?>><?php _e('No', 'mailgun'); ?></option>
291
+ </select>
292
+ <p class="description">
293
+ <?php
294
+ $url = 'https://documentation.mailgun.com/en/latest/user_manual.html#tracking-opens';
295
+ $link = sprintf(
296
+ wp_kses(
297
+ __('If enabled, HTML messages will include an open tracking beacon. <a href="%1$s" target="%2$s">Open Tracking Documentation</a>.', 'mailgun'),
298
+ array('a' => array(
299
+ 'href' => array(),
300
+ 'target' => array()
301
+ )
302
+ )
303
+ ), esc_url($url), '_blank'
304
+ );
305
+ echo $link;
306
+ ?>
307
+ </p>
308
+ </td>
309
+ </tr>
310
+ <tr valign="top">
311
+ <th scope="row">
312
+ <?php _e('From Address', 'mailgun'); ?>
313
+ </th>
314
+ <td>
315
+ <input type="text"
316
+ class="regular-text"
317
+ name="mailgun[from-address]"
318
+ value="<?php esc_attr_e($mailgun_from_address); ?>"
319
+ placeholder="wordpress@mydomain.com"
320
+ <?php echo $mailgun_from_address_const ? 'readonly="readonly"' : '' ?>
321
+ />
322
+ <p class="description">
323
+ <?php
324
+ _e('The &lt;address@mydomain.com&gt; part of the sender information (<code>"Excited User &lt;user@samples.mailgun.org&gt;"</code>). This address will appear as the `From` address on sent mail. <strong>It is recommended that the @mydomain portion matches your Mailgun sending domain.</strong>', 'mailgun');
325
+ ?>
326
+ </p>
327
+ </td>
328
+ </tr>
329
+ <tr valign="top">
330
+ <th scope="row">
331
+ <?php _e('From Name', 'mailgun'); ?>
332
+ </th>
333
+ <td>
334
+ <input type="text" class="regular-text"
335
+ name="mailgun[from-name]"
336
+ value="<?php esc_attr_e($mailgun_from_name); ?>"
337
+ placeholder="WordPress"
338
+ <?php echo $mailgun_from_name_const ? 'readonly="readonly"' : '' ?>
339
+ />
340
+ <p class="description">
341
+ <?php
342
+ _e('The "User Name" part of the sender information (<code>"Excited User &lt;user@samples.mailgun.org&gt;"</code>).', 'mailgun');
343
+ ?>
344
+ </p>
345
+ </td>
346
+ </tr>
347
+ <tr valign="top">
348
+ <th scope="row">
349
+ <?php _e('Override "From" Details', 'mailgun'); ?>
350
+ </th>
351
+ <td>
352
+ <select name="mailgun[override-from]">
353
+ <option value="1"<?php selected('1', (int)$this->get_option('override-from')); ?>><?php _e('Yes', 'mailgun'); ?></option>
354
+ <option value="0"<?php selected('0', (int)$this->get_option('override-from')); ?>><?php _e('No', 'mailgun'); ?></option>
355
+ </select>
356
+ <p class="description">
357
+ <?php
358
+ _e('If enabled, all emails will be sent with the above "From Name" and "From Address", regardless of values set by other plugins. Useful for cases where other plugins don\'t play nice with our "From Name" / "From Address" setting.', 'mailgun');
359
+ ?>
360
+ </p>
361
+ </td>
362
+ </tr>
363
+ <tr valign="top">
364
+ <th scope="row">
365
+ <?php _e('Tag', 'mailgun'); ?>
366
+ </th>
367
+ <td>
368
+ <input type="text" class="regular-text"
369
+ name="mailgun[campaign-id]"
370
+ value="<?php esc_attr_e($this->get_option('campaign-id')); ?>"
371
+ placeholder="tag"
372
+ />
373
+ <p class="description">
374
+ <?php
375
+ _e('If added, this tag will exist on every outbound message. Statistics will be populated in the Mailgun Control Panel. Use a comma to define multiple tags. ', 'mailgun');
376
+ _e('Learn more about', 'mailgun');
377
 
378
+ $url1 = 'https://documentation.mailgun.com/en/latest/user_manual.html#tracking-messages';
379
+ $url2 = 'https://documentation.mailgun.com/en/latest/user_manual.html#tagging';
380
+ $link = sprintf(
381
+ wp_kses(
382
+ __('<a href="%1$s" target="%3$s">Tracking</a> and <a href="%2$s" target="%3$s">Tagging</a>', 'mailgun'),
383
+ array('a' => array(
384
+ 'href' => array(),
385
+ 'target' => array()
386
+ )
387
+ )
388
+ ), esc_url($url1), esc_url($url2), '_blank'
389
+ );
390
+ echo $link;
391
+ ?>
392
+ </p>
393
+ </td>
394
+ </tr>
395
+ </table>
396
+ <h3><?php _e('Lists', 'mailgun'); ?></h3>
397
+ <table class="form-table">
398
+ <tr valign="top">
399
+ <th scope="row">
400
+ <?php _e('Shortcode', 'mailgun'); ?>
401
+ </th>
402
+ <td>
403
+ <div>
404
+ <code>[mailgun id="<em>{mailgun list id}</em>" collect_name="true"]</code>
405
+ </div>
406
+ <div>
407
+ <p class="description">
408
+ <?php
409
+ _e('Use the shortcode above to associate a widget instance with a mailgun list', 'mailgun');
410
+ ?>
411
+ </p>
412
+ </div>
413
+ </td>
414
+ </tr>
415
+ <tr valign="top">
416
+ <th scope="row">
417
+ <?php _e('Lists', 'mailgun'); ?>
418
+ </th>
419
+ <td>
420
+ <?php
421
+ $url = '?page=mailgun-lists';
422
 
423
+ $link = sprintf(
424
+ wp_kses(
425
+ __('<a href="%1$s" target="%2$s">View available lists</a>.', 'mailgun'),
426
+ array('a' => array(
427
+ 'href' => array(),
428
+ )
429
+ )
430
+ ), esc_url($url)
431
+ );
432
+ echo $link;
433
+ ?>
434
+ </td>
435
+ </tr>
436
+ </table>
437
+ <p>
438
+ <?php
439
+ _e('Before attempting to test the configuration, please click "Save Changes".', 'mailgun');
440
+ ?>
441
+ </p>
442
+ <p class="submit">
443
+ <input type="submit"
444
+ class="button-primary"
445
+ value="<?php _e('Save Changes', 'mailgun'); ?>"
446
+ />
447
+ <input type="button"
448
+ id="mailgun-test"
449
+ class="button-secondary"
450
+ value="<?php _e('Test Configuration', 'mailgun'); ?>"
451
+ />
452
+ </p>
453
 
454
+ <p>
455
+ <?php _e("The configuration test email will be sent to your site's administrative email address:", 'mailgun'); ?><?php echo esc_html(get_option('admin_email')); ?>
456
+ </p>
457
+ </form>
458
  </div>
includes/widget.php CHANGED
@@ -19,7 +19,7 @@
19
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
  */
21
 
22
- class list_widget extends WP_Widget
23
  {
24
  public function __construct()
25
  {
@@ -37,8 +37,11 @@ class list_widget extends WP_Widget
37
  // This is where the action happens
38
  public function widget($args, $instance)
39
  {
40
- global $mailgun;
41
 
 
 
 
42
  // vars
43
  $list_address = apply_filters('list_address', $instance['list_address']);
44
 
@@ -60,8 +63,6 @@ class list_widget extends WP_Widget
60
  // Widget Backend
61
  public function form($instance)
62
  {
63
- global $mailgun;
64
-
65
  if (isset($instance['list_address'])) {
66
  $list_address = $instance['list_address'];
67
  } else {
@@ -74,8 +75,8 @@ class list_widget extends WP_Widget
74
  $collect_name = '';
75
  }
76
 
77
- $list_title = isset($instance['list_title']) ? $instance['list_title'] : null;
78
- $list_description = isset($instance['list_description']) ? $instance['list_description'] : null;
79
 
80
  // Widget admin form
81
  ?>
19
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
  */
21
 
22
+ class list_widget extends \WP_Widget
23
  {
24
  public function __construct()
25
  {
37
  // This is where the action happens
38
  public function widget($args, $instance)
39
  {
40
+ $mailgun = Mailgun::getInstance();
41
 
42
+ if (!isset($instance['list_address']) || !$instance['list_address']) {
43
+ return;
44
+ }
45
  // vars
46
  $list_address = apply_filters('list_address', $instance['list_address']);
47
 
63
  // Widget Backend
64
  public function form($instance)
65
  {
 
 
66
  if (isset($instance['list_address'])) {
67
  $list_address = $instance['list_address'];
68
  } else {
75
  $collect_name = '';
76
  }
77
 
78
+ $list_title = $instance['list_title'] ?? null;
79
+ $list_description = $instance['list_description'] ?? null;
80
 
81
  // Widget admin form
82
  ?>
includes/wp-mail-api.php CHANGED
@@ -20,19 +20,19 @@
20
  */
21
 
22
  // Include MG filter functions
23
- if (!include dirname(__FILE__).'/mg-filter.php') {
24
- Mailgun::deactivate_and_die(dirname(__FILE__).'/mg-filter.php');
25
  }
26
 
27
  /**
28
  * mg_api_last_error is a compound getter/setter for the last error that was
29
  * encountered during a Mailgun API call.
30
  *
31
- * @param string $error OPTIONAL
32
  *
33
- * @return string Last error that occurred.
34
  *
35
- * @since 1.5.0
36
  */
37
  function mg_api_last_error($error = null)
38
  {
@@ -40,12 +40,12 @@ function mg_api_last_error($error = null)
40
 
41
  if (null === $error) {
42
  return $last_error;
43
- } else {
44
- $tmp = $last_error;
45
- $last_error = $error;
46
-
47
- return $tmp;
48
  }
 
 
 
 
 
49
  }
50
 
51
  /*
@@ -79,14 +79,14 @@ function mg_mutate_to_rcpt_vars_cb($to_addrs)
79
 
80
  // TODO: Also add folding to prevent hitting the 998 char limit on headers.
81
  return array(
82
- 'to' => '%recipient%',
83
  'rcpt_vars' => json_encode($rcpt_vars),
84
  );
85
  }
86
  }
87
 
88
  return array(
89
- 'to' => $to_addrs,
90
  'rcpt_vars' => null,
91
  );
92
  }
@@ -98,365 +98,354 @@ function mg_mutate_to_rcpt_vars_cb($to_addrs)
98
  * Based off of the core wp_mail function, but with modifications required to
99
  * send email using the Mailgun HTTP API
100
  *
101
- * @param string|array $to Array or comma-separated list of email addresses to send message.
102
- * @param string $subject Email subject
103
- * @param string $message Message contents
104
- * @param string|array $headers Optional. Additional headers.
105
- * @param string|array $attachments Optional. Files to attach.
106
  *
107
- * @return bool Whether the email contents were sent successfully.
108
  *
109
  * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
110
  *
111
- * @since 0.1
112
  */
113
  if (!function_exists('wp_mail')) {
114
- function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
115
- {
116
- // Compact the input, apply the filters, and extract them back out
117
- extract(apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments')));
 
 
 
 
118
 
119
- $mailgun = get_option('mailgun');
120
- $region = (defined('MAILGUN_REGION') && MAILGUN_REGION) ? MAILGUN_REGION : $mailgun['region'];
121
- $apiKey = (defined('MAILGUN_APIKEY') && MAILGUN_APIKEY) ? MAILGUN_APIKEY : $mailgun['apiKey'];
122
- $domain = (defined('MAILGUN_DOMAIN') && MAILGUN_DOMAIN) ? MAILGUN_DOMAIN : $mailgun['domain'];
123
 
124
- if (empty($apiKey) || empty($domain)) {
125
- return false;
126
- }
127
 
128
- // If a region is not set via defines or through the options page, default to US region.
129
- if (!((bool) $region)) {
130
- error_log('[Mailgun] No region configuration was found! Defaulting to US region.');
131
- $region = 'us';
132
- }
133
 
134
- if (!is_array($attachments)) {
135
- $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
136
- }
137
 
138
- // Headers
139
- if (empty($headers)) {
140
- $headers = array();
141
- } else {
142
- if (!is_array($headers)) {
143
- // Explode the headers out, so this function can take both
144
- // string headers and an array of headers.
145
- $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
146
  } else {
147
- $tempheaders = $headers;
148
- }
149
- $headers = array();
150
- $cc = array();
151
- $bcc = array();
152
-
153
- // If it's actually got contents
154
- if (!empty($tempheaders)) {
155
- // Iterate through the raw headers
156
- foreach ((array) $tempheaders as $header) {
157
- if (strpos($header, ':') === false) {
158
- if (false !== stripos($header, 'boundary=')) {
159
- $parts = preg_split('/boundary=/i', trim($header));
160
- $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
161
- }
162
- continue;
163
- }
164
- // Explode them out
165
- list($name, $content) = explode(':', trim($header), 2);
166
-
167
- // Cleanup crew
168
- $name = trim($name);
169
- $content = trim($content);
170
-
171
- switch (strtolower($name)) {
172
- // Mainly for legacy -- process a From: header if it's there
173
- case 'from':
174
- if (strpos($content, '<') !== false) {
175
- // So... making my life hard again?
176
- $from_name = substr($content, 0, strpos($content, '<') - 1);
177
- $from_name = str_replace('"', '', $from_name);
178
- $from_name = trim($from_name);
179
-
180
- $from_email = substr($content, strpos($content, '<') + 1);
181
- $from_email = str_replace('>', '', $from_email);
182
- $from_email = trim($from_email);
183
- } else {
184
- $from_email = trim($content);
185
- }
186
- break;
187
- case 'content-type':
188
- if (strpos($content, ';') !== false) {
189
- list($type, $charset) = explode(';', $content);
190
- $content_type = trim($type);
191
- if (false !== stripos($charset, 'charset=')) {
192
- $charset = trim(str_replace(array('charset=', '"'), '', $charset));
193
- } elseif (false !== stripos($charset, 'boundary=')) {
194
- $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
195
- $charset = '';
196
  }
197
- } else {
198
- $content_type = trim($content);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  }
200
- break;
201
- case 'cc':
202
- $cc = array_merge((array) $cc, explode(',', $content));
203
- break;
204
- case 'bcc':
205
- $bcc = array_merge((array) $bcc, explode(',', $content));
206
- break;
207
- default:
208
- // Add it to our grand headers array
209
- $headers[trim($name)] = trim($content);
210
- break;
211
  }
212
  }
213
  }
214
- }
215
-
216
- if (!isset($from_name)) {
217
- $from_name = null;
218
- }
219
 
220
- if (!isset($from_email)) {
221
- $from_email = null;
222
- }
223
 
224
- $from_name = mg_detect_from_name($from_name);
225
- $from_email = mg_detect_from_address($from_email);
 
226
 
227
- $body = array(
228
- 'from' => "{$from_name} <{$from_email}>",
229
- 'to' => $to,
230
- 'subject' => $subject,
231
- );
232
 
233
- $rcpt_data = apply_filters('mg_mutate_to_rcpt_vars', $to);
234
- if (!is_null($rcpt_data['rcpt_vars'])) {
235
- $body['recipient-variables'] = $rcpt_data['rcpt_vars'];
236
- }
 
237
 
238
- $body['o:tag'] = array();
239
- $body['o:tracking-clicks'] = !empty($mailgun['track-clicks']) ? $mailgun['track-clicks'] : 'no';
240
- $body['o:tracking-opens'] = empty($mailgun['track-opens']) ? 'no' : 'yes';
 
241
 
242
- // this is the wordpress site tag
243
- if (isset($mailgun['tag'])) {
244
- $tags = explode(',', str_replace(' ', '', $mailgun['tag']));
245
- $body['o:tag'] = $tags;
246
- }
247
 
248
- // campaign-id now refers to a list of tags which will be appended to the site tag
249
- if (!empty($mailgun['campaign-id'])) {
250
- $tags = explode(',', str_replace(' ', '', $mailgun['campaign-id']));
251
- if (empty($body['o:tag'])) {
252
  $body['o:tag'] = $tags;
253
- } elseif (is_array($body['o:tag'])) {
254
- $body['o:tag'] = array_merge($body['o:tag'], $tags);
255
- } else {
256
- $body['o:tag'] .= ','.$tags;
257
  }
258
- }
259
 
260
- /**
261
- * Filter tags.
262
- *
263
- * @param array $tags Mailgun tags.
264
- * @param string $to To address.
265
- * @param string $subject Subject line.
266
- * @param string $message Message content.
267
- * @param array $headers Headers array.
268
- * @param array $attachments Attachments array.
269
- * @param string $region Mailgun region.
270
- * @param string $domain Mailgun domain.
271
- *
272
- * @return array Mailgun tags.
273
- */
274
- $body['o:tag'] = apply_filters( 'mailgun_tags', $body['o:tag'], $to, $subject, $message, $headers, $attachments, $region, $domain );
275
-
276
- if (!empty($cc) && is_array($cc)) {
277
- $body['cc'] = implode(', ', $cc);
278
- }
279
 
280
- if (!empty($bcc) && is_array($bcc)) {
281
- $body['bcc'] = implode(', ', $bcc);
282
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
 
284
- // If we are not given a Content-Type in the supplied headers,
285
- // write the message body to a file and try to determine the mimetype
286
- // using get_mime_content_type.
287
- if (!isset($content_type)) {
288
- $tmppath = tempnam(get_temp_dir(), 'mg');
289
- $tmp = fopen($tmppath, 'w+');
290
 
291
- fwrite($tmp, $message);
292
- fclose($tmp);
 
 
 
 
293
 
294
- $content_type = get_mime_content_type($tmppath, 'text/plain');
 
295
 
296
- unlink($tmppath);
297
- }
298
 
299
- // Allow external content type filter to function normally
300
- if (has_filter('wp_mail_content_type')) {
301
- $content_type = apply_filters(
302
- 'wp_mail_content_type',
303
- $content_type
304
- );
305
- }
306
 
307
- if ('text/plain' === $content_type) {
308
- $body['text'] = $message;
309
- } else if ('text/html' === $content_type) {
310
- $body['html'] = $message;
311
- } else {
312
- // Unknown Content-Type??
313
- error_log('[mailgun] Got unknown Content-Type: ' . $content_type);
314
- $body['text'] = $message;
315
- $body['html'] = $message;
316
- }
317
 
318
- // Some plugins, such as WooCommerce (@see WC_Email::handle_multipart()), to handle multipart/alternative with html
319
- // and plaintext messages hooks into phpmailer_init action to override AltBody property directly in $phpmailer,
320
- // so we should allow them to do this, and then get overridden plain text body from $phpmailer.
321
- // Partly, this logic is taken from original wp_mail function.
322
- if (false !== stripos($content_type, 'multipart')) {
323
- global $phpmailer;
324
-
325
- // (Re)create it, if it's gone missing.
326
- if (!($phpmailer instanceof PHPMailer\PHPMailer\PHPMailer)) {
327
- require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
328
- require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
329
- require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
330
- $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
331
-
332
- $phpmailer::$validator = static function ($email) {
333
- return (bool)is_email($email);
334
- };
335
  }
336
 
337
- /**
338
- * Fires after PHPMailer is initialized.
339
- *
340
- * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
341
- */
342
- do_action_ref_array('phpmailer_init', array(&$phpmailer));
 
 
 
 
 
 
 
 
 
 
 
 
343
 
344
- $plainTextMessage = $phpmailer->AltBody;
 
 
 
 
 
345
 
346
- if ($plainTextMessage) {
347
- $body['text'] = $plainTextMessage;
 
 
 
348
  }
349
- }
350
 
351
- // If we don't have a charset from the input headers
352
- if (!isset($charset)) {
353
- $charset = get_bloginfo('charset');
354
- }
355
 
356
- // Set the content-type and charset
357
- $charset = apply_filters('wp_mail_charset', $charset);
358
- if (isset($headers['Content-Type'])) {
359
- if (!strstr($headers['Content-Type'], 'charset')) {
360
- $headers['Content-Type'] = rtrim($headers['Content-Type'], '; ')."; charset={$charset}";
 
361
  }
362
- }
363
 
364
- // Set custom headers
365
- if (!empty($headers)) {
366
- foreach ((array) $headers as $name => $content) {
367
- $body["h:{$name}"] = $content;
 
368
  }
369
 
370
- // TODO: Can we handle this?
371
- //if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) )
372
- // $phpmailer->AddCustomHeader( sprintf( "Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) );
373
- }
 
374
 
375
- /*
376
- * Deconstruct post array and create POST payload.
377
- * This entire routine is because wp_remote_post does
378
- * not support files directly.
379
- */
380
 
381
- $payload = '';
 
382
 
383
- // First, generate a boundary for the multipart message.
384
- $boundary = sha1(uniqid('', true));
 
 
 
385
 
386
- // Allow other plugins to apply body changes before creating the payload.
387
- $body = apply_filters('mg_mutate_message_body', $body);
388
- if ( ($body_payload = mg_build_payload_from_body($body, $boundary)) != null ) {
389
- $payload .= $body_payload;
390
- }
391
 
392
- // TODO: Special handling for multipart/alternative mail
393
- // if ('multipart/alternative' === $content_type) {
394
- // // Build payload from mime
395
- // // error_log(sprintf('building message payload from multipart/alternative'));
396
- // // error_log($body['message']);
397
- // // error_log('Attachments:');
398
- // // foreach ($attachments as $attachment) {
399
- // // error_log($attachment);
400
- // // }
401
- // }
402
-
403
- // Allow other plugins to apply attachment changes before writing to the payload.
404
- $attachments = apply_filters('mg_mutate_attachments', $attachments);
405
- if ( ($attachment_payload = mg_build_attachments_payload($attachments, $boundary)) != null ) {
406
- $payload .= $attachment_payload;
407
- }
408
 
409
- $payload .= '--'.$boundary.'--';
 
 
 
 
 
 
410
 
411
- $data = array(
412
- 'body' => $payload,
413
- 'headers' => array(
414
- 'Authorization' => 'Basic '.base64_encode("api:{$apiKey}"),
415
- 'Content-Type' => 'multipart/form-data; boundary='.$boundary,
416
- ),
417
- );
418
 
419
- $endpoint = mg_api_get_region($region);
420
- $endpoint = ($endpoint) ? $endpoint : 'https://api.mailgun.net/v3/';
421
- $url = $endpoint."{$domain}/messages";
 
 
 
422
 
423
- // TODO: Mailgun only supports 1000 recipients per request, since we are
424
- // overriding this function, let's add looping here to handle that
425
- $response = wp_remote_post($url, $data);
426
- if (is_wp_error($response)) {
427
- // Store WP error in last error.
428
- mg_api_last_error($response->get_error_message());
429
 
430
- return false;
431
- }
432
 
433
- $response_code = wp_remote_retrieve_response_code($response);
434
- $response_body = json_decode(wp_remote_retrieve_body($response));
 
 
 
 
 
 
435
 
436
- // Mailgun API should *always* return a `message` field, even when
437
- // $response_code != 200, so a lack of `message` indicates something
438
- // is broken.
439
- if ((int) $response_code != 200 || !isset($response_body->message)) {
440
- // Store response code and HTTP response message in last error.
441
- $response_message = wp_remote_retrieve_response_message($response);
442
- $errmsg = "$response_code - $response_message";
443
- mg_api_last_error($errmsg);
444
 
445
- return false;
446
- }
 
447
 
448
- // Not sure there is any additional checking that needs to be done here, but why not?
449
- if ($response_body->message != 'Queued. Thank you.') {
450
- mg_api_last_error($response_body->message);
451
 
452
- return false;
453
  }
454
-
455
- return true;
456
- }
457
  }
458
 
459
- function mg_build_payload_from_body($body, $boundary) {
 
460
  $payload = '';
461
 
462
  // Iterate through pre-built params and build payload:
@@ -464,16 +453,16 @@ function mg_build_payload_from_body($body, $boundary) {
464
  if (is_array($value)) {
465
  $parent_key = $key;
466
  foreach ($value as $key => $value) {
467
- $payload .= '--'.$boundary;
468
  $payload .= "\r\n";
469
- $payload .= 'Content-Disposition: form-data; name="'.$parent_key."\"\r\n\r\n";
470
  $payload .= $value;
471
  $payload .= "\r\n";
472
  }
473
  } else {
474
- $payload .= '--'.$boundary;
475
  $payload .= "\r\n";
476
- $payload .= 'Content-Disposition: form-data; name="'.$key.'"'."\r\n\r\n";
477
  $payload .= $value;
478
  $payload .= "\r\n";
479
  }
@@ -482,10 +471,8 @@ function mg_build_payload_from_body($body, $boundary) {
482
  return $payload;
483
  }
484
 
485
- function mg_build_payload_from_mime($body, $boundary) {
486
- }
487
-
488
- function mg_build_attachments_payload($attachments, $boundary) {
489
  $payload = '';
490
 
491
  // If we have attachments, add them to the payload.
@@ -493,9 +480,9 @@ function mg_build_attachments_payload($attachments, $boundary) {
493
  $i = 0;
494
  foreach ($attachments as $attachment) {
495
  if (!empty($attachment)) {
496
- $payload .= '--'.$boundary;
497
  $payload .= "\r\n";
498
- $payload .= 'Content-Disposition: form-data; name="attachment['.$i.']"; filename="'.basename($attachment).'"'."\r\n\r\n";
499
  $payload .= file_get_contents($attachment);
500
  $payload .= "\r\n";
501
  $i++;
20
  */
21
 
22
  // Include MG filter functions
23
+ if (!include __DIR__ . '/mg-filter.php') {
24
+ (new Mailgun)->deactivate_and_die(__DIR__ . '/mg-filter.php');
25
  }
26
 
27
  /**
28
  * mg_api_last_error is a compound getter/setter for the last error that was
29
  * encountered during a Mailgun API call.
30
  *
31
+ * @param string $error OPTIONAL
32
  *
33
+ * @return string Last error that occurred.
34
  *
35
+ * @since 1.5.0
36
  */
37
  function mg_api_last_error($error = null)
38
  {
40
 
41
  if (null === $error) {
42
  return $last_error;
 
 
 
 
 
43
  }
44
+
45
+ $tmp = $last_error;
46
+ $last_error = $error;
47
+
48
+ return $tmp;
49
  }
50
 
51
  /*
79
 
80
  // TODO: Also add folding to prevent hitting the 998 char limit on headers.
81
  return array(
82
+ 'to' => '%recipient%',
83
  'rcpt_vars' => json_encode($rcpt_vars),
84
  );
85
  }
86
  }
87
 
88
  return array(
89
+ 'to' => $to_addrs,
90
  'rcpt_vars' => null,
91
  );
92
  }
98
  * Based off of the core wp_mail function, but with modifications required to
99
  * send email using the Mailgun HTTP API
100
  *
101
+ * @param string|array $to Array or comma-separated list of email addresses to send message.
102
+ * @param string $subject Email subject
103
+ * @param string $message Message contents
104
+ * @param string|array $headers Optional. Additional headers.
105
+ * @param string|array $attachments Optional. Files to attach.
106
  *
107
+ * @return bool Whether the email contents were sent successfully.
108
  *
109
  * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
110
  *
 
111
  */
112
  if (!function_exists('wp_mail')) {
113
+ function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
114
+ {
115
+ // Compact the input, apply the filters, and extract them back out
116
+ $extractData = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
117
+ if (!is_array($extractData)) {
118
+ $extractData = (array)$extractData;
119
+ }
120
+ extract($extractData, EXTR_OVERWRITE);
121
 
122
+ $mailgun = get_option('mailgun');
123
+ $region = (defined('MAILGUN_REGION') && MAILGUN_REGION) ? MAILGUN_REGION : $mailgun['region'];
124
+ $apiKey = (defined('MAILGUN_APIKEY') && MAILGUN_APIKEY) ? MAILGUN_APIKEY : $mailgun['apiKey'];
125
+ $domain = (defined('MAILGUN_DOMAIN') && MAILGUN_DOMAIN) ? MAILGUN_DOMAIN : $mailgun['domain'];
126
 
127
+ if (empty($apiKey) || empty($domain)) {
128
+ return false;
129
+ }
130
 
131
+ // If a region is not set via defines or through the options page, default to US region.
132
+ if (!((bool)$region)) {
133
+ error_log('[Mailgun] No region configuration was found! Defaulting to US region.');
134
+ $region = 'us';
135
+ }
136
 
137
+ if (!is_array($attachments)) {
138
+ $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
139
+ }
140
 
141
+ // Headers
142
+ if (empty($headers)) {
143
+ $headers = [];
 
 
 
 
 
144
  } else {
145
+ if (!is_array($headers)) {
146
+ // Explode the headers out, so this function can take both
147
+ // string headers and an array of headers.
148
+ $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
149
+ } else {
150
+ $tempheaders = $headers;
151
+ }
152
+ $headers = [];
153
+ $cc = [];
154
+ $bcc = [];
155
+
156
+ // If it's actually got contents
157
+ if (!empty($tempheaders)) {
158
+ // Iterate through the raw headers
159
+ foreach ((array)$tempheaders as $header) {
160
+ if (strpos($header, ':') === false) {
161
+ if (false !== stripos($header, 'boundary=')) {
162
+ $parts = preg_split('/boundary=/i', trim($header));
163
+ $boundary = trim(str_replace(["'", '"'], '', $parts[1]));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  }
165
+ continue;
166
+ }
167
+ // Explode them out
168
+ list($name, $content) = explode(':', trim($header), 2);
169
+
170
+ // Cleanup crew
171
+ $name = trim($name);
172
+ $content = trim($content);
173
+
174
+ switch (strtolower($name)) {
175
+ // Mainly for legacy -- process a From: header if it's there
176
+ case 'from':
177
+ if (strpos($content, '<') !== false) {
178
+ // So... making my life hard again?
179
+ $from_name = substr($content, 0, strpos($content, '<') - 1);
180
+ $from_name = str_replace('"', '', $from_name);
181
+ $from_name = trim($from_name);
182
+
183
+ $from_email = substr($content, strpos($content, '<') + 1);
184
+ $from_email = str_replace('>', '', $from_email);
185
+ $from_email = trim($from_email);
186
+ } else {
187
+ $from_email = trim($content);
188
+ }
189
+ break;
190
+ case 'content-type':
191
+ if (strpos($content, ';') !== false) {
192
+ list($type, $charset) = explode(';', $content);
193
+ $content_type = trim($type);
194
+ if (false !== stripos($charset, 'charset=')) {
195
+ $charset = trim(str_replace(array('charset=', '"'), '', $charset));
196
+ } elseif (false !== stripos($charset, 'boundary=')) {
197
+ $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
198
+ $charset = '';
199
+ }
200
+ } else {
201
+ $content_type = trim($content);
202
+ }
203
+ break;
204
+ case 'cc':
205
+ $cc = array_merge((array)$cc, explode(',', $content));
206
+ break;
207
+ case 'bcc':
208
+ $bcc = array_merge((array)$bcc, explode(',', $content));
209
+ break;
210
+ default:
211
+ // Add it to our grand headers array
212
+ $headers[trim($name)] = trim($content);
213
+ break;
214
  }
 
 
 
 
 
 
 
 
 
 
 
215
  }
216
  }
217
  }
 
 
 
 
 
218
 
219
+ if (!isset($from_name)) {
220
+ $from_name = null;
221
+ }
222
 
223
+ if (!isset($from_email)) {
224
+ $from_email = null;
225
+ }
226
 
227
+ $from_name = mg_detect_from_name($from_name);
228
+ $from_email = mg_detect_from_address($from_email);
 
 
 
229
 
230
+ $body = array(
231
+ 'from' => "{$from_name} <{$from_email}>",
232
+ 'to' => $to,
233
+ 'subject' => $subject,
234
+ );
235
 
236
+ $rcpt_data = apply_filters('mg_mutate_to_rcpt_vars', $to);
237
+ if (!is_null($rcpt_data['rcpt_vars'])) {
238
+ $body['recipient-variables'] = $rcpt_data['rcpt_vars'];
239
+ }
240
 
241
+ $body['o:tag'] = array();
242
+ $body['o:tracking-clicks'] = !empty($mailgun['track-clicks']) ? $mailgun['track-clicks'] : 'no';
243
+ $body['o:tracking-opens'] = empty($mailgun['track-opens']) ? 'no' : 'yes';
 
 
244
 
245
+ // this is the wordpress site tag
246
+ if (isset($mailgun['tag'])) {
247
+ $tags = explode(',', str_replace(' ', '', $mailgun['tag']));
 
248
  $body['o:tag'] = $tags;
 
 
 
 
249
  }
 
250
 
251
+ // campaign-id now refers to a list of tags which will be appended to the site tag
252
+ if (!empty($mailgun['campaign-id'])) {
253
+ $tags = explode(',', str_replace(' ', '', $mailgun['campaign-id']));
254
+ if (empty($body['o:tag'])) {
255
+ $body['o:tag'] = $tags;
256
+ } elseif (is_array($body['o:tag'])) {
257
+ $body['o:tag'] = array_merge($body['o:tag'], $tags);
258
+ } else {
259
+ $body['o:tag'] .= ',' . $tags;
260
+ }
261
+ }
 
 
 
 
 
 
 
 
262
 
263
+ /**
264
+ * Filter tags.
265
+ *
266
+ * @param array $tags Mailgun tags.
267
+ * @param string $to To address.
268
+ * @param string $subject Subject line.
269
+ * @param string $message Message content.
270
+ * @param array $headers Headers array.
271
+ * @param array $attachments Attachments array.
272
+ * @param string $region Mailgun region.
273
+ * @param string $domain Mailgun domain.
274
+ *
275
+ * @return array Mailgun tags.
276
+ */
277
+ $body['o:tag'] = apply_filters('mailgun_tags', $body['o:tag'], $to, $subject, $message, $headers, $attachments, $region, $domain);
278
+
279
+ if (!empty($cc) && is_array($cc)) {
280
+ $body['cc'] = implode(', ', $cc);
281
+ }
282
 
283
+ if (!empty($bcc) && is_array($bcc)) {
284
+ $body['bcc'] = implode(', ', $bcc);
285
+ }
 
 
 
286
 
287
+ // If we are not given a Content-Type in the supplied headers,
288
+ // write the message body to a file and try to determine the mimetype
289
+ // using get_mime_content_type.
290
+ if (!isset($content_type)) {
291
+ $tmppath = tempnam(get_temp_dir(), 'mg');
292
+ $tmp = fopen($tmppath, 'w+');
293
 
294
+ fwrite($tmp, $message);
295
+ fclose($tmp);
296
 
297
+ $content_type = get_mime_content_type($tmppath, 'text/plain');
 
298
 
299
+ unlink($tmppath);
300
+ }
 
 
 
 
 
301
 
302
+ // Allow external content type filter to function normally
303
+ if (has_filter('wp_mail_content_type')) {
304
+ $content_type = apply_filters(
305
+ 'wp_mail_content_type',
306
+ $content_type
307
+ );
308
+ }
 
 
 
309
 
310
+ if ('text/plain' === $content_type) {
311
+ $body['text'] = $message;
312
+ } else if ('text/html' === $content_type) {
313
+ $body['html'] = $message;
314
+ } else {
315
+ // Unknown Content-Type??
316
+ error_log('[mailgun] Got unknown Content-Type: ' . $content_type);
317
+ $body['text'] = $message;
318
+ $body['html'] = $message;
 
 
 
 
 
 
 
 
319
  }
320
 
321
+ // Some plugins, such as WooCommerce (@see WC_Email::handle_multipart()), to handle multipart/alternative with html
322
+ // and plaintext messages hooks into phpmailer_init action to override AltBody property directly in $phpmailer,
323
+ // so we should allow them to do this, and then get overridden plain text body from $phpmailer.
324
+ // Partly, this logic is taken from original wp_mail function.
325
+ if (false !== stripos($content_type, 'multipart')) {
326
+ global $phpmailer;
327
+
328
+ // (Re)create it, if it's gone missing.
329
+ if (!($phpmailer instanceof PHPMailer\PHPMailer\PHPMailer)) {
330
+ require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
331
+ require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
332
+ require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
333
+ $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
334
+
335
+ $phpmailer::$validator = static function ($email) {
336
+ return (bool)is_email($email);
337
+ };
338
+ }
339
 
340
+ /**
341
+ * Fires after PHPMailer is initialized.
342
+ *
343
+ * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
344
+ */
345
+ do_action_ref_array('phpmailer_init', array(&$phpmailer));
346
 
347
+ $plainTextMessage = $phpmailer->AltBody;
348
+
349
+ if ($plainTextMessage) {
350
+ $body['text'] = $plainTextMessage;
351
+ }
352
  }
 
353
 
354
+ // If we don't have a charset from the input headers
355
+ if (!isset($charset)) {
356
+ $charset = get_bloginfo('charset');
357
+ }
358
 
359
+ // Set the content-type and charset
360
+ $charset = apply_filters('wp_mail_charset', $charset);
361
+ if (isset($headers['Content-Type'])) {
362
+ if (!strstr($headers['Content-Type'], 'charset')) {
363
+ $headers['Content-Type'] = rtrim($headers['Content-Type'], '; ') . "; charset={$charset}";
364
+ }
365
  }
 
366
 
367
+ // Set custom headers
368
+ if (!empty($headers)) {
369
+ foreach ((array)$headers as $name => $content) {
370
+ $body["h:{$name}"] = $content;
371
+ }
372
  }
373
 
374
+ /*
375
+ * Deconstruct post array and create POST payload.
376
+ * This entire routine is because wp_remote_post does
377
+ * not support files directly.
378
+ */
379
 
380
+ $payload = '';
 
 
 
 
381
 
382
+ // First, generate a boundary for the multipart message.
383
+ $boundary = sha1(uniqid('', true));
384
 
385
+ // Allow other plugins to apply body changes before creating the payload.
386
+ $body = apply_filters('mg_mutate_message_body', $body);
387
+ if (($body_payload = mg_build_payload_from_body($body, $boundary)) != null) {
388
+ $payload .= $body_payload;
389
+ }
390
 
391
+ // Allow other plugins to apply attachment changes before writing to the payload.
392
+ $attachments = apply_filters('mg_mutate_attachments', $attachments);
393
+ if (($attachment_payload = mg_build_attachments_payload($attachments, $boundary)) != null) {
394
+ $payload .= $attachment_payload;
395
+ }
396
 
397
+ $payload .= '--' . $boundary . '--';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
 
399
+ $data = array(
400
+ 'body' => $payload,
401
+ 'headers' => array(
402
+ 'Authorization' => 'Basic ' . base64_encode("api:{$apiKey}"),
403
+ 'Content-Type' => 'multipart/form-data; boundary=' . $boundary,
404
+ ),
405
+ );
406
 
407
+ $endpoint = mg_api_get_region($region);
408
+ $endpoint = ($endpoint) ? $endpoint : 'https://api.mailgun.net/v3/';
409
+ $url = $endpoint . "{$domain}/messages";
 
 
 
 
410
 
411
+ // TODO: Mailgun only supports 1000 recipients per request, since we are
412
+ // overriding this function, let's add looping here to handle that
413
+ $response = wp_remote_post($url, $data);
414
+ if (is_wp_error($response)) {
415
+ // Store WP error in last error.
416
+ mg_api_last_error($response->get_error_message());
417
 
418
+ return false;
419
+ }
 
 
 
 
420
 
421
+ $response_code = wp_remote_retrieve_response_code($response);
422
+ $response_body = json_decode(wp_remote_retrieve_body($response));
423
 
424
+ // Mailgun API should *always* return a `message` field, even when
425
+ // $response_code != 200, so a lack of `message` indicates something
426
+ // is broken.
427
+ if ((int)$response_code != 200 || !isset($response_body->message)) {
428
+ // Store response code and HTTP response message in last error.
429
+ $response_message = wp_remote_retrieve_response_message($response);
430
+ $errmsg = "$response_code - $response_message";
431
+ mg_api_last_error($errmsg);
432
 
433
+ return false;
434
+ }
 
 
 
 
 
 
435
 
436
+ // Not sure there is any additional checking that needs to be done here, but why not?
437
+ if ($response_body->message != 'Queued. Thank you.') {
438
+ mg_api_last_error($response_body->message);
439
 
440
+ return false;
441
+ }
 
442
 
443
+ return true;
444
  }
 
 
 
445
  }
446
 
447
+ function mg_build_payload_from_body($body, $boundary)
448
+ {
449
  $payload = '';
450
 
451
  // Iterate through pre-built params and build payload:
453
  if (is_array($value)) {
454
  $parent_key = $key;
455
  foreach ($value as $key => $value) {
456
+ $payload .= '--' . $boundary;
457
  $payload .= "\r\n";
458
+ $payload .= 'Content-Disposition: form-data; name="' . $parent_key . "\"\r\n\r\n";
459
  $payload .= $value;
460
  $payload .= "\r\n";
461
  }
462
  } else {
463
+ $payload .= '--' . $boundary;
464
  $payload .= "\r\n";
465
+ $payload .= 'Content-Disposition: form-data; name="' . $key . '"' . "\r\n\r\n";
466
  $payload .= $value;
467
  $payload .= "\r\n";
468
  }
471
  return $payload;
472
  }
473
 
474
+ function mg_build_attachments_payload($attachments, $boundary)
475
+ {
 
 
476
  $payload = '';
477
 
478
  // If we have attachments, add them to the payload.
480
  $i = 0;
481
  foreach ($attachments as $attachment) {
482
  if (!empty($attachment)) {
483
+ $payload .= '--' . $boundary;
484
  $payload .= "\r\n";
485
+ $payload .= 'Content-Disposition: form-data; name="attachment[' . $i . ']"; filename="' . basename($attachment) . '"' . "\r\n\r\n";
486
  $payload .= file_get_contents($attachment);
487
  $payload .= "\r\n";
488
  $i++;
includes/wp-mail-smtp.php CHANGED
@@ -20,8 +20,8 @@
20
  */
21
 
22
  // Include MG filter functions
23
- if (!include dirname(__FILE__).'/mg-filter.php') {
24
- Mailgun::deactivate_and_die(dirname(__FILE__).'/mg-filter.php');
25
  }
26
 
27
  /**
@@ -40,12 +40,12 @@ function mg_smtp_last_error($error = null)
40
 
41
  if (null === $error) {
42
  return $last_error;
43
- } else {
44
- $tmp = $last_error;
45
- $last_error = $error;
46
-
47
- return $tmp;
48
  }
 
 
 
 
 
49
  }
50
 
51
  /**
@@ -54,11 +54,11 @@ function mg_smtp_last_error($error = null)
54
  * @param string $str Log message
55
  * @param string $level Logging level
56
  *
57
- * @return none
58
  *
59
  * @since 1.5.7
60
  */
61
- function mg_smtp_debug_output($str, $level)
62
  {
63
  if (defined('MG_DEBUG_SMTP') && MG_DEBUG_SMTP) {
64
  error_log("PHPMailer [$level] $str");
@@ -69,9 +69,9 @@ function mg_smtp_debug_output($str, $level)
69
  * Capture and store the failure message from PHPmailer so the user will
70
  * actually know what is wrong.
71
  *
72
- * @param WP_Error $error Error raised by Wordpress/PHPmailer
73
  *
74
- * @return none
75
  *
76
  * @since 1.5.7
77
  */
@@ -86,7 +86,7 @@ function wp_mail_failed($error)
86
 
87
  /**
88
  * Provides a `wp_mail` compatible filter for SMTP sends through the
89
- * Wordpress PHPmailer transport.
90
  *
91
  * @param array $args Compacted array of arguments.
92
  *
@@ -97,7 +97,7 @@ function wp_mail_failed($error)
97
  function mg_smtp_mail_filter(array $args)
98
  {
99
  // Extract the arguments from array to ($to, $subject, $message, $headers, $attachments)
100
- extract($args);
101
 
102
  // $headers and $attachments are optional - make sure they exist
103
  $headers = (!isset($headers)) ? '' : $headers;
@@ -109,7 +109,7 @@ function mg_smtp_mail_filter(array $args)
109
  // Filter the `From:` header
110
  $from_header = (isset($mg_headers['From'])) ? $mg_headers['From'][0] : null;
111
 
112
- list($from_name, $from_addr) = array(null, null);
113
  if (!is_null($from_header)) {
114
  $content = $from_header['value'];
115
  $boundary = $from_header['boundary'];
20
  */
21
 
22
  // Include MG filter functions
23
+ if (!include __DIR__ .'/mg-filter.php') {
24
+ (new Mailgun)->deactivate_and_die(__DIR__ .'/mg-filter.php');
25
  }
26
 
27
  /**
40
 
41
  if (null === $error) {
42
  return $last_error;
 
 
 
 
 
43
  }
44
+
45
+ $tmp = $last_error;
46
+ $last_error = $error;
47
+
48
+ return $tmp;
49
  }
50
 
51
  /**
54
  * @param string $str Log message
55
  * @param string $level Logging level
56
  *
57
+ * @return void
58
  *
59
  * @since 1.5.7
60
  */
61
+ function mg_smtp_debug_output(string $str, $level)
62
  {
63
  if (defined('MG_DEBUG_SMTP') && MG_DEBUG_SMTP) {
64
  error_log("PHPMailer [$level] $str");
69
  * Capture and store the failure message from PHPmailer so the user will
70
  * actually know what is wrong.
71
  *
72
+ * @param WP_Error $error Error raised by WordPress/PHPmailer
73
  *
74
+ * @return void
75
  *
76
  * @since 1.5.7
77
  */
86
 
87
  /**
88
  * Provides a `wp_mail` compatible filter for SMTP sends through the
89
+ * WordPress PHPmailer transport.
90
  *
91
  * @param array $args Compacted array of arguments.
92
  *
97
  function mg_smtp_mail_filter(array $args)
98
  {
99
  // Extract the arguments from array to ($to, $subject, $message, $headers, $attachments)
100
+ extract($args, EXTR_OVERWRITE);
101
 
102
  // $headers and $attachments are optional - make sure they exist
103
  $headers = (!isset($headers)) ? '' : $headers;
109
  // Filter the `From:` header
110
  $from_header = (isset($mg_headers['From'])) ? $mg_headers['From'][0] : null;
111
 
112
+ list($from_name, $from_addr) = [null, null];
113
  if (!is_null($from_header)) {
114
  $content = $from_header['value'];
115
  $boundary = $from_header['boundary'];
mailgun.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
-
3
  /**
4
  * Plugin Name: Mailgun
5
  * Plugin URI: http://wordpress.org/extend/plugins/mailgun/
6
  * Description: Mailgun integration for WordPress
7
- * Version: 1.8.0
 
8
  * Author: Mailgun
9
  * Author URI: http://www.mailgun.com/
10
  * License: GPLv2 or later
@@ -36,10 +36,15 @@
36
  * either API or SMTP.
37
  *
38
  * Registers handlers for later actions and sets up config variables with
39
- * Wordpress.
40
  */
41
  class Mailgun
42
  {
 
 
 
 
 
43
  /**
44
  * @var false|mixed|null
45
  */
@@ -63,7 +68,6 @@ class Mailgun
63
  /**
64
  * Setup shared functionality for Admin and Front End.
65
  *
66
- * @since 0.1
67
  */
68
  public function __construct()
69
  {
@@ -95,6 +99,18 @@ class Mailgun
95
  }
96
  }
97
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  /**
99
  * Get specific option from the options table.
100
  *
@@ -104,7 +120,6 @@ class Mailgun
104
  *
105
  * @return mixed
106
  *
107
- * @since 0.1
108
  */
109
  public function get_option(string $option, ?array $options = null, bool $default = false)
110
  {
@@ -127,7 +142,6 @@ class Mailgun
127
  *
128
  * @return void
129
  *
130
- * @since 0.1
131
  */
132
  public function phpmailer_init(&$phpmailer)
133
  {
@@ -174,8 +188,6 @@ class Mailgun
174
  * @param $file Files critical to plugin functionality
175
  *
176
  * @return void
177
- *
178
- * @since 0.1
179
  */
180
  public function deactivate_and_die($file)
181
  {
@@ -198,7 +210,6 @@ class Mailgun
198
  *
199
  * @return string
200
  *
201
- * @since 0.1
202
  */
203
  public function api_call($uri, $params = [], $method = 'POST'): string
204
  {
@@ -208,7 +219,7 @@ class Mailgun
208
  $domain = (defined('MAILGUN_DOMAIN') && MAILGUN_DOMAIN) ? MAILGUN_DOMAIN : $options[ 'domain' ];
209
 
210
  $region = mg_api_get_region($getRegion);
211
- $this->api_endpoint = ($region) ? $region : 'https://api.mailgun.net/v3/';
212
 
213
  $time = time();
214
  $url = $this->api_endpoint . $uri;
@@ -266,7 +277,6 @@ class Mailgun
266
  * @return array
267
  *
268
  * @throws JsonException
269
- * @since 0.1
270
  */
271
  public function get_lists(): array
272
  {
@@ -285,21 +295,21 @@ class Mailgun
285
  /**
286
  * Handle add list ajax post.
287
  *
288
- * @return string json
289
  *
290
  * @throws JsonException
291
- * @since 0.1
292
  */
293
  public function add_list()
294
  {
295
  $name = $_POST['name'] ?? null;
296
  $email = $_POST['email'] ?? null;
297
 
298
- $list_addresses = $_POST[ 'addresses' ];
299
 
300
  if (!empty($list_addresses)) {
 
301
  foreach ($list_addresses as $address => $val) {
302
- $this->api_call(
303
  "lists/{$address}/members",
304
  [
305
  'address' => $email,
@@ -307,7 +317,19 @@ class Mailgun
307
  ]
308
  );
309
  }
310
- echo json_encode(['status' => 200, 'message' => 'Thank you!'], JSON_THROW_ON_ERROR);
 
 
 
 
 
 
 
 
 
 
 
 
311
  } else {
312
  echo json_encode([
313
  'status' => 500,
@@ -325,12 +347,12 @@ class Mailgun
325
  * @param array $instance widget instance params
326
  *
327
  * @throws JsonException
328
- * @since 0.1
329
  */
330
- public function list_form(string $list_address, array $args = [], array $instance = []): void
331
  {
332
- $widget_class_id = "mailgun-list-widget-{$args['widget_id']}";
333
- $form_class_id = "list-form-{$args['widget_id']}";
 
334
 
335
  // List addresses from the plugin config
336
  $list_addresses = array_map('trim', explode(',', $list_address));
@@ -355,7 +377,7 @@ class Mailgun
355
  </p>
356
  </div>
357
  <?php endif; ?>
358
- <?php if (isset($args[ 'collect_name' ]) && intval($args[ 'collect_name' ]) === 1): ?>
359
  <p class="mailgun-list-widget-name">
360
  <strong>Name:</strong>
361
  <input type="text" name="name"/>
@@ -424,7 +446,6 @@ class Mailgun
424
  dataType: 'json',
425
  data: jQuery('.' + form_id + '').serialize(),
426
  success: function (data) {
427
-
428
  data_msg = data.message
429
  already_exists = false
430
  if (data_msg !== undefined) {
@@ -457,7 +478,6 @@ class Mailgun
457
  * @return string
458
  *
459
  * @throws JsonException
460
- * @since 0.1
461
  */
462
  public function build_list_form(array $atts): string
463
  {
@@ -488,10 +508,8 @@ class Mailgun
488
 
489
  /**
490
  * Initialize List Widget.
491
- *
492
- * @since 0.1
493
  */
494
- public function load_list_widget(): void
495
  {
496
  register_widget('list_widget');
497
  add_shortcode('mailgun', [&$this, 'build_list_form']);
@@ -506,7 +524,7 @@ class Mailgun
506
  }
507
  }
508
 
509
- $mailgun = new Mailgun();
510
 
511
  if (@include __DIR__ . '/includes/widget.php') {
512
  add_action('widgets_init', [&$mailgun, 'load_list_widget']);
1
  <?php
 
2
  /**
3
  * Plugin Name: Mailgun
4
  * Plugin URI: http://wordpress.org/extend/plugins/mailgun/
5
  * Description: Mailgun integration for WordPress
6
+ * Version: 1.8.7
7
+ * Tested up to: 6.1
8
  * Author: Mailgun
9
  * Author URI: http://www.mailgun.com/
10
  * License: GPLv2 or later
36
  * either API or SMTP.
37
  *
38
  * Registers handlers for later actions and sets up config variables with
39
+ * WordPress.
40
  */
41
  class Mailgun
42
  {
43
+ /**
44
+ * @var Mailgun $instance
45
+ */
46
+ private static $instance;
47
+
48
  /**
49
  * @var false|mixed|null
50
  */
68
  /**
69
  * Setup shared functionality for Admin and Front End.
70
  *
 
71
  */
72
  public function __construct()
73
  {
99
  }
100
  }
101
 
102
+ /**
103
+ * @return static
104
+ */
105
+ public static function getInstance()
106
+ {
107
+ if (!isset(self::$instance)) {
108
+ self::$instance = new self();
109
+ }
110
+
111
+ return self::$instance;
112
+ }
113
+
114
  /**
115
  * Get specific option from the options table.
116
  *
120
  *
121
  * @return mixed
122
  *
 
123
  */
124
  public function get_option(string $option, ?array $options = null, bool $default = false)
125
  {
142
  *
143
  * @return void
144
  *
 
145
  */
146
  public function phpmailer_init(&$phpmailer)
147
  {
188
  * @param $file Files critical to plugin functionality
189
  *
190
  * @return void
 
 
191
  */
192
  public function deactivate_and_die($file)
193
  {
210
  *
211
  * @return string
212
  *
 
213
  */
214
  public function api_call($uri, $params = [], $method = 'POST'): string
215
  {
219
  $domain = (defined('MAILGUN_DOMAIN') && MAILGUN_DOMAIN) ? MAILGUN_DOMAIN : $options[ 'domain' ];
220
 
221
  $region = mg_api_get_region($getRegion);
222
+ $this->api_endpoint = ($region) ?: 'https://api.mailgun.net/v3/';
223
 
224
  $time = time();
225
  $url = $this->api_endpoint . $uri;
277
  * @return array
278
  *
279
  * @throws JsonException
 
280
  */
281
  public function get_lists(): array
282
  {
295
  /**
296
  * Handle add list ajax post.
297
  *
298
+ * @return void json
299
  *
300
  * @throws JsonException
 
301
  */
302
  public function add_list()
303
  {
304
  $name = $_POST['name'] ?? null;
305
  $email = $_POST['email'] ?? null;
306
 
307
+ $list_addresses = $_POST['addresses'];
308
 
309
  if (!empty($list_addresses)) {
310
+ $result = [];
311
  foreach ($list_addresses as $address => $val) {
312
+ $result[] = $this->api_call(
313
  "lists/{$address}/members",
314
  [
315
  'address' => $email,
317
  ]
318
  );
319
  }
320
+ $message = 'Thank you!';
321
+ if ($result) {
322
+ $message = 'Something went wrong';
323
+ $response = json_decode($result[0], true);
324
+ if (is_array($response) && isset($response['message'])) {
325
+ $message = $response['message'];
326
+ }
327
+
328
+ }
329
+ echo json_encode([
330
+ 'status' => 200,
331
+ 'message' => $message
332
+ ], JSON_THROW_ON_ERROR);
333
  } else {
334
  echo json_encode([
335
  'status' => 500,
347
  * @param array $instance widget instance params
348
  *
349
  * @throws JsonException
 
350
  */
351
+ public function list_form(string $list_address, array $args = [], array $instance = [])
352
  {
353
+ $widgetId = $args['widget_id'] ?? 0;
354
+ $widget_class_id = "mailgun-list-widget-{$widgetId}";
355
+ $form_class_id = "list-form-{$widgetId}";
356
 
357
  // List addresses from the plugin config
358
  $list_addresses = array_map('trim', explode(',', $list_address));
377
  </p>
378
  </div>
379
  <?php endif; ?>
380
+ <?php if (isset($args[ 'collect_name' ]) && (int)$args['collect_name'] === 1): ?>
381
  <p class="mailgun-list-widget-name">
382
  <strong>Name:</strong>
383
  <input type="text" name="name"/>
446
  dataType: 'json',
447
  data: jQuery('.' + form_id + '').serialize(),
448
  success: function (data) {
 
449
  data_msg = data.message
450
  already_exists = false
451
  if (data_msg !== undefined) {
478
  * @return string
479
  *
480
  * @throws JsonException
 
481
  */
482
  public function build_list_form(array $atts): string
483
  {
508
 
509
  /**
510
  * Initialize List Widget.
 
 
511
  */
512
+ public function load_list_widget()
513
  {
514
  register_widget('list_widget');
515
  add_shortcode('mailgun', [&$this, 'build_list_form']);
524
  }
525
  }
526
 
527
+ $mailgun = Mailgun::getInstance();
528
 
529
  if (@include __DIR__ . '/includes/widget.php') {
530
  add_action('widgets_init', [&$mailgun, 'load_list_widget']);
readme.md CHANGED
@@ -4,14 +4,13 @@ Mailgun for WordPress
4
  Contributors: mailgun, sivel, lookahead.io, m35dev
5
  Tags: mailgun, smtp, http, api, mail, email
6
  Requires at least: 3.3
7
- Tested up to: 6.0.1
8
- Stable tag: 1.8.0
 
9
  License: GPLv2 or later
10
 
11
-
12
  Easily send email from your WordPress site through Mailgun using the HTTP API or SMTP.
13
 
14
-
15
  ## Description
16
 
17
  [Mailgun](http://www.mailgun.com/) is the email automation engine trusted by over 10,000 website and application developers for sending, receiving and tracking emails. By taking advantage of Mailgun's powerful email APIs, developers can spend more time building awesome websites and less time fighting with email servers. Mailgun supports all of the most popular languages including PHP, Ruby, Python, C# and Java.
@@ -131,6 +130,18 @@ MAILGUN_FROM_ADDRESS Type: string
131
 
132
 
133
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
134
  = 1.8.0 (2022-08-18): =
135
  - Plugin refactoring. Using new languages constructions. Extended readme. Update version
136
 
4
  Contributors: mailgun, sivel, lookahead.io, m35dev
5
  Tags: mailgun, smtp, http, api, mail, email
6
  Requires at least: 3.3
7
+ Tested up to: 6.1
8
+ Stable tag: 1.8.7
9
+ Requires PHP: 5.6
10
  License: GPLv2 or later
11
 
 
12
  Easily send email from your WordPress site through Mailgun using the HTTP API or SMTP.
13
 
 
14
  ## Description
15
 
16
  [Mailgun](http://www.mailgun.com/) is the email automation engine trusted by over 10,000 website and application developers for sending, receiving and tracking emails. By taking advantage of Mailgun's powerful email APIs, developers can spend more time building awesome websites and less time fighting with email servers. Mailgun supports all of the most popular languages including PHP, Ruby, Python, C# and Java.
130
 
131
 
132
  == Changelog ==
133
+ = 1.8.7 (2022-11-12): =
134
+ - Fixed bug when field `Override "From" Details` was not updated
135
+
136
+ = 1.8.3 (2022-08-30): =
137
+ - Plugin refactoring. Widget fixes for working with Legacy Widget Block. PHP8.0 support check
138
+
139
+ = 1.8.2 (2022-08-24): =
140
+ - Plugin refactoring. Small fixes
141
+
142
+ = 1.8.1 (2022-08-19): =
143
+ - backward compatibility with php7.0
144
+
145
  = 1.8.0 (2022-08-18): =
146
  - Plugin refactoring. Using new languages constructions. Extended readme. Update version
147
 
readme.txt CHANGED
@@ -3,12 +3,12 @@ Mailgun for WordPress
3
 
4
  Contributors: mailgun, sivel, lookahead.io, m35dev
5
  Tags: mailgun, smtp, http, api, mail, email
6
- Requires at least: 3.3
7
- Tested up to: 6.0.1
8
- Stable tag: 1.8.0
 
9
  License: GPLv2 or later
10
 
11
-
12
  Easily send email from your WordPress site through Mailgun using the HTTP API or SMTP.
13
 
14
 
@@ -128,6 +128,18 @@ MAILGUN_FROM_ADDRESS Type: string
128
 
129
 
130
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
131
  = 1.8.0 (2022-08-18): =
132
  - Plugin refactoring. Using new languages constructions. Extended readme. Update version
133
 
3
 
4
  Contributors: mailgun, sivel, lookahead.io, m35dev
5
  Tags: mailgun, smtp, http, api, mail, email
6
+ Requires at least: 4.4
7
+ Tested up to: 6.1
8
+ Stable tag: 1.8.7
9
+ Requires PHP: 5.6
10
  License: GPLv2 or later
11
 
 
12
  Easily send email from your WordPress site through Mailgun using the HTTP API or SMTP.
13
 
14
 
128
 
129
 
130
  == Changelog ==
131
+ = 1.8.7 (2022-11-12): =
132
+ - Fixed bug when field `Override "From" Details` was not updated
133
+
134
+ = 1.8.3 (2022-08-30): =
135
+ - Plugin refactoring. Widget fixes for working with Legacy Widget Block. PHP8.0 support check
136
+
137
+ = 1.8.2 (2022-08-24): =
138
+ - Plugin refactoring. Small fixes
139
+
140
+ = 1.8.1 (2022-08-19): =
141
+ - backward compatibility with php7.0
142
+
143
  = 1.8.0 (2022-08-18): =
144
  - Plugin refactoring. Using new languages constructions. Extended readme. Update version
145