Newsletter - Version 6.4.0

Version Description

  • Fixed extra profile fields management in REST and PHP API
  • Removed the "read more" added by themes on posts excerpt
  • Core improvements
Download this release

Release Info

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

Code changes from version 6.3.8 to 6.4.0

emails/blocks/posts/block.php CHANGED
@@ -91,6 +91,8 @@ $button_color = $options['button_font_color'];
91
 
92
  $alternative = plugins_url('newsletter') . '/emails/blocks/posts/images/blank.png';
93
  $alternative_2 = plugins_url('newsletter') . '/emails/blocks/posts/images/blank-240x160.png';
 
 
94
  ?>
95
 
96
  <?php if ($options['layout'] == 'one') { ?>
91
 
92
  $alternative = plugins_url('newsletter') . '/emails/blocks/posts/images/blank.png';
93
  $alternative_2 = plugins_url('newsletter') . '/emails/blocks/posts/images/blank-240x160.png';
94
+
95
+ remove_all_filters('excerpt_more');
96
  ?>
97
 
98
  <?php if ($options['layout'] == 'one') { ?>
emails/blocks/posts/options.php CHANGED
@@ -24,7 +24,7 @@
24
 
25
  <?php $fields->checkbox('show_date', __('Show date', 'newsletter')) ?>
26
 
27
- <?php $fields->select_number('max', __('Max posts', 'newsletter'), 1, 20); ?>
28
 
29
  <?php $fields->language(); ?>
30
 
24
 
25
  <?php $fields->checkbox('show_date', __('Show date', 'newsletter')) ?>
26
 
27
+ <?php $fields->select_number('max', __('Max posts', 'newsletter'), 1, 40); ?>
28
 
29
  <?php $fields->language(); ?>
30
 
includes/TNP.php CHANGED
@@ -16,286 +16,297 @@
16
  * @author roby
17
  */
18
  class TNP {
19
- /*
20
- * The full process of subscription
21
- */
22
-
23
- public static function subscribe($params) {
24
-
25
- $newsletter = Newsletter::instance();
26
- $subscription = NewsletterSubscription::instance();
27
-
28
- // default params
29
- $defaults = array('send_emails' => true);
30
- $params = array_merge ($defaults, $params);
31
-
32
- // Messages
33
- $options = get_option('newsletter', array());
34
-
35
- // Form field configuration
36
- $options_profile = get_option('newsletter_profile', array());
37
-
38
- $optin = (int) $options['noconfirmation']; // 0 - double, 1 - single
39
-
40
- $email = $newsletter->normalize_email(stripslashes($params['email']));
41
-
42
- // Should never reach this point without a valid email address
43
- if ($email == null) {
44
- return new WP_Error('-1', 'Email address not valid', array('status' => 400));
45
- }
46
-
47
- $user = $newsletter->get_user($email);
48
-
49
- if ($user != null) {
50
-
51
- $newsletter->logger->info('Subscription of an address with status ' . $user->status);
52
-
53
- // Bounced
54
- if ($user->status == 'B') {
55
- return new WP_Error('-1', 'Bounced address', array('status' => 400));
56
- }
57
-
58
- // If asked to put in confirmed status, do not check further
59
- if ($params['status'] != 'C' && $optin == 0) {
60
-
61
- // Already confirmed
62
- //if ($optin == 0 && $user->status == 'C') {
63
- if ($user->status == 'C') {
64
-
65
- set_transient($user->id . '-' . $user->token, $params, 3600 * 48);
66
- $subscription->set_updated($user);
67
-
68
- // A second subscription always require confirmation otherwise anywan can change other users' data
69
- $user->status = 'S';
70
- $subscription->send_activation_email($user);
71
-
72
- return $user;
73
- }
74
- }
75
- }
76
-
77
- if ($user != null) {
78
- $newsletter->logger->info("Email address subscribed but not confirmed");
79
- $user = array('id' => $user->id);
80
- } else {
81
- $newsletter->logger->info("New email address");
82
- }
83
-
84
- if ($optin) {
85
- $params['status'] = 'C';
86
- } else {
87
- $params['status'] = 'S';
88
- }
89
-
90
- // Lists
91
-
92
- if (!isset($params['lists']) || !is_array($params['lists'])) {
93
- $params['lists'] = array();
94
- }
95
-
96
- // Public lists: rebuild the array keeping only the valid lists
97
- $lists = $newsletter->get_lists_public();
98
-
99
- // Public list IDs
100
- $public_lists = array();
101
- foreach ($lists as $list) {
102
- $public_lists[] = $list->id;
103
- }
104
-
105
- // Keep only the public lists
106
- $params['lists'] = array_intersect($public_lists, $params['lists']);
107
-
108
- // Pre assigned lists
109
- $lists = $newsletter->get_lists();
110
- foreach ($lists as $list) {
111
- if ($list->forced) {
112
- $params['lists'][] = $list->id;
113
- }
114
- }
115
-
116
- apply_filters('newsletter_api_subscribe', $params);
117
-
118
- $user = TNP::add_subscriber($params);
119
-
120
- if (is_wp_error($user)) {
121
- return ($user);
122
- }
123
-
124
- // Notification to admin (only for new confirmed subscriptions)
125
- if ($user->status == 'C') {
126
- do_action('newsletter_user_confirmed', $user);
127
- $subscription->notify_admin($user, 'Newsletter subscription');
128
- setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
129
- }
130
-
131
- // skip messages if send_emails = false
132
- if (!$params['send_emails']) {
133
- return $user;
134
- }
135
-
136
- $message_type = ($user->status == 'C') ? 'confirmed' : 'confirmation';
137
- $subscription->send_message($message_type, $user);
138
-
139
- return $user;
140
- }
141
-
142
- /*
143
- * The UNsubscription
144
- */
145
-
146
- public static function unsubscribe($params) {
147
-
148
- $newsletter = Newsletter::instance();
149
- $user = $newsletter->get_user($params['email']);
 
 
 
 
 
 
 
 
150
 
151
  // $newsletter->logger->debug($params);
152
 
153
- if (!$user) {
154
- return new WP_Error('-1', 'Email address not found', array('status' => 404));
155
- }
 
 
 
 
 
 
 
 
 
 
 
156
 
157
- if ($user->status == 'U') {
158
- return $user;
159
- }
160
 
161
- $user = $newsletter->set_user_status($user, 'U');
 
 
162
 
163
- if (empty(NewsletterSubscription::instance()->options['unsubscribed_disabled'])) {
164
- $newsletter->mail($user->email, $newsletter->replace(NewsletterSubscription::instance()->options['unsubscribed_subject'], $user), $newsletter->replace(NewsletterSubscription::instance()->options['unsubscribed_message'], $user));
165
- }
166
- NewsletterSubscription::instance()->notify_admin($user, 'Newsletter unsubscription');
167
 
168
- return $user;
169
- }
170
 
171
- /*
172
- * Adds a subscriber if not already in
173
- */
174
 
175
- public static function add_subscriber($params) {
 
 
176
 
177
- $newsletter = Newsletter::instance();
178
 
179
- $email = $newsletter->normalize_email(stripslashes($params['email']));
 
 
180
 
181
- if (!$email) {
182
- return new WP_Error('-1', 'Email address not valid', array('status' => 400));
183
- }
184
 
185
- $user = $newsletter->get_user($email);
 
 
186
 
187
- if ($user) {
188
- return new WP_Error('-1', 'Email address already exists', array('status' => 400));
189
- }
190
 
191
- $user = array('email' => $email);
 
 
192
 
193
- if (isset($params['name'])) {
194
- $user['name'] = $newsletter->normalize_name(stripslashes($params['name']));
195
- }
 
 
196
 
197
- if (isset($params['surname'])) {
198
- $user['surname'] = $newsletter->normalize_name(stripslashes($params['surname']));
199
- }
 
 
 
 
200
 
201
- if (!empty($params['gender'])) {
202
- $user['sex'] = $newsletter->normalize_sex($params['gender']);
203
- }
204
 
205
- if (isset($params['profile']) && is_array($params['profile'])) {
206
- foreach ($params['profile'] as $key => $value) {
207
- $user['profile_' . $key] = trim(stripslashes($value));
208
- }
209
- }
210
 
211
- // Lists (an arrayunder the key "lists")
212
- // Preferences (field names are nl[] and values the list number so special forms with radio button can work)
213
- if (isset($params['lists']) && is_array($params['lists'])) {
214
- foreach ($params['lists'] as $list_id) {
215
- $user['list_' . ((int)$list_id)] = 1;
216
- }
217
- }
218
 
 
219
 
220
- if (!empty($params['status'])) {
221
- $user['status'] = $params['status'];
222
- } else {
223
- $user['status'] = 'C';
224
- }
225
 
226
- $user['token'] = $newsletter->get_token();
227
- $user['updated'] = time();
228
-
229
- $user['ip'] = Newsletter::get_remote_ip();
230
 
231
- $user = $newsletter->save_user($user);
 
 
232
 
233
- return $user;
234
- }
235
 
236
- /*
237
- * Subscribers list
238
- */
239
 
240
- public static function subscribers($params) {
 
241
 
242
- global $wpdb;
243
- $newsletter = Newsletter::instance();
 
244
 
245
- $items_per_page = 20;
246
- $where = "";
247
 
248
- $query = "select name, email from " . NEWSLETTER_USERS_TABLE . ' ' . $where . " order by id desc";
249
- $query .= " limit 0," . $items_per_page;
250
- $list = $wpdb->get_results($query);
251
 
252
- return $list;
253
- }
254
 
255
- /*
256
- * Deletes a subscriber
257
- */
258
 
259
- public static function delete_subscriber($params) {
260
 
261
- global $wpdb;
262
- $newsletter = Newsletter::instance();
 
263
 
264
- $user = $newsletter->get_user($params['email']);
 
 
 
265
 
266
- if (!$user) {
267
- return new WP_Error('-1', 'Email address not found', array('status' => 404));
268
- }
269
 
270
- if ($wpdb->query($wpdb->prepare("delete from " . NEWSLETTER_USERS_TABLE . " where id=%d", (int) $user->id))) {
271
- return "OK";
272
- } else {
273
- $newsletter->logger->debug($wpdb->last_query);
274
- return new WP_Error('-1', $wpdb->last_error, array('status' => 400));
275
- }
276
- }
277
 
278
- /*
279
- * Newsletters list
280
- */
281
 
282
- public static function newsletters($params) {
 
283
 
284
- global $wpdb;
285
- $newsletter = Newsletter::instance();
286
 
287
- $list = $wpdb->get_results("SELECT id, subject, created, status, total, sent, send_on FROM " . NEWSLETTER_EMAILS_TABLE . " ORDER BY id DESC LIMIT 10", OBJECT);
 
288
 
289
- if ($wpdb->last_error) {
290
- $newsletter->logger->error($wpdb->last_error);
291
- return false;
292
- }
293
 
294
- if (empty($list)) {
295
- return array();
296
- }
297
 
298
- return $list;
299
- }
300
 
301
  }
16
  * @author roby
17
  */
18
  class TNP {
19
+ /*
20
+ * The full process of subscription
21
+ */
22
+
23
+ public static function subscribe( $params ) {
24
+
25
+ $newsletter = Newsletter::instance();
26
+ $subscription = NewsletterSubscription::instance();
27
+
28
+ // default params
29
+ $defaults = array( 'send_emails' => true );
30
+ $params = array_merge( $defaults, $params );
31
+
32
+ // Messages
33
+ $options = get_option( 'newsletter', array() );
34
+
35
+ // Form field configuration
36
+ $options_profile = get_option( 'newsletter_profile', array() );
37
+
38
+ $optin = (int) $options['noconfirmation']; // 0 - double, 1 - single
39
+
40
+ $email = $newsletter->normalize_email( stripslashes( $params['email'] ) );
41
+
42
+ // Should never reach this point without a valid email address
43
+ if ( $email == null ) {
44
+ return new WP_Error( '-1', 'Email address not valid', array( 'status' => 400 ) );
45
+ }
46
+
47
+ $user = $newsletter->get_user( $email );
48
+
49
+ if ( $user != null ) {
50
+
51
+ $newsletter->logger->info( 'Subscription of an address with status ' . $user->status );
52
+
53
+ // Bounced
54
+ if ( $user->status == 'B' ) {
55
+ return new WP_Error( '-1', 'Bounced address', array( 'status' => 400 ) );
56
+ }
57
+
58
+ // If asked to put in confirmed status, do not check further
59
+ if ( $params['status'] != 'C' && $optin == 0 ) {
60
+
61
+ // Already confirmed
62
+ //if ($optin == 0 && $user->status == 'C') {
63
+ if ( $user->status == 'C' ) {
64
+
65
+ set_transient( $user->id . '-' . $user->token, $params, 3600 * 48 );
66
+ $subscription->set_updated( $user );
67
+
68
+ // A second subscription always require confirmation otherwise anywan can change other users' data
69
+ $user->status = 'S';
70
+ $subscription->send_activation_email( $user );
71
+
72
+ return $user;
73
+ }
74
+ }
75
+ }
76
+
77
+ if ( $user != null ) {
78
+ $newsletter->logger->info( "Email address subscribed but not confirmed" );
79
+ $user = array( 'id' => $user->id );
80
+ } else {
81
+ $newsletter->logger->info( "New email address" );
82
+ }
83
+
84
+ if ( $optin ) {
85
+ $params['status'] = 'C';
86
+ } else {
87
+ $params['status'] = 'S';
88
+ }
89
+
90
+ // Lists
91
+
92
+ if ( ! isset( $params['lists'] ) || ! is_array( $params['lists'] ) ) {
93
+ $params['lists'] = array();
94
+ }
95
+
96
+ // Public lists: rebuild the array keeping only the valid lists
97
+ $lists = $newsletter->get_lists_public();
98
+
99
+ // Public list IDs
100
+ $public_lists = array();
101
+ foreach ( $lists as $list ) {
102
+ $public_lists[] = $list->id;
103
+ }
104
+
105
+ // Keep only the public lists
106
+ $params['lists'] = array_intersect( $public_lists, $params['lists'] );
107
+
108
+ // Pre assigned lists
109
+ $lists = $newsletter->get_lists();
110
+ foreach ( $lists as $list ) {
111
+ if ( $list->forced ) {
112
+ $params['lists'][] = $list->id;
113
+ }
114
+ }
115
+
116
+ // Keep only the public profile fields
117
+ for ( $i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i ++ ) {
118
+ // If the profile cannot be set by subscriber, skip it.
119
+ if ( $subscription->options_profile[ 'profile_' . $i . '_status' ] == 0 ) {
120
+ unset( $params[ 'profile_' . $i ] );
121
+ }
122
+ }
123
+
124
+ apply_filters( 'newsletter_api_subscribe', $params );
125
+
126
+ $user = TNP::add_subscriber( $params );
127
+
128
+ if ( is_wp_error( $user ) ) {
129
+ return ( $user );
130
+ }
131
+
132
+ // Notification to admin (only for new confirmed subscriptions)
133
+ if ( $user->status == 'C' ) {
134
+ do_action( 'newsletter_user_confirmed', $user );
135
+ $subscription->notify_admin( $user, 'Newsletter subscription' );
136
+ setcookie( 'newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/' );
137
+ }
138
+
139
+ // skip messages if send_emails = false
140
+ if ( ! $params['send_emails'] ) {
141
+ return $user;
142
+ }
143
+
144
+ $message_type = ( $user->status == 'C' ) ? 'confirmed' : 'confirmation';
145
+ $subscription->send_message( $message_type, $user );
146
+
147
+ return null;
148
+ }
149
+
150
+ /*
151
+ * The UNsubscription
152
+ */
153
+
154
+ public static function unsubscribe( $params ) {
155
+
156
+ $newsletter = Newsletter::instance();
157
+ $user = $newsletter->get_user( $params['email'] );
158
 
159
  // $newsletter->logger->debug($params);
160
 
161
+ if ( ! $user ) {
162
+ return new WP_Error( '-1', 'Email address not found', array( 'status' => 404 ) );
163
+ }
164
+
165
+ if ( $user->status == 'U' ) {
166
+ return $user;
167
+ }
168
+
169
+ $user = $newsletter->set_user_status( $user, 'U' );
170
+
171
+ if ( empty( NewsletterSubscription::instance()->options['unsubscribed_disabled'] ) ) {
172
+ $newsletter->mail( $user->email, $newsletter->replace( NewsletterSubscription::instance()->options['unsubscribed_subject'], $user ), $newsletter->replace( NewsletterSubscription::instance()->options['unsubscribed_message'], $user ) );
173
+ }
174
+ NewsletterSubscription::instance()->notify_admin( $user, 'Newsletter unsubscription' );
175
 
176
+ return $user;
177
+ }
 
178
 
179
+ /*
180
+ * Adds a subscriber if not already in
181
+ */
182
 
183
+ public static function add_subscriber( $params ) {
 
 
 
184
 
185
+ $newsletter = Newsletter::instance();
186
+ $subscription = NewsletterSubscription::instance();
187
 
188
+ $email = $newsletter->normalize_email( stripslashes( $params['email'] ) );
 
 
189
 
190
+ if ( ! $email ) {
191
+ return new WP_Error( '-1', 'Email address not valid', array( 'status' => 400 ) );
192
+ }
193
 
194
+ $user = $newsletter->get_user( $email );
195
 
196
+ if ( $user ) {
197
+ return new WP_Error( '-1', 'Email address already exists', array( 'status' => 400 ) );
198
+ }
199
 
200
+ $user = array( 'email' => $email );
 
 
201
 
202
+ if ( isset( $params['name'] ) ) {
203
+ $user['name'] = $newsletter->normalize_name( stripslashes( $params['name'] ) );
204
+ }
205
 
206
+ if ( isset( $params['surname'] ) ) {
207
+ $user['surname'] = $newsletter->normalize_name( stripslashes( $params['surname'] ) );
208
+ }
209
 
210
+ if ( ! empty( $params['gender'] ) ) {
211
+ $user['sex'] = $newsletter->normalize_sex( $params['gender'] );
212
+ }
213
 
214
+ for ( $i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i ++ ) {
215
+ if ( isset( $params[ 'profile_' . $i ] ) ) {
216
+ $user[ 'profile_' . $i ] = trim( stripslashes( $params[ 'profile_' . $i ] ) );
217
+ }
218
+ }
219
 
220
+ // Lists (an array under the key "lists")
221
+ // Preferences (field names are nl[] and values the list number so special forms with radio button can work)
222
+ if ( isset( $params['lists'] ) && is_array( $params['lists'] ) ) {
223
+ foreach ( $params['lists'] as $list_id ) {
224
+ $user[ 'list_' . ( (int) $list_id ) ] = 1;
225
+ }
226
+ }
227
 
 
 
 
228
 
229
+ if ( ! empty( $params['status'] ) ) {
230
+ $user['status'] = $params['status'];
231
+ } else {
232
+ $user['status'] = 'C';
233
+ }
234
 
235
+ $user['token'] = $newsletter->get_token();
236
+ $user['updated'] = time();
 
 
 
 
 
237
 
238
+ $user['ip'] = Newsletter::get_remote_ip();
239
 
240
+ $user = $newsletter->save_user( $user );
 
 
 
 
241
 
242
+ return $user;
243
+ }
 
 
244
 
245
+ /*
246
+ * Subscribers list
247
+ */
248
 
249
+ public static function subscribers( $params ) {
 
250
 
251
+ global $wpdb;
252
+ $newsletter = Newsletter::instance();
 
253
 
254
+ $items_per_page = 20;
255
+ $where = "";
256
 
257
+ $query = "select name, email from " . NEWSLETTER_USERS_TABLE . ' ' . $where . " order by id desc";
258
+ $query .= " limit 0," . $items_per_page;
259
+ $list = $wpdb->get_results( $query );
260
 
261
+ return $list;
262
+ }
263
 
264
+ /*
265
+ * Deletes a subscriber
266
+ */
267
 
268
+ public static function delete_subscriber( $params ) {
 
269
 
270
+ global $wpdb;
271
+ $newsletter = Newsletter::instance();
 
272
 
273
+ $user = $newsletter->get_user( $params['email'] );
274
 
275
+ if ( ! $user ) {
276
+ return new WP_Error( '-1', 'Email address not found', array( 'status' => 404 ) );
277
+ }
278
 
279
+ if ( $wpdb->query( $wpdb->prepare( "delete from " . NEWSLETTER_USERS_TABLE . " where id=%d", (int) $user->id ) ) ) {
280
+ return "OK";
281
+ } else {
282
+ $newsletter->logger->debug( $wpdb->last_query );
283
 
284
+ return new WP_Error( '-1', $wpdb->last_error, array( 'status' => 400 ) );
285
+ }
286
+ }
287
 
288
+ /*
289
+ * Newsletters list
290
+ */
 
 
 
 
291
 
292
+ public static function newsletters( $params ) {
 
 
293
 
294
+ global $wpdb;
295
+ $newsletter = Newsletter::instance();
296
 
297
+ $list = $wpdb->get_results( "SELECT id, subject, created, status, total, sent, send_on FROM " . NEWSLETTER_EMAILS_TABLE . " ORDER BY id DESC LIMIT 10", OBJECT );
 
298
 
299
+ if ( $wpdb->last_error ) {
300
+ $newsletter->logger->error( $wpdb->last_error );
301
 
302
+ return false;
303
+ }
 
 
304
 
305
+ if ( empty( $list ) ) {
306
+ return array();
307
+ }
308
 
309
+ return $list;
310
+ }
311
 
312
  }
includes/logger.php CHANGED
@@ -2,7 +2,7 @@
2
  defined('ABSPATH') || exit;
3
 
4
  if (!defined('NEWSLETTER_LOG_DIR')) {
5
- define('NEWSLETTER_LOG_DIR', WP_CONTENT_DIR . '/logs/newsletter/');
6
  }
7
 
8
  class NewsletterLogger {
2
  defined('ABSPATH') || exit;
3
 
4
  if (!defined('NEWSLETTER_LOG_DIR')) {
5
+ define('NEWSLETTER_LOG_DIR', WP_CONTENT_DIR . '/logs/newsletter');
6
  }
7
 
8
  class NewsletterLogger {
includes/mailers.php CHANGED
@@ -38,6 +38,7 @@ class NewsletterMailMethodWrapper extends NewsletterMailer {
38
  }
39
  return true;
40
  }
 
41
  }
42
 
43
  /**
@@ -78,6 +79,7 @@ class NewsletterOldMailerWrapper extends NewsletterMailer {
78
  }
79
  return true;
80
  }
 
81
  }
82
 
83
  /**
@@ -86,18 +88,13 @@ class NewsletterOldMailerWrapper extends NewsletterMailer {
86
  class NewsletterDefaultMailer extends NewsletterMailer {
87
 
88
  var $filter_active = false;
89
-
90
- /**
91
- * Used when the internal SMTP is active
92
- * @var PHPMailer
93
- */
94
- var $mailer = null;
95
 
96
  /**
 
97
  * @var TNP_Mailer_Message
98
  */
99
  var $current_message = null;
100
-
101
  function __construct() {
102
  parent::__construct('default', Newsletter::instance()->get_options('smtp'));
103
  }
@@ -107,30 +104,31 @@ class NewsletterDefaultMailer extends NewsletterMailer {
107
  return 'wp_mail() WordPress function (could be extended by a SMTP plugin)';
108
  }
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  function send($message) {
111
 
112
  if (!$this->filter_active) {
113
- add_action('phpmailer_init', function ($mailer) {
114
- $newsletter = Newsletter::instance();
115
- if (!empty($newsletter->options['content_transfer_encoding'])) {
116
- $mailer->Encoding = $newsletter->options['content_transfer_encoding'];
117
- } else {
118
- $mailer->Encoding = 'base64';
119
- }
120
-
121
- // If there is not a current message, wp_mail() was not called by us
122
- if (is_null($this->current_message)) {
123
- return;
124
- }
125
-
126
- /* @var $mailer PHPMailer */
127
- $mailer->Sender = $newsletter->options['return_path'];
128
-
129
- if (!empty($this->current_message->body) && !empty($this->current_message->body_text)) {
130
- $mailer->AltBody = $this->current_message->body_text;
131
- }
132
-
133
- }, 100);
134
  $this->filter_active = true;
135
  }
136
 
@@ -142,7 +140,7 @@ class NewsletterDefaultMailer extends NewsletterMailer {
142
  if (!empty($newsletter->options['reply_to'])) {
143
  $wp_mail_headers[] = 'Reply-To: ' . $newsletter->options['reply_to'];
144
  }
145
-
146
  // Manage from and from name
147
 
148
  if (!empty($message->headers)) {
@@ -161,11 +159,11 @@ class NewsletterDefaultMailer extends NewsletterMailer {
161
  $message->error = 'Empty body';
162
  return new WP_Error(self::ERROR_GENERIC, 'Message format');
163
  }
164
-
165
  $this->current_message = $message;
166
  $r = wp_mail($message->to, $message->subject, $body, $wp_mail_headers);
167
  $this->current_message = null;
168
-
169
  if (!$r) {
170
  $last_error = error_get_last();
171
  if (is_array($last_error)) {
@@ -182,6 +180,7 @@ class NewsletterDefaultMailer extends NewsletterMailer {
182
  }
183
  return true;
184
  }
 
185
  }
186
 
187
  /**
@@ -190,7 +189,7 @@ class NewsletterDefaultMailer extends NewsletterMailer {
190
  class NewsletterDefaultSMTPMailer extends NewsletterMailer {
191
 
192
  var $mailer = null;
193
-
194
  function __construct($options) {
195
  parent::__construct('internal-smtp', $options);
196
  }
@@ -208,7 +207,7 @@ class NewsletterDefaultSMTPMailer extends NewsletterMailer {
208
  $logger = $this->get_logger();
209
  $logger->debug('Start sending to ' . $message->to);
210
  $mailer = $this->get_mailer();
211
-
212
  if (!empty($message->body)) {
213
  $mailer->IsHTML(true);
214
  $mailer->Body = $message->body;
@@ -218,7 +217,7 @@ class NewsletterDefaultSMTPMailer extends NewsletterMailer {
218
  $mailer->Body = $message->body_text;
219
  $mailer->AltBody = '';
220
  }
221
-
222
  $mailer->Subject = $message->subject;
223
 
224
  $mailer->ClearCustomHeaders();
@@ -235,7 +234,7 @@ class NewsletterDefaultSMTPMailer extends NewsletterMailer {
235
  $newsletter = Newsletter::instance();
236
  $mailer->setFrom($newsletter->options['sender_email'], $newsletter->options['sender_name']);
237
  }
238
-
239
  $mailer->ClearAddresses();
240
  $mailer->AddAddress($message->to);
241
  $mailer->Send();
@@ -249,7 +248,7 @@ class NewsletterDefaultSMTPMailer extends NewsletterMailer {
249
  $message->error = $mailer->ErrorInfo;
250
  return new WP_Error(self::ERROR_GENERIC, $mailer->ErrorInfo);
251
  }
252
-
253
  $logger->debug('Sent ' . $message->to);
254
  //$logger->error('Time: ' . (microtime(true) - $start) . ' seconds');
255
  return true;
@@ -318,5 +317,5 @@ class NewsletterDefaultSMTPMailer extends NewsletterMailer {
318
 
319
  return $this->mailer;
320
  }
321
- }
322
 
 
38
  }
39
  return true;
40
  }
41
+
42
  }
43
 
44
  /**
79
  }
80
  return true;
81
  }
82
+
83
  }
84
 
85
  /**
88
  class NewsletterDefaultMailer extends NewsletterMailer {
89
 
90
  var $filter_active = false;
 
 
 
 
 
 
91
 
92
  /**
93
+ * Static to be accessed in the hook: on some installation the object $this is not working, we're still trying to understand why
94
  * @var TNP_Mailer_Message
95
  */
96
  var $current_message = null;
97
+
98
  function __construct() {
99
  parent::__construct('default', Newsletter::instance()->get_options('smtp'));
100
  }
104
  return 'wp_mail() WordPress function (could be extended by a SMTP plugin)';
105
  }
106
 
107
+ function fix_mailer($mailer) {
108
+ $newsletter = Newsletter::instance();
109
+ if (!empty($newsletter->options['content_transfer_encoding'])) {
110
+ $mailer->Encoding = $newsletter->options['content_transfer_encoding'];
111
+ } else {
112
+ $mailer->Encoding = 'base64';
113
+ }
114
+
115
+ // If there is not a current message, wp_mail() was not called by us
116
+ if (is_null($this->current_message)) {
117
+ return;
118
+ }
119
+
120
+ /* @var $mailer PHPMailer */
121
+ $mailer->Sender = $newsletter->options['return_path'];
122
+
123
+ if (!empty($this->current_message->current_message->body) && !empty($this->current_message->current_message->body_text)) {
124
+ $mailer->AltBody = $this->current_message->current_message->body_text;
125
+ }
126
+ }
127
+
128
  function send($message) {
129
 
130
  if (!$this->filter_active) {
131
+ add_action('phpmailer_init', array($this, 'fix_mailer'), 100);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  $this->filter_active = true;
133
  }
134
 
140
  if (!empty($newsletter->options['reply_to'])) {
141
  $wp_mail_headers[] = 'Reply-To: ' . $newsletter->options['reply_to'];
142
  }
143
+
144
  // Manage from and from name
145
 
146
  if (!empty($message->headers)) {
159
  $message->error = 'Empty body';
160
  return new WP_Error(self::ERROR_GENERIC, 'Message format');
161
  }
162
+
163
  $this->current_message = $message;
164
  $r = wp_mail($message->to, $message->subject, $body, $wp_mail_headers);
165
  $this->current_message = null;
166
+
167
  if (!$r) {
168
  $last_error = error_get_last();
169
  if (is_array($last_error)) {
180
  }
181
  return true;
182
  }
183
+
184
  }
185
 
186
  /**
189
  class NewsletterDefaultSMTPMailer extends NewsletterMailer {
190
 
191
  var $mailer = null;
192
+
193
  function __construct($options) {
194
  parent::__construct('internal-smtp', $options);
195
  }
207
  $logger = $this->get_logger();
208
  $logger->debug('Start sending to ' . $message->to);
209
  $mailer = $this->get_mailer();
210
+
211
  if (!empty($message->body)) {
212
  $mailer->IsHTML(true);
213
  $mailer->Body = $message->body;
217
  $mailer->Body = $message->body_text;
218
  $mailer->AltBody = '';
219
  }
220
+
221
  $mailer->Subject = $message->subject;
222
 
223
  $mailer->ClearCustomHeaders();
234
  $newsletter = Newsletter::instance();
235
  $mailer->setFrom($newsletter->options['sender_email'], $newsletter->options['sender_name']);
236
  }
237
+
238
  $mailer->ClearAddresses();
239
  $mailer->AddAddress($message->to);
240
  $mailer->Send();
248
  $message->error = $mailer->ErrorInfo;
249
  return new WP_Error(self::ERROR_GENERIC, $mailer->ErrorInfo);
250
  }
251
+
252
  $logger->debug('Sent ' . $message->to);
253
  //$logger->error('Time: ' . (microtime(true) - $start) . ' seconds');
254
  return true;
317
 
318
  return $this->mailer;
319
  }
 
320
 
321
+ }
includes/module.php CHANGED
@@ -118,16 +118,6 @@ class NewsletterAddon {
118
  }
119
  add_action('newsletter_init', array($this, 'init'));
120
 
121
- if (is_admin()) {
122
- if (!class_exists('NewsletterExtensions')) {
123
- add_filter('plugin_row_meta', function ($plugin_meta, $plugin_file) {
124
- if ($plugin_file === 'newsletter-' . $this->name . '/' . $this->name . '.php') {
125
- $plugin_meta[] = '<a href="admin.php?page=newsletter_main_extensions" style="font-weight: bold">Newsletter Addons Manager required</a>';
126
- }
127
- return $plugin_meta;
128
- }, 10, 2);
129
- }
130
- }
131
  }
132
 
133
  function upgrade($first_install = false) {
@@ -269,7 +259,6 @@ class NewsletterMailer {
269
  const ERROR_FATAL = '2';
270
 
271
  /* @var NewsletterLogger */
272
-
273
  var $logger;
274
  var $name;
275
  var $options;
@@ -571,7 +560,7 @@ class NewsletterModule {
571
  }
572
  return $r;
573
  }
574
-
575
  function get_results($query) {
576
  global $wpdb;
577
  $r = $wpdb->get_results($query);
@@ -581,7 +570,7 @@ class NewsletterModule {
581
  $logger->fatal($wpdb->last_error);
582
  }
583
  return $r;
584
- }
585
 
586
  /**
587
  *
@@ -2264,6 +2253,19 @@ class NewsletterModule {
2264
  return (int) $var;
2265
  }
2266
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2267
  static function sanitize_ip($ip) {
2268
  if (empty($ip))
2269
  return '';
118
  }
119
  add_action('newsletter_init', array($this, 'init'));
120
 
 
 
 
 
 
 
 
 
 
 
121
  }
122
 
123
  function upgrade($first_install = false) {
259
  const ERROR_FATAL = '2';
260
 
261
  /* @var NewsletterLogger */
 
262
  var $logger;
263
  var $name;
264
  var $options;
560
  }
561
  return $r;
562
  }
563
+
564
  function get_results($query) {
565
  global $wpdb;
566
  $r = $wpdb->get_results($query);
570
  $logger->fatal($wpdb->last_error);
571
  }
572
  return $r;
573
+ }
574
 
575
  /**
576
  *
2253
  return (int) $var;
2254
  }
2255
 
2256
+ static function to_array($text) {
2257
+ $text = trim($text);
2258
+ if (empty($text)) {
2259
+ return array();
2260
+ }
2261
+ $text = preg_split("/\\r\\n/", $text);
2262
+ $text = array_map('trim', $text);
2263
+ $text = array_map('strtolower', $text);
2264
+ $text = array_filter($text);
2265
+
2266
+ return $text;
2267
+ }
2268
+
2269
  static function sanitize_ip($ip) {
2270
  if (empty($ip))
2271
  return '';
main/index.php CHANGED
@@ -244,11 +244,11 @@ $labels = array_reverse( $labels );
244
  </a>
245
  </h3>
246
  <div class="inside">
247
- <div class="tnp-video-container">
248
  <iframe width="480" height="360"
249
  src="https://www.youtube.com/embed/JaxK7XwqvVI?rel=0" frameborder="0"
250
  allowfullscreen></iframe>
251
- </div>
252
  <div>
253
  <a class="orange"
254
  href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-documentation/email-sending-issues"
244
  </a>
245
  </h3>
246
  <div class="inside">
247
+ <!-- <div class="tnp-video-container">
248
  <iframe width="480" height="360"
249
  src="https://www.youtube.com/embed/JaxK7XwqvVI?rel=0" frameborder="0"
250
  allowfullscreen></iframe>
251
+ </div> -->
252
  <div>
253
  <a class="orange"
254
  href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-documentation/email-sending-issues"
main/main.php CHANGED
@@ -53,6 +53,7 @@ if (!$controls->is_action()) {
53
 
54
  //$module->hook_newsletter_extension_versions(true);
55
  delete_transient("tnp_extensions_json");
 
56
  }
57
 
58
  if ($controls->is_action('create')) {
@@ -78,48 +79,20 @@ if (!$controls->is_action()) {
78
  }
79
  }
80
 
81
- /* TODO switch to check_license function */
82
 
83
- if (!empty($controls->data['contract_key']) || defined('NEWSLETTER_LICENSE_KEY')) {
84
-
85
- if (defined('NEWSLETTER_LICENSE_KEY')) {
86
- $license_key = NEWSLETTER_LICENSE_KEY;
87
- } else {
88
- $license_key = $controls->data['contract_key'];
89
- }
90
-
91
- $response = wp_remote_get('http://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/license-check.php?k=' . urlencode($license_key), array('sslverify' => false));
92
-
93
- if (is_wp_error($response)) {
94
- /* @var $response WP_Error */
95
- $controls->errors .= 'It seems that your blog cannot contact the license validator. Ask your provider to unlock the HTTP/HTTPS connections to www.thenewsletterplugin.com<br>';
96
- $controls->errors .= esc_html($response->get_error_code()) . ' - ' . esc_html($response->get_error_message());
97
- $controls->data['licence_expires'] = '';
98
- } else {
99
- if (wp_remote_retrieve_response_code($response) != 200) {
100
- $controls->errors .= '[' . wp_remote_retrieve_response_code($response) . '] The license validator returned an error, please check your <a href="https://www.thenewsletterplugin.com/account">license code and status</a>, thank you.';
101
- $controls->errors .= '<br>You can anyway download the professional addons from https://www.thenewsletterplugin.com if your license is valid.';
102
- $controls->data['licence_expires'] = '';
103
  } else {
104
- $expires = json_decode(wp_remote_retrieve_body($response));
105
-
106
- if (!empty($expires->message)) {
107
- $controls->errors = $expires->message;
108
- } else {
109
- $controls->data['licence_expires'] = $expires->expire;
110
-
111
- if ($expires->expire == -1) {
112
- $controls->messages = 'Your FREE license is valid';
113
- } elseif ($expires->expire >= time()) {
114
- $controls->messages = 'Your license is valid and expires on ' . esc_html(date('Y-m-d', $expires->expire));
115
- } else {
116
- $controls->messages = 'Your license is expired on ' . esc_html(date('Y-m-d', $expires->expire));
117
- }
118
- }
119
  }
120
-
121
  }
122
- $module->merge_options($controls->data);
123
  }
124
 
125
  $return_path = $module->options['return_path'];
53
 
54
  //$module->hook_newsletter_extension_versions(true);
55
  delete_transient("tnp_extensions_json");
56
+ delete_transient('newsletter_license_data');
57
  }
58
 
59
  if ($controls->is_action('create')) {
79
  }
80
  }
81
 
82
+ $license_data = $module->get_license_data(true);
83
 
84
+ if (is_wp_error($license_data)) {
85
+ $controls->errors .= esc_html('[' . $license_data->get_error_code()) . '] - ' . esc_html($license_data->get_error_message());
86
+ } else {
87
+ if ($license_data !== false) {
88
+ if ($license_data->expire == 0) {
89
+ $controls->messages = 'Your FREE license is valid';
90
+ } elseif ($license_data->expire >= time()) {
91
+ $controls->messages = 'Your license is valid and expires on ' . esc_html(date('Y-m-d', $license_data->expire));
 
 
 
 
 
 
 
 
 
 
 
 
92
  } else {
93
+ $controls->errors = 'Your license is expired on ' . esc_html(date('Y-m-d', $license_data->expire));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
 
95
  }
 
96
  }
97
 
98
  $return_path = $module->options['return_path'];
main/status.php CHANGED
@@ -8,10 +8,12 @@ $controls = new NewsletterControls();
8
 
9
 
10
  $wp_cron_calls = get_option('newsletter_diagnostic_cron_calls', array());
 
 
 
 
11
  if (count($wp_cron_calls) > 20) {
12
- $total = 0;
13
- $wp_cron_calls_max = 0;
14
- $wp_cron_calls_min = 0;
15
  for ($i = 1; $i < count($wp_cron_calls); $i++) {
16
  $diff = $wp_cron_calls[$i] - $wp_cron_calls[$i - 1];
17
  $total += $diff;
@@ -221,6 +223,8 @@ $speed = Newsletter::$instance->options['scheduler_max'];
221
 
222
  <?php echo esc_html($name) ?>
223
  </td>
 
 
224
  <tr>
225
  <td>Mailing</td>
226
  <td>
@@ -254,7 +258,24 @@ $speed = Newsletter::$instance->options['scheduler_max'];
254
  </td>
255
 
256
  </tr>
257
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  <?php
259
  $return_path = $module->options['return_path'];
260
  if (!empty($return_path)) {
@@ -1017,9 +1038,9 @@ $speed = Newsletter::$instance->options['scheduler_max'];
1017
 
1018
  <?php
1019
  wp_mkdir_p(NEWSLETTER_LOG_DIR);
1020
- $res = is_dir(NEWSLETTER_LOG_DIR);
1021
  if ($res) {
1022
- file_put_contents(NEWSLETTER_LOG_DIR . '/test.txt', "");
1023
  $res = is_file(NEWSLETTER_LOG_DIR . '/test.txt');
1024
  if ($res) {
1025
  @unlink(NEWSLETTER_LOG_DIR . '/test.txt');
8
 
9
 
10
  $wp_cron_calls = get_option('newsletter_diagnostic_cron_calls', array());
11
+ $total = 0;
12
+ $wp_cron_calls_max = 0;
13
+ $wp_cron_calls_min = 0;
14
+ $wp_cron_calls_avg = 0;
15
  if (count($wp_cron_calls) > 20) {
16
+
 
 
17
  for ($i = 1; $i < count($wp_cron_calls); $i++) {
18
  $diff = $wp_cron_calls[$i] - $wp_cron_calls[$i - 1];
19
  $total += $diff;
223
 
224
  <?php echo esc_html($name) ?>
225
  </td>
226
+ </tr>
227
+
228
  <tr>
229
  <td>Mailing</td>
230
  <td>
258
  </td>
259
 
260
  </tr>
261
+
262
+ <?php if (ini_get('opcache.validate_timestamps') === '0') { ?>
263
+
264
+ <tr>
265
+ <td>
266
+ Opcache
267
+ </td>
268
+
269
+ <td>
270
+ <span class="tnp-ko">KO</span>
271
+ </td>
272
+
273
+ <td>
274
+ You have the PHP opcache active with file validation disable so every blog plugins update needs a webserver restart!
275
+ </td>
276
+ </tr>
277
+ <?php } ?>
278
+
279
  <?php
280
  $return_path = $module->options['return_path'];
281
  if (!empty($return_path)) {
1038
 
1039
  <?php
1040
  wp_mkdir_p(NEWSLETTER_LOG_DIR);
1041
+ $res = is_dir(NEWSLETTER_LOG_DIR) && is_writable(NEWSLETTER_LOG_DIR);
1042
  if ($res) {
1043
+ @file_put_contents(NEWSLETTER_LOG_DIR . '/test.txt', "");
1044
  $res = is_file(NEWSLETTER_LOG_DIR . '/test.txt');
1045
  if ($res) {
1046
  @unlink(NEWSLETTER_LOG_DIR . '/test.txt');
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.3.8
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.
@@ -28,7 +28,7 @@
28
 
29
  */
30
 
31
- define('NEWSLETTER_VERSION', '6.3.8');
32
 
33
  global $newsletter, $wpdb;
34
 
@@ -186,11 +186,28 @@ class Newsletter extends NewsletterModule {
186
 
187
  add_shortcode('newsletter_replace', array($this, 'shortcode_newsletter_replace'));
188
 
189
- if (!method_exists('NewsletterExtensions', 'hook_site_transient_update_plugins')) {
190
- add_filter('site_transient_update_plugins', array($this, 'hook_site_transient_update_plugins'));
191
- }
192
 
193
  if (is_admin()) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  add_action('in_admin_header', array($this, 'hook_in_admin_header'), 1000);
195
 
196
  if ($this->is_admin_page()) {
@@ -642,7 +659,6 @@ class Newsletter extends NewsletterModule {
642
  $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set status='sent', total=sent where id=" . $email->id . " limit 1");
643
  return true;
644
  }
645
-
646
  } else {
647
  $this->logger->info(__METHOD__ . '> Subscribers supplied');
648
  }
@@ -670,7 +686,7 @@ class Newsletter extends NewsletterModule {
670
  $user = apply_filters('newsletter_send_user', $user);
671
  $message = $this->build_message($email, $user);
672
  $this->save_sent_message($message);
673
-
674
  if (!$test) {
675
  $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set sent=sent+1, last_id=" . $user->id . " where id=" . $email->id . " limit 1");
676
  }
@@ -709,7 +725,7 @@ class Newsletter extends NewsletterModule {
709
  $message = $this->build_message($email, $user);
710
  $this->save_sent_message($message);
711
  $messages[] = $message;
712
-
713
  if (!$test) {
714
  $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set sent=sent+1, last_id=" . $user->id . " where id=" . $email->id . " limit 1");
715
  }
@@ -724,7 +740,7 @@ class Newsletter extends NewsletterModule {
724
  $this->save_sent_message($message);
725
  }
726
  }
727
-
728
  if (is_wp_error($r)) {
729
  $this->logger->error($r);
730
  return $r;
@@ -747,7 +763,7 @@ class Newsletter extends NewsletterModule {
747
  if ($supplied_users && $this->limits_exceeded()) {
748
  $result = false;
749
  }
750
-
751
  $this->logger->info(__METHOD__ . '> End run for email ' . $email->id);
752
 
753
  return $result;
@@ -1064,11 +1080,11 @@ class Newsletter extends NewsletterModule {
1064
  $plugin->plugin = $extension->plugin;
1065
  $plugin->new_version = $extension->version;
1066
  $plugin->url = $extension->url;
1067
- if (class_exists('NewsletterExtensions') && $extension->downloadable) {
1068
  // NO filters here!
1069
  $plugin->package = NewsletterExtensions::$instance->get_package($extension->id, $license_key);
1070
  } else {
1071
-
1072
  }
1073
  // [banners] => Array
1074
  // (
@@ -1132,9 +1148,6 @@ class Newsletter extends NewsletterModule {
1132
 
1133
  if (empty($extensions_json)) {
1134
  $url = "http://www.thenewsletterplugin.com/wp-content/extensions.json?ver=" . NEWSLETTER_VERSION;
1135
- if (!empty($this->options['contract_key'])) {
1136
- $url = "http://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/extensions.php?k=" . $this->options['contract_key'] . '&ver=' . NEWSLETTER_VERSION;
1137
- }
1138
  $extensions_response = wp_remote_get($url);
1139
  $extensions_json = wp_remote_retrieve_body($extensions_response);
1140
  if (!empty($extensions_json)) {
@@ -1216,6 +1229,74 @@ class Newsletter extends NewsletterModule {
1216
  return false;
1217
  }
1218
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1219
  public static function check_license($license_key) {
1220
  $response = wp_remote_get('http://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/check.php?k=' . urlencode($license_key), array('sslverify' => false));
1221
  if (is_wp_error($response)) {
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.4.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.
28
 
29
  */
30
 
31
+ define('NEWSLETTER_VERSION', '6.4.0');
32
 
33
  global $newsletter, $wpdb;
34
 
186
 
187
  add_shortcode('newsletter_replace', array($this, 'shortcode_newsletter_replace'));
188
 
189
+ add_filter('site_transient_update_plugins', array($this, 'hook_site_transient_update_plugins'));
 
 
190
 
191
  if (is_admin()) {
192
+ if (!class_exists('NewsletterExtensions')) {
193
+
194
+ add_filter('plugin_row_meta', function ($plugin_meta, $plugin_file) {
195
+
196
+ static $slugs = array();
197
+ if (empty($slugs)) {
198
+ $addons = $this->getTnpExtensions();
199
+ foreach ($addons as $addon) {
200
+ $slugs[] = $addon->wp_slug;
201
+ }
202
+ }
203
+ if (array_search($plugin_file, $slugs) !== false) {
204
+
205
+ $plugin_meta[] = '<a href="admin.php?page=newsletter_main_extensions" style="font-weight: bold">Newsletter Addons Manager required</a>';
206
+ }
207
+ return $plugin_meta;
208
+ }, 10, 2);
209
+ }
210
+
211
  add_action('in_admin_header', array($this, 'hook_in_admin_header'), 1000);
212
 
213
  if ($this->is_admin_page()) {
659
  $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set status='sent', total=sent where id=" . $email->id . " limit 1");
660
  return true;
661
  }
 
662
  } else {
663
  $this->logger->info(__METHOD__ . '> Subscribers supplied');
664
  }
686
  $user = apply_filters('newsletter_send_user', $user);
687
  $message = $this->build_message($email, $user);
688
  $this->save_sent_message($message);
689
+
690
  if (!$test) {
691
  $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set sent=sent+1, last_id=" . $user->id . " where id=" . $email->id . " limit 1");
692
  }
725
  $message = $this->build_message($email, $user);
726
  $this->save_sent_message($message);
727
  $messages[] = $message;
728
+
729
  if (!$test) {
730
  $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set sent=sent+1, last_id=" . $user->id . " where id=" . $email->id . " limit 1");
731
  }
740
  $this->save_sent_message($message);
741
  }
742
  }
743
+
744
  if (is_wp_error($r)) {
745
  $this->logger->error($r);
746
  return $r;
763
  if ($supplied_users && $this->limits_exceeded()) {
764
  $result = false;
765
  }
766
+
767
  $this->logger->info(__METHOD__ . '> End run for email ' . $email->id);
768
 
769
  return $result;
1080
  $plugin->plugin = $extension->plugin;
1081
  $plugin->new_version = $extension->version;
1082
  $plugin->url = $extension->url;
1083
+ if (class_exists('NewsletterExtensions')) {
1084
  // NO filters here!
1085
  $plugin->package = NewsletterExtensions::$instance->get_package($extension->id, $license_key);
1086
  } else {
1087
+ $plugin->package = '';
1088
  }
1089
  // [banners] => Array
1090
  // (
1148
 
1149
  if (empty($extensions_json)) {
1150
  $url = "http://www.thenewsletterplugin.com/wp-content/extensions.json?ver=" . NEWSLETTER_VERSION;
 
 
 
1151
  $extensions_response = wp_remote_get($url);
1152
  $extensions_json = wp_remote_retrieve_body($extensions_response);
1153
  if (!empty($extensions_json)) {
1229
  return false;
1230
  }
1231
 
1232
+ function get_license_data($refresh = false) {
1233
+
1234
+ if (!$refresh) {
1235
+ $license_data = get_transient('newsletter_license_data');
1236
+ if (!empty($license_data) && is_object($license_data)) {
1237
+ return $license_data;
1238
+ }
1239
+ }
1240
+
1241
+ $this->logger->debug('Refreshing the license data');
1242
+
1243
+ delete_transient('newsletter_license_data');
1244
+
1245
+ $license_key = $this->get_license_key();
1246
+ if (empty($license_key)) {
1247
+ $this->logger->debug('License was empty');
1248
+ return false;
1249
+ }
1250
+ $license_data_url = 'https://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/get-license-data.php';
1251
+
1252
+ $response = wp_remote_post($license_data_url, array(
1253
+ 'body' => array('k' => $license_key)
1254
+ ));
1255
+
1256
+ // Fall back to http...
1257
+ if (is_wp_error($response)) {
1258
+ $this->logger->error('Falling back to http');
1259
+ $this->logger->error($response);
1260
+ $response = wp_remote_post($license_data_url, array(
1261
+ 'body' => array('k' => $license_key)
1262
+ ));
1263
+ if (is_wp_error($response)) {
1264
+ $this->logger->error($response);
1265
+ return $response;
1266
+ }
1267
+ }
1268
+
1269
+ $download_message = 'You can download all addons from www.thenewsletterplugin.com if your license is valid.';
1270
+
1271
+ if (wp_remote_retrieve_response_code($response) != '200') {
1272
+ $this->logger->error('license data error: ' . wp_remote_retrieve_response_code($response));
1273
+ return new WP_Error(wp_remote_retrieve_response_code($response), 'License validation service error. <br>' . $download_message);
1274
+ }
1275
+
1276
+ $json = wp_remote_retrieve_body($response);
1277
+ $data = json_decode($json);
1278
+
1279
+ if (!is_object($data)) {
1280
+ $this->logger->error($json);
1281
+ return new WP_Error(1, 'License validation service error. <br>' . $download_message);
1282
+ }
1283
+
1284
+ if (isset($data->message)) {
1285
+ return new WP_Error(1, $data->message . ' (check the license on Newsletter main settings)');
1286
+ }
1287
+
1288
+ $timeout = 24 * 7 * 3600;
1289
+ if ($data->expire < time() + $timeout) $timeout = $data->expire;
1290
+ set_transient('newsletter_license_data', $data, $timeout);
1291
+
1292
+ return $data;
1293
+ }
1294
+
1295
+ /**
1296
+ * @deprecated
1297
+ * @param type $license_key
1298
+ * @return \WP_Error
1299
+ */
1300
  public static function check_license($license_key) {
1301
  $response = wp_remote_get('http://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/check.php?k=' . urlencode($license_key), array('sslverify' => false));
1302
  if (is_wp_error($response)) {
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.2.4
5
- Stable tag: 6.3.8
6
  Requires PHP: 5.6
7
  Contributors: satollo,webagile,michael-travan
8
 
@@ -109,6 +109,16 @@ Thank you, The Newsletter Team
109
 
110
  == Changelog ==
111
 
 
 
 
 
 
 
 
 
 
 
112
  = 6.3.8 =
113
 
114
  * Fixed email encoding when sent with wp_mail() and an encoding is selected on main settings
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.2.4
5
+ Stable tag: 6.4.0
6
  Requires PHP: 5.6
7
  Contributors: satollo,webagile,michael-travan
8
 
109
 
110
  == Changelog ==
111
 
112
+ = 6.4.0 =
113
+
114
+ * Fixed extra profile fields management in REST and PHP API
115
+ * Removed the "read more" added by themes on posts excerpt
116
+ * Core improvements
117
+
118
+ = 6.3.9 =
119
+
120
+ * Improved antibot and/or spam subscription checks (please review your security configuration)
121
+
122
  = 6.3.8 =
123
 
124
  * Fixed email encoding when sent with wp_mail() and an encoding is selected on main settings
subscription/antibot.php CHANGED
@@ -1,46 +1,22 @@
1
  <?php
 
2
  defined('ABSPATH') || exit;
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
6
- $module = NewsletterSubscription::instance();
7
-
8
- // TODO: Remove and use the $module->options.
9
- $options = get_option('newsletter', array());
10
 
11
  if ($controls->is_action()) {
12
 
13
  if ($controls->is_action('save')) {
14
 
15
- $blacklist = trim($controls->data['ip_blacklist']);
16
- if (empty($blacklist))
17
- $blacklist = array();
18
- else {
19
- $blacklist = preg_split("/\\r\\n/", $blacklist);
20
- $blacklist = array_map('trim', $blacklist);
21
- $blacklist = array_map('strtolower', $blacklist);
22
- $blacklist = array_filter($blacklist);
23
-
24
- $controls->data['ip_blacklist'] = $blacklist;
25
- }
26
-
27
- $blacklist = trim($controls->data['address_blacklist']);
28
- if (empty($blacklist))
29
- $blacklist = array();
30
- else {
31
- $blacklist = preg_split("/\\r\\n/", $blacklist);
32
- $blacklist = array_map('trim', $blacklist);
33
- $blacklist = array_map('strtolower', $blacklist);
34
- $blacklist = array_filter($blacklist);
35
-
36
- $controls->data['address_blacklist'] = $blacklist;
37
- }
38
-
39
- $module->merge_options($controls->data);
40
  $controls->add_message_saved();
41
  }
42
  } else {
43
- $controls->data = get_option('newsletter', array());
44
  }
45
  ?>
46
 
@@ -78,7 +54,7 @@ if ($controls->is_action()) {
78
  <tr>
79
  <th><?php _e('Disable antibot/antispam?', 'newsletter') ?></th>
80
  <td>
81
- <?php $controls->yesno('antibot_disable'); ?>
82
  <p class="description">
83
  <?php _e('Disable for ajax form submission', 'newsletter'); ?>
84
  </p>
@@ -123,7 +99,7 @@ if ($controls->is_action()) {
123
  <tr>
124
  <th><?php _e('Captcha', 'newsletter') ?> </th>
125
  <td>
126
- <?php $controls->enabled('captcha'); ?> <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/antiflood#captcha')?>
127
  </td>
128
  </tr>
129
  <?php /*
@@ -150,10 +126,8 @@ if ($controls->is_action()) {
150
  <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/antiflood#ip') ?>
151
  </th>
152
  <td>
153
- <?php
154
- $controls->textarea('ip_blacklist');
155
- ?>
156
- <p class="description"><?php _e('One per line', 'newsletter')?></p>
157
  </td>
158
  </tr>
159
  <tr>
@@ -162,10 +136,8 @@ if ($controls->is_action()) {
162
  <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/antiflood#domains') ?>
163
  </th>
164
  <td>
165
- <?php
166
- $controls->textarea('address_blacklist');
167
- ?>
168
- <p class="description"><?php _e('One per line', 'newsletter')?></p>
169
  </td>
170
  </tr>
171
  </table>
1
  <?php
2
+ /* @var $this NewsletterSubscription */
3
  defined('ABSPATH') || exit;
4
 
5
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
 
 
 
 
7
 
8
  if ($controls->is_action()) {
9
 
10
  if ($controls->is_action('save')) {
11
 
12
+ $controls->data['ip_blacklist'] = $this->to_array($controls->data['ip_blacklist']);
13
+ $controls->data['address_blacklist'] = $this->to_array($controls->data['address_blacklist']);
14
+
15
+ $this->save_options($controls->data, 'antibot');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  $controls->add_message_saved();
17
  }
18
  } else {
19
+ $controls->data = $this->get_options('antibot');
20
  }
21
  ?>
22
 
54
  <tr>
55
  <th><?php _e('Disable antibot/antispam?', 'newsletter') ?></th>
56
  <td>
57
+ <?php $controls->yesno('disabled'); ?>
58
  <p class="description">
59
  <?php _e('Disable for ajax form submission', 'newsletter'); ?>
60
  </p>
99
  <tr>
100
  <th><?php _e('Captcha', 'newsletter') ?> </th>
101
  <td>
102
+ <?php $controls->enabled('captcha'); ?> <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/antiflood#captcha') ?>
103
  </td>
104
  </tr>
105
  <?php /*
126
  <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/antiflood#ip') ?>
127
  </th>
128
  <td>
129
+ <?php $controls->textarea('ip_blacklist'); ?>
130
+ <p class="description"><?php _e('One per line', 'newsletter') ?></p>
 
 
131
  </td>
132
  </tr>
133
  <tr>
136
  <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/antiflood#domains') ?>
137
  </th>
138
  <td>
139
+ <?php $controls->textarea('address_blacklist'); ?>
140
+ <p class="description"><?php _e('One per line', 'newsletter') ?></p>
 
 
141
  </td>
142
  </tr>
143
  </table>
subscription/defaults-antibot.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // This file is used only on first installation!
4
+
5
+ $options = array();
6
+ $options['ip_blacklist'] = array();
7
+ $options['address_blacklist'] = array();
8
+ $options['antiflood'] = 60;
9
+ $options['akismet'] = 0;
10
+ $options['captcha'] = 0;
11
+ $options['disabled'] = 0;
subscription/defaults.php CHANGED
@@ -13,12 +13,14 @@
13
  $options = array();
14
 
15
  $options['noconfirmation'] = 1;
16
- $options['antiflood'] = 10;
17
- $options['ip_blacklist'] = array();
18
- $options['address_blacklist'] = array();
19
- $options['domain_check'] = 0;
20
- $options['akismet'] = 0;
21
- $options['captcha'] = 0;
 
 
22
  $options['notify_email'] = get_option('admin_email');
23
  $options['multiple'] = 1;
24
  $options['notify'] = 0;
13
  $options = array();
14
 
15
  $options['noconfirmation'] = 1;
16
+
17
+ //$options['antiflood'] = 10;
18
+ //$options['ip_blacklist'] = array();
19
+ //$options['address_blacklist'] = array();
20
+ //$options['domain_check'] = 0;
21
+ //$options['akismet'] = 1;
22
+ //$options['captcha'] = 1;
23
+
24
  $options['notify_email'] = get_option('admin_email');
25
  $options['multiple'] = 1;
26
  $options['notify'] = 0;
subscription/subscription.php CHANGED
@@ -35,7 +35,7 @@ class NewsletterSubscription extends NewsletterModule {
35
 
36
  function __construct() {
37
 
38
- parent::__construct('subscription', '2.1.7', null, array('lists', 'template', 'profile'));
39
  $this->options_profile = $this->get_options('profile');
40
  $this->options_lists = $this->get_options('lists');
41
 
@@ -109,13 +109,15 @@ class NewsletterSubscription extends NewsletterModule {
109
  }
110
 
111
  function is_address_blacklisted($email) {
112
- if (empty($this->options['address_blacklist'])) {
 
 
113
  return false;
114
  }
115
 
116
  $this->logger->debug('Address blacklist check');
117
  $rev_email = strrev($email);
118
- foreach ($this->options['address_blacklist'] as $item) {
119
  if (strpos($rev_email, strrev($item)) === 0) {
120
  return true;
121
  }
@@ -124,11 +126,13 @@ class NewsletterSubscription extends NewsletterModule {
124
  }
125
 
126
  function is_ip_blacklisted($ip) {
127
- if (empty($this->options['ip_blacklist'])) {
 
 
128
  return false;
129
  }
130
  $this->logger->debug('IP blacklist check');
131
- foreach ($this->options['ip_blacklist'] as $item) {
132
  if ($this->ip_match($ip, $item)) {
133
  return true;
134
  }
@@ -156,8 +160,10 @@ class NewsletterSubscription extends NewsletterModule {
156
 
157
  function is_flood($email, $ip) {
158
  global $wpdb;
159
-
160
- if (empty($this->options['antiflood'])) {
 
 
161
  return false;
162
  }
163
 
@@ -165,7 +171,7 @@ class NewsletterSubscription extends NewsletterModule {
165
 
166
  $updated = $wpdb->get_var($wpdb->prepare("select updated from " . NEWSLETTER_USERS_TABLE . " where ip=%s or email=%s order by updated desc limit 1", $ip, $email));
167
 
168
- if ($updated && time() - $updated < $this->options['antiflood']) {
169
  return true;
170
  }
171
 
@@ -183,7 +189,10 @@ class NewsletterSubscription extends NewsletterModule {
183
  }
184
 
185
  function is_spam_by_akismet($email, $name, $ip, $agent, $referrer) {
186
- if (empty($this->options['akismet'])) {
 
 
 
187
  return false;
188
  }
189
  if (!class_exists('Akismet')) {
@@ -283,10 +292,12 @@ class NewsletterSubscription extends NewsletterModule {
283
  $antibot_logger->fatal($email . ' - ' . $ip . ' - HTTP method invalid');
284
  die('Invalid');
285
  }
 
 
286
 
287
- $captcha = !empty($this->options['captcha']);
288
 
289
- if (!empty($this->options['antibot_disable']) || $this->antibot_form_check($captcha)) {
290
 
291
 
292
  if ($this->is_spam_text($full_name)) {
@@ -397,6 +408,25 @@ class NewsletterSubscription extends NewsletterModule {
397
  function upgrade() {
398
  global $wpdb, $charset_collate;
399
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
  parent::upgrade();
401
 
402
  $newsletter = Newsletter::instance();
@@ -458,6 +488,8 @@ class NewsletterSubscription extends NewsletterModule {
458
 
459
  $this->init_options('template', false);
460
 
 
 
461
  global $wpdb, $charset_collate;
462
 
463
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
35
 
36
  function __construct() {
37
 
38
+ parent::__construct('subscription', '2.2.7', null, array('lists', 'template', 'profile', 'antibot'));
39
  $this->options_profile = $this->get_options('profile');
40
  $this->options_lists = $this->get_options('lists');
41
 
109
  }
110
 
111
  function is_address_blacklisted($email) {
112
+ // TODO: Optimize!
113
+ $options = $this->get_options('antibot');
114
+ if (empty($options['address_blacklist'])) {
115
  return false;
116
  }
117
 
118
  $this->logger->debug('Address blacklist check');
119
  $rev_email = strrev($email);
120
+ foreach ($options['address_blacklist'] as $item) {
121
  if (strpos($rev_email, strrev($item)) === 0) {
122
  return true;
123
  }
126
  }
127
 
128
  function is_ip_blacklisted($ip) {
129
+ // TODO: Optimize!
130
+ $options = $this->get_options('antibot');
131
+ if (empty($options['ip_blacklist'])) {
132
  return false;
133
  }
134
  $this->logger->debug('IP blacklist check');
135
+ foreach ($options['ip_blacklist'] as $item) {
136
  if ($this->ip_match($ip, $item)) {
137
  return true;
138
  }
160
 
161
  function is_flood($email, $ip) {
162
  global $wpdb;
163
+ // TODO: Optimize!
164
+ $options = $this->get_options('antibot');
165
+
166
+ if (empty($options['antiflood'])) {
167
  return false;
168
  }
169
 
171
 
172
  $updated = $wpdb->get_var($wpdb->prepare("select updated from " . NEWSLETTER_USERS_TABLE . " where ip=%s or email=%s order by updated desc limit 1", $ip, $email));
173
 
174
+ if ($updated && time() - $updated < $options['antiflood']) {
175
  return true;
176
  }
177
 
189
  }
190
 
191
  function is_spam_by_akismet($email, $name, $ip, $agent, $referrer) {
192
+ // TODO: Optimize!
193
+ $options = $this->get_options('antibot');
194
+
195
+ if (empty($options['akismet'])) {
196
  return false;
197
  }
198
  if (!class_exists('Akismet')) {
292
  $antibot_logger->fatal($email . ' - ' . $ip . ' - HTTP method invalid');
293
  die('Invalid');
294
  }
295
+
296
+ $options_antibot = $this->get_options('antibot');
297
 
298
+ $captcha = !empty($options_antibot['captcha']);
299
 
300
+ if (!empty($options_antibot['disabled']) || $this->antibot_form_check($captcha)) {
301
 
302
 
303
  if ($this->is_spam_text($full_name)) {
408
  function upgrade() {
409
  global $wpdb, $charset_collate;
410
 
411
+ // Possible migration
412
+ $options_antibot = $this->get_options('antibot');
413
+
414
+ if (empty($options_antibot)) {
415
+ $options = $this->get_options();
416
+ foreach (array('address_blacklist', 'ip_blacklist', 'akismet', 'captcha', 'antiflood') as $key) {
417
+ if (isset($options[$key])) {
418
+ $options_antibot[$key] = $options[$key];
419
+ }
420
+ }
421
+ if (isset($options['antibot_disable'])) {
422
+ $options_antibot['disabled'] = $options['antibot_disable'];
423
+ } else {
424
+ $options_antibot['disabled'] = 0;
425
+ }
426
+
427
+ $this->save_options($options_antibot, 'antibot');
428
+ }
429
+
430
  parent::upgrade();
431
 
432
  $newsletter = Newsletter::instance();
488
 
489
  $this->init_options('template', false);
490
 
491
+
492
+
493
  global $wpdb, $charset_collate;
494
 
495
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
tnp-header.php CHANGED
@@ -138,37 +138,38 @@ $warning |= empty($status_options['mail']);
138
  </a>
139
  </li>
140
  <?php } ?>
 
 
141
 
142
- <?php if (empty(Newsletter::instance()->options['contract_key']) && !defined('NEWSLETTER_LICENSE_KEY')) { ?>
143
 
144
  <li class="tnp-professional-extensions-button"><a href="https://www.thenewsletterplugin.com/premium?utm_source=plugin&utm_medium=link&utm_campaign=header" target="_blank">
145
  <i class="fa fa-trophy"></i> <?php _e('Get Professional Addons', 'newsletter') ?></a>
146
  </li>
 
 
 
 
147
 
148
- <?php } elseif (Newsletter::instance()->options['licence_expires'] == -1) { ?>
149
 
150
  <li class="tnp-professional-extensions-button"><a href="https://www.thenewsletterplugin.com/premium?utm_source=plugin&utm_medium=link&utm_campaign=header" target="_blank">
151
  <i class="fa fa-trophy"></i> <?php _e('Get Professional Addons', 'newsletter') ?></a>
152
  </li>
153
 
154
- <?php } elseif (empty(Newsletter::instance()->options['licence_expires'])) { ?>
155
 
156
  <li class="tnp-professional-extensions-button-red">
157
- <a href="?page=newsletter_main_main"><i class="fa fa-hand-paper" style="color: white"></i> <?php _e('Licence not valid', 'newsletter') ?></a>
158
  </li>
159
 
160
- <?php } elseif (Newsletter::instance()->options['licence_expires'] >= time()) { ?>
161
 
162
  <?php $p = class_exists('NewsletterExtensions')?'newsletter_extensions_index':'newsletter_main_extensions'; ?>
163
  <li class="tnp-professional-extensions-button">
164
- <a href="?page=<?php echo $p?>"><i class="fa fa-check-square"></i> <?php _e('Licence active', 'newsletter') ?></a>
165
- </li>
166
-
167
- <?php } elseif (Newsletter::instance()->options['licence_expires'] < time()) { ?>
168
-
169
- <li class="tnp-professional-extensions-button-red">
170
- <a href="?page=newsletter_main_main"><i class="fa fa-hand-paper" style="color: white"></i> <?php _e('Licence expired', 'newsletter') ?></a>
171
  </li>
 
172
 
173
  <?php } ?>
174
  </ul>
138
  </a>
139
  </li>
140
  <?php } ?>
141
+
142
+ <?php $license_data = Newsletter::instance()->get_license_data() ?>
143
 
144
+ <?php if (empty($license_data)) { ?>
145
 
146
  <li class="tnp-professional-extensions-button"><a href="https://www.thenewsletterplugin.com/premium?utm_source=plugin&utm_medium=link&utm_campaign=header" target="_blank">
147
  <i class="fa fa-trophy"></i> <?php _e('Get Professional Addons', 'newsletter') ?></a>
148
  </li>
149
+ <?php } elseif (is_wp_error($license_data)) { ?>
150
+ <li class="tnp-professional-extensions-button-red">
151
+ <a href="?page=newsletter_main_main"><i class="fa fa-hand-paper" style="color: white"></i> <?php _e('License not valid', 'newsletter') ?></a>
152
+ </li>
153
 
154
+ <?php } elseif ($license_data->expire == 0) { ?>
155
 
156
  <li class="tnp-professional-extensions-button"><a href="https://www.thenewsletterplugin.com/premium?utm_source=plugin&utm_medium=link&utm_campaign=header" target="_blank">
157
  <i class="fa fa-trophy"></i> <?php _e('Get Professional Addons', 'newsletter') ?></a>
158
  </li>
159
 
160
+ <?php } elseif ($license_data->expire < time()) { ?>
161
 
162
  <li class="tnp-professional-extensions-button-red">
163
+ <a href="?page=newsletter_main_main"><i class="fa fa-hand-paper" style="color: white"></i> <?php _e('License expired', 'newsletter') ?></a>
164
  </li>
165
 
166
+ <?php } elseif ($license_data->expire >= time()) { ?>
167
 
168
  <?php $p = class_exists('NewsletterExtensions')?'newsletter_extensions_index':'newsletter_main_extensions'; ?>
169
  <li class="tnp-professional-extensions-button">
170
+ <a href="?page=<?php echo $p?>"><i class="fa fa-check-square"></i> <?php _e('License active', 'newsletter') ?></a>
 
 
 
 
 
 
171
  </li>
172
+
173
 
174
  <?php } ?>
175
  </ul>