Newsletter - Version 5.2.5

Version Description

  • Fixed url attributes on privacy field shortcode
  • Fixed few debug notices
  • (NEW) PHP API for coders (and companion REST API with the free Newsletter API extension)
Download this release

Release Info

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

Code changes from version 5.2.4 to 5.2.5

admin.css CHANGED
@@ -13,6 +13,13 @@
13
  box-sizing: border-box;
14
  }
15
 
 
 
 
 
 
 
 
16
  #tnp-wrap *:before,
17
  #tnp-wrap *:after {
18
  -webkit-box-sizing: border-box;
@@ -1014,7 +1021,7 @@ p.description {
1014
  background-color: #ECF0F1;
1015
  }
1016
 
1017
- .wp-core-ui .button-secondary, .wp-core-ui .button, .wp-core-ui .button-primary {
1018
  background-color: #3498db;
1019
  border: none;
1020
  box-shadow: none;
13
  box-sizing: border-box;
14
  }
15
 
16
+ /* Color picker patch */
17
+ #tnp-wrap .iris-picker, #tnp-wrap .iris-picker * {
18
+ -moz-box-sizing: content-box;
19
+ -webkit-box-sizing: content-box;
20
+ box-sizing: content-box;
21
+ }
22
+
23
  #tnp-wrap *:before,
24
  #tnp-wrap *:after {
25
  -webkit-box-sizing: border-box;
1021
  background-color: #ECF0F1;
1022
  }
1023
 
1024
+ .wp-core-ui .button-secondary, .wp-core-ui .button-primary {
1025
  background-color: #3498db;
1026
  border: none;
1027
  box-shadow: none;
includes/TNP.php ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * TNP classes for internal API
5
+ *
6
+ * Error reference
7
+ * 404 Object not found
8
+ * 403 Not allowed (when the API key is missing or wrong)
9
+ * 400 Bad request, when the parameters are not correct or required parameters are missing
10
+ *
11
+ */
12
+
13
+ /**
14
+ * Main API functions
15
+ *
16
+ * @author roby
17
+ */
18
+ class TNP {
19
+ /*
20
+ * The full process of subscription
21
+ */
22
+
23
+ public static function subscribe($params) {
24
+
25
+ // error_reporting(E_ALL);
26
+
27
+ $newsletter = Newsletter::instance();
28
+ $subscription = NewsletterSubscription::instance();
29
+
30
+ // Messages
31
+ $options = get_option('newsletter', array());
32
+
33
+ // Form field configuration
34
+ $options_profile = get_option('newsletter_profile', array());
35
+
36
+ $optin = (int) $newsletter->options['noconfirmation']; // 0 - double, 1 - single
37
+ if (isset($params['optin'])) {
38
+ switch ($params['optin']) {
39
+ case 'single': $optin = 1;
40
+ break;
41
+ case 'double': $optin = 0;
42
+ break;
43
+ }
44
+ }
45
+
46
+ $email = $newsletter->normalize_email(stripslashes($params['email']));
47
+
48
+ // Should never reach this point without a valid email address
49
+ if ($email == null) {
50
+ return new WP_Error('-1', 'Email address not valid', array('status' => 400));
51
+ }
52
+
53
+ $user = $newsletter->get_user($email);
54
+
55
+ if ($user != null) {
56
+
57
+ $newsletter->logger->info('Subscription of an address with status ' . $user->status);
58
+
59
+ // Bounced
60
+ if ($user->status == 'B') {
61
+ return new WP_Error('-1', 'Bounced address', array('status' => 400));
62
+ }
63
+
64
+ // If asked to put in confirmed status, do not check further
65
+ if ($params['status'] != 'C' && $optin == 0) {
66
+
67
+ // Already confirmed
68
+ //if ($optin == 0 && $user->status == 'C') {
69
+ if ($user->status == 'C') {
70
+
71
+ set_transient($user->id . '-' . $user->token, $params, 3600 * 48);
72
+ $subscription->set_updated($user);
73
+
74
+ // A second subscription always require confirmation otherwise anywan can change other users' data
75
+ $user->status = 'S';
76
+
77
+ $prefix = 'confirmation_';
78
+
79
+ if (empty($options[$prefix . 'disabled'])) {
80
+
81
+ $message = $options[$prefix . 'message'];
82
+ // TODO: This is always empty!
83
+ //$message_text = $options[$prefix . 'message_text'];
84
+ $subject = $options[$prefix . 'subject'];
85
+ $message = $subscription->add_microdata($message);
86
+ $newsletter->mail($user->email, $newsletter->replace($subject, $user), $newsletter->replace($message, $user));
87
+ }
88
+
89
+ return $user;
90
+ }
91
+ }
92
+ }
93
+
94
+ if ($user != null) {
95
+ $newsletter->logger->info("Email address subscribed but not confirmed");
96
+ $user = array('id' => $user->id);
97
+ } else {
98
+ $newsletter->logger->info("New email address");
99
+ $user = array('email' => $email);
100
+ }
101
+
102
+ $user = TNP::add_subscriber($params);
103
+
104
+ // TODO: decidere se applicare i filtri sulle API
105
+ // $user = apply_filters('newsletter_user_subscribe', $user);
106
+
107
+ if (is_wp_error($user)) {
108
+ return ($user);
109
+ }
110
+
111
+ // Notification to admin (only for new confirmed subscriptions)
112
+ if ($user->status == 'C') {
113
+ do_action('newsletter_user_confirmed', $user);
114
+ $subscription->notify_admin($user, 'Newsletter subscription');
115
+ setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
116
+ }
117
+
118
+ if (empty($params['send_emails']) || !$params['send_emails']) {
119
+ return $user;
120
+ }
121
+
122
+ $prefix = ($user->status == 'C') ? 'confirmed_' : 'confirmation_';
123
+
124
+ if (empty($options[$prefix . 'disabled'])) {
125
+ $message = $options[$prefix . 'message'];
126
+
127
+ if ($user->status == 'S') {
128
+ $message = $newsletter->add_microdata($message);
129
+ }
130
+
131
+ // TODO: This is always empty!
132
+ //$message_text = $options[$prefix . 'message_text'];
133
+ $subject = $options[$prefix . 'subject'];
134
+
135
+ $newsletter->mail($user->email, $newsletter->replace($subject, $user), $newsletter->replace($message, $user));
136
+ }
137
+ return $user;
138
+
139
+ }
140
+
141
+ /*
142
+ * The UNsubscription
143
+ */
144
+
145
+ public static function unsubscribe($params) {
146
+
147
+ $newsletter = Newsletter::instance();
148
+ $user = $newsletter->get_user($params['email']);
149
+
150
+ // $newsletter->logger->debug($params);
151
+
152
+ if (!$user) {
153
+ return new WP_Error('-1', 'Email address not found', array('status' => 404));
154
+ }
155
+
156
+ if ($user->status == 'U') {
157
+ return $user;
158
+ }
159
+
160
+ $newsletter->set_user_status($user->id, 'U');
161
+
162
+ if (empty($newsletter->options['unsubscribed_disabled'])) {
163
+ $newsletter->mail($user->email, $newsletter->replace($newsletter->options['unsubscribed_subject'], $user), $newsletter->replace($newsletter->options['unsubscribed_message'], $user));
164
+ }
165
+ $newsletter->notify_admin($user, 'Newsletter unsubscription');
166
+
167
+ return $user;
168
+ }
169
+
170
+ /*
171
+ * Adds a subscriber if not already in
172
+ */
173
+
174
+ public static function add_subscriber($params) {
175
+
176
+ $newsletter = Newsletter::instance();
177
+
178
+ $email = $newsletter->normalize_email(stripslashes($params['email']));
179
+
180
+ if (!$email) {
181
+ return new WP_Error('-1', 'Email address not valid', array('status' => 400));
182
+ }
183
+
184
+ $user = $newsletter->get_user($email);
185
+
186
+ if ($user) {
187
+ return new WP_Error('-1', 'Email address already exists', array('status' => 400));
188
+ }
189
+
190
+ $user = array('email' => $email);
191
+
192
+ if (isset($params['name'])) {
193
+ $user['name'] = $newsletter->normalize_name(stripslashes($params['name']));
194
+ }
195
+
196
+ if (isset($params['surname'])) {
197
+ $user['surname'] = $newsletter->normalize_name(stripslashes($params['surname']));
198
+ }
199
+
200
+ if (!empty($params['gender'])) {
201
+ $user['gender'] = $newsletter->normalize_sex($params['gender']);
202
+ }
203
+
204
+ if (is_array($params['profile'])) {
205
+ foreach ($params['profile'] as $key => $value) {
206
+ $user['profile_' . $key] = trim(stripslashes($value));
207
+ }
208
+ }
209
+
210
+ if (!empty($params['status'])) {
211
+ $user['status'] = $params['status'];
212
+ } else {
213
+ $user['status'] = 'C';
214
+ }
215
+
216
+ $user['token'] = $newsletter->get_token();
217
+ $user['updated'] = time();
218
+
219
+ $user = $newsletter->save_user($user);
220
+
221
+ return $user;
222
+ }
223
+
224
+ /*
225
+ * Deletes a subscriber
226
+ */
227
+
228
+ public static function delete_subscriber($params) {
229
+
230
+ global $wpdb;
231
+ $newsletter = Newsletter::instance();
232
+
233
+ $user = $newsletter->get_user($params['email']);
234
+
235
+ if (!$user) {
236
+ return new WP_Error('-1', 'Email address not found', array('status' => 404));
237
+ }
238
+
239
+ if ($wpdb->query($wpdb->prepare("delete from " . NEWSLETTER_USERS_TABLE . " where id=%d", (int) $user->id))) {
240
+ return "OK";
241
+ } else {
242
+ $newsletter->logger->debug($wpdb->last_query);
243
+ return new WP_Error('-1', $wpdb->last_error, array('status' => 400));
244
+ }
245
+ }
246
+
247
+ }
includes/module.php CHANGED
@@ -1034,18 +1034,20 @@ class NewsletterModule {
1034
 
1035
  $home_url = home_url('/');
1036
 
 
1037
  if ($email) {
1038
  $text = str_replace('{email_id}', $email->id, $text);
1039
  $text = str_replace('{email_subject}', $email->subject, $text);
1040
  $text = $this->replace_url($text, 'EMAIL_URL', $home_url . '?na=v&id=' . $email->id . '&amp;nk=' . $nk);
 
1041
  }
1042
 
1043
 
1044
  $text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', $home_url . '?na=c&nk=' . $nk);
1045
  $text = $this->replace_url($text, 'ACTIVATION_URL', $home_url . '?na=c&nk=' . $nk);
1046
 
1047
- $text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', $home_url . '?na=uc&nk=' . $nk . ($email ? '&nek=' . $email->id : ''));
1048
- $text = $this->replace_url($text, 'UNSUBSCRIPTION_URL', $home_url . '?na=u&nk=' . $nk . ($email ? '&nek=' . $email->id : ''));
1049
 
1050
  // Obsolete.
1051
  $text = $this->replace_url($text, 'FOLLOWUP_SUBSCRIPTION_URL', self::add_qs($base, 'nm=fs' . $id_token));
@@ -1059,9 +1061,7 @@ class NewsletterModule {
1059
  $text = $this->replace_url($text, 'PROFILE_URL', self::add_qs($options_profile['profile_url'], 'ni=' . $user->id . '&amp;nt=' . $user->token));
1060
 
1061
  $text = $this->replace_url($text, 'UNLOCK_URL', $home_url . '?na=ul&nk=' . $nk);
1062
- if ($email) {
1063
-
1064
- }
1065
  } else {
1066
  $text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', '#');
1067
  $text = $this->replace_url($text, 'ACTIVATION_URL', '#');
1034
 
1035
  $home_url = home_url('/');
1036
 
1037
+ $nek = false;
1038
  if ($email) {
1039
  $text = str_replace('{email_id}', $email->id, $text);
1040
  $text = str_replace('{email_subject}', $email->subject, $text);
1041
  $text = $this->replace_url($text, 'EMAIL_URL', $home_url . '?na=v&id=' . $email->id . '&amp;nk=' . $nk);
1042
+ $nek = $email->id . '-' . $email->token;
1043
  }
1044
 
1045
 
1046
  $text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', $home_url . '?na=c&nk=' . $nk);
1047
  $text = $this->replace_url($text, 'ACTIVATION_URL', $home_url . '?na=c&nk=' . $nk);
1048
 
1049
+ $text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', $home_url . '?na=uc&nk=' . $nk . ($nek ? '&nek=' . $nek : ''));
1050
+ $text = $this->replace_url($text, 'UNSUBSCRIPTION_URL', $home_url . '?na=u&nk=' . $nk . ($nek ? '&nek=' . $nek : ''));
1051
 
1052
  // Obsolete.
1053
  $text = $this->replace_url($text, 'FOLLOWUP_SUBSCRIPTION_URL', self::add_qs($base, 'nm=fs' . $id_token));
1061
  $text = $this->replace_url($text, 'PROFILE_URL', self::add_qs($options_profile['profile_url'], 'ni=' . $user->id . '&amp;nt=' . $user->token));
1062
 
1063
  $text = $this->replace_url($text, 'UNLOCK_URL', $home_url . '?na=ul&nk=' . $nk);
1064
+
 
 
1065
  } else {
1066
  $text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', '#');
1067
  $text = $this->replace_url($text, 'ACTIVATION_URL', '#');
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: 5.2.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.
@@ -14,7 +14,7 @@
14
  */
15
 
16
  // Used as dummy parameter on css and js links
17
- define('NEWSLETTER_VERSION', '5.2.4');
18
 
19
  global $wpdb, $newsletter;
20
 
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: 5.2.5
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.
14
  */
15
 
16
  // Used as dummy parameter on css and js links
17
+ define('NEWSLETTER_VERSION', '5.2.5');
18
 
19
  global $wpdb, $newsletter;
20
 
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Tags: newsletter,email,subscription,mass mail,list build,email marketing,direct mailing,automation,automated
3
  Requires at least: 3.4.0
4
  Tested up to: 4.9.4
5
- Stable tag: 5.2.4
6
  Contributors: satollo,webagile,michael-travan
7
 
8
  Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
@@ -21,6 +21,7 @@ send and track e-mails, headache-free. It just works out of box!
21
  * Wordpress User Registration **seamless integration**
22
  * **Single** And **Double Opt-In** plus privacy checkbox for EU laws compliance
23
  * **Subscribers lists** to fine-target your campaigns
 
24
  * SMTP-Ready
25
  * Customizable Themes
26
  * Newsletter with Html and Text message versions
@@ -38,19 +39,21 @@ send and track e-mails, headache-free. It just works out of box!
38
 
39
  Find and install them from the Extensions panel in your blog.
40
 
41
- * WP Registration Integration: connects the WordPress standard registration with Newsletter subscription. Optionally imports all registered users as subscribers.
42
- * Locked Content: exchange the access to your premium contents with a subscription
43
- * Archive: creates a simple blog page which lists all your sent newsletters
44
 
45
  = Professional Extensions =
46
 
47
  Need *more power*? Feel *something's missing*? The Newsletter Plugin features can be easily extended through
48
  our **premium, professional Extensions**! Let us introduce just two of them : )
49
 
50
- * [Reports Extension](https://www.thenewsletterplugin.com/reports) is a regular WordPress plugin which improves the internal statistics collection system and provides better reports of data collected for each sent email. Neat.
51
- * [Automated Extension](https://www.thenewsletterplugin.com/automated) generates and sends your newsletters using your blog last posts, even custom ones like events or products. Just sit and watch!
52
- * [WooCommerce Extension](https://www.thenewsletterplugin.com/woocommerce) subscribe customers to a mailing list and generate product newletters.
53
- * [Amazon SES and other providers integration](https://www.thenewsletterplugin.com/integrations) seamlessly integrate Amazon SES and other email service providers with The Newsletter Plugin. Hassle-free.
 
 
54
 
55
  = Support =
56
 
@@ -85,6 +88,12 @@ Thank you, The Newsletter Team
85
 
86
  == Changelog ==
87
 
 
 
 
 
 
 
88
  = 5.2.4 =
89
 
90
  * readme.txt fix
2
  Tags: newsletter,email,subscription,mass mail,list build,email marketing,direct mailing,automation,automated
3
  Requires at least: 3.4.0
4
  Tested up to: 4.9.4
5
+ Stable tag: 5.2.5
6
  Contributors: satollo,webagile,michael-travan
7
 
8
  Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
21
  * Wordpress User Registration **seamless integration**
22
  * **Single** And **Double Opt-In** plus privacy checkbox for EU laws compliance
23
  * **Subscribers lists** to fine-target your campaigns
24
+ * PHP API and REST API for coders and integrations
25
  * SMTP-Ready
26
  * Customizable Themes
27
  * Newsletter with Html and Text message versions
39
 
40
  Find and install them from the Extensions panel in your blog.
41
 
42
+ * [WP Registration Integration](https://www.thenewsletterplugin.com/documentation/wpusers-extension) - connects the WordPress standard and custom registration with Newsletter subscription. Optionally imports all registered users as subscribers.
43
+ * [Archive Extension](https://www.thenewsletterplugin.com/documentation/archive-extension) - creates a simple blog page which lists all your sent newsletters
44
+ * [Locked Content Extension](https://www.thenewsletterplugin.com/documentation/locked-content-extension) - open up your premium content only after subscription
45
 
46
  = Professional Extensions =
47
 
48
  Need *more power*? Feel *something's missing*? The Newsletter Plugin features can be easily extended through
49
  our **premium, professional Extensions**! Let us introduce just two of them : )
50
 
51
+ * [Reports Extension](https://www.thenewsletterplugin.com/reports) - improves the internal statistics collection system and provides better reports of data collected for each sent email. Neat.
52
+ * [Automated Extension](https://www.thenewsletterplugin.com/automated) - generates and sends your newsletters using your blog last posts, even custom ones like events or products. Just sit and watch!
53
+ * [WooCommerce Extension](https://www.thenewsletterplugin.com/woocommerce) - subscribe customers to a mailing list and generate product newletters.
54
+ * [Amazon SES and other providers integration](https://www.thenewsletterplugin.com/integrations) - seamlessly integrate Amazon SES and other email service providers with The Newsletter Plugin. Hassle-free.
55
+ * [Contact Form 7 Extension](https://www.thenewsletterplugin.com/documentation/contact-form-7-extension) - integrate the subscription on Contact Form 7 forms
56
+ * [Google Analytics Extension](https://www.thenewsletterplugin.com/google-analytics) - track newsletter links with Google UTM tracking paramaters
57
 
58
  = Support =
59
 
88
 
89
  == Changelog ==
90
 
91
+ = 5.2.5 =
92
+
93
+ * Fixed url attributes on privacy field shortcode
94
+ * Fixed few debug notices
95
+ * (NEW) PHP API for coders (and companion REST API with the free Newsletter API extension)
96
+
97
  = 5.2.4 =
98
 
99
  * readme.txt fix
statistics/statistics.php CHANGED
@@ -138,6 +138,8 @@ class NewsletterStatistics extends NewsletterModule {
138
  } else {
139
  $this->logger->info('Email with no token hence not signature to check');
140
  }
 
 
141
 
142
  $row = $wpdb->get_row($wpdb->prepare("select * from " . NEWSLETTER_STATS_TABLE . " where email_id=%d and user_id=%d and url='' limit 1", $email->id, $user->id));
143
  if ($row) {
138
  } else {
139
  $this->logger->info('Email with no token hence not signature to check');
140
  }
141
+
142
+ $ip = preg_replace('/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR']);
143
 
144
  $row = $wpdb->get_row($wpdb->prepare("select * from " . NEWSLETTER_STATS_TABLE . " where email_id=%d and user_id=%d and url='' limit 1", $email->id, $user->id));
145
  if ($row) {
subscription/subscription.php CHANGED
@@ -780,7 +780,7 @@ class NewsletterSubscription extends NewsletterModule {
780
  }
781
 
782
  if ($email) {
783
- $params .= '&nek=' . $email->id;
784
  }
785
 
786
  // Add exceptions for "profile" key.
@@ -1128,7 +1128,7 @@ class NewsletterSubscription extends NewsletterModule {
1128
  $buffer .= '<input type="checkbox" name="ny" required class="tnp-privacy" id="tnp-privacy"> ';
1129
  $buffer .= '<label for="tnp-privacy">';
1130
  if (!empty($attrs['url'])) {
1131
- $buffer .= '<a target="_blank" href="' . esc_attr($options_profile['privacy_url']) . '">';
1132
  }
1133
  $buffer .= $attrs['label'];
1134
  if (!empty($attrs['url'])) {
780
  }
781
 
782
  if ($email) {
783
+ $params .= '&nek=' . $email->id . '-' . $email->token;
784
  }
785
 
786
  // Add exceptions for "profile" key.
1128
  $buffer .= '<input type="checkbox" name="ny" required class="tnp-privacy" id="tnp-privacy"> ';
1129
  $buffer .= '<label for="tnp-privacy">';
1130
  if (!empty($attrs['url'])) {
1131
+ $buffer .= '<a target="_blank" href="' . esc_attr($attrs['url']) . '">';
1132
  }
1133
  $buffer .= $attrs['label'];
1134
  if (!empty($attrs['url'])) {