Newsletter - Version 5.9.0

Version Description

  • Fixes on privacy setting with multilanguage plugins
  • Added per language statistics on subscribers statistics panel
  • Added language set action on subscribers maintenance panel
  • Separated the pre confirm and post confirm tokens
Download this release

Release Info

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

Code changes from version 5.8.9 to 5.9.0

includes/controls.php CHANGED
@@ -1477,7 +1477,7 @@ class NewsletterControls {
1477
  echo $output;
1478
  }
1479
 
1480
- function language($name = 'language') {
1481
  if (!class_exists('SitePress') && !function_exists('pll_default_language') && !class_exists('TRP_Translate_Press')) {
1482
  echo __('Install a multilanguage plugin.', 'newsletter');
1483
  echo ' <a href="https://www.thenewsletterplugin.com/documentation/multilanguage" target="_blank">', __('Read more', 'newsletter'), '</a>';
@@ -1485,8 +1485,9 @@ class NewsletterControls {
1485
  }
1486
 
1487
  $languages = Newsletter::instance()->get_languages();
1488
- $languages = array_merge(array('' => 'All'), $languages);
1489
-
 
1490
  $this->select($name, $languages);
1491
  }
1492
 
1477
  echo $output;
1478
  }
1479
 
1480
+ function language($name = 'language', $empty_label='All') {
1481
  if (!class_exists('SitePress') && !function_exists('pll_default_language') && !class_exists('TRP_Translate_Press')) {
1482
  echo __('Install a multilanguage plugin.', 'newsletter');
1483
  echo ' <a href="https://www.thenewsletterplugin.com/documentation/multilanguage" target="_blank">', __('Read more', 'newsletter'), '</a>';
1485
  }
1486
 
1487
  $languages = Newsletter::instance()->get_languages();
1488
+ if (!empty($empty_label)) {
1489
+ $languages = array_merge(array('' => $empty_label), $languages);
1490
+ }
1491
  $this->select($name, $languages);
1492
  }
1493
 
includes/module.php CHANGED
@@ -65,16 +65,19 @@ abstract class TNP_Email {
65
  * @property string $id Theme identifier
66
  * @property string $dir Absolute path to the theme folder
67
  * @property string $name Theme name
68
- **/
69
  class TNP_Theme {
 
70
  var $dir;
71
  var $name;
72
-
73
  public function get_defaults() {
74
  @include $this->dir . '/theme-defaults.php';
75
- if (!isset($theme_defaults) || !is_array($theme_defaults)) return array();
 
76
  return $theme_defaults;
77
  }
 
78
  }
79
 
80
  class NewsletterModule {
@@ -668,7 +671,7 @@ class NewsletterModule {
668
  $newsletter = Newsletter::instance();
669
  $capability = ($newsletter->options['editor'] == 1) ? 'manage_categories' : 'manage_options';
670
  }
671
-
672
  $name = 'newsletter_' . $this->module . '_' . $page;
673
  $name = apply_filters('newsletter_admin_page', $name);
674
  add_submenu_page(null, $title, $title, $capability, $name, array($this, 'menu_page'));
@@ -883,7 +886,7 @@ class NewsletterModule {
883
  *
884
  * @return TNP_User
885
  */
886
- function check_user() {
887
  global $wpdb;
888
 
889
  $user = null;
@@ -896,8 +899,14 @@ class NewsletterModule {
896
 
897
  if (isset($id)) {
898
  $user = $this->get_user($id);
899
- if ($token != $user->token) {
900
- $user = null;
 
 
 
 
 
 
901
  }
902
  }
903
 
@@ -948,7 +957,10 @@ class NewsletterModule {
948
  * @param TNP_User $user
949
  * @return string
950
  */
951
- function get_user_key($user) {
 
 
 
952
  return $user->id . '-' . $user->token;
953
  }
954
 
@@ -960,14 +972,19 @@ class NewsletterModule {
960
  * @param bool $die_on_fail
961
  * @return TNP_User
962
  */
963
- function get_user_from_request($die_on_fail = false) {
964
  $id = 0;
965
  if (isset($_REQUEST['nk'])) {
966
  list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
967
  }
968
  $user = $this->get_user($id);
969
 
970
- if ($user == null || $token != $user->token) {
 
 
 
 
 
971
  if ($die_on_fail) {
972
  die(__('No subscriber found.', 'newsletter'));
973
  } else {
@@ -976,7 +993,7 @@ class NewsletterModule {
976
  }
977
  return $user;
978
  }
979
-
980
  /**
981
  * @param string $language The language for the list labels (it does not affect the lists returned)
982
  * @return TNP_Profile[]
@@ -1156,7 +1173,7 @@ class NewsletterModule {
1156
  global $wpdb;
1157
  $this->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set last_activity=%d where id=%d limit 1", time(), $user->id));
1158
  }
1159
-
1160
  function update_user_ip($user, $ip) {
1161
  global $wpdb;
1162
  // Only if changed
@@ -1241,7 +1258,12 @@ class NewsletterModule {
1241
  if (!is_object($user)) {
1242
  $user = $this->get_user($user);
1243
  }
1244
- $params .= '&nk=' . urlencode($this->get_user_key($user));
 
 
 
 
 
1245
  $language = $this->get_user_language($user);
1246
  }
1247
 
@@ -1820,7 +1842,7 @@ class NewsletterModule {
1820
  if (function_exists('pll_current_language')) {
1821
  return pll_current_language();
1822
  }
1823
-
1824
  $current_language = apply_filters('newsletter_current_language', '');
1825
 
1826
  return $current_language;
@@ -1864,7 +1886,7 @@ class NewsletterModule {
1864
  $language_options[$code] = $language['native_name'];
1865
  }
1866
  return $language_options;
1867
- }
1868
 
1869
  return apply_filters('newsletter_languages', $language_options);
1870
  }
65
  * @property string $id Theme identifier
66
  * @property string $dir Absolute path to the theme folder
67
  * @property string $name Theme name
68
+ * */
69
  class TNP_Theme {
70
+
71
  var $dir;
72
  var $name;
73
+
74
  public function get_defaults() {
75
  @include $this->dir . '/theme-defaults.php';
76
+ if (!isset($theme_defaults) || !is_array($theme_defaults))
77
+ return array();
78
  return $theme_defaults;
79
  }
80
+
81
  }
82
 
83
  class NewsletterModule {
671
  $newsletter = Newsletter::instance();
672
  $capability = ($newsletter->options['editor'] == 1) ? 'manage_categories' : 'manage_options';
673
  }
674
+
675
  $name = 'newsletter_' . $this->module . '_' . $page;
676
  $name = apply_filters('newsletter_admin_page', $name);
677
  add_submenu_page(null, $title, $title, $capability, $name, array($this, 'menu_page'));
886
  *
887
  * @return TNP_User
888
  */
889
+ function check_user($context = '') {
890
  global $wpdb;
891
 
892
  $user = null;
899
 
900
  if (isset($id)) {
901
  $user = $this->get_user($id);
902
+ if ($context == 'preconfirm') {
903
+ if ($token != md5($user->token)) {
904
+ $user = null;
905
+ }
906
+ } else {
907
+ if ($token != $user->token) {
908
+ $user = null;
909
+ }
910
  }
911
  }
912
 
957
  * @param TNP_User $user
958
  * @return string
959
  */
960
+ function get_user_key($user, $context = '') {
961
+ if ($context == 'preconfirm') {
962
+ return $user->id . '-' . md5($user->token);
963
+ }
964
  return $user->id . '-' . $user->token;
965
  }
966
 
972
  * @param bool $die_on_fail
973
  * @return TNP_User
974
  */
975
+ function get_user_from_request($die_on_fail = false, $context = '') {
976
  $id = 0;
977
  if (isset($_REQUEST['nk'])) {
978
  list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
979
  }
980
  $user = $this->get_user($id);
981
 
982
+ if ($context == 'preconfirm') {
983
+ $user_token = md5($user->token);
984
+ } else {
985
+ $user_token = $user->token;
986
+ }
987
+ if ($user == null || $token != $user_token) {
988
  if ($die_on_fail) {
989
  die(__('No subscriber found.', 'newsletter'));
990
  } else {
993
  }
994
  return $user;
995
  }
996
+
997
  /**
998
  * @param string $language The language for the list labels (it does not affect the lists returned)
999
  * @return TNP_Profile[]
1173
  global $wpdb;
1174
  $this->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set last_activity=%d where id=%d limit 1", time(), $user->id));
1175
  }
1176
+
1177
  function update_user_ip($user, $ip) {
1178
  global $wpdb;
1179
  // Only if changed
1258
  if (!is_object($user)) {
1259
  $user = $this->get_user($user);
1260
  }
1261
+ if ($message_key == 'confirmation') {
1262
+ $params .= '&nk=' . urlencode($this->get_user_key($user, 'preconfirm'));
1263
+ } else {
1264
+ $params .= '&nk=' . urlencode($this->get_user_key($user));
1265
+ }
1266
+
1267
  $language = $this->get_user_language($user);
1268
  }
1269
 
1842
  if (function_exists('pll_current_language')) {
1843
  return pll_current_language();
1844
  }
1845
+
1846
  $current_language = apply_filters('newsletter_current_language', '');
1847
 
1848
  return $current_language;
1886
  $language_options[$code] = $language['native_name'];
1887
  }
1888
  return $language_options;
1889
+ }
1890
 
1891
  return apply_filters('newsletter_languages', $language_options);
1892
  }
main/status.php CHANGED
@@ -694,7 +694,7 @@ $speed = Newsletter::$instance->options['scheduler_max'];
694
  </td>
695
  <td>
696
  <?php if (!$res) { ?>
697
- The blog is not responding to Newsletter URLs: ask the provider or your IT consultant to check this problem. Report the URL and error blow<br>
698
  Error: <?php echo esc_html($message) ?><br>
699
  <?php } else { ?>
700
 
694
  </td>
695
  <td>
696
  <?php if (!$res) { ?>
697
+ The blog is not responding to Newsletter URLs: ask the provider or your IT consultant to check this problem. Report the URL and error below<br>
698
  Error: <?php echo esc_html($message) ?><br>
699
  <?php } else { ?>
700
 
plugin.php CHANGED
@@ -4,14 +4,14 @@
4
  Plugin Name: Newsletter
5
  Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
6
  Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
7
- Version: 5.8.9
8
  Author: Stefano Lissa & The Newsletter Team
9
  Author URI: https://www.thenewsletterplugin.com
10
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
11
  Text Domain: newsletter
12
  License: GPLv2 or later
13
 
14
- Copyright 2009-2018 The Newsletter Team (email: info@thenewsletterplugin.com, web: https://www.thenewsletterplugin.com)
15
 
16
  Newsletter is free software: you can redistribute it and/or modify
17
  it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@
29
  */
30
 
31
  // Used as dummy parameter on css and js links
32
- define('NEWSLETTER_VERSION', '5.8.9');
33
 
34
  global $newsletter, $wpdb;
35
 
4
  Plugin Name: Newsletter
5
  Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
6
  Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
7
+ Version: 5.9.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.
11
  Text Domain: newsletter
12
  License: GPLv2 or later
13
 
14
+ Copyright 2009-2019 The Newsletter Team (email: info@thenewsletterplugin.com, web: https://www.thenewsletterplugin.com)
15
 
16
  Newsletter is free software: you can redistribute it and/or modify
17
  it under the terms of the GNU General Public License as published by
29
  */
30
 
31
  // Used as dummy parameter on css and js links
32
+ define('NEWSLETTER_VERSION', '5.9.0');
33
 
34
  global $newsletter, $wpdb;
35
 
readme.txt CHANGED
@@ -1,7 +1,7 @@
1
  === Newsletter ===
2
  Tags: newsletter,email,subscription,mass mail,list build,email marketing,direct mailing,automation,automated,mailing list
3
  Requires at least: 3.4.0
4
- Tested up to: 5.0.3
5
  Stable tag: 5.8.9
6
  Contributors: satollo,webagile,michael-travan
7
 
@@ -122,13 +122,20 @@ Thank you, The Newsletter Team
122
 
123
  == Changelog ==
124
 
 
 
 
 
 
 
 
125
  = 5.8.9 =
126
 
127
  * Global constant to block the media resizing
128
  * Resized thumbnails folder changed to the uploads folder (newsletter/thumbnails subfolder)
129
  * Fall back on first post gallery image if the featured image is missing
130
  * Patch to block third party plugins visual editor injection in out pages
131
- * Fix media selector button on visual composer
132
 
133
  = 5.8.8 =
134
 
1
  === Newsletter ===
2
  Tags: newsletter,email,subscription,mass mail,list build,email marketing,direct mailing,automation,automated,mailing list
3
  Requires at least: 3.4.0
4
+ Tested up to: 5.1
5
  Stable tag: 5.8.9
6
  Contributors: satollo,webagile,michael-travan
7
 
122
 
123
  == Changelog ==
124
 
125
+ = 5.9.0 =
126
+
127
+ * Fixes on privacy setting with multilanguage plugins
128
+ * Added per language statistics on subscribers statistics panel
129
+ * Added language set action on subscribers maintenance panel
130
+ * Separated the pre confirm and post confirm tokens
131
+
132
  = 5.8.9 =
133
 
134
  * Global constant to block the media resizing
135
  * Resized thumbnails folder changed to the uploads folder (newsletter/thumbnails subfolder)
136
  * Fall back on first post gallery image if the featured image is missing
137
  * Patch to block third party plugins visual editor injection in out pages
138
+ * Fix media selector button on visual composer
139
 
140
  = 5.8.8 =
141
 
subscription/page.php CHANGED
@@ -15,8 +15,12 @@
15
  if (!defined('ABSPATH')) exit;
16
 
17
  $module = NewsletterSubscription::instance();
18
- $user = $module->get_user_from_request(true);
19
  $message_key = $module->get_message_key_from_request();
 
 
 
 
 
20
  $message = apply_filters('newsletter_page_text', '', $message_key, $user);
21
  $options = $module->get_options('', $module->get_user_language($user));
22
  if (!$message) {
15
  if (!defined('ABSPATH')) exit;
16
 
17
  $module = NewsletterSubscription::instance();
 
18
  $message_key = $module->get_message_key_from_request();
19
+ if ($message_key == 'confirmation') {
20
+ $user = $module->get_user_from_request(true, 'preconfirm');
21
+ } else {
22
+ $user = $module->get_user_from_request(true);
23
+ }
24
  $message = apply_filters('newsletter_page_text', '', $message_key, $user);
25
  $options = $module->get_options('', $module->get_user_language($user));
26
  if (!$message) {
subscription/profile.php CHANGED
@@ -155,16 +155,29 @@ $rules = array(0 => __('Optional', 'newsletter'), 1 => __('Required', 'newslette
155
  <tr><th>Enabled?</th><td><?php $controls->select('privacy_status', array(0 => 'No', 1 => 'Yes', 2 => 'Only the notice')); ?></td></tr>
156
  <?php } ?>
157
  <tr><th>Label</th><td><?php $controls->text('privacy', 50); ?></td></tr>
158
- <tr><th>Privacy URL</th><td>
159
- <?php if (function_exists('get_privacy_policy_url') && get_privacy_policy_url()) { ?>
160
- <?php $controls->checkbox('privacy_use_wp_url', __('Use WordPress privacy URL', 'newsletter')); ?>
161
- (<a href="<?php echo esc_attr(get_privacy_policy_url()) ?>"><?php echo esc_html(get_privacy_policy_url()) ?></a>)
162
- <br>OR<br>
 
 
 
 
 
 
 
 
 
 
 
 
163
  <?php } ?>
164
-
165
- <?php $controls->text_url('privacy_url', 50); ?>
166
- </td></tr>
167
- <tr><th>Error message</th><td><?php $controls->text('privacy_error', 50); ?></td></tr>
 
168
  </table>
169
  <p class="description">
170
  The privacy acceptance checkbox (required in many Europen countries) force the subscriber to
155
  <tr><th>Enabled?</th><td><?php $controls->select('privacy_status', array(0 => 'No', 1 => 'Yes', 2 => 'Only the notice')); ?></td></tr>
156
  <?php } ?>
157
  <tr><th>Label</th><td><?php $controls->text('privacy', 50); ?></td></tr>
158
+ <tr>
159
+ <th>Privacy URL</th>
160
+ <td>
161
+ <?php if (!$is_all_languages && !empty($controls->data['privacy_use_wp_url'])) { ?>
162
+ The "all language" setting is set to use the WordPress default privacy page. Please translate that page.
163
+ <?php } else { ?>
164
+ <?php if ($is_all_languages) { ?>
165
+ <?php if (function_exists('get_privacy_policy_url') && get_privacy_policy_url()) { ?>
166
+ <?php $controls->checkbox('privacy_use_wp_url', __('Use WordPress privacy URL', 'newsletter')); ?>
167
+ (<a href="<?php echo esc_attr(get_privacy_policy_url()) ?>"><?php echo esc_html(get_privacy_policy_url()) ?></a>)
168
+ <br>OR<br>
169
+ <?php } ?>
170
+ <?php } ?>
171
+ <?php if (!$is_all_languages) { ?>
172
+ To use the WordPress privacy page, switch to "all language" and activate it.<br>
173
+ <?php } ?>
174
+ <?php $controls->text_url('privacy_url', 50); ?>
175
  <?php } ?>
176
+ </td>
177
+ </tr>
178
+ <tr>
179
+ <th>Error message</th>
180
+ <td><?php $controls->text('privacy_error', 50); ?></td></tr>
181
  </table>
182
  <p class="description">
183
  The privacy acceptance checkbox (required in many Europen countries) force the subscriber to
subscription/subscription.php CHANGED
@@ -1686,8 +1686,12 @@ class NewsletterSubscription extends NewsletterModule {
1686
  function shortcode_newsletter($attrs, $content) {
1687
  global $wpdb;
1688
 
1689
- $user = $this->get_user_from_request();
1690
  $message_key = $this->get_message_key_from_request();
 
 
 
 
 
1691
 
1692
  $message = apply_filters('newsletter_page_text', '', $message_key, $user);
1693
 
1686
  function shortcode_newsletter($attrs, $content) {
1687
  global $wpdb;
1688
 
 
1689
  $message_key = $this->get_message_key_from_request();
1690
+ if ($message_key == 'confirmation') {
1691
+ $user = $this->get_user_from_request(false, 'preconfirm');
1692
+ } else {
1693
+ $user = $this->get_user_from_request();
1694
+ }
1695
 
1696
  $message = apply_filters('newsletter_page_text', '', $message_key, $user);
1697
 
users/massive.php CHANGED
@@ -56,6 +56,11 @@ if ($controls->is_action('list_delete')) {
56
  $controls->messages = $count . ' ' . __('deleted', 'newsletter');
57
  }
58
 
 
 
 
 
 
59
  if ($controls->is_action('list_manage')) {
60
  if ($controls->data['list_action'] == 'move') {
61
  $wpdb->query("update " . NEWSLETTER_USERS_TABLE . ' set list_' . ((int) $controls->data['list_1']) . '=0, list_' . ((int) $controls->data['list_2']) . '=1' .
@@ -261,6 +266,19 @@ if ($controls->is_action('bounces')) {
261
  <?php $controls->button_confirm('update_inactive', __('Update', 'newsletter')); ?>
262
  </td>
263
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  </table>
265
 
266
 
@@ -294,6 +312,8 @@ if ($controls->is_action('bounces')) {
294
  <?php $controls->lists_select('list_3') ?> <?php _e('subscribers without a list', 'newsletter') ?> <?php $controls->button_confirm('list_none', '&raquo;'); ?>
295
  </td>
296
  </tr>
 
 
297
 
298
  </table>
299
  </div>
56
  $controls->messages = $count . ' ' . __('deleted', 'newsletter');
57
  }
58
 
59
+ if ($controls->is_action('language')) {
60
+ $count = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set language=%s where language=''", $controls->data['language']));
61
+ $controls->add_message_done();
62
+ }
63
+
64
  if ($controls->is_action('list_manage')) {
65
  if ($controls->data['list_action'] == 'move') {
66
  $wpdb->query("update " . NEWSLETTER_USERS_TABLE . ' set list_' . ((int) $controls->data['list_1']) . '=0, list_' . ((int) $controls->data['list_2']) . '=1' .
266
  <?php $controls->button_confirm('update_inactive', __('Update', 'newsletter')); ?>
267
  </td>
268
  </tr>
269
+
270
+ <?php if ($module->is_multilanguage()) { ?>
271
+ <tr>
272
+ <td>Language</td>
273
+ <td>
274
+ <?php _e('Set to', 'newsletter') ?>
275
+ <?php $controls->language('language', false) ?> <?php _e('subscribers without a language', 'newsletter') ?>
276
+ </td>
277
+ <td>
278
+ <?php $controls->button_confirm('language', '&raquo;'); ?>
279
+ </td>
280
+ </tr>
281
+ <?php } ?>
282
  </table>
283
 
284
 
312
  <?php $controls->lists_select('list_3') ?> <?php _e('subscribers without a list', 'newsletter') ?> <?php $controls->button_confirm('list_none', '&raquo;'); ?>
313
  </td>
314
  </tr>
315
+
316
+
317
 
318
  </table>
319
  </div>
users/statistics.php CHANGED
@@ -88,6 +88,36 @@ $controls = new NewsletterControls();
88
  </tr>
89
  </tbody>
90
  </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
  </div>
93
 
88
  </tr>
89
  </tbody>
90
  </table>
91
+
92
+ <?php if ($module->is_multilanguage()) { ?>
93
+ <h3>By language</h3>
94
+ <?php $languages = $module->get_languages(); ?>
95
+
96
+ <table class="widefat" style="width: auto">
97
+ <thead>
98
+ <tr>
99
+ <th><?php _e('Status', 'newsletter') ?></th>
100
+ <th><?php _e('Total', 'newsletter') ?></th>
101
+ </tr>
102
+ <tbody>
103
+ <?php foreach ($languages as $code=>$label) { ?>
104
+ <tr>
105
+ <td><?php echo esc_html($label) ?></td>
106
+ <td>
107
+ <?php echo $wpdb->get_var($wpdb->prepare("select count(*) from " . NEWSLETTER_USERS_TABLE . " where language=%s", $code)); ?>
108
+ </td>
109
+ </tr>
110
+ <?php } ?>
111
+ <tr>
112
+ <td><?php _e('Without language', 'newsletter') ?></td>
113
+ <td>
114
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where language=''"); ?>
115
+ </td>
116
+ </tr>
117
+ </thead>
118
+ </tbody>
119
+ </table>
120
+ <?php } ?>
121
 
122
  </div>
123
 
users/users.php CHANGED
@@ -19,7 +19,7 @@ class NewsletterUsers extends NewsletterModule {
19
  }
20
 
21
  function __construct() {
22
- parent::__construct('users', '1.2.9');
23
  add_action('init', array($this, 'hook_init'));
24
  }
25
 
19
  }
20
 
21
  function __construct() {
22
+ parent::__construct('users', '1.3.0');
23
  add_action('init', array($this, 'hook_init'));
24
  }
25