Newsletter - Version 6.9.4

Version Description

  • Fixed the profile save
  • Improved the email change management from the subscriber data page
  • Removed custom javascript and opted for HTML5 validation (you can use a polyfill plugin like parsely)
  • Removed custom error messages (see above)
  • Check on delivery speed to be minimum 10 emails per hour
Download this release

Release Info

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

Code changes from version 6.9.3 to 6.9.4

emails/blocks/giphy/block.php CHANGED
@@ -19,7 +19,8 @@ $default_options = array(
19
  'block_padding_top'=>15,
20
  'block_padding_bottom'=>15,
21
  'block_padding_left'=>0,
22
- 'block_padding_right'=>0
 
23
  );
24
 
25
  $options = array_merge($default_options, $options);
19
  'block_padding_top'=>15,
20
  'block_padding_bottom'=>15,
21
  'block_padding_left'=>0,
22
+ 'block_padding_right'=>0,
23
+ 'giphy_url' => ''
24
  );
25
 
26
  $options = array_merge($default_options, $options);
emails/blocks/hero/block-left.php CHANGED
@@ -38,7 +38,9 @@
38
  <tr>
39
  <td align="center" valign="top">
40
  <a href="<?php echo $url ?>" target="_blank" rel="noopener nofollow" inline-class="image-a">
 
41
  <img src="<?php echo $media->url ?>" border="0" alt="<?php echo esc_attr($media->alt) ?>" width="<?php echo $media->width ?>" height="<?php echo $media->height ?>" inline-class="image">
 
42
  </a>
43
  </td>
44
  </tr>
38
  <tr>
39
  <td align="center" valign="top">
40
  <a href="<?php echo $url ?>" target="_blank" rel="noopener nofollow" inline-class="image-a">
41
+ <?php if ($media) { ?>
42
  <img src="<?php echo $media->url ?>" border="0" alt="<?php echo esc_attr($media->alt) ?>" width="<?php echo $media->width ?>" height="<?php echo $media->height ?>" inline-class="image">
43
+ <?php } ?>
44
  </a>
45
  </td>
46
  </tr>
emails/blocks/hero/block-right.php CHANGED
@@ -40,7 +40,9 @@
40
  <tr>
41
  <td align="center" valign="top" dir="ltr">
42
  <a href="<?php echo $url ?>" target="_blank" rel="noopener nofollow" inline-class="image-a">
 
43
  <img src="<?php echo $media->url ?>" border="0" alt="<?php echo esc_attr($media->alt) ?>" width="<?php echo $media->width ?>" height="<?php echo $media->height ?>" inline-class="image">
 
44
  </a>
45
  </td>
46
  </tr>
40
  <tr>
41
  <td align="center" valign="top" dir="ltr">
42
  <a href="<?php echo $url ?>" target="_blank" rel="noopener nofollow" inline-class="image-a">
43
+ <?php if ($media) { ?>
44
  <img src="<?php echo $media->url ?>" border="0" alt="<?php echo esc_attr($media->alt) ?>" width="<?php echo $media->width ?>" height="<?php echo $media->height ?>" inline-class="image">
45
+ <?php } ?>
46
  </a>
47
  </td>
48
  </tr>
emails/blocks/html/block.php CHANGED
@@ -17,7 +17,8 @@ $default_options = array(
17
  'block_padding_bottom' => 20,
18
  'block_background' => '#ffffff',
19
  'font_family' => 'Helvetica, Arial, sans-serif',
20
- 'font_size' => 16
 
21
  );
22
 
23
  $options = array_merge($default_options, $options);
17
  'block_padding_bottom' => 20,
18
  'block_background' => '#ffffff',
19
  'font_family' => 'Helvetica, Arial, sans-serif',
20
+ 'font_size' => 16,
21
+ 'font_color' => '#000'
22
  );
23
 
24
  $options = array_merge($default_options, $options);
images/extensions/tnp-feed-by-mail-extension-icon-150x150.png DELETED
Binary file
images/extensions/tnp-reports-extension-icon-150x150.png DELETED
Binary file
images/extensions/tnp-woocommerce-extension-150x150px.png DELETED
Binary file
includes/TNP.php CHANGED
@@ -21,148 +21,62 @@ class TNP {
21
  */
22
 
23
  public static function subscribe($params) {
 
 
 
 
24
 
25
  $logger = new NewsletterLogger('phpapi');
26
  $logger->debug($params);
27
 
 
 
28
  $newsletter = Newsletter::instance();
29
- $subscription = NewsletterSubscription::instance();
30
-
31
- // default params
32
- $defaults = array('send_emails' => true);
33
- $params = array_merge($defaults, $params);
34
-
35
- // Messages
36
- $options = get_option('newsletter', array());
37
 
38
  // Form field configuration
39
  $options_profile = get_option('newsletter_profile', array());
 
 
40
 
41
- $optin = (int) $options['noconfirmation']; // 0 - double, 1 - single
42
-
43
- $email = $newsletter->normalize_email(stripslashes($params['email']));
44
-
45
- // Should never reach this point without a valid email address
46
- if ($email == null) {
47
- return new WP_Error('-1', 'Email address not valid', array('status' => 400));
48
- }
49
-
50
- $user = $newsletter->get_user($email);
51
-
52
- if ($user != null) {
53
-
54
- $newsletter->logger->info('Subscription of an address with status ' . $user->status);
55
-
56
- // Bounced
57
- if ($user->status == 'B') {
58
- return new WP_Error('-1', 'Bounced address', array('status' => 400));
59
- }
60
-
61
- // If asked to put in confirmed status, do not check further
62
- if ($params['status'] != 'C' && $optin == 0) {
63
-
64
- // Already confirmed
65
- //if ($optin == 0 && $user->status == 'C') {
66
- if ($user->status == 'C') {
67
-
68
- set_transient($user->id . '-' . $user->token, $params, 3600 * 48);
69
- $subscription->set_updated($user);
70
-
71
- // A second subscription always require confirmation otherwise anywan can change other users' data
72
- $user->status = 'S';
73
- $subscription->send_activation_email($user);
74
-
75
- return $user;
76
- }
77
- }
78
- }
79
-
80
- if ($user != null) {
81
- $newsletter->logger->info("Email address subscribed but not confirmed");
82
- $user = array('id' => $user->id);
83
- } else {
84
- $newsletter->logger->info("New email address");
85
  }
86
 
87
- if ($optin) {
88
- $params['status'] = 'C';
89
- } else {
90
- $params['status'] = 'S';
91
  }
92
-
93
  // Lists
94
-
95
- if (!isset($params['lists']) || !is_array($params['lists'])) {
96
- $params['lists'] = array();
97
- }
98
-
99
- // Public lists: rebuild the array keeping only the valid lists
100
- $lists = $newsletter->get_lists_public();
101
-
102
- // Public list IDs
103
- $public_lists = array();
104
- foreach ($lists as $list) {
105
- $public_lists[] = $list->id;
106
- }
107
-
108
- // Keep only the public lists
109
- $params['lists'] = array_intersect($public_lists, $params['lists']);
110
-
111
- // Pre assigned lists
112
- $lists = $newsletter->get_lists();
113
- foreach ($lists as $list) {
114
- if ($list->forced) {
115
- $params['lists'][] = $list->id;
116
  }
117
- }
118
-
119
- // Keep only the public profile fields
120
- for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i ++) {
121
- // If the profile cannot be set by subscriber, skip it.
122
- if ($subscription->options_profile['profile_' . $i . '_status'] == 0) {
123
- unset($params['profile_' . $i]);
 
 
124
  }
125
  }
126
 
127
- apply_filters('newsletter_api_subscribe', $params);
128
-
129
- $full_name = '';
130
- if (isset($params['name'])) {
131
- $params['name'] = $newsletter->normalize_name($params['name']);
132
- $full_name .= $params['name'];
133
- }
134
-
135
- if (isset($params['surname'])) {
136
- $params['surname'] = $newsletter->normalize_name($params['surname']);
137
- $full_name .= ' ' . $params['surname'];
138
- }
139
-
140
- $ip = $newsletter->get_remote_ip();
141
-
142
- //NewsletterSubscription::instance()->valid_subscription_or_die($email, $full_name, $ip);
143
-
144
- $user = TNP::add_subscriber($params);
145
-
146
- if (is_wp_error($user)) {
147
- return ( $user );
148
- }
149
-
150
- // Notification to admin (only for new confirmed subscriptions)
151
- if ($user->status == 'C') {
152
- do_action('newsletter_user_confirmed', $user);
153
- $subscription->notify_admin_on_subscription($user);
154
- setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
155
- }
156
-
157
- // skip messages if send_emails = false
158
- if (!$params['send_emails']) {
159
- return $user;
160
- }
161
 
162
- $message_type = ( $user->status == 'C' ) ? 'confirmed' : 'confirmation';
163
- $subscription->send_message($message_type, $user);
164
 
165
- return null;
166
  }
167
 
168
  /*
21
  */
22
 
23
  public static function subscribe($params) {
24
+
25
+ if ($params instanceof TNP_Subscription) {
26
+ return NewsletterSubscription::instance()->subscribe2($params);
27
+ }
28
 
29
  $logger = new NewsletterLogger('phpapi');
30
  $logger->debug($params);
31
 
32
+ apply_filters('newsletter_api_subscribe', $params);
33
+
34
  $newsletter = Newsletter::instance();
35
+
36
+ $subscription = NewsletterSubscription::instance()->get_default_subscription();
37
+ $subscription->spamcheck = isset($params['spamcheck']);
38
+ $data = $subscription->data;
39
+
40
+ $subscription->send_emails = !empty($params['send_emails']);
 
 
41
 
42
  // Form field configuration
43
  $options_profile = get_option('newsletter_profile', array());
44
+
45
+ $data->email = $params['email'];
46
 
47
+ if (isset($params['name'])) {
48
+ $data->name = $params['name'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
 
51
+ if (isset($params['surname'])) {
52
+ $data->surname = $params['surname'];
 
 
53
  }
54
+
55
  // Lists
56
+ if (isset($params['lists']) && is_array($params['lists'])) {
57
+ $public_lists = array_keys($newsletter->get_lists_public());
58
+ $list_ids = array_intersect($public_lists, $params['lists']);
59
+
60
+ foreach ($list_ids as $list_id) {
61
+ $data->lists['' . $list_id] = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  }
63
+ }
64
+
65
+ for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
66
+ // If the profile cannot be set by subscriber, skip it.
67
+ if ($options_profile['profile_' . $i . '_status'] == 0) {
68
+ continue;
69
+ }
70
+ if (isset($params['profile_' . $i])) {
71
+ $data->profiles['' . $i] = stripslashes($params['profile_' . $i]);
72
  }
73
  }
74
 
75
+ $data->ip = $newsletter->get_remote_ip();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
+ $user = NewsletterSubscription::instance()->subscribe2($subscription);
 
78
 
79
+ return $user;
80
  }
81
 
82
  /*
includes/antispam.php CHANGED
@@ -5,7 +5,7 @@ class NewsletterAntispam {
5
  var $options;
6
  var $logger;
7
 
8
- public function instance() {
9
  static $instance;
10
  if (!$instance) {
11
  $instance = new NewsletterAntispam();
5
  var $options;
6
  var $logger;
7
 
8
+ public static function instance() {
9
  static $instance;
10
  if (!$instance) {
11
  $instance = new NewsletterAntispam();
includes/composer.php CHANGED
@@ -281,6 +281,7 @@ class TNP_Composer {
281
  }
282
 
283
  /**
 
284
  *
285
  * @param TNP_Media $media
286
  * @return string
@@ -294,7 +295,7 @@ class TNP_Composer {
294
  $b .= '<img src="' . $media->url . '" width="' . $media->width . '"'
295
  . ' height="' . $media->height . '"'
296
  . ' alt="' . esc_attr($media->alt) . '"'
297
- . ' border="0" style="max-width: 100%">';
298
 
299
  if ($media->link) {
300
  $b .= '</a>';
281
  }
282
 
283
  /**
284
+ * Generates an IMG tag, linked if the media has an URL.
285
  *
286
  * @param TNP_Media $media
287
  * @return string
295
  $b .= '<img src="' . $media->url . '" width="' . $media->width . '"'
296
  . ' height="' . $media->height . '"'
297
  . ' alt="' . esc_attr($media->alt) . '"'
298
+ . ' border="0" style="max-width: 100%; height: auto;" class="image">';
299
 
300
  if ($media->link) {
301
  $b .= '</a>';
includes/mailer.php CHANGED
@@ -324,16 +324,20 @@ class NewsletterDefaultMailer extends NewsletterMailer {
324
  }
325
 
326
  function fix_mailer($mailer) {
 
 
 
 
 
327
  $newsletter = Newsletter::instance();
 
 
 
328
  if (!empty($newsletter->options['content_transfer_encoding'])) {
329
  $mailer->Encoding = $newsletter->options['content_transfer_encoding'];
330
  } else {
331
  $mailer->Encoding = 'base64';
332
  }
333
-
334
- // If there is not a current message, wp_mail() was not called by us
335
- if (is_null($this->current_message)) {
336
- return;
337
  }
338
 
339
  /* @var $mailer PHPMailer */
324
  }
325
 
326
  function fix_mailer($mailer) {
327
+ // If there is not a current message, wp_mail() was not called by us
328
+ if (is_null($this->current_message)) {
329
+ return;
330
+ }
331
+
332
  $newsletter = Newsletter::instance();
333
+ if (isset($this->current_message->encoding)) {
334
+ $mailer->Encoding = $this->current_message->encoding;
335
+ } else {
336
  if (!empty($newsletter->options['content_transfer_encoding'])) {
337
  $mailer->Encoding = $newsletter->options['content_transfer_encoding'];
338
  } else {
339
  $mailer->Encoding = 'base64';
340
  }
 
 
 
 
341
  }
342
 
343
  /* @var $mailer PHPMailer */
includes/module.php CHANGED
@@ -106,6 +106,10 @@ class TNP_Profile {
106
  function is_private() {
107
  return $this->status == self::STATUS_PRIVATE;
108
  }
 
 
 
 
109
 
110
  }
111
 
@@ -654,8 +658,9 @@ class NewsletterModule {
654
  * returns false.
655
  */
656
  static function normalize_email($email) {
657
- if (!is_string($email))
658
  return false;
 
659
  $email = strtolower(trim($email));
660
  if (!is_email($email)) {
661
  return false;
@@ -682,8 +687,9 @@ class NewsletterModule {
682
 
683
  static function is_email($email, $empty_ok = false) {
684
 
685
- if (!is_string($email))
686
  return false;
 
687
  $email = strtolower(trim($email));
688
 
689
  if ($email == '') {
@@ -1333,6 +1339,51 @@ class NewsletterModule {
1333
  function get_profiles($language = '') {
1334
  return TNP_Profile_Service::get_profiles($language);
1335
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1336
 
1337
  /**
1338
  * @param string $language The language for the list labels (it does not affect the lists returned)
106
  function is_private() {
107
  return $this->status == self::STATUS_PRIVATE;
108
  }
109
+
110
+ function show_on_profile() {
111
+ return $this->status == self::STATUS_PROFILE_ONLY || $this->status == self::STATUS_PUBLIC;
112
+ }
113
 
114
  }
115
 
658
  * returns false.
659
  */
660
  static function normalize_email($email) {
661
+ if (!is_string($email)) {
662
  return false;
663
+ }
664
  $email = strtolower(trim($email));
665
  if (!is_email($email)) {
666
  return false;
687
 
688
  static function is_email($email, $empty_ok = false) {
689
 
690
+ if (!is_string($email)) {
691
  return false;
692
+ }
693
  $email = strtolower(trim($email));
694
 
695
  if ($email == '') {
1339
  function get_profiles($language = '') {
1340
  return TNP_Profile_Service::get_profiles($language);
1341
  }
1342
+
1343
+ /**
1344
+ * Returns a list of TNP_Profile which are public.
1345
+ *
1346
+ * @staticvar array $profiles
1347
+ * @param string $language
1348
+ * @return TNP_Profile[]
1349
+ */
1350
+ function get_profiles_public($language = '') {
1351
+ static $profiles = [];
1352
+ if (isset($profiles[$language])) {
1353
+ return $profiles[$language];
1354
+ }
1355
+
1356
+ $profiles[$language] = [];
1357
+ $all = $this->get_profiles($language);
1358
+ foreach ($all as $profile) {
1359
+ if ($profile->is_private()) continue;
1360
+
1361
+ $profiles[$language]['' . $profile->id] = $profile;
1362
+ }
1363
+ return $profiles[$language];
1364
+ }
1365
+
1366
+ /**
1367
+ * Really bad name!
1368
+ * @staticvar array $profiles
1369
+ * @param type $language
1370
+ * @return array
1371
+ */
1372
+ function get_profiles_for_profile($language = '') {
1373
+ static $profiles = [];
1374
+ if (isset($profiles[$language])) {
1375
+ return $profiles[$language];
1376
+ }
1377
+
1378
+ $profiles[$language] = [];
1379
+ $all = $this->get_profiles($language);
1380
+ foreach ($all as $profile) {
1381
+ if (!$profile->show_on_profile()) continue;
1382
+
1383
+ $profiles[$language]['' . $profile->id] = $profile;
1384
+ }
1385
+ return $profiles[$language];
1386
+ }
1387
 
1388
  /**
1389
  * @param string $language The language for the list labels (it does not affect the lists returned)
main/main.php CHANGED
@@ -33,6 +33,9 @@ if (!$controls->is_action()) {
33
  } else {
34
  $controls->data['return_path'] = $this->normalize_email($controls->data['return_path']);
35
  }
 
 
 
36
 
37
 
38
  if (!$this->is_email($controls->data['reply_to'], true)) {
@@ -240,7 +243,7 @@ if (!empty($return_path)) {
240
  <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/delivery-and-spam/newsletter-delivery-engine/') ?>
241
  </th>
242
  <td>
243
- <?php $controls->text('scheduler_max', 5); ?>
244
  </td>
245
  </tr>
246
  </table>
33
  } else {
34
  $controls->data['return_path'] = $this->normalize_email($controls->data['return_path']);
35
  }
36
+
37
+ $controls->data['scheduler_max'] = (int)$controls->data['scheduler_max'];
38
+ if ($controls->data['scheduler_max'] < 10) $controls->data['scheduler_max'] = 10;
39
 
40
 
41
  if (!$this->is_email($controls->data['reply_to'], true)) {
243
  <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/delivery-and-spam/newsletter-delivery-engine/') ?>
244
  </th>
245
  <td>
246
+ <?php $controls->text('scheduler_max', 5); ?> (min. 10)
247
  </td>
248
  </tr>
249
  </table>
main/smtp.php CHANGED
@@ -74,7 +74,7 @@ if (empty($controls->data['enabled']) && !empty($controls->data['host'])) {
74
  On GoDaddy you should follow this <a href="https://www.thenewsletterplugin.com/godaddy-using-smtp-external-server-shared-hosting" target="_blank">special setup</a>.
75
  </p>
76
  <p>
77
- Consider <a href="https://www.thenewsletterplugin.com/affiliate/sendgrid" target="_blank">SendGrid</a> for a serious and reliable SMTP service.
78
  </p>
79
 
80
  </div>
74
  On GoDaddy you should follow this <a href="https://www.thenewsletterplugin.com/godaddy-using-smtp-external-server-shared-hosting" target="_blank">special setup</a>.
75
  </p>
76
  <p>
77
+ Consider <a href="https://www.sendinblue.com/?tap_a=30591-fb13f0&tap_s=626735-cdbaad" target="_blank">Sedinblue</a> (aff) for a serious and reliable SMTP service.
78
  </p>
79
 
80
  </div>
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.9.3
8
  Author: Stefano Lissa & The Newsletter Team
9
  Author URI: https://www.thenewsletterplugin.com
10
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
@@ -35,7 +35,7 @@ if (version_compare(phpversion(), '5.6', '<')) {
35
  return;
36
  }
37
 
38
- define('NEWSLETTER_VERSION', '6.9.3');
39
 
40
  global $newsletter, $wpdb;
41
 
@@ -960,8 +960,15 @@ class Newsletter extends NewsletterModule {
960
  return $this->mailer;
961
  }
962
 
 
 
 
 
 
963
  function deliver($message) {
964
  $mailer = $this->get_mailer();
 
 
965
  return $mailer->send($message);
966
  }
967
 
@@ -995,6 +1002,8 @@ class Newsletter extends NewsletterModule {
995
  $mailer_message->body = $this->clean_eol($message['html']);
996
  }
997
  }
 
 
998
 
999
  $mailer = $this->get_mailer();
1000
 
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.9.4
8
  Author: Stefano Lissa & The Newsletter Team
9
  Author URI: https://www.thenewsletterplugin.com
10
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
35
  return;
36
  }
37
 
38
+ define('NEWSLETTER_VERSION', '6.9.4');
39
 
40
  global $newsletter, $wpdb;
41
 
960
  return $this->mailer;
961
  }
962
 
963
+ /**
964
+ *
965
+ * @param TNP_Mailer_Message $message
966
+ * @return type
967
+ */
968
  function deliver($message) {
969
  $mailer = $this->get_mailer();
970
+ if (empty($message->from)) $message->from = $this->options['sender_email'];
971
+ if (empty($message->from_name)) $mailer->from_name = $this->options['sender_name'];
972
  return $mailer->send($message);
973
  }
974
 
1002
  $mailer_message->body = $this->clean_eol($message['html']);
1003
  }
1004
  }
1005
+
1006
+ $this->logger->debug($mailer_message);
1007
 
1008
  $mailer = $this->get_mailer();
1009
 
profile/profile.php CHANGED
@@ -48,9 +48,13 @@ class NewsletterProfile extends NewsletterModule {
48
 
49
  case 'profile-save':
50
  case 'ps':
51
- $user = $this->save_profile($user);
52
- // $user->alert is a temporary field
53
- wp_redirect($this->build_message_url($this->options['url'], 'profile', $user, $email, $user->alert));
 
 
 
 
54
  die();
55
  break;
56
 
@@ -212,7 +216,7 @@ class NewsletterProfile extends NewsletterModule {
212
  $buffer = '';
213
 
214
  $buffer .= '<div class="tnp tnp-profile">';
215
- $buffer .= '<form action="' . $this->build_action_url('ps') . '" method="post" onsubmit="return newsletter_check(this)">';
216
  $buffer .= '<input type="hidden" name="nk" value="' . esc_attr($user->id . '-' . $user->token) . '">';
217
 
218
  $buffer .= '<div class="tnp-field tnp-field-email">';
@@ -256,7 +260,7 @@ class NewsletterProfile extends NewsletterModule {
256
 
257
  $buffer .= '<option value="" disabled ' . ( empty($user->language) ? ' selected' : '' ) . '>' . __('Select language', 'newsletter') . '</option>';
258
  foreach ($languages as $key => $language) {
259
- $buffer .= '<option value="' . $key . '"' . ( $user->language == $key ? ' selected' : '' ) . '>' . $language . '</option>';
260
  }
261
 
262
  $buffer .= '</select>';
@@ -264,32 +268,28 @@ class NewsletterProfile extends NewsletterModule {
264
  }
265
 
266
  // Profile
267
- for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
268
- if ($options['profile_' . $i . '_status'] == 0) {
269
- continue;
270
- }
271
 
272
  $buffer .= '<div class="tnp-field tnp-field-profile">';
273
- $buffer .= '<label>' . esc_html($options['profile_' . $i]) . '</label>';
274
 
275
  $field = 'profile_' . $i;
276
 
277
- if ($options['profile_' . $i . '_type'] == 'text') {
278
  $buffer .= '<input class="tnp-profile tnp-profile-' . $i . '" type="text" name="np' . $i . '" value="' . esc_attr($user->$field) . '"' .
279
- ($options['profile_' . $i . '_rules'] == 1 ? ' required' : '') . '>';
280
  }
281
 
282
- if ($options['profile_' . $i . '_type'] == 'select') {
283
- $buffer .= '<select class="tnp-profile tnp-profile-' . $i . '" name="np' . $i . '"' .
284
- ($options['profile_' . $i . '_rules'] == 1 ? ' required' : '') . '>';
285
- $opts = explode(',', $options['profile_' . $i . '_options']);
286
- for ($j = 0; $j < count($opts); $j++) {
287
- $opts[$j] = trim($opts[$j]);
288
  $buffer .= '<option';
289
- if ($opts[$j] == $user->$field) {
290
  $buffer .= ' selected';
291
  }
292
- $buffer .= '>' . esc_html($opts[$j]) . '</option>';
293
  }
294
  $buffer .= '</select>';
295
  }
@@ -316,6 +316,7 @@ class NewsletterProfile extends NewsletterModule {
316
  $buffer .= '<div class="tnp-lists">' . "\n" . $tmp . "\n" . '</div>';
317
  }
318
 
 
319
  $extra = apply_filters('newsletter_profile_extra', array(), $user);
320
  foreach ($extra as $x) {
321
  $buffer .= '<div class="tnp-field">';
@@ -355,7 +356,7 @@ class NewsletterProfile extends NewsletterModule {
355
  * Saves the subscriber data extracting them from the $_REQUEST and for the
356
  * subscriber identified by the <code>$user</code> object.
357
  *
358
- * @return type
359
  */
360
  function save_profile($user) {
361
  global $wpdb;
@@ -370,38 +371,48 @@ class NewsletterProfile extends NewsletterModule {
370
 
371
  // Not an elegant interaction between modules but...
372
  $subscription_module = NewsletterSubscription::instance();
 
 
 
 
 
 
373
 
374
- if (!$this->is_email($_REQUEST['ne'])) {
375
- $user->alert = $options['profile_error'];
376
- return $user;
377
  }
378
-
379
- $email = $this->normalize_email(stripslashes($_REQUEST['ne']));
 
 
 
380
  $email_changed = ($email != $user->email);
381
 
382
  // If the email has been changed, check if it is available
383
  if ($email_changed) {
384
  $tmp = $this->get_user($email);
385
  if ($tmp != null && $tmp->id != $user->id) {
386
- $user->alert = $options['error'];
387
- return $user;
388
  }
389
- $data['status'] = Newsletter::STATUS_NOT_CONFIRMED;
390
  }
391
-
392
- // General data
393
- $data['email'] = $email;
 
 
 
 
394
  if (isset($_REQUEST['nn'])) {
395
  $data['name'] = $this->normalize_name(stripslashes($_REQUEST['nn']));
396
- //if ($subscription_module->is_spam_text($data['name'])) {
397
- // die();
398
- //}
399
  }
400
  if (isset($_REQUEST['ns'])) {
401
  $data['surname'] = $this->normalize_name(stripslashes($_REQUEST['ns']));
402
- //if ($subscription_module->is_spam_text($data['surname'])) {
403
- // die();
404
- //}
405
  }
406
  if ($options_profile['sex_status'] >= 1) {
407
  $data['sex'] = $_REQUEST['nx'][0];
@@ -431,15 +442,13 @@ class NewsletterProfile extends NewsletterModule {
431
  }
432
 
433
  // Profile
434
- for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
435
- // Private fields cannot be changed by the subscriber
436
- if ($options_profile['profile_' . $i . '_status'] == 0) {
437
- continue;
438
  }
439
- $data['profile_' . $i] = stripslashes($_REQUEST['np' . $i]);
440
  }
441
 
442
-
443
  // Feed by Mail service is saved here
444
  $data = apply_filters('newsletter_profile_save', $data);
445
 
@@ -451,25 +460,12 @@ class NewsletterProfile extends NewsletterModule {
451
  $this->add_user_log($user, 'profile');
452
 
453
  // Send the activation again only if we use double opt-in, otherwise it has no meaning
454
- // TODO: Maybe define a specific email for that and not the activation email
455
  if ($email_changed && $subscription_module->is_double_optin()) {
456
  $subscription_module->send_activation_email($user);
457
- // TODO: Move this option on new profile configuration panel
458
- $alert = $this->options['profile_email_changed'];
459
- }
460
-
461
- if (isset($alert)) {
462
- $user->alert = $alert;
463
- } else {
464
- $user->alert = $options['saved'];
465
  }
466
- return $user;
467
- }
468
-
469
- function upgrade() {
470
- global $wpdb, $charset_collate;
471
-
472
- parent::upgrade();
473
  }
474
 
475
  function admin_menu() {
48
 
49
  case 'profile-save':
50
  case 'ps':
51
+ $res = $this->save_profile($user);
52
+ if (is_wp_error($res)) {
53
+ wp_redirect($this->build_message_url($this->options['url'], 'profile', $user, $email, $res->get_error_message()));
54
+ die();
55
+ }
56
+
57
+ wp_redirect($this->build_message_url($this->options['url'], 'profile', $user, $email, $res));
58
  die();
59
  break;
60
 
216
  $buffer = '';
217
 
218
  $buffer .= '<div class="tnp tnp-profile">';
219
+ $buffer .= '<form action="' . $this->build_action_url('ps') . '" method="post">';
220
  $buffer .= '<input type="hidden" name="nk" value="' . esc_attr($user->id . '-' . $user->token) . '">';
221
 
222
  $buffer .= '<div class="tnp-field tnp-field-email">';
260
 
261
  $buffer .= '<option value="" disabled ' . ( empty($user->language) ? ' selected' : '' ) . '>' . __('Select language', 'newsletter') . '</option>';
262
  foreach ($languages as $key => $language) {
263
+ $buffer .= '<option value="' . $key . '"' . ( $user->language == $key ? ' selected' : '' ) . '>' . esc_html($language) . '</option>';
264
  }
265
 
266
  $buffer .= '</select>';
268
  }
269
 
270
  // Profile
271
+ $profiles = NewsletterSubscription::instance()->get_profiles_for_profile($user->language);
272
+ foreach ($profiles as $profile) {
273
+ $i = $profile->id; // I'm lazy
 
274
 
275
  $buffer .= '<div class="tnp-field tnp-field-profile">';
276
+ $buffer .= '<label>' . esc_html($profile->name) . '</label>';
277
 
278
  $field = 'profile_' . $i;
279
 
280
+ if ($profile->is_text()) {
281
  $buffer .= '<input class="tnp-profile tnp-profile-' . $i . '" type="text" name="np' . $i . '" value="' . esc_attr($user->$field) . '"' .
282
+ ($profile->is_required() ? ' required' : '') . '>';
283
  }
284
 
285
+ if ($profile->is_select()) {
286
+ $buffer .= '<select class="tnp-profile tnp-profile-' . $i . '" name="np' . $i . '"' . ($profile->is_required() ? ' required' : '') . '>';
287
+ foreach ($profile->options as $option) {
 
 
 
288
  $buffer .= '<option';
289
+ if ($option == $user->$field) {
290
  $buffer .= ' selected';
291
  }
292
+ $buffer .= '>' . esc_html($option) . '</option>';
293
  }
294
  $buffer .= '</select>';
295
  }
316
  $buffer .= '<div class="tnp-lists">' . "\n" . $tmp . "\n" . '</div>';
317
  }
318
 
319
+ // Obsolete
320
  $extra = apply_filters('newsletter_profile_extra', array(), $user);
321
  foreach ($extra as $x) {
322
  $buffer .= '<div class="tnp-field">';
356
  * Saves the subscriber data extracting them from the $_REQUEST and for the
357
  * subscriber identified by the <code>$user</code> object.
358
  *
359
+ * @return string|WP_Error If not an error the string represent the message to show
360
  */
361
  function save_profile($user) {
362
  global $wpdb;
371
 
372
  // Not an elegant interaction between modules but...
373
  $subscription_module = NewsletterSubscription::instance();
374
+
375
+ require_once NEWSLETTER_INCLUDES_DIR . '/antispam.php';
376
+
377
+ $antispam = NewsletterAntispam::instance();
378
+
379
+ $email = $this->normalize_email(stripslashes($_REQUEST['ne']));
380
 
381
+ if ($antispam->is_address_blacklisted($email)) {
382
+ return new WP_Error('spam', 'That email address is not accepted');
 
383
  }
384
+
385
+ if (!$email) {
386
+ return new WP_Error('email', $options['error']);
387
+ }
388
+
389
  $email_changed = ($email != $user->email);
390
 
391
  // If the email has been changed, check if it is available
392
  if ($email_changed) {
393
  $tmp = $this->get_user($email);
394
  if ($tmp != null && $tmp->id != $user->id) {
395
+ return new WP_Error('inuse', $options['error']);
 
396
  }
 
397
  }
398
+
399
+ if ($email_changed && $subscription_module->is_double_optin()) {
400
+ set_transient('newsletter_user_' . $user->id . '_email', $email, DAY_IN_SECONDS);
401
+ } else {
402
+ $data['email'] = $email;
403
+ }
404
+
405
  if (isset($_REQUEST['nn'])) {
406
  $data['name'] = $this->normalize_name(stripslashes($_REQUEST['nn']));
407
+ if ($antispam->is_spam_text($data['name'])) {
408
+ return new WP_Error('spam', 'That name/surname');
409
+ }
410
  }
411
  if (isset($_REQUEST['ns'])) {
412
  $data['surname'] = $this->normalize_name(stripslashes($_REQUEST['ns']));
413
+ if ($antispam->is_spam_text($data['surname'])) {
414
+ return new WP_Error('spam', 'That name/surname');
415
+ }
416
  }
417
  if ($options_profile['sex_status'] >= 1) {
418
  $data['sex'] = $_REQUEST['nx'][0];
442
  }
443
 
444
  // Profile
445
+ $profiles = $this->get_profiles_public();
446
+ foreach ($profiles as $profile) {
447
+ if (isset($_REQUEST['np' . $profile->id])) {
448
+ $data['profile_' . $profile->id] = stripslashes($_REQUEST['np' . $profile->id]);
449
  }
 
450
  }
451
 
 
452
  // Feed by Mail service is saved here
453
  $data = apply_filters('newsletter_profile_save', $data);
454
 
460
  $this->add_user_log($user, 'profile');
461
 
462
  // Send the activation again only if we use double opt-in, otherwise it has no meaning
 
463
  if ($email_changed && $subscription_module->is_double_optin()) {
464
  $subscription_module->send_activation_email($user);
465
+ return $options['email_changed'];
 
 
 
 
 
 
 
466
  }
467
+
468
+ return $options['saved'];
 
 
 
 
 
469
  }
470
 
471
  function admin_menu() {
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.5.1
5
- Stable tag: 6.9.3
6
  Requires PHP: 5.6
7
  Contributors: satollo,webagile,michael-travan
8
 
@@ -113,13 +113,21 @@ Thank you, The Newsletter Team
113
 
114
  == Changelog ==
115
 
 
 
 
 
 
 
 
 
116
  = 6.9.3 =
117
 
118
  * Fixed profile saving spam check
119
 
120
  = 6.9.2 =
121
 
122
- * Fixed TNP::subscribe() error
123
 
124
  = 6.9.1 =
125
 
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.5.1
5
+ Stable tag: 6.9.4
6
  Requires PHP: 5.6
7
  Contributors: satollo,webagile,michael-travan
8
 
113
 
114
  == Changelog ==
115
 
116
+ = 6.9.4 =
117
+
118
+ * Fixed the profile save
119
+ * Improved the email change management from the subscriber data page
120
+ * Removed custom javascript and opted for HTML5 validation (you can use a polyfill plugin like parsely)
121
+ * Removed custom error messages (see above)
122
+ * Check on delivery speed to be minimum 10 emails per hour
123
+
124
  = 6.9.3 =
125
 
126
  * Fixed profile saving spam check
127
 
128
  = 6.9.2 =
129
 
130
+ * Fixed error on TNP::subscribe()
131
 
132
  = 6.9.1 =
133
 
subscription/defaults-profile.php CHANGED
@@ -6,17 +6,17 @@ $options = array();
6
  $options['email'] = 'Email';
7
  $options['email_error'] = __('Email address is not correct', 'newsletter');
8
  $options['name'] = __('First name or full name', 'newsletter');
9
- $options['name_error'] = __('Name is required', 'newsletter');
10
  $options['name_status'] = 0;
11
  $options['name_rules'] = 0;
12
  $options['surname'] = __('Last name', 'newsletter');
13
- $options['surname_error'] = __('Last name is required', 'newsletter');
14
  $options['surname_status'] = 0;
15
  $options['sex_status'] = 0;
16
  $options['sex'] = __('I\'m', 'newsletter');
17
 
18
  $options['privacy'] = __('By continuing, you accept the privacy policy', 'newsletter');
19
- $options['privacy_error'] = 'You must accept the privacy policy';
20
  $options['privacy_status'] = 0;
21
  $options['privacy_url'] = '';
22
  $options['privacy_use_wp_url'] = 0;
@@ -31,7 +31,7 @@ $options['sex_male'] = 'Man';
31
  $options['sex_female'] = 'Woman';
32
  $options['sex_none'] = 'Not specified';
33
 
34
- $options['profile_error'] = __('A mandatory field is not filled in', 'newsletter');
35
 
36
  for ($i=1; $i<=NEWSLETTER_PROFILE_MAX; $i++) {
37
  $options['profile_' . $i . '_status'] = 0;
6
  $options['email'] = 'Email';
7
  $options['email_error'] = __('Email address is not correct', 'newsletter');
8
  $options['name'] = __('First name or full name', 'newsletter');
9
+ //$options['name_error'] = __('Name is required', 'newsletter');
10
  $options['name_status'] = 0;
11
  $options['name_rules'] = 0;
12
  $options['surname'] = __('Last name', 'newsletter');
13
+ //$options['surname_error'] = __('Last name is required', 'newsletter');
14
  $options['surname_status'] = 0;
15
  $options['sex_status'] = 0;
16
  $options['sex'] = __('I\'m', 'newsletter');
17
 
18
  $options['privacy'] = __('By continuing, you accept the privacy policy', 'newsletter');
19
+ //$options['privacy_error'] = 'You must accept the privacy policy';
20
  $options['privacy_status'] = 0;
21
  $options['privacy_url'] = '';
22
  $options['privacy_use_wp_url'] = 0;
31
  $options['sex_female'] = 'Woman';
32
  $options['sex_none'] = 'Not specified';
33
 
34
+ //$options['profile_error'] = __('A mandatory field is not filled in', 'newsletter');
35
 
36
  for ($i=1; $i<=NEWSLETTER_PROFILE_MAX; $i++) {
37
  $options['profile_' . $i . '_status'] = 0;
subscription/profile.php CHANGED
@@ -82,7 +82,6 @@ $extra_type = array('text' => __('Text', 'newsletter'), 'select' => __('List', '
82
  <tr><th>When to show</th><td><?php $controls->select('name_status', $status); ?></td></tr>
83
  <tr><th>Rules</th><td><?php $controls->select('name_rules', $rules); ?></td></tr>
84
  <?php } ?>
85
- <tr><th>Error message</th><td><?php $controls->text('name_error', 50); ?></td></tr>
86
  </table>
87
  <p class="description">
88
  If you want to collect only a generic "name", use only this field and not the
@@ -99,7 +98,6 @@ $extra_type = array('text' => __('Text', 'newsletter'), 'select' => __('List', '
99
  <tr><th>When to show</th><td><?php $controls->select('surname_status', $status); ?></td></tr>
100
  <tr><th>Rules</th><td><?php $controls->select('surname_rules', $rules); ?></td></tr>
101
  <?php } ?>
102
- <tr><th>Error message</th><td><?php $controls->text('surname_error', 50); ?></td></tr>
103
  </table>
104
  </td>
105
  </tr>
@@ -112,19 +110,25 @@ $extra_type = array('text' => __('Text', 'newsletter'), 'select' => __('List', '
112
  <tr><th>When to show</th><td><?php $controls->select('sex_status', $status); ?></td></tr>
113
  <tr><th>Rules</th><td><?php $controls->select('sex_rules', $rules); ?></td></tr>
114
  <?php } ?>
115
- <tr><th>Value labels</th><td>
 
 
116
  female: <?php $controls->text('sex_female'); ?>
117
  male: <?php $controls->text('sex_male'); ?>
118
  not specified: <?php $controls->text('sex_none'); ?>
119
- </td></tr>
 
120
 
121
 
122
- <tr><th>Salutation titles</th><td>
 
 
123
 
124
  for males: <?php $controls->text('title_male'); ?> (ex. "Mr")<br>
125
  for females: <?php $controls->text('title_female'); ?> (ex. "Mrs")<br>
126
  for others: <?php $controls->text('title_none'); ?>
127
- </td></tr>
 
128
  </table>
129
  <p class="description">
130
  Salutation titles are inserted in emails message when the tag {title} is used. For example
@@ -172,9 +176,6 @@ $extra_type = array('text' => __('Text', 'newsletter'), 'select' => __('List', '
172
  <?php } ?>
173
  </td>
174
  </tr>
175
- <tr>
176
- <th>Error message</th>
177
- <td><?php $controls->text('privacy_error', 50); ?></td></tr>
178
  </table>
179
  <p class="description">
180
  The privacy acceptance checkbox (required in many Europen countries) forces the subscriber to
@@ -197,15 +198,6 @@ $extra_type = array('text' => __('Text', 'newsletter'), 'select' => __('List', '
197
  The placeholder works only on HTML 5 compliant browsers.
198
  </p>
199
 
200
- <table class="form-table">
201
- <tr>
202
- <th>Error message</th>
203
- <td>
204
- <?php $controls->text('profile_error', 50); ?>
205
- </td>
206
- </tr>
207
- </table>
208
-
209
  <table class="widefat">
210
  <thead>
211
  <tr>
82
  <tr><th>When to show</th><td><?php $controls->select('name_status', $status); ?></td></tr>
83
  <tr><th>Rules</th><td><?php $controls->select('name_rules', $rules); ?></td></tr>
84
  <?php } ?>
 
85
  </table>
86
  <p class="description">
87
  If you want to collect only a generic "name", use only this field and not the
98
  <tr><th>When to show</th><td><?php $controls->select('surname_status', $status); ?></td></tr>
99
  <tr><th>Rules</th><td><?php $controls->select('surname_rules', $rules); ?></td></tr>
100
  <?php } ?>
 
101
  </table>
102
  </td>
103
  </tr>
110
  <tr><th>When to show</th><td><?php $controls->select('sex_status', $status); ?></td></tr>
111
  <tr><th>Rules</th><td><?php $controls->select('sex_rules', $rules); ?></td></tr>
112
  <?php } ?>
113
+ <tr>
114
+ <th>Value labels</th>
115
+ <td>
116
  female: <?php $controls->text('sex_female'); ?>
117
  male: <?php $controls->text('sex_male'); ?>
118
  not specified: <?php $controls->text('sex_none'); ?>
119
+ </td>
120
+ </tr>
121
 
122
 
123
+ <tr>
124
+ <th>Salutation titles</th>
125
+ <td>
126
 
127
  for males: <?php $controls->text('title_male'); ?> (ex. "Mr")<br>
128
  for females: <?php $controls->text('title_female'); ?> (ex. "Mrs")<br>
129
  for others: <?php $controls->text('title_none'); ?>
130
+ </td>
131
+ </tr>
132
  </table>
133
  <p class="description">
134
  Salutation titles are inserted in emails message when the tag {title} is used. For example
176
  <?php } ?>
177
  </td>
178
  </tr>
 
 
 
179
  </table>
180
  <p class="description">
181
  The privacy acceptance checkbox (required in many Europen countries) forces the subscriber to
198
  The placeholder works only on HTML 5 compliant browsers.
199
  </p>
200
 
 
 
 
 
 
 
 
 
 
201
  <table class="widefat">
202
  <thead>
203
  <tr>
subscription/subscription.php CHANGED
@@ -62,7 +62,6 @@ class NewsletterSubscription extends NewsletterModule {
62
  if (is_admin()) {
63
  add_action('admin_init', array($this, 'hook_admin_init'));
64
  } else {
65
- add_action('wp_enqueue_scripts', array($this, 'hook_wp_enqueue_scripts'));
66
  // Shortcode for the Newsletter page
67
  add_shortcode('newsletter', array($this, 'shortcode_newsletter'));
68
  add_shortcode('newsletter_form', array($this, 'shortcode_newsletter_form'));
@@ -83,33 +82,6 @@ class NewsletterSubscription extends NewsletterModule {
83
  }
84
  }
85
 
86
- function hook_wp_enqueue_scripts() {
87
-
88
- wp_enqueue_script('newsletter-subscription', plugins_url('newsletter') . '/subscription/validate.js', array(), NEWSLETTER_VERSION, true);
89
-
90
- $options = $this->get_options('profile', $this->get_current_language());
91
-
92
- $data = array();
93
- $data['messages'] = array();
94
- if (isset($options['email_error'])) {
95
- $data['messages']['email_error'] = $options['email_error'];
96
- }
97
- if (isset($options['name_error'])) {
98
- $data['messages']['name_error'] = $options['name_error'];
99
- }
100
- if (isset($options['surname_error'])) {
101
- $data['messages']['surname_error'] = $options['surname_error'];
102
- }
103
- if (isset($options['profile_error'])) {
104
- $data['messages']['profile_error'] = $options['profile_error'];
105
- }
106
- if (isset($options['privacy_error'])) {
107
- $data['messages']['privacy_error'] = $options['privacy_error'];
108
- }
109
- $data['profile_max'] = NEWSLETTER_PROFILE_MAX;
110
- wp_localize_script('newsletter-subscription', 'newsletter', $data);
111
- }
112
-
113
  /**
114
  *
115
  * @global wpdb $wpdb
@@ -187,10 +159,12 @@ class NewsletterSubscription extends NewsletterModule {
187
  $this->dienow('Registration failed.', $user->get_error_message(), 400);
188
  }
189
 
190
- if ($user->status == TNP_User::STATUS_CONFIRMED)
191
  $this->show_message('confirmed', $user);
192
- if ($user->status == TNP_User::STATUS_NOT_CONFIRMED)
 
193
  $this->show_message('confirmation', $user);
 
194
  } else {
195
  $this->request_to_antibot_form('Subscribe', $captcha);
196
  }
@@ -200,7 +174,6 @@ class NewsletterSubscription extends NewsletterModule {
200
  case 'ajaxsub':
201
 
202
  if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
203
- //$antibot_logger->fatal('HTTP method invalid');
204
  $this->dienow('Invalid request');
205
  }
206
 
@@ -312,7 +285,7 @@ class NewsletterSubscription extends NewsletterModule {
312
  }
313
 
314
  function first_install() {
315
-
316
  }
317
 
318
  function admin_menu() {
@@ -535,7 +508,7 @@ class NewsletterSubscription extends NewsletterModule {
535
  if ($subscription->spamcheck) {
536
  // TODO: Use autoload
537
  require_once NEWSLETTER_INCLUDES_DIR . '/antispam.php';
538
- $antispam = new NewsletterAntispam();
539
  if ($antispam->is_spam($subscription)) {
540
  return new WP_Error('spam', 'This looks like a spam subscription');
541
  }
@@ -997,16 +970,11 @@ class NewsletterSubscription extends NewsletterModule {
997
  $user->status = Newsletter::STATUS_NOT_CONFIRMED;
998
  delete_transient('newsletter_subscription_' . $user->id);
999
  } else {
1000
- // Is there any temporary data from a subscription to be confirmed?
1001
- $data = get_transient($this->get_user_key($user));
1002
- if ($data !== false) {
1003
- $_REQUEST = $data;
1004
- // Update the user profile since it's now confirmed
1005
- $user = $this->update_user_from_request((array) $user);
1006
- $user = $this->save_user($user);
1007
- delete_transient($this->get_user_key($user));
1008
- // Forced a fake status so the welcome email is sent
1009
- $user->status = Newsletter::STATUS_NOT_CONFIRMED;
1010
  }
1011
  }
1012
 
@@ -1136,51 +1104,11 @@ class NewsletterSubscription extends NewsletterModule {
1136
  }
1137
 
1138
  function get_form_javascript() {
1139
- $this->setup_form_options();
1140
-
1141
- $buffer = "\n\n";
1142
- $buffer .= '<script type="text/javascript">' . "\n";
1143
- $buffer .= '//<![CDATA[' . "\n";
1144
- $buffer .= 'if (typeof newsletter_check !== "function") {' . "\n";
1145
- $buffer .= 'window.newsletter_check = function (f) {' . "\n";
1146
- $buffer .= ' var re = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-]{1,})+\.)+([a-zA-Z0-9]{2,})+$/;' . "\n";
1147
- $buffer .= ' if (!re.test(f.elements["ne"].value)) {' . "\n";
1148
- $buffer .= ' alert("' . addslashes($this->form_options['email_error']) . '");' . "\n";
1149
- $buffer .= ' return false;' . "\n";
1150
- $buffer .= ' }' . "\n";
1151
- if ($this->form_options['name_status'] == 2 && $this->form_options['name_rules'] == 1) {
1152
- $buffer .= ' if (f.elements["nn"] && (f.elements["nn"].value == "" || f.elements["nn"].value == f.elements["nn"].defaultValue)) {' . "\n";
1153
- $buffer .= ' alert("' . addslashes($this->form_options['name_error']) . '");' . "\n";
1154
- $buffer .= ' return false;' . "\n";
1155
- $buffer .= ' }' . "\n";
1156
- }
1157
- if ($this->form_options['surname_status'] == 2 && $this->form_options['surname_rules'] == 1) {
1158
- $buffer .= ' if (f.elements["ns"] && (f.elements["ns"].value == "" || f.elements["ns"].value == f.elements["ns"].defaultValue)) {' . "\n";
1159
- $buffer .= ' alert("' . addslashes($this->form_options['surname_error']) . '");' . "\n";
1160
- $buffer .= ' return false;' . "\n";
1161
- $buffer .= ' }' . "\n";
1162
- }
1163
- $buffer .= ' for (var i=1; i<' . NEWSLETTER_PROFILE_MAX . '; i++) {' . "\n";
1164
- $buffer .= ' if (f.elements["np" + i] && f.elements["np" + i].required && f.elements["np" + i].value == "") {' . "\n";
1165
- $buffer .= ' alert("' . addslashes($this->form_options['profile_error']) . '");' . "\n";
1166
- $buffer .= ' return false;' . "\n";
1167
- $buffer .= ' }' . "\n";
1168
- $buffer .= ' }' . "\n";
1169
-
1170
- $buffer .= ' if (f.elements["ny"] && !f.elements["ny"].checked) {' . "\n";
1171
- $buffer .= ' alert("' . addslashes($this->form_options['privacy_error']) . '");' . "\n";
1172
- $buffer .= ' return false;' . "\n";
1173
- $buffer .= ' }' . "\n";
1174
- $buffer .= ' return true;' . "\n";
1175
- $buffer .= '}' . "\n";
1176
- $buffer .= '}' . "\n";
1177
- $buffer .= '//]]>' . "\n";
1178
- $buffer .= '</script>' . "\n\n";
1179
- return $buffer;
1180
  }
1181
 
1182
  /**
1183
- * Manages the custom forms made with [newsletter_form] and internal [newsletter_field] shorcodes.
1184
  *
1185
  * @param array $attrs
1186
  * @param string $content
@@ -1202,31 +1130,7 @@ class NewsletterSubscription extends NewsletterModule {
1202
 
1203
  $language = $this->get_current_language();
1204
 
1205
- $buffer .= '<input type="hidden" name="nlang" value="' . esc_attr($language) . '">' . "\n";
1206
-
1207
- if (isset($attrs['referrer'])) {
1208
- $buffer .= '<input type="hidden" name="nr" value="' . esc_attr($attrs['referrer']) . '">' . "\n";
1209
- }
1210
-
1211
- if (isset($attrs['optin'])) {
1212
- $buffer .= $this->build_optin_field($attrs['optin']);
1213
- }
1214
-
1215
- if (isset($attrs['confirmation_url'])) {
1216
- if ($attrs['confirmation_url'] == '#') {
1217
- $attrs['confirmation_url'] = $_SERVER['REQUEST_URI'];
1218
- }
1219
- $buffer .= "<input type='hidden' name='ncu' value='" . esc_attr($attrs['confirmation_url']) . "'>\n";
1220
- }
1221
-
1222
- // Compatibility
1223
- if (isset($attrs['list'])) {
1224
- $attrs['lists'] = $attrs['list'];
1225
- }
1226
-
1227
- if (isset($attrs['lists'])) {
1228
- $buffer .= $this->_form_implicit_lists($attrs['lists'], $language);
1229
- }
1230
 
1231
  $buffer .= do_shortcode($content);
1232
 
@@ -1257,16 +1161,18 @@ class NewsletterSubscription extends NewsletterModule {
1257
  * @param string $language ???
1258
  * @return string
1259
  */
1260
- function _form_implicit_lists($lists, $language) {
1261
  $buffer = '';
 
1262
  $arr = explode(',', $lists);
1263
- if (!$arr) return'';
1264
  foreach ($arr as $a) {
1265
  $a = trim($a);
1266
  if (empty($a)) continue;
1267
- $list = $this->get_list($a, $language);
 
1268
  if (!$list) {
1269
- $buffer .= $this->build_field_admin_notice('List ' . $a . ' added in the form is not configured, skipped.');
1270
  continue;
1271
  }
1272
 
@@ -1285,6 +1191,55 @@ class NewsletterSubscription extends NewsletterModule {
1285
  return $buffer;
1286
  }
1287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1288
  /**
1289
  * Internal use only
1290
  *
@@ -1293,8 +1248,7 @@ class NewsletterSubscription extends NewsletterModule {
1293
  * @param type $suffix
1294
  * @return string
1295
  */
1296
- function _shortcode_label($name, $attrs, $suffix = null) {
1297
- //$this->setup_form_options();
1298
 
1299
  if (!$suffix) {
1300
  $suffix = $name;
@@ -1315,11 +1269,18 @@ class NewsletterSubscription extends NewsletterModule {
1315
  return $buffer;
1316
  }
1317
 
 
 
 
 
 
 
 
1318
  function build_field_admin_notice($message) {
1319
  if (!current_user_can('administrator')) {
1320
  return '';
1321
  }
1322
- return '<p style="background-color: #eee; color: #000; padding: 10px; margin: 10px 0">' . $message . ' <strong>This notice is shown only to administrators.</strong></p>';
1323
  }
1324
 
1325
  function shortcode_newsletter_field($attrs, $content = '') {
@@ -1547,16 +1508,6 @@ class NewsletterSubscription extends NewsletterModule {
1547
  }
1548
  }
1549
 
1550
- /**
1551
- * Returns the form html code for subscription.
1552
- *
1553
- * @return string The html code of the subscription form
1554
- * @deprecated since version 6.6.0
1555
- */
1556
- function get_subscription_form_html5($referrer = null, $action = null, $attrs = array()) {
1557
- return $this->get_subscription_form($referrer, $action, $attrs);
1558
- }
1559
-
1560
  /**
1561
  * Builds the privacy field only for completely generated forms.
1562
  *
@@ -1586,51 +1537,30 @@ class NewsletterSubscription extends NewsletterModule {
1586
  return $pre_html . $buffer . $post_html;
1587
  }
1588
 
1589
- /**
1590
- * Creates the hidden alternative optin field on custom form showing notices if used in the wrong
1591
- * way.
1592
- *
1593
- * @since 6.8.3
1594
- * @param string $optin Could be single or double, lowercase
1595
- * @return string The complete HTML field
1596
- */
1597
- function build_optin_field($optin) {
1598
- if (empty($optin)) {
1599
- return '';
1600
- }
1601
-
1602
- if ($optin !== 'double' && $optin !== 'single') {
1603
- return $this->build_field_admin_notice('The optin is set to an invalid value.');
1604
- }
1605
-
1606
- if ($optin !== 'double' && $this->is_double_optin() && empty($this->options['optin_override'])) {
1607
- return $this->build_field_admin_notice('The optin is specified but cannot be overridden (see the subscription configiraton page).');
1608
- }
1609
-
1610
- $b = '<input type="hidden" name="optin" value="' . esc_attr($optin) . '">' . "\n";
1611
-
1612
- return $b;
1613
- }
1614
-
1615
  /**
1616
  * The new standard form.
1617
  *
1618
- * @param type $referrer
1619
- * @param type $action
1620
- * @param type $attrs
1621
- * @return string
1622
  */
1623
- function get_subscription_form($referrer = '', $action = null, $attrs = array()) {
1624
  $language = $this->get_current_language();
1625
  $options_profile = $this->get_options('profile', $language);
 
 
 
 
1626
 
1627
  // Possible alternative form actions (used by...?)
1628
  if (isset($attrs['action'])) {
1629
  $action = $attrs['action'];
1630
  }
1631
 
1632
- if (isset($attrs['referrer'])) {
1633
- $referrer = $attrs['referrer'];
 
1634
  }
1635
 
1636
  $buffer = '';
@@ -1639,36 +1569,19 @@ class NewsletterSubscription extends NewsletterModule {
1639
  $action = $this->build_action_url('s');
1640
  }
1641
 
1642
- if ($referrer != 'widget') {
 
 
1643
  if (isset($attrs['class'])) {
1644
  $buffer .= '<div class="tnp tnp-subscription ' . $attrs['class'] . '">' . "\n";
1645
  } else {
1646
  $buffer .= '<div class="tnp tnp-subscription">' . "\n";
1647
  }
1648
  }
1649
- $buffer .= '<form method="post" action="' . esc_attr($action) . '" onsubmit="return newsletter_check(this)">' . "\n\n";
1650
 
1651
- $buffer .= '<input type="hidden" name="nlang" value="' . esc_attr($language) . '">' . "\n";
1652
 
1653
- if (!empty($attrs['optin'])) {
1654
- $buffer .= $this->build_optin_field($attrs['optin']);
1655
- }
1656
-
1657
- if (!empty($referrer)) {
1658
- $buffer .= '<input type="hidden" name="nr" value="' . esc_attr($referrer) . '">' . "\n";
1659
- }
1660
- if (isset($attrs['confirmation_url'])) {
1661
- $buffer .= "<input type='hidden' name='ncu' value='" . esc_attr($attrs['confirmation_url']) . "'>\n";
1662
- }
1663
-
1664
- // Compatibility
1665
- if (isset($attrs['list'])) {
1666
- $attrs['lists'] = $attrs['list'];
1667
- }
1668
-
1669
- if (isset($attrs['lists'])) {
1670
- $buffer .= $this->_form_implicit_lists($attrs['lists'], $language);
1671
- }
1672
 
1673
  if ($options_profile['name_status'] == 2) {
1674
  $buffer .= $this->shortcode_newsletter_field(['name' => 'first_name']);
@@ -1705,6 +1618,7 @@ class NewsletterSubscription extends NewsletterModule {
1705
  $buffer .= $this->shortcode_newsletter_field(['name' => 'profile', 'number' => $i]);
1706
  }
1707
 
 
1708
  $extra = apply_filters('newsletter_subscription_extra', array());
1709
  foreach ($extra as $x) {
1710
  $label = $x['label'];
@@ -1735,20 +1649,14 @@ class NewsletterSubscription extends NewsletterModule {
1735
  }
1736
 
1737
  $buffer .= "</div>\n</form>\n";
1738
- if ($referrer != 'widget') {
 
 
 
1739
  $buffer .= "</div>\n";
1740
  }
1741
- return $buffer;
1742
- }
1743
 
1744
- /**
1745
- *
1746
- * @deprecated since version 6.0.0
1747
- * @param type $user
1748
- * @return type
1749
- */
1750
- function get_profile_form($user) {
1751
- return NewsletterProfile::instance()->get_profile_form($user);
1752
  }
1753
 
1754
  function get_form($number) {
@@ -1811,7 +1719,6 @@ class NewsletterSubscription extends NewsletterModule {
1811
  */
1812
  function get_subscription_form_minimal($attrs) {
1813
 
1814
- $language = $this->get_current_language();
1815
  $this->setup_form_options();
1816
 
1817
  if (!is_array($attrs)) {
@@ -1828,19 +1735,8 @@ class NewsletterSubscription extends NewsletterModule {
1828
  $form .= '<div class="tnp tnp-subscription-minimal ' . $attrs['class'] . '">';
1829
  $form .= '<form action="' . esc_attr($this->build_action_url('s')) . '" method="post">';
1830
 
1831
- if (isset($attrs['optin'])) {
1832
- $form .= $this->build_optin_field($attrs['optin']);
1833
- }
1834
-
1835
- if (isset($attrs['confirmation_url'])) {
1836
- $form .= "<input type='hidden' name='ncu' value='" . esc_attr($attrs['confirmation_url']) . "'>\n";
1837
- }
1838
 
1839
- if (isset($attrs['lists'])) {
1840
- $form .= $this->_form_implicit_lists($attrs['lists'], $language);
1841
- }
1842
- $form .= '<input type="hidden" name="nr" value="' . esc_attr($attrs['referrer']) . '">';
1843
- $form .= '<input type="hidden" name="nlang" value="' . esc_attr($language) . '">' . "\n";
1844
  $form .= '<input class="tnp-email" type="email" required name="ne" value="" placeholder="' . esc_attr($attrs['placeholder']) . '">';
1845
  $form .= '<input class="tnp-submit" type="submit" value="' . esc_attr($attrs['button']) . '"'
1846
  . ' style="background-color:' . esc_attr($attrs['button_color']) . '">';
@@ -1854,7 +1750,7 @@ class NewsletterSubscription extends NewsletterModule {
1854
 
1855
  function shortcode_newsletter_form($attrs, $content) {
1856
 
1857
- if (isset($attrs['type']) && $attrs['type'] == 'minimal') {
1858
  return $this->get_subscription_form_minimal($attrs);
1859
  }
1860
 
@@ -1906,14 +1802,12 @@ class NewsletterSubscription extends NewsletterModule {
1906
  }
1907
  }
1908
 
1909
-
1910
  // Now check what form must be added
1911
  if ($message_key == 'subscription') {
1912
 
1913
  // Compatibility check
1914
  if (stripos($message, '<form') !== false) {
1915
- $message .= $this->get_form_javascript();
1916
- $message = str_ireplace('<form', '<form method="post" action="' . esc_attr($this->get_subscribe_url()) . '" onsubmit="return newsletter_check(this)"', $message);
1917
  } else {
1918
 
1919
  if (strpos($message, '{subscription_form') === false) {
62
  if (is_admin()) {
63
  add_action('admin_init', array($this, 'hook_admin_init'));
64
  } else {
 
65
  // Shortcode for the Newsletter page
66
  add_shortcode('newsletter', array($this, 'shortcode_newsletter'));
67
  add_shortcode('newsletter_form', array($this, 'shortcode_newsletter_form'));
82
  }
83
  }
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  /**
86
  *
87
  * @global wpdb $wpdb
159
  $this->dienow('Registration failed.', $user->get_error_message(), 400);
160
  }
161
 
162
+ if ($user->status == TNP_User::STATUS_CONFIRMED) {
163
  $this->show_message('confirmed', $user);
164
+ }
165
+ if ($user->status == TNP_User::STATUS_NOT_CONFIRMED) {
166
  $this->show_message('confirmation', $user);
167
+ }
168
  } else {
169
  $this->request_to_antibot_form('Subscribe', $captcha);
170
  }
174
  case 'ajaxsub':
175
 
176
  if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
 
177
  $this->dienow('Invalid request');
178
  }
179
 
285
  }
286
 
287
  function first_install() {
288
+
289
  }
290
 
291
  function admin_menu() {
508
  if ($subscription->spamcheck) {
509
  // TODO: Use autoload
510
  require_once NEWSLETTER_INCLUDES_DIR . '/antispam.php';
511
+ $antispam = NewsletterAntispam::instance();
512
  if ($antispam->is_spam($subscription)) {
513
  return new WP_Error('spam', 'This looks like a spam subscription');
514
  }
970
  $user->status = Newsletter::STATUS_NOT_CONFIRMED;
971
  delete_transient('newsletter_subscription_' . $user->id);
972
  } else {
973
+ $new_email = get_transient('newsletter_user_' . $user->id . '_email');
974
+ if ($new_email) {
975
+ $data = ['id'=>$user->id, 'email'=>$new_email];
976
+ $this->save_user($data);
977
+ delete_transient('newsletter_user_' . $user->id . '_email');
 
 
 
 
 
978
  }
979
  }
980
 
1104
  }
1105
 
1106
  function get_form_javascript() {
1107
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1108
  }
1109
 
1110
  /**
1111
+ * Manages the custom forms made with [newsletter_form] and internal [newsletter_field] shortcodes.
1112
  *
1113
  * @param array $attrs
1114
  * @param string $content
1130
 
1131
  $language = $this->get_current_language();
1132
 
1133
+ $buffer .= $this->get_form_hidden_fields($attrs);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1134
 
1135
  $buffer .= do_shortcode($content);
1136
 
1161
  * @param string $language ???
1162
  * @return string
1163
  */
1164
+ function get_form_implicit_lists($lists, $language = '') {
1165
  $buffer = '';
1166
+
1167
  $arr = explode(',', $lists);
1168
+
1169
  foreach ($arr as $a) {
1170
  $a = trim($a);
1171
  if (empty($a)) continue;
1172
+
1173
+ $list = $this->get_list($a);
1174
  if (!$list) {
1175
+ $buffer .= $this->build_field_admin_notice('List "' . $a . '" added to the form is not configured, skipped.');
1176
  continue;
1177
  }
1178
 
1191
  return $buffer;
1192
  }
1193
 
1194
+ /**
1195
+ * Builds all the hidden fields of a subscription form. Implicit lists, confirmation url,
1196
+ * referrer, language, ...
1197
+ *
1198
+ * @param array $attrs Attributes of form shortcode
1199
+ * @return string HTML with the hidden fields
1200
+ */
1201
+ function get_form_hidden_fields($attrs) {
1202
+ $b = '';
1203
+
1204
+ // Compatibility
1205
+ if (isset($attrs['list'])) {
1206
+ $attrs['lists'] = $attrs['list'];
1207
+ }
1208
+ if (isset($attrs['lists'])) {
1209
+ $b .= $this->get_form_implicit_lists($attrs['lists']);
1210
+ }
1211
+
1212
+ if (isset($attrs['referrer'])) {
1213
+ $b .= '<input type="hidden" name="nr" value="' . esc_attr($attrs['referrer']) . '">';
1214
+ }
1215
+
1216
+ if (isset($attrs['confirmation_url'])) {
1217
+ if ($attrs['confirmation_url'] === '#') {
1218
+ $attrs['confirmation_url'] = $_SERVER['REQUEST_URI'];
1219
+ }
1220
+
1221
+ $b .= '<input type="hidden" name="ncu" value="' . esc_attr($attrs['confirmation_url']) . '">';
1222
+ }
1223
+
1224
+ if (isset($attrs['optin'])) {
1225
+ $optin = trim(strtolower($attrs['optin']));
1226
+ if ($optin !== 'double' && $optin !== 'single') {
1227
+ $b .= $this->build_field_admin_notice('The optin is set to an invalid value.');
1228
+ } else {
1229
+ if ($optin !== 'double' && $this->is_double_optin() && empty($this->options['optin_override'])) {
1230
+ $b .= $this->build_field_admin_notice('The optin is specified but cannot be overridden (see the subscription configiraton page).');
1231
+ } else {
1232
+ $b .= '<input type="hidden" name="optin" value="' . esc_attr($optin) . '">';
1233
+ }
1234
+ }
1235
+ }
1236
+
1237
+ $language = $this->get_current_language();
1238
+ $b .= '<input type="hidden" name="nlang" value="' . esc_attr($language) . '">';
1239
+
1240
+ return $b;
1241
+ }
1242
+
1243
  /**
1244
  * Internal use only
1245
  *
1248
  * @param type $suffix
1249
  * @return string
1250
  */
1251
+ private function _shortcode_label($name, $attrs, $suffix = null) {
 
1252
 
1253
  if (!$suffix) {
1254
  $suffix = $name;
1269
  return $buffer;
1270
  }
1271
 
1272
+ /**
1273
+ * Creates a notices to be displayed near a subscription form field to inform of worng configurations.
1274
+ * It is created only if the current user looking at the form is the administrator.
1275
+ *
1276
+ * @param string $message
1277
+ * @return string
1278
+ */
1279
  function build_field_admin_notice($message) {
1280
  if (!current_user_can('administrator')) {
1281
  return '';
1282
  }
1283
+ return '<p style="background-color: #eee; color: #000; padding: 10px; margin: 10px 0">' . $message . ' <strong>This notice is shown only to administrators to help with configuration.</strong></p>';
1284
  }
1285
 
1286
  function shortcode_newsletter_field($attrs, $content = '') {
1508
  }
1509
  }
1510
 
 
 
 
 
 
 
 
 
 
 
1511
  /**
1512
  * Builds the privacy field only for completely generated forms.
1513
  *
1537
  return $pre_html . $buffer . $post_html;
1538
  }
1539
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1540
  /**
1541
  * The new standard form.
1542
  *
1543
+ * @param string $referrer Deprecated since 6.9.1, use the "referrer" key on $attrs
1544
+ * @param string $action
1545
+ * @param string $attrs
1546
+ * @return string The full HTML form
1547
  */
1548
+ function get_subscription_form($referrer = '', $action = null, $attrs = []) {
1549
  $language = $this->get_current_language();
1550
  $options_profile = $this->get_options('profile', $language);
1551
+
1552
+ if (!is_array($attrs)) {
1553
+ $attrs = [];
1554
+ }
1555
 
1556
  // Possible alternative form actions (used by...?)
1557
  if (isset($attrs['action'])) {
1558
  $action = $attrs['action'];
1559
  }
1560
 
1561
+ // The referrer parameter is deprecated
1562
+ if (!empty($referrer)) {
1563
+ $attrs['referrer'] = $referrer;
1564
  }
1565
 
1566
  $buffer = '';
1569
  $action = $this->build_action_url('s');
1570
  }
1571
 
1572
+ if (isset($attrs['before'])) {
1573
+ $buffer .= $attrs['before'];
1574
+ } else {
1575
  if (isset($attrs['class'])) {
1576
  $buffer .= '<div class="tnp tnp-subscription ' . $attrs['class'] . '">' . "\n";
1577
  } else {
1578
  $buffer .= '<div class="tnp tnp-subscription">' . "\n";
1579
  }
1580
  }
 
1581
 
1582
+ $buffer .= '<form method="post" action="' . esc_attr($action) . '">' . "\n\n";
1583
 
1584
+ $buffer .= $this->get_form_hidden_fields($attrs);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1585
 
1586
  if ($options_profile['name_status'] == 2) {
1587
  $buffer .= $this->shortcode_newsletter_field(['name' => 'first_name']);
1618
  $buffer .= $this->shortcode_newsletter_field(['name' => 'profile', 'number' => $i]);
1619
  }
1620
 
1621
+ // Deprecated
1622
  $extra = apply_filters('newsletter_subscription_extra', array());
1623
  foreach ($extra as $x) {
1624
  $label = $x['label'];
1649
  }
1650
 
1651
  $buffer .= "</div>\n</form>\n";
1652
+
1653
+ if (isset($attrs['after'])) {
1654
+ $buffer .= $attrs['after'];
1655
+ } else {
1656
  $buffer .= "</div>\n";
1657
  }
 
 
1658
 
1659
+ return $buffer;
 
 
 
 
 
 
 
1660
  }
1661
 
1662
  function get_form($number) {
1719
  */
1720
  function get_subscription_form_minimal($attrs) {
1721
 
 
1722
  $this->setup_form_options();
1723
 
1724
  if (!is_array($attrs)) {
1735
  $form .= '<div class="tnp tnp-subscription-minimal ' . $attrs['class'] . '">';
1736
  $form .= '<form action="' . esc_attr($this->build_action_url('s')) . '" method="post">';
1737
 
1738
+ $form .= $this->get_form_hidden_fields($attrs);
 
 
 
 
 
 
1739
 
 
 
 
 
 
1740
  $form .= '<input class="tnp-email" type="email" required name="ne" value="" placeholder="' . esc_attr($attrs['placeholder']) . '">';
1741
  $form .= '<input class="tnp-submit" type="submit" value="' . esc_attr($attrs['button']) . '"'
1742
  . ' style="background-color:' . esc_attr($attrs['button_color']) . '">';
1750
 
1751
  function shortcode_newsletter_form($attrs, $content) {
1752
 
1753
+ if (isset($attrs['type']) && $attrs['type'] === 'minimal') {
1754
  return $this->get_subscription_form_minimal($attrs);
1755
  }
1756
 
1802
  }
1803
  }
1804
 
 
1805
  // Now check what form must be added
1806
  if ($message_key == 'subscription') {
1807
 
1808
  // Compatibility check
1809
  if (stripos($message, '<form') !== false) {
1810
+ $message = str_ireplace('<form', '<form method="post" action="' . esc_attr($this->get_subscribe_url()) . '"', $message);
 
1811
  } else {
1812
 
1813
  if (strpos($message, '{subscription_form') === false) {
subscription/validate.js DELETED
@@ -1,31 +0,0 @@
1
- function newsletter_check_field(field, message) {
2
- if (!field) return true;
3
- if (field.type == "checkbox" && !field.checked) {
4
- alert(message);
5
- return false;
6
- }
7
-
8
- if (field.required !== undefined && field.required !== false && field.value == "") {
9
- alert(message);
10
- return false;
11
- }
12
- return true;
13
- }
14
-
15
- function newsletter_check(f) {
16
- var re = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-]{1,})+\.)+([a-zA-Z0-9]{2,})+$/;
17
- if (!re.test(f.elements["ne"].value)) {
18
- alert(newsletter.messages.email_error);
19
- return false;
20
- }
21
- if (!newsletter_check_field(f.elements["nn"], newsletter.messages.name_error)) return false;
22
- if (!newsletter_check_field(f.elements["ns"], newsletter.messages.surname_error)) return false;
23
-
24
- for (var i=1; i<newsletter.profile_max; i++) {
25
- if (!newsletter_check_field(f.elements["np" + i], newsletter.messages.profile_error)) return false;
26
- }
27
-
28
- if (!newsletter_check_field(f.elements["ny"], newsletter.messages.privacy_error)) return false;
29
-
30
- return true;
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
unsubscription/unsubscription.php CHANGED
@@ -30,7 +30,7 @@ class NewsletterUnsubscription extends NewsletterModule {
30
 
31
  if (in_array($action, ['u', 'uc', 'lu', 'reactivate'])) {
32
  if (!$user) {
33
- $this->dienow('The subscriber was not found.', '', 404);
34
  }
35
  }
36
 
@@ -87,8 +87,6 @@ class NewsletterUnsubscription extends NewsletterModule {
87
 
88
  do_action('newsletter_user_unsubscribed', $user);
89
 
90
-
91
-
92
  if ($email) {
93
  $wpdb->update(NEWSLETTER_USERS_TABLE, array('unsub_email_id' => (int) $email->id, 'unsub_time' => time()), array('id' => $user->id));
94
  }
@@ -182,10 +180,6 @@ class NewsletterUnsubscription extends NewsletterModule {
182
  return $text;
183
  }
184
 
185
- function upgrade() {
186
- parent::upgrade();
187
- }
188
-
189
  function admin_menu() {
190
  $this->add_admin_page('index', 'Unsubscribe');
191
  }
30
 
31
  if (in_array($action, ['u', 'uc', 'lu', 'reactivate'])) {
32
  if (!$user) {
33
+ $this->dienow(__('Subscriber not found', 'newsletter'), 'Already deleted or using the wrong subscriber key in the URL', 404);
34
  }
35
  }
36
 
87
 
88
  do_action('newsletter_user_unsubscribed', $user);
89
 
 
 
90
  if ($email) {
91
  $wpdb->update(NEWSLETTER_USERS_TABLE, array('unsub_email_id' => (int) $email->id, 'unsub_time' => time()), array('id' => $user->id));
92
  }
180
  return $text;
181
  }
182
 
 
 
 
 
183
  function admin_menu() {
184
  $this->add_admin_page('index', 'Unsubscribe');
185
  }
widget/minimal.php CHANGED
@@ -36,7 +36,7 @@ class NewsletterWidgetMinimal extends WP_Widget {
36
  }
37
 
38
  $form = '<div class="tnp tnp-widget-minimal">';
39
- $form .= '<form class="tnp-form" action="' . $newsletter->build_action_url('s') . '" method="post" onsubmit="return newsletter_check(this)">';
40
  if (isset($instance['nl']) && is_array($instance['nl'])) {
41
  foreach ($instance['nl'] as $a) {
42
  $form .= "<input type='hidden' name='nl[]' value='" . ((int) trim($a)) . "'>\n";
36
  }
37
 
38
  $form = '<div class="tnp tnp-widget-minimal">';
39
+ $form .= '<form class="tnp-form" action="' . $newsletter->build_action_url('s') . '" method="post">';
40
  if (isset($instance['nl']) && is_array($instance['nl'])) {
41
  foreach ($instance['nl'] as $a) {
42
  $form .= "<input type='hidden' name='nl[]' value='" . ((int) trim($a)) . "'>\n";
widget/standard.php CHANGED
@@ -27,14 +27,15 @@ class NewsletterWidget extends WP_Widget {
27
  $options_profile = get_option('newsletter_profile');
28
  $form = '';
29
 
30
- $form .= '<div class="tnp tnp-widget">';
31
  $form .= NewsletterSubscription::instance()->get_subscription_form('widget', null, array(
 
 
 
32
  'list' => implode(',', $instance['nl']),
33
  'lists_field_layout' => $instance['lists_layout'],
34
  'lists_field_empty_label' => $instance['lists_empty_label'],
35
  'lists_field_label' => $instance['lists_field_label'],
36
  ));
37
- $form .= "</div>\n";
38
 
39
  return $form;
40
  }
@@ -77,7 +78,7 @@ class NewsletterWidget extends WP_Widget {
77
  }
78
  }
79
  } else {
80
- $buffer = str_ireplace('<form', '<form method="post" action="' . esc_attr($newsletter->get_subscribe_url()) . '" onsubmit="return newsletter_check(this)"', $buffer);
81
  $buffer = str_ireplace('</form>', '<input type="hidden" name="nr" value="widget"/></form>', $buffer);
82
  }
83
 
27
  $options_profile = get_option('newsletter_profile');
28
  $form = '';
29
 
 
30
  $form .= NewsletterSubscription::instance()->get_subscription_form('widget', null, array(
31
+ 'referrer'=>'widget',
32
+ 'before'=>'<div class="tnp tnp-widget">',
33
+ 'after'=>'</div>',
34
  'list' => implode(',', $instance['nl']),
35
  'lists_field_layout' => $instance['lists_layout'],
36
  'lists_field_empty_label' => $instance['lists_empty_label'],
37
  'lists_field_label' => $instance['lists_field_label'],
38
  ));
 
39
 
40
  return $form;
41
  }
78
  }
79
  }
80
  } else {
81
+ $buffer = str_ireplace('<form', '<form method="post" action="' . esc_attr($newsletter->get_subscribe_url()) . '"', $buffer);
82
  $buffer = str_ireplace('</form>', '<input type="hidden" name="nr" value="widget"/></form>', $buffer);
83
  }
84