Newsletter - Version 6.6.4

Version Description

  • Added filter on profile fields on targeting
  • Administrator notice on custom forms using provate lists
  • Added translation code on some words
  • Compatibility check with WP 5.4.1
  • Tip changed on SMTP panel about GMail
Download this release

Release Info

Developer satollo
Plugin Icon 128x128 Newsletter
Version 6.6.4
Comparing to
See all releases

Code changes from version 6.6.3 to 6.6.4

admin.js CHANGED
@@ -46,41 +46,70 @@ function tnp_toggle_schedule() {
46
  }
47
 
48
  window.onload = function () {
49
- jQuery('.tnp-counter-animation').each(function () {
50
- var _this = jQuery(this);
51
-
52
- var val = null;
53
- if (!isFloat(_this.text())) {
54
- val = {
55
- parsed: parseInt(_this.text()),
56
- rounded: function (value) {
57
- return Math.ceil(value);
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  }
59
- };
60
 
61
- if (_this.hasClass('percentage')) {
62
- _this.css('min-width', '60px');
63
- }
64
- } else {
65
- val = {
66
- parsed: parseFloat(_this.text()),
67
- rounded: function (value) {
68
- return value.toFixed(1);
 
 
69
  }
70
- };
71
- }
72
 
73
- jQuery({counter: 0}).animate({counter: val.parsed}, {
74
- duration: 1000,
75
- easing: 'swing',
76
- step: function () {
77
- _this.text(val.rounded(this.counter));
78
- }
79
  });
80
 
81
- function isFloat(value) {
82
- return !isNaN(Number(value)) && Number(value).toString().indexOf('.') !== -1;
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- });
86
  };
 
 
46
  }
47
 
48
  window.onload = function () {
49
+ jQuery('.tnp-counter-animation').each(function () {
50
+ var _this = jQuery(this);
51
+
52
+ var val = null;
53
+ if (!isFloat(_this.text())) {
54
+ val = {
55
+ parsed: parseInt(_this.text()),
56
+ rounded: function (value) {
57
+ return Math.ceil(value);
58
+ }
59
+ };
60
+
61
+ if (_this.hasClass('percentage')) {
62
+ _this.css('min-width', '60px');
63
+ }
64
+ } else {
65
+ val = {
66
+ parsed: parseFloat(_this.text()),
67
+ rounded: function (value) {
68
+ return value.toFixed(1);
69
+ }
70
+ };
71
  }
 
72
 
73
+ jQuery({counter: 0}).animate({counter: val.parsed}, {
74
+ duration: 1000,
75
+ easing: 'swing',
76
+ step: function () {
77
+ _this.text(val.rounded(this.counter));
78
+ }
79
+ });
80
+
81
+ function isFloat(value) {
82
+ return !isNaN(Number(value)) && Number(value).toString().indexOf('.') !== -1;
83
  }
 
 
84
 
 
 
 
 
 
 
85
  });
86
 
87
+ (function targetinFormOnChangeHandler() {
88
+
89
+ if (isNewsletterOptionsPage()) {
90
+
91
+ var newsletterStatusScheduleValue = jQuery('#tnp-nl-status .tnp-nl-status-schedule-value');
92
+
93
+ jQuery('#newsletter-form').change(function (event) {
94
+
95
+ if (isElementInsideTargettingTab(event.target)) {
96
+ newsletterStatusScheduleValue.text(tnp_translations['save_to_update_counter']);
97
+ }
98
+
99
+ function isElementInsideTargettingTab(element) {
100
+ return jQuery(element).parents('#tabs-options').length === 1
101
+ }
102
+
103
+ });
104
+ }
105
+
106
+ function isNewsletterOptionsPage() {
107
+ return jQuery("#tnp-nl-status").length
108
+ && jQuery("#newsletter-form").length;
109
+ }
110
+
111
+ })();
112
 
 
113
  };
114
+
115
+
emails/blocks/social/block.php CHANGED
@@ -43,14 +43,6 @@ $configured = false;
43
  </span>
44
  <?php } ?>
45
  <?php
46
- if (!empty($block_options['googleplus_url'])) {
47
- $configured = true;
48
- ?>
49
- <span class="tnpc-row-edit" data-type="image">
50
- <a href="<?php echo $block_options['googleplus_url'] ?>"><img src="<?php echo $social_icon_url ?>/googleplus.png" alt="Google+"></a>
51
- </span>
52
- <?php } ?>
53
- <?php
54
  if (!empty($block_options['pinterest_url'])) {
55
  $configured = true;
56
  ?>
43
  </span>
44
  <?php } ?>
45
  <?php
 
 
 
 
 
 
 
 
46
  if (!empty($block_options['pinterest_url'])) {
47
  $configured = true;
48
  ?>
emails/edit.php CHANGED
@@ -35,7 +35,7 @@ if ($controls->is_action('continue')) {
35
  $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'sending'), array('id' => $email_id));
36
  $email = $module->get_email($_GET['id'], ARRAY_A);
37
  tnp_prepare_controls($email, $controls);
38
- }
39
 
40
  if ($controls->is_action('abort')) {
41
  $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set last_id=0, sent=0, status='new' where id=" . $email_id);
@@ -106,7 +106,7 @@ if ($controls->is_action('html')) {
106
  $controls->messages = 'You can now edit the newsletter as pure HTML';
107
 
108
  tnp_prepare_controls($email, $controls);
109
-
110
  $editor_type = NewsletterEmails::EDITOR_HTML;
111
  }
112
 
@@ -124,17 +124,19 @@ if ($controls->is_action('test') || $controls->is_action('save') || $controls->i
124
  } else {
125
  $email['send_on'] = $controls->data['send_on'];
126
  }
127
-
128
  // Reset and refill the options
129
  // Try without the reset and let's see where the problems are
130
  //$email['options'] = array();
131
-
132
  // Reset only specific keys
133
  unset($email['options']['lists']);
134
  unset($email['options']['lists_operator']);
135
  unset($email['options']['lists_exclude']);
136
  unset($email['options']['sex']);
137
-
 
 
 
138
  foreach ($controls->data as $name => $value) {
139
  if (strpos($name, 'options_') === 0) {
140
  $email['options'][substr($name, 8)] = $value;
@@ -152,12 +154,12 @@ if ($controls->is_action('test') || $controls->is_action('save') || $controls->i
152
  if ($email['options']['wp_users'] == '1') {
153
  $query .= " and wp_user_id<>0";
154
  }
155
-
156
  if (!empty($email['options']['language'])) {
157
  $query .= " and language='" . esc_sql((string) $email['options']['language']) . "'";
158
  }
159
-
160
-
161
  $list_where = array();
162
  if (isset($email['options']['lists']) && count($email['options']['lists'])) {
163
  foreach ($email['options']['lists'] as $list) {
@@ -200,6 +202,18 @@ if ($controls->is_action('test') || $controls->is_action('save') || $controls->i
200
  }
201
  }
202
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  // Temporary save to have an object and call the query filter
204
  $e = Newsletter::instance()->save_email($email);
205
  $query = apply_filters('newsletter_emails_email_query', $query, $e);
@@ -218,7 +232,7 @@ if ($controls->is_action('test') || $controls->is_action('save') || $controls->i
218
  $email = Newsletter::instance()->save_email($email, ARRAY_A);
219
 
220
  tnp_prepare_controls($email, $controls);
221
-
222
  if ($email === false) {
223
  $controls->errors = 'Unable to save. Try to deactivate and reactivate the plugin may be the database is out of sync.';
224
  }
@@ -227,18 +241,18 @@ if ($controls->is_action('test') || $controls->is_action('save') || $controls->i
227
  }
228
 
229
  if ($controls->is_action('send') || $controls->is_action('schedule')) {
230
-
231
  NewsletterStatistics::instance()->reset_stats($email);
232
-
233
  if ($email['subject'] == '') {
234
  $controls->errors = __('A subject is required to send', 'newsletter');
235
  } else {
236
  $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'sending'), array('id' => $email_id));
237
  $email['status'] = 'sending';
238
  if ($controls->is_action('send')) {
239
- $controls->messages = __( 'Now sending.', 'newsletter' );
240
  } else {
241
- $controls->messages = __( 'Scheduled.', 'newsletter' );
242
  }
243
  }
244
  }
@@ -260,7 +274,6 @@ if ($email['status'] != 'sent') {
260
  } else {
261
  $subscriber_count = $email['sent'];
262
  }
263
-
264
  ?>
265
  <style>
266
  .select2-container {
@@ -295,8 +308,8 @@ if ($email['status'] != 'sent') {
295
  <?php $controls->button_back('?page=newsletter_emails_index') ?>
296
 
297
  <?php } else { ?>
298
-
299
- <a class="button-primary" href="<?php echo $module->get_editor_url($email_id, $editor_type)?>">
300
  <i class="fas fa-edit"></i> <?php _e('Edit', 'newsletter') ?>
301
  </a>
302
 
@@ -334,14 +347,15 @@ if ($email['status'] != 'sent') {
334
  <?php $module->show_email_progress_bar($email, array('numbers' => $email['status'] == 'sent' ? false : true)) ?>
335
 
336
  <?php if ($email['status'] == 'sent' || $email['status'] == 'sending') { ?>
337
- <div class="tnp-nl-status-row">
338
- <span class="tnp-nl-status-schedule-value"><?php if ($email['status'] == 'sent') {
339
- echo __('Sent on'), ' ', $module->format_date( $email['send_on']);
340
- } else if ($email['status'] == 'sending' && $email['send_on'] > time()) {
341
- echo __('Scheduled on'), ' ', $module->format_date( $email['send_on']);
342
- }
343
- ?></span>
344
- </div>
 
345
  <?php } ?>
346
  <div class="tnp-nl-status-row">
347
  <span class="tnp-nl-status-schedule-targeting"><?php _e('Targeted subscribers', 'newsletter') ?>:</span>
@@ -354,7 +368,7 @@ if ($email['status'] != 'sent') {
354
  </div>
355
 
356
  <div id="tabs">
357
-
358
  <ul>
359
  <li><a href="#tabs-options"><?php _e('Sending Options', 'newsletter') ?></a></li>
360
  <li><a href="#tabs-advanced"><?php _e('Advanced', 'newsletter') ?></a></li>
@@ -387,14 +401,14 @@ if ($email['status'] != 'sent') {
387
  <?php $controls->select2('options_lists_exclude', $lists, null, true, null, __('None', 'newsletter')); ?>
388
  </td>
389
  </tr>
390
-
391
  <tr>
392
  <th><?php _e('Language', 'newsletter') ?></th>
393
  <td>
394
  <?php $controls->language('options_language'); ?>
395
  </td>
396
  </tr>
397
-
398
  <tr>
399
  <th><?php _e('Gender', 'newsletter') ?></th>
400
  <td>
@@ -414,13 +428,31 @@ if ($email['status'] != 'sent') {
414
  <?php $controls->yesno('options_wp_users'); ?>
415
  </td>
416
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
  </table>
418
 
419
  <?php do_action('newsletter_emails_edit_target', $module->get_email($email_id), $controls) ?>
420
 
421
  </div>
422
 
423
-
424
  <div id="tabs-advanced">
425
 
426
  <table class="form-table">
@@ -467,7 +499,7 @@ if ($email['status'] != 'sent') {
467
  </tr>
468
  </table>
469
  </div>
470
-
471
 
472
  <div id="tabs-preview">
473
 
@@ -502,7 +534,7 @@ if ($email['status'] != 'sent') {
502
  </script>
503
 
504
  <p>
505
- <?php if ($editor_type != NewsletterEmails::EDITOR_HTML && $email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_confirm('html', __('Convert to HTML newsletter', 'newsletter'), 'Attention: no way back!'); ?>
506
  </p>
507
  </div>
508
 
35
  $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'sending'), array('id' => $email_id));
36
  $email = $module->get_email($_GET['id'], ARRAY_A);
37
  tnp_prepare_controls($email, $controls);
38
+ }
39
 
40
  if ($controls->is_action('abort')) {
41
  $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set last_id=0, sent=0, status='new' where id=" . $email_id);
106
  $controls->messages = 'You can now edit the newsletter as pure HTML';
107
 
108
  tnp_prepare_controls($email, $controls);
109
+
110
  $editor_type = NewsletterEmails::EDITOR_HTML;
111
  }
112
 
124
  } else {
125
  $email['send_on'] = $controls->data['send_on'];
126
  }
127
+
128
  // Reset and refill the options
129
  // Try without the reset and let's see where the problems are
130
  //$email['options'] = array();
 
131
  // Reset only specific keys
132
  unset($email['options']['lists']);
133
  unset($email['options']['lists_operator']);
134
  unset($email['options']['lists_exclude']);
135
  unset($email['options']['sex']);
136
+ for ($i = 1; $i <= 20; $i ++) {
137
+ unset($email['options']["profile_$i"]);
138
+ }
139
+
140
  foreach ($controls->data as $name => $value) {
141
  if (strpos($name, 'options_') === 0) {
142
  $email['options'][substr($name, 8)] = $value;
154
  if ($email['options']['wp_users'] == '1') {
155
  $query .= " and wp_user_id<>0";
156
  }
157
+
158
  if (!empty($email['options']['language'])) {
159
  $query .= " and language='" . esc_sql((string) $email['options']['language']) . "'";
160
  }
161
+
162
+
163
  $list_where = array();
164
  if (isset($email['options']['lists']) && count($email['options']['lists'])) {
165
  foreach ($email['options']['lists'] as $list) {
202
  }
203
  }
204
 
205
+ // Profile fields filter
206
+ $profile_clause = array();
207
+ for ($i = 1; $i <= 20; $i ++) {
208
+ if (isset($email["options"]["profile_$i"]) && count($email["options"]["profile_$i"])) {
209
+ $profile_clause[] = 'profile_' . $i . " IN ('" . implode("','", esc_sql($email["options"]["profile_$i"])) . "') ";
210
+ }
211
+ }
212
+
213
+ if (!empty($profile_clause)) {
214
+ $query .= ' and (' . implode(' and ', $profile_clause) . ')';
215
+ }
216
+
217
  // Temporary save to have an object and call the query filter
218
  $e = Newsletter::instance()->save_email($email);
219
  $query = apply_filters('newsletter_emails_email_query', $query, $e);
232
  $email = Newsletter::instance()->save_email($email, ARRAY_A);
233
 
234
  tnp_prepare_controls($email, $controls);
235
+
236
  if ($email === false) {
237
  $controls->errors = 'Unable to save. Try to deactivate and reactivate the plugin may be the database is out of sync.';
238
  }
241
  }
242
 
243
  if ($controls->is_action('send') || $controls->is_action('schedule')) {
244
+
245
  NewsletterStatistics::instance()->reset_stats($email);
246
+
247
  if ($email['subject'] == '') {
248
  $controls->errors = __('A subject is required to send', 'newsletter');
249
  } else {
250
  $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'sending'), array('id' => $email_id));
251
  $email['status'] = 'sending';
252
  if ($controls->is_action('send')) {
253
+ $controls->messages = __('Now sending.', 'newsletter');
254
  } else {
255
+ $controls->messages = __('Scheduled.', 'newsletter');
256
  }
257
  }
258
  }
274
  } else {
275
  $subscriber_count = $email['sent'];
276
  }
 
277
  ?>
278
  <style>
279
  .select2-container {
308
  <?php $controls->button_back('?page=newsletter_emails_index') ?>
309
 
310
  <?php } else { ?>
311
+
312
+ <a class="button-primary" href="<?php echo $module->get_editor_url($email_id, $editor_type) ?>">
313
  <i class="fas fa-edit"></i> <?php _e('Edit', 'newsletter') ?>
314
  </a>
315
 
347
  <?php $module->show_email_progress_bar($email, array('numbers' => $email['status'] == 'sent' ? false : true)) ?>
348
 
349
  <?php if ($email['status'] == 'sent' || $email['status'] == 'sending') { ?>
350
+ <div class="tnp-nl-status-row">
351
+ <span class="tnp-nl-status-schedule-value"><?php
352
+ if ($email['status'] == 'sent') {
353
+ echo __('Sent on'), ' ', $module->format_date($email['send_on']);
354
+ } else if ($email['status'] == 'sending' && $email['send_on'] > time()) {
355
+ echo __('Scheduled on'), ' ', $module->format_date($email['send_on']);
356
+ }
357
+ ?></span>
358
+ </div>
359
  <?php } ?>
360
  <div class="tnp-nl-status-row">
361
  <span class="tnp-nl-status-schedule-targeting"><?php _e('Targeted subscribers', 'newsletter') ?>:</span>
368
  </div>
369
 
370
  <div id="tabs">
371
+
372
  <ul>
373
  <li><a href="#tabs-options"><?php _e('Sending Options', 'newsletter') ?></a></li>
374
  <li><a href="#tabs-advanced"><?php _e('Advanced', 'newsletter') ?></a></li>
401
  <?php $controls->select2('options_lists_exclude', $lists, null, true, null, __('None', 'newsletter')); ?>
402
  </td>
403
  </tr>
404
+
405
  <tr>
406
  <th><?php _e('Language', 'newsletter') ?></th>
407
  <td>
408
  <?php $controls->language('options_language'); ?>
409
  </td>
410
  </tr>
411
+
412
  <tr>
413
  <th><?php _e('Gender', 'newsletter') ?></th>
414
  <td>
428
  <?php $controls->yesno('options_wp_users'); ?>
429
  </td>
430
  </tr>
431
+ <?php
432
+ $fields = TNP_Profile_Service::get_profiles('', TNP_Profile::TYPE_SELECT);
433
+ ?>
434
+ <?php if (!empty($fields)) { ?>
435
+ <tr>
436
+ <th><?php _e('Profile fields', 'newsletter') ?></th>
437
+ <td>
438
+ <?php foreach ($fields as $profile) { ?>
439
+ <?php echo esc_html($profile->name), ' ', __('is one of:', 'newsletter') ?>
440
+ <?php $controls->select2("options_profile_$profile->id", $profile->options, null, true, null, __('Do not filter by this field', 'newsletter')); ?>
441
+ <br>
442
+ <?php } ?>
443
+ <p class="description">
444
+
445
+ </p>
446
+ </td>
447
+ </tr>
448
+ <?php } ?>
449
  </table>
450
 
451
  <?php do_action('newsletter_emails_edit_target', $module->get_email($email_id), $controls) ?>
452
 
453
  </div>
454
 
455
+
456
  <div id="tabs-advanced">
457
 
458
  <table class="form-table">
499
  </tr>
500
  </table>
501
  </div>
502
+
503
 
504
  <div id="tabs-preview">
505
 
534
  </script>
535
 
536
  <p>
537
+ <?php if ($editor_type != NewsletterEmails::EDITOR_HTML && $email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_confirm('html', __('Convert to HTML newsletter', 'newsletter'), 'Attention: no way back!'); ?>
538
  </p>
539
  </div>
540
 
emails/themes/default/social-options.php CHANGED
@@ -19,10 +19,6 @@ if (!defined('ABSPATH')) exit;
19
  <th>Pinterest</th>
20
  <td><?php $controls->text_url('theme_pinterest', 30); ?></td>
21
  </tr>
22
- <tr>
23
- <th>Google+</th>
24
- <td><?php $controls->text_url('theme_googleplus', 30); ?></td>
25
- </tr>
26
  <tr>
27
  <th>LinkedIn</th>
28
  <td><?php $controls->text_url('theme_linkedin', 30); ?></td>
19
  <th>Pinterest</th>
20
  <td><?php $controls->text_url('theme_pinterest', 30); ?></td>
21
  </tr>
 
 
 
 
22
  <tr>
23
  <th>LinkedIn</th>
24
  <td><?php $controls->text_url('theme_linkedin', 30); ?></td>
emails/themes/default/social.php CHANGED
@@ -19,12 +19,6 @@ $social_icon_url = plugins_url('newsletter') . '/emails/themes/default/images';
19
  </td>
20
  <?php } ?>
21
 
22
- <?php if (!empty($theme_options['theme_googleplus'])) { ?>
23
- <td style="text-align: center; vertical-align: top" align="center" valign="top">
24
- <a href="<?php echo esc_attr($theme_options['theme_googleplus']) ?>"><img src="<?php echo $social_icon_url ?>/googleplus.png"><br>Google+</a>
25
- </td>
26
- <?php } ?>
27
-
28
  <?php if (!empty($theme_options['theme_pinterest'])) { ?>
29
  <td style="text-align: center; vertical-align: top" align="center" valign="top">
30
  <a href="<?php echo esc_attr($theme_options['theme_pinterest']) ?>"><img src="<?php echo $social_icon_url ?>/pinterest.png"><br>Pinterest</a>
19
  </td>
20
  <?php } ?>
21
 
 
 
 
 
 
 
22
  <?php if (!empty($theme_options['theme_pinterest'])) { ?>
23
  <td style="text-align: center; vertical-align: top" align="center" valign="top">
24
  <a href="<?php echo esc_attr($theme_options['theme_pinterest']) ?>"><img src="<?php echo $social_icon_url ?>/pinterest.png"><br>Pinterest</a>
emails/themes/default/social_main.php CHANGED
@@ -12,12 +12,6 @@ $social_icon_url = plugins_url('newsletter') . '/emails/themes/default/images';
12
  <a href="<?php echo esc_attr($theme_options['main_facebook_url']) ?>"><img src="<?php echo $social_icon_url ?>/facebook.png" alt="Facebook"></a>
13
  </td>
14
  <?php } ?>
15
-
16
- <?php if (!empty($theme_options['main_googleplus_url'])) { ?>
17
- <td style="text-align: center; vertical-align: top" align="center" valign="top">
18
- <a href="<?php echo esc_attr($theme_options['main_googleplus_url']) ?>"><img src="<?php echo $social_icon_url ?>/googleplus.png"></a>
19
- </td>
20
- <?php } ?>
21
 
22
  <?php if (!empty($theme_options['main_twitter_url'])) { ?>
23
  <td style="text-align: center; vertical-align: top" align="center" valign="top">
12
  <a href="<?php echo esc_attr($theme_options['main_facebook_url']) ?>"><img src="<?php echo $social_icon_url ?>/facebook.png" alt="Facebook"></a>
13
  </td>
14
  <?php } ?>
 
 
 
 
 
 
15
 
16
  <?php if (!empty($theme_options['main_twitter_url'])) { ?>
17
  <td style="text-align: center; vertical-align: top" align="center" valign="top">
emails/themes/linear/theme.php CHANGED
@@ -76,7 +76,7 @@ $posts = get_posts($filters);
76
  <tr>
77
  <td valign="top" align="left">
78
  <?php
79
- foreach (array('facebook', 'twitter', 'youtube', 'linkedin', 'googleplus', 'pinterest', 'tumblr', 'instagram') as $social) {
80
  if (empty($theme_options["theme_$social"]))
81
  continue;
82
  ?>
76
  <tr>
77
  <td valign="top" align="left">
78
  <?php
79
+ foreach (array('facebook', 'twitter', 'youtube', 'linkedin', 'pinterest', 'tumblr', 'instagram') as $social) {
80
  if (empty($theme_options["theme_$social"]))
81
  continue;
82
  ?>
includes/controls.php CHANGED
@@ -15,7 +15,7 @@ class NewsletterControls {
15
  */
16
  var $messages = '';
17
  /**
18
- * @var array
19
  */
20
  var $warnings = array();
21
  var $countries = array(
@@ -678,10 +678,12 @@ class NewsletterControls {
678
 
679
  foreach ($options as $key => $data) {
680
  echo '<option value="' . esc_attr($key) . '"';
681
- if (is_array($value) && in_array($key, $value) || $value == $key)
682
- echo ' selected';
 
683
  echo '>' . esc_html($data) . '</option>';
684
  }
 
685
  echo '</select>';
686
  echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({placeholder: "', esc_js($placeholder), '"});</script>';
687
  }
@@ -866,7 +868,7 @@ class NewsletterControls {
866
  }
867
  echo '</button>';
868
  }
869
-
870
  function button_test($action = 'test', $label = 'Test') {
871
  echo '<button class="button-secondary" onclick="this.form.act.value=\'' . esc_attr($action) . '\';if (!confirm(\'';
872
  echo esc_attr(esc_js(__('Proceed with a test?', 'newsletter')));
@@ -884,7 +886,7 @@ class NewsletterControls {
884
  }
885
  }
886
  echo '</button>';
887
- }
888
 
889
  /**
890
  * Creates a button with "delete" action.
@@ -925,7 +927,7 @@ class NewsletterControls {
925
  echo '<input class="button-primary" type="button" value="' . esc_attr($label) . '" onclick="this.form.btn.value=\'' . esc_attr($data) . '\';this.form.act.value=\'' . esc_attr($action) . '\';if (confirm(\'' .
926
  esc_attr(esc_js($message)) . '\')) this.form.submit()"/>';
927
  }
928
-
929
  function button_statistics($url) {
930
  echo '<a class="button-primary" href="' . $url . '" title="Statistics"><i class="fas fa-chart-bar"></i></a>';
931
  }
@@ -1654,18 +1656,18 @@ class NewsletterControls {
1654
  }
1655
  return $buffer;
1656
  }
1657
-
1658
  static function delta_time($delta = 0) {
1659
  $seconds = $delta % 60;
1660
  $minutes = floor(($delta/60) % 60);
1661
  $hours = floor(($delta/(60*60)) % 24);
1662
  $days = floor($delta / (24*60*60));
1663
-
1664
-
1665
  return $days . ' day(s), ' . $hours . ' hour(s), ' . $minutes . ' minute(s)';
1666
-
1667
  }
1668
-
1669
  /**
1670
  * Prints the help button near a form field. The label is used as icon title.
1671
  *
15
  */
16
  var $messages = '';
17
  /**
18
+ * @var array
19
  */
20
  var $warnings = array();
21
  var $countries = array(
678
 
679
  foreach ($options as $key => $data) {
680
  echo '<option value="' . esc_attr($key) . '"';
681
+ if ( is_array( $value ) && in_array( $key, $value ) || ( ! is_null( $value ) && $value == $key ) ) {
682
+ echo ' selected';
683
+ }
684
  echo '>' . esc_html($data) . '</option>';
685
  }
686
+
687
  echo '</select>';
688
  echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({placeholder: "', esc_js($placeholder), '"});</script>';
689
  }
868
  }
869
  echo '</button>';
870
  }
871
+
872
  function button_test($action = 'test', $label = 'Test') {
873
  echo '<button class="button-secondary" onclick="this.form.act.value=\'' . esc_attr($action) . '\';if (!confirm(\'';
874
  echo esc_attr(esc_js(__('Proceed with a test?', 'newsletter')));
886
  }
887
  }
888
  echo '</button>';
889
+ }
890
 
891
  /**
892
  * Creates a button with "delete" action.
927
  echo '<input class="button-primary" type="button" value="' . esc_attr($label) . '" onclick="this.form.btn.value=\'' . esc_attr($data) . '\';this.form.act.value=\'' . esc_attr($action) . '\';if (confirm(\'' .
928
  esc_attr(esc_js($message)) . '\')) this.form.submit()"/>';
929
  }
930
+
931
  function button_statistics($url) {
932
  echo '<a class="button-primary" href="' . $url . '" title="Statistics"><i class="fas fa-chart-bar"></i></a>';
933
  }
1656
  }
1657
  return $buffer;
1658
  }
1659
+
1660
  static function delta_time($delta = 0) {
1661
  $seconds = $delta % 60;
1662
  $minutes = floor(($delta/60) % 60);
1663
  $hours = floor(($delta/(60*60)) % 24);
1664
  $days = floor($delta / (24*60*60));
1665
+
1666
+
1667
  return $days . ' day(s), ' . $hours . ' hour(s), ' . $minutes . ' minute(s)';
1668
+
1669
  }
1670
+
1671
  /**
1672
  * Prints the help button near a form field. The label is used as icon title.
1673
  *
includes/module.php CHANGED
@@ -45,13 +45,87 @@ abstract class TNP_List {
45
  * @property int $id The list unique identifier
46
  * @property string $name The list name
47
  * @property int $status When and how the list is visible to the subscriber - see constants
 
 
48
  */
49
- abstract class TNP_Profile {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
- const STATUS_PRIVATE = 0;
52
- const STATUS_PUBLIC = 2;
53
- const STATUS_PROFILE_ONLY = 1;
54
- const STATUS_HIDDEN = 3; // Public but never show (can be set with a hidden form field)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  }
57
 
@@ -1041,26 +1115,9 @@ class NewsletterModule {
1041
  * @param string $language The language for the list labels (it does not affect the lists returned)
1042
  * @return TNP_Profile[]
1043
  */
1044
- function get_profiles($language = '') {
1045
- static $profiles = array();
1046
- if (isset($profiles[$language])) {
1047
- return $profiles[$language];
1048
- }
1049
-
1050
- $profiles[$language] = array();
1051
- $data = NewsletterSubscription::instance()->get_options('profile', $language);
1052
- for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
1053
- if (empty($data['profile_' . $i])) {
1054
- continue;
1055
- }
1056
- $profile = new stdClass();
1057
- $profile->name = $data['profile_' . $i];
1058
- $profile->id = $i;
1059
- $profile->status = (int) $data['profile_' . $i . '_status'];
1060
- $profiles[$language][] = $profile;
1061
- }
1062
- return $profiles[$language];
1063
- }
1064
 
1065
  /**
1066
  * @param string $language The language for the list labels (it does not affect the lists returned)
@@ -2018,39 +2075,39 @@ class NewsletterModule {
2018
  return $posts;
2019
  }
2020
 
2021
- protected function generate_admin_notification_message( $user ) {
2022
 
2023
- $message = "Subscriber details:\n\n" .
2024
- "email: " . $user->email . "\n" .
2025
- "first name: " . $user->name . "\n" .
2026
- "last name: " . $user->surname . "\n" .
2027
- "gender: " . $user->sex . "\n";
2028
 
2029
- $lists = $this->get_lists();
2030
- foreach ( $lists as $list ) {
2031
- $field = 'list_' . $list->id;
2032
- $message .= $list->name . ': ' . ( empty( $user->$field ) ? "NO" : "YES" ) . "\n";
2033
- }
2034
 
2035
- for ( $i = 0; $i < NEWSLETTER_PROFILE_MAX; $i ++ ) {
2036
- if ( empty( $this->options_profile[ 'profile_' . $i ] ) ) {
2037
- continue;
2038
- }
2039
- $field = 'profile_' . $i;
2040
- $message .= $this->options_profile[ 'profile_' . $i ] . ': ' . $user->$field . "\n";
2041
- }
2042
 
2043
- $message .= "token: " . $user->token . "\n" .
2044
- "status: " . $user->status . "\n";
2045
 
2046
- return $message;
2047
- }
2048
 
2049
- protected function generate_admin_notification_subject( $subject ) {
2050
- $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
2051
 
2052
- return '[' . $blogname . '] ' . $subject;
2053
- }
2054
 
2055
  }
2056
 
45
  * @property int $id The list unique identifier
46
  * @property string $name The list name
47
  * @property int $status When and how the list is visible to the subscriber - see constants
48
+ * @property string $type Field type: text or select
49
+ * @property array $options Field options (usually the select items)
50
  */
51
+ class TNP_Profile {
52
+
53
+ const STATUS_PRIVATE = 0;
54
+ const STATUS_PUBLIC = 2;
55
+ const STATUS_PROFILE_ONLY = 1;
56
+ const STATUS_HIDDEN = 3; // Public but never shown (can be set with a hidden form field)
57
+
58
+ const TYPE_TEXT = 'text';
59
+ const TYPE_SELECT = 'select';
60
+
61
+ public $id;
62
+ public $name;
63
+ public $status;
64
+ public $type;
65
+ public $options;
66
+
67
+ public function __construct( $id, $name, $status, $type, $options ) {
68
+ $this->id = $id;
69
+ $this->name = $name;
70
+ $this->status = $status;
71
+ $this->type = $type;
72
+ $this->options = $options;
73
+ }
74
 
75
+ function is_select() {
76
+ return $this->type == self::TYPE_SELECT;
77
+ }
78
+
79
+ function is_text() {
80
+ return $this->type == self::TYPE_TEXT;
81
+ }
82
+ }
83
+
84
+ class TNP_Profile_Service {
85
+
86
+ static function get_profiles( $language = '', $type = null ) {
87
+
88
+ static $profiles = array();
89
+ if ( isset( $profiles[ $language ] ) ) {
90
+ return $profiles[ $language ];
91
+ }
92
+
93
+ $profiles[ $language ] = array();
94
+ $data = NewsletterSubscription::instance()->get_options( 'profile', $language );
95
+ for ( $i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i ++ ) {
96
+ if ( empty( $data[ 'profile_' . $i ] ) ) {
97
+ continue;
98
+ }
99
+ $profile = new TNP_Profile(
100
+ $i,
101
+ $data[ 'profile_' . $i ],
102
+ (int) $data[ 'profile_' . $i . '_status' ],
103
+ $data[ 'profile_' . $i . '_type' ],
104
+ self::string_db_options_to_array( $data[ 'profile_' . $i . '_options' ] )
105
+ );
106
+
107
+ if ( is_null( $type ) ||
108
+ ( $type == TNP_Profile::TYPE_SELECT && $profile->is_select() ) ||
109
+ ( $type == TNP_Profile::TYPE_TEXT && $profile->is_text() ) ) {
110
+ $profiles[ $language ][] = $profile;
111
+ }
112
+
113
+ }
114
+
115
+ return $profiles[ $language ];
116
+
117
+ }
118
+
119
+ /**
120
+ * Returns a list of strings which are the items for the select field.
121
+ * @return array
122
+ */
123
+ private static function string_db_options_to_array( $string_options ) {
124
+ $items = array_map( 'trim', explode( ',', $string_options ) );
125
+ $items = array_combine($items,$items);
126
+
127
+ return $items;
128
+ }
129
 
130
  }
131
 
1115
  * @param string $language The language for the list labels (it does not affect the lists returned)
1116
  * @return TNP_Profile[]
1117
  */
1118
+ function get_profiles( $language = '' ) {
1119
+ return TNP_Profile_Service::get_profiles( $language );
1120
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1121
 
1122
  /**
1123
  * @param string $language The language for the list labels (it does not affect the lists returned)
2075
  return $posts;
2076
  }
2077
 
2078
+ protected function generate_admin_notification_message($user) {
2079
 
2080
+ $message = "Subscriber details:\n\n" .
2081
+ "email: " . $user->email . "\n" .
2082
+ "first name: " . $user->name . "\n" .
2083
+ "last name: " . $user->surname . "\n" .
2084
+ "gender: " . $user->sex . "\n";
2085
 
2086
+ $lists = $this->get_lists();
2087
+ foreach ($lists as $list) {
2088
+ $field = 'list_' . $list->id;
2089
+ $message .= $list->name . ': ' . ( empty($user->$field) ? "NO" : "YES" ) . "\n";
2090
+ }
2091
 
2092
+ for ($i = 0; $i < NEWSLETTER_PROFILE_MAX; $i ++) {
2093
+ if (empty($this->options_profile['profile_' . $i])) {
2094
+ continue;
2095
+ }
2096
+ $field = 'profile_' . $i;
2097
+ $message .= $this->options_profile['profile_' . $i] . ': ' . $user->$field . "\n";
2098
+ }
2099
 
2100
+ $message .= "token: " . $user->token . "\n" .
2101
+ "status: " . $user->status . "\n";
2102
 
2103
+ return $message;
2104
+ }
2105
 
2106
+ protected function generate_admin_notification_subject($subject) {
2107
+ $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
2108
 
2109
+ return '[' . $blogname . '] ' . $subject;
2110
+ }
2111
 
2112
  }
2113
 
main/defaults-info.php CHANGED
@@ -10,7 +10,6 @@ $options = array(
10
  'facebook_url' => '',
11
  'twitter_url' => '',
12
  'instagram_url' => '',
13
- 'googleplus_url' => '',
14
  'pinterest_url' => '',
15
  'linkedin_url' => '',
16
  'tumblr_url' => '',
10
  'facebook_url' => '',
11
  'twitter_url' => '',
12
  'instagram_url' => '',
 
13
  'pinterest_url' => '',
14
  'linkedin_url' => '',
15
  'tumblr_url' => '',
main/defaults.php CHANGED
@@ -32,7 +32,6 @@ $options = array(
32
  'facebook_url' => '',
33
  'twitter_url' => '',
34
  'instagram_url' => '',
35
- 'googleplus_url' => '',
36
  'pinterest_url' => '',
37
  'linkedin_url' => '',
38
  'tumblr_url' => '',
32
  'facebook_url' => '',
33
  'twitter_url' => '',
34
  'instagram_url' => '',
 
35
  'pinterest_url' => '',
36
  'linkedin_url' => '',
37
  'tumblr_url' => '',
main/info.php CHANGED
@@ -110,12 +110,6 @@ if (!$controls->is_action()) {
110
  <?php $controls->text('instagram_url', 40); ?>
111
  </td>
112
  </tr>
113
- <tr>
114
- <th>Google+ URL</th>
115
- <td>
116
- <?php $controls->text('googleplus_url', 40); ?>
117
- </td>
118
- </tr>
119
  <tr>
120
  <th>Pinterest URL</th>
121
  <td>
110
  <?php $controls->text('instagram_url', 40); ?>
111
  </td>
112
  </tr>
 
 
 
 
 
 
113
  <tr>
114
  <th>Pinterest URL</th>
115
  <td>
main/smtp.php CHANGED
@@ -96,8 +96,9 @@ if (empty($controls->data['enabled']) && !empty($controls->data['host'])) {
96
  port: <?php $controls->text('port', 6); ?>
97
  <?php $controls->select('secure', array('' => 'No secure protocol', 'tls' => 'TLS protocol', 'ssl' => 'SSL protocol')); ?>
98
  <p class="description">
99
- Leave port empty for default value (25). To use Gmail try host "smtp.gmail.com" and port "465" and SSL protocol (without quotes).
100
- For GoDaddy use "relay-hosting.secureserver.net".
 
101
  </p>
102
  </td>
103
  </tr>
96
  port: <?php $controls->text('port', 6); ?>
97
  <?php $controls->select('secure', array('' => 'No secure protocol', 'tls' => 'TLS protocol', 'ssl' => 'SSL protocol')); ?>
98
  <p class="description">
99
+ Leave port empty for default value (25).<br>
100
+ To use GMail, do not set the SMTP here but use a <a href="https://wordpress.org/plugins/search/smtp+gmail/" target="_blank">SMTP plugin which supprts oAuth 2.0</a><br>
101
+ On GoDaddy TRY to use "relay-hosting.secureserver.net".
102
  </p>
103
  </td>
104
  </tr>
plugin.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: Newsletter
5
  Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
6
  Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
7
- Version: 6.6.3
8
  Author: Stefano Lissa & The Newsletter Team
9
  Author URI: https://www.thenewsletterplugin.com
10
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
@@ -35,7 +35,7 @@ if (version_compare(phpversion(), '5.6', '<')) {
35
  return;
36
  }
37
 
38
- define('NEWSLETTER_VERSION', '6.6.3');
39
 
40
  global $newsletter, $wpdb;
41
 
@@ -519,6 +519,11 @@ class Newsletter extends NewsletterModule {
519
 
520
  wp_enqueue_script( 'tnp-admin', $newsletter_url . '/admin.js', array( 'jquery' ), time() );
521
 
 
 
 
 
 
522
  wp_enqueue_style('wp-color-picker');
523
  wp_enqueue_script('wp-color-picker');
524
 
@@ -1214,15 +1219,15 @@ class Newsletter extends NewsletterModule {
1214
  }
1215
 
1216
  /**
1217
- *
1218
  * @return int
1219
  */
1220
  function get_newsletter_page_id() {
1221
  return (int) $this->options['page'];
1222
  }
1223
-
1224
  /**
1225
- *
1226
  * @return WP_Post
1227
  */
1228
  function get_newsletter_page() {
4
  Plugin Name: Newsletter
5
  Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
6
  Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
7
+ Version: 6.6.4
8
  Author: Stefano Lissa & The Newsletter Team
9
  Author URI: https://www.thenewsletterplugin.com
10
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
35
  return;
36
  }
37
 
38
+ define('NEWSLETTER_VERSION', '6.6.4');
39
 
40
  global $newsletter, $wpdb;
41
 
519
 
520
  wp_enqueue_script( 'tnp-admin', $newsletter_url . '/admin.js', array( 'jquery' ), time() );
521
 
522
+ $translations_array = array(
523
+ 'save_to_update_counter' => __( 'Save the newsletter to update the counter!', 'newsletter' )
524
+ );
525
+ wp_localize_script( 'tnp-admin', 'tnp_translations', $translations_array );
526
+
527
  wp_enqueue_style('wp-color-picker');
528
  wp_enqueue_script('wp-color-picker');
529
 
1219
  }
1220
 
1221
  /**
1222
+ *
1223
  * @return int
1224
  */
1225
  function get_newsletter_page_id() {
1226
  return (int) $this->options['page'];
1227
  }
1228
+
1229
  /**
1230
+ *
1231
  * @return WP_Post
1232
  */
1233
  function get_newsletter_page() {
readme.txt CHANGED
@@ -1,8 +1,8 @@
1
  === Newsletter ===
2
  Tags: email, email marketing, newsletter, newsletter subscribers, welcome email, signup forms, contact, lead generation, popup, marketing automation
3
  Requires at least: 3.4.0
4
- Tested up to: 5.4
5
- Stable tag: 6.6.3
6
  Requires PHP: 5.6
7
  Contributors: satollo,webagile,michael-travan
8
 
@@ -109,6 +109,14 @@ Thank you, The Newsletter Team
109
 
110
  == Changelog ==
111
 
 
 
 
 
 
 
 
 
112
  = 6.6.3 =
113
 
114
  * Changed the administration script enqueuing
1
  === Newsletter ===
2
  Tags: email, email marketing, newsletter, newsletter subscribers, welcome email, signup forms, contact, lead generation, popup, marketing automation
3
  Requires at least: 3.4.0
4
+ Tested up to: 5.4.1
5
+ Stable tag: 6.6.4
6
  Requires PHP: 5.6
7
  Contributors: satollo,webagile,michael-travan
8
 
109
 
110
  == Changelog ==
111
 
112
+ = 6.6.4 =
113
+
114
+ * Added filter on profile fields on targeting
115
+ * Administrator notice on custom forms using provate lists
116
+ * Added translation code on some words
117
+ * Compatibility check with WP 5.4.1
118
+ * Tip changed on SMTP panel about GMail
119
+
120
  = 6.6.3 =
121
 
122
  * Changed the administration script enqueuing
style.css CHANGED
@@ -246,7 +246,6 @@ CUSTOM CSS RULES.
246
  font-size: 14px;
247
  line-height: normal;
248
  border-radius: 0px;
249
- box-sizing: border-box;
250
  height: auto;
251
  margin: 0;
252
  }
@@ -295,7 +294,6 @@ CUSTOM CSS RULES.
295
  color: #fff;
296
  font-size: 14px;
297
  line-height: 20px;
298
- box-sizing: border-box;
299
  border-radius: 0px;
300
  margin: 0;
301
  }
246
  font-size: 14px;
247
  line-height: normal;
248
  border-radius: 0px;
 
249
  height: auto;
250
  margin: 0;
251
  }
294
  color: #fff;
295
  font-size: 14px;
296
  line-height: 20px;
 
297
  border-radius: 0px;
298
  margin: 0;
299
  }
subscription/subscription.php CHANGED
@@ -828,6 +828,19 @@ class NewsletterSubscription extends NewsletterModule {
828
  $user['profile_' . $i] = trim(stripslashes($_REQUEST['np' . $i]));
829
  }
830
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
831
 
832
  // Preferences (field names are nl[] and values the list number so special forms with radio button can work)
833
  if (isset($_REQUEST['nl']) && is_array($_REQUEST['nl'])) {
828
  $user['profile_' . $i] = trim(stripslashes($_REQUEST['np' . $i]));
829
  }
830
  }
831
+
832
+ // Extra validation to explain the administrator while the submitted data could
833
+ // be interpreted only partially
834
+ if (current_user_can('administrator')) {
835
+ if (isset($_REQUEST['nl']) && is_array($_REQUEST['nl'])) {
836
+ foreach ($_REQUEST['nl'] as $list_id) {
837
+ $list = $this->get_list($list_id);
838
+ if ($list->status === TNP_List::STATUS_PRIVATE) {
839
+ die('Message visible only to the administrator. List ' . $list_id . ' has been submitted but it is set as private. Please fix the subscription form.');
840
+ }
841
+ }
842
+ }
843
+ }
844
 
845
  // Preferences (field names are nl[] and values the list number so special forms with radio button can work)
846
  if (isset($_REQUEST['nl']) && is_array($_REQUEST['nl'])) {
users/edit.php CHANGED
@@ -139,13 +139,14 @@ function percentValue($value, $total) {
139
  <tr>
140
  <th><?php _e('Gender', 'newsletter'); ?></th>
141
  <td>
142
- <?php $controls->select('sex', array('n' => 'Not specified', 'f' => 'female', 'm' => 'male')); ?>
143
  </td>
144
  </tr>
145
  <tr>
146
  <th><?php _e('Status', 'newsletter'); ?></th>
147
  <td>
148
- <?php $controls->select('status', array('C' => 'Confirmed', 'S' => 'Not confirmed', 'U' => 'Unsubscribed', 'B' => 'Bounced')); ?>
 
149
  </td>
150
  </tr>
151
  <tr>
139
  <tr>
140
  <th><?php _e('Gender', 'newsletter'); ?></th>
141
  <td>
142
+ <?php $controls->select('sex', array('n' => __('Not specified', 'newsletter'), 'f' => __('Female', 'newsletter'), 'm' => __('Male', 'newsletter'))); ?>
143
  </td>
144
  </tr>
145
  <tr>
146
  <th><?php _e('Status', 'newsletter'); ?></th>
147
  <td>
148
+ <?php $controls->select('status', array('C' => __('Confirmed', 'newsletter'), 'S' => __('Not confirmed', 'newsletter'),
149
+ 'U' => __('Unsubscribed', 'newsletter'), 'B' => __('Bounced', 'newsletter'))); ?>
150
  </td>
151
  </tr>
152
  <tr>