Newsletter - Version 7.1.0

Version Description

  • [COMPOSER] Added link to tags documentation to inject subscriber's data
  • [COMPOSER] Fixed layout of posts block for Outlook 365
  • [GENERAL] Improved caching of addons json (even on error)
  • [GENERAL] Status menu changed to System/Status and System/Logs
  • [API] Fixed the subscriber status management (the API Addon should be updated as well)
  • [GENERAL] Fixed management of fatal errors on sending
  • [GENERAL] Limited error string per message to 250 chars
  • [GENERAL] Fixed check on field names (thanks Peter P.)
Download this release

Release Info

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

Code changes from version 7.0.9 to 7.1.0

admin.css CHANGED
@@ -604,11 +604,18 @@ table.clicks {
604
  margin: 0px;
605
  }
606
 
607
- #tnp-heading p {
608
  margin: 0px;
609
  color: #ccc;
610
  }
611
 
 
 
 
 
 
 
 
612
  /* Style for WP global notices */
613
  #tnp-heading .notice p {
614
  margin: 0.5em 0;
604
  margin: 0px;
605
  }
606
 
607
+ #tnp-heading p, #tnp-heading ul {
608
  margin: 0px;
609
  color: #ccc;
610
  }
611
 
612
+ #tnp-heading ul {
613
+ list-style-type: circle;
614
+ list-style-position: inside;
615
+ margin-left: 2em;
616
+ margin-top: 1em;
617
+ }
618
+
619
  /* Style for WP global notices */
620
  #tnp-heading .notice p {
621
  margin: 0.5em 0;
emails/blocks/posts/layout-one-2.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
2
  $size = ['width' => 600, 'height' => 0];
 
 
3
  ?>
4
  <style>
5
- .post-title {
6
  font-family: <?php echo $title_font_family ?>;
7
  font-size: <?php echo $title_font_size ?>px;
8
  font-weight: <?php echo $title_font_weight ?>;
@@ -11,7 +13,7 @@ $size = ['width' => 600, 'height' => 0];
11
  padding: 0 0 10px 0;
12
  }
13
 
14
- .post-excerpt {
15
  font-family: <?php echo $text_font_family ?>;
16
  font-size: <?php echo $text_font_size ?>px;
17
  font-weight: <?php echo $text_font_weight ?>;
@@ -21,16 +23,7 @@ $size = ['width' => 600, 'height' => 0];
21
  text-decoration: none;
22
  }
23
 
24
- .readmore {
25
- font-family: <?php echo $text_font_family ?>;
26
- font-size: <?php echo $text_font_size ?>px;
27
- font-weight: <?php echo $text_font_weight ?>;
28
- color: <?php echo $text_font_color ?>;
29
- line-height: 1.5em;
30
- text-decoration: none;
31
- }
32
-
33
- .post-date {
34
  font-family: <?php echo $text_font_family ?>;
35
  color: <?php echo $text_font_color ?>;
36
  font-size: <?php echo round($text_font_size * 0.8) ?>px;
@@ -38,7 +31,7 @@ $size = ['width' => 600, 'height' => 0];
38
  padding: 0 0 5px 0;
39
  }
40
 
41
- .post-author {
42
  font-family: <?php echo $text_font_family ?>;
43
  color: <?php echo $text_font_color ?>;
44
  font-size: <?php echo round($text_font_size * 0.8) ?>px;
@@ -48,89 +41,81 @@ $size = ['width' => 600, 'height' => 0];
48
  </style>
49
 
50
 
51
- <table border="0" cellpadding="0" cellspacing="0" width="100%" class="responsive-table">
52
 
53
  <?php foreach ($posts as $post) { ?>
54
  <?php
55
  $url = tnp_post_permalink($post);
56
- $options['button_url'] = $url;
57
 
58
  $media = null;
59
  if ($show_image) {
60
  $media = tnp_composer_block_posts_get_media($post, $size);
61
  if ($media) {
62
  $media->link = $url;
63
- $media->set_width(250);
64
  }
65
  }
66
 
67
- $author = '';
68
- if ($show_author) {
69
- $author_object = get_user_by('id', $post->post_author);
70
- if ($author_object) {
71
- $author = $author_object->display_name;
72
- }
73
- }
74
-
75
  ?>
76
 
77
  <tr>
78
- <td align="<?php echo $align_left ?>"
79
- inline-class="post-title"
80
- class="tnpc-row-edit tnpc-inline-editable"
81
- data-type="title" data-id="<?php echo $post->ID ?>" dir="<?php echo $dir ?>">
82
- <?php
83
- echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'title', $post->ID) ?
84
- TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'title', $post->ID) :
85
- tnp_post_title($post)
86
- ?>
87
  </td>
88
  </tr>
89
 
90
  <tr>
91
 
92
- <td valign="top" style="padding: 20px 0 0 0;" class="td-1">
93
-
94
-
95
 
96
  <?php if ($media) { ?>
97
- <table width="40%" cellpadding="0" cellspacing="0" border="0" align="left" class="responsive" style="margin-bottom: 20px">
98
  <tr>
99
  <td>
100
- <?php echo TNP_Composer::image($media, ['class'=>'responsive']) ?>
101
  </td>
102
  </tr>
103
  </table>
104
  <?php } ?>
105
 
106
- <table width="<?php echo $media ? '57%' : '100%' ?>" cellpadding="0" cellspacing="0" border="0" class="responsive-table" align="right">
107
  <tr>
108
  <td>
109
-
110
- <!-- ARTICLE -->
111
  <table border="0" cellspacing="0" cellpadding="0" width="100%">
112
  <?php if ($show_date) { ?>
113
  <tr>
114
- <td align="<?php echo $align_left ?>" inline-class="post-date">
115
  <?php echo tnp_post_date($post) ?>
116
  </td>
117
  </tr>
118
  <?php } ?>
119
 
120
- <?php if ($show_author) { ?>
121
  <tr>
122
- <td align="<?php echo $align_left ?>" inline-class="post-author">
123
- <?php echo $author ?>
124
  </td>
125
  </tr>
126
- <?php } ?>
127
 
128
  <tr>
129
  <td align="<?php echo $align_left ?>"
130
  inline-class="post-excerpt"
131
 
132
  data-id="<?php echo $post->ID ?>" dir="<?php echo $dir ?>">
133
- <a href="<?php $url ?>" inline-class="post-excerpt" class="tnpc-row-edit tnpc-inline-editable" data-type="text">
134
  <?php
135
  echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'text', $post->ID) ?
136
  TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'text', $post->ID) :
@@ -139,15 +124,16 @@ $size = ['width' => 600, 'height' => 0];
139
  </a>
140
  </td>
141
  </tr>
142
- <?php if ($show_read_more_button) { ?>
 
143
  <tr>
144
- <td align="<?php echo $align_left ?>" class="padding">
145
- <?php $button_options['button_url'] = $url; ?>
146
- <?php echo TNP_Composer::button( $button_options ) ?>
147
- <br><br>
148
  </td>
149
  </tr>
150
- <?php } ?>
151
  </table>
152
 
153
  </td>
1
  <?php
2
  $size = ['width' => 600, 'height' => 0];
3
+ $total_width = 600 - $options['block_padding_left'] - $options['block_padding_right'];
4
+ $column_width = $total_width / 2 - 10;
5
  ?>
6
  <style>
7
+ .title {
8
  font-family: <?php echo $title_font_family ?>;
9
  font-size: <?php echo $title_font_size ?>px;
10
  font-weight: <?php echo $title_font_weight ?>;
13
  padding: 0 0 10px 0;
14
  }
15
 
16
+ .excerpt {
17
  font-family: <?php echo $text_font_family ?>;
18
  font-size: <?php echo $text_font_size ?>px;
19
  font-weight: <?php echo $text_font_weight ?>;
23
  text-decoration: none;
24
  }
25
 
26
+ .date {
 
 
 
 
 
 
 
 
 
27
  font-family: <?php echo $text_font_family ?>;
28
  color: <?php echo $text_font_color ?>;
29
  font-size: <?php echo round($text_font_size * 0.8) ?>px;
31
  padding: 0 0 5px 0;
32
  }
33
 
34
+ .author {
35
  font-family: <?php echo $text_font_family ?>;
36
  color: <?php echo $text_font_color ?>;
37
  font-size: <?php echo round($text_font_size * 0.8) ?>px;
41
  </style>
42
 
43
 
44
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" class="responsive">
45
 
46
  <?php foreach ($posts as $post) { ?>
47
  <?php
48
  $url = tnp_post_permalink($post);
49
+ $options['button_url'] = $url;
50
 
51
  $media = null;
52
  if ($show_image) {
53
  $media = tnp_composer_block_posts_get_media($post, $size);
54
  if ($media) {
55
  $media->link = $url;
56
+ $media->set_width($column_width);
57
  }
58
  }
59
 
60
+ $author = '';
61
+ if ($show_author) {
62
+ $author_object = get_user_by('id', $post->post_author);
63
+ if ($author_object) {
64
+ $author = $author_object->display_name;
65
+ }
66
+ }
 
67
  ?>
68
 
69
  <tr>
70
+ <td align="<?php echo $align_left ?>" inline-class="title" class="tnpc-row-edit tnpc-inline-editable" data-type="title" data-id="<?php echo $post->ID ?>" dir="<?php echo $dir ?>">
71
+ <?php
72
+ echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'title', $post->ID) ?
73
+ TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'title', $post->ID) :
74
+ tnp_post_title($post)
75
+ ?>
 
 
 
76
  </td>
77
  </tr>
78
 
79
  <tr>
80
 
81
+ <td valign="top" style="padding: 20px 0 25px 0;">
 
 
82
 
83
  <?php if ($media) { ?>
84
+ <table width="<?php echo $column_width ?>" cellpadding="0" cellspacing="0" border="0" align="left" class="responsive">
85
  <tr>
86
  <td>
87
+ <?php echo TNP_Composer::image($media, ['class' => 'responsive']) ?>
88
  </td>
89
  </tr>
90
  </table>
91
  <?php } ?>
92
 
93
+ <table width="<?php echo $media ? $column_width : '100%' ?>" cellpadding="0" cellspacing="0" border="0" class="responsive" align="right">
94
  <tr>
95
  <td>
 
 
96
  <table border="0" cellspacing="0" cellpadding="0" width="100%">
97
  <?php if ($show_date) { ?>
98
  <tr>
99
+ <td align="<?php echo $align_left ?>" inline-class="date">
100
  <?php echo tnp_post_date($post) ?>
101
  </td>
102
  </tr>
103
  <?php } ?>
104
 
105
+ <?php if ($show_author) { ?>
106
  <tr>
107
+ <td align="<?php echo $align_left ?>" inline-class="author">
108
+ <?php echo $author ?>
109
  </td>
110
  </tr>
111
+ <?php } ?>
112
 
113
  <tr>
114
  <td align="<?php echo $align_left ?>"
115
  inline-class="post-excerpt"
116
 
117
  data-id="<?php echo $post->ID ?>" dir="<?php echo $dir ?>">
118
+ <a href="<?php $url ?>" inline-class="excerpt" class="tnpc-row-edit tnpc-inline-editable" data-type="text">
119
  <?php
120
  echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'text', $post->ID) ?
121
  TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'text', $post->ID) :
124
  </a>
125
  </td>
126
  </tr>
127
+
128
+ <?php if ($show_read_more_button) { ?>
129
  <tr>
130
+ <td align="<?php echo $align_left ?>">
131
+ <br>
132
+ <?php $button_options['button_url'] = $url; ?>
133
+ <?php echo TNP_Composer::button($button_options) ?>
134
  </td>
135
  </tr>
136
+ <?php } ?>
137
  </table>
138
 
139
  </td>
emails/blocks/posts/layout-one.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
  $size = ['width' => 600, 'height' => 0];
 
 
3
  ?>
4
  <style>
5
  .post-title {
@@ -50,7 +52,7 @@ $size = ['width' => 600, 'height' => 0];
50
  $media = tnp_composer_block_posts_get_media($post, $size);
51
  if ($media) {
52
  $media->link = $url;
53
- $media->set_width(250);
54
  }
55
  }
56
 
@@ -69,7 +71,7 @@ $size = ['width' => 600, 'height' => 0];
69
  <td valign="top" style="padding: 20px 0 0 0;" class="td-1">
70
 
71
  <?php if ($media) { ?>
72
- <table width="40%" cellpadding="0" cellspacing="0" border="0" align="left" class="1-column" style="margin-bottom: 20px">
73
  <tr>
74
  <td>
75
  <?php echo TNP_Composer::image($media) ?>
@@ -78,7 +80,7 @@ $size = ['width' => 600, 'height' => 0];
78
  </table>
79
  <?php } ?>
80
 
81
- <table width="<?php echo $media ? '57%' : '100%' ?>" cellpadding="0" cellspacing="0" border="0" class="responsive-table" align="right">
82
  <tr>
83
  <td>
84
 
1
  <?php
2
  $size = ['width' => 600, 'height' => 0];
3
+ $total_width = 600 - $options['block_padding_left'] - $options['block_padding_right'];
4
+ $column_width = $total_width / 2 - 10;
5
  ?>
6
  <style>
7
  .post-title {
52
  $media = tnp_composer_block_posts_get_media($post, $size);
53
  if ($media) {
54
  $media->link = $url;
55
+ $media->set_width($column_width);
56
  }
57
  }
58
 
71
  <td valign="top" style="padding: 20px 0 0 0;" class="td-1">
72
 
73
  <?php if ($media) { ?>
74
+ <table width="<?php echo $column_width?>" cellpadding="0" cellspacing="0" border="0" align="left" class="responsive">
75
  <tr>
76
  <td>
77
  <?php echo TNP_Composer::image($media) ?>
80
  </table>
81
  <?php } ?>
82
 
83
+ <table width="<?php echo $media ? $column_width : '100%' ?>" cellpadding="0" cellspacing="0" border="0" class="responsive" align="right">
84
  <tr>
85
  <td>
86
 
emails/composer.php CHANGED
@@ -11,46 +11,48 @@ wp_enqueue_style('tnpc-newsletter-style', home_url('/') . '?na=emails-composer-c
11
 
12
  include NEWSLETTER_INCLUDES_DIR . '/codemirror.php';
13
 
 
 
14
  if ($controls->is_action()) {
15
 
16
- if ( $controls->is_action( 'save_preset' ) ) {
17
- // Create new preset email
18
- $email = new stdClass();
19
- TNP_Composer::update_email( $email, $controls );
20
- $email->type = NewsletterEmails::PRESET_EMAIL_TYPE;
21
- $email->editor = NewsletterEmails::EDITOR_COMPOSER;
22
- $email->subject = $module->sanitize_preset_name( $controls->data['subject'] );
23
- $email->message = $controls->data['message'];
24
 
25
- $email = Newsletter::instance()->save_email( $email );
26
 
27
- $redirect = $module->get_admin_page_url( 'composer' );
28
- $controls->js_redirect( $redirect );
29
 
30
- return;
31
- }
32
 
33
- if ( $controls->is_action( 'update_preset' ) && ! empty( $_POST['preset_id'] ) ) {
34
 
35
- $email = Newsletter::instance()->get_email( (int) $_POST['preset_id'] );
36
- TNP_Composer::update_email( $email, $controls );
37
 
38
- if ( $email->subject != sanitize_text_field($controls->data['subject']) ) {
39
- $email->subject = $module->sanitize_preset_name( $controls->data['subject'] );
40
- }
41
 
42
- $email->message = $controls->data['message'];
43
 
44
- $email = Newsletter::instance()->save_email( $email );
45
 
46
- $redirect = $module->get_admin_page_url( 'composer' );
47
- $controls->js_redirect( $redirect );
48
 
49
- return;
50
- }
51
 
52
 
53
- if (empty($_GET['id'])) {
54
 
55
  // Create a new email
56
  $email = new stdClass();
@@ -58,7 +60,7 @@ if ($controls->is_action()) {
58
  $email->track = Newsletter::instance()->options['track'];
59
  $email->token = $module->get_token();
60
  $email->message_text = "This email requires a modern e-mail reader but you can view the email online here:\n{email_url}.\nThank you, " . wp_specialchars_decode(get_option('blogname'), ENT_QUOTES) .
61
- "\nTo change your subscription follow: {profile_url}.";
62
  $email->editor = NewsletterEmails::EDITOR_COMPOSER;
63
  $email->type = 'message';
64
  $email->send_on = time();
@@ -72,7 +74,6 @@ if ($controls->is_action()) {
72
  $email = Newsletter::instance()->get_email($_GET['id']);
73
  TNP_Composer::update_email($email, $controls);
74
  $email = Newsletter::instance()->save_email($email);
75
-
76
  }
77
 
78
  $controls->add_message_saved();
@@ -93,25 +94,20 @@ if ($controls->is_action()) {
93
  return;
94
  } else {
95
 
96
- if ( ! empty( $_GET['id'] ) ) {
97
- $email = Newsletter::instance()->get_email( (int) $_GET['id'] );
98
- }
99
-
100
  }
101
 
102
- if (isset($email)) {
103
- TNP_Composer::prepare_controls($controls, $email);
104
- } else {
105
- //Add default global styles to controls data
106
- $controls->data = array_merge( TNP_Composer::get_global_style_defaults(), empty( $controls->data ) ? [] : $controls->data );
107
- }
108
  ?>
109
 
110
  <div id="tnp-notification">
111
  <?php
112
- $controls->show();
113
- $controls->messages = '';
114
- $controls->errors = '';
115
  ?>
116
  </div>
117
 
11
 
12
  include NEWSLETTER_INCLUDES_DIR . '/codemirror.php';
13
 
14
+ $email = null;
15
+
16
  if ($controls->is_action()) {
17
 
18
+ if ($controls->is_action('save_preset')) {
19
+ // Create new preset email
20
+ $email = new stdClass();
21
+ TNP_Composer::update_email($email, $controls);
22
+ $email->type = NewsletterEmails::PRESET_EMAIL_TYPE;
23
+ $email->editor = NewsletterEmails::EDITOR_COMPOSER;
24
+ $email->subject = $module->sanitize_preset_name($controls->data['subject']);
25
+ $email->message = $controls->data['message'];
26
 
27
+ $email = Newsletter::instance()->save_email($email);
28
 
29
+ $redirect = $module->get_admin_page_url('composer');
30
+ $controls->js_redirect($redirect);
31
 
32
+ return;
33
+ }
34
 
35
+ if ($controls->is_action('update_preset') && !empty($_POST['preset_id'])) {
36
 
37
+ $email = Newsletter::instance()->get_email((int) $_POST['preset_id']);
38
+ TNP_Composer::update_email($email, $controls);
39
 
40
+ if ($email->subject != sanitize_text_field($controls->data['subject'])) {
41
+ $email->subject = $module->sanitize_preset_name($controls->data['subject']);
42
+ }
43
 
44
+ $email->message = $controls->data['message'];
45
 
46
+ $email = Newsletter::instance()->save_email($email);
47
 
48
+ $redirect = $module->get_admin_page_url('composer');
49
+ $controls->js_redirect($redirect);
50
 
51
+ return;
52
+ }
53
 
54
 
55
+ if (empty($_GET['id'])) {
56
 
57
  // Create a new email
58
  $email = new stdClass();
60
  $email->track = Newsletter::instance()->options['track'];
61
  $email->token = $module->get_token();
62
  $email->message_text = "This email requires a modern e-mail reader but you can view the email online here:\n{email_url}.\nThank you, " . wp_specialchars_decode(get_option('blogname'), ENT_QUOTES) .
63
+ "\nTo change your subscription follow: {profile_url}.";
64
  $email->editor = NewsletterEmails::EDITOR_COMPOSER;
65
  $email->type = 'message';
66
  $email->send_on = time();
74
  $email = Newsletter::instance()->get_email($_GET['id']);
75
  TNP_Composer::update_email($email, $controls);
76
  $email = Newsletter::instance()->save_email($email);
 
77
  }
78
 
79
  $controls->add_message_saved();
94
  return;
95
  } else {
96
 
97
+ if (!empty($_GET['id'])) {
98
+ $email = Newsletter::instance()->get_email((int) $_GET['id']);
99
+ }
 
100
  }
101
 
102
+ TNP_Composer::prepare_controls($controls, $email);
103
+
 
 
 
 
104
  ?>
105
 
106
  <div id="tnp-notification">
107
  <?php
108
+ $controls->show();
109
+ $controls->messages = '';
110
+ $controls->errors = '';
111
  ?>
112
  </div>
113
 
emails/tnp-composer/index-v2.php CHANGED
@@ -82,9 +82,13 @@ $rev_dir = is_rtl() ? 'ltr' : 'rlt';
82
  </tr>
83
  </table>
84
 
85
- </div>
 
 
 
86
  <?php } ?>
87
 
 
88
  <div id="newsletter-builder-area-center-frame-content" dir="<?php echo $dir ?>">
89
 
90
  <!-- Composer content -->
82
  </tr>
83
  </table>
84
 
85
+ <div style="text-align: left; margin-left: 1em;">
86
+ <a href="https://www.thenewsletterplugin.com/documentation/newsletters/newsletter-tags/" target="_blank">You can use tags to inject subscriber fields</a>. Even on subject.
87
+ </div>
88
+ </div>
89
  <?php } ?>
90
 
91
+
92
  <div id="newsletter-builder-area-center-frame-content" dir="<?php echo $dir ?>">
93
 
94
  <!-- Composer content -->
includes/composer.php CHANGED
@@ -213,27 +213,33 @@ class TNP_Composer {
213
 
214
  /**
215
  * Prepares a controls object injecting the relevant fields from an email
216
- * which cannot be directly used by controls.
 
217
  *
218
- * @param Newsletter $controls
219
  * @param TNP_Email $email
220
  */
221
- static function prepare_controls($controls, $email) {
 
 
 
 
 
 
 
 
 
222
 
223
- foreach ($email->options as $name => $value) {
224
- //if (strpos($name, 'composer_') === 0) {
225
- $controls->data['options_' . $name] = $value;
226
- //}
227
  }
228
 
229
- $controls->data['message'] = TNP_Composer::unwrap_email($email->message);
230
- $controls->data['subject'] = $email->subject;
231
  if (!empty($email->options['sender_email'])) {
232
  $controls->data['sender_email'] = $email->options['sender_email'];
233
  } else {
234
  $controls->data['sender_email'] = Newsletter::instance()->options['sender_email'];
235
  }
236
-
237
  if (!empty($email->options['sender_name'])) {
238
  $controls->data['sender_name'] = $email->options['sender_name'];
239
  } else {
213
 
214
  /**
215
  * Prepares a controls object injecting the relevant fields from an email
216
+ * which cannot be directly used by controls. If $email is null or missing,
217
+ * $controls is prepared with default values.
218
  *
219
+ * @param NewsletterControls $controls
220
  * @param TNP_Email $email
221
  */
222
+ static function prepare_controls($controls, $email = null) {
223
+
224
+ // Controls for a new email (which actually does not exist yet
225
+ if (!empty($email)) {
226
+
227
+ foreach ($email->options as $name => $value) {
228
+ //if (strpos($name, 'composer_') === 0) {
229
+ $controls->data['options_' . $name] = $value;
230
+ //}
231
+ }
232
 
233
+ $controls->data['message'] = TNP_Composer::unwrap_email($email->message);
234
+ $controls->data['subject'] = $email->subject;
 
 
235
  }
236
 
 
 
237
  if (!empty($email->options['sender_email'])) {
238
  $controls->data['sender_email'] = $email->options['sender_email'];
239
  } else {
240
  $controls->data['sender_email'] = Newsletter::instance()->options['sender_email'];
241
  }
242
+
243
  if (!empty($email->options['sender_name'])) {
244
  $controls->data['sender_name'] = $email->options['sender_name'];
245
  } else {
includes/controls.php CHANGED
@@ -6,7 +6,7 @@ include_once __DIR__ . '/fields.php';
6
 
7
  class NewsletterControls {
8
 
9
- var $data;
10
  var $action = false;
11
  var $button_data = '';
12
  var $errors = '';
@@ -274,13 +274,17 @@ class NewsletterControls {
274
  'A2' => 'Satellite IP'
275
  );
276
 
 
 
 
 
277
  function __construct($options = null) {
278
- if ($options == null) {
279
  if (isset($_POST['options'])) {
280
  $this->data = stripslashes_deep($_POST['options']);
281
  }
282
  } else {
283
- $this->data = $options;
284
  }
285
 
286
  if (isset($_REQUEST['act'])) {
6
 
7
  class NewsletterControls {
8
 
9
+ var $data = [];
10
  var $action = false;
11
  var $button_data = '';
12
  var $errors = '';
274
  'A2' => 'Satellite IP'
275
  );
276
 
277
+ /**
278
+ *
279
+ * @param array $options
280
+ */
281
  function __construct($options = null) {
282
+ if ($options === null) {
283
  if (isset($_POST['options'])) {
284
  $this->data = stripslashes_deep($_POST['options']);
285
  }
286
  } else {
287
+ $this->data = (array)$options;
288
  }
289
 
290
  if (isset($_REQUEST['act'])) {
includes/module.php CHANGED
@@ -861,7 +861,7 @@ class NewsletterModule {
861
  }
862
 
863
  function admin_menu() {
864
-
865
  }
866
 
867
  function add_menu_page($page, $title, $capability = '') {
861
  }
862
 
863
  function admin_menu() {
864
+
865
  }
866
 
867
  function add_menu_page($page, $title, $capability = '') {
includes/store.php CHANGED
@@ -57,8 +57,7 @@ class NewsletterStore {
57
  global $wpdb;
58
  $field_name = (string)$field_name;
59
  $field_value = (string)$field_value;
60
-
61
- if (preg_match('/^[a-zA-Z_]+$/', $field_name) == 0) {
62
  $this->logger->error('Invalis field name: ' . $field_name);
63
  return false;
64
  }
57
  global $wpdb;
58
  $field_name = (string)$field_name;
59
  $field_value = (string)$field_value;
60
+ if (preg_match('/^[a-zA-Z0-9_]+$/', $field_name) == 0) {
 
61
  $this->logger->error('Invalis field name: ' . $field_name);
62
  return false;
63
  }
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: 7.0.9
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', '7.0.9');
39
 
40
  global $newsletter, $wpdb;
41
 
@@ -384,7 +384,7 @@ class Newsletter extends NewsletterModule {
384
  status tinyint(1) unsigned NOT NULL DEFAULT '0',
385
  open tinyint(1) unsigned NOT NULL DEFAULT '0',
386
  time int(10) unsigned NOT NULL DEFAULT '0',
387
- error varchar(100) NOT NULL DEFAULT '',
388
  ip varchar(100) NOT NULL DEFAULT '',
389
  PRIMARY KEY (email_id,user_id),
390
  KEY user_id (user_id),
@@ -808,7 +808,7 @@ class Newsletter extends NewsletterModule {
808
 
809
  if (is_wp_error($r)) {
810
 
811
- if (!$test) {
812
  $this->set_error_state_of_email($email, $r->get_error_message());
813
  }
814
 
@@ -906,7 +906,7 @@ class Newsletter extends NewsletterModule {
906
  } else {
907
  $message->from = $this->options['sender_email'];
908
  }
909
-
910
  if (!empty($email->options['sender_name'])) {
911
  $message->from_name = $email->options['sender_name'];
912
  } else {
@@ -932,8 +932,10 @@ class Newsletter extends NewsletterModule {
932
  return;
933
  }
934
  $status = empty($message->error) ? 0 : 1;
 
 
935
 
936
- $this->query($wpdb->prepare("insert into " . $wpdb->prefix . 'newsletter_sent (user_id, email_id, time, status, error) values (%d, %d, %d, %d, %s) on duplicate key update time=%d, status=%d, error=%s', $message->user_id, $message->email_id, time(), $status, $message->error, time(), $status, $message->error));
937
  }
938
 
939
  /**
@@ -1256,14 +1258,24 @@ class Newsletter extends NewsletterModule {
1256
  $extensions_json = get_transient('tnp_extensions_json');
1257
 
1258
  if (empty($extensions_json)) {
1259
- $url = "http://www.thenewsletterplugin.com/wp-content/extensions.json?ver=" . NEWSLETTER_VERSION;
1260
  $extensions_response = wp_remote_get($url);
 
1261
  if (is_wp_error($extensions_response)) {
 
 
 
1262
  $this->logger->error($extensions_response);
1263
- return false;
1264
- }
1265
- $extensions_json = wp_remote_retrieve_body($extensions_response);
1266
- if (!empty($extensions_json)) {
 
 
 
 
 
 
1267
  set_transient('tnp_extensions_json', $extensions_json, 72 * 60 * 60);
1268
  }
1269
  }
@@ -1299,14 +1311,14 @@ class Newsletter extends NewsletterModule {
1299
  function has_license() {
1300
  return !empty($this->options['contract_key']);
1301
  }
1302
-
1303
  function get_sender_name() {
1304
  return $this->options['sender_name'];
1305
  }
1306
-
1307
  function get_sender_email() {
1308
  return $this->options['sender_email'];
1309
- }
1310
 
1311
  /**
1312
  *
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: 7.1.0
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', '7.1.0');
39
 
40
  global $newsletter, $wpdb;
41
 
384
  status tinyint(1) unsigned NOT NULL DEFAULT '0',
385
  open tinyint(1) unsigned NOT NULL DEFAULT '0',
386
  time int(10) unsigned NOT NULL DEFAULT '0',
387
+ error varchar(255) NOT NULL DEFAULT '',
388
  ip varchar(100) NOT NULL DEFAULT '',
389
  PRIMARY KEY (email_id,user_id),
390
  KEY user_id (user_id),
808
 
809
  if (is_wp_error($r)) {
810
 
811
+ if (!$test && $r->get_error_code() == NewsletterMailer::ERROR_FATAL) {
812
  $this->set_error_state_of_email($email, $r->get_error_message());
813
  }
814
 
906
  } else {
907
  $message->from = $this->options['sender_email'];
908
  }
909
+
910
  if (!empty($email->options['sender_name'])) {
911
  $message->from_name = $email->options['sender_name'];
912
  } else {
932
  return;
933
  }
934
  $status = empty($message->error) ? 0 : 1;
935
+
936
+ $error = mb_substr($message->error, 0, 250);
937
 
938
+ $this->query($wpdb->prepare("insert into " . $wpdb->prefix . 'newsletter_sent (user_id, email_id, time, status, error) values (%d, %d, %d, %d, %s) on duplicate key update time=%d, status=%d, error=%s', $message->user_id, $message->email_id, time(), $status, $error, time(), $status, $error));
939
  }
940
 
941
  /**
1258
  $extensions_json = get_transient('tnp_extensions_json');
1259
 
1260
  if (empty($extensions_json)) {
1261
+ $url = "http://www.thenewsletterplugin.com/wp-content/extesions.json?ver=" . NEWSLETTER_VERSION;
1262
  $extensions_response = wp_remote_get($url);
1263
+
1264
  if (is_wp_error($extensions_response)) {
1265
+ // Cache anyway for blogs which cannot connect outside
1266
+ $extensions_json = '[]';
1267
+ set_transient('tnp_extensions_json', $extensions_json, 72 * 60 * 60);
1268
  $this->logger->error($extensions_response);
1269
+ } else {
1270
+
1271
+ $extensions_json = wp_remote_retrieve_body($extensions_response);
1272
+
1273
+ // Not clear cases
1274
+ if (empty($extensions_json) || !json_decode($extensions_json)) {
1275
+ $this->logger->error('Invalid json from thenewsletterplugin.com: retrying in 72 hours');
1276
+ $this->logger->error('JSON: ' . $extensions_json);
1277
+ $extensions_json = '[]';
1278
+ }
1279
  set_transient('tnp_extensions_json', $extensions_json, 72 * 60 * 60);
1280
  }
1281
  }
1311
  function has_license() {
1312
  return !empty($this->options['contract_key']);
1313
  }
1314
+
1315
  function get_sender_name() {
1316
  return $this->options['sender_name'];
1317
  }
1318
+
1319
  function get_sender_email() {
1320
  return $this->options['sender_email'];
1321
+ }
1322
 
1323
  /**
1324
  *
readme.txt CHANGED
@@ -2,7 +2,7 @@
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.7
5
- Stable tag: 7.0.9
6
  Requires PHP: 5.6
7
  Contributors: satollo,webagile,michael-travan
8
  License: GPLv2 or later
@@ -100,6 +100,7 @@ Premium Users with an active license have access to one-to-one support via our [
100
  = Follow Us =
101
 
102
  * **Our Official Website** - [https://www.thenewsletterplugin.com/](https://www.thenewsletterplugin.com/)
 
103
  * **Our Facebook Page** - [https://www.facebook.com/thenewsletterplugin](https://www.facebook.com/thenewsletterplugin)
104
  * **Our Twitter Account** - [https://twitter.com/newsletterwp](https://twitter.com/newsletterwp)
105
 
@@ -120,6 +121,18 @@ Thank you, The Newsletter Team
120
 
121
  == Changelog ==
122
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  = 7.0.9 =
124
 
125
  * [CAPTCHA] Fixed button label translation
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.7
5
+ Stable tag: 7.1.0
6
  Requires PHP: 5.6
7
  Contributors: satollo,webagile,michael-travan
8
  License: GPLv2 or later
100
  = Follow Us =
101
 
102
  * **Our Official Website** - [https://www.thenewsletterplugin.com/](https://www.thenewsletterplugin.com/)
103
+ * **LinkedIn** - [https://www.linkedin.com/company/the-newsletter-plugin](https://www.linkedin.com/company/the-newsletter-plugin)
104
  * **Our Facebook Page** - [https://www.facebook.com/thenewsletterplugin](https://www.facebook.com/thenewsletterplugin)
105
  * **Our Twitter Account** - [https://twitter.com/newsletterwp](https://twitter.com/newsletterwp)
106
 
121
 
122
  == Changelog ==
123
 
124
+ = 7.1.0 =
125
+
126
+ * [COMPOSER] Added link to tags documentation to inject subscriber's data
127
+ * [COMPOSER] Fixed layout of posts block for Outlook 365
128
+ * [GENERAL] Improved caching of addons json (even on error)
129
+ * [GENERAL] Status menu changed to System/Status and System/Logs
130
+ * [API] Fixed the subscriber status management (the API Addon should be updated as well)
131
+ * [GENERAL] Fixed management of fatal errors on sending
132
+ * [GENERAL] Limited error string per message to 250 chars
133
+ * [GENERAL] Fixed check on field names (thanks Peter P.)
134
+
135
+
136
  = 7.0.9 =
137
 
138
  * [CAPTCHA] Fixed button label translation
subscription/subscription.php CHANGED
@@ -464,7 +464,7 @@ class NewsletterSubscription extends NewsletterModule {
464
  /**
465
  * Builds a default subscription object to be used to collect data and subscription options.
466
  *
467
- * @return \TNP_Subscription
468
  */
469
  function get_default_subscription($language = null) {
470
  $subscription = new TNP_Subscription();
464
  /**
465
  * Builds a default subscription object to be used to collect data and subscription options.
466
  *
467
+ * @return TNP_Subscription
468
  */
469
  function get_default_subscription($language = null) {
470
  $subscription = new TNP_Subscription();
tnp-header.php CHANGED
@@ -177,12 +177,17 @@ $warning |= empty($status_options['mail']);
177
 
178
  <?php if ($is_administrator) { ?>
179
  <li>
180
- <a href="?page=newsletter_main_status"><i class="fas fa-thermometer"></i> <?php _e('Status', 'newsletter') ?>
181
  <?php if ($warning) { ?>
182
  <i class="fas fa-exclamation-triangle" style="color: red;"></i>
183
  <?php } ?>
184
  </a>
185
  <ul>
 
 
 
 
 
186
  <li>
187
  <a href="?page=newsletter_main_logs"><i class="fas fa-file"></i> <?php _e('Logs', 'newsletter') ?>
188
  <small><?php _e('Plugin and addons logs', 'newsletter') ?></small></a>
177
 
178
  <?php if ($is_administrator) { ?>
179
  <li>
180
+ <a href="#"><i class="fas fa-thermometer"></i> <?php _e('System', 'newsletter') ?>
181
  <?php if ($warning) { ?>
182
  <i class="fas fa-exclamation-triangle" style="color: red;"></i>
183
  <?php } ?>
184
  </a>
185
  <ul>
186
+ <li>
187
+ <a href="?page=newsletter_main_status"><i class="fas fa-file"></i> <?php _e('Status', 'newsletter') ?>
188
+ <small><?php _e('Checks and parameters', 'newsletter') ?></small></a>
189
+ </li>
190
+
191
  <li>
192
  <a href="?page=newsletter_main_logs"><i class="fas fa-file"></i> <?php _e('Logs', 'newsletter') ?>
193
  <small><?php _e('Plugin and addons logs', 'newsletter') ?></small></a>