Newsletter - Version 5.4.3

Version Description

  • Improved the profile editing page and the email change check with activation id in double opt-in mode
  • New profile editing panel configuration
  • Privacy notice optionally even on profile panel
  • New list change logging with source
  • Removed old tabled-layout on profile editing page
  • Clean up procedure for statistics and logs tables
  • Removed old widget layout
  • New options on list management panel
  • Forced lists option removed from the subscription panel
  • Dedicated page moved to main settings panel
  • Tracking default value on main settings panel
  • Removed old translations
  • Added default option files
  • Service message template no more on PHP file, the configurable template must be used
  • Reactivation after cancellation feature
  • Revised and simplified all texts for easy translation by the community
  • The messages alternative page (/extensions/newsletter/subscription/page.php) is now deprecated and will be removed
  • New cancellation documentation page published
  • Integrated SMTP is now deprecated (soon will be replaced with a free extension)
  • {home_url} tag is now deprecated, use {blog_url} instead
  • Introduced tags {company_name} and {company_address} replaced by info in the company info configuration
  • Default template for messages has been improved with company contacts
  • Repeated subscriptions management
  • Generally improved the performances with caching and code clean up
  • General CSS moved to the main settings panel
  • Option to disable the default CSS
  • Profile export fix
Download this release

Release Info

Developer webagile
Plugin Icon 128x128 Newsletter
Version 5.4.3
Comparing to
See all releases

Code changes from version 5.4.2 to 5.4.3

Files changed (87) hide show
  1. admin.css +32 -0
  2. emails/blocks/giphy/block.php +1 -1
  3. emails/blocks/giphy/blockx.php +0 -34
  4. emails/blocks/giphy/options.php +1 -1
  5. emails/blocks/list/blockx.php +0 -51
  6. emails/blocks/list/icon.png +0 -0
  7. emails/blocks/list/options.php +0 -74
  8. emails/blocks/list/style.css +0 -6
  9. emails/composer.php +1 -1
  10. emails/{languages/en_US.php → defaults.php} +0 -0
  11. emails/edit-editor.php +1 -1
  12. emails/edit.php +1 -1
  13. emails/index.php +6 -12
  14. emails/languages/en_US.po +0 -172
  15. emails/languages/it_IT.mo +0 -0
  16. emails/languages/it_IT.po +0 -180
  17. emails/new.php +2 -2
  18. emails/tnp-composer/_/content-06-posts.block.php +0 -94
  19. emails/tnp-composer/_/content-06-posts.block.png +0 -0
  20. emails/tnp-composer/_/content-07-twocols.block.php +0 -109
  21. emails/tnp-composer/_/content-07-twocols.block.png +0 -0
  22. emails/tnp-composer/blocks/content-01-hero.block.png +0 -0
  23. emails/tnp-composer/blocks/content-02-heading.block.png +0 -0
  24. emails/tnp-composer/blocks/content-03-text.block.png +0 -0
  25. emails/tnp-composer/blocks/content-05-image.block.png +0 -0
  26. emails/tnp-composer/blocks/footer-01-footer.block.png +0 -0
  27. emails/tnp-composer/blocks/footer-02-canspam.block.png +0 -0
  28. emails/tnp-composer/blocks/footer-03-social.block.png +0 -0
  29. emails/tnp-composer/blocks/header-01-header.block.png +0 -0
  30. emails/tnp-composer/index.php +1 -1
  31. images/test.jpg +0 -0
  32. includes/controls.php +89 -59
  33. includes/logger.php +20 -5
  34. includes/module.php +399 -91
  35. main/defaults-info.php +6 -0
  36. main/{languages/smtp-en_US.php → defaults-smtp.php} +0 -0
  37. main/{languages/en_US.php → defaults.php} +4 -1
  38. main/info.php +4 -4
  39. main/main.php +88 -9
  40. main/welcome.php +3 -3
  41. plugin.php +100 -73
  42. profile/defaults.php +16 -0
  43. profile/index.php +104 -2
  44. profile/profile.php +305 -26
  45. readme.txt +34 -4
  46. statistics/statistics.php +28 -36
  47. subscription/style.css → style.css +14 -2
  48. subscription/antibot.php +2 -1
  49. subscription/{languages/lists-en_US.php → defaults-lists.php} +1 -0
  50. subscription/defaults-profile.php +41 -0
  51. subscription/defaults-template.php +6 -0
  52. subscription/defaults.php +68 -0
  53. subscription/email-alternative.php +0 -32
  54. subscription/email.html +18 -9
  55. subscription/email.php +0 -48
  56. subscription/forms.php +2 -2
  57. subscription/languages/de_DE.php +0 -50
  58. subscription/languages/en_US.php +0 -102
  59. subscription/languages/es_ES.php +0 -56
  60. subscription/languages/fr_FR.php +0 -44
  61. subscription/languages/it_IT.php +0 -41
  62. subscription/languages/nl_NL.php +0 -49
  63. subscription/languages/pl_PL.php +0 -48
  64. subscription/languages/profile-en_US.php +0 -51
  65. subscription/languages/profile-it_IT.php +0 -17
  66. subscription/languages/pt_BR.php +0 -50
  67. subscription/languages/ru_RU.php +0 -44
  68. subscription/languages/template-en_US.php +0 -7
  69. subscription/lists.php +48 -11
  70. subscription/options.php +13 -145
  71. subscription/page-alternative.php +0 -54
  72. subscription/profile.php +14 -21
  73. subscription/subscription.php +550 -681
  74. subscription/template.php +36 -43
  75. subscription/unsubscription.php +68 -59
  76. tnp-header.php +27 -19
  77. users/edit.php +30 -39
  78. users/export.php +1 -8
  79. users/images/map.png +0 -0
  80. users/index.php +10 -24
  81. users/massive.php +21 -33
  82. users/new.php +1 -2
  83. users/statistics-time.php +1 -2
  84. users/statistics.php +5 -5
  85. users/users.php +5 -7
  86. widget/minimal.php +10 -11
  87. widget/standard.php +34 -126
admin.css CHANGED
@@ -2029,3 +2029,35 @@ input:checked + .slider:before {
2029
  .tnp-list-conditions p {
2030
  margin: 0px 10px;
2031
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2029
  .tnp-list-conditions p {
2030
  margin: 0px 10px;
2031
  }
2032
+
2033
+ /* Lists panel */
2034
+ .tnp-lists .tnp-notes {
2035
+ margin: 0;
2036
+ font-size: .9em;
2037
+ }
2038
+
2039
+ /* Codemirror editor with preview */
2040
+ iframe.tnp-editor-preview-mobile {
2041
+ box-sizing: border-box;
2042
+ background-color: #fff;
2043
+ border: 1px solid #bbb;
2044
+ box-shadow: 1px 1px 10px #777;
2045
+ border-radius: 10px;
2046
+ padding: 5px;
2047
+ width: 320px;
2048
+ height: 500px;
2049
+ float: left;
2050
+ }
2051
+
2052
+ iframe.tnp-editor-preview-desktop {
2053
+ box-sizing: border-box;
2054
+ background-color: #fff;
2055
+ border: 1px solid #bbb;
2056
+ border-radius: 10px;
2057
+ box-shadow: 1px 1px 10px #777;
2058
+ padding: 15px;
2059
+ width: 650px;
2060
+ margin-right: 20px;
2061
+ height: 500px;
2062
+ float: left;
2063
+ }
emails/blocks/giphy/block.php CHANGED
@@ -27,7 +27,7 @@ $options['block_padding_bottom'] = '15px';
27
  <table width="100%" border="0" cellpadding="0" align="center" cellspacing="0">
28
  <tr>
29
  <td width="100%" valign="top" align="center">
30
- <img src="<?php echo $options['giphy_url'] ?>" />
31
  </td>
32
  </tr>
33
  </table>
27
  <table width="100%" border="0" cellpadding="0" align="center" cellspacing="0">
28
  <tr>
29
  <td width="100%" valign="top" align="center">
30
+ <img src="<?php echo $options['giphy_url'] ?>" style="max-width: 100%!important; height: auto!important;" />
31
  </td>
32
  </tr>
33
  </table>
emails/blocks/giphy/blockx.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
- /*
3
- * Name: Giphy
4
- * Section: content
5
- * Description: Add a Giphy image
6
- *
7
- */
8
-
9
- /* @var $options array */
10
- /* @var $wpdb wpdb */
11
-
12
- $default_options = array(
13
- 'view'=>'View online',
14
- 'text'=>'Few words summary',
15
- 'block_background'=>'#ffffff',
16
- 'font_family'=>$font_family,
17
- 'font_size'=>13,
18
- 'color'=>'#999999'
19
- );
20
-
21
- $options = array_merge($default_options, $options);
22
- $options['block_padding_top'] = '15px';
23
- $options['block_padding_bottom'] = '15px';
24
-
25
- ?>
26
-
27
- <table width="100%" border="0" cellpadding="0" align="center" cellspacing="0">
28
- <tr>
29
- <td width="100%" valign="top" align="center">
30
- <img src="<?php echo $options['giphy_url'] ?>" />
31
- </td>
32
- </tr>
33
- </table>
34
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
emails/blocks/giphy/options.php CHANGED
@@ -46,7 +46,7 @@
46
  window.clearTimeout(tid);
47
  }
48
  tid = window.setTimeout(function () {
49
- jQuery.get("http://api.giphy.com/v1/gifs/search", {api_key: "57FLbVJJd7oQBZ0fEiRnzhM2VtZp5OP1", q: jQuery("#options-q").val()}, function (data) {
50
  jQuery("#tnp-giphy-results").html("");
51
  jQuery.each(data.data, function (index, value) {
52
  jQuery("#tnp-giphy-results").append('<img src="' + value.images.fixed_width_small.url + '" onclick="choose_gif(\'' + value.images.fixed_height.url + '\')" style="float:left;" />');
46
  window.clearTimeout(tid);
47
  }
48
  tid = window.setTimeout(function () {
49
+ jQuery.get("https://api.giphy.com/v1/gifs/search", {api_key: "57FLbVJJd7oQBZ0fEiRnzhM2VtZp5OP1", q: jQuery("#options-q").val()}, function (data) {
50
  jQuery("#tnp-giphy-results").html("");
51
  jQuery.each(data.data, function (index, value) {
52
  jQuery("#tnp-giphy-results").append('<img src="' + value.images.fixed_width_small.url + '" onclick="choose_gif(\'' + value.images.fixed_height.url + '\')" style="float:left;" />');
emails/blocks/list/blockx.php DELETED
@@ -1,51 +0,0 @@
1
- <?php
2
- /*
3
- * Name: List
4
- * Section: content
5
- * Description: A well designed list for your strength points
6
- *
7
- */
8
-
9
- /* @var $options array */
10
- /* @var $wpdb wpdb */
11
-
12
- $defaults = array(
13
- 'bullet' => '1',
14
- 'text_1' => 'Element 1',
15
- 'text_2' => 'Element 2',
16
- 'text_3' => 'Element 3',
17
- 'font_size' => '16',
18
- 'font_family' => 'Helvetica, Arial, sans-serif',
19
- 'color' => '#000000',
20
- 'background' => '#ffffff',
21
- );
22
-
23
- $options = array_merge($defaults, $options);
24
-
25
- ?>
26
- <table border="0" cellpadding="0" align="center" cellspacing="0" width="100%" style="width: 100%!important; max-width: <?php echo $width ?>px!important">
27
- <tr>
28
- <td style="padding: 15px 20px;" bgcolor="<?php echo $options['background'] ?>">
29
-
30
- <table cellspacing="0" cellpadding="5" align="left">
31
- <?php
32
- for ($i = 1; $i <= 10; $i++) {
33
- if (empty($options['text_' . $i])) {
34
- continue;
35
- }
36
- ?>
37
- <tr>
38
- <td style="font-size: <?php echo $options['font_size'] ?>px; font-family: <?php echo $options['font_family'] ?>; color: <?php echo $options['color'] ?>;">
39
- <span style="color: <?php echo $options['bullet_color'] ?>">&#x<?php echo $options['bullet'] ?>;</span>&nbsp;<?php echo $options['text_' . $i] ?>
40
- </td>
41
- </tr>
42
- <?php
43
- echo '</td></tr>';
44
- }
45
- ?>
46
- </table>
47
-
48
- </td>
49
- </tr>
50
- </table>
51
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
emails/blocks/list/icon.png DELETED
Binary file
emails/blocks/list/options.php DELETED
@@ -1,74 +0,0 @@
1
- <?php
2
- /* @var $options array contains all the options the current block we're ediging contains */
3
- /* @var $controls NewsletterControls */
4
- ?>
5
-
6
- <table class="form-table">
7
- <tr>
8
- <th>Bullet</th>
9
- <td>
10
- <?php
11
- $bullets = array(
12
- '2713'=>'&#x2713;',
13
- '2714'=>'&#x2714;',
14
- '25BA'=>'&#x25BA;',
15
- 'd7'=>'&#xd7;',
16
- 'bb'=>'&#xbb;',
17
- '25c9'=>'&#x25c9;',
18
- '203A'=>'&#x203A;',
19
- '25CE'=>'&#x25CE;',
20
-
21
- // Arrows
22
- '2192'=>'&#x2192;',
23
- '2190'=>'&#x2190;',
24
- '2191'=>'&#x2191;',
25
- '2193'=>'&#x2193;',
26
-
27
-
28
- );
29
-
30
- $controls->select('bullet', $bullets);
31
- ?>
32
- </td>
33
- </tr>
34
- <tr>
35
- <th><?php _e('Bullet color', 'newsletter')?></th>
36
- <td>
37
- <?php $controls->color('bullet_color') ?>
38
- </td>
39
- </tr>
40
- <tr>
41
- <th>Items</th>
42
- <td>
43
- <?php
44
- for ($i = 1; $i <= 10; $i++) {
45
- $controls->text('text_' . $i, 50);
46
- }
47
- ?>
48
- </td>
49
- </tr>
50
- <tr>
51
- <th>Font family</th>
52
- <td>
53
- <?php $controls->css_font_family('font_family') ?>
54
- </td>
55
- </tr>
56
- <tr>
57
- <th>Font size</th>
58
- <td>
59
- <?php $controls->css_font_size('font_size') ?>
60
- </td>
61
- </tr>
62
- <tr>
63
- <th><?php _e('Color', 'newsletter')?></th>
64
- <td>
65
- <?php $controls->color('color') ?>
66
- </td>
67
- </tr>
68
- <tr>
69
- <th><?php _e('Background', 'newsletter')?></th>
70
- <td>
71
- <?php $controls->color('background') ?>
72
- </td>
73
- </tr>
74
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
emails/blocks/list/style.css DELETED
@@ -1,6 +0,0 @@
1
- @media all and (max-width: 480px) {
2
- .list-text .mobile {
3
- font-size: 20px;
4
- }
5
- }
6
-
 
 
 
 
 
 
emails/composer.php CHANGED
@@ -32,7 +32,7 @@ if (($controls->is_action('save') || $controls->is_action('preview')) && !isset(
32
  $email = array();
33
  $email['status'] = 'new';
34
  $email['subject'] = __('Here the email subject', 'newsletter');
35
- $email['track'] = 1;
36
  $email['token'] = $module->get_token();
37
 
38
  $email['message'] = $controls->data['body'];
32
  $email = array();
33
  $email['status'] = 'new';
34
  $email['subject'] = __('Here the email subject', 'newsletter');
35
+ $email['track'] = Newsletter::instance()->options['track'];
36
  $email['token'] = $module->get_token();
37
 
38
  $email['message'] = $controls->data['body'];
emails/{languages/en_US.php → defaults.php} RENAMED
File without changes
emails/edit-editor.php CHANGED
@@ -1,4 +1,4 @@
1
- <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.7.3/tinymce.min.js"></script>
2
  <script type="text/javascript">
3
 
4
  // https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
1
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.7.12/tinymce.min.js"></script>
2
  <script type="text/javascript">
3
 
4
  // https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
emails/edit.php CHANGED
@@ -5,7 +5,7 @@ $controls = new NewsletterControls();
5
  $module = NewsletterEmails::instance();
6
 
7
  // Always required
8
- $email = Newsletter::instance()->get_email($_GET['id'], ARRAY_A);
9
  if (empty($email['query'])) {
10
  $email['query'] = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
11
  }
5
  $module = NewsletterEmails::instance();
6
 
7
  // Always required
8
+ $email = $module->get_email($_GET['id'], ARRAY_A);
9
  if (empty($email['query'])) {
10
  $email['query'] = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
11
  }
emails/index.php CHANGED
@@ -1,16 +1,10 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
 
5
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
7
  $module = NewsletterEmails::instance();
8
 
9
- if ($controls->is_action('convert')) {
10
- $module->convert_old_emails();
11
- $controls->messages = 'Converted!';
12
- }
13
-
14
  if ($controls->is_action('copy')) {
15
  $original = Newsletter::instance()->get_email($_POST['btn']);
16
  $email = array();
@@ -23,13 +17,13 @@ if ($controls->is_action('copy')) {
23
  $email['track'] = $original->track;
24
  $email['options'] = $original->options;
25
 
26
- Newsletter::instance()->save_email($email);
27
  $controls->messages .= __('Message duplicated.', 'newsletter');
28
  }
29
 
30
  if ($controls->is_action('delete')) {
31
- Newsletter::instance()->delete_email($_POST['btn']);
32
- $controls->messages .= __('Message deleted.', 'newsletter');
33
  }
34
 
35
  if ($controls->is_action('delete_selected')) {
@@ -37,7 +31,7 @@ if ($controls->is_action('delete_selected')) {
37
  $controls->messages .= $r . ' message(s) deleted';
38
  }
39
 
40
- $emails = Newsletter::instance()->get_emails('message');
41
  ?>
42
 
43
  <div class="wrap tnp-emails tnp-emails-index" id="tnp-wrap">
@@ -57,7 +51,7 @@ $emails = Newsletter::instance()->get_emails('message');
57
 
58
  <p>
59
  <a href="<?php echo $module->get_admin_page_url('theme'); ?>" class="button-primary"><?php _e('New newsletter', 'newsletter') ?></a>
60
- <?php $controls->button_confirm('delete_selected', __('Delete selected newsletters', 'newsletter'), __('Proceed?', 'newsletter')); ?>
61
 
62
  </p>
63
  <table class="widefat" style="width: 100%">
1
  <?php
2
+ defined('ABSPATH') || exit;
 
3
 
4
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
6
  $module = NewsletterEmails::instance();
7
 
 
 
 
 
 
8
  if ($controls->is_action('copy')) {
9
  $original = Newsletter::instance()->get_email($_POST['btn']);
10
  $email = array();
17
  $email['track'] = $original->track;
18
  $email['options'] = $original->options;
19
 
20
+ $module->save_email($email);
21
  $controls->messages .= __('Message duplicated.', 'newsletter');
22
  }
23
 
24
  if ($controls->is_action('delete')) {
25
+ $module->delete_email($_POST['btn']);
26
+ $controls->add_message_deleted();
27
  }
28
 
29
  if ($controls->is_action('delete_selected')) {
31
  $controls->messages .= $r . ' message(s) deleted';
32
  }
33
 
34
+ $emails = $module->get_emails('message');
35
  ?>
36
 
37
  <div class="wrap tnp-emails tnp-emails-index" id="tnp-wrap">
51
 
52
  <p>
53
  <a href="<?php echo $module->get_admin_page_url('theme'); ?>" class="button-primary"><?php _e('New newsletter', 'newsletter') ?></a>
54
+ <?php $controls->button_confirm('delete_selected', __('Delete selected newsletters', 'newsletter')); ?>
55
 
56
  </p>
57
  <table class="widefat" style="width: 100%">
emails/languages/en_US.po DELETED
@@ -1,172 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Content-Type: text/plain; charset=utf-8\n"
4
- "Content-Transfer-Encoding: 8bit\n"
5
-
6
- #. Text in echo
7
- #: emails/new.php:132
8
- msgid "Back to the themes"
9
- msgstr ""
10
-
11
- #. Text in function
12
- #: emails/index.php:131
13
- msgid "Copy"
14
- msgstr ""
15
-
16
- #. Text in echo
17
- #: emails/new.php:131
18
- msgid "Create a newsletter"
19
- msgstr ""
20
-
21
- #. Text in echo
22
- #: emails/index.php:94
23
- msgid "Date"
24
- msgstr ""
25
-
26
- #. Text in function
27
- #: emails/index.php:132
28
- msgid "Delete"
29
- msgstr ""
30
-
31
- #. Text in function
32
- #: emails/index.php:82
33
- msgid "Delete selected newsletters"
34
- msgstr ""
35
-
36
- #. Text in function
37
- #: emails/index.php:1
38
- msgid "Delivery engine triggered."
39
- msgstr ""
40
-
41
- #. Text in echo
42
- #: emails/edit.php:302
43
- msgid "Gender"
44
- msgstr ""
45
-
46
- #. Text in function
47
- #: emails/new.php:1
48
- #: emails/new.php:43
49
- msgid "Here the email subject"
50
- msgstr ""
51
-
52
- #. Text in echo
53
- #: emails/edit.php:259
54
- msgid "Message"
55
- msgstr ""
56
-
57
- #. Text in echo
58
- #: emails/edit.php:260
59
- msgid "Message (textual)"
60
- msgstr ""
61
-
62
- #. Text in function
63
- #: emails/index.php:1
64
- msgid "Message deleted."
65
- msgstr ""
66
-
67
- #. Text in function
68
- #: emails/index.php:1
69
- msgid "Message duplicated."
70
- msgstr ""
71
-
72
- #. Text in echo
73
- #: emails/index.php:81
74
- msgid "New newsletter"
75
- msgstr ""
76
-
77
- #. Text in echo
78
- #: emails/index.php:58
79
- msgid "Newsletters"
80
- msgstr ""
81
-
82
- #. Text in function
83
- #: emails/index.php:82
84
- #: emails/index.php:131
85
- #: emails/index.php:132
86
- msgid "Proceed?"
87
- msgstr ""
88
-
89
- #. Text in echo
90
- #: emails/index.php:93
91
- msgid "Progress"
92
- msgstr ""
93
-
94
- #. Text in function
95
- #: emails/edit.php:1
96
- msgid "Read more about test subscribers"
97
- msgstr ""
98
-
99
- #. Text in echo
100
- #: emails/new.php:146
101
- msgid "Refresh the preview"
102
- msgstr ""
103
-
104
- #. Text in echo
105
- #: emails/index.php:111
106
- msgid "Scheduled"
107
- msgstr ""
108
-
109
- #. Text in echo
110
- #: emails/theme.php:54
111
- msgid "Select a theme"
112
- msgstr ""
113
-
114
- #. Text in echo
115
- #: emails/index.php:111
116
- msgid "Sending"
117
- msgstr ""
118
-
119
- #. Text in echo
120
- #: emails/index.php:92
121
- msgid "Status"
122
- msgstr ""
123
-
124
- #. Text in echo
125
- #: emails/index.php:91
126
- msgid "Subject"
127
- msgstr ""
128
-
129
- #. Text in echo
130
- #: emails/edit.php:311
131
- msgid "Subscriber preferences"
132
- msgstr ""
133
-
134
- #. Text in function
135
- #: emails/edit.php:1
136
- msgid "Test newsletter sent to:"
137
- msgstr ""
138
-
139
- #. Text in echo
140
- #: emails/index.php:137
141
- msgid "The expected total can change at the delivery end due to subscriptions/unsubscriptions in the meanwhile."
142
- msgstr ""
143
-
144
- #. Text in echo
145
- #: emails/new.php:147
146
- msgid "Theme options are saved for next time you\\'ll use this theme."
147
- msgstr ""
148
-
149
- #. Text in function
150
- #: emails/edit.php:1
151
- msgid "There are no test subscribers."
152
- msgstr ""
153
-
154
- #. Text in echo
155
- #: emails/index.php:95
156
- msgid "Tracking"
157
- msgstr ""
158
-
159
- #. Text in function
160
- #: emails/index.php:84
161
- msgid "Trigger the delivery engine"
162
- msgstr ""
163
-
164
- #. Text in function
165
- #: emails/index.php:126
166
- msgid "Yes"
167
- msgstr ""
168
-
169
- #. Text in function
170
- #: emails/index.php:124
171
- msgid "of"
172
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
emails/languages/it_IT.mo DELETED
Binary file
emails/languages/it_IT.po DELETED
@@ -1,180 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Content-Type: text/plain; charset=UTF-8\n"
4
- "Content-Transfer-Encoding: 8bit\n"
5
- "Project-Id-Version: \n"
6
- "POT-Creation-Date: \n"
7
- "PO-Revision-Date: \n"
8
- "Last-Translator: \n"
9
- "Language-Team: \n"
10
- "MIME-Version: 1.0\n"
11
- "X-Generator: Poedit 1.7.3\n"
12
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
- "Language: it_IT\n"
14
-
15
- #. Text in echo
16
- #: emails/new.php:132
17
- msgid "Back to the themes"
18
- msgstr "Torna ai temi"
19
-
20
- #. Text in function
21
- #: emails/index.php:131
22
- msgid "Copy"
23
- msgstr "Copia"
24
-
25
- #. Text in echo
26
- #: emails/new.php:131
27
- msgid "Create a newsletter"
28
- msgstr "Crea una newsletter"
29
-
30
- #. Text in echo
31
- #: emails/index.php:94
32
- msgid "Date"
33
- msgstr "Data"
34
-
35
- #. Text in function
36
- #: emails/index.php:132
37
- msgid "Delete"
38
- msgstr "Elimina"
39
-
40
- #. Text in function
41
- #: emails/index.php:82
42
- msgid "Delete selected newsletters"
43
- msgstr "Cancella le newsletter selezionate"
44
-
45
- #. Text in function
46
- #: emails/index.php:1
47
- msgid "Delivery engine triggered."
48
- msgstr ""
49
-
50
- #. Text in echo
51
- #: emails/edit.php:302
52
- msgid "Gender"
53
- msgstr "Genere"
54
-
55
- #. Text in function
56
- #: emails/new.php:1 emails/new.php:43
57
- msgid "Here the email subject"
58
- msgstr "Qui l'oggetto dell'email"
59
-
60
- #. Text in echo
61
- #: emails/edit.php:259
62
- msgid "Message"
63
- msgstr "Messaggio"
64
-
65
- #. Text in echo
66
- #: emails/edit.php:260
67
- msgid "Message (textual)"
68
- msgstr "Messaggio (testo)"
69
-
70
- #. Text in function
71
- #: emails/index.php:1
72
- msgid "Message deleted."
73
- msgstr "Messaggio cancellato."
74
-
75
- #. Text in function
76
- #: emails/index.php:1
77
- msgid "Message duplicated."
78
- msgstr "Messaggio duplicato."
79
-
80
- #. Text in echo
81
- #: emails/index.php:81
82
- msgid "New newsletter"
83
- msgstr "Nuova newsletter"
84
-
85
- #. Text in echo
86
- #: emails/index.php:58
87
- msgid "Newsletters"
88
- msgstr ""
89
-
90
- #. Text in function
91
- #: emails/index.php:82 emails/index.php:131 emails/index.php:132
92
- msgid "Proceed?"
93
- msgstr ""
94
-
95
- #. Text in echo
96
- #: emails/index.php:93
97
- msgid "Progress"
98
- msgstr ""
99
-
100
- #. Text in function
101
- #: emails/edit.php:1
102
- msgid "Read more about test subscribers"
103
- msgstr ""
104
-
105
- #. Text in echo
106
- #: emails/new.php:146
107
- msgid "Refresh the preview"
108
- msgstr ""
109
-
110
- #. Text in echo
111
- #: emails/index.php:111
112
- msgid "Scheduled"
113
- msgstr ""
114
-
115
- #. Text in echo
116
- #: emails/theme.php:54
117
- msgid "Select a theme"
118
- msgstr ""
119
-
120
- #. Text in echo
121
- #: emails/index.php:111
122
- msgid "Sending"
123
- msgstr ""
124
-
125
- #. Text in echo
126
- #: emails/index.php:92
127
- msgid "Status"
128
- msgstr ""
129
-
130
- #. Text in echo
131
- #: emails/index.php:91
132
- msgid "Subject"
133
- msgstr ""
134
-
135
- #. Text in echo
136
- #: emails/edit.php:311
137
- msgid "Subscriber preferences"
138
- msgstr ""
139
-
140
- #. Text in function
141
- #: emails/edit.php:1
142
- msgid "Test newsletter sent to:"
143
- msgstr ""
144
-
145
- #. Text in echo
146
- #: emails/index.php:137
147
- msgid ""
148
- "The expected total can change at the delivery end due to subscriptions/"
149
- "unsubscriptions in the meanwhile."
150
- msgstr ""
151
-
152
- #. Text in echo
153
- #: emails/new.php:147
154
- msgid "Theme options are saved for next time you\\'ll use this theme."
155
- msgstr ""
156
-
157
- #. Text in function
158
- #: emails/edit.php:1
159
- msgid "There are no test subscribers."
160
- msgstr ""
161
-
162
- #. Text in echo
163
- #: emails/index.php:95
164
- msgid "Tracking"
165
- msgstr ""
166
-
167
- #. Text in function
168
- #: emails/index.php:84
169
- msgid "Trigger the delivery engine"
170
- msgstr ""
171
-
172
- #. Text in function
173
- #: emails/index.php:126
174
- msgid "Yes"
175
- msgstr ""
176
-
177
- #. Text in function
178
- #: emails/index.php:124
179
- msgid "of"
180
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
emails/new.php CHANGED
@@ -14,7 +14,7 @@ if ($controls->is_action('theme')) {
14
  $email = array();
15
  $email['status'] = 'new';
16
  $email['subject'] = __('Here the email subject', 'newsletter');
17
- $email['track'] = 1;
18
  $email['token'] = $module->get_token();
19
 
20
  if ($controls->data['theme'] == 'rawhtml') {
@@ -69,7 +69,7 @@ if ($controls->is_action('create')) {
69
  $email = array();
70
  $email['status'] = 'new';
71
  $email['subject'] = __('Here the email subject', 'newsletter');
72
- $email['track'] = 1;
73
 
74
  $theme_options = $module->get_current_theme_options();
75
 
14
  $email = array();
15
  $email['status'] = 'new';
16
  $email['subject'] = __('Here the email subject', 'newsletter');
17
+ $email['track'] = Newsletter::instance()->options['track'];
18
  $email['token'] = $module->get_token();
19
 
20
  if ($controls->data['theme'] == 'rawhtml') {
69
  $email = array();
70
  $email['status'] = 'new';
71
  $email['subject'] = __('Here the email subject', 'newsletter');
72
+ $email['track'] = Newsletter::instance()->options['track'];
73
 
74
  $theme_options = $module->get_current_theme_options();
75
 
emails/tnp-composer/_/content-06-posts.block.php DELETED
@@ -1,94 +0,0 @@
1
- <?php
2
- include NEWSLETTER_INCLUDES_DIR . '/helper.php';
3
-
4
- $filters = array();
5
- $filters['showposts'] = isset($_POST['num']) ? intval($_POST['num']) : 3;
6
- if (!empty($_POST['categories'])) {
7
- $filters['category__in'] = $_POST['categories'];
8
- }
9
- if (!empty($_POST['tags'])) {
10
- $filters['tag'] = $_POST['tags'];
11
- }
12
- $posts = get_posts($filters);
13
-
14
- $bgcolor = isset($_POST['bgcolor']) ? $_POST['bgcolor'] : '#E6E9ED';
15
-
16
- ?>
17
-
18
- <!-- COMPACT ARTICLE SECTION -->
19
- <?php echo $wrapper_open ?>
20
- <table border="0" cellpadding="0" align="center" cellspacing="0" width="100%" style="width: 100%!important; max-width: <?php echo $width ?>px!important">
21
- <tr>
22
- <td bgcolor="<?php echo $bgcolor ?>" align="center" style="padding: 70px 15px 70px 15px;" class="section-padding edit-block">
23
-
24
- <table border="0" cellpadding="0" cellspacing="0" width="100%" class="tnpc-row tnpc-row-posts" data-id="content-06" data-block="content-06-posts">
25
- <tr>
26
- <td bgcolor="<?php echo $bgcolor ?>" align="center" style="padding: 70px 15px 70px 15px;" class="section-padding edit-block">
27
-
28
- <table border="0" cellpadding="0" cellspacing="0" width="500" style="padding:0 0 20px 0;" class="responsive-table">
29
- <!-- TITLE -->
30
- <tr>
31
- <td align="center" style="padding: 0 0 10px 0; font-size: 25px; font-family: Helvetica, Arial, sans-serif; font-weight: normal; color: #333333;" class="padding-copy tnpc-row-edit" data-type="title" colspan="2">From Our Blog</td>
32
- </tr>
33
-
34
- <?php foreach ($posts AS $post) { ?>
35
-
36
- <tr>
37
- <td valign="top" style="padding: 40px 0 0 0;" class="mobile-hide tnpc-row-edit" data-type="image">
38
- <a href="<?php echo tnp_post_permalink($post) ?>" target="_blank">
39
- <img src="<?php echo tnp_post_thumbnail_src($post) ?>" width="105" height="105" border="0" style="display: block; font-family: Arial; color: #666666; font-size: 14px; width: 105px!important; height: 105px!important;">
40
- </a>
41
- </td>
42
- <td style="padding: 40px 0 0 0;" class="no-padding">
43
- <!-- ARTICLE -->
44
- <table border="0" cellspacing="0" cellpadding="0" width="100%">
45
- <tr>
46
- <td align="left" style="padding: 0 0 5px 25px; font-size: 13px; font-family: Helvetica, Arial, sans-serif; font-weight: normal; color: #aaaaaa;" class="padding-meta">
47
- <?php echo tnp_post_date($post) ?>
48
- </td>
49
- </tr>
50
- <tr>
51
- <td align="left" style="padding: 0 0 5px 25px; font-size: 22px; font-family: Helvetica, Arial, sans-serif; font-weight: normal; color: #333333;" class="padding-copy tnpc-row-edit" data-type="title">
52
- <?php echo tnp_post_title($post) ?>
53
- </td>
54
- </tr>
55
- <tr>
56
- <td align="left" style="padding: 10px 0 15px 25px; font-size: 16px; line-height: 24px; font-family: Helvetica, Arial, sans-serif; color: #666666;" class="padding-copy tnpc-row-edit" data-type="text">
57
- <?php echo tnp_post_excerpt($post) ?>
58
- </td>
59
- </tr>
60
- <tr>
61
- <td style="padding:0 0 45px 25px;" align="left" class="padding">
62
- <table border="0" cellspacing="0" cellpadding="0" class="mobile-button-container">
63
- <tr>
64
- <td align="center">
65
- <!-- BULLETPROOF BUTTON -->
66
- <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mobile-button-container">
67
- <tr>
68
- <td align="center" style="padding: 0;" class="padding-copy">
69
- <table border="0" cellspacing="0" cellpadding="0" class="responsive-table">
70
- <tr>
71
- <td align="center">
72
- <a href="<?php echo tnp_post_permalink($post) ?>" target="_blank" style="font-size: 15px; font-family: Helvetica, Arial, sans-serif; font-weight: normal; color: #ffffff; text-decoration: none; background-color: #256F9C; border-top: 10px solid #256F9C; border-bottom: 10px solid #256F9C; border-left: 20px solid #256F9C; border-right: 20px solid #256F9C; border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; display: inline-block;" class="mobile-button tnpc-row-edit" data-type="link">Go To Article &rarr;</a>
73
- </td>
74
- </tr>
75
- </table>
76
- </td>
77
- </tr>
78
- </table>
79
- </td>
80
- </tr>
81
- </table>
82
- </td>
83
- </tr>
84
- </table>
85
- </td>
86
- </tr>
87
-
88
- <?php } ?>
89
-
90
- </table>
91
- </td>
92
- </tr>
93
- </table>
94
- <?php echo $wrapper_close ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
emails/tnp-composer/_/content-06-posts.block.png DELETED
Binary file
emails/tnp-composer/_/content-07-twocols.block.php DELETED
@@ -1,109 +0,0 @@
1
- <?php
2
- include NEWSLETTER_INCLUDES_DIR . '/helper.php';
3
-
4
- $filters = array();
5
- $filters['showposts'] = isset($_POST['num']) ? intval($_POST['num']) : 3;
6
- if (!empty($_POST['categories'])) {
7
- $filters['category__in'] = $_POST['categories'];
8
- }
9
- if (!empty($_POST['tags'])) {
10
- $filters['tag'] = $_POST['tags'];
11
- }
12
- $posts = get_posts($filters);
13
-
14
- $bgcolor = isset($_POST['bgcolor']) ? $_POST['bgcolor'] : '#E6E9ED';
15
-
16
- ?>
17
-
18
- <!-- TWO COLUMN SECTION -->
19
- <table border="0" cellpadding="0" cellspacing="0" width="100%" class="tnpc-row tnpc-row-posts" data-id="content-07" data-block="content-07-twocols">
20
- <tr>
21
- <td bgcolor="<?php echo $bgcolor ?>" align="center" style="padding: 70px 15px 70px 15px;" class="section-padding edit-block">
22
- <table border="0" cellpadding="0" cellspacing="0" width="500" class="responsive-table">
23
- <tr>
24
- <td>
25
- <!-- TITLE SECTION AND COPY -->
26
- <table width="100%" border="0" cellspacing="0" cellpadding="0">
27
- <tr>
28
- <td align="center" style="font-size: 25px; font-family: Helvetica, Arial, sans-serif; color: #333333;" class="padding-copy tnpc-row-edit" data-type="title">Great News!</td>
29
- </tr>
30
- <tr>
31
- <td align="center" style="padding: 20px 0 20px 0; font-size: 16px; line-height: 25px; font-family: Helvetica, Arial, sans-serif; color: #666666;" class="padding-copy tnpc-row-edit" data-type="text">The twelve jurors were all writing very busily on slates.</td>
32
- </tr>
33
- </table>
34
- </td>
35
- </tr>
36
- <tr>
37
- <td>
38
- <!-- TWO COLUMNS -->
39
- <table cellspacing="0" cellpadding="0" border="0" width="100%">
40
- <?php foreach (array_chunk($posts, 2) AS $row) { ?>
41
- <tr>
42
- <td valign="top" style="padding: 0;" class="mobile-wrapper">
43
-
44
- <!-- LEFT COLUMN -->
45
- <table cellpadding="0" cellspacing="0" border="0" width="47%" align="left" class="responsive-table">
46
- <tr>
47
- <td style="padding: 20px 0 40px 0;">
48
- <table cellpadding="0" cellspacing="0" border="0" width="100%">
49
- <tr>
50
- <td align="center" bgcolor="#F5F7FA" valign="middle" class="tnpc-row-edit" data-type="image">
51
- <a href="<?php echo tnp_post_permalink($row[0]) ?>" target="_blank">
52
- <img src="<?php echo tnp_post_thumbnail_src($row[0], array(240, 160, true)) ?>" width="240" height="160" style="display: block; color: #666666; font-family: Helvetica, arial, sans-serif; font-size: 13px; width: 240px; height: 160px;" border="0" class="img-max">
53
- </a>
54
- </td>
55
- </tr>
56
- <tr>
57
- <td align="center" style="padding: 15px 0 0 0; font-family: Arial, sans-serif; color: #333333; font-size: 20px;" bgcolor="#F5F7FA" class="tnpc-row-edit" data-type="title"><?php echo tnp_post_title($row[0]) ?></td>
58
- </tr>
59
- <tr>
60
- <td align="center" style="padding: 5px 0 0 0; font-family: Arial, sans-serif; color: #666666; font-size: 14px; line-height: 20px;" bgcolor="#F5F7FA" class="tnpc-row-edit" data-type="text"><?php echo tnp_post_excerpt($row[0]) ?></td>
61
- </tr>
62
- <tr>
63
- <td align="center" style="padding: 5px 0 0 0; font-family: Arial, sans-serif; color: #666666; font-size: 14px; line-height: 20px;" bgcolor="#F5F7FA"><a href="<?php echo tnp_post_permalink($row[0]) ?>" style="color: #256F9C; text-decoration: none;" class="tnpc-row-edit" data-type="link">Go To Article &rarr;</a></td>
64
- </tr>
65
- </table>
66
- </td>
67
- </tr>
68
- </table>
69
-
70
- <?php if (!empty($row[1])) { ?>
71
- <!-- RIGHT COLUMN -->
72
- <table cellpadding="0" cellspacing="0" border="0" width="47%" align="right" class="responsive-table">
73
- <tr>
74
- <td style="padding: 20px 0 40px 0;">
75
- <table cellpadding="0" cellspacing="0" border="0" width="100%">
76
- <tr>
77
- <td align="center" bgcolor="#F5F7FA" valign="middle" class="tnpc-row-edit" data-type="image">
78
- <a href="<?php echo tnp_post_permalink($row[1]) ?>" target="_blank">
79
- <img src="<?php echo tnp_post_thumbnail_src($row[1], array(240, 160)) ?>" width="240" height="160" style="display: block; color: #666666; font-family: Helvetica, arial, sans-serif; font-size: 13px; width: 240px; height: 160px;" border="0" class="img-max">
80
- </a>
81
- </td>
82
- </tr>
83
- <tr>
84
- <td align="center" style="padding: 15px 0 0 0; font-family: Arial, sans-serif; color: #333333; font-size: 20px;" bgcolor="#F5F7FA" class="tnpc-row-edit" data-type="title"><?php echo tnp_post_title($row[1]) ?></td>
85
- </tr>
86
- <tr>
87
- <td align="center" style="padding: 5px 0 0 0; font-family: Arial, sans-serif; color: #666666; font-size: 14px; line-height: 20px;" bgcolor="#F5F7FA" class="tnpc-row-edit" data-type="text"><?php echo tnp_post_excerpt($row[1]) ?></td>
88
- </tr>
89
- <tr>
90
- <td align="center" style="padding: 5px 0 0 0; font-family: Arial, sans-serif; color: #666666; font-size: 14px; line-height: 20px;" bgcolor="#F5F7FA"><a href="<?php echo tnp_post_permalink($row[1]) ?>" style="color: #256F9C; text-decoration: none;" class="tnpc-row-edit" data-type="link">Go To Article &rarr;</a></td>
91
- </tr>
92
- </table>
93
- </td>
94
- </tr>
95
- </table>
96
- <?php } ?>
97
-
98
- </td>
99
- </tr>
100
-
101
- <?php } ?>
102
-
103
- </table>
104
- </td>
105
- </tr>
106
- </table>
107
- </td>
108
- </tr>
109
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
emails/tnp-composer/_/content-07-twocols.block.png DELETED
Binary file
emails/tnp-composer/blocks/content-01-hero.block.png CHANGED
File without changes
emails/tnp-composer/blocks/content-02-heading.block.png CHANGED
File without changes
emails/tnp-composer/blocks/content-03-text.block.png CHANGED
File without changes
emails/tnp-composer/blocks/content-05-image.block.png CHANGED
File without changes
emails/tnp-composer/blocks/footer-01-footer.block.png CHANGED
File without changes
emails/tnp-composer/blocks/footer-02-canspam.block.png CHANGED
File without changes
emails/tnp-composer/blocks/footer-03-social.block.png CHANGED
File without changes
emails/tnp-composer/blocks/header-01-header.block.png CHANGED
File without changes
emails/tnp-composer/index.php CHANGED
@@ -99,7 +99,7 @@ $block_options = get_option('newsletter_main');
99
  TNP_HOME_URL = "<?php echo home_url('/', is_ssl() ? 'https' : 'http') ?>";
100
  </script>
101
  <script type="text/javascript" src="<?php echo plugins_url('newsletter'); ?>/emails/tnp-composer/_scripts/newsletter-builder.js?ver=<?php echo time() ?>"></script>
102
- <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.7.3/tinymce.min.js"></script>
103
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.nicescroll/3.6.8-fix/jquery.nicescroll.min.js"></script>
104
  <script>
105
  jQuery(function () {
99
  TNP_HOME_URL = "<?php echo home_url('/', is_ssl() ? 'https' : 'http') ?>";
100
  </script>
101
  <script type="text/javascript" src="<?php echo plugins_url('newsletter'); ?>/emails/tnp-composer/_scripts/newsletter-builder.js?ver=<?php echo time() ?>"></script>
102
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.7.12/tinymce.min.js"></script>
103
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.nicescroll/3.6.8-fix/jquery.nicescroll.min.js"></script>
104
  <script>
105
  jQuery(function () {
images/test.jpg ADDED
Binary file
includes/controls.php CHANGED
@@ -355,7 +355,7 @@ class NewsletterControls {
355
  echo '</div>';
356
  }
357
  if (!empty($this->warnings)) {
358
- foreach ((array)$this->warnings as $warning) {
359
  echo '<div class="tnp-warning">';
360
  echo $warning;
361
  echo '</div>';
@@ -374,6 +374,20 @@ class NewsletterControls {
374
  }
375
  $this->messages .= __('Saved.', 'newsletter');
376
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
 
378
  function add_message_done() {
379
  if (!empty($this->messages)) {
@@ -516,10 +530,10 @@ class NewsletterControls {
516
 
517
  $this->select($name, $options);
518
  }
519
-
520
  function select_number($name, $min, $max) {
521
  $options = array();
522
- for ($i=$min; $i<=$max; $i++) {
523
  $options['' . $i] = $i;
524
  }
525
  $this->select($name, $options);
@@ -592,15 +606,15 @@ class NewsletterControls {
592
  echo '</select>';
593
  echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({templateResult: tnp_select_images, templateSelection: tnp_select_images_selection});</script>';
594
  }
595
-
596
- function select2($name, $options, $first = null, $multiple = false, $style = null, $placeholder='') {
597
-
598
  if ($multiple) {
599
  $option_name = "options[" . esc_attr($name) . "][]";
600
  } else {
601
  $option_name = "options[" . esc_attr($name) . "]";
602
  }
603
-
604
  if (is_null($style)) {
605
  $style = 'width: 100%';
606
  }
@@ -608,11 +622,11 @@ class NewsletterControls {
608
  $value = $this->get_value($name);
609
 
610
  echo '<select id="options-', esc_attr($name), '" name="', $option_name, '" style="', $style, '"',
611
- ($multiple ? ' multiple' : ''), '>';
612
  if (!empty($first)) {
613
  echo '<option value="">' . esc_html($first) . '</option>';
614
  }
615
-
616
  foreach ($options as $key => $data) {
617
  echo '<option value="' . esc_attr($key) . '"';
618
  if (is_array($value) && in_array($key, $value) || $value == $key)
@@ -733,8 +747,9 @@ class NewsletterControls {
733
  * With translated "Save" label.
734
  */
735
  function button_save($function = null) {
736
- $this->button_primary('save', __('Save', 'newsletter'), $function);
737
  }
 
738
 
739
  function button_reset($data = '') {
740
  echo '<button class="button-secondary" onclick="this.form.btn.value=\'' . esc_attr($data) . '\';this.form.act.value=\'reset\';if (!confirm(\'';
@@ -781,19 +796,19 @@ class NewsletterControls {
781
 
782
  function button_primary($action, $label, $function = null) {
783
  if ($function != null) {
784
- echo '<input class="button-primary" type="button" value="' . esc_attr($label) . '" onclick="this.form.act.value=\'' . esc_attr($action) . '\';' . esc_attr($function) . '"/>';
785
  } else {
786
- echo '<input class="button-primary" type="button" value="' . esc_attr($label) . '" onclick="this.form.act.value=\'' . esc_attr($action) . '\';this.form.submit()"/>';
787
  }
788
  }
789
 
790
  function button_confirm($action, $label, $message = '', $data = '') {
791
  if (empty($message)) {
792
- echo '<input class="button-secondary" type="button" value="' . esc_attr($label) . '" onclick="this.form.btn.value=\'' . esc_attr($data) . '\';this.form.act.value=\'' . esc_attr($action) . '\';this.form.submit()"/>';
793
- } else {
794
- echo '<input class="button-secondary" type="button" value="' . esc_attr($label) . '" onclick="this.form.btn.value=\'' . esc_attr($data) . '\';this.form.act.value=\'' . esc_attr($action) . '\';if (confirm(\'' .
795
- esc_attr(esc_js($message)) . '\')) this.form.submit()"/>';
796
  }
 
 
 
797
  }
798
 
799
  function editor($name, $rows = 5, $cols = 75) {
@@ -806,9 +821,9 @@ class NewsletterControls {
806
  $value = $this->get_value($name);
807
  wp_editor($value, $name, array_merge(array(
808
  'tinymce' => array('content_css' => plugins_url('newsletter') . '/css/wp-editor.css?ver=' . filemtime(NEWSLETTER_DIR . '/css/wp-editor.css')),
809
- 'textarea_name' => 'options[' . esc_attr($name) . ']',
810
  'wpautop' => false
811
- ), $settings));
812
  //echo '<p class="description">You can install <a href="https://wordpress.org/plugins/tinymce-advanced/" target="_blank">TinyMCE Advanced</a> for advanced editing features</p>';
813
  }
814
 
@@ -841,13 +856,13 @@ class NewsletterControls {
841
  echo esc_html($value);
842
  echo '</textarea>';
843
  echo '<div id="options-' . esc_attr($name) . '-preview" style="box-sizing: border-box; background-color: #eee; border: 1px solid #bbb; padding: 15px; width: auto; position: absolute; top: 20px; left: 20px; box-shadow: 0 0 20px #777; z-index: 10000; display: none">';
844
- echo '<iframe id="options-' . esc_attr($name) . '-iframe" style="box-sizing: border-box; background-color: #fff; border: 1px solid #bbb; box-shadow: 1px 1px 10px #777; padding: 15px; width: 650px; margin-right: 20px; height: 500px; float: left"></iframe>';
845
- echo '<iframe id="options-' . esc_attr($name) . '-iframe-phone" style="box-sizing: border-box; background-color: #fff; border: 1px solid #bbb; box-shadow: 1px 1px 10px #777; border-radius: 10px; padding: 5px; width: 320px; height: 500px; float: left"></iframe>';
846
  echo '</div>';
847
  echo '</div>';
848
  }
849
 
850
- function email($prefix, $editor = null, $disable_option = false) {
851
  if ($disable_option) {
852
  $this->disabled($prefix . '_disabled');
853
  echo '<br>';
@@ -855,9 +870,9 @@ class NewsletterControls {
855
 
856
  $this->text($prefix . '_subject', 90, 'Subject');
857
  echo '<br><br>';
858
-
859
  if ($editor == 'wordpress') {
860
- $this->wp_editor($prefix . '_message');
861
  } else if ($editor == 'textarea') {
862
  $this->textarea($prefix . '_message');
863
  } else {
@@ -938,12 +953,11 @@ class NewsletterControls {
938
  }
939
 
940
  function color($name) {
941
-
942
  $value = $this->get_value($name);
943
  echo '<input id="options-', esc_attr($name), '" class="tnp-controls-color" name="options[' . $name . ']" type="text" size="' . $size . '" value="';
944
  echo esc_attr($value);
945
  echo '">';
946
-
947
  }
948
 
949
  /** Creates a set of checkbox named $name_[category id] (so they are posted with distinct names).
@@ -985,15 +999,15 @@ class NewsletterControls {
985
  * Empty preferences are skipped.
986
  */
987
  function preferences($name = 'preferences') {
988
- $options_profile = get_option('newsletter_profile');
989
  echo '<div class="newsletter-preferences-group">';
990
 
991
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
992
- if (empty($options_profile['list_' . $i])) {
993
  continue;
994
  }
995
  echo '<div class="newsletter-preferences-item">';
996
- $this->checkbox2($name . '_' . $i, esc_html($options_profile['list_' . $i]));
997
  echo '</div>';
998
  }
999
  }
@@ -1004,15 +1018,15 @@ class NewsletterControls {
1004
  * will be an array if at east one preference is checked).
1005
  */
1006
  function preferences_group($name = 'preferences') {
1007
- $options_profile = get_option('newsletter_profile');
1008
 
1009
  echo '<div class="newsletter-preferences-group">';
1010
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1011
- if (empty($options_profile['list_' . $i])) {
1012
  continue;
1013
  }
1014
  echo '<div class="newsletter-preferences-item">';
1015
- $this->checkbox_group($name, $i, '(' . $i . ') ' . esc_html($options_profile['list_' . $i]));
1016
  echo '</div>';
1017
  }
1018
  echo '<div style="clear: both"></div>';
@@ -1026,18 +1040,18 @@ class NewsletterControls {
1026
  * 'any', 'yes', 'no' corresponding to the values 0, 1, 2.
1027
  */
1028
  function preferences_selects($name = 'preferences', $skip_empty = false) {
1029
- $options_profile = get_option('newsletter_profile');
1030
 
1031
  echo '<div class="newsletter-preferences-group">';
1032
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1033
- if (empty($options_profile['list_' . $i])) {
1034
  continue;
1035
  }
1036
 
1037
  echo '<div class="newsletter-preferences-item">';
1038
 
1039
  $this->select($name . '_' . $i, array(0 => 'Any', 1 => 'Yes', 2 => 'No'));
1040
- echo '(' . $i . ') ' . esc_html($options_profile['list_' . $i]);
1041
 
1042
  echo '</div>';
1043
  }
@@ -1050,26 +1064,38 @@ class NewsletterControls {
1050
  * Creates a single select with the active preferences.
1051
  */
1052
  function preferences_select($name = 'preference', $empty_label = null) {
1053
- $options_profile = get_option('newsletter_profile');
1054
 
1055
  $lists = array();
1056
  if ($empty_label) {
1057
  $lists[''] = $empty_label;
1058
  }
1059
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1060
- $lists['' . $i] = '(' . $i . ') ' . $options_profile['list_' . $i];
1061
  }
1062
  $this->select($name, $lists);
1063
  echo ' <a href="admin.php?page=newsletter_subscription_lists" target="_blank"><i class="fa fa-edit"></i></a>';
1064
  }
1065
-
 
 
 
 
 
 
 
 
 
 
 
 
1066
  /**
1067
  * Generates an associative array with the active lists to be used in a select.
1068
  * @param string $empty_label
1069
  * @return array
1070
  */
1071
  function get_list_options($empty_label = null) {
1072
- $options_profile = get_option('newsletter_profile');
1073
  $lists = array();
1074
  if ($empty_label) {
1075
  $lists[''] = $empty_label;
@@ -1310,13 +1336,13 @@ class NewsletterControls {
1310
  }
1311
  echo '</select>&nbsp;px';
1312
  }
1313
-
1314
  function css_font_family($name = 'font_family') {
1315
  $value = $this->get_value($name);
1316
 
1317
  $fonts = array('Helvetica, Arial, sans-serif', 'Arial Black, Gadget, sans-serif', 'Garamond, serif', 'Courier, monospace', 'Cominc Sans MS, cursive', 'Impact, Charcoal, sans-serif',
1318
  'Tahoma, Geneva, sans-serif', 'Times New Roman, Times, serif', 'Verdana, Geneva, sans-serif');
1319
-
1320
  echo '<select id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']">';
1321
  foreach ($fonts as $font) {
1322
  echo '<option value="', esc_attr($font), '"';
@@ -1326,13 +1352,13 @@ class NewsletterControls {
1326
  echo '>', esc_html($font), '</option>';
1327
  }
1328
  echo '</select>';
1329
- }
1330
-
1331
  function css_text_align($name) {
1332
- $options = array('left'=>__('Left', 'newsletter'), 'right'=>__('Right', 'newsletter'),
1333
- 'center'=>__('Center', 'newsletter'));
1334
  $this->select($name, $options);
1335
- }
1336
 
1337
  function css_border($name) {
1338
  $value = $this->get_value($name . '_width');
@@ -1430,33 +1456,34 @@ class NewsletterControls {
1430
  }
1431
  if ($left) {
1432
  if ($time - time() < 0) {
1433
- $buffer .= ', ' . (time()-$time) . ' seconds late';
1434
  } else {
1435
  $buffer .= ', ' . gmdate('H:i:s', $time - time()) . ' left';
1436
  }
1437
  }
1438
  return $buffer;
1439
  }
1440
-
1441
  /**
1442
  * Prints the help button near a form field. The label is used as icon title.
1443
  *
1444
  * @param string $url
1445
  * @param string $label
1446
  */
1447
- static function help($url, $label='') {
1448
  echo '<a href="', $url, '" target="_blank" title="', esc_attr($label), '"><i class="fa fa-question-circle-o"></i></a>';
1449
  }
1450
-
1451
- static function idea($url, $label='') {
1452
  echo '<a href="', $url, '" target="_blank" title="', esc_attr($label), '"><i class="fa fa-lightbulb-o"></i></a>';
1453
  }
1454
-
1455
  static function field_help($url, $text = '') {
1456
- if (empty($text)) $text = __('Read more', 'newsletter');
 
1457
  echo '<i class="fa fa-question-circle"></i>&nbsp;<a href="', $url, '" target="_blank">', $text, '</a>';
1458
  }
1459
-
1460
  /**
1461
  * Prints a panel link to the documentation.
1462
  *
@@ -1464,22 +1491,25 @@ class NewsletterControls {
1464
  * @param type $text
1465
  */
1466
  static function panel_help($url, $text = '') {
1467
- if (empty($text)) $text = __('Need help?', 'newsletter');
 
1468
  echo '<span class="tnp-panel-help"><a href="', $url, '" target="_blank">', $text, '</a></span>';
1469
  }
1470
-
1471
  /**
1472
  * Prints an administration page link to the documentation (just under the administration page title.
1473
  * @param type $url
1474
  * @param type $text
1475
  */
1476
  static function page_help($url, $text = '') {
1477
- if (empty($text)) $text = __('Need help?', 'newsletter');
 
1478
  echo '<div class="tnp-page-help"><a href="', $url, '" target="_blank">', $text, '</a></div>';
1479
  }
1480
-
1481
- static function print_truncated($text, $size=50) {
1482
- if (mb_strlen($text) < $size) return esc_html($text);
 
1483
  $sub = mb_substr($text, 0, $size);
1484
  echo '<span title="', esc_attr($text), '">', esc_html($sub), '...</span>';
1485
  }
355
  echo '</div>';
356
  }
357
  if (!empty($this->warnings)) {
358
+ foreach ((array) $this->warnings as $warning) {
359
  echo '<div class="tnp-warning">';
360
  echo $warning;
361
  echo '</div>';
374
  }
375
  $this->messages .= __('Saved.', 'newsletter');
376
  }
377
+
378
+ function add_message_deleted() {
379
+ if (!empty($this->messages)) {
380
+ $this->messages .= '<br><br>';
381
+ }
382
+ $this->messages .= __('Deleted.', 'newsletter');
383
+ }
384
+
385
+ function add_message_reset() {
386
+ if (!empty($this->messages)) {
387
+ $this->messages .= '<br><br>';
388
+ }
389
+ $this->messages .= __('Options reset.', 'newsletter');
390
+ }
391
 
392
  function add_message_done() {
393
  if (!empty($this->messages)) {
530
 
531
  $this->select($name, $options);
532
  }
533
+
534
  function select_number($name, $min, $max) {
535
  $options = array();
536
+ for ($i = $min; $i <= $max; $i++) {
537
  $options['' . $i] = $i;
538
  }
539
  $this->select($name, $options);
606
  echo '</select>';
607
  echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({templateResult: tnp_select_images, templateSelection: tnp_select_images_selection});</script>';
608
  }
609
+
610
+ function select2($name, $options, $first = null, $multiple = false, $style = null, $placeholder = '') {
611
+
612
  if ($multiple) {
613
  $option_name = "options[" . esc_attr($name) . "][]";
614
  } else {
615
  $option_name = "options[" . esc_attr($name) . "]";
616
  }
617
+
618
  if (is_null($style)) {
619
  $style = 'width: 100%';
620
  }
622
  $value = $this->get_value($name);
623
 
624
  echo '<select id="options-', esc_attr($name), '" name="', $option_name, '" style="', $style, '"',
625
+ ($multiple ? ' multiple' : ''), '>';
626
  if (!empty($first)) {
627
  echo '<option value="">' . esc_html($first) . '</option>';
628
  }
629
+
630
  foreach ($options as $key => $data) {
631
  echo '<option value="' . esc_attr($key) . '"';
632
  if (is_array($value) && in_array($key, $value) || $value == $key)
747
  * With translated "Save" label.
748
  */
749
  function button_save($function = null) {
750
+ $this->button_primary('save', '<i class="fa fa-save"></i> ' . __('Save', 'newsletter'), $function);
751
  }
752
+
753
 
754
  function button_reset($data = '') {
755
  echo '<button class="button-secondary" onclick="this.form.btn.value=\'' . esc_attr($data) . '\';this.form.act.value=\'reset\';if (!confirm(\'';
796
 
797
  function button_primary($action, $label, $function = null) {
798
  if ($function != null) {
799
+ echo '<button class="button-primary" onclick="this.form.act.value=\'' . esc_attr($action) . '\';' . esc_attr($function) . '">', $label, '</button>';
800
  } else {
801
+ echo '<button class="button-primary" onclick="this.form.act.value=\'' . esc_attr($action) . '\';this.form.submit()"/>', $label, '</button>';
802
  }
803
  }
804
 
805
  function button_confirm($action, $label, $message = '', $data = '') {
806
  if (empty($message)) {
807
+ $message = __('Are you sure?', 'newsletter');
 
 
 
808
  }
809
+
810
+ echo '<input class="button-secondary" type="button" value="' . esc_attr($label) . '" onclick="this.form.btn.value=\'' . esc_attr($data) . '\';this.form.act.value=\'' . esc_attr($action) . '\';if (confirm(\'' .
811
+ esc_attr(esc_js($message)) . '\')) this.form.submit()"/>';
812
  }
813
 
814
  function editor($name, $rows = 5, $cols = 75) {
821
  $value = $this->get_value($name);
822
  wp_editor($value, $name, array_merge(array(
823
  'tinymce' => array('content_css' => plugins_url('newsletter') . '/css/wp-editor.css?ver=' . filemtime(NEWSLETTER_DIR . '/css/wp-editor.css')),
824
+ 'textarea_name' => 'options[' . esc_attr($name) . ']',
825
  'wpautop' => false
826
+ ), $settings));
827
  //echo '<p class="description">You can install <a href="https://wordpress.org/plugins/tinymce-advanced/" target="_blank">TinyMCE Advanced</a> for advanced editing features</p>';
828
  }
829
 
856
  echo esc_html($value);
857
  echo '</textarea>';
858
  echo '<div id="options-' . esc_attr($name) . '-preview" style="box-sizing: border-box; background-color: #eee; border: 1px solid #bbb; padding: 15px; width: auto; position: absolute; top: 20px; left: 20px; box-shadow: 0 0 20px #777; z-index: 10000; display: none">';
859
+ echo '<iframe id="options-' . esc_attr($name) . '-iframe" class="tnp-editor-preview-desktop"></iframe>';
860
+ echo '<iframe id="options-' . esc_attr($name) . '-iframe-phone" class="tnp-editor-preview-mobile"></iframe>';
861
  echo '</div>';
862
  echo '</div>';
863
  }
864
 
865
+ function email($prefix, $editor = null, $disable_option = false, $settings = array()) {
866
  if ($disable_option) {
867
  $this->disabled($prefix . '_disabled');
868
  echo '<br>';
870
 
871
  $this->text($prefix . '_subject', 90, 'Subject');
872
  echo '<br><br>';
873
+
874
  if ($editor == 'wordpress') {
875
+ $this->wp_editor($prefix . '_message', $settings);
876
  } else if ($editor == 'textarea') {
877
  $this->textarea($prefix . '_message');
878
  } else {
953
  }
954
 
955
  function color($name) {
956
+
957
  $value = $this->get_value($name);
958
  echo '<input id="options-', esc_attr($name), '" class="tnp-controls-color" name="options[' . $name . ']" type="text" size="' . $size . '" value="';
959
  echo esc_attr($value);
960
  echo '">';
 
961
  }
962
 
963
  /** Creates a set of checkbox named $name_[category id] (so they are posted with distinct names).
999
  * Empty preferences are skipped.
1000
  */
1001
  function preferences($name = 'preferences') {
1002
+ $lists = NewsletterSubscription::instance()->options_lists;
1003
  echo '<div class="newsletter-preferences-group">';
1004
 
1005
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1006
+ if (empty($lists['list_' . $i])) {
1007
  continue;
1008
  }
1009
  echo '<div class="newsletter-preferences-item">';
1010
+ $this->checkbox2($name . '_' . $i, esc_html($lists['list_' . $i]));
1011
  echo '</div>';
1012
  }
1013
  }
1018
  * will be an array if at east one preference is checked).
1019
  */
1020
  function preferences_group($name = 'preferences') {
1021
+ $lists = NewsletterSubscription::instance()->options_lists;
1022
 
1023
  echo '<div class="newsletter-preferences-group">';
1024
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1025
+ if (empty($lists['list_' . $i])) {
1026
  continue;
1027
  }
1028
  echo '<div class="newsletter-preferences-item">';
1029
+ $this->checkbox_group($name, $i, '(' . $i . ') ' . esc_html($lists['list_' . $i]));
1030
  echo '</div>';
1031
  }
1032
  echo '<div style="clear: both"></div>';
1040
  * 'any', 'yes', 'no' corresponding to the values 0, 1, 2.
1041
  */
1042
  function preferences_selects($name = 'preferences', $skip_empty = false) {
1043
+ $lists = NewsletterSubscription::instance()->options_lists;
1044
 
1045
  echo '<div class="newsletter-preferences-group">';
1046
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1047
+ if (empty($lists['list_' . $i])) {
1048
  continue;
1049
  }
1050
 
1051
  echo '<div class="newsletter-preferences-item">';
1052
 
1053
  $this->select($name . '_' . $i, array(0 => 'Any', 1 => 'Yes', 2 => 'No'));
1054
+ echo '(' . $i . ') ' . esc_html($lists['list_' . $i]);
1055
 
1056
  echo '</div>';
1057
  }
1064
  * Creates a single select with the active preferences.
1065
  */
1066
  function preferences_select($name = 'preference', $empty_label = null) {
1067
+ $options = NewsletterSubscription::instance()->options_lists;
1068
 
1069
  $lists = array();
1070
  if ($empty_label) {
1071
  $lists[''] = $empty_label;
1072
  }
1073
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1074
+ $lists['' . $i] = '(' . $i . ') ' . $options['list_' . $i];
1075
  }
1076
  $this->select($name, $lists);
1077
  echo ' <a href="admin.php?page=newsletter_subscription_lists" target="_blank"><i class="fa fa-edit"></i></a>';
1078
  }
1079
+
1080
+ function lists_select($name = 'list', $empty_label = null) {
1081
+ $objs = Newsletter::instance()->get_lists();
1082
+ $lists = array();
1083
+ if ($empty_label) {
1084
+ $lists[''] = $empty_label;
1085
+ }
1086
+ foreach ($objs as $list) {
1087
+ $lists['' . $list->id] = '[' . $list->id . '] ' . $list->name;
1088
+ }
1089
+ $this->select($name, $lists);
1090
+ }
1091
+
1092
  /**
1093
  * Generates an associative array with the active lists to be used in a select.
1094
  * @param string $empty_label
1095
  * @return array
1096
  */
1097
  function get_list_options($empty_label = null) {
1098
+ $options_profile = NewsletterSubscription::instance()->options_lists;
1099
  $lists = array();
1100
  if ($empty_label) {
1101
  $lists[''] = $empty_label;
1336
  }
1337
  echo '</select>&nbsp;px';
1338
  }
1339
+
1340
  function css_font_family($name = 'font_family') {
1341
  $value = $this->get_value($name);
1342
 
1343
  $fonts = array('Helvetica, Arial, sans-serif', 'Arial Black, Gadget, sans-serif', 'Garamond, serif', 'Courier, monospace', 'Cominc Sans MS, cursive', 'Impact, Charcoal, sans-serif',
1344
  'Tahoma, Geneva, sans-serif', 'Times New Roman, Times, serif', 'Verdana, Geneva, sans-serif');
1345
+
1346
  echo '<select id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']">';
1347
  foreach ($fonts as $font) {
1348
  echo '<option value="', esc_attr($font), '"';
1352
  echo '>', esc_html($font), '</option>';
1353
  }
1354
  echo '</select>';
1355
+ }
1356
+
1357
  function css_text_align($name) {
1358
+ $options = array('left' => __('Left', 'newsletter'), 'right' => __('Right', 'newsletter'),
1359
+ 'center' => __('Center', 'newsletter'));
1360
  $this->select($name, $options);
1361
+ }
1362
 
1363
  function css_border($name) {
1364
  $value = $this->get_value($name . '_width');
1456
  }
1457
  if ($left) {
1458
  if ($time - time() < 0) {
1459
+ $buffer .= ', ' . (time() - $time) . ' seconds late';
1460
  } else {
1461
  $buffer .= ', ' . gmdate('H:i:s', $time - time()) . ' left';
1462
  }
1463
  }
1464
  return $buffer;
1465
  }
1466
+
1467
  /**
1468
  * Prints the help button near a form field. The label is used as icon title.
1469
  *
1470
  * @param string $url
1471
  * @param string $label
1472
  */
1473
+ static function help($url, $label = '') {
1474
  echo '<a href="', $url, '" target="_blank" title="', esc_attr($label), '"><i class="fa fa-question-circle-o"></i></a>';
1475
  }
1476
+
1477
+ static function idea($url, $label = '') {
1478
  echo '<a href="', $url, '" target="_blank" title="', esc_attr($label), '"><i class="fa fa-lightbulb-o"></i></a>';
1479
  }
1480
+
1481
  static function field_help($url, $text = '') {
1482
+ if (empty($text))
1483
+ $text = __('Read more', 'newsletter');
1484
  echo '<i class="fa fa-question-circle"></i>&nbsp;<a href="', $url, '" target="_blank">', $text, '</a>';
1485
  }
1486
+
1487
  /**
1488
  * Prints a panel link to the documentation.
1489
  *
1491
  * @param type $text
1492
  */
1493
  static function panel_help($url, $text = '') {
1494
+ if (empty($text))
1495
+ $text = __('Need help?', 'newsletter');
1496
  echo '<span class="tnp-panel-help"><a href="', $url, '" target="_blank">', $text, '</a></span>';
1497
  }
1498
+
1499
  /**
1500
  * Prints an administration page link to the documentation (just under the administration page title.
1501
  * @param type $url
1502
  * @param type $text
1503
  */
1504
  static function page_help($url, $text = '') {
1505
+ if (empty($text))
1506
+ $text = __('Need help?', 'newsletter');
1507
  echo '<div class="tnp-page-help"><a href="', $url, '" target="_blank">', $text, '</a></div>';
1508
  }
1509
+
1510
+ static function print_truncated($text, $size = 50) {
1511
+ if (mb_strlen($text) < $size)
1512
+ return esc_html($text);
1513
  $sub = mb_substr($text, 0, $size);
1514
  echo '<span title="', esc_attr($text), '">', esc_html($sub), '...</span>';
1515
  }
includes/logger.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
3
 
4
  if (!defined('NEWSLETTER_LOG_DIR')) {
5
  define('NEWSLETTER_LOG_DIR', WP_CONTENT_DIR . '/logs/newsletter/');
@@ -35,9 +35,21 @@ class NewsletterLogger {
35
  $this->file = NEWSLETTER_LOG_DIR . '/' . $module . '-' . date('Y-m') . '-' . $secret . '.txt';
36
  }
37
 
 
 
 
 
 
38
  function log($text, $level = self::ERROR) {
39
-
 
40
  if ($this->level < $level) return;
 
 
 
 
 
 
41
 
42
  $time = date('d-m-Y H:i:s ');
43
  switch ($level) {
@@ -56,14 +68,17 @@ class NewsletterLogger {
56
  } else {
57
  if (is_array($text) || is_object($text)) $text = print_r($text, true);
58
  }
 
59
  // The "logs" dir is created on Newsletter constructor.
60
- $current_user_id = 0;
61
- if (function_exists('get_current_user_id')) $current_user_id = get_current_user_id();
62
- $res = @file_put_contents($this->file, $time . ' - m: ' . size_format(memory_get_usage(), 1) . ', u: ' . $current_user_id . ' - ' . $text . "\n", FILE_APPEND | FILE_TEXT);
63
  if ($res === false) {
64
  $this->level = self::NONE;
65
  }
66
  }
 
 
 
 
67
 
68
  function error($text) {
69
  self::log($text, self::ERROR);
1
  <?php
2
+ defined('ABSPATH') || exit;
3
 
4
  if (!defined('NEWSLETTER_LOG_DIR')) {
5
  define('NEWSLETTER_LOG_DIR', WP_CONTENT_DIR . '/logs/newsletter/');
35
  $this->file = NEWSLETTER_LOG_DIR . '/' . $module . '-' . date('Y-m') . '-' . $secret . '.txt';
36
  }
37
 
38
+ /**
39
+ *
40
+ * @param string|WP_Error|array|stdClass $text
41
+ * @param int $level
42
+ */
43
  function log($text, $level = self::ERROR) {
44
+ global $current_user;
45
+
46
  if ($this->level < $level) return;
47
+
48
+ if ($current_user) {
49
+ $user_id = $current_user->ID;
50
+ } else {
51
+ $user_id = 0;
52
+ }
53
 
54
  $time = date('d-m-Y H:i:s ');
55
  switch ($level) {
68
  } else {
69
  if (is_array($text) || is_object($text)) $text = print_r($text, true);
70
  }
71
+
72
  // The "logs" dir is created on Newsletter constructor.
73
+ $res = @file_put_contents($this->file, $time . ' - m: ' . size_format(memory_get_usage(), 1) . ', u: ' . $user_id . ' - ' . $text . "\n", FILE_APPEND | FILE_TEXT);
 
 
74
  if ($res === false) {
75
  $this->level = self::NONE;
76
  }
77
  }
78
+
79
+ function get_user_id() {
80
+
81
+ }
82
 
83
  function error($text) {
84
  self::log($text, self::ERROR);
includes/module.php CHANGED
@@ -2,6 +2,48 @@
2
 
3
  defined('ABSPATH') || exit;
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  class NewsletterModule {
6
 
7
  /**
@@ -44,12 +86,15 @@ class NewsletterModule {
44
  * @var NewsletterThemes
45
  */
46
  var $themes;
 
47
 
48
- function __construct($module, $version, $module_id = null) {
49
  $this->module = $module;
50
  $this->version = $version;
51
  $this->module_id = $module_id;
52
  $this->prefix = 'newsletter_' . $module;
 
 
53
 
54
 
55
  $this->logger = new NewsletterLogger($module);
@@ -81,17 +126,37 @@ class NewsletterModule {
81
  }
82
 
83
  /**
84
- * Exceutes a query and log it.
 
 
85
  */
86
  function query($query) {
87
  global $wpdb;
88
 
89
- $this->log($query, 3);
90
- return $wpdb->query($query);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  }
92
 
93
  function first_install() {
94
-
95
  }
96
 
97
  /**
@@ -100,25 +165,18 @@ class NewsletterModule {
100
  * internal $options.
101
  */
102
  function upgrade() {
103
- $default_options = $this->get_default_options();
104
- if (empty($this->options) || !is_array($this->options)) {
105
- $this->save_options($default_options);
106
- } else {
107
- $this->save_options(array_merge($default_options, $this->options));
108
  }
109
  }
110
 
111
- function init_options($sub, $autoload = true) {
112
  global $wpdb;
113
- $default_options = $this->get_default_options($sub);
114
- $options = $this->get_options($sub);
115
  $options = array_merge($default_options, $options);
116
- $this->save_options($options, $sub);
117
- if ($autoload) {
118
- $this->upgrade_query('update ' . $wpdb->options . " set autoload='yes' where option_name='" . esc_sql($this->get_prefix($sub)) . "' limit 1");
119
- } else {
120
- $this->upgrade_query('update ' . $wpdb->options . " set autoload='no' where option_name='" . esc_sql($this->get_prefix($sub)) . "' limit 1");
121
- }
122
  }
123
 
124
  function upgrade_query($query) {
@@ -170,12 +228,10 @@ class NewsletterModule {
170
 
171
  function get_default_options($sub = '') {
172
  if (!empty($sub)) {
173
- $sub .= '-';
174
- }
175
- @include NEWSLETTER_DIR . '/' . $this->module . '/languages/' . $sub . 'en_US.php';
176
- if (defined('WPLANG') && WPLANG != 'en_US') {
177
- @include NEWSLETTER_DIR . '/' . $this->module . '/languages/' . $sub . WPLANG . '.php';
178
  }
 
 
179
  if (!isset($options) || !is_array($options)) {
180
  return array();
181
  }
@@ -184,7 +240,7 @@ class NewsletterModule {
184
 
185
  function reset_options($sub = '') {
186
  $this->save_options(array_merge($this->get_options($sub), $this->get_default_options($sub)), $sub);
187
- return $this->options;
188
  }
189
 
190
  /**
@@ -198,16 +254,13 @@ class NewsletterModule {
198
  * @param array $options
199
  * @param string $sub
200
  */
201
- function save_options($options, $sub = '') {
202
- update_option($this->get_prefix($sub), $options);
203
  if (empty($sub)) {
204
  $this->options = $options;
205
  if (isset($this->themes) && isset($options['theme'])) {
206
  $this->themes->save_options($options['theme'], $options);
207
  }
208
- // TODO: To be remove since there is no more log level at module level (should it be reintroduced?)
209
- if (isset($options['log_level']))
210
- update_option('newsletter_' . $this->module . '_log_level', $options['log_level']);
211
  }
212
  }
213
 
@@ -625,16 +678,25 @@ class NewsletterModule {
625
  */
626
  function get_email($id, $format = OBJECT) {
627
  $email = $this->store->get_single(NEWSLETTER_EMAILS_TABLE, $id, $format);
628
- if (!$email)
629
- return $email;
 
630
  if ($format == OBJECT) {
631
  $email->options = maybe_unserialize($email->options);
632
- if (!is_array($email->options))
633
  $email->options = array();
 
 
 
 
634
  } else if ($format == ARRAY_A) {
635
  $email['options'] = maybe_unserialize($email['options']);
636
- if (!is_array($email['options']))
637
  $email['options'] = array();
 
 
 
 
638
  }
639
  return $email;
640
  }
@@ -668,6 +730,19 @@ class NewsletterModule {
668
  return $email;
669
  }
670
 
 
 
 
 
 
 
 
 
 
 
 
 
 
671
  function delete_email($id) {
672
  global $wpdb;
673
  $r = $this->store->delete(NEWSLETTER_EMAILS_TABLE, $id);
@@ -708,6 +783,11 @@ class NewsletterModule {
708
  if (is_object($type))
709
  $type = $type->type;
710
 
 
 
 
 
 
711
  switch ($type) {
712
  case 'followup':
713
  return 'Followup';
@@ -718,7 +798,7 @@ class NewsletterModule {
718
  }
719
 
720
  if (strpos($type, 'automated') === 0) {
721
- list($a, $id) = explode('_', $type->type);
722
  return 'Automated Channel ' . $id;
723
  }
724
 
@@ -765,8 +845,8 @@ class NewsletterModule {
765
  *
766
  * @global type $wpdb
767
  * @param string|int|object|array $id_or_email
768
- * @param type $format
769
- * @return boolean
770
  */
771
  function get_user($id_or_email, $format = OBJECT) {
772
  global $wpdb;
@@ -793,13 +873,22 @@ class NewsletterModule {
793
  return $r;
794
  }
795
 
 
 
 
 
 
 
 
 
 
796
  /**
797
  * Return the user identified by the "nk" parameter (POST or GET).
798
- * If no user can be found, returns null.
799
- * If die_on_fail is true, it dies.
800
  *
801
  * @param bool $die_on_fail
802
- * @return type
803
  */
804
  function get_user_from_request($die_on_fail = false) {
805
  $id = 0;
@@ -818,16 +907,114 @@ class NewsletterModule {
818
  return $user;
819
  }
820
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
821
  function get_list($id) {
822
  global $wpdb;
823
  $id = (int) $id;
824
- if (!$id)
825
  return null;
826
- $list = get_option('newsletter_list_' . $id, array());
827
- $profile = get_option('newsletter_profile');
828
- $list['name'] = $profile['list_' . $id];
829
- $list['subscriber_count'] = $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C' and list_" . $id . "=1");
830
- $list['status'] = (int) $profile['list_' . $id . '_status'];
 
 
 
831
  return $list;
832
  }
833
 
@@ -837,7 +1024,7 @@ class NewsletterModule {
837
  * Saves a new user on the database. Return false if the email (that must be unique) is already
838
  * there. For a new users set the token and creation time if not passed.
839
  *
840
- * @param array|object $user
841
  */
842
  function save_user($user, $return_format = OBJECT) {
843
  if (is_object($user)) {
@@ -859,6 +1046,11 @@ class NewsletterModule {
859
  return $this->store->save(NEWSLETTER_USERS_TABLE, $user, $return_format);
860
  }
861
 
 
 
 
 
 
862
  function inline_css($content, $strip_style_blocks = false) {
863
  // CSS
864
  $matches = array();
@@ -887,7 +1079,7 @@ class NewsletterModule {
887
 
888
  /**
889
  * Returns a list of users marked as "test user".
890
- * @return array
891
  */
892
  function get_test_users() {
893
  return $this->store->get_all(NEWSLETTER_USERS_TABLE, "where test=1");
@@ -895,60 +1087,96 @@ class NewsletterModule {
895
 
896
  function delete_user($id) {
897
  global $wpdb;
898
- $r = $this->store->delete(NEWSLETTER_USERS_TABLE, $id);
899
- if ($r !== false) {
900
- $wpdb->delete(NEWSLETTER_STATS_TABLE, array('user_id' => $id));
901
- $wpdb->delete(NEWSLETTER_SENT_TABLE, array('user_id' => $id));
902
  }
 
 
 
 
 
903
  }
904
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
905
  function anonymize_ip($ip) {
906
- if (empty($ip)) return $ip;
 
 
907
  $parts = explode('.', $ip);
908
  array_pop($parts);
909
  return implode('.', $parts);
910
  }
911
-
912
  function anonymize_user($id) {
913
  global $wpdb;
914
  $user = $this->get_user($id);
915
- if (!$user) return null;
916
-
 
917
  $user->name = '';
918
  $user->surname = '';
919
  $user->ip = $this->anonymize_ip($user->ip);
920
-
921
- for ($i=1; $i<=NEWSLETTER_PROFILE_MAX; $i++) {
922
  $field = 'profile_' . $i;
923
  $user->$field = '';
924
  }
925
-
926
  // [TODO] Status?
927
  $user->status = 'U';
928
  $user->email = $user->id . '@anonymi.zed';
929
-
930
  $user = $this->save_user($user);
931
-
932
  return $user;
933
- }
934
 
935
  /**
936
- *
937
- * @global Newsletter $newsletter
938
  * @param int|string $id_or_email
939
  * @param string $status
940
  * @return boolean
941
  */
942
- function set_user_status($id_or_email, $status) {
943
  global $wpdb;
944
  $status = (string) $status;
945
  $this->logger->debug('Status change to ' . $status . ' of subscriber ' . $id_or_email . ' from ' . $_SERVER['REQUEST_URI']);
946
 
947
- $id_or_email = strtolower(trim($id_or_email));
948
- if (is_numeric($id_or_email)) {
949
- $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where id=%d limit 1", $status, $id_or_email));
950
  } else {
951
- $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where email=%s limit 1", $status, $id_or_email));
 
 
 
 
 
952
  }
953
 
954
  if ($wpdb->last_error) {
@@ -958,12 +1186,45 @@ class NewsletterModule {
958
  return $r;
959
  }
960
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
961
  function set_user_list($user, $list, $value) {
962
  global $wpdb;
963
 
964
  $list = (int) $list;
965
- $value = $value ? 0 : 1;
966
- $wpdb->update(NEWSLETTER_USERS_TABLE, array('list_' . $list => $value), array('id' => $user->id));
967
  }
968
 
969
  function set_user_field($id, $field, $value) {
@@ -974,6 +1235,12 @@ class NewsletterModule {
974
  $this->store->set_field(NEWSLETTER_USERS_TABLE, $user_id, 'wp_user_id', $wp_user_id);
975
  }
976
 
 
 
 
 
 
 
977
  function get_user_by_wp_user_id($wp_user_id, $format = OBJECT) {
978
  return $this->store->get_single_by_field(NEWSLETTER_USERS_TABLE, 'wp_user_id', $wp_user_id, $format);
979
  }
@@ -991,6 +1258,12 @@ class NewsletterModule {
991
  function replace($text, $user = null, $email = null, $referrer = null) {
992
  global $wpdb;
993
 
 
 
 
 
 
 
994
  //$this->logger->debug('Replace start');
995
  if ($user !== null && !is_object($user)) {
996
  if (is_array($user)) {
@@ -1015,8 +1288,8 @@ class NewsletterModule {
1015
 
1016
  $text = apply_filters('newsletter_replace', $text, $user, $email);
1017
 
1018
- $text = $this->replace_url($text, 'BLOG_URL', home_url('/'));
1019
- $text = $this->replace_url($text, 'HOME_URL', home_url('/'));
1020
 
1021
  $text = str_replace('{blog_title}', get_option('blogname'), $text);
1022
  $text = str_replace('{blog_description}', get_option('blogdescription'), $text);
@@ -1024,6 +1297,7 @@ class NewsletterModule {
1024
  $text = $this->replace_date($text);
1025
 
1026
  if ($user) {
 
1027
  $options_profile = get_option('newsletter_profile');
1028
 
1029
  $text = str_replace('{email}', $user->email, $text);
@@ -1063,12 +1337,8 @@ class NewsletterModule {
1063
  $text = str_replace('{id}', $user->id, $text);
1064
  $text = str_replace('%7Bid%7D', $user->id, $text);
1065
  $text = str_replace('{ip}', $user->ip, $text);
1066
- $text = str_replace('{key}', $user->id . '-' . $user->token, $text);
1067
- $text = str_replace('%7Bkey%7D', $user->id . '-' . $user->token, $text);
1068
-
1069
- if (strpos($text, '{profile_form}') !== false) {
1070
- $text = str_replace('{profile_form}', NewsletterSubscription::instance()->get_profile_form_html5($user), $text);
1071
- }
1072
 
1073
  for ($i = 1; $i < NEWSLETTER_PROFILE_MAX; $i++) {
1074
  $p = 'profile_' . $i;
@@ -1077,28 +1347,33 @@ class NewsletterModule {
1077
 
1078
  $base = (empty($this->options_main['url']) ? get_option('home') : $this->options_main['url']);
1079
  $id_token = '&amp;ni=' . $user->id . '&amp;nt=' . $user->token;
1080
- $nk = $user->id . '-' . $user->token;
1081
 
1082
  $options_subscription = NewsletterSubscription::instance()->options;
1083
 
1084
- $home_url = home_url('/');
1085
 
1086
  $nek = false;
1087
  if ($email) {
 
1088
  $text = str_replace('{email_id}', $email->id, $text);
1089
- $text = str_replace('{email_key}', $email->id . '-' . $email->token, $text);
1090
  $text = str_replace('{email_subject}', $email->subject, $text);
1091
  $text = $this->replace_url($text, 'EMAIL_URL', $home_url . '?na=v&id=' . $email->id . '&amp;nk=' . $nk);
1092
- $nek = $email->id . '-' . $email->token;
1093
  }
1094
 
1095
 
 
 
 
1096
  $text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', $home_url . '?na=c&nk=' . $nk);
1097
  $text = $this->replace_url($text, 'ACTIVATION_URL', $home_url . '?na=c&nk=' . $nk);
1098
 
1099
  $text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', $home_url . '?na=uc&nk=' . $nk . ($nek ? '&nek=' . $nek : ''));
1100
  $text = $this->replace_url($text, 'UNSUBSCRIPTION_URL', $home_url . '?na=u&nk=' . $nk . ($nek ? '&nek=' . $nek : ''));
1101
 
 
 
1102
  // Obsolete.
1103
  $text = $this->replace_url($text, 'FOLLOWUP_SUBSCRIPTION_URL', self::add_qs($base, 'nm=fs' . $id_token));
1104
  $text = $this->replace_url($text, 'FOLLOWUP_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=fu' . $id_token));
@@ -1133,6 +1408,13 @@ class NewsletterModule {
1133
  }
1134
  }
1135
  }
 
 
 
 
 
 
 
1136
 
1137
  //$this->logger->debug('Replace end');
1138
  return $text;
@@ -1148,13 +1430,16 @@ class NewsletterModule {
1148
  if ($y === false)
1149
  continue;
1150
  $f = substr($text, $x + 6, $y - $x - 6);
1151
- $text = substr($text, 0, $x) . date($f) . substr($text, $y + 1);
1152
  }
1153
  return $text;
1154
  }
1155
 
1156
  function replace_url($text, $tag, $url) {
1157
- $home = trailingslashit(home_url());
 
 
 
1158
  $tag_lower = strtolower($tag);
1159
  $text = str_replace('http://{' . $tag_lower . '}', $url, $text);
1160
  $text = str_replace('https://{' . $tag_lower . '}', $url, $text);
@@ -1163,8 +1448,9 @@ class NewsletterModule {
1163
  $text = str_replace('{' . $tag_lower . '}', $url, $text);
1164
  $text = str_replace('%7B' . $tag_lower . '%7D', $url, $text);
1165
 
1166
- $text = str_replace('%7B' . $tag_lower . '_encoded%7D', urlencode($url), $text);
1167
- $text = str_replace('{' . $tag_lower . '_encoded}', urlencode($url), $text);
 
1168
 
1169
  // for compatibility
1170
  $text = str_replace($home . $tag, $url, $text);
@@ -1173,8 +1459,10 @@ class NewsletterModule {
1173
  }
1174
 
1175
  public static function antibot_form_check($captcha = false) {
1176
- if (strtolower($_SERVER['REQUEST_METHOD']) != 'post') return false;
1177
-
 
 
1178
  if (!isset($_POST['ts']) || time() - $_POST['ts'] > 60) {
1179
  return false;
1180
  }
@@ -1192,7 +1480,7 @@ class NewsletterModule {
1192
  return false;
1193
  }
1194
  }
1195
-
1196
  return true;
1197
  }
1198
 
@@ -1303,6 +1591,26 @@ class NewsletterModule {
1303
  return self::sanitize_ip($_SERVER['REMOTE_ADDR']);
1304
  }
1305
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1306
  }
1307
 
1308
  /**
2
 
3
  defined('ABSPATH') || exit;
4
 
5
+ /**
6
+ * @property int $id The list unique identifier
7
+ * @property string $name The list name
8
+ * @property bool $forced If the list must be added to every new subscriber
9
+ * @property int $status When and how the list is visible to the subscriber - see constants
10
+ * @property bool $checked If it must be pre-checked on subscription form
11
+ * */
12
+ abstract class TNP_List {
13
+
14
+ const STAUTS_PRIVATE = 0;
15
+ const STAUTS_PUBLIC = 1;
16
+ const STAUTS_PROFILE_ONLY = 2;
17
+ const STAUTS_HIDDEN = 3; // Public but never show (can be set with a hidden form field)
18
+
19
+ }
20
+
21
+ /**
22
+ * @property int $id The subscriber unique identifier
23
+ * @property string $email The subscriber email
24
+ * @property string $name The subscriber name or first name
25
+ * @property string $surname The subscriber last name
26
+ * @property string $status The subscriber status
27
+ * */
28
+ abstract class TNP_User {
29
+
30
+ const STAUTS_CONFIRMED = 'C';
31
+ const STAUTS_NOT_CONFIRMED = 'S';
32
+ const STAUTS_UNSUBSCRIBED = 'U';
33
+ const STAUTS_BOUNCED = 'B';
34
+ }
35
+
36
+ /**
37
+ * @property int $id The subscriber unique identifier
38
+ * @property string $subject The subscriber email
39
+ * @property string $message The subscriber name or first name
40
+ * @property string $track The subscriber last name
41
+ * @property array $options The subscriber status
42
+ * */
43
+ abstract class TNP_Email {
44
+
45
+ }
46
+
47
  class NewsletterModule {
48
 
49
  /**
86
  * @var NewsletterThemes
87
  */
88
  var $themes;
89
+ var $components;
90
 
91
+ function __construct($module, $version, $module_id = null, $components = array()) {
92
  $this->module = $module;
93
  $this->version = $version;
94
  $this->module_id = $module_id;
95
  $this->prefix = 'newsletter_' . $module;
96
+ array_unshift($components, '');
97
+ $this->components = $components;
98
 
99
 
100
  $this->logger = new NewsletterLogger($module);
126
  }
127
 
128
  /**
129
+ *
130
+ * @global wpdb $wpdb
131
+ * @param string $query
132
  */
133
  function query($query) {
134
  global $wpdb;
135
 
136
+ $this->logger->debug($query);
137
+ $r = $wpdb->query($query);
138
+ if ($r === false) {
139
+ $this->logger->fatal($wpdb->last_error);
140
+ }
141
+ }
142
+
143
+ /**
144
+ *
145
+ * @global wpdb $wpdb
146
+ * @param string $table
147
+ * @param array $data
148
+ */
149
+ function insert($table, $data) {
150
+ global $wpdb;
151
+ $this->logger->debug("inserting into table $table");
152
+ $wpdb->insert($table, $data);
153
+ if ($r === false) {
154
+ $this->logger->fatal($wpdb->last_error);
155
+ }
156
  }
157
 
158
  function first_install() {
159
+ $this->logger->debug('First install');
160
  }
161
 
162
  /**
165
  * internal $options.
166
  */
167
  function upgrade() {
168
+ foreach ($this->components as $component) {
169
+ $this->logger->debug('Upgrading component ' . $component);
170
+ $this->init_options($component);
 
 
171
  }
172
  }
173
 
174
+ function init_options($component = '', $autoload = true) {
175
  global $wpdb;
176
+ $default_options = $this->get_default_options($component);
177
+ $options = $this->get_options($component);
178
  $options = array_merge($default_options, $options);
179
+ $this->save_options($options, $component, $autoload);
 
 
 
 
 
180
  }
181
 
182
  function upgrade_query($query) {
228
 
229
  function get_default_options($sub = '') {
230
  if (!empty($sub)) {
231
+ $sub = '-' . $sub;
 
 
 
 
232
  }
233
+ include NEWSLETTER_DIR . '/' . $this->module . '/defaults' . $sub . '.php';
234
+
235
  if (!isset($options) || !is_array($options)) {
236
  return array();
237
  }
240
 
241
  function reset_options($sub = '') {
242
  $this->save_options(array_merge($this->get_options($sub), $this->get_default_options($sub)), $sub);
243
+ return $this->get_options($sub);
244
  }
245
 
246
  /**
254
  * @param array $options
255
  * @param string $sub
256
  */
257
+ function save_options($options, $sub = '', $autoload = null) {
258
+ update_option($this->get_prefix($sub), $options, $autoload);
259
  if (empty($sub)) {
260
  $this->options = $options;
261
  if (isset($this->themes) && isset($options['theme'])) {
262
  $this->themes->save_options($options['theme'], $options);
263
  }
 
 
 
264
  }
265
  }
266
 
678
  */
679
  function get_email($id, $format = OBJECT) {
680
  $email = $this->store->get_single(NEWSLETTER_EMAILS_TABLE, $id, $format);
681
+ if (!$email) {
682
+ return null;
683
+ }
684
  if ($format == OBJECT) {
685
  $email->options = maybe_unserialize($email->options);
686
+ if (!is_array($email->options)) {
687
  $email->options = array();
688
+ }
689
+ if (empty($email->query)) {
690
+ $email->query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
691
+ }
692
  } else if ($format == ARRAY_A) {
693
  $email['options'] = maybe_unserialize($email['options']);
694
+ if (!is_array($email['options'])) {
695
  $email['options'] = array();
696
+ }
697
+ if (empty($email['query'])) {
698
+ $email['query'] = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
699
+ }
700
  }
701
  return $email;
702
  }
730
  return $email;
731
  }
732
 
733
+ function get_email_from_request() {
734
+
735
+ if (isset($_REQUEST['nek'])) {
736
+ list($id, $token) = @explode('-', $_REQUEST['nek'], 2);
737
+ } else {
738
+ return null;
739
+ }
740
+
741
+ $email = $this->get_email($id);
742
+
743
+ return $email;
744
+ }
745
+
746
  function delete_email($id) {
747
  global $wpdb;
748
  $r = $this->store->delete(NEWSLETTER_EMAILS_TABLE, $id);
783
  if (is_object($type))
784
  $type = $type->type;
785
 
786
+ $label = apply_filters('newsletter_email_type', '', $type);
787
+
788
+ if (!empty($label))
789
+ return $label;
790
+
791
  switch ($type) {
792
  case 'followup':
793
  return 'Followup';
798
  }
799
 
800
  if (strpos($type, 'automated') === 0) {
801
+ list($a, $id) = explode('_', $type);
802
  return 'Automated Channel ' . $id;
803
  }
804
 
845
  *
846
  * @global type $wpdb
847
  * @param string|int|object|array $id_or_email
848
+ * @param string $format
849
+ * @return TNP_User
850
  */
851
  function get_user($id_or_email, $format = OBJECT) {
852
  global $wpdb;
873
  return $r;
874
  }
875
 
876
+ /**
877
+ * Returns the user unique key
878
+ * @param TNP_User $user
879
+ * @return string
880
+ */
881
+ function get_user_key($user) {
882
+ return $user->id . '-' . $user->token;
883
+ }
884
+
885
  /**
886
  * Return the user identified by the "nk" parameter (POST or GET).
887
+ * If no user can be found or the token is not matching, returns null.
888
+ * If die_on_fail is true it dies instead of return null.
889
  *
890
  * @param bool $die_on_fail
891
+ * @return TNP_User
892
  */
893
  function get_user_from_request($die_on_fail = false) {
894
  $id = 0;
907
  return $user;
908
  }
909
 
910
+ /**
911
+ *
912
+ * @return TNP_List[]
913
+ */
914
+ function get_lists() {
915
+ static $lists = null;
916
+ if (is_array($lists))
917
+ return $lists;
918
+
919
+ $lists = array();
920
+ $data = NewsletterSubscription::instance()->options_lists;
921
+ for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
922
+ if (empty($data['list_' . $i])) {
923
+ continue;
924
+ }
925
+ $list = new stdClass();
926
+ $list->name = $data['list_' . $i];
927
+ $list->id = $i;
928
+ $list->forced = !empty($data['list_' . $i . '_forced']);
929
+ $list->status = (int) $data['list_' . $i . '_status'];
930
+ $list->checked = !empty($data['list_' . $i . '_checked']);
931
+ $lists[] = $list;
932
+ }
933
+ return $lists;
934
+ }
935
+
936
+ /**
937
+ *
938
+ * @return TNP_List[]
939
+ */
940
+ function get_lists_public() {
941
+ static $lists = null;
942
+ if (is_array($lists)) {
943
+ return $lists;
944
+ }
945
+
946
+ $lists = array();
947
+ $all = $this->get_lists();
948
+ foreach ($all as $list) {
949
+ if ($list->status == 0) {
950
+ continue;
951
+ }
952
+ $lists[] = $list;
953
+ }
954
+ return $lists;
955
+ }
956
+
957
+ /**
958
+ *
959
+ * @return TNP_List[]
960
+ */
961
+ function get_lists_for_subscription() {
962
+ static $lists = null;
963
+ if (is_array($lists)) {
964
+ return $lists;
965
+ }
966
+
967
+ $lists = array();
968
+ $all = $this->get_lists();
969
+ foreach ($all as $list) {
970
+ if ($list->status != 2 || $list->forced) {
971
+ continue;
972
+ }
973
+ $lists[] = $list;
974
+ }
975
+ return $lists;
976
+ }
977
+
978
+ /**
979
+ *
980
+ * @return TNP_List[]
981
+ */
982
+ function get_lists_for_profile() {
983
+ static $lists = null;
984
+ if (is_array($lists)) {
985
+ return $lists;
986
+ }
987
+
988
+ $lists = array();
989
+ $all = $this->get_lists();
990
+ foreach ($all as $list) {
991
+ if ($list->status == 0 || $list->status == 3) {
992
+ continue;
993
+ }
994
+ $lists[] = $list;
995
+ }
996
+ return $lists;
997
+ }
998
+
999
+ /**
1000
+ *
1001
+ * @global wpdb $wpdb
1002
+ * @param int $id
1003
+ * @return TNP_List
1004
+ */
1005
  function get_list($id) {
1006
  global $wpdb;
1007
  $id = (int) $id;
1008
+ if (!$id) {
1009
  return null;
1010
+ }
1011
+ $data = NewsletterSubscription::instance()->options_lists;
1012
+ $list = new stdClass();
1013
+ $list->name = $data['list_' . $id];
1014
+ $list->id = $id;
1015
+ $list->forced = !empty($data['list_' . $id . '_forced']);
1016
+ $list->status = (int) $data['list_' . $id . '_status'];
1017
+ $list->checked = !empty($data['list_' . $id . '_checked']);
1018
  return $list;
1019
  }
1020
 
1024
  * Saves a new user on the database. Return false if the email (that must be unique) is already
1025
  * there. For a new users set the token and creation time if not passed.
1026
  *
1027
+ * @param TNP_User $user
1028
  */
1029
  function save_user($user, $return_format = OBJECT) {
1030
  if (is_object($user)) {
1046
  return $this->store->save(NEWSLETTER_USERS_TABLE, $user, $return_format);
1047
  }
1048
 
1049
+ function update_user_last_activity($user) {
1050
+ global $wpdb;
1051
+ $this->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set last_activity=%d where id=%d limit 1", time(), $user->id));
1052
+ }
1053
+
1054
  function inline_css($content, $strip_style_blocks = false) {
1055
  // CSS
1056
  $matches = array();
1079
 
1080
  /**
1081
  * Returns a list of users marked as "test user".
1082
+ * @return TNP_User[]
1083
  */
1084
  function get_test_users() {
1085
  return $this->store->get_all(NEWSLETTER_USERS_TABLE, "where test=1");
1087
 
1088
  function delete_user($id) {
1089
  global $wpdb;
1090
+ $user = $this->get_user($id);
1091
+ if ($user) {
1092
+ $r = $this->store->delete(NEWSLETTER_USERS_TABLE, $id);
1093
+ do_action('newsletter_user_deleted', $user);
1094
  }
1095
+ // Anyway try a table clean up, nothing bad happens
1096
+ $wpdb->delete(NEWSLETTER_STATS_TABLE, array('user_id' => $id));
1097
+ $wpdb->delete(NEWSLETTER_SENT_TABLE, array('user_id' => $id));
1098
+
1099
+
1100
  }
1101
+
1102
+ function clean_stats_table() {
1103
+ global $wpdb;
1104
+ $this->logger->info('Cleaning up stats table');
1105
+ $this->query("delete s from `{$wpdb->prefix}newsletter_stats` s left join `{$wpdb->prefix}newsletter` u on s.user_id=u.id where u.id is null");
1106
+ $this->query("delete s from `{$wpdb->prefix}newsletter_stats` s left join `{$wpdb->prefix}newsletter_emails` e on s.email_id=e.id where e.id is null");
1107
+ }
1108
+
1109
+ function clean_sent_table() {
1110
+ global $wpdb;
1111
+ $this->logger->info('Cleaning up sent table');
1112
+ $this->query("delete s from `{$wpdb->prefix}newsletter_sent` s left join `{$wpdb->prefix}newsletter` u on s.user_id=u.id where u.id is null");
1113
+ $this->query("delete s from `{$wpdb->prefix}newsletter_sent` s left join `{$wpdb->prefix}newsletter_emails` e on s.email_id=e.id where e.id is null");
1114
+ }
1115
+
1116
+ function clean_user_logs_table() {
1117
+ //global $wpdb;
1118
+ }
1119
+
1120
+ function clean_tables() {
1121
+ $this->clean_sent_table();
1122
+ $this->clean_stats_table();
1123
+ $this->clean_user_logs_table();
1124
+ }
1125
+
1126
  function anonymize_ip($ip) {
1127
+ if (empty($ip)) {
1128
+ return $ip;
1129
+ }
1130
  $parts = explode('.', $ip);
1131
  array_pop($parts);
1132
  return implode('.', $parts);
1133
  }
1134
+
1135
  function anonymize_user($id) {
1136
  global $wpdb;
1137
  $user = $this->get_user($id);
1138
+ if (!$user)
1139
+ return null;
1140
+
1141
  $user->name = '';
1142
  $user->surname = '';
1143
  $user->ip = $this->anonymize_ip($user->ip);
1144
+
1145
+ for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
1146
  $field = 'profile_' . $i;
1147
  $user->$field = '';
1148
  }
1149
+
1150
  // [TODO] Status?
1151
  $user->status = 'U';
1152
  $user->email = $user->id . '@anonymi.zed';
1153
+
1154
  $user = $this->save_user($user);
1155
+
1156
  return $user;
1157
+ }
1158
 
1159
  /**
1160
+ * Changes a user status. Accept a user object, user id or user email.
1161
+ *
1162
  * @param int|string $id_or_email
1163
  * @param string $status
1164
  * @return boolean
1165
  */
1166
+ function set_user_status($user, $status) {
1167
  global $wpdb;
1168
  $status = (string) $status;
1169
  $this->logger->debug('Status change to ' . $status . ' of subscriber ' . $id_or_email . ' from ' . $_SERVER['REQUEST_URI']);
1170
 
1171
+ if (is_object($user)) {
1172
+ $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where id=%d limit 1", $status, $user->id));
 
1173
  } else {
1174
+ $id_or_email = strtolower(trim($id_or_email));
1175
+ if (is_numeric($id_or_email)) {
1176
+ $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where id=%d limit 1", $status, $id_or_email));
1177
+ } else {
1178
+ $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where email=%s limit 1", $status, $id_or_email));
1179
+ }
1180
  }
1181
 
1182
  if ($wpdb->last_error) {
1186
  return $r;
1187
  }
1188
 
1189
+ /**
1190
+ * Create a log entry with the meaningful user data.
1191
+ *
1192
+ * @global wpdb $wpdb
1193
+ * @param TNP_User $user
1194
+ * @param string $source
1195
+ * @return type
1196
+ */
1197
+ function add_user_log($user, $source = '') {
1198
+ global $wpdb;
1199
+ if (!is_object($user)) {
1200
+ return;
1201
+ }
1202
+
1203
+ $options_profile = get_option('newsletter_profile', array());
1204
+ for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1205
+ if ($options_profile['list_' . $i . '_status'] == 0) {
1206
+ continue;
1207
+ }
1208
+ $field_name = 'list_' . $i;
1209
+ $data[$field_name] = $user->$field_name;
1210
+ }
1211
+ $data['status'] = $user->status;
1212
+ $this->store->save($wpdb->prefix . 'newsletter_user_logs', array('user_id' => $user->id, 'source' => $source, 'created' => time(), 'data' => json_encode($data)));
1213
+ }
1214
+
1215
+ /**
1216
+ *
1217
+ * @global wpdb $wpdb
1218
+ * @param TNP_User $user
1219
+ * @param int $list
1220
+ * @param type $value
1221
+ */
1222
  function set_user_list($user, $list, $value) {
1223
  global $wpdb;
1224
 
1225
  $list = (int) $list;
1226
+ $value = $value ? 1 : 0;
1227
+ $r = $wpdb->update(NEWSLETTER_USERS_TABLE, array('list_' . $list => $value), array('id' => $user->id));
1228
  }
1229
 
1230
  function set_user_field($id, $field, $value) {
1235
  $this->store->set_field(NEWSLETTER_USERS_TABLE, $user_id, 'wp_user_id', $wp_user_id);
1236
  }
1237
 
1238
+ /**
1239
+ *
1240
+ * @param int $wp_user_id
1241
+ * @param string $format
1242
+ * @return TNP_User
1243
+ */
1244
  function get_user_by_wp_user_id($wp_user_id, $format = OBJECT) {
1245
  return $this->store->get_single_by_field(NEWSLETTER_USERS_TABLE, 'wp_user_id', $wp_user_id, $format);
1246
  }
1258
  function replace($text, $user = null, $email = null, $referrer = null) {
1259
  global $wpdb;
1260
 
1261
+ static $home_url = false;
1262
+
1263
+ if (!$home_url) {
1264
+ $home_url = home_url('/');
1265
+ }
1266
+
1267
  //$this->logger->debug('Replace start');
1268
  if ($user !== null && !is_object($user)) {
1269
  if (is_array($user)) {
1288
 
1289
  $text = apply_filters('newsletter_replace', $text, $user, $email);
1290
 
1291
+ $text = $this->replace_url($text, 'BLOG_URL', $home_url);
1292
+ $text = $this->replace_url($text, 'HOME_URL', $home_url);
1293
 
1294
  $text = str_replace('{blog_title}', get_option('blogname'), $text);
1295
  $text = str_replace('{blog_description}', get_option('blogdescription'), $text);
1297
  $text = $this->replace_date($text);
1298
 
1299
  if ($user) {
1300
+ $nk = $this->get_user_key($user);
1301
  $options_profile = get_option('newsletter_profile');
1302
 
1303
  $text = str_replace('{email}', $user->email, $text);
1337
  $text = str_replace('{id}', $user->id, $text);
1338
  $text = str_replace('%7Bid%7D', $user->id, $text);
1339
  $text = str_replace('{ip}', $user->ip, $text);
1340
+ $text = str_replace('{key}', $nk, $text);
1341
+ $text = str_replace('%7Bkey%7D', $nk, $text);
 
 
 
 
1342
 
1343
  for ($i = 1; $i < NEWSLETTER_PROFILE_MAX; $i++) {
1344
  $p = 'profile_' . $i;
1347
 
1348
  $base = (empty($this->options_main['url']) ? get_option('home') : $this->options_main['url']);
1349
  $id_token = '&amp;ni=' . $user->id . '&amp;nt=' . $user->token;
1350
+
1351
 
1352
  $options_subscription = NewsletterSubscription::instance()->options;
1353
 
1354
+
1355
 
1356
  $nek = false;
1357
  if ($email) {
1358
+ $nek = $email->id . '-' . $email->token;
1359
  $text = str_replace('{email_id}', $email->id, $text);
1360
+ $text = str_replace('{email_key}', $nek, $text);
1361
  $text = str_replace('{email_subject}', $email->subject, $text);
1362
  $text = $this->replace_url($text, 'EMAIL_URL', $home_url . '?na=v&id=' . $email->id . '&amp;nk=' . $nk);
 
1363
  }
1364
 
1365
 
1366
+ //$text = str_replace('{activation_link}', '<a href="{activation_url}">' . $options_subscription['confirmation_label'] . '</a>', $text);
1367
+
1368
+
1369
  $text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', $home_url . '?na=c&nk=' . $nk);
1370
  $text = $this->replace_url($text, 'ACTIVATION_URL', $home_url . '?na=c&nk=' . $nk);
1371
 
1372
  $text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', $home_url . '?na=uc&nk=' . $nk . ($nek ? '&nek=' . $nek : ''));
1373
  $text = $this->replace_url($text, 'UNSUBSCRIPTION_URL', $home_url . '?na=u&nk=' . $nk . ($nek ? '&nek=' . $nek : ''));
1374
 
1375
+ $text = $this->replace_url($text, 'REACTIVATE_URL', $home_url . '?na=reactivate&nk=' . $nk . ($nek ? '&nek=' . $nek : ''));
1376
+
1377
  // Obsolete.
1378
  $text = $this->replace_url($text, 'FOLLOWUP_SUBSCRIPTION_URL', self::add_qs($base, 'nm=fs' . $id_token));
1379
  $text = $this->replace_url($text, 'FOLLOWUP_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=fu' . $id_token));
1408
  }
1409
  }
1410
  }
1411
+
1412
+ // Company info
1413
+ // TODO: Move to another module
1414
+ $options = Newsletter::instance()->options;
1415
+ $text = str_replace('{company_address}', $options['footer_contact'], $text);
1416
+ $text = str_replace('{company_name}', $options['footer_title'], $text);
1417
+
1418
 
1419
  //$this->logger->debug('Replace end');
1420
  return $text;
1430
  if ($y === false)
1431
  continue;
1432
  $f = substr($text, $x + 6, $y - $x - 6);
1433
+ $text = substr($text, 0, $x) . date_i18n($f) . substr($text, $y + 1);
1434
  }
1435
  return $text;
1436
  }
1437
 
1438
  function replace_url($text, $tag, $url) {
1439
+ static $home = false;
1440
+ if (!$home) {
1441
+ $home = trailingslashit(home_url());
1442
+ }
1443
  $tag_lower = strtolower($tag);
1444
  $text = str_replace('http://{' . $tag_lower . '}', $url, $text);
1445
  $text = str_replace('https://{' . $tag_lower . '}', $url, $text);
1448
  $text = str_replace('{' . $tag_lower . '}', $url, $text);
1449
  $text = str_replace('%7B' . $tag_lower . '%7D', $url, $text);
1450
 
1451
+ $url_encoded = urlencode($url);
1452
+ $text = str_replace('%7B' . $tag_lower . '_encoded%7D', $url_encoded, $text);
1453
+ $text = str_replace('{' . $tag_lower . '_encoded}', $url_encoded, $text);
1454
 
1455
  // for compatibility
1456
  $text = str_replace($home . $tag, $url, $text);
1459
  }
1460
 
1461
  public static function antibot_form_check($captcha = false) {
1462
+ if (strtolower($_SERVER['REQUEST_METHOD']) != 'post') {
1463
+ return false;
1464
+ }
1465
+
1466
  if (!isset($_POST['ts']) || time() - $_POST['ts'] > 60) {
1467
  return false;
1468
  }
1480
  return false;
1481
  }
1482
  }
1483
+
1484
  return true;
1485
  }
1486
 
1591
  return self::sanitize_ip($_SERVER['REMOTE_ADDR']);
1592
  }
1593
 
1594
+ static function get_signature($text) {
1595
+ $key = NewsletterStatistics::instance()->options['key'];
1596
+ return md5($text . $key);
1597
+ }
1598
+
1599
+ static function check_signature($text, $signature) {
1600
+ if (empty($signature))
1601
+ return false;
1602
+ $key = NewsletterStatistics::instance()->options['key'];
1603
+ return md5($text . $key) === $signature;
1604
+ }
1605
+
1606
+ static function get_home_url() {
1607
+ static $url = false;
1608
+ if (!$url) {
1609
+ $url = home_url('/');
1610
+ }
1611
+ return $url;
1612
+ }
1613
+
1614
  }
1615
 
1616
  /**
main/defaults-info.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $options = array(
4
+ 'header_title' => get_bloginfo('name'),
5
+ 'header_sub' => get_bloginfo('description')
6
+ );
main/{languages/smtp-en_US.php → defaults-smtp.php} RENAMED
File without changes
main/{languages/en_US.php → defaults.php} RENAMED
@@ -14,5 +14,8 @@ $options = array(
14
  'editor' => 0,
15
  'scheduler_max' => 100,
16
  'phpmailer'=>0,
17
- 'debug'=>0
 
 
 
18
  );
14
  'editor' => 0,
15
  'scheduler_max' => 100,
16
  'phpmailer'=>0,
17
+ 'debug'=>0,
18
+ 'track'=>1,
19
+ 'css'=>'',
20
+ 'css_disabled'=>0
21
  );
main/info.php CHANGED
@@ -1,6 +1,5 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
 
5
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $module = Newsletter::instance();
@@ -12,7 +11,8 @@ if (!$controls->is_action()) {
12
 
13
  if ($controls->is_action('save')) {
14
  $module->merge_options($controls->data);
15
- $controls->messages .= 'Saved.';
 
16
  }
17
  }
18
  ?>
@@ -157,7 +157,7 @@ if (!$controls->is_action()) {
157
  </div>
158
 
159
  <p>
160
- <?php $controls->button('save', 'Save'); ?>
161
  </p>
162
 
163
  </form>
1
  <?php
2
+ defined('ABSPATH') || exit;
 
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $module = Newsletter::instance();
11
 
12
  if ($controls->is_action('save')) {
13
  $module->merge_options($controls->data);
14
+ $module->save_options($controls->data, 'info');
15
+ $controls->add_message_saved();
16
  }
17
  }
18
  ?>
157
  </div>
158
 
159
  <p>
160
+ <?php $controls->button_save(); ?>
161
  </p>
162
 
163
  </form>
main/main.php CHANGED
@@ -41,6 +41,7 @@ if (!$controls->is_action()) {
41
  if (empty($controls->errors)) {
42
  $module->merge_options($controls->data);
43
  $controls->add_message_saved();
 
44
  }
45
 
46
  update_option('newsletter_log_level', $controls->data['log_level']);
@@ -48,6 +49,23 @@ if (!$controls->is_action()) {
48
  $module->hook_newsletter_extension_versions(true);
49
  delete_transient("tnp_extensions_json");
50
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  }
52
 
53
  if (!empty($controls->data['contract_key']) || defined('NEWSLETTER_LICENSE_KEY')) {
@@ -90,7 +108,33 @@ if (!empty($return_path)) {
90
  $controls->warnings[] = __('Your Return Path domain is different from your Sender domain. Providers may require them to match.', 'newsletter');
91
  }
92
  }
 
 
 
 
 
 
93
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
  <div class="wrap" id="tnp-wrap">
96
 
@@ -151,18 +195,31 @@ if (!empty($return_path)) {
151
  <?php $controls->help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#reply-to') ?>
152
  </td>
153
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
154
 
155
  <tr>
156
  <th><?php _e('License key', 'newsletter') ?></th>
157
  <td>
158
- <?php if (defined('NEWSLETTER_LICENSE_KEY')) { ?>
159
- <?php _e('A license key is set','newsletter') ?>
160
- <?php } else { ?>
161
- <?php $controls->text('contract_key', 40); ?>
162
- <p class="description">
163
- <?php printf(__('Find it in <a href="%s" target="_blank">your account</a> page', 'newsletter'), "https://www.thenewsletterplugin.com/account") ?>
164
- </p>
165
- <?php } ?>
166
  </td>
167
  </tr>
168
 
@@ -194,7 +251,21 @@ if (!empty($return_path)) {
194
  </p>
195
 
196
  <table class="form-table">
197
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  <tr>
199
  <th><?php _e('Enable access to blog editors?', 'newsletter') ?></th>
200
  <td>
@@ -211,6 +282,14 @@ if (!empty($return_path)) {
211
  </td>
212
  </tr>
213
 
 
 
 
 
 
 
 
 
214
  <tr>
215
  <th><?php _e('Debug mode', 'newsletter') ?></th>
216
  <td>
41
  if (empty($controls->errors)) {
42
  $module->merge_options($controls->data);
43
  $controls->add_message_saved();
44
+ $module->logger->debug('Main options saved');
45
  }
46
 
47
  update_option('newsletter_log_level', $controls->data['log_level']);
49
  $module->hook_newsletter_extension_versions(true);
50
  delete_transient("tnp_extensions_json");
51
  }
52
+
53
+ if ($controls->is_action('create')) {
54
+ $page = array();
55
+ $page['post_title'] = 'Newsletter';
56
+ $page['post_content'] = '[newsletter]';
57
+ $page['post_status'] = 'publish';
58
+ $page['post_type'] = 'page';
59
+ $page['comment_status'] = 'closed';
60
+ $page['ping_status'] = 'closed';
61
+ $page['post_category'] = array(1);
62
+
63
+ // Insert the post into the database
64
+ $page_id = wp_insert_post($page);
65
+
66
+ $controls->data['page'] = $page_id;
67
+ $module->merge_options($controls->data);
68
+ }
69
  }
70
 
71
  if (!empty($controls->data['contract_key']) || defined('NEWSLETTER_LICENSE_KEY')) {
108
  $controls->warnings[] = __('Your Return Path domain is different from your Sender domain. Providers may require them to match.', 'newsletter');
109
  }
110
  }
111
+
112
+ if (empty($controls->data['page'])) {
113
+ $controls->messages .= '<p>You should set a dedicated page for Newsletter which used to interact with your subscribers.</p>';
114
+ } else {
115
+
116
+ }
117
  ?>
118
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.css" type="text/css">
119
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/addon/hint/show-hint.css">
120
+ <style>
121
+ .CodeMirror {
122
+ border: 1px solid #ddd;
123
+ }
124
+ </style>
125
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.js"></script>
126
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/mode/css/css.js"></script>
127
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/addon/hint/show-hint.js"></script>
128
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/addon/hint/css-hint.js"></script>
129
+ <script>
130
+ jQuery(function () {
131
+ var editor = CodeMirror.fromTextArea(document.getElementById("options-css"), {
132
+ lineNumbers: true,
133
+ mode: 'css',
134
+ extraKeys: {"Ctrl-Space": "autocomplete"}
135
+ });
136
+ });
137
+ </script>
138
 
139
  <div class="wrap" id="tnp-wrap">
140
 
195
  <?php $controls->help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#reply-to') ?>
196
  </td>
197
  </tr>
198
+ <tr>
199
+ <th><?php _e('Dedicated page', 'newsletter') ?></th>
200
+ <td>
201
+ <?php $controls->page('page', __('Unstyled page', 'newsletter')); ?>
202
+ <?php
203
+ if (empty($controls->data['page'])) {
204
+ $controls->button('create', __('Create the page', 'newsletter'));
205
+ }
206
+ ?>
207
+ <?php $controls->help('https://www.thenewsletterplugin.com/documentation/newsletter-configuration#dedicated-page') ?>
208
+
209
+ </td>
210
+ </tr>
211
 
212
  <tr>
213
  <th><?php _e('License key', 'newsletter') ?></th>
214
  <td>
215
+ <?php if (defined('NEWSLETTER_LICENSE_KEY')) { ?>
216
+ <?php _e('A license key is set', 'newsletter') ?>
217
+ <?php } else { ?>
218
+ <?php $controls->text('contract_key', 40); ?>
219
+ <p class="description">
220
+ <?php printf(__('Find it in <a href="%s" target="_blank">your account</a> page', 'newsletter'), "https://www.thenewsletterplugin.com/account") ?>
221
+ </p>
222
+ <?php } ?>
223
  </td>
224
  </tr>
225
 
251
  </p>
252
 
253
  <table class="form-table">
254
+ <tr>
255
+ <th><?php _e('Disable standard styles', 'newsletter') ?></th>
256
+ <td>
257
+ <?php $controls->yesno('css_disabled'); ?>
258
+ </td>
259
+ </tr>
260
+ <tr>
261
+ <th><?php _e('Custom styles', 'newsletter') ?></th>
262
+ <td>
263
+ <?php if (apply_filters('newsletter_enqueue_style', true) === false) { ?>
264
+ <p><strong>Warning: Newsletter styles and custom styles are disable by your theme or a plugin.</strong></p>
265
+ <?php } ?>
266
+ <?php $controls->textarea('css'); ?>
267
+ </td>
268
+ </tr>
269
  <tr>
270
  <th><?php _e('Enable access to blog editors?', 'newsletter') ?></th>
271
  <td>
282
  </td>
283
  </tr>
284
 
285
+ <tr>
286
+ <th><?php _e('Newsletters tracking default', 'newsletter') ?></th>
287
+ <td>
288
+ <?php $controls->yesno('track'); ?>
289
+ <p class="description">It can be changed on each newsletter.</p>
290
+ </td>
291
+ </tr>
292
+
293
  <tr>
294
  <th><?php _e('Debug mode', 'newsletter') ?></th>
295
  <td>
main/welcome.php CHANGED
@@ -72,9 +72,9 @@ if (!$page_exists) {
72
  // Insert the post into the database
73
  $page_id = wp_insert_post($page);
74
 
75
- $subscription_options['page'] = $page_id;
76
- NewsletterSubscription::instance()->save_options($subscription_options);
77
- $subscription_options = NewsletterSubscription::instance()->get_options();
78
  $page_exists = true;
79
  }
80
  ?>
72
  // Insert the post into the database
73
  $page_id = wp_insert_post($page);
74
 
75
+ $main_options['page'] = $page_id;
76
+ Newsletter::instance()->save_options($main_options);
77
+ $main_options = Newsletter::instance()->get_options();
78
  $page_exists = true;
79
  }
80
  ?>
plugin.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: Newsletter
5
  Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
6
  Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
7
- Version: 5.4.2
8
  Author: Stefano Lissa & The Newsletter Team
9
  Author URI: https://www.thenewsletterplugin.com
10
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
@@ -14,7 +14,7 @@
14
  */
15
 
16
  // Used as dummy parameter on css and js links
17
- define('NEWSLETTER_VERSION', '5.4.2');
18
 
19
  global $wpdb, $newsletter;
20
 
@@ -42,7 +42,7 @@ define('NEWSLETTER_INCLUDES_DIR', WP_PLUGIN_DIR . '/' . NEWSLETTER_SLUG . '/incl
42
  define('NEWSLETTER_URL', WP_PLUGIN_URL . '/newsletter');
43
 
44
  if (!defined('NEWSLETTER_LIST_MAX'))
45
- define('NEWSLETTER_LIST_MAX', 20);
46
 
47
  if (!defined('NEWSLETTER_PROFILE_MAX'))
48
  define('NEWSLETTER_PROFILE_MAX', 20);
@@ -95,6 +95,8 @@ class Newsletter extends NewsletterModule {
95
  static $instance;
96
 
97
  const MAX_CRON_SAMPLES = 100;
 
 
98
 
99
  /**
100
  * @return Newsletter
@@ -124,8 +126,7 @@ class Newsletter extends NewsletterModule {
124
 
125
  // Here because the upgrade is called by the parent constructor and uses the scheduler
126
  add_filter('cron_schedules', array($this, 'hook_cron_schedules'), 1000);
127
-
128
- parent::__construct('main', '1.3.2');
129
 
130
  $max = $this->options['scheduler_max'];
131
  if (!is_numeric($max)) {
@@ -141,6 +142,26 @@ class Newsletter extends NewsletterModule {
141
  // This specific event is created by "Feed by mail" panel on configuration
142
  add_action('shutdown', array($this, 'hook_shutdown'));
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  if (defined('DOING_CRON') && DOING_CRON) {
145
  $calls = get_option('newsletter_diagnostic_cron_calls', array());
146
  $calls[] = time();
@@ -166,25 +187,6 @@ class Newsletter extends NewsletterModule {
166
  $mean = $mean / count($calls) - 1;
167
  update_option('newsletter_diagnostic_cron_data', array('mean' => $mean, 'max' => $max, 'min' => $min), false);
168
  }
169
- return;
170
- }
171
-
172
- register_activation_hook(__FILE__, array($this, 'hook_activate'));
173
- register_deactivation_hook(__FILE__, array($this, 'hook_deactivate'));
174
-
175
- add_action('admin_init', array($this, 'hook_admin_init'));
176
-
177
- if (is_admin()) {
178
- add_action('admin_head', array($this, 'hook_admin_head'));
179
-
180
- // Protection against strange schedule removal on some installations
181
- if (!wp_next_scheduled('newsletter') && (!defined('WP_INSTALLING') || !WP_INSTALLING)) {
182
- wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
183
- }
184
-
185
-
186
-
187
- add_action('admin_menu', array($this, 'add_extensions_menu'), 90);
188
  }
189
  }
190
 
@@ -207,14 +209,11 @@ class Newsletter extends NewsletterModule {
207
  NewsletterEmails::instance()->upgrade();
208
  NewsletterSubscription::instance()->upgrade();
209
  NewsletterStatistics::instance()->upgrade();
 
210
  }
211
 
212
  function first_install() {
213
  parent::first_install();
214
- $dismissed = get_option('newsletter_dismissed', array());
215
-
216
- $dismissed['wpmail'] = 1;
217
- update_option('newsletter_dismissed', $dismissed);
218
  update_option('newsletter_show_welcome', '1', false);
219
  }
220
 
@@ -285,57 +284,30 @@ class Newsletter extends NewsletterModule {
285
  // Some setting check to avoid the common support request for mis-configurations
286
  $options = $this->get_options();
287
 
288
- if (empty($options['sender_email'])) {
289
- // That code was taken from WordPress
290
- $sitename = strtolower($_SERVER['SERVER_NAME']);
291
- if (substr($sitename, 0, 4) == 'www.')
292
- $sitename = substr($sitename, 4);
293
- // WordPress build an address in the same way using wordpress@...
294
- $options['sender_email'] = 'newsletter@' . $sitename;
295
- $this->save_options($options);
296
- }
297
-
298
  if (empty($options['scheduler_max']) || !is_numeric($options['scheduler_max'])) {
299
  $options['scheduler_max'] = 100;
300
  $this->save_options($options);
301
  }
302
 
303
- if (empty($options['api_key'])) {
304
- $options['api_key'] = self::get_token();
305
- $this->save_options($options);
306
- }
307
-
308
- if (empty($options['scheduler_max'])) {
309
- $options['scheduler_max'] = 100;
310
- $this->save_options($options);
311
- }
312
-
313
  wp_clear_scheduled_hook('newsletter');
314
  wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
315
 
316
  wp_clear_scheduled_hook('newsletter_extension_versions');
317
  wp_schedule_event(time() + 30, 'daily', 'newsletter_extension_versions');
318
 
319
- // If the original options has already saved once
320
- if (isset($options['smtp_host'])) {
321
- $smtp_options['enabled'] = $options['smtp_enabled'];
322
- $smtp_options['test_email'] = $options['smtp_test_email'];
323
- $smtp_options['host'] = $options['smtp_host'];
324
- $smtp_options['pass'] = $options['smtp_pass'];
325
- $smtp_options['port'] = $options['smtp_port'];
326
- $smtp_options['user'] = $options['smtp_user'];
327
- $smtp_options['secure'] = $options['smtp_secure'];
328
- $this->save_options($smtp_options, 'smtp');
329
- unset($options['smtp_enabled']);
330
- unset($options['smtp_test_email']);
331
- unset($options['smtp_pass']);
332
- unset($options['smtp_port']);
333
- unset($options['smtp_user']);
334
- unset($options['smtp_secure']);
335
- unset($options['smtp_host']);
336
- $this->save_options($options);
337
  }
338
- $this->init_options('smtp');
339
 
340
  return true;
341
  }
@@ -393,13 +365,17 @@ class Newsletter extends NewsletterModule {
393
  ini_set('error_log', WP_CONTENT_DIR . '/logs/newsletter/php-' . date('Y-m') . '-' . get_option('newsletter_logger_secret') . '.txt');
394
  }
395
 
 
 
 
396
  if (is_admin()) {
397
  if ($this->is_admin_page()) {
398
  wp_enqueue_script('jquery-ui-tabs');
 
399
  wp_enqueue_media();
400
  wp_enqueue_style('tnp-admin', plugins_url('newsletter') . '/admin.css', array(), filemtime(NEWSLETTER_DIR . '/admin.css'));
401
  wp_enqueue_script('tnp-admin', plugins_url('newsletter') . '/admin.js', array('jquery'), time());
402
-
403
  wp_enqueue_style('wp-color-picker');
404
  wp_enqueue_script('wp-color-picker');
405
 
@@ -420,8 +396,8 @@ class Newsletter extends NewsletterModule {
420
  exit();
421
  }
422
  }
423
-
424
-
425
  }
426
 
427
  $action = isset($_REQUEST['na']) ? $_REQUEST['na'] : '';
@@ -455,21 +431,42 @@ class Newsletter extends NewsletterModule {
455
  }
456
  }
457
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
458
  function is_admin_page() {
459
  if (!isset($_GET['page'])) {
460
  return false;
461
  }
462
  $page = $_GET['page'];
463
- return strpos($page, 'newsletter_') === 0; // || strpos($page, 'newsletter-') === 0;
464
  }
465
 
466
  function hook_admin_init() {
467
  // Verificare il contesto
468
- if (isset($_GET['page']) && $_GET['page'] === 'newsletter_main_welcome') return;
 
469
  if (get_option('newsletter_show_welcome')) {
470
  delete_option('newsletter_show_welcome');
471
  wp_redirect(admin_url('admin.php?page=newsletter_main_welcome'));
472
- }
473
  }
474
 
475
  function hook_admin_head() {
@@ -1033,6 +1030,8 @@ class Newsletter extends NewsletterModule {
1033
 
1034
  /**
1035
  * Return a user if there are request parameters or cookie with identification data otherwise null.
 
 
1036
  */
1037
  function check_user() {
1038
  global $wpdb, $current_user;
@@ -1209,6 +1208,34 @@ class Newsletter extends NewsletterModule {
1209
  return !empty($this->options['contract_key']);
1210
  }
1211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1212
  }
1213
 
1214
  $newsletter = Newsletter::instance();
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.4.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.
14
  */
15
 
16
  // Used as dummy parameter on css and js links
17
+ define('NEWSLETTER_VERSION', '5.4.3');
18
 
19
  global $wpdb, $newsletter;
20
 
42
  define('NEWSLETTER_URL', WP_PLUGIN_URL . '/newsletter');
43
 
44
  if (!defined('NEWSLETTER_LIST_MAX'))
45
+ define('NEWSLETTER_LIST_MAX', 40);
46
 
47
  if (!defined('NEWSLETTER_PROFILE_MAX'))
48
  define('NEWSLETTER_PROFILE_MAX', 20);
95
  static $instance;
96
 
97
  const MAX_CRON_SAMPLES = 100;
98
+ const STATUS_NOT_CONFIRMED = 'S';
99
+ const STATUS_CONFIRMED = 'C';
100
 
101
  /**
102
  * @return Newsletter
126
 
127
  // Here because the upgrade is called by the parent constructor and uses the scheduler
128
  add_filter('cron_schedules', array($this, 'hook_cron_schedules'), 1000);
129
+ parent::__construct('main', '1.4.3', null, array('info', 'smtp'));
 
130
 
131
  $max = $this->options['scheduler_max'];
132
  if (!is_numeric($max)) {
142
  // This specific event is created by "Feed by mail" panel on configuration
143
  add_action('shutdown', array($this, 'hook_shutdown'));
144
 
145
+ $this->update_cron_stats();
146
+
147
+ register_activation_hook(__FILE__, array($this, 'hook_activate'));
148
+ register_deactivation_hook(__FILE__, array($this, 'hook_deactivate'));
149
+
150
+ add_action('admin_init', array($this, 'hook_admin_init'));
151
+
152
+ if (is_admin()) {
153
+ add_action('admin_head', array($this, 'hook_admin_head'));
154
+
155
+ // Protection against strange schedule removal on some installations
156
+ if (!wp_next_scheduled('newsletter') && (!defined('WP_INSTALLING') || !WP_INSTALLING)) {
157
+ wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
158
+ }
159
+
160
+ add_action('admin_menu', array($this, 'add_extensions_menu'), 90);
161
+ }
162
+ }
163
+
164
+ function update_cron_stats() {
165
  if (defined('DOING_CRON') && DOING_CRON) {
166
  $calls = get_option('newsletter_diagnostic_cron_calls', array());
167
  $calls[] = time();
187
  $mean = $mean / count($calls) - 1;
188
  update_option('newsletter_diagnostic_cron_data', array('mean' => $mean, 'max' => $max, 'min' => $min), false);
189
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  }
191
  }
192
 
209
  NewsletterEmails::instance()->upgrade();
210
  NewsletterSubscription::instance()->upgrade();
211
  NewsletterStatistics::instance()->upgrade();
212
+ NewsletterProfile::instance()->upgrade();
213
  }
214
 
215
  function first_install() {
216
  parent::first_install();
 
 
 
 
217
  update_option('newsletter_show_welcome', '1', false);
218
  }
219
 
284
  // Some setting check to avoid the common support request for mis-configurations
285
  $options = $this->get_options();
286
 
 
 
 
 
 
 
 
 
 
 
287
  if (empty($options['scheduler_max']) || !is_numeric($options['scheduler_max'])) {
288
  $options['scheduler_max'] = 100;
289
  $this->save_options($options);
290
  }
291
 
 
 
 
 
 
 
 
 
 
 
292
  wp_clear_scheduled_hook('newsletter');
293
  wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
294
 
295
  wp_clear_scheduled_hook('newsletter_extension_versions');
296
  wp_schedule_event(time() + 30, 'daily', 'newsletter_extension_versions');
297
 
298
+ $subscription_options = get_option('newsletter', array());
299
+
300
+ // Settings migration
301
+ if (empty($this->options['page'])) {
302
+ if (isset($subscription_options['page']))
303
+ $this->options['page'] = $subscription_options['page'];
304
+ $this->save_options($this->options);
305
+ }
306
+
307
+ if (empty($this->options['css']) && !empty($subscription_options['css'])) {
308
+ $this->options['css'] = $subscription_options['css'];
309
+ $this->save_options($this->options);
 
 
 
 
 
 
310
  }
 
311
 
312
  return true;
313
  }
365
  ini_set('error_log', WP_CONTENT_DIR . '/logs/newsletter/php-' . date('Y-m') . '-' . get_option('newsletter_logger_secret') . '.txt');
366
  }
367
 
368
+ add_shortcode('newsletter_replace', array($this, 'shortcode_newsletter_replace'));
369
+ //add_shortcode('newsletter_action', array($this, 'shortcode_newsletter_action'));
370
+
371
  if (is_admin()) {
372
  if ($this->is_admin_page()) {
373
  wp_enqueue_script('jquery-ui-tabs');
374
+ wp_enqueue_script('jquery-ui-tooltip');
375
  wp_enqueue_media();
376
  wp_enqueue_style('tnp-admin', plugins_url('newsletter') . '/admin.css', array(), filemtime(NEWSLETTER_DIR . '/admin.css'));
377
  wp_enqueue_script('tnp-admin', plugins_url('newsletter') . '/admin.js', array('jquery'), time());
378
+
379
  wp_enqueue_style('wp-color-picker');
380
  wp_enqueue_script('wp-color-picker');
381
 
396
  exit();
397
  }
398
  }
399
+ } else {
400
+ add_action('wp_enqueue_scripts', array($this, 'hook_wp_enqueue_scripts'));
401
  }
402
 
403
  $action = isset($_REQUEST['na']) ? $_REQUEST['na'] : '';
431
  }
432
  }
433
 
434
+ function hook_wp_enqueue_scripts() {
435
+ if (empty($this->options['css_disabled']) && apply_filters('newsletter_enqueue_style', true)) {
436
+ wp_enqueue_style('newsletter-subscription', plugins_url('newsletter') . '/style.css', array(), NEWSLETTER_VERSION);
437
+ if (!empty($this->options['css'])) {
438
+ wp_add_inline_style('newsletter', $this->options['css']);
439
+ }
440
+ }
441
+ }
442
+
443
+ function shortcode_newsletter_replace($attrs, $content) {
444
+ $content = do_shortcode($content);
445
+ $content = $this->replace($content, $this->get_user_from_request(), $this->get_email_from_request());
446
+ return $content;
447
+ }
448
+
449
+ function shortcode_newsletter_action($attrs, $content) {
450
+ $content = apply_filters('newsletter_action_shortcode', '', $attrs, $content, $this->get_user_from_request(), $this->get_email_from_request());
451
+ return $content;
452
+ }
453
+
454
  function is_admin_page() {
455
  if (!isset($_GET['page'])) {
456
  return false;
457
  }
458
  $page = $_GET['page'];
459
+ return strpos($page, 'newsletter_') === 0;
460
  }
461
 
462
  function hook_admin_init() {
463
  // Verificare il contesto
464
+ if (isset($_GET['page']) && $_GET['page'] === 'newsletter_main_welcome')
465
+ return;
466
  if (get_option('newsletter_show_welcome')) {
467
  delete_option('newsletter_show_welcome');
468
  wp_redirect(admin_url('admin.php?page=newsletter_main_welcome'));
469
+ }
470
  }
471
 
472
  function hook_admin_head() {
1030
 
1031
  /**
1032
  * Return a user if there are request parameters or cookie with identification data otherwise null.
1033
+ *
1034
+ * @return TNP_User The user identified or null
1035
  */
1036
  function check_user() {
1037
  global $wpdb, $current_user;
1208
  return !empty($this->options['contract_key']);
1209
  }
1210
 
1211
+ function get_newsletter_page_url($message_key, $user = false, $email = false, $alert = '') {
1212
+ static $url = false;
1213
+
1214
+ if (!$url) {
1215
+ if (!empty($this->options['page'])) {
1216
+ $url = get_permalink($this->options['page']);
1217
+ }
1218
+ if (!$url) {
1219
+ $url = self::get_home_url() . '?na=m';
1220
+ }
1221
+ }
1222
+ $params = 'nm=' . urlencode($message_key);
1223
+
1224
+ if ($user) {
1225
+ $params .= '&nk=' . urlencode($this->get_user_key($user));
1226
+ }
1227
+
1228
+ if ($email) {
1229
+ $params .= '&nek=' . urlencode($email->id . '-' . $email->token);
1230
+ }
1231
+
1232
+ if ($alert) {
1233
+ $params .= '&alert=' . urlencode($alert);
1234
+ }
1235
+
1236
+ return self::add_qs($url, $params, false);
1237
+ }
1238
+
1239
  }
1240
 
1241
  $newsletter = Newsletter::instance();
profile/defaults.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $options = array();
4
+
5
+ // Profile page
6
+ $options['text'] = '{profile_form}' . __('
7
+ <p>If you change your email address, a confirmation email will be sent to activate it.</p>
8
+ <p><a href="{unsubscription_confirm_url}">Cancel your subscription</a></p>', 'newsletter');
9
+
10
+ // Profile page messages
11
+ $options['email_changed'] = __("Your email has been changed, an activation email has been sent with instructions.", 'newsletter');
12
+ $options['error'] = __("Your email is not valid or already in use.", 'newsletter');
13
+ $options['save_label'] = __('Save', 'newsletter');
14
+ $options['privacy_label'] = __('Read our privacy note', 'newsletter');
15
+ $options['saved'] = __('Profile saved.', 'newsletter');
16
+
profile/index.php CHANGED
@@ -6,6 +6,20 @@ require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
7
  $module = NewsletterProfile::instance();
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  ?>
10
 
11
  <div class="wrap tnp-profile tnp-profile-index" id="tnp-wrap">
@@ -14,7 +28,7 @@ $module = NewsletterProfile::instance();
14
 
15
  <div id="tnp-heading">
16
 
17
- <h2><?php _e('Profile editing', 'newsletter') ?></h2>
18
 
19
  </div>
20
 
@@ -22,8 +36,96 @@ $module = NewsletterProfile::instance();
22
 
23
  <form id="channel" method="post" action="">
24
  <?php $controls->init(); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
-
27
  </form>
28
  </div>
29
 
6
  $controls = new NewsletterControls();
7
  $module = NewsletterProfile::instance();
8
 
9
+ // Profile options are still inside the main options
10
+ if ($controls->is_action()) {
11
+ if ($controls->is_action('save')) {
12
+ $module->save_options($controls->data);
13
+ $controls->add_message_saved();
14
+ }
15
+ if ($controls->is_action('reset')) {
16
+ $module->reset_options();
17
+ $controls->data = $module->get_options();
18
+ $controls->add_message_reset();
19
+ }
20
+ } else {
21
+ $controls->data = $module->get_options();
22
+ }
23
  ?>
24
 
25
  <div class="wrap tnp-profile tnp-profile-index" id="tnp-wrap">
28
 
29
  <div id="tnp-heading">
30
 
31
+ <h2><?php _e('The subscriber profile page', 'newsletter') ?></h2>
32
 
33
  </div>
34
 
36
 
37
  <form id="channel" method="post" action="">
38
  <?php $controls->init(); ?>
39
+ <div id="tabs">
40
+ <ul>
41
+ <li><a href="#tabs-general"><?php _e('General', 'newsletter') ?></a></li>
42
+
43
+ </ul>
44
+
45
+ <div id="tabs-general">
46
+
47
+
48
+ <table class="form-table">
49
+
50
+ <tr>
51
+ <th><?php _e('Profile page', 'newsletter') ?>
52
+ <br><?php $controls->help('https://www.thenewsletterplugin.com/documentation/subscription#profile') ?>
53
+ </th>
54
+ <td>
55
+ <?php $controls->wp_editor('text'); ?>
56
+ </td>
57
+ </tr>
58
+
59
+ <tr>
60
+ <th><?php _e('Alternative profile page URL', 'newsletter') ?></th>
61
+ <td>
62
+ <?php $controls->text('url', 70); ?>
63
+ </td>
64
+ </tr>
65
+
66
+ </table>
67
+
68
+ <h3><?php _e('Messages', 'newsletter')?></h3>
69
+ <table class="form-table">
70
+ <tr>
71
+ <th>Profile saved</th>
72
+ <td>
73
+ <?php $controls->text('saved', 80); ?>
74
+ </td>
75
+ </tr>
76
+
77
+ <tr>
78
+ <tr>
79
+ <th><?php _e('Email changed alert', 'newsletter')?></th>
80
+ <td>
81
+ <?php $controls->text('email_changed', 80); ?>
82
+ </td>
83
+ </tr>
84
+
85
+ <tr>
86
+
87
+ <tr>
88
+ <tr>
89
+ <th><?php _e('General error', 'newsletter')?></th>
90
+ <td>
91
+ <?php $controls->text('error', 80); ?>
92
+ <p class="description">
93
+ Email not valid or already used.
94
+ </p>
95
+ </td>
96
+ </tr>
97
+
98
+ </table>
99
+
100
+ <h3>Labels</h3>
101
+ <table class="form-table">
102
+ <tr>
103
+ <th><?php _e('"Save" label', 'newsletter')?></th>
104
+ <td>
105
+ <?php $controls->text('save_label'); ?>
106
+ </td>
107
+ </tr>
108
+
109
+ <tr>
110
+ <th><?php _e('Privacy link text', 'newsletter')?></th>
111
+ <td>
112
+ <?php $controls->text('privacy_label', 80); ?>
113
+ <p class="description">
114
+
115
+ </p>
116
+ </td>
117
+ </tr>
118
+
119
+ </table>
120
+ </div>
121
+
122
+ </div>
123
+
124
+ <p>
125
+ <?php $controls->button_save() ?>
126
+ <?php $controls->button_reset() ?>
127
+ </p>
128
 
 
129
  </form>
130
  </div>
131
 
profile/profile.php CHANGED
@@ -7,7 +7,6 @@ require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
7
  class NewsletterProfile extends NewsletterModule {
8
 
9
  static $instance;
10
- var $home_url;
11
 
12
  /**
13
  * @return NewsletterProfile
@@ -20,7 +19,7 @@ class NewsletterProfile extends NewsletterModule {
20
  }
21
 
22
  function __construct() {
23
- parent::__construct('profile', '1.0.0');
24
  add_action('init', array($this, 'hook_init'));
25
  add_action('wp_loaded', array($this, 'hook_wp_loaded'));
26
  add_shortcode('newsletter_profile', array($this, 'shortcode_newsletter_profile'));
@@ -31,17 +30,37 @@ class NewsletterProfile extends NewsletterModule {
31
  add_action('wp_ajax_newsletter_users_export', array($this, 'hook_wp_ajax_newsletter_users_export'));
32
  }
33
  add_filter('newsletter_replace', array($this, 'hook_newsletter_replace'), 10, 3);
 
34
  }
35
 
36
  function hook_wp_loaded() {
37
  global $wpdb;
38
 
39
- $this->home_url = home_url('/');
40
-
41
  switch (Newsletter::instance()->action) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  case 'profile_export':
43
  $user = $this->get_user_from_request(true);
44
- header('Content-Type: application/json;chartse=UTF-8');
45
  echo $this->to_json($user);
46
  die();
47
  }
@@ -52,7 +71,7 @@ class NewsletterProfile extends NewsletterModule {
52
  * @param stdClass $user
53
  */
54
  function get_profile_export_url($user) {
55
- return $this->home_url . '?na=profile_export&nk=' . $user->id . '-' . $user->token;
56
  }
57
 
58
  /**
@@ -60,12 +79,10 @@ class NewsletterProfile extends NewsletterModule {
60
  * @param stdClass $user
61
  */
62
  function get_profile_url($user) {
63
- $options_profile = get_option('newsletter_profile');
64
-
65
- if (empty($options_profile['profile_url'])) {
66
- $profile_url = $this->home_url . '?na=profile&nk=' . $user->id . '-' . $user->token;
67
  } else {
68
- $profile_url = self::add_qs($options_profile['profile_url'], 'nk=' . $user->id . '-' . $user->token);
69
  }
70
 
71
  $profile_url = apply_filters('newsletter_profile_url', $profile_url, $user);
@@ -73,19 +90,31 @@ class NewsletterProfile extends NewsletterModule {
73
  }
74
 
75
  function hook_newsletter_replace($text, $user, $email) {
76
- if (!$user) return $text;
77
-
 
 
78
  $profile_options = NewsletterSubscription::instance()->get_options('profile');
79
 
80
  // Profile edit page URL and link
81
  $url = $this->get_profile_url($user);
82
  $text = $this->replace_url($text, 'PROFILE_URL', $url);
83
- $text = str_replace('{profile_link}', '<a class="tnp-profile-link" href="' . $url . '">' . $profile_options['profile_edit'] . '</a>', $text);
84
-
85
  // Profile export URL and link
86
  $url = $this->get_profile_export_url($user);
87
  $text = $this->replace_url($text, 'PROFILE_EXPORT_URL', $url);
88
- $text = str_replace('{profile_export_link}', '<a class="tnp-profile-export-link" href="' . $url . '">' . $profile_options['profile_export'] . '</a>', $text);
 
 
 
 
 
 
 
 
 
 
 
89
  return $text;
90
  }
91
 
@@ -100,11 +129,7 @@ class NewsletterProfile extends NewsletterModule {
100
  }
101
  }
102
 
103
- if (isset($attrs['layout']) && $attrs['layout'] == 'table') {
104
- return NewsletterSubscription::instance()->get_profile_form($user);
105
- } else {
106
- return NewsletterSubscription::instance()->get_profile_form_html5($user);
107
- }
108
  }
109
 
110
  function to_json($user) {
@@ -118,7 +143,8 @@ class NewsletterProfile extends NewsletterModule {
118
  $profiles = array();
119
  foreach ($user as $key => $value) {
120
  if (strpos($key, 'list_') === 0) {
121
- if (empty($value)) continue;
 
122
  if ($options_profile[$key . '_status'] != 1 && $options_profile[$key . '_status'] != 2) {
123
  continue;
124
  }
@@ -127,7 +153,8 @@ class NewsletterProfile extends NewsletterModule {
127
 
128
  // Check if disabled
129
  if (strpos($key, 'profile_') === 0) {
130
- if (empty($value)) continue;
 
131
  if ($options_profile[$key . '_status'] == 0) {
132
  continue;
133
  }
@@ -138,10 +165,10 @@ class NewsletterProfile extends NewsletterModule {
138
  if (in_array($key, $fields))
139
  $data[$key] = $value;
140
  }
141
-
142
  $data['lists'] = $lists;
143
  $data['profiles'] = $profiles;
144
-
145
 
146
  // Newsletters
147
  $sent = $wpdb->get_results($wpdb->prepare("select * from {$wpdb->prefix}newsletter_sent where user_id=%d order by email_id asc", $user['id']));
@@ -169,15 +196,267 @@ class NewsletterProfile extends NewsletterModule {
169
  return json_encode($data, JSON_PRETTY_PRINT);
170
  }
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  function upgrade() {
173
  global $wpdb, $charset_collate;
174
 
175
  parent::upgrade();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  }
177
 
178
  function admin_menu() {
179
  //$this->add_menu_page('index', 'Subscribers');
180
- //$this->add_admin_page('index', 'Profile');
 
 
 
 
 
 
 
 
181
  }
182
 
183
  }
7
  class NewsletterProfile extends NewsletterModule {
8
 
9
  static $instance;
 
10
 
11
  /**
12
  * @return NewsletterProfile
19
  }
20
 
21
  function __construct() {
22
+ parent::__construct('profile', '1.1.0');
23
  add_action('init', array($this, 'hook_init'));
24
  add_action('wp_loaded', array($this, 'hook_wp_loaded'));
25
  add_shortcode('newsletter_profile', array($this, 'shortcode_newsletter_profile'));
30
  add_action('wp_ajax_newsletter_users_export', array($this, 'hook_wp_ajax_newsletter_users_export'));
31
  }
32
  add_filter('newsletter_replace', array($this, 'hook_newsletter_replace'), 10, 3);
33
+ add_filter('newsletter_page_text', array($this, 'hook_newsletter_page_text'), 10, 2);
34
  }
35
 
36
  function hook_wp_loaded() {
37
  global $wpdb;
38
 
 
 
39
  switch (Newsletter::instance()->action) {
40
+ case 'profile':
41
+ case 'p':
42
+ case 'pe':
43
+ $user = $this->check_user();
44
+ if ($user == null) {
45
+ die('No subscriber found.');
46
+ }
47
+
48
+ wp_redirect(Newsletter::instance()->get_newsletter_page_url('profile', $user));
49
+ die();
50
+
51
+ break;
52
+
53
+ case 'profile-save':
54
+ case 'ps':
55
+ $user = $this->save_profile();
56
+ // $user->alert is a temporary field
57
+ wp_redirect(Newsletter::instance()->get_newsletter_page_url('profile', $user, null, $user->alert));
58
+ die();
59
+ break;
60
+
61
  case 'profile_export':
62
  $user = $this->get_user_from_request(true);
63
+ header('Content-Type: application/json;charset=UTF-8');
64
  echo $this->to_json($user);
65
  die();
66
  }
71
  * @param stdClass $user
72
  */
73
  function get_profile_export_url($user) {
74
+ return $this->get_home_url() . '?na=profile_export&nk=' . $this->get_user_key($user);
75
  }
76
 
77
  /**
79
  * @param stdClass $user
80
  */
81
  function get_profile_url($user) {
82
+ if (empty($this->options['url'])) {
83
+ $profile_url = $this->get_home_url() . '?na=profile&nk=' . $this->get_user_key($user);
 
 
84
  } else {
85
+ $profile_url = self::add_qs($this->options['url'], 'nk=' . $this->get_user_key($user));
86
  }
87
 
88
  $profile_url = apply_filters('newsletter_profile_url', $profile_url, $user);
90
  }
91
 
92
  function hook_newsletter_replace($text, $user, $email) {
93
+ if (!$user) {
94
+ return $text;
95
+ }
96
+
97
  $profile_options = NewsletterSubscription::instance()->get_options('profile');
98
 
99
  // Profile edit page URL and link
100
  $url = $this->get_profile_url($user);
101
  $text = $this->replace_url($text, 'PROFILE_URL', $url);
102
+ // $text = str_replace('{profile_link}', '<a class="tnp-profile-link" href="' . $url . '">' . $this->options['edit_label'] . '</a>', $text);
 
103
  // Profile export URL and link
104
  $url = $this->get_profile_export_url($user);
105
  $text = $this->replace_url($text, 'PROFILE_EXPORT_URL', $url);
106
+ // $text = str_replace('{profile_export_link}', '<a class="tnp-profile-export-link" href="' . $url . '">' . $this->options['export_label'] . '</a>', $text);
107
+
108
+ if (strpos($text, '{profile_form}') !== false) {
109
+ $text = str_replace('{profile_form}', $this->get_profile_form($user), $text);
110
+ }
111
+ return $text;
112
+ }
113
+
114
+ function hook_newsletter_page_text($text, $key) {
115
+ if ($key == 'profile') {
116
+ return $this->options['text'];
117
+ }
118
  return $text;
119
  }
120
 
129
  }
130
  }
131
 
132
+ return NewsletterSubscription::instance()->get_profile_form($user);
 
 
 
 
133
  }
134
 
135
  function to_json($user) {
143
  $profiles = array();
144
  foreach ($user as $key => $value) {
145
  if (strpos($key, 'list_') === 0) {
146
+ if (empty($value))
147
+ continue;
148
  if ($options_profile[$key . '_status'] != 1 && $options_profile[$key . '_status'] != 2) {
149
  continue;
150
  }
153
 
154
  // Check if disabled
155
  if (strpos($key, 'profile_') === 0) {
156
+ if (empty($value))
157
+ continue;
158
  if ($options_profile[$key . '_status'] == 0) {
159
  continue;
160
  }
165
  if (in_array($key, $fields))
166
  $data[$key] = $value;
167
  }
168
+
169
  $data['lists'] = $lists;
170
  $data['profiles'] = $profiles;
171
+
172
 
173
  // Newsletters
174
  $sent = $wpdb->get_results($wpdb->prepare("select * from {$wpdb->prefix}newsletter_sent where user_id=%d order by email_id asc", $user['id']));
196
  return json_encode($data, JSON_PRETTY_PRINT);
197
  }
198
 
199
+ function get_profile_form($user) {
200
+ // Do not pay attention to option name here, it's a compatibility problem
201
+ $options = NewsletterSubscription::instance()->options_profile;
202
+ $options_lists = NewsletterSubscription::instance()->options_lists;
203
+
204
+ $buffer = '';
205
+
206
+ $buffer .= '<div class="tnp tnp-profile">';
207
+ $buffer .= '<form action="' . esc_attr($this->get_home_url() . '?na=ps') . '" method="post" onsubmit="return newsletter_check(this)">';
208
+ $buffer .= '<input type="hidden" name="nk" value="' . esc_attr($user->id . '-' . $user->token) . '">';
209
+
210
+ $buffer .= '<div class="tnp-field tnp-field-email">';
211
+ $buffer .= '<label>' . esc_html($options['email']) . '</label>';
212
+ $buffer .= '<input class="tnp-email" type="text" name="ne" required value="' . esc_attr($user->email) . '">';
213
+ $buffer .= "</div>\n";
214
+
215
+
216
+ if ($options['name_status'] >= 1) {
217
+ $buffer .= '<div class="tnp-field tnp-field-firstname">';
218
+ $buffer .= '<label>' . esc_html($options['name']) . '</label>';
219
+ $buffer .= '<input class="tnp-firstname" type="text" name="nn" value="' . esc_attr($user->name) . '"' . ($options['name_rules'] == 1 ? ' required' : '') . '>';
220
+ $buffer .= "</div>\n";
221
+ }
222
+
223
+ if ($options['surname_status'] >= 1) {
224
+ $buffer .= '<div class="tnp-field tnp-field-lastname">';
225
+ $buffer .= '<label>' . esc_html($options['surname']) . '</label>';
226
+ $buffer .= '<input class="tnp-lastname" type="text" name="ns" value="' . esc_attr($user->surname) . '"' . ($options['surname_rules'] == 1 ? ' required' : '') . '>';
227
+ $buffer .= "</div>\n";
228
+ }
229
+
230
+ if ($options['sex_status'] >= 1) {
231
+ $buffer .= '<div class="tnp-field tnp-field-gender">';
232
+ $buffer .= '<label>' . esc_html($options['sex']) . '</label>';
233
+ $buffer .= '<select name="nx" class="tnp-gender">';
234
+ $buffer .= '<option value="f"' . ($user->sex == 'f' ? ' selected' : '') . '>' . esc_html($options['sex_female']) . '</option>';
235
+ $buffer .= '<option value="m"' . ($user->sex == 'm' ? ' selected' : '') . '>' . esc_html($options['sex_male']) . '</option>';
236
+ $buffer .= '<option value="n"' . ($user->sex == 'n' ? ' selected' : '') . '>' . esc_html($options['sex_none']) . '</option>';
237
+ $buffer .= '</select>';
238
+ $buffer .= "</div>\n";
239
+ }
240
+
241
+ // Profile
242
+ for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
243
+ if ($options['profile_' . $i . '_status'] == 0) {
244
+ continue;
245
+ }
246
+
247
+ $buffer .= '<div class="tnp-field tnp-field-profile">';
248
+ $buffer .= '<label>' . esc_html($options['profile_' . $i]) . '</label>';
249
+
250
+ $field = 'profile_' . $i;
251
+
252
+ if ($options['profile_' . $i . '_type'] == 'text') {
253
+ $buffer .= '<input class="tnp-profile tnp-profile-' . $i . '" type="text" name="np' . $i . '" value="' . esc_attr($user->$field) . '"' .
254
+ ($options['profile_' . $i . '_rules'] == 1 ? ' required' : '') . '>';
255
+ }
256
+
257
+ if ($options['profile_' . $i . '_type'] == 'select') {
258
+ $buffer .= '<select class="tnp-profile tnp-profile-' . $i . '" name="np' . $i . '"' .
259
+ ($options['profile_' . $i . '_rules'] == 1 ? ' required' : '') . '>';
260
+ $opts = explode(',', $options['profile_' . $i . '_options']);
261
+ for ($j = 0; $j < count($opts); $j++) {
262
+ $opts[$j] = trim($opts[$j]);
263
+ $buffer .= '<option';
264
+ if ($opts[$j] == $user->$field)
265
+ $buffer .= ' selected';
266
+ $buffer .= '>' . esc_html($opts[$j]) . '</option>';
267
+ }
268
+ $buffer .= '</select>';
269
+ }
270
+
271
+ $buffer .= "</div>\n";
272
+ }
273
+
274
+ // Lists
275
+ $lists = $this->get_lists_for_profile();
276
+ $tmp = '';
277
+ foreach ($lists as $list) {
278
+
279
+ $tmp .= '<div class="tnp-field tnp-field-list">';
280
+ $tmp .= '<label><input class="tnp-list tnp-list-' . $list->id . '" type="checkbox" name="nl[]" value="' . $list->id . '"';
281
+ $field = 'list_' . $list->id;
282
+ if ($user->$field == 1) {
283
+ $tmp .= ' checked';
284
+ }
285
+ $tmp .= '><span class="tnp-list-label">' . esc_html($list->name) . '</span></label>';
286
+ $tmp .= "</div>\n";
287
+ }
288
+
289
+ if (!empty($tmp)) {
290
+ $buffer .= '<div class="tnp-lists">' . "\n" . $tmp . "\n" . '</div>';
291
+ }
292
+
293
+ $extra = apply_filters('newsletter_profile_extra', array(), $user);
294
+ foreach ($extra as $x) {
295
+ $buffer .= '<div class="tnp-field">';
296
+ $buffer .= '<label>' . $x['label'] . "</label>";
297
+ $buffer .= $x['field'];
298
+ $buffer .= "</div>\n";
299
+ }
300
+
301
+ // Privacy
302
+ if (!empty($this->options['privacy_label'])) {
303
+ $buffer .= '<div class="tnp-field tnp-field-privacy">';
304
+ if (!empty($options['privacy_url'])) {
305
+ $buffer .= '<a href="' . $options['privacy_url'] . '" target="_blank">';
306
+ }
307
+
308
+ $buffer .= $this->options['privacy_label'];
309
+
310
+ if (!empty($options['privacy_url'])) {
311
+ $buffer .= '</a>';
312
+ }
313
+ $buffer .= "</div>\n";
314
+ }
315
+
316
+ $buffer .= '<div class="tnp-field tnp-field-button">';
317
+ $buffer .= '<input class="tnp-submit" type="submit" value="' . esc_attr($this->options['save_label']) . '">';
318
+ $buffer .= "</div>\n";
319
+
320
+ $buffer .= "</form>\n</div>\n";
321
+
322
+ return $buffer;
323
+ }
324
+
325
+ /**
326
+ * Saves the subscriber data.
327
+ *
328
+ * @return type
329
+ */
330
+ function save_profile() {
331
+ global $wpdb;
332
+
333
+ // Get the current subscriber, fail if not found
334
+ $user = $this->get_user_from_request(true);
335
+
336
+ // Conatains the cleaned up user data to be saved
337
+ $data = array();
338
+ $data['id'] = $user->id;
339
+
340
+ $options_profile = get_option('newsletter_profile', array());
341
+ $options_main = get_option('newsletter_main', array());
342
+
343
+ // Not an elegant interaction between modules but...
344
+ $subscription_module = NewsletterSubscription::instance();
345
+
346
+ if (!$this->is_email($_REQUEST['ne'])) {
347
+ $user->alert = $this->options['profile_error'];
348
+ return $user;
349
+ }
350
+
351
+ $email = $this->normalize_email(stripslashes($_REQUEST['ne']));
352
+ $email_changed = ($email != $user->email);
353
+
354
+ // If the email has been changed, check if it is available
355
+ if ($email_changed) {
356
+ $tmp = $this->get_user($email);
357
+ if ($tmp != null && $tmp->id != $user->id) {
358
+ // TODO: Move the label on profile setting panel
359
+ $user->alert = $subscription_module->options['profile_error'];
360
+ return $user;
361
+ }
362
+ $data['status'] = Newsletter::STATUS_NOT_CONFIRMED;
363
+ }
364
+
365
+ // General data
366
+ $data['email'] = $email;
367
+ $data['name'] = $this->normalize_name(stripslashes($_REQUEST['nn']));
368
+ $data['surname'] = $this->normalize_name(stripslashes($_REQUEST['ns']));
369
+ if ($options_profile['sex_status'] >= 1) {
370
+ $data['sex'] = $_REQUEST['nx'][0];
371
+ // Wrong data injection check
372
+ if ($data['sex'] != 'm' && $data['sex'] != 'f' && $data['sex'] != 'n') {
373
+ die('Wrong sex field');
374
+ }
375
+ }
376
+
377
+ // Lists. If not list is present or there is no list to choose or all are unchecked.
378
+ $nl = array();
379
+ if (isset($_REQUEST['nl']) && is_array($_REQUEST['nl'])) {
380
+ $nl = $_REQUEST['nl'];
381
+ }
382
+
383
+ // Every possible list shown in the profile must be processed
384
+ $lists = $this->get_lists_for_profile();
385
+ foreach ($lists as $list) {
386
+ $field_name = 'list_' . $list->id;
387
+ $data[$field_name] = in_array($list->id, $nl) ? 1 : 0;
388
+ }
389
+
390
+ // Profile
391
+ for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
392
+ // Private fields cannot be changed by the subscriber
393
+ if ($options_profile['profile_' . $i . '_status'] == 0) {
394
+ continue;
395
+ }
396
+ $data['profile_' . $i] = stripslashes($_REQUEST['np' . $i]);
397
+ }
398
+
399
+
400
+ // Feed by Mail service is saved here
401
+ $data = apply_filters('newsletter_profile_save', $data);
402
+
403
+ $user = $this->save_user($data);
404
+ $this->add_user_log($user, 'profile');
405
+
406
+ // Send the activation again only if we use double opt-in, otherwise it has no meaning
407
+ // TODO: Maybe define a specific email for that and not the activation email
408
+ if ($email_changed && $subscription_module->is_double_optin()) {
409
+ $subscription_module->send_activation_email($user);
410
+ // TODO: Move this option on new profile configuration panel
411
+ $alert = $subscription_module->options['profile_email_changed'];
412
+ }
413
+
414
+ if (isset($alert)) {
415
+ $user->alert = $alert;
416
+ } else {
417
+ // TODO: Move this label on profile settings panel
418
+ $user->alert = $subscription_module->options['profile_saved'];
419
+ }
420
+ return $user;
421
+ }
422
+
423
  function upgrade() {
424
  global $wpdb, $charset_collate;
425
 
426
  parent::upgrade();
427
+
428
+ // Migration code
429
+ if (empty($this->options) || empty($this->options['email_changed'])) {
430
+ // Options of the subscription module (worng name, I know)
431
+ $options = get_option('newsletter');
432
+ $this->options['saved'] = $options['profile_saved'];
433
+ $this->options['text'] = $options['profile_text'];
434
+ $this->options['email_changed'] = $options['profile_email_changed'];
435
+ $this->options['error'] = $options['profile_error'];
436
+ $this->options['url'] = $options['profile_url'];
437
+ $this->save_options($this->options);
438
+ }
439
+
440
+ if (empty($this->options) || empty($this->options['save_label'])) {
441
+ $options = get_option('newsletter_profile');
442
+ $this->options['save_label'] = $options['save'];
443
+ $this->save_options($this->options);
444
+ }
445
+
446
+
447
  }
448
 
449
  function admin_menu() {
450
  //$this->add_menu_page('index', 'Subscribers');
451
+ $this->add_admin_page('index', 'Profile');
452
+ }
453
+
454
+ // Patch to avoid conflicts with the "newsletter_profile" option of the subscription module
455
+ // TODO: Fix it
456
+ public function get_prefix($sub = '') {
457
+ if (empty($sub))
458
+ $sub = 'main';
459
+ return parent::get_prefix($sub);
460
  }
461
 
462
  }
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Tags: newsletter,email,subscription,mass mail,list build,email marketing,direct mailing,automation,automated
3
  Requires at least: 3.4.0
4
  Tested up to: 4.9.5
5
- Stable tag: 5.4.2
6
  Contributors: satollo,webagile,michael-travan
7
 
8
  Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
@@ -14,11 +14,11 @@ send and track e-mails, headache-free. It just works out of box!
14
 
15
  = Main Features =
16
 
17
- * Subscription spam check with domain/ip black lists, Akismet, captcha
18
- * GDPR ready
19
- * **Responsive email Drag & Drop composer**
20
  * **Unlimited subscribers** with statistics
21
  * **Unlimited newsletter** with tracking
 
 
 
22
  * Customizable **subscription widget**, **page** or **custom form**
23
  * Wordpress User Registration **seamless integration**
24
  * **Single** And **Double Opt-In** plus privacy checkbox for EU laws compliance
@@ -90,6 +90,36 @@ Thank you, The Newsletter Team
90
 
91
  == Changelog ==
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  = 5.4.2 =
94
 
95
  * SVN Deleted files fix
2
  Tags: newsletter,email,subscription,mass mail,list build,email marketing,direct mailing,automation,automated
3
  Requires at least: 3.4.0
4
  Tested up to: 4.9.5
5
+ Stable tag: 5.4.3
6
  Contributors: satollo,webagile,michael-travan
7
 
8
  Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
14
 
15
  = Main Features =
16
 
 
 
 
17
  * **Unlimited subscribers** with statistics
18
  * **Unlimited newsletter** with tracking
19
+ * Subscription spam check with domain/ip black lists, Akismet, captcha
20
+ * [GDPR ready](https://www.thenewsletterplugin.com/documentation/gdpr-compliancy)
21
+ * **Responsive email Drag & Drop composer**
22
  * Customizable **subscription widget**, **page** or **custom form**
23
  * Wordpress User Registration **seamless integration**
24
  * **Single** And **Double Opt-In** plus privacy checkbox for EU laws compliance
90
 
91
  == Changelog ==
92
 
93
+ = 5.4.3 =
94
+
95
+ * Improved the profile editing page and the email change check with activation id in double opt-in mode
96
+ * New profile editing panel configuration
97
+ * Privacy notice optionally even on profile panel
98
+ * New list change logging with source
99
+ * Removed old tabled-layout on profile editing page
100
+ * Clean up procedure for statistics and logs tables
101
+ * Removed old widget layout
102
+ * New options on list management panel
103
+ * Forced lists option removed from the subscription panel
104
+ * Dedicated page moved to main settings panel
105
+ * Tracking default value on main settings panel
106
+ * Removed old translations
107
+ * Added default option files
108
+ * Service message template no more on PHP file, the configurable template must be used
109
+ * Reactivation after cancellation feature
110
+ * Revised and simplified all texts for easy translation by the community
111
+ * The messages alternative page (/extensions/newsletter/subscription/page.php) is now deprecated and will be removed
112
+ * New [cancellation documentation page published](/extensions/newsletter/subscription/page.php)
113
+ * Integrated SMTP is now deprecated (soon will be replaced with a **free extension**)
114
+ * {home_url} tag is now deprecated, use {blog_url} instead
115
+ * Introduced tags {company_name} and {company_address} replaced by info in the company info configuration
116
+ * Default template for messages has been improved with company contacts
117
+ * Repeated subscriptions management
118
+ * Generally improved the performances with caching and code clean up
119
+ * General CSS moved to the main settings panel
120
+ * Option to disable the default CSS
121
+ * Profile export fix
122
+
123
  = 5.4.2 =
124
 
125
  * SVN Deleted files fix
statistics/statistics.php CHANGED
@@ -8,6 +8,9 @@ require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
8
  class NewsletterStatistics extends NewsletterModule {
9
 
10
  static $instance;
 
 
 
11
 
12
  /**
13
  * @return NewsletterStatistics
@@ -87,24 +90,18 @@ class NewsletterStatistics extends NewsletterModule {
87
  setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
88
 
89
  $is_action = strpos($url, '?na=');
90
-
91
  $ip = $this->get_remote_ip();
92
 
93
  if (!$is_action) {
94
-
95
- $res = $wpdb->insert(NEWSLETTER_STATS_TABLE, array(
96
- 'email_id' => $email_id,
97
- 'user_id' => $user_id,
98
- 'url' => $url,
99
- 'ip' => $ip
100
- )
101
- );
102
- $wpdb->query($wpdb->prepare("update " . NEWSLETTER_SENT_TABLE . " set open=2, ip=%s where email_id=%d and user_id=%d limit 1", $ip, $email_id, $user_id));
103
  } else {
104
- $wpdb->query($wpdb->prepare("update " . NEWSLETTER_SENT_TABLE . " set open=1, ip=%s where email_id=%d and user_id=%d and open=0 limit 1", $ip, $email_id, $user_id));
 
105
  }
106
 
107
- $this->update_last_activity($user);
108
 
109
  header('Location: ' . apply_filters('newsletter_redirect_url', $url, $email, $user));
110
  die();
@@ -141,28 +138,16 @@ class NewsletterStatistics extends NewsletterModule {
141
 
142
  $ip = $this->get_remote_ip();
143
 
144
- $wpdb->query($wpdb->prepare("update " . NEWSLETTER_SENT_TABLE . " set open=1, ip=%s where email_id=%d and user_id=%d and open=0 limit 1", $ip, $email_id, $user_id));
145
- $res = $wpdb->insert(NEWSLETTER_STATS_TABLE, array(
146
- 'email_id' => (int) $email_id,
147
- 'user_id' => (int) $user_id,
148
- 'ip' => $ip)
149
- );
150
- if (!$res) {
151
- $this->logger->fatal($wpdb->last_error);
152
- }
153
-
154
- $this->update_last_activity($user);
155
 
156
- header('Content-Type: image/gif');
 
 
157
  echo base64_decode('_R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
158
  die();
159
  }
160
  }
161
-
162
- function update_last_activity($user) {
163
- global $wpdb;
164
- $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set last_activity=%d where id=%d limit 1", time(), $user->id));
165
- }
166
 
167
  function upgrade() {
168
  global $wpdb, $charset_collate;
@@ -173,7 +158,6 @@ class NewsletterStatistics extends NewsletterModule {
173
  `id` int(11) NOT NULL AUTO_INCREMENT,
174
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
175
  `url` varchar(255) NOT NULL DEFAULT '',
176
- `anchor` varchar(200) NOT NULL DEFAULT '',
177
  `user_id` int(11) NOT NULL DEFAULT '0',
178
  `email_id` varchar(10) NOT NULL DEFAULT '0',
179
  `link_id` int(11) NOT NULL DEFAULT '0',
@@ -267,7 +251,7 @@ class NewsletterStatistics extends NewsletterModule {
267
 
268
  // Very old emails was missing the send_on
269
  if ($email->send_on == 0) {
270
- $wpdb->query($wpdb->prepare("update " . NEWSLETTER_EMAILS_TABLE . " set send_on=unix_timestamp(created) where id=%d limit 1", $email->id));
271
  $email = $this->get_email($email->id);
272
  }
273
 
@@ -292,7 +276,7 @@ class NewsletterStatistics extends NewsletterModule {
292
  $query = $email->query . " and unix_timestamp(created)<" . $email->send_on;
293
 
294
  $query = str_replace('*', 'id, ' . $email->id . ', ' . $email->send_on, $query);
295
- $wpdb->query("insert ignore into " . NEWSLETTER_SENT_TABLE . " (user_id, email_id, time) " . $query);
296
  }
297
 
298
  function update_stats($email) {
@@ -326,17 +310,25 @@ class NewsletterStatistics extends NewsletterModule {
326
  function add_click($url, $user_id, $email_id, $ip = null) {
327
  global $wpdb;
328
  if (is_null($ip)) {
329
- $ip = preg_replace('/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR']);
330
  }
331
- $wpdb->insert(NEWSLETTER_STATS_TABLE, array(
332
- 'email_id' => $user_id,
333
- 'user_id' => $email_id,
334
  'url' => $url,
335
  'ip' => $ip
336
  )
337
  );
338
  }
339
 
 
 
 
 
 
 
 
 
340
  }
341
 
342
  NewsletterStatistics::instance();
8
  class NewsletterStatistics extends NewsletterModule {
9
 
10
  static $instance;
11
+
12
+ const SENT_READ = 1;
13
+ const SENT_CLICK = 2;
14
 
15
  /**
16
  * @return NewsletterStatistics
90
  setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
91
 
92
  $is_action = strpos($url, '?na=');
93
+
94
  $ip = $this->get_remote_ip();
95
 
96
  if (!$is_action) {
97
+ $this->add_click($url, $user_id, $email_id, $ip);
98
+ $this->update_open_value(self::SENT_CLICK, $user_id, $email_id, $ip);
 
 
 
 
 
 
 
99
  } else {
100
+ // Track an action as an email read and not a click
101
+ $this->update_open_value(self::SENT_READ, $user_id, $email_id, $ip);
102
  }
103
 
104
+ $this->update_user_last_activity($user);
105
 
106
  header('Location: ' . apply_filters('newsletter_redirect_url', $url, $email, $user));
107
  die();
138
 
139
  $ip = $this->get_remote_ip();
140
 
141
+ $this->add_click('', $user_id, $email_id, $ip);
142
+ $this->update_open_value(self::SENT_READ, $user_id, $email_id, $ip);
 
 
 
 
 
 
 
 
 
143
 
144
+ $this->update_user_last_activity($user);
145
+
146
+ header('Content-Type: image/gif', true);
147
  echo base64_decode('_R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
148
  die();
149
  }
150
  }
 
 
 
 
 
151
 
152
  function upgrade() {
153
  global $wpdb, $charset_collate;
158
  `id` int(11) NOT NULL AUTO_INCREMENT,
159
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
160
  `url` varchar(255) NOT NULL DEFAULT '',
 
161
  `user_id` int(11) NOT NULL DEFAULT '0',
162
  `email_id` varchar(10) NOT NULL DEFAULT '0',
163
  `link_id` int(11) NOT NULL DEFAULT '0',
251
 
252
  // Very old emails was missing the send_on
253
  if ($email->send_on == 0) {
254
+ $this->query($wpdb->prepare("update " . NEWSLETTER_EMAILS_TABLE . " set send_on=unix_timestamp(created) where id=%d limit 1", $email->id));
255
  $email = $this->get_email($email->id);
256
  }
257
 
276
  $query = $email->query . " and unix_timestamp(created)<" . $email->send_on;
277
 
278
  $query = str_replace('*', 'id, ' . $email->id . ', ' . $email->send_on, $query);
279
+ $this->query("insert ignore into " . NEWSLETTER_SENT_TABLE . " (user_id, email_id, time) " . $query);
280
  }
281
 
282
  function update_stats($email) {
310
  function add_click($url, $user_id, $email_id, $ip = null) {
311
  global $wpdb;
312
  if (is_null($ip)) {
313
+ $ip = $this->get_remote_ip();
314
  }
315
+ $this->insert(NEWSLETTER_STATS_TABLE, array(
316
+ 'email_id' => $email_id,
317
+ 'user_id' => $user_id,
318
  'url' => $url,
319
  'ip' => $ip
320
  )
321
  );
322
  }
323
 
324
+ function update_open_value($value, $user_id, $email_id, $ip = null) {
325
+ global $wpdb;
326
+ if (is_null($ip)) {
327
+ $ip = $this->get_remote_ip();
328
+ }
329
+ $this->query($wpdb->prepare("update " . NEWSLETTER_SENT_TABLE . " set open=%d, ip=%s where email_id=%d and user_id=%d and open<%d limit 1", $value, $ip, $email_id, $user_id, $value));
330
+ }
331
+
332
  }
333
 
334
  NewsletterStatistics::instance();
subscription/style.css → style.css RENAMED
@@ -54,7 +54,7 @@ CUSTOM CSS RULES.
54
 
55
  .tnp-subscription input[type=checkbox],
56
  .tnp-widget input[type=radio] {
57
- width: auto;
58
  display: inline;
59
  }
60
 
@@ -118,7 +118,7 @@ CUSTOM CSS RULES.
118
  }
119
 
120
  .tnp-profile form input[type=checkbox], .tnp-profile input[type=radio] {
121
- width: auto;
122
  display: inline;
123
  }
124
 
@@ -134,9 +134,16 @@ CUSTOM CSS RULES.
134
  .tnp-profile form .tnp-field input[type=submit] {
135
  background-color: #444;
136
  color: #fff;
 
137
  height: auto;
138
  }
139
 
 
 
 
 
 
 
140
 
141
 
142
  .tnp-widget {
@@ -241,6 +248,7 @@ CUSTOM CSS RULES.
241
  height: auto;
242
  }
243
 
 
244
 
245
  .tnp-subscription-minimal {
246
  width: 100%;
@@ -269,6 +277,10 @@ CUSTOM CSS RULES.
269
  border-radius: 0px;
270
  }
271
 
 
 
 
 
272
  .tnp-subscription-minimal input.tnp-submit {
273
  width: 29%;
274
  box-sizing: border-box;
54
 
55
  .tnp-subscription input[type=checkbox],
56
  .tnp-widget input[type=radio] {
57
+ max-width: 20px;
58
  display: inline;
59
  }
60
 
118
  }
119
 
120
  .tnp-profile form input[type=checkbox], .tnp-profile input[type=radio] {
121
+ max-width: 20px;
122
  display: inline;
123
  }
124
 
134
  .tnp-profile form .tnp-field input[type=submit] {
135
  background-color: #444;
136
  color: #fff;
137
+ width: auto;
138
  height: auto;
139
  }
140
 
141
+ @media all and (max-width: 480px) {
142
+ .tnp-profile input[type=submit] {
143
+ width: 100%;
144
+ }
145
+ }
146
+
147
 
148
 
149
  .tnp-widget {
248
  height: auto;
249
  }
250
 
251
+ /* The minimal form */
252
 
253
  .tnp-subscription-minimal {
254
  width: 100%;
277
  border-radius: 0px;
278
  }
279
 
280
+ .tnp-subscription-minimal .tnp-privacy-field {
281
+ margin-top: 10px;
282
+ }
283
+
284
  .tnp-subscription-minimal input.tnp-submit {
285
  width: 29%;
286
  box-sizing: border-box;
subscription/antibot.php CHANGED
@@ -114,7 +114,8 @@ if ($controls->is_action()) {
114
  300 => '5 ' . __('minutes', 'newsletter'),
115
  600 => '10 ' . __('minutes', 'newsletter'),
116
  900 => '15 ' . __('minutes', 'newsletter'),
117
- 1800 => '30 ' . __('minutes', 'newsletter')
 
118
  ));
119
  ?>
120
  <?php $controls->help('https://www.thenewsletterplugin.com/documentation/antiflood') ?>
114
  300 => '5 ' . __('minutes', 'newsletter'),
115
  600 => '10 ' . __('minutes', 'newsletter'),
116
  900 => '15 ' . __('minutes', 'newsletter'),
117
+ 1800 => '30 ' . __('minutes', 'newsletter'),
118
+ 360 => '60 ' . __('minutes', 'newsletter')
119
  ));
120
  ?>
121
  <?php $controls->help('https://www.thenewsletterplugin.com/documentation/antiflood') ?>
subscription/{languages/lists-en_US.php → defaults-lists.php} RENAMED
@@ -6,4 +6,5 @@ for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
6
  $options['list_' . $i] = '';
7
  $options['list_' . $i . '_status'] = 0;
8
  $options['list_' . $i . '_checked'] = 0;
 
9
  }
6
  $options['list_' . $i] = '';
7
  $options['list_' . $i . '_status'] = 0;
8
  $options['list_' . $i . '_checked'] = 0;
9
+ $options['list_' . $i . '_forced'] = 0;
10
  }
subscription/defaults-profile.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // This file is used only on first installation!
4
+
5
+ $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
+
23
+ $options['subscribe'] = __('Subscribe', 'newsletter');
24
+
25
+ $options['title_female'] = __('Ms.', 'newsletter');
26
+ $options['title_male'] = __('Mr.', 'newsletter');
27
+ $options['title_none'] = __('Dear', 'newsletter');
28
+
29
+ $options['sex_male'] = 'Man';
30
+ $options['sex_female'] = 'Woman';
31
+ $options['sex_none'] = 'Not specified';
32
+
33
+ for ($i=1; $i<=NEWSLETTER_PROFILE_MAX; $i++) {
34
+ $options['profile_' . $i . '_status'] = 0;
35
+ $options['profile_' . $i] = '';
36
+ $options['profile_' . $i . '_type'] = 'text';
37
+ $options['profile_' . $i . '_placeholder'] = '';
38
+ $options['profile_' . $i . '_rules'] = 0;
39
+ $options['profile_' . $i . '_options'] = '';
40
+ }
41
+
subscription/defaults-template.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // This file is used only on first installation!
4
+
5
+ $options = array();
6
+ $options['template'] = @file_get_contents(__DIR__ . '/../email.html');
subscription/defaults.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Those default options are used ONLY on FIRST setup and on plugin updates but limited to
3
+ // new options that may have been added between your and new version.
4
+ //
5
+ // This is the main language file, too, which is always loaded by Newsletter. Other language
6
+ // files are loaded according the WPLANG constant defined in wp-config.php file. Those language
7
+ // specific files are "merged" with this one and the language specific configuration
8
+ // keys override the ones in this file.
9
+ //
10
+ // Language specific files only need to override configurations containing texts
11
+ // langiage dependant.
12
+
13
+ $options = array();
14
+
15
+ $options['noconfirmation'] = 1;
16
+ $options['antiflood'] = 10;
17
+ $options['ip_blacklist'] = array();
18
+ $options['address_blacklist'] = array();
19
+ $options['domain_check'] = 0;
20
+ $options['akismet'] = 0;
21
+ $options['captcha'] = 0;
22
+ $options['notify_email'] = get_option('admin_email');
23
+ $options['multiple'] = 1;
24
+
25
+ $options['error_text'] = '<p>' . __('You cannot subscribe with the email address you entered, please contact the site administrator.', 'newsletter') . '</p>';
26
+
27
+ //$options['already_confirmed_text'] = '<p>This email address is already subscribed, anyway a welcome email has been sent again. Thank you.</p>';
28
+
29
+ // Subscription page introductory text (befor the subscription form)
30
+ $options['subscription_text'] = "{subscription_form}";
31
+
32
+ // Message show after a subbscription request has made.
33
+ $options['confirmation_text'] = '<p>' . __('A confirmation email is on the way. Follow the instructions and check the spam folder. Thank you.') . '</p>';
34
+
35
+ // Confirmation email subject (double opt-in)
36
+ $options['confirmation_subject'] = __("Please confirm your subscription", 'newsletter');
37
+
38
+ $options['confirmation_tracking'] = '';
39
+
40
+ // Confirmation email body (double opt-in)
41
+ $options['confirmation_message'] = '<p>' . __('Please confirm your subscription <a href="{subscription_confirm_url}">clicking here</a>', 'newsletter') . '</p>';
42
+
43
+ // Subscription confirmed text (after a user clicked the confirmation link
44
+ // on the email he received
45
+ $options['confirmed_text'] = '<p>' . __('Your subscription has been confirmed', 'newsletter') . '</p>';
46
+
47
+ $options['confirmed_subject'] = __('Welcome', 'newsletter');
48
+
49
+ $options['confirmed_message'] =
50
+ "<p>" . __('This message confirms your subscription to our newsletter. Thank you!', 'newsletter') . '</p>' .
51
+ '<hr>' .
52
+ '<p><a href="{profile_url}">' . __('Change your profile', 'newsletter') . '</p>';
53
+
54
+ $options['confirmed_tracking'] = '';
55
+
56
+ // Unsubscription process
57
+
58
+ $options['unsubscription_text'] = '<p>' . __('Please confirm you want to unsubscribe <a href="{unsubscription_confirm_url}">clicking here</a>.', 'newsletter') . '</p>';
59
+ $options['unsubscription_error_text'] = '<p>' . __("Subscriber not found, it probably has already been removed. No further actions are required.", 'newsletter') . '</p>';
60
+
61
+ // When you finally loosed your subscriber
62
+ $options['unsubscribed_text'] = "<p>" . __('Your subscription has been deleted. If that was an error you can <a href="{reactivate_url}">subscribe again here</a>.', 'newsletter') . "</p>";
63
+
64
+ $options['unsubscribed_subject'] = __("Goodbye", 'newsletter');
65
+
66
+ $options['unsubscribed_message'] = '<p>' . __('This message confirms that you have unsubscribed from our newsletter. Thank you.') . '</p>';
67
+
68
+ $options['reactivated_text'] = '<p>' . __('Your subscription has been reactivated.') . '</p>';
subscription/email-alternative.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
- /*
3
- * PLEASE USE THE TEMPLATE EDITOR INSIDE THE PLUGIN ADMINISTRATIVE PANEL, THIS FILE WILL BE SHORTLY DEPRECATED.
4
- *
5
- * Copy this file into
6
- *
7
- * wp-content/extensions/newsletter/subscription
8
- *
9
- * and RENAME it to email.php.
10
- *
11
- * It will be used insted of the standard email.php file to generate the body of
12
- * confirmation and welcome emails.
13
- *
14
- * A globally available $message variable contains the generated message as resulted
15
- * by merging your configured message (on subscription steps panel) and the user's
16
- * data.
17
- *
18
- */
19
- ?>
20
- <html>
21
- <head>
22
- <style type="text/css">
23
- </style>
24
- </head>
25
-
26
- <body style="font-family: sans-serif; font-size: 12px">
27
-
28
- <?php // NEVER FORGET THIS LINE! ?>
29
- <?php echo $message; ?>
30
-
31
- </body>
32
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/email.html CHANGED
@@ -9,13 +9,14 @@
9
  }
10
  </style>
11
  </head>
12
-
13
- <!-- KEEP THE TAMPLE SIMPLE: THOSE ARE SERVICE MESSAGES. -->
14
- <body style="margin: 0;">
15
- <!-- Top title with dark background #333, font color #fff, font size 32px -->
16
- <table style="background-color: #333; width: 100%; color: #fff; font-size: 32px">
 
17
  <tr>
18
- <td style="padding: 25px; text-align: center">
19
  {blog_title}
20
  </td>
21
  </tr>
@@ -24,17 +25,25 @@
24
  <!-- Main table 100% wide with background color #eee -->
25
  <table style="background-color: #eee; width: 100%;">
26
  <tr>
27
- <td align="center" style="padding: 15px;">
28
 
29
  <!-- Content table with backgdound color #fff, width 500px -->
30
  <table style="background-color: #fff; max-width: 600px; width: 100%; border: 1px solid #ddd;">
31
  <tr>
32
- <td style="padding: 15px; font-size: 16px; font-family: sans-serif">
33
  <!-- The {message} tag is replaced with one of confirmation, welcome or goodbye messages -->
34
  <!-- Messages content can be configured on Newsletter List Building panels -->
35
 
36
  {message}
37
-
 
 
 
 
 
 
 
 
38
  <!-- Signature if not already added to single messages (surround with <p>) -->
39
 
40
  </td>
9
  }
10
  </style>
11
  </head>
12
+
13
+ <!-- KEEP THE LAYOUT SIMPLE: THOSE ARE SERVICE MESSAGES. -->
14
+ <body style="margin: 0; padding: 0;">
15
+
16
+ <!-- Top title with dark background -->
17
+ <table style="background-color: #444; width: 100%;" cellspacing="0" cellpadding="0">
18
  <tr>
19
+ <td style="padding: 20px; text-align: center; font-family: sans-serif; color: #fff; font-size: 28px">
20
  {blog_title}
21
  </td>
22
  </tr>
25
  <!-- Main table 100% wide with background color #eee -->
26
  <table style="background-color: #eee; width: 100%;">
27
  <tr>
28
+ <td align="center" style="padding: 15px;">
29
 
30
  <!-- Content table with backgdound color #fff, width 500px -->
31
  <table style="background-color: #fff; max-width: 600px; width: 100%; border: 1px solid #ddd;">
32
  <tr>
33
+ <td style="padding: 15px; color: #333; font-size: 16px; font-family: sans-serif">
34
  <!-- The {message} tag is replaced with one of confirmation, welcome or goodbye messages -->
35
  <!-- Messages content can be configured on Newsletter List Building panels -->
36
 
37
  {message}
38
+
39
+ <hr>
40
+ <p>
41
+ <small>
42
+ <a href="{blog_url}">{blog_url}</a><br>
43
+ {company_name}<br>
44
+ {company_address}
45
+ </small>
46
+ </p>
47
  <!-- Signature if not already added to single messages (surround with <p>) -->
48
 
49
  </td>
subscription/email.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
- /*
3
- * PLEASE USE THE TEMPLATE EDITOR INSIDE THE PLUGIN ADMINISTRATIVE PANEL, THIS FILE WILL BE SHORTLY DEPRECATED.
4
- *
5
- * NEVER EDIT THIS FILE OR COPY IT SOMEWHERE ELSE!
6
- *
7
- * See the email-alternative.php to customized the confirmation and welcome
8
- * emails layout.
9
- *
10
- */
11
-
12
- // Check for an alternative email builder.
13
- if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/subscription/email.php')) {
14
- include WP_CONTENT_DIR . '/extensions/newsletter/subscription/email.php';
15
- return;
16
- }
17
-
18
- ?><!DOCTYPE html>
19
- <html>
20
- <head>
21
- <style type="text/css" media="all">
22
- a {
23
- text-decoration: none;
24
- color: #0088cc;
25
- }
26
- </style>
27
- </head>
28
- <body style="background-color: #ddd; font-family: Helvetica Neue, Helvetica, Arial, sans-serif; font-size: 14px; color: #666; margin: 0 auto; padding: 0;">
29
- <br>
30
- <table align="center">
31
- <tr>
32
- <td style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif; font-size: 14px; color: #666;">
33
- <div style="text-align: left; max-width: 500px; border-top: 10px solid #43A4D0; border-bottom: 3px solid #43A4D0;">
34
- <div style="padding: 10px 20px; color: #000; font-size: 20px; background-color: #EFEFEF; border-bottom: 1px solid #ddd">
35
- <?php echo get_option('blogname'); ?>
36
- </div>
37
- <div style="padding: 20px; background-color: #fff; line-height: 18px">
38
-
39
- <?php echo $message; ?>
40
-
41
- </div>
42
-
43
- </div>
44
- </td>
45
- </tr>
46
- </table>
47
- </body>
48
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/forms.php CHANGED
@@ -6,11 +6,11 @@ $controls = new NewsletterControls();
6
  $module = NewsletterSubscription::instance();
7
 
8
  if (!$controls->is_action()) {
9
- $controls->data = get_option('newsletter_forms');
10
  }
11
 
12
  if ($controls->is_action('save')) {
13
- update_option('newsletter_forms', $controls->data);
14
  $controls->add_message_saved();
15
  }
16
  ?>
6
  $module = NewsletterSubscription::instance();
7
 
8
  if (!$controls->is_action()) {
9
+ $controls->data = $module->get_options('forms');
10
  }
11
 
12
  if ($controls->is_action('save')) {
13
+ $module->save_options($controls->data, 'forms');
14
  $controls->add_message_saved();
15
  }
16
  ?>
subscription/languages/de_DE.php DELETED
@@ -1,50 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- // Message show after a subbscription request has made.
6
- $options['confirmation_text'] =
7
- "<p>Sie haben sich in unseren Newsletter eingetragen.
8
- In wenigen Minuten erhalten Sie eine Best&auml;tigungs-Email. Folgen Sie dem Link um die Anmeldung zu best&auml;tigen. Sollte die Email nicht innerhalb der n&auml;chsten 15 Minuten in Ihrem Posteingang erscheinen, &uuml;berpr&uuml;fen Sie Ihren Spam-Ordner.</p>";
9
-
10
- // Confirmation email subject (double opt-in)
11
- $options['confirmation_subject'] =
12
- "{name},{blog_title} Newsletter - hier Anmeldebest&auml;tigung";
13
-
14
- // Confirmation email body (double opt-in)
15
- $options['confirmation_message'] =
16
- "<p>Hallo {name},</p>
17
- <p>Für diese Email-Adresse haben wir eine Anmeldung zu unserem Newsletter erhalten. Sie k&ouml;nnen diese Anmeldung best&auml;tigen, in dem Sie <a href=\"{subscription_confirm_url}\"><strong>hier klicken</strong></a>.
18
- Wenn Sie nicht klicken k&ouml;nnen, nutzen Sie die folgenden URL in Ihren Browser ein:</p>
19
- <p>{subscription_confirm_url}</p>
20
- <p>Wenn die Anmeldung zu unserem Newsletter nicht von Ihnen stammt, ignorieren Sie diese Nachricht einfach.</p>
21
- <p>Vielen Dank.</p>";
22
-
23
-
24
- // Subscription confirmed text (after a user clicked the confirmation link
25
- // on the email he received
26
- $options['confirmed_text'] =
27
- "<p>Ihre Anmeldung zu unserem Newsletter wurde best&auml;tigt!
28
- Herzlichen Dank!</p>";
29
-
30
- $options['confirmed_subject'] =
31
- "{blog_title} Newsletter - Willkommen";
32
-
33
- $options['confirmed_message'] =
34
- "<p>
35
- Hallo {name},
36
- Willkommen zu unserem {blog_title} Newsletter.</p>
37
- <p>
38
- Wir werden Sie künftig regelm&auml;&szlig;ig &uuml;ber Neuigkeiten zu {blog_title} informieren</p>
39
- <p>
40
- Wenn Sie unseren newsletter nicht mehr erhalten m&ouml;chten, tragen Sie sich bitte unter dem folgenden Link aus dem Verteiler aus: <a href=\"{unsubscription_url}\">austragen</a></p>
41
- <p>Besten Dank!</p>";
42
-
43
- // Unsubscription request introductory text
44
- $options['unsubscription_text'] =
45
- "<p>Bitte best&auml;tigen Sie, dass Sie unseren Newsletter abbestellen, indem Sie
46
- <a href=\"{unsubscription_confirm_url}\">hier klicken</a>.";
47
-
48
- // When you finally loosed your subscriber
49
- $options['unsubscribed_text'] =
50
- "<p>Herzlichen Dank, Sie wurden aus dem Verteiler entfernt...</p>";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/en_US.php DELETED
@@ -1,102 +0,0 @@
1
- <?php
2
- // Those default options are used ONLY on FIRST setup and on plugin updates but limited to
3
- // new options that may have been added between your and new version.
4
- //
5
- // This is the main language file, too, which is always loaded by Newsletter. Other language
6
- // files are loaded according the WPLANG constant defined in wp-config.php file. Those language
7
- // specific files are "merged" with this one and the language specific configuration
8
- // keys override the ones in this file.
9
- //
10
- // Language specific files only need to override configurations containing texts
11
- // langiage dependant.
12
-
13
- $options = array();
14
-
15
- $options['noconfirmation'] = 1;
16
- $options['antiflood'] = 10;
17
- $options['ip_blacklist'] = array();
18
- $options['address_blacklist'] = array();
19
- $options['domain_check'] = 0;
20
- $options['akismet'] = 0;
21
- $options['captcha'] = 0;
22
- $options['notify_email'] = get_option('admin_email');
23
-
24
- // Profile page
25
- $options['profile_text'] = __("{profile_form}
26
- <p>If you change your email address, a confirmation email will be sent to activate it.</p>
27
- <p><a href=\"{unsubscription_confirm_url}\">Cancel your subscription</a></p>", 'newsletter');
28
-
29
- // Profile page messages
30
- $options['profile_email_changed'] = "Your email has been changed, an activation email has been sent. Please follow the instructions to activate the new address.";
31
- $options['profile_error'] = "Your email is not valid or already in use by another subscriber or another generic error has been found. Check your data or contact the site owner.";
32
-
33
- $options['error_text'] = '<p>This subscription can\'t be completed, sorry. The email address is blocked or already subscribed. You should contact the owner to unlock that email address. Thank you.</p>';
34
-
35
- //$options['already_confirmed_text'] = '<p>This email address is already subscribed, anyway a welcome email has been resent. Thank you.</p>';
36
-
37
- // Subscription page introductory text (befor the subscription form)
38
- $options['subscription_text'] =
39
- "{subscription_form}";
40
-
41
- // Message show after a subbscription request has made.
42
- $options['confirmation_text'] =
43
- "<p>You have successfully subscribed to the newsletter. You'll
44
- receive a confirmation email in a few minutes. Please follow the
45
- link to confirm your subscription. If the email takes
46
- more than 15 minutes to appear in your mailbox, please check
47
- your spam folder.</p>";
48
-
49
- // Confirmation email subject (double opt-in)
50
- $options['confirmation_subject'] =
51
- "Please confirm subscription - {blog_title} newsletter";
52
-
53
- $options['confirmation_tracking'] = '';
54
-
55
- // Confirmation email body (double opt-in)
56
- $options['confirmation_message'] =
57
- "<p>Hi {name},</p>
58
- <p>A newsletter subscription request for this email address was
59
- received. Please confirm it by <a href=\"{subscription_confirm_url}\"><strong>clicking here</strong></a>. If you cannot
60
- click the link, please use the following link:</p>
61
-
62
- <p>{subscription_confirm_url}</p>
63
-
64
- <p>If you did not make this subscription request, just ignore this
65
- message.</p>
66
- <p>Thank you!<br>
67
- <a href='{blog_url}'>{blog_url}</a></p>";
68
-
69
-
70
-
71
- // Subscription confirmed text (after a user clicked the confirmation link
72
- // on the email he received
73
- $options['confirmed_text'] =
74
- "<p>Your subscription has been confirmed! Thank you {name}!</p>";
75
-
76
- $options['confirmed_subject'] =
77
- "Welcome aboard, {name}";
78
-
79
- $options['confirmed_message'] =
80
- "<p>This message confirms your subscription to the {blog_title} newsletter.</p>
81
- <p>Thank you!<br>
82
- <a href='{blog_url}'>{blog_url}</a></p>
83
- <p>To unsubscribe, <a href='{unsubscription_url}'>click here</a>. To change subscriber options,
84
- <a href='{profile_url}'>click here</a>.</p>";
85
-
86
- $options['confirmed_tracking'] = '';
87
-
88
- // Unsubscription process
89
-
90
- $options['unsubscription_text'] = "<p>Please confirm that you want to unsubscribe by <a href='{unsubscription_confirm_url}'>clicking here</a>.</p>";
91
- $options['unsubscription_error_text'] = "<p>The subscriber was not found, it probably has already been removed. No further actions are required. Thank you.</p>";
92
-
93
- // When you finally loosed your subscriber
94
- $options['unsubscribed_text'] = "<p>Your subscription has been deleted. Thank you.</p>";
95
-
96
- $options['unsubscribed_subject'] = "Goodbye!";
97
-
98
- $options['unsubscribed_message'] =
99
- "<p>This message confirms that you have unsubscribed from the {blog_title} newsletter.</p>
100
- <p>You're welcome to sign up again anytime.</p>
101
- <p>Thank you!<br>
102
- <a href='{blog_url}'>{blog_url}</a></p>";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/es_ES.php DELETED
@@ -1,56 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- // Mostrar mensaje despues de una solicitud de suscripcion hecha.
6
- $options['confirmation_text'] =
7
- "<p>Con exito suscrito a mi boletín informativo.
8
- Usted recibirá en pocos minutos un email de confirmacion. Siga el enlace
9
- en el para confirmar la suscripcion. Si el correo tarda mas de 15
10
- minutos en aparecer en su buzon de correo, revise la carpeta de spam.</p>";
11
-
12
- // Tema de correo electronico de confirmacion (double opt-in)
13
- $options['confirmation_subject'] =
14
- "{name}, confirmar su suscripcion a {blog_title}";
15
-
16
- // Cuerpo confirmacion por correo electronico (double opt-in)
17
- $options['confirmation_message'] =
18
- "<p>Hola {name},</p>
19
- <p>He recibido una solicitud de suscripcion para esta direccion de correo electronico. Usted puede confirmar:
20
- <a href=\"{subscription_confirm_url}\"><strong>click aquí</strong></a>.
21
- Si usted no puede hacer click en el enlace, utilice el siguiente enlace:</p>
22
- <p>{subscription_confirm_url}</p>
23
- <p>Si esta solicitud de suscripcion no se ha hecho de usted, simplemente ignore este mensaje.</p>
24
- <p>Gracias.</p>";
25
-
26
-
27
- // Suscripcion confirmacion texto (despues de que un usuario hace clic en el enlace de confirmacion
28
- // en el correo electronico que recibira
29
- $options['confirmed_text'] =
30
- "<p>Su suscripcion se ha confirmado!
31
- Gracias {name}!</p>";
32
-
33
- $options['confirmed_subject'] =
34
- "Bienvenido a bordo, {name}";
35
-
36
- $options['confirmed_message'] =
37
- "<p>El mensaje de confirmar su suscripcion a {blog_title} newsletter.</p>
38
- <p>Gracias!</p>";
39
-
40
- // Darse de baja de la solicitud introduccion de texto
41
- $options['unsubscription_text'] =
42
- "<p>Por favor, confirme que desea darse de baja mi boletín de noticias
43
- <a href=\"{unsubscription_confirm_url}\">click aquí</a>.";
44
-
45
-
46
- $options['unsubscribed_text'] =
47
- "<p>Me hace llorar, pero he quitado su suscripcion ...</p>";
48
-
49
- $options['unsubscribed_subject'] =
50
- "Adios, {name}";
51
-
52
- $options['unsubscribed_message'] =
53
- "<p>Mensaje de confirmacion de su baja en {blog_title} Boletín de noticias.</p>
54
- <p>Adios!</p>";
55
-
56
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/fr_FR.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- // Message show after a subbscription request has made.
6
- $options['confirmation_text'] =
7
- "<p>Votre demande d'inscription est enregistr&eacute;e. Merci ! Un e-mail de confirmation vous a été envoyé. V&eacute;rifier &eacute;galement votre dossier spam.</p>";
8
-
9
- // Confirmation email subject (double opt-in)
10
- $options['confirmation_subject'] =
11
- "Inscription &agrave; la lettre d&prime;information de {blog_title}";
12
-
13
- // Confirmation email body (double opt-in)
14
- $options['confirmation_message'] =
15
- "<p>Bonjour {name}!</p>
16
- <p>Vous recevez cet e-mail car nous avons enregistr&eacute; une demande d&prime;inscription &agrave; la lettre d&prime;infrmation de {blog_title}.
17
- Merci de confirmer votre inscription en cliquant sur le lien suivant : <a href=\"{subscription_confirm_url}\"><strong>je confirme mon inscription.</strong></a>.
18
- Si le lien ne fonctionne pas, merci d'utiliser cette adresse :</p>
19
- <p>{subscription_confirm_url}</p>
20
- <p>Ignorez ce message si vous n'avez pas effectué de demande.</p>
21
- <p>Merci !</p>";
22
-
23
-
24
- // Subscription confirmed text (after a user clicked the confirmation link
25
- // on the email he received
26
- $options['confirmed_text'] =
27
- "<p>Votre inscription est confirm&eacute;e. Merci !</p>";
28
-
29
- $options['confirmed_subject'] =
30
- "Bienvenue, {name}";
31
-
32
- $options['confirmed_message'] =
33
- "<p>Votre inscription est confirm&eacute;e. Merci !</p>";
34
-
35
- // Unsubscription request introductory text
36
- $options['unsubscription_text'] =
37
- "<p>&Ecirc;tes-vous certain de vouloir vous d&eacute;sinscrire de la lettre d&prime;information de {blog_title} ? <a href=\"{unsubscription_confirm_url}\">Oui</a>.";
38
-
39
- // When you finally loosed your subscriber
40
- $options['unsubscribed_text'] =
41
- "<p>Vous n&prime;&ecirc;tes plus abonn&eacute; &agrave; la lettre d'information de {blog_title}. Merci de nous avoir suivi et &agrave; bient&ocirc;t !</p>";
42
-
43
-
44
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/it_IT.php DELETED
@@ -1,41 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- // Subscription registration message
6
- $options['confirmation_text'] =
7
- "<p>L'iscrizione è quasi completa: controlla la tua
8
- casella di posta, c'è un messaggio per te con il quale confermare l'iscrizione.</p>";
9
-
10
- // Confirmation email (double opt-in)
11
- $options['confirmation_subject'] =
12
- "{name}, conferma l'iscrizione alle newsletter di {blog_title}";
13
-
14
- $options['confirmation_message'] =
15
- "<p>Ciao {name},</p>
16
- <p>hai richiesto l'iscrizione alla newsletter di {blog_title}.
17
- Conferma l'iscrizione <a href=\"{subscription_confirm_url}\"><strong>cliccando qui</strong></a>
18
- oppure copia il link qui sotto nel tu programma di navigazione:</p>
19
- <p>{subscription_confirm_url}</p>
20
- <p>Grazie!</p>";
21
-
22
- $options['confirmed_subject'] =
23
- "Benvenuto {name}!";
24
-
25
- $options['confirmed_message'] =
26
- "<p>Con questo messaggio ti confermo l'iscrizione alla newsletter.</p>
27
- <p>Grazie!</p>";
28
-
29
- // Subscription confirmed text
30
- $options['confirmed_text'] =
31
- "<p>{name}, la tua iscrizione è stata confermata.
32
- Buona lettura!</p>";
33
-
34
-
35
- $options['unsubscription_text'] =
36
- "<p>{name}, vuoi eliminare la tua iscrizione?
37
- Se sì... mi dispace, ma non ti trattengo oltre:</p>
38
- <p><a href=\"{unsubscription_confirm_url}\">Sì, voglio eliminare la mia iscrizione per sempre</a>.</p>";
39
-
40
- $options['unsubscribed_text'] =
41
- "<p>La tua iscrizione è stata definitivamente eliminata.</p>";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/nl_NL.php DELETED
@@ -1,49 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- // Message show after a subbscription request has made.
6
- $options['confirmation_text'] =
7
- "<p>Je hebt je ingeschreven op de nieuwsbrief.</p>
8
- <p>Binnen enkele minuten zal je een bevestigingsmail ontvangen. Volg de link in die mail om jouw inschrijving te bevestigen. Indien je problemen hebt met het ontvangen van de bevestigingsmail kan je ons via het contactformulier bereiken.</p>";
9
-
10
- // Confirmation email subject (double opt-in)
11
- $options['confirmation_subject'] =
12
- "{name}, Bevestig jouw inschrijving op de nieuwsbrief van {blog_title}";
13
-
14
- // Confirmation email body (double opt-in)
15
- $options['confirmation_message'] =
16
- "<p>Hallo {name},</p>
17
- <p>We ontvingen jouw inschrijving op onze nieuwsbrief. Gelieve de inschrijving te bevestigen door <a href=\"{subscription_confirm_url}\"><strong>hier</strong></a> te klikken. Als het klikken op de link voor jou niet werkt, kan je de volgende link in jouw browser copieren.</p>
18
- <p>{subscription_confirm_url}</p>
19
- <p>Indien je deze mail ontvangt en toch geen inschrijving gevraagd hebt, hoef je niets te doen. De inschrijving wordt dan automatisch geannuleerd.</p>
20
- <p>Dank u wel.</p>";
21
-
22
- // Subscription confirmed text (after a user clicked the confirmation link
23
- // on the email he received
24
- $options['confirmed_text'] =
25
- "<p>Je hebt zonet jouw inschrijving bevestigd.</p><p>bedankt {name} !</p>";
26
-
27
- $options['confirmed_subject'] =
28
- "Welkom, {name}";
29
-
30
- $options['confirmed_message'] =
31
- "<p>Uw inschrijving op de niewsbrief van {blog_title} is bevestigd.</p>
32
- <p>Bedankt !</p>";
33
-
34
- // Unsubscription request introductory text
35
- $options['unsubscription_text'] =
36
- "<p>Gelieve uw uitschrijving te bevestigen door <a href=\"{unsubscription_confirm_url}\">hier</a> te klikken.";
37
-
38
- // When you finally loosed your subscriber
39
- $options['unsubscribed_text'] =
40
- "<p>U bent uit onze lijst verwijderd.</p>";
41
-
42
- $options['unsubscribed_subject'] =
43
- "Tot ziens, {name}";
44
-
45
- $options['unsubscribed_message'] =
46
- "<p>Uw uitschrijving op de nieuwsbrief van {blog_title} is bevestigd.</p>
47
- <p>Tot ziens.</p>";
48
-
49
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/pl_PL.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- // Message show after a subbscription request has made.
6
- $options['confirmation_text'] =
7
- "<p>Zostałeś zapisany do subskrypcji.
8
- W ciągu kilku minut otrzymasz e-mail potwierdzający.
9
- Kliknij w odnośnik w nim zawarty aby potwierdzić subskrypcję. Jeśli e-mail nie pojawi się w Twojej skrzynce przez 15 minut - sprawdź folder spam.</p>";
10
-
11
- // Confirmation email subject (double opt-in)
12
- $options['confirmation_subject'] =
13
- "{name}, potwierdź swoją subskrypcję w {blog_title}";
14
-
15
- // Confirmation email body (double opt-in)
16
- $options['confirmation_message'] =
17
- "<p>Witaj {name},</p>
18
- <p>Otrzymaliśmy prośbę o wpis do subskrypcji dla tego adresu e-mail. Możesz potwierdzić ją
19
- <a href=\"{subscription_confirm_url}\"><strong>klikając tutaj</strong></a>.
20
- Jeśli nie możesz kliknąć odnośnika, użyj poniższego linku:</p>
21
- <p>{subscription_confirm_url}</p>
22
- <p>Jeśli to nie Ty wpisywałeś się do subskrypcji, po prostu zignoruj tę wiadomość.</p>
23
- <p>Dziękujemy.</p>";
24
-
25
-
26
- // Subscription confirmed text (after a user clicked the confirmation link
27
- // on the email he received
28
- $options['confirmed_text'] =
29
- "<p>Twoja subskrypcja została potwierdzona!
30
- Dziękujemy {name}!</p>";
31
-
32
- $options['confirmed_subject'] =
33
- "Witaj, {name}";
34
-
35
- $options['confirmed_message'] =
36
- "<p>Wiadomość potwierdzająca subskyrpcję {blog_title}.</p>
37
- <p>Dziękujemy!</p>";
38
-
39
- // Unsubscription request introductory text
40
- $options['unsubscription_text'] =
41
- "<p>Proszę potwierdzić rezygnację z subskrypcji
42
- <a href=\"{unsubscription_confirm_url}\">klikając tutaj</a>.";
43
-
44
- // When you finally loosed your subscriber
45
- $options['unsubscribed_text'] =
46
- "<p>To smutne, ale usunęliśmy Twój e-mail z subskrypcji...</p>";
47
-
48
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/profile-en_US.php DELETED
@@ -1,51 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- $options = array();
6
- $options['email'] = 'Email';
7
- $options['email_error'] = 'The email is not correct';
8
- $options['name'] = 'Name';
9
- $options['name_error'] = 'The name is not correct';
10
- $options['name_status'] = 0;
11
- $options['name_rules'] = 0;
12
- $options['surname'] = 'Last name';
13
- $options['surname_error'] = 'The last name is not correct';
14
- $options['surname_status'] = 0;
15
- $options['sex_status'] = 0;
16
- $options['sex'] = 'I\'m';
17
-
18
- $options['privacy'] = 'Subscribing I accept the privacy rules of this site';
19
- $options['privacy_error'] = 'You must accept the privacy statement';
20
- $options['privacy_status'] = 0;
21
- $options['privacy_url'] = '';
22
-
23
- $options['subscribe'] = 'Subscribe';
24
- $options['save'] = 'Save';
25
- $options['profile_export'] = 'Export your data';
26
- $options['profile_edit'] = 'Change your profile';
27
-
28
- $options['title_female'] = 'Mrs.';
29
- $options['title_male'] = 'Mr.';
30
- $options['title_none'] = 'Dear';
31
-
32
- $options['sex_male'] = 'Man';
33
- $options['sex_female'] = 'Woman';
34
- $options['sex_none'] = 'None';
35
-
36
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
37
- $options['list_' . $i] = '';
38
- $options['list_' . $i . '_status'] = 0;
39
- $options['list_' . $i . '_checked'] = 0;
40
- }
41
-
42
- for ($i=1; $i<=NEWSLETTER_PROFILE_MAX; $i++) {
43
- $options['profile_' . $i . '_status'] = 0;
44
- $options['profile_' . $i] = '';
45
- $options['profile_' . $i . '_type'] = 'text';
46
- $options['profile_' . $i . '_placeholder'] = '';
47
- $options['profile_' . $i . '_rules'] = 0;
48
- $options['profile_' . $i . '_options'] = '';
49
- }
50
-
51
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/profile-it_IT.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- $options = array();
6
- $options['email'] = 'Email';
7
- $options['email_error'] = 'L\'indirizzo email non è corretto';
8
- $options['name'] = 'Nome';
9
- $options['name_error'] = 'Il nome non è corretto';
10
- $options['surname'] = 'Cognome';
11
- $options['surname_error'] = 'Il cognome non è corretto';
12
- $options['sex'] = 'Sono';
13
- $options['privacy'] = 'Accetto le regole di riservatezza di questo sito';
14
- $options['privacy_error'] = 'Devi accettare le regole di riservatezza';
15
- $options['subscribe'] = 'Procedi';
16
- $options['save'] = 'Salva';
17
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/pt_BR.php DELETED
@@ -1,50 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- // Message show after a subbscription request has made.
6
- $options['confirmation_text'] =
7
- "<p>Você foi inscrito corretamente na newsletter.
8
- Em alguns minutos você receberá um email de confirmação. Siga o link para confirmar a inscrição.
9
- Se o email demorar mais do que 15 minutos para chegar, cheque sua caixa de SPAM.</p>";
10
-
11
- // Confirmation email subject (double opt-in)
12
- $options['confirmation_subject'] =
13
- "{name}, confirme sua inscrição no site {blog_title}";
14
-
15
- // Confirmation email body (double opt-in)
16
- $options['confirmation_message'] =
17
- "<p>Oi {name},</p>
18
- <p>Recebemos um pedido de inscrição nos nossos informativos deste email. Você pode confirmar
19
- <a href=\"{subscription_confirm_url}\"><strong>clicando aqui</strong></a>.
20
- Se você não puder seguir o link, acesse este endereço:</p>
21
- <p>{subscription_confirm_url}</p>
22
- <p>Se o pedido de inscrição não veio de você, apenas ignore esta mensagem.</p>
23
- <p>Obrigado.</p>";
24
-
25
-
26
- // Subscription confirmed text (after a user clicked the confirmation link
27
- // on the email he received
28
- $options['confirmed_text'] =
29
- "<p>Sua inscrição foi confirmada!
30
- Obrigado {name}.</p>";
31
-
32
- $options['confirmed_subject'] =
33
- "Bem vindo(a) a bordo, {name}";
34
-
35
- $options['confirmed_message'] =
36
- "<p>A mensagem confirma a sua inscrição nos nossos informativos.</p>
37
- <p>Obrigado.</p>";
38
-
39
- // Unsubscription request introductory text
40
- $options['unsubscription_text'] =
41
- "<p>Cancele a sua inscrição nos informativos
42
- <a href=\"{unsubscription_confirm_url}\">clicando aqui</a>.";
43
-
44
- // When you finally loosed your subscriber
45
- $options['unsubscribed_text'] =
46
- "<p>Sua inscrição foi cancelada. Inscreva-se novamente quando quiser.</p>";
47
-
48
-
49
-
50
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/ru_RU.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- // Message show after a subbscription request has made.
6
- $options['confirmation_text'] =
7
- "<p>Вы успешно подписаны на рассылку. Вы получите письмо с подтверждением через несколько минут. Перейдите по ссылке в письме для подтверждения. Если в течении 15 минут письмо все-таки не пришло, проверьте папку со спамом на вашем ящике, на случай если почтовая служба сочла письмо спамом. Если же письма нигде нет, свяжитесь с администратором сайта</a>.</p>";
8
-
9
- // Confirmation email subject (double opt-in)
10
- $options['confirmation_subject'] =
11
- "{name}, Подвердите вашу подписку на новостную ленту {blog_title}";
12
-
13
- // Confirmation email body (double opt-in)
14
- $options['confirmation_message'] =
15
- "<p>Здравствуйте, {name},</p>
16
- <p>От Вас поступил запрос на получение новостной рассылки. Вы можете подтвердить его, кликнув на эту <a href=\"{subscription_confirm_url}\"><strong>ссылку</strong></a>. Если ссылка по каким-то причинам не нажимается, вставьте вручную в браузер, ссылку:</p>
17
- <p>{subscription_confirm_url}</p>
18
- <p>Если Вы не посылали запрос, или кто-то это сделал за Вас, просто проигнорируйте это письмо.</p>
19
- <p>Спасибо!</p>";
20
-
21
-
22
- // Subscription confirmed text (after a user clicked the confirmation link
23
- // on the email he received
24
- $options['confirmed_text'] =
25
- "<p>Ваша подписка подтверждена! Спасибо, {name}!</p>";
26
-
27
- $options['confirmed_subject'] =
28
- "Добро пожаловать, {name}";
29
-
30
- $options['confirmed_message'] =
31
- "<p>Вы были успешно подписаны на новостную ленту {blog_title}.</p>
32
- <p>Спасибо!</p>";
33
-
34
- // Unsubscription request introductory text
35
- $options['unsubscription_text'] =
36
- "<p>Пожалуйста, подведите свой отказ от подписки, кликнув <a href=\"{unsubscription_confirm_url}\">здесь</a>.</p>";
37
-
38
- // When you finally loosed your subscriber
39
- $options['unsubscribed_text'] =
40
- "<p>Это сделает нам немножечко больно, но мы отписали Вас от получения новостей...</p>";
41
-
42
- $options['unsubscribed_subject'] =
43
- "До свидания, {name}";
44
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/languages/template-en_US.php DELETED
@@ -1,7 +0,0 @@
1
- <?php
2
-
3
- // This file is used only on first installation!
4
-
5
- $options = array();
6
- $options['enabled'] = 0;
7
- $options['template'] = @file_get_contents(dirname(__FILE__) . '/../email.html');
 
 
 
 
 
 
 
subscription/lists.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
@@ -15,10 +15,27 @@ if (!$controls->is_action()) {
15
  $controls->add_message_saved();
16
  }
17
  }
 
 
 
 
 
 
 
 
18
  $status = array(0 => 'Disabled/Private use', 1 => 'Only on profile page', 2 => 'Even on subscription forms', '3' => 'Hidden');
19
  ?>
20
-
21
- <div class="wrap" id="tnp-wrap">
 
 
 
 
 
 
 
 
 
22
 
23
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
24
 
@@ -32,22 +49,42 @@ $status = array(0 => 'Disabled/Private use', 1 => 'Only on profile page', 2 => '
32
 
33
  <form method="post" action="">
34
  <?php $controls->init(); ?>
35
-
 
 
36
  <table class="widefat">
37
  <thead>
38
  <tr>
39
- <th>Field</th>
40
- <th>Name/Label</th>
41
- <th>On subscription</th>
42
- <th>Initially...</th>
 
 
 
43
  </tr>
44
  </thead>
45
  <?php for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) { ?>
46
  <tr>
47
- <td>List <?php echo $i; ?></td>
48
- <td><?php $controls->text('list_' . $i); ?></td>
49
  <td><?php $controls->select('list_' . $i . '_status', $status); ?></td>
50
- <td><?php $controls->select('list_' . $i . '_checked', array(0 => 'Unchecked', 1 => 'Checked')); ?></td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  </tr>
52
  <?php } ?>
53
  </table>
1
  <?php
2
+ defined('ABSPATH') || exit;
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
15
  $controls->add_message_saved();
16
  }
17
  }
18
+
19
+ for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
20
+ if (!isset($controls->data['list_' . $i . '_forced'])) {
21
+ $controls->data['list_' . $i . '_forced'] = empty($module->options['preferences_' . $i]) ? 0 : 1;
22
+ }
23
+ }
24
+
25
+
26
  $status = array(0 => 'Disabled/Private use', 1 => 'Only on profile page', 2 => 'Even on subscription forms', '3' => 'Hidden');
27
  ?>
28
+ <script>
29
+ jQuery(function () {
30
+ jQuery(".tnp-notes").tooltip({
31
+ content: function () {
32
+ // That activates the HTML in the tooltip
33
+ return this.title;
34
+ }
35
+ });
36
+ });
37
+ </script>
38
+ <div class="wrap tnp-lists" id="tnp-wrap">
39
 
40
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
41
 
49
 
50
  <form method="post" action="">
51
  <?php $controls->init(); ?>
52
+ <p>
53
+ <?php $controls->button_save(); ?>
54
+ </p>
55
  <table class="widefat">
56
  <thead>
57
  <tr>
58
+ <th>#</th>
59
+ <th><?php _e('Name', 'newsletter')?></th>
60
+ <th><?php _e('Visibility', 'newsletter')?></th>
61
+ <th><?php _e('Pre-checked', 'newsletter')?></th>
62
+ <th><?php _e('Pre-assigned', 'newsletter')?></th>
63
+ <th><?php _e('Subscribers', 'newsletter')?></th>
64
+ <th><?php _e('Notes', 'newsletter') ?></th>
65
  </tr>
66
  </thead>
67
  <?php for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) { ?>
68
  <tr>
69
+ <td><?php echo $i; ?></td>
70
+ <td><?php $controls->text('list_' . $i, 50); ?></td>
71
  <td><?php $controls->select('list_' . $i . '_status', $status); ?></td>
72
+ <td><?php $controls->select('list_' . $i . '_checked', array(0 => 'No', 1 => 'Yes')); ?></td>
73
+ <td><?php $controls->select('list_' . $i . '_forced', array(0 => 'No', 1 => 'Yes')); ?></td>
74
+ <td><?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where list_" . $i . "=1 and status='C'"); ?></td>
75
+ <td>
76
+ <?php $notes = apply_filters('newsletter_lists_notes', array(), $i); ?>
77
+ <?php
78
+ $text = '';
79
+ foreach ($notes as $note) {
80
+ $text .= $note . '<br>';
81
+ }
82
+ if (!empty($text)) {
83
+ echo '<i class="fa fa-info-circle tnp-notes" title="', esc_attr($text), '"></i>';
84
+ }
85
+ ?>
86
+
87
+ </td>
88
  </tr>
89
  <?php } ?>
90
  </table>
subscription/options.php CHANGED
@@ -1,6 +1,5 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
 
5
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
@@ -14,10 +13,6 @@ if ($controls->is_action()) {
14
 
15
  $defaults = $module->get_default_options();
16
 
17
- if (empty($controls->data['profile_text'])) {
18
- $controls->data['profile_text'] = $defaults['profile_text'];
19
- }
20
-
21
  // Without the last curly bracket since there can be a form number apended
22
  if (empty($controls->data['subscription_text'])) {
23
  $controls->data['subscription_text'] = $defaults['subscription_text'];
@@ -55,31 +50,10 @@ if ($controls->is_action()) {
55
  $controls->data['confirmed_url'] = trim($controls->data['confirmed_url']);
56
  $controls->data['confirmation_url'] = trim($controls->data['confirmation_url']);
57
 
58
- if (!empty($controls->data['page'])) {
59
- $controls->data['url'] = ''; // do not unset
60
- }
61
-
62
  $module->merge_options($controls->data);
63
  $controls->add_message_saved();
64
  }
65
 
66
- if ($controls->is_action('create')) {
67
- $page = array();
68
- $page['post_title'] = 'Newsletter';
69
- $page['post_content'] = '[newsletter]';
70
- $page['post_status'] = 'publish';
71
- $page['post_type'] = 'page';
72
- $page['comment_status'] = 'closed';
73
- $page['ping_status'] = 'closed';
74
- $page['post_category'] = array(1);
75
-
76
- // Insert the post into the database
77
- $page_id = wp_insert_post($page);
78
-
79
- $controls->data['page'] = $page_id;
80
- $module->merge_options($controls->data);
81
- }
82
-
83
  if ($controls->is_action('reset')) {
84
  $controls->data = $module->reset_options();
85
  }
@@ -129,49 +103,15 @@ if ($controls->is_action()) {
129
  $controls->data = get_option('newsletter', array());
130
  }
131
 
132
- if (empty($controls->data['page'])) {
133
- $controls->messages .= '<p>You should set a dedicated page for Newsletter which used to interact with your subscribers.</p>';
134
- } else {
135
- $post = get_post($controls->data['page']);
136
-
137
- if (!$post || $post->post_status != 'publish') {
138
- $controls->errors .= '<p>The dedicated page selected below does not exist anymore or has been unpublished. Please, select a different one.</p>';
139
- } else {
140
- if (strpos($post->post_content, '[newsletter') === false) {
141
- $controls->errors .= '<p>The dedicated page selected DOES NOT contain the [newsletter] shortcode. Please fix it. It should contain ONLY the [newsletter] shortcode.</p>';
142
- }
143
- }
144
- }
145
  ?>
146
 
147
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.css" type="text/css">
148
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/addon/hint/show-hint.css">
149
- <style>
150
- .CodeMirror {
151
- border: 1px solid #ddd;
152
- }
153
- </style>
154
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.js"></script>
155
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/mode/css/css.js"></script>
156
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/addon/hint/show-hint.js"></script>
157
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/addon/hint/css-hint.js"></script>
158
- <script>
159
- jQuery(function () {
160
- var editor = CodeMirror.fromTextArea(document.getElementById("options-css"), {
161
- lineNumbers: true,
162
- mode: 'css',
163
- extraKeys: {"Ctrl-Space": "autocomplete"}
164
- });
165
- });
166
- </script>
167
-
168
  <div class="wrap" id="tnp-wrap">
169
 
170
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
171
 
172
  <div id="tnp-heading">
173
 
174
- <h2><?php _e('Subscription, Profile Page Configuration', 'newsletter') ?></h2>
175
  <?php $controls->page_help('https://www.thenewsletterplugin.com/documentation/subscription') ?>
176
 
177
  </div>
@@ -186,7 +126,6 @@ if (empty($controls->data['page'])) {
186
  <li><a href="#tabs-2"><?php _e('Subscription', 'newsletter') ?></a></li>
187
  <li><a href="#tabs-4"><?php _e('Welcome', 'newsletter') ?></a></li>
188
  <li><a href="#tabs-3"><?php _e('Activation', 'newsletter') ?></a></li>
189
- <li><a href="#tabs-9"><?php _e('Profile', 'newsletter') ?></a></li>
190
  </ul>
191
 
192
  <div id="tabs-general">
@@ -199,39 +138,25 @@ if (empty($controls->data['page'])) {
199
  </td>
200
  </tr>
201
  <tr>
202
- <th><?php _e('Dedicated page', 'newsletter') ?></th>
203
  <td>
204
- <?php $controls->page('page', __('Unstyled page', 'newsletter')); ?>
205
- <?php
206
- if (empty($controls->data['url']) && empty($controls->data['page'])) {
207
- $controls->button('create', __('Create the page', 'newsletter'));
208
- }
209
- ?>
210
- <?php if (!empty($controls->data['url'])) { ?>
211
- <!-- do not translate, will be removed -->
212
- <p class="description">
213
- <strong>
214
- You're currently using the URL <code><?php echo esc_html($controls->data['url']) ?></code>
215
- as dedicated page. Please select the corrisponding page above (new as version 4.6.5+).
216
- </strong>
217
- </p>
218
- <?php } ?>
219
  </td>
220
  </tr>
221
  <tr>
222
- <th><?php _e('Notifications', 'newsletter') ?></th>
223
  <td>
224
- <?php $controls->yesno('notify'); ?>
225
- <?php $controls->text_email('notify_email'); ?>
 
226
  </td>
227
  </tr>
 
228
  <tr>
229
- <th><?php _e('Custom styles', 'newsletter') ?></th>
230
  <td>
231
- <?php if (apply_filters('newsletter_enqueue_style', true) === false) { ?>
232
- <p><strong>Warning: Newsletter styles and custom styles are disable by your theme or a plugin.</strong></p>
233
- <?php } ?>
234
- <?php $controls->textarea('css'); ?>
235
  </td>
236
  </tr>
237
  </table>
@@ -247,31 +172,12 @@ if (empty($controls->data['page'])) {
247
  <?php $controls->wp_editor('subscription_text'); ?>
248
  </td>
249
  </tr>
250
- <tr>
251
- <th><?php _e('Forced lists', 'newsletter') ?></th>
252
- <td>
253
- <?php $controls->preferences(); ?>
254
- </td>
255
- </tr>
256
  </table>
257
 
258
  <h3>Special cases</h3>
259
 
260
  <table class="form-table">
261
- <!--
262
- <tr>
263
- <th>Already subscribed page content</th>
264
- <td>
265
- <?php //$controls->wp_editor('already_confirmed_text'); ?><br>
266
- <?php //$controls->checkbox('resend_welcome_email_disabled', 'Do not resend the welcome email'); ?>
267
- <p class="description">
268
- Shown when the email is already subscribed and confirmed. The welcome email, if not disabled, will
269
- be sent. Find out more on this topic on its
270
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscription-module#repeated" target="_blank">documentation page</a>.
271
- </p>
272
- </td>
273
- </tr>
274
- -->
275
  <tr>
276
  <th><?php _e('Error page', 'newsletter') ?></th>
277
  <td>
@@ -358,44 +264,6 @@ if (empty($controls->data['page'])) {
358
  </table>
359
  </div>
360
 
361
- <!-- PROFILE -->
362
- <div id="tabs-9">
363
-
364
- <table class="form-table">
365
-
366
- <tr>
367
- <th><?php _e('Profile page', 'newsletter') ?>
368
- <br><?php $controls->help('https://www.thenewsletterplugin.com/documentation/subscription#profile') ?>
369
- </th>
370
- <td>
371
- <?php $controls->wp_editor('profile_text'); ?>
372
- </td>
373
- </tr>
374
-
375
- <tr>
376
- <th><?php _e('Alternative profile page URL', 'newsletter') ?></th>
377
- <td>
378
- <?php $controls->text('profile_url', 70); ?>
379
- </td>
380
- </tr>
381
-
382
- <tr>
383
- <th>Other messages</th>
384
- <td>
385
- confirmation after profile save<br>
386
- <?php $controls->text('profile_saved', 80); ?><br><br>
387
- email changed notice<br>
388
- <?php $controls->text('profile_email_changed', 80); ?>
389
- <p class="description">when a subscriber changes his email, he will be unconfirmed and a new confirmation email is sent</p>
390
- <br><br>
391
- generic error<br>
392
- <?php $controls->text('profile_error', 80); ?>
393
- <p class="description">when the email is not valid or already used by another subscriber</p>
394
- </td>
395
- </tr>
396
- </table>
397
- </div>
398
-
399
  </div>
400
 
401
  <p>
1
  <?php
2
+ defined('ABSPATH') || exit;
 
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
13
 
14
  $defaults = $module->get_default_options();
15
 
 
 
 
 
16
  // Without the last curly bracket since there can be a form number apended
17
  if (empty($controls->data['subscription_text'])) {
18
  $controls->data['subscription_text'] = $defaults['subscription_text'];
50
  $controls->data['confirmed_url'] = trim($controls->data['confirmed_url']);
51
  $controls->data['confirmation_url'] = trim($controls->data['confirmation_url']);
52
 
 
 
 
 
53
  $module->merge_options($controls->data);
54
  $controls->add_message_saved();
55
  }
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  if ($controls->is_action('reset')) {
58
  $controls->data = $module->reset_options();
59
  }
103
  $controls->data = get_option('newsletter', array());
104
  }
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  ?>
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  <div class="wrap" id="tnp-wrap">
109
 
110
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
111
 
112
  <div id="tnp-heading">
113
 
114
+ <h2><?php _e('Subscription Configuration', 'newsletter') ?></h2>
115
  <?php $controls->page_help('https://www.thenewsletterplugin.com/documentation/subscription') ?>
116
 
117
  </div>
126
  <li><a href="#tabs-2"><?php _e('Subscription', 'newsletter') ?></a></li>
127
  <li><a href="#tabs-4"><?php _e('Welcome', 'newsletter') ?></a></li>
128
  <li><a href="#tabs-3"><?php _e('Activation', 'newsletter') ?></a></li>
 
129
  </ul>
130
 
131
  <div id="tabs-general">
138
  </td>
139
  </tr>
140
  <tr>
141
+ <th><?php _e('Override Opt In', 'newsletter') ?></th>
142
  <td>
143
+ <?php $controls->yesno('optin_override'); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  </td>
145
  </tr>
146
  <tr>
147
+ <th><?php _e('Repeated subscriptions', 'newsletter') ?></th>
148
  <td>
149
+ <?php //$controls->select('multiple', array('0'=>__('No', 'newsletter'), '1'=>__('Yes', 'newsletter'), '2'=>__('On new lists added', 'newsletter'))); ?>
150
+ <?php $controls->select('multiple', array('0'=>__('No', 'newsletter'), '1'=>__('Yes', 'newsletter'))); ?>
151
+ <?php $controls->help('https://www.thenewsletterplugin.com/documentation/subscription#repeated')?>
152
  </td>
153
  </tr>
154
+
155
  <tr>
156
+ <th><?php _e('Notifications', 'newsletter') ?></th>
157
  <td>
158
+ <?php $controls->yesno('notify'); ?>
159
+ <?php $controls->text_email('notify_email'); ?>
 
 
160
  </td>
161
  </tr>
162
  </table>
172
  <?php $controls->wp_editor('subscription_text'); ?>
173
  </td>
174
  </tr>
175
+
 
 
 
 
 
176
  </table>
177
 
178
  <h3>Special cases</h3>
179
 
180
  <table class="form-table">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  <tr>
182
  <th><?php _e('Error page', 'newsletter') ?></th>
183
  <td>
264
  </table>
265
  </div>
266
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  </div>
268
 
269
  <p>
subscription/page-alternative.php DELETED
@@ -1,54 +0,0 @@
1
- <?php
2
- // This is an alternative subscription message showing page. Variables are already initialized
3
- // on the original page which includes this one.
4
- ?>
5
- <html>
6
- <head>
7
- <style type="text/css">
8
- body {
9
- font-family: verdana;
10
- background-color: #ddd;
11
- font-size: 12px;
12
- }
13
- #container {
14
- border: 1px solid #aaa;
15
- border-radius: 5px;
16
- background-color: #fff;
17
- margin: 40px auto;
18
- width: 600px;
19
- padding: 20px
20
- }
21
- h1 {
22
- font-size: 24px;
23
- font-weight: normal;
24
- border-bottom: 1px solid #aaa;
25
- margin-top: 0;
26
- }
27
- h2 {
28
- font-size: 20px;
29
- }
30
- th, td {
31
- font-size: 12px;
32
- }
33
- th {
34
- padding-right: 10px;
35
- text-align: right;
36
- vertical-align: middle;
37
- font-weight: normal;
38
- }
39
- </style>
40
- </head>
41
-
42
- <body>
43
- <?php if (!empty($alert)) { ?>
44
- <script>
45
- alert("<?php echo addslashes($alert); ?>");
46
- </script>
47
- <?php } ?>
48
-
49
- <div id="container">
50
- <h1><?php echo get_option('blogname'); ?></h1>
51
- <?php echo $message; ?>
52
- </div>
53
- </body>
54
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
subscription/profile.php CHANGED
@@ -14,16 +14,13 @@ if (!$controls->is_action()) {
14
  }
15
 
16
  if ($controls->is_action('reset')) {
17
- // TODO: Move this inside the module
18
- @include NEWSLETTER_DIR . '/subscription/languages/profile-en_US.php';
19
- @include NEWSLETTER_DIR . '/subscription/languages/profile-' . WPLANG . '.php';
20
- update_option('newsletter_profile', array_merge(get_option('newsletter_profile', array()), $options));
21
- $controls->data = $module->get_options('profile');
22
  }
23
  }
24
 
25
- $status = array(0 => 'Disabled/Private use', 1 => 'Only on profile page', 2 => 'Even on subscription forms');
26
- $rules = array(0 => 'Optional', 1 => 'Required');
27
  ?>
28
 
29
  <div class="wrap" id="tnp-wrap">
@@ -71,7 +68,7 @@ $rules = array(0 => 'Optional', 1 => 'Required');
71
  </td>
72
  </tr>
73
  <tr>
74
- <th>Name or first name</th>
75
  <td>
76
  <table class="newsletter-option-grid">
77
  <tr><th>Field label</th><td><?php $controls->text('name', 50); ?></td></tr>
@@ -86,7 +83,7 @@ $rules = array(0 => 'Optional', 1 => 'Required');
86
  </td>
87
  </tr>
88
  <tr>
89
- <th>Last name</th>
90
  <td>
91
  <table class="newsletter-option-grid">
92
  <tr><th>Field label</th><td><?php $controls->text('surname', 50); ?></td></tr>
@@ -97,7 +94,7 @@ $rules = array(0 => 'Optional', 1 => 'Required');
97
  </td>
98
  </tr>
99
  <tr>
100
- <th>Sex/Gender</th>
101
  <td>
102
  <table class="newsletter-option-grid">
103
  <tr><th>Field label</th><td><?php $controls->text('sex', 50); ?></td></tr>
@@ -124,16 +121,12 @@ $rules = array(0 => 'Optional', 1 => 'Required');
124
  </tr>
125
 
126
  <tr>
127
- <th>Button labels</th>
128
  <td>
129
- <table class="newsletter-option-grid">
130
- <tr><th>Subscribe button</th><td><?php $controls->text('subscribe'); ?></td></tr>
131
- <tr><th>Save button</th><td><?php $controls->text('save'); ?> (on profile page)</td></tr>
132
- <tr><th>Export button/link</th><td><?php $controls->text('profile_export'); ?></td></tr>
133
- <tr><th>Profile editing link</th><td><?php $controls->text('profile_edit'); ?></td></tr>
134
- </table>
135
  <p class="description">
136
- For "subscribe" insert an URL to an image (http://...) to use it as a graphical button.
137
  </p>
138
  </td>
139
  </tr>
@@ -149,7 +142,7 @@ $rules = array(0 => 'Optional', 1 => 'Required');
149
  </table>
150
  <p class="description">
151
  The privacy acceptance checkbox (required in many Europen countries) force the subscriber to
152
- check it to procees. If an URL is specified the label is linket to that page.
153
  </p>
154
  </td>
155
  </tr>
@@ -205,7 +198,7 @@ $rules = array(0 => 'Optional', 1 => 'Required');
205
  <p>This panel shows the form HTML code generated by Newsletter if you want to copy it as starting point for a custom form.</p>
206
 
207
  <h3>Standard form code</h3>
208
- <textarea readonly style="width: 100%; height: 500px; font-family: monospace"><?php echo esc_html(NewsletterSubscription::instance()->get_subscription_form_html5()); ?></textarea>
209
 
210
  <h3>Widget form code</h3>
211
  <textarea readonly style="width: 100%; height: 500px; font-family: monospace"><?php echo htmlspecialchars(NewsletterSubscription::instance()->get_subscription_form()); ?></textarea>
@@ -216,7 +209,7 @@ $rules = array(0 => 'Optional', 1 => 'Required');
216
 
217
  <p>
218
  <?php $controls->button_save(); ?>
219
- <?php $controls->button_confirm('reset', 'Reset all', 'Are you sure you want to reset all?'); ?>
220
  </p>
221
 
222
  </form>
14
  }
15
 
16
  if ($controls->is_action('reset')) {
17
+ $controls->data = $module->reset_options('profile');
18
+ $controls->add_message_done();
 
 
 
19
  }
20
  }
21
 
22
+ $status = array(0 => __('Private', 'newsletter'), 1 => __('Show on profile page', 'newsletter'), 2 => __('Show on subscription form', 'newsletter'));
23
+ $rules = array(0 => __('Optional', 'newsletter'), 1 => __('Required', 'newsletter'));
24
  ?>
25
 
26
  <div class="wrap" id="tnp-wrap">
68
  </td>
69
  </tr>
70
  <tr>
71
+ <th><?php _e('First name', 'newsletter')?></th>
72
  <td>
73
  <table class="newsletter-option-grid">
74
  <tr><th>Field label</th><td><?php $controls->text('name', 50); ?></td></tr>
83
  </td>
84
  </tr>
85
  <tr>
86
+ <th><?php _e('Last name', 'newsletter')?></th>
87
  <td>
88
  <table class="newsletter-option-grid">
89
  <tr><th>Field label</th><td><?php $controls->text('surname', 50); ?></td></tr>
94
  </td>
95
  </tr>
96
  <tr>
97
+ <th><?php _e('Gender', 'newsletter')?></th>
98
  <td>
99
  <table class="newsletter-option-grid">
100
  <tr><th>Field label</th><td><?php $controls->text('sex', 50); ?></td></tr>
121
  </tr>
122
 
123
  <tr>
124
+ <th><?php _e('"Subscribe" label', 'newsletter')?></th>
125
  <td>
126
+ <?php $controls->text('subscribe', 40); ?>
127
+
 
 
 
 
128
  <p class="description">
129
+ You can use an image URL (http://...).
130
  </p>
131
  </td>
132
  </tr>
142
  </table>
143
  <p class="description">
144
  The privacy acceptance checkbox (required in many Europen countries) force the subscriber to
145
+ check it before proceeding. If an URL is specified the label become a link.
146
  </p>
147
  </td>
148
  </tr>
198
  <p>This panel shows the form HTML code generated by Newsletter if you want to copy it as starting point for a custom form.</p>
199
 
200
  <h3>Standard form code</h3>
201
+ <textarea readonly style="width: 100%; height: 500px; font-family: monospace"><?php echo esc_html(NewsletterSubscription::instance()->get_subscription_form()); ?></textarea>
202
 
203
  <h3>Widget form code</h3>
204
  <textarea readonly style="width: 100%; height: 500px; font-family: monospace"><?php echo htmlspecialchars(NewsletterSubscription::instance()->get_subscription_form()); ?></textarea>
209
 
210
  <p>
211
  <?php $controls->button_save(); ?>
212
+ <?php $controls->button_reset(); ?>
213
  </p>
214
 
215
  </form>
subscription/subscription.php CHANGED
@@ -8,8 +8,12 @@ require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
8
  class NewsletterSubscription extends NewsletterModule {
9
 
10
  const MESSAGE_CONFIRMED = 'confirmed';
 
 
11
 
12
  static $instance;
 
 
13
 
14
  /**
15
  * @return NewsletterSubscription
@@ -23,7 +27,9 @@ class NewsletterSubscription extends NewsletterModule {
23
 
24
  function __construct() {
25
 
26
- parent::__construct('subscription', '2.0.5');
 
 
27
 
28
  // Must be called after the Newsletter::hook_init, since some constants are defined
29
  // there.
@@ -38,7 +44,6 @@ class NewsletterSubscription extends NewsletterModule {
38
  add_action('wp_enqueue_scripts', array($this, 'hook_wp_enqueue_scripts'));
39
  add_shortcode('newsletter', array($this, 'shortcode_newsletter'));
40
  add_shortcode('newsletter_form', array($this, 'shortcode_newsletter_form'));
41
- //add_shortcode('newsletter_profile', array($this, 'shortcode_newsletter_profile'));
42
  add_shortcode('newsletter_field', array($this, 'shortcode_newsletter_field'));
43
  }
44
  }
@@ -58,23 +63,23 @@ class NewsletterSubscription extends NewsletterModule {
58
  }
59
 
60
  wp_enqueue_script('newsletter-subscription', plugins_url('newsletter') . '/subscription/validate.js', array(), NEWSLETTER_VERSION, true);
61
- $options = $this->get_options('profile');
62
  $data = array();
63
  $data['messages'] = array();
64
  if (isset($options['email_error'])) {
65
- $data['messages']['email_error'] = $options['email_error'];
66
  }
67
  if (isset($options['name_error'])) {
68
- $data['messages']['name_error'] = $options['name_error'];
69
  }
70
  if (isset($options['surname_error'])) {
71
- $data['messages']['surname_error'] = $options['surname_error'];
72
  }
73
  if (isset($options['profile_error'])) {
74
- $data['messages']['profile_error'] = $options['profile_error'];
75
  }
76
  if (isset($options['privacy_error'])) {
77
- $data['messages']['privacy_error'] = $options['privacy_error'];
78
  }
79
  $data['profile_max'] = NEWSLETTER_PROFILE_MAX;
80
  wp_localize_script('newsletter-subscription', 'newsletter', $data);
@@ -93,8 +98,112 @@ class NewsletterSubscription extends NewsletterModule {
93
  }
94
  }
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  function hook_wp_loaded() {
97
- global $newsletter, $wpdb;
 
 
98
 
99
  switch ($newsletter->action) {
100
  case 'profile-change':
@@ -114,15 +223,18 @@ class NewsletterSubscription extends NewsletterModule {
114
 
115
  // Check if the list is public
116
  $list = $this->get_list($list_id);
117
- if (!$list || $list['status'] == 0) {
118
  die('Private list.');
119
  }
120
 
121
  $url = $_REQUEST['redirect'];
122
 
123
  $this->set_user_list($user, $list_id, $_REQUEST['value']);
124
- NewsletterStatistics::instance()->add_click(wp_sanitize_redirect($url), $user->id, $email->id);
125
- wp_safe_redirect($url);
 
 
 
126
  die();
127
  }
128
  } else {
@@ -132,6 +244,7 @@ class NewsletterSubscription extends NewsletterModule {
132
  die();
133
 
134
  case 'm':
 
135
  include dirname(__FILE__) . '/page.php';
136
  die();
137
 
@@ -142,13 +255,15 @@ class NewsletterSubscription extends NewsletterModule {
142
  $ip = $this->get_remote_ip();
143
  $email = $this->normalize_email($_REQUEST['ne']);
144
  $first_name = '';
145
- if (isset($_REQUEST['nn'])) $first_name = $this->normalize_name($_REQUEST['nn']);
146
-
 
147
  $last_name = '';
148
- if (isset($_REQUEST['ns'])) $last_name = $this->normalize_name($_REQUEST['ns']);
149
-
 
150
  $full_name = trim($first_name . ' ' . $last_name);
151
-
152
  $antibot_logger = new NewsletterLogger('antibot');
153
 
154
  if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
@@ -161,84 +276,49 @@ class NewsletterSubscription extends NewsletterModule {
161
  if (!empty($this->options['antibot_disable']) || $this->antibot_form_check($captcha)) {
162
 
163
 
164
- if (stripos($full_name, 'http://') !== false || stripos($full_name, 'https://') !== false) {
165
  $antibot_logger->fatal($email . ' - ' . $ip . ' - Name with http: ' . $full_name);
166
  header("HTTP/1.0 404 Not Found");
167
  die();
168
  }
169
 
170
-
171
-
172
  // Cannot check for administrator here, too early.
173
  if (true) {
174
 
175
  $this->logger->debug('Subscription of: ' . $email);
176
- // if ($this->options['domain_check']) {
177
- // $this->logger->debug('Domain checking');
178
- // list($local, $domain) = explode('@', $email);
179
- //
180
- // $hosts = array();
181
- // if (!getmxrr($domain, $hosts)) {
182
- // $antibot_logger->fatal($email . ' - ' . $ip . ' - MX check failed');
183
- // die('Blocked 0');
184
- // }
185
- // }
186
-
187
- if (!empty($this->options['ip_blacklist'])) {
188
- $this->logger->debug('IP blacklist check');
189
- foreach ($this->options['ip_blacklist'] as $item) {
190
- if ($this->ip_match($ip, $item)) {
191
- $antibot_logger->fatal($email . ' - ' . $ip . ' - IP blacklisted');
192
- header("HTTP/1.0 404 Not Found");
193
- die();
194
- }
195
- }
196
  }
197
 
198
- if (!empty($this->options['address_blacklist'])) {
199
- $this->logger->debug('Address blacklist check');
200
- $rev_email = strrev($email);
201
- foreach ($this->options['address_blacklist'] as $item) {
202
- if (strpos($rev_email, strrev($item)) === 0) {
203
- $antibot_logger->fatal($email . ' - ' . $ip . ' - Address blacklisted');
204
- header("HTTP/1.0 404 Not Found");
205
- die();
206
- }
207
- }
208
  }
209
 
210
  // Akismet check
211
- if (!empty($this->options['akismet']) && class_exists('Akismet')) {
212
- $this->logger->debug('Akismet check');
213
- $request = 'blog=' . urlencode(home_url()) . '&referrer=' . urlencode($_SERVER['HTTP_REFERER']) .
214
- '&user_agent=' . urlencode($_SERVER['HTTP_USER_AGENT']) .
215
- '&comment_type=signup' .
216
- '&comment_author_email=' . urlencode($email) .
217
- '&user_ip=' . urlencode($_SERVER['REMOTE_ADDR']);
218
- if (!empty($full_name)) {
219
- $request .= '&comment_author=' . urlencode($full_name);
220
- }
221
-
222
- $response = Akismet::http_post($request, 'comment-check');
223
-
224
- if ($response && $response[1] == 'true') {
225
- $antibot_logger->fatal($email . ' - ' . $ip . ' - Akismet blocked');
226
- header("HTTP/1.0 404 Not Found");
227
- die();
228
- }
229
  }
230
 
231
  // Flood check
232
- if (!empty($this->options['antiflood'])) {
233
- $this->logger->debug('Antiflood check');
234
- $email = $this->is_email($_REQUEST['ne']);
235
- $updated = $wpdb->get_var($wpdb->prepare("select updated from " . NEWSLETTER_USERS_TABLE . " where ip=%s or email=%s order by updated desc limit 1", $ip, $email));
236
-
237
- if ($updated && time() - $updated < $this->options['antiflood']) {
238
- $antibot_logger->fatal($email . ' - ' . $ip . ' - Antiflood triggered');
239
- header("HTTP/1.0 404 Not Found");
240
- die('Too quick');
241
- }
242
  }
243
 
244
  $user = $this->subscribe();
@@ -304,23 +384,16 @@ class NewsletterSubscription extends NewsletterModule {
304
  }
305
  die();
306
  break;
307
- case 'profile':
308
- case 'p':
309
- case 'pe':
310
- $user = $this->check_user();
311
- if ($user == null) {
312
- die('No subscriber found.');
313
- }
314
 
315
- $this->show_message('profile', $user);
 
 
 
 
 
 
316
  die();
317
- break;
318
 
319
- case 'ps':
320
- $user = $this->save_profile();
321
- // $user->alert is a temporary field
322
- $this->show_message('profile', $user, $user->alert);
323
- die();
324
  break;
325
 
326
  case 'c':
@@ -345,37 +418,38 @@ class NewsletterSubscription extends NewsletterModule {
345
  }
346
 
347
  function upgrade() {
348
- global $wpdb, $charset_collate, $newsletter;
349
 
350
  parent::upgrade();
351
 
352
- $this->init_options('profile');
353
- $this->init_options('lists');
354
-
355
- $default_options = $this->get_default_options();
356
 
357
- if (empty($this->options['error_text'])) {
358
- $this->options['error_text'] = $default_options['error_text'];
359
- $this->save_options($this->options);
 
 
 
360
  }
361
 
362
- // Old migration code
363
- if (isset($options_profile['profile_text'])) {
364
- $this->options['profile_text'] = $options_profile['profile_text'];
365
- if (empty($this->options['profile_text'])) {
366
- $this->options['profile_text'] = '{profile_form}<p><a href="{unsubscription_url}">I want to unsubscribe.</a>';
367
  }
368
-
369
- $this->save_options($this->options);
370
- unset($options_profile['profile_text']);
371
- update_option('newsletter_profile', $options_profile);
372
  }
373
 
374
- if (isset($options_profile['profile_saved'])) {
375
- $this->options['profile_saved'] = $options_profile['profile_saved'];
 
 
 
 
 
 
376
  $this->save_options($this->options);
377
- unset($options_profile['profile_saved']);
378
- update_option('newsletter_profile', $options_profile);
379
  }
380
 
381
  if ($this->old_version < '2.0.0') {
@@ -399,7 +473,7 @@ class NewsletterSubscription extends NewsletterModule {
399
  }
400
 
401
  $this->init_options('template', false);
402
-
403
  global $wpdb, $charset_collate;
404
 
405
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
@@ -407,12 +481,13 @@ class NewsletterSubscription extends NewsletterModule {
407
 
408
 
409
  $sql = "CREATE TABLE `" . $wpdb->prefix . "newsletter_user_logs` (
410
- `id` int(11) NOT NULL AUTO_INCREMENT,
411
- `user_id` int(11) NOT NULL DEFAULT 0,
412
- `data` longtext,
413
- `created` int(11) NOT NULL DEFAULT 0,
414
- PRIMARY KEY (`id`)
415
- ) $charset_collate;";
 
416
 
417
  dbDelta($sql);
418
 
@@ -429,6 +504,7 @@ class NewsletterSubscription extends NewsletterModule {
429
  $this->add_admin_page('profile', 'Subscription Form');
430
  $this->add_admin_page('forms', 'Forms');
431
  $this->add_admin_page('lists', 'Lists');
 
432
  $this->add_admin_page('template', 'Template');
433
  $this->add_admin_page('unsubscription', 'Unsubscription');
434
  }
@@ -444,15 +520,27 @@ class NewsletterSubscription extends NewsletterModule {
444
  * @param array $options
445
  * @param string $sub
446
  */
447
- function save_options($options, $sub = '') {
448
  if ($sub == '') {
449
  // For compatibility the options are wrongly named
450
- return update_option('newsletter', $options);
451
  }
 
452
  if ($sub == 'profile') {
453
- return update_option('newsletter_profile', $options);
 
 
 
 
 
 
 
454
  }
455
- return parent::save_options($options, $sub);
 
 
 
 
456
  }
457
 
458
  function get_options($sub = '') {
@@ -467,6 +555,10 @@ class NewsletterSubscription extends NewsletterModule {
467
  // For compatibility the options are wrongly named
468
  return get_option('newsletter_profile', array());
469
  }
 
 
 
 
470
  return parent::get_options($sub);
471
  }
472
 
@@ -476,7 +568,7 @@ class NewsletterSubscription extends NewsletterModule {
476
  $time = time();
477
 
478
  if (!$ip)
479
- $ip = $_SERVER['REMOTE_ADDR'];
480
 
481
  if (is_object($user))
482
  $id = $user->id;
@@ -500,19 +592,27 @@ class NewsletterSubscription extends NewsletterModule {
500
  // Messages
501
  $options = get_option('newsletter', array());
502
 
503
- // Form field configuration
504
- $options_profile = get_option('newsletter_profile', array());
505
-
506
  $opt_in = (int) $this->options['noconfirmation']; // 0 - double, 1 - single
507
- if (isset($_REQUEST['optin'])) {
508
  switch ($_REQUEST['optin']) {
509
- case 'single': $opt_in = 1;
510
  break;
511
- case 'double': $opt_in = 0;
512
  break;
513
  }
514
  }
515
 
 
 
 
 
 
 
 
 
 
 
 
516
  $email = $newsletter->normalize_email(stripslashes($_REQUEST['ne']));
517
 
518
  // Shound never reach this point without a valid email address
@@ -520,48 +620,66 @@ class NewsletterSubscription extends NewsletterModule {
520
  die('Wrong email');
521
  }
522
 
523
- $user = $newsletter->get_user($email);
524
 
525
  if ($user != null) {
 
526
  $this->logger->info('Subscription of an address with status ' . $user->status);
527
 
528
  // Bounced
 
529
  if ($user->status == 'B') {
530
  // Non persistent status to decide which message to show (error)
531
  $user->status = 'E';
532
  return $user;
533
  }
534
 
535
- // If asked to put in confirmed status, do not check further
536
- if ($status != 'C' && $opt_in == 0) {
537
 
538
- // Already confirmed
539
- //if ($opt_in == 0 && $user->status == 'C') {
540
- if ($user->status == 'C') {
 
541
 
542
- set_transient($user->id . '-' . $user->token, $_REQUEST, 3600 * 48);
543
- $this->set_updated($user);
 
 
 
 
 
 
 
 
 
 
 
 
544
 
545
- // A second subscription always require confirmation otherwise anywan can change other users' data
546
- $user->status = 'S';
 
 
 
547
 
548
- $prefix = 'confirmation_';
 
 
549
 
550
- if (empty($options[$prefix . 'disabled'])) {
551
- $message = $options[$prefix . 'message'];
552
 
553
- // TODO: This is always empty!
554
- //$message_text = $options[$prefix . 'message_text'];
555
- $subject = $options[$prefix . 'subject'];
556
- $message = $this->add_microdata($message);
557
- $this->mail($user->email, $newsletter->replace($subject, $user), $newsletter->replace($message, $user));
558
- }
559
 
560
- return $user;
561
- }
 
562
  }
563
  }
564
 
 
 
565
  if ($user != null) {
566
  $this->logger->info("Email address subscribed but not confirmed");
567
  $user = array('id' => $user->id);
@@ -572,13 +690,10 @@ class NewsletterSubscription extends NewsletterModule {
572
 
573
  $user = $this->update_user_from_request($user);
574
 
575
- $user['token'] = $newsletter->get_token();
576
- $user['ip'] = $_SERVER['REMOTE_ADDR'];
577
- if ($status != null) {
578
- $user['status'] = $status;
579
- } else {
580
- $user['status'] = $opt_in == 1 ? 'C' : 'S';
581
- }
582
 
583
  $user['updated'] = time();
584
 
@@ -593,32 +708,19 @@ class NewsletterSubscription extends NewsletterModule {
593
 
594
  $user = $this->save_user($user);
595
 
 
 
596
  // Notification to admin (only for new confirmed subscriptions)
597
- if ($user->status == 'C') {
598
  do_action('newsletter_user_confirmed', $user);
599
  $this->notify_admin($user, 'Newsletter subscription');
600
  setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
601
  }
602
 
603
- if (!$emails) {
604
- return $user;
605
  }
606
 
607
- $prefix = ($user->status == 'C') ? 'confirmed_' : 'confirmation_';
608
-
609
- if (empty($options[$prefix . 'disabled'])) {
610
- $message = $options[$prefix . 'message'];
611
-
612
- if ($user->status == 'S') {
613
- $message = $this->add_microdata($message);
614
- }
615
-
616
- // TODO: This is always empty!
617
- //$message_text = $options[$prefix . 'message_text'];
618
- $subject = $options[$prefix . 'subject'];
619
-
620
- $this->mail($user->email, $newsletter->replace($subject, $user), $newsletter->replace($message, $user));
621
- }
622
  return $user;
623
  }
624
 
@@ -663,35 +765,33 @@ class NewsletterSubscription extends NewsletterModule {
663
  // New profiles
664
  for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
665
  // If the profile cannot be set by subscriber, skip it.
666
- if ($options_profile['profile_' . $i . '_status'] == 0) {
667
  continue;
668
  }
669
-
670
- $user['profile_' . $i] = trim(stripslashes($_REQUEST['np' . $i]));
 
671
  }
672
 
 
 
673
  // Preferences (field names are nl[] and values the list number so special forms with radio button can work)
674
  if (isset($_REQUEST['nl']) && is_array($_REQUEST['nl'])) {
675
  $this->logger->debug($_REQUEST['nl']);
676
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
677
- // If not zero it is selectable by user (on subscription or on profile)
678
- if ($options_profile['list_' . $i . '_status'] == 0) {
679
- continue;
680
- }
681
- if (in_array($i, $_REQUEST['nl'])) {
682
- $user['list_' . $i] = 1;
683
  }
684
  }
685
  } else {
686
  $this->logger->debug('No preferences received');
687
  }
688
 
689
- // Forced preferences as set on subscription configuration
690
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
691
- if (empty($options['preferences_' . $i])) {
692
- continue;
693
  }
694
- $user['list_' . $i] = 1;
695
  }
696
 
697
  // TODO: should be removed!!!
@@ -711,29 +811,34 @@ class NewsletterSubscription extends NewsletterModule {
711
  */
712
  function mail($to, $subject, $message) {
713
  $options_template = $this->get_options('template');
714
- // If the template setup on administrative panel is enabled, use it, if not
715
- // use the default old templating system.
716
- if (!empty($options_template['enabled'])) {
717
- $template = trim($options_template['template']);
718
- if (empty($template) || strpos($template, '{message}') === false) {
719
- $template = '{message}';
720
- }
721
- $message = str_replace('{message}', $message, $template);
722
- } else {
723
- ob_start();
724
- include NEWSLETTER_DIR . '/subscription/email.php';
725
- $message = ob_get_clean();
726
  }
 
 
727
 
728
  $headers = array('Auto-Submitted' => 'auto-generated');
729
 
730
- $message = Newsletter::instance()->replace($message);
731
  return Newsletter::instance()->mail($to, $subject, $message, $headers);
732
  }
733
 
 
 
 
 
 
 
 
 
 
 
 
 
734
  /**
735
  *
736
- * @global Newsletter $newsletter
737
  * @param type $user
738
  * @return stdClass
739
  */
@@ -742,15 +847,16 @@ class NewsletterSubscription extends NewsletterModule {
742
  if ($user_id == null) {
743
  $user = $this->get_user_from_request();
744
  if ($user) {
745
- $data = get_transient($user->id . '-' . $user->token);
 
746
  if ($data !== false) {
747
  $_REQUEST = $data;
748
  // Update the user profile since it's now confirmed
749
  $user = $this->update_user_from_request((array) $user);
750
  $user = $this->save_user($user);
751
- delete_transient($user->id . '-' . $user->token);
752
  // Forced a fake status so the welcome email is sent
753
- $user->status = 'S';
754
  }
755
  }
756
  } else {
@@ -762,9 +868,12 @@ class NewsletterSubscription extends NewsletterModule {
762
  die('No subscriber found.');
763
  }
764
 
 
 
765
  setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
766
 
767
- if ($user->status == 'C') {
 
768
  do_action('newsletter_user_confirmed', $user);
769
  return $user;
770
  }
@@ -775,28 +884,40 @@ class NewsletterSubscription extends NewsletterModule {
775
  // return $user;
776
  // }
777
 
778
- $this->set_user_status($user->id, 'C');
779
- $user->status = 'C';
 
 
 
 
780
  do_action('newsletter_user_confirmed', $user);
781
  $this->notify_admin($user, 'Newsletter subscription');
782
 
783
- if (!$emails) {
784
- return $user;
785
  }
786
 
787
- $this->send_message('confirmed', $user);
788
-
789
  return $user;
790
  }
791
 
792
- function send_message($type, $user) {
793
- if (empty($this->options[$type . '_disabled'])) {
794
- $message = $this->options[$type . '_message'];
795
- //$message_text = $this->options[$type . '_message_text'];
796
- $subject = $this->options[$type . '_subject'];
 
 
 
 
 
797
 
798
- $this->mail($user->email, $this->replace($subject, $user), $this->replace($message, $user));
 
 
799
  }
 
 
 
800
  }
801
 
802
  /**
@@ -813,19 +934,25 @@ class NewsletterSubscription extends NewsletterModule {
813
  return $user;
814
  }
815
 
816
- $newsletter->set_user_status($user->id, 'U');
 
 
 
 
817
  do_action('newsletter_unsubscribed', $user);
818
 
819
  global $wpdb;
820
- if (isset($_REQUEST['nek'])) {
821
- list($email_id, $email_token) = explode('-', $_REQUEST['nek']);
 
822
  $wpdb->update(NEWSLETTER_USERS_TABLE, array('unsub_email_id' => (int) $email_id, 'unsub_time' => time()), array('id' => $user->id));
823
  }
824
 
825
- if (empty($this->options['unsubscribed_disabled'])) {
826
- $this->mail($user->email, $newsletter->replace($this->options['unsubscribed_subject'], $user), $newsletter->replace($this->options['unsubscribed_message'], $user));
827
- }
828
  $this->notify_admin($user, 'Newsletter unsubscription');
 
 
829
  }
830
 
831
  /**
@@ -834,103 +961,21 @@ class NewsletterSubscription extends NewsletterModule {
834
  * @return type
835
  */
836
  function save_profile() {
837
- global $wpdb;
838
- // Get the current subscriber
839
- $user = $this->get_user_from_request(true);
840
-
841
- $options_profile = get_option('newsletter_profile', array());
842
- $options_main = get_option('newsletter_main', array());
843
-
844
- if (!$this->is_email($_REQUEST['ne'])) {
845
- $user->alert = $this->options['profile_error'];
846
- return $user;
847
- }
848
-
849
- $email = $this->normalize_email(stripslashes($_REQUEST['ne']));
850
- $email_changed = ($email != $user->email);
851
-
852
- // If the email has been changed, check if it is available
853
- if ($email_changed) {
854
- $tmp = $this->get_user($email);
855
- if ($tmp != null && $tmp->id != $user->id) {
856
- $user->alert = $this->options['profile_error'];
857
- return $user;
858
- }
859
- }
860
-
861
- // General data
862
- $data['email'] = $email;
863
- $data['name'] = $this->normalize_name(stripslashes($_REQUEST['nn']));
864
- $data['surname'] = $this->normalize_name(stripslashes($_REQUEST['ns']));
865
- if ($options_profile['sex_status'] >= 1) {
866
- $data['sex'] = $_REQUEST['nx'][0];
867
- // Wrong data injection check
868
- if ($data['sex'] != 'm' && $data['sex'] != 'f' && $data['sex'] != 'n') {
869
- die('Wrong sex field');
870
- }
871
- }
872
-
873
- // Lists. If not list is present or there is no list to choose or all are unchecked.
874
- $nl = $_REQUEST['nl'];
875
- if (!is_array($nl)) {
876
- $nl = array();
877
- }
878
-
879
- // For each preference which an be edited (and so is present on profile form)...
880
- $lists_changed = false;
881
- $changed = array('old'=>array(), 'new'=>array());
882
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
883
- if ($options_profile['list_' . $i . '_status'] == 0) {
884
- continue;
885
- }
886
- $field_name = 'list_' . $i;
887
- $data[$field_name] = in_array($i, $nl) ? 1 : 0;
888
- if ($data[$field_name] != $user->$field_name) {
889
- $lists_changed = true;
890
- $changed['old'][$field_name] = $user->$field_name;
891
- $changed['new'][$field_name] = $data[$field_name];
892
- }
893
- }
894
-
895
- // Profile
896
- for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
897
- if ($options_profile['profile_' . $i . '_status'] == 0) {
898
- continue;
899
- }
900
- $data['profile_' . $i] = stripslashes($_REQUEST['np' . $i]);
901
- }
902
-
903
- $data['id'] = $user->id;
904
-
905
- // Feed by Mail service is saved here
906
- $data = apply_filters('newsletter_profile_save', $data);
907
-
908
- // Log the previous user data as a for of consensus if he changed the lists
909
- if ($lists_changed) {
910
- $this->store->save($wpdb->prefix . 'newsletter_user_logs', array('user_id'=>$user->id, 'created'=>time(), 'data'=> json_encode($changed)));
911
- }
912
-
913
- $user = $this->save_user($data);
914
 
915
- // Email has been changed? Are we using double opt-in?
916
- $opt_in = (int) $this->options['noconfirmation'];
917
- //die($opt_in);
918
- if ($opt_in == 0 && $email_changed) {
919
- $data['status'] = 'S';
920
- if (empty($this->options['confirmation_disabled'])) {
921
- $message = $this->options['confirmation_message'];
922
- $subject = $this->options['confirmation_subject'];
923
- $res = $this->mail($user->email, $this->replace($subject, $user), $this->replace($message, $user));
924
- $alert = $this->options['profile_email_changed'];
925
- }
926
- }
927
 
928
- if (isset($alert)) {
929
- $user->alert = $alert;
930
- } else {
931
- $user->alert = $this->options['profile_saved'];
932
- }
933
- return $user;
 
 
934
  }
935
 
936
  /**
@@ -963,43 +1008,24 @@ global $wpdb;
963
  $params .= '&nek=' . $email->id . '-' . $email->token;
964
  }
965
 
966
- // Add exceptions for "profile" key.
967
- // Is there a custom url?
968
- if (!empty($this->options[$key . '_url'])) {
969
- header('Location: ' . self::add_qs($this->options[$key . '_url'], 'nk=' . $user->id . '-' . $user->token, false) . $params);
970
- die();
971
- }
972
-
973
- if (!empty($this->options['page'])) {
974
- $url = get_permalink($this->options['page']);
975
- }
976
-
977
- // Old URL
978
- if (empty($url) && !empty($this->options['url'])) {
979
- $url = $this->options['url'];
980
- }
981
 
982
  if (empty($url)) {
983
- $url = home_url('/') . '?na=m';
 
 
 
 
 
 
 
 
984
  }
985
 
986
- header('Location: ' . self::add_qs($url, 'nm=' . $key . '&nk=' . $user->id . '-' . $user->token, false) . $params);
987
  die();
988
  }
989
 
990
- function get_email_from_request() {
991
- $newsletter = Newsletter::instance();
992
-
993
- if (isset($_REQUEST['nek'])) {
994
- list($id, $token) = @explode('-', $_REQUEST['nek'], 2);
995
- } else {
996
- return null;
997
- }
998
- $email = $newsletter->get_email($id);
999
-
1000
- return $email;
1001
- }
1002
-
1003
  function get_message_key_from_request() {
1004
  if (empty($_GET['nm'])) {
1005
  return 'subscription';
@@ -1017,10 +1043,18 @@ global $wpdb;
1017
  }
1018
  }
1019
 
 
 
 
 
 
 
 
 
 
 
1020
  function get_form_javascript() {
1021
- $options_profile = get_option('newsletter_profile');
1022
- if (!isset($options_profile['profile_error']))
1023
- $options_profile['profile_error'] = '';
1024
  $buffer = "\n\n";
1025
  $buffer .= '<script type="text/javascript">' . "\n";
1026
  $buffer .= '//<![CDATA[' . "\n";
@@ -1028,30 +1062,30 @@ global $wpdb;
1028
  $buffer .= 'window.newsletter_check = function (f) {' . "\n";
1029
  $buffer .= ' var re = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-]{1,})+\.)+([a-zA-Z0-9]{2,})+$/;' . "\n";
1030
  $buffer .= ' if (!re.test(f.elements["ne"].value)) {' . "\n";
1031
- $buffer .= ' alert("' . addslashes($options_profile['email_error']) . '");' . "\n";
1032
  $buffer .= ' return false;' . "\n";
1033
  $buffer .= ' }' . "\n";
1034
- if ($options_profile['name_status'] == 2 && $options_profile['name_rules'] == 1) {
1035
  $buffer .= ' if (f.elements["nn"] && (f.elements["nn"].value == "" || f.elements["nn"].value == f.elements["nn"].defaultValue)) {' . "\n";
1036
- $buffer .= ' alert("' . addslashes($options_profile['name_error']) . '");' . "\n";
1037
  $buffer .= ' return false;' . "\n";
1038
  $buffer .= ' }' . "\n";
1039
  }
1040
- if ($options_profile['surname_status'] == 2 && $options_profile['surname_rules'] == 1) {
1041
  $buffer .= ' if (f.elements["ns"] && (f.elements["ns"].value == "" || f.elements["ns"].value == f.elements["ns"].defaultValue)) {' . "\n";
1042
- $buffer .= ' alert("' . addslashes($options_profile['surname_error']) . '");' . "\n";
1043
  $buffer .= ' return false;' . "\n";
1044
  $buffer .= ' }' . "\n";
1045
  }
1046
  $buffer .= ' for (var i=1; i<' . NEWSLETTER_PROFILE_MAX . '; i++) {' . "\n";
1047
  $buffer .= ' if (f.elements["np" + i] && f.elements["np" + i].required && f.elements["np" + i].value == "") {' . "\n";
1048
- $buffer .= ' alert("' . addslashes($options_profile['profile_error']) . '");' . "\n";
1049
  $buffer .= ' return false;' . "\n";
1050
  $buffer .= ' }' . "\n";
1051
  $buffer .= ' }' . "\n";
1052
 
1053
  $buffer .= ' if (f.elements["ny"] && !f.elements["ny"].checked) {' . "\n";
1054
- $buffer .= ' alert("' . addslashes($options_profile['privacy_error']) . '");' . "\n";
1055
  $buffer .= ' return false;' . "\n";
1056
  $buffer .= ' }' . "\n";
1057
  $buffer .= ' return true;' . "\n";
@@ -1069,7 +1103,6 @@ global $wpdb;
1069
 
1070
  $attrs = array_merge(array('class' => 'newsletter', 'style' => ''), $attrs);
1071
 
1072
- $options_profile = get_option('newsletter_profile');
1073
  $action = esc_attr(home_url('/') . '?na=s');
1074
  $class = esc_attr($attrs['class']);
1075
  $style = esc_attr($attrs['style']);
@@ -1096,7 +1129,7 @@ global $wpdb;
1096
  if (isset($attrs['button_label'])) {
1097
  $label = $attrs['button_label'];
1098
  } else {
1099
- $label = $options_profile['subscribe'];
1100
  }
1101
 
1102
  if (!empty($label)) {
@@ -1118,7 +1151,6 @@ global $wpdb;
1118
  if (!$suffix) {
1119
  $suffix = $name;
1120
  }
1121
- $options_profile = get_option('newsletter_profile');
1122
  $buffer = '<label for="tnp-' . $suffix . '">';
1123
  if (isset($attrs['label'])) {
1124
  if (empty($attrs['label'])) {
@@ -1127,14 +1159,13 @@ global $wpdb;
1127
  $buffer .= esc_html($attrs['label']);
1128
  }
1129
  } else {
1130
- $buffer .= esc_html($options_profile[$name]);
1131
  }
1132
  $buffer .= "</label>\n";
1133
  return $buffer;
1134
  }
1135
 
1136
  function shortcode_newsletter_field($attrs, $content) {
1137
- $options_profile = get_option('newsletter_profile');
1138
  $name = $attrs['name'];
1139
 
1140
  $buffer = '';
@@ -1166,7 +1197,7 @@ global $wpdb;
1166
  $buffer .= '<input class="tnp-name" type="text" name="nn" value=""';
1167
  if (isset($attrs['placeholder']))
1168
  $buffer .= ' placeholder="' . esc_attr($attrs['placeholder']) . '"';
1169
- if ($options_profile['name_rules'] == 1) {
1170
  $buffer .= ' required';
1171
  }
1172
  $buffer .= '>';
@@ -1181,7 +1212,7 @@ global $wpdb;
1181
  $buffer .= '<input class="tnp-surname" type="text" name="ns" value=""';
1182
  if (isset($attrs['placeholder']))
1183
  $buffer .= ' placeholder="' . esc_attr($attrs['placeholder']) . '"';
1184
- if ($options_profile['surname_rules'] == 1) {
1185
  $buffer .= ' required';
1186
  }
1187
  $buffer .= '>';
@@ -1190,21 +1221,24 @@ global $wpdb;
1190
  }
1191
 
1192
  if ($name == 'preference' || $name == 'list') {
1193
- $list = (int) $attrs['number'];
 
 
 
1194
  if (isset($attrs['hidden'])) {
1195
- return '<input type="hidden" name="nl[]" value="' . esc_attr($list) . '">';
1196
  }
1197
- $buffer .= '<div class="tnp-field tnp-field-checkbox tnp-field-list">';
1198
- $buffer .= '<input type="checkbox" id="nl' . esc_attr($list) . '" name="nl[]" value="' . esc_attr($list) . '"';
1199
  if (isset($attrs['checked'])) {
1200
  $buffer .= ' checked';
1201
  }
1202
  $buffer .= '>';
1203
  if (isset($attrs['label'])) {
1204
  if ($attrs['label'] != '')
1205
- $buffer .= '<label for="nl' . esc_attr($list) . '">' . esc_html($attrs['label']) . '</label>';
1206
  } else {
1207
- $buffer .= '<label for="nl' . esc_attr($list) . '">' . esc_html($options_profile['list_' . $list]) . '</label>';
1208
  }
1209
  $buffer .= "</div>\n";
1210
 
@@ -1213,19 +1247,21 @@ global $wpdb;
1213
 
1214
  // All the lists
1215
  if ($name == 'lists' || $name == 'preferences') {
1216
- $lists = '';
1217
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1218
- if ($options_profile['list_' . $i . '_status'] != 2) {
 
1219
  continue;
1220
  }
1221
- $lists .= '<div class="tnp-field tnp-field-checkbox tnp-field-list">';
1222
- $lists .= '<input type="checkbox" id="nl' . $i . '" name="nl[]" value="' . $i . '"';
1223
- if ($options_profile['list_' . $i . '_checked'] == 1)
1224
- $lists .= ' checked';
1225
- $lists .= '> <label for="nl' . $i . '>' . esc_html($options_profile['list_' . $i]) . '</label>';
1226
- $lists .= "</div>\n";
 
1227
  }
1228
- return $lists;
1229
  }
1230
 
1231
  // TODO: add the "not specified"
@@ -1235,12 +1271,12 @@ global $wpdb;
1235
  if ($attrs['label'] != '')
1236
  $buffer .= '<label for="">' . esc_html($attrs['label']) . '</label>';
1237
  } else {
1238
- $buffer .= '<label for="">' . esc_html($options_profile['sex']) . '</label>';
1239
  }
1240
 
1241
  $buffer .= '<select name="nx" class="tnp-gender">';
1242
- $buffer .= '<option value="m">' . esc_html($options_profile['sex_male']) . '</option>';
1243
- $buffer .= '<option value="f">' . esc_html($options_profile['sex_female']) . '</option>';
1244
  $buffer .= '</select>';
1245
  $buffer .= "</div>\n";
1246
  return $buffer;
@@ -1248,7 +1284,7 @@ global $wpdb;
1248
 
1249
  if ($name == 'profile' && isset($attrs['number'])) {
1250
  $number = (int) $attrs['number'];
1251
- $type = $options_profile['profile_' . $number . '_type'];
1252
  $size = isset($attrs['size']) ? $attrs['size'] : '';
1253
  $buffer .= '<div class="tnp-field tnp-field-profile">';
1254
  if (isset($attrs['label'])) {
@@ -1256,11 +1292,11 @@ global $wpdb;
1256
  $buffer .= '<label>' . esc_html($attrs['label']) . '</label>';
1257
  }
1258
  } else {
1259
- $buffer .= '<label>' . esc_html($options_profile['profile_' . $number]) . '</label>';
1260
  }
1261
- $placeholder = isset($attrs['placeholder']) ? $attrs['placeholder'] : $options_profile['profile_' . $number . '_placeholder'];
1262
 
1263
- $required = $options_profile['profile_' . $number . '_rules'] == 1;
1264
 
1265
  // Text field
1266
  if ($type == 'text') {
@@ -1281,7 +1317,7 @@ global $wpdb;
1281
  if (!empty($placeholder)) {
1282
  $buffer .= '<option value="">' . esc_html($placeholder) . '</option>';
1283
  }
1284
- $opts = explode(',', $options_profile['profile_' . $number . '_options']);
1285
  for ($j = 0; $j < count($opts); $j++) {
1286
  $buffer .= '<option>' . esc_html(trim($opts[$j])) . '</option>';
1287
  }
@@ -1296,11 +1332,11 @@ global $wpdb;
1296
  if (strpos($name, 'privacy') === 0) {
1297
 
1298
  if (!isset($attrs['url'])) {
1299
- $attrs['url'] = $options_profile['privacy_url'];
1300
  }
1301
 
1302
  if (!isset($attrs['label'])) {
1303
- $attrs['label'] = $options_profile['privacy_label'];
1304
  }
1305
 
1306
  $buffer .= '<div class="tnp-field tnp-field-checkbox tnp-field-privacy">';
@@ -1326,8 +1362,27 @@ global $wpdb;
1326
  *
1327
  * @return string The html code of the subscription form
1328
  */
1329
- function get_subscription_form($referrer = null, $action = null, $attrs = array()) {
1330
- return $this->get_subscription_form_html5($referrer, $action, $attrs);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1331
  }
1332
 
1333
  /**
@@ -1338,7 +1393,7 @@ global $wpdb;
1338
  * @param type $attrs
1339
  * @return string
1340
  */
1341
- function get_subscription_form_html5($referrer = null, $action = null, $attrs = array()) {
1342
  if (isset($attrs['action'])) {
1343
  $action = $attrs['action'];
1344
  }
@@ -1346,9 +1401,6 @@ global $wpdb;
1346
  $referrer = $attrs['referrer'];
1347
  }
1348
 
1349
- $options_profile = get_option('newsletter_profile');
1350
- $options = get_option('newsletter');
1351
-
1352
  $buffer = '';
1353
 
1354
  if (empty($action)) {
@@ -1371,106 +1423,114 @@ global $wpdb;
1371
  $buffer .= "<input type='hidden' name='ncu' value='" . esc_attr($attrs['confirmation_url']) . "'>\n";
1372
  }
1373
 
1374
- if (isset($attrs['lists']))
1375
- $attrs['list'] = $attrs['lists'];
1376
  if (isset($attrs['list'])) {
1377
- $arr = explode(',', $attrs['list']);
 
 
 
 
 
1378
  foreach ($arr as $a) {
1379
  $buffer .= "<input type='hidden' name='nl[]' value='" . ((int) trim($a)) . "'>\n";
1380
  }
1381
  }
1382
 
1383
- if ($options_profile['name_status'] == 2) {
1384
- $buffer .= '<div class="tnp-field tnp-field-firstname"><label>' . esc_html($options_profile['name']) . '</label>';
1385
- $buffer .= '<input class="tnp-firstname" type="text" name="nn" ' . ($options_profile['name_rules'] == 1 ? 'required' : '') . '></div>';
1386
  $buffer .= "\n";
1387
  }
1388
 
1389
- if ($options_profile['surname_status'] == 2) {
1390
- $buffer .= '<div class="tnp-field tnp-field-lastname"><label>' . esc_html($options_profile['surname']) . '</label>';
1391
- $buffer .= '<input class="tnp-lastname" type="text" name="ns" ' . ($options_profile['surname_rules'] == 1 ? 'required' : '') . '></div>';
1392
  $buffer .= "\n";
1393
  }
1394
 
1395
- $buffer .= '<div class="tnp-field tnp-field-email"><label>' . esc_html($options_profile['email']) . '</label>';
1396
  $buffer .= '<input class="tnp-email" type="email" name="ne" required></div>';
1397
  $buffer .= "\n";
1398
 
1399
- if (isset($options_profile['sex_status']) && $options_profile['sex_status'] == 2) {
1400
- $buffer .= '<div class="tnp-field tnp-field-gender"><label>' . esc_html($options_profile['sex']) . '</label>';
1401
  $buffer .= '<select name="nx" class="tnp-gender"';
1402
- if ($options_profile['sex_rules'] == 1) {
1403
  $buffer .= ' required><option value=""></option>';
1404
  } else {
1405
- $buffer .= '><option value="n">' . esc_html($options_profile['sex_none']) . '</option>';
1406
  }
1407
- $buffer .= '<option value="m">' . esc_html($options_profile['sex_male']) . '</option>';
1408
- $buffer .= '<option value="f">' . esc_html($options_profile['sex_female']) . '</option>';
1409
  $buffer .= '</select></div>';
1410
  $buffer .= "\n";
1411
  }
1412
 
1413
- $lists = '';
 
1414
  if (!empty($attrs['lists_field_layout']) && $attrs['lists_field_layout'] == 'dropdown') {
1415
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1416
- if ($options_profile['list_' . $i . '_status'] != 2) {
1417
- continue;
1418
- }
1419
- $lists .= '<option value="' . $i . '"';
1420
- if ($options_profile['list_' . $i . '_checked'] == 1) {
1421
- $lists .= ' selected';
1422
  }
1423
- $lists .= '>' . esc_html($options_profile['list_' . $i]) . '</option>';
1424
- $lists .= "\n";
1425
  }
1426
  if (!empty($attrs['lists_field_empty_label'])) {
1427
- $lists = '<option value="">' . $attrs['lists_field_empty_label'] . '</option>' . $lists;
1428
  }
1429
- if (!empty($lists)) {
1430
- $lists = '<select class="tnp-lists" name="nl[]" required>' . $lists . '</select>';
1431
  }
1432
- } else {
1433
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1434
- if ($options_profile['list_' . $i . '_status'] != 2) {
1435
- continue;
1436
  }
1437
- $lists .= '<div class="tnp-field tnp-field-list"><label><input class="tnp-preference" type="checkbox" name="nl[]" value="' . $i . '"';
1438
- if ($options_profile['list_' . $i . '_checked'] == 1) {
1439
- $lists .= ' checked';
1440
- }
1441
- $lists .= '/>&nbsp;' . esc_html($options_profile['list_' . $i]) . '</label></div>';
1442
  }
1443
- }
 
 
1444
 
1445
- if (!empty($lists)) {
1446
- $buffer .= '<div class="tnp-field tnp-field-lists">';
1447
- if (!empty($attrs['lists_field_label'])) {
1448
- $buffer .= '<label>' . $attrs['lists_field_label'] . '</label>';
 
 
 
 
 
 
 
 
1449
  }
1450
- $buffer .= $lists . '</div>';
1451
  }
1452
 
1453
  // Extra profile fields
1454
  for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
1455
  // Not for subscription form
1456
- if ($options_profile['profile_' . $i . '_status'] != 2) {
1457
  continue;
1458
  }
1459
 
1460
 
1461
  $buffer .= '<div class="tnp-field tnp-field-profile"><label>' .
1462
- esc_html($options_profile['profile_' . $i]) . '</label>';
1463
 
1464
  // Text field
1465
- if ($options_profile['profile_' . $i . '_type'] == 'text') {
1466
- $buffer .= '<input class="tnp-profile tnp-profile-' . $i . '" type="text"' . ($options_profile['profile_' . $i . '_rules'] == 1 ? ' required' : '') . ' name="np' . $i . '">';
1467
  }
1468
 
1469
  // Select field
1470
- if ($options_profile['profile_' . $i . '_type'] == 'select') {
1471
  $buffer .= '<select class="tnp-profile tnp-profile-' . $i . '" name="np' . $i . '" required>' . "\n";
1472
  $buffer .= "<option></option>\n";
1473
- $opts = explode(',', $options_profile['profile_' . $i . '_options']);
1474
  for ($j = 0; $j < count($opts); $j++) {
1475
  $buffer .= "<option>" . esc_html(trim($opts[$j])) . "</option>\n";
1476
  }
@@ -1492,8 +1552,8 @@ global $wpdb;
1492
  $buffer .= '<div class="tnp-field tnp-field-' . $name . '"><label>' . $label . "</label>";
1493
  $buffer .= $x['field'] . "</div>\n";
1494
  }
1495
-
1496
- $privacy_status = (int)$options_profile['privacy_status'];
1497
 
1498
  if ($privacy_status === 1 || $privacy_status === 2) {
1499
  $buffer .= '<div class="tnp-field tnp-field-privacy">';
@@ -1501,22 +1561,23 @@ global $wpdb;
1501
  if ($privacy_status === 1) {
1502
  $buffer .= '<input type="checkbox" name="ny" required class="tnp-privacy">&nbsp;';
1503
  }
1504
- if (!empty($options_profile['privacy_url'])) {
1505
- $buffer .= '<a target="_blank" href="' . esc_attr($options_profile['privacy_url']) . '">';
1506
- $buffer .= esc_attr($options_profile['privacy']) . '</a>';
 
1507
  } else {
1508
- $buffer .= esc_html($options_profile['privacy']);
1509
  }
1510
 
1511
  $buffer .= "</label></div>\n";
1512
- }
1513
 
1514
  $buffer .= '<div class="tnp-field tnp-field-button">';
1515
 
1516
- if (strpos($options_profile['subscribe'], 'http://') !== false) {
1517
- $buffer .= '<input class="tnp-submit-image" type="image" src="' . esc_attr($options_profile['subscribe']) . '">' . "\n";
1518
  } else {
1519
- $buffer .= '<input class="tnp-submit" type="submit" value="' . esc_attr($options_profile['subscribe']) . '">' . "\n";
1520
  }
1521
 
1522
  $buffer .= "</div>\n</form>\n";
@@ -1526,206 +1587,8 @@ global $wpdb;
1526
  return $buffer;
1527
  }
1528
 
1529
- /**
1530
- * Generate the profile editing form.
1531
- */
1532
  function get_profile_form($user) {
1533
- $options = get_option('newsletter_profile');
1534
-
1535
- $buffer = '';
1536
-
1537
- $buffer .= '<div class="tnp-profile">';
1538
- $buffer .= '<form action="' . esc_attr(home_url('/') . '?na=ps') . '" method="post" onsubmit="return newsletter_check(this)">';
1539
- // TODO: use nk
1540
- $buffer .= '<input type="hidden" name="nk" value="' . esc_attr($user->id . '-' . $user->token) . '">';
1541
- $buffer .= '<table cellspacing="0" cellpadding="3" border="0">';
1542
- $buffer .= '<tr><th align="right">' . esc_html($options['email']) . '</th><td><input class="tnp-email" type="text" size="30" name="ne" required value="' . esc_attr($user->email) . '"></td></tr>';
1543
- if ($options['name_status'] >= 1) {
1544
- $buffer .= '<tr><th align="right">' . esc_html($options['name']) . '</th><td><input class="tnp-firstname" type="text" size="30" name="nn" value="' . esc_attr($user->name) . '"></td></tr>';
1545
- }
1546
- if ($options['surname_status'] >= 1) {
1547
- $buffer .= '<tr><th align="right">' . esc_html($options['surname']) . '</th><td><input class="tnp-lastname" type="text" size="30" name="ns" value="' . esc_attr($user->surname) . '"></td></tr>';
1548
- }
1549
- if ($options['sex_status'] >= 1) {
1550
- $buffer .= '<tr><th align="right">' . esc_html($options['sex']) . '</th><td><select name="nx" class="tnp-gender">';
1551
- $buffer .= '<option value="f"' . ($user->sex == 'f' ? ' selected' : '') . '>' . esc_html($options['sex_female']) . '</option>';
1552
- $buffer .= '<option value="m"' . ($user->sex == 'm' ? ' selected' : '') . '>' . esc_html($options['sex_male']) . '</option>';
1553
- $buffer .= '<option value="n"' . ($user->sex == 'n' ? ' selected' : '') . '>' . esc_html($options['sex_none']) . '</option>';
1554
- $buffer .= '</select></td></tr>';
1555
- }
1556
-
1557
- // Profile
1558
- for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
1559
- if ($options['profile_' . $i . '_status'] == 0)
1560
- continue;
1561
-
1562
- $buffer .= '<tr><th align="right">' . esc_html($options['profile_' . $i]) . '</th><td>';
1563
-
1564
- $field = 'profile_' . $i;
1565
-
1566
- if ($options['profile_' . $i . '_type'] == 'text') {
1567
- $buffer .= '<input class="tnp-profile tnp-profile-' . $i . '" type="text" size="50" name="np' . $i . '" value="' . esc_attr($user->$field) . '"/>';
1568
- }
1569
-
1570
- if ($options['profile_' . $i . '_type'] == 'select') {
1571
- $buffer .= '<select class="tnp-profile tnp-profile-' . $i . '" name="np' . $i . '">';
1572
- $opts = explode(',', $options['profile_' . $i . '_options']);
1573
- for ($j = 0; $j < count($opts); $j++) {
1574
- $opts[$j] = trim($opts[$j]);
1575
- $buffer .= '<option';
1576
- if ($opts[$j] == $user->$field)
1577
- $buffer .= ' selected';
1578
- $buffer .= '>' . esc_html($opts[$j]) . '</option>';
1579
- }
1580
- $buffer .= '</select>';
1581
- }
1582
-
1583
- $buffer .= '</td></tr>';
1584
- }
1585
-
1586
- // Lists
1587
- $buffer .= '<tr><th>&nbsp;</th><td style="text-align: left"><div class="tnp-lists">';
1588
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1589
- if ($options['list_' . $i . '_status'] == 0) {
1590
- continue;
1591
- }
1592
- $buffer .= '<input class="tnp-list" type="checkbox" name="nl[]" value="' . $i . '"';
1593
- $list = 'list_' . $i;
1594
- if ($user->$list == 1) {
1595
- $buffer .= ' checked';
1596
- }
1597
- $buffer .= '/>&nbsp;<span class="tnp-list-label">' . esc_html($options['list_' . $i]) . '</span><br />';
1598
- }
1599
- $buffer .= '</div></td></tr>';
1600
-
1601
- $extra = apply_filters('newsletter_profile_extra', array(), $user);
1602
- foreach ($extra as &$x) {
1603
- $buffer .= "<tr>\n\t<th>" . $x['label'] . "</th>\n\t<td>\n\t\t";
1604
- $buffer .= $x['field'] . "\n\t</td>\n</tr>\n\n";
1605
- }
1606
-
1607
- $buffer .= '<tr><td colspan="2" class="tnp-td-submit">';
1608
-
1609
- if (strpos($options['save'], 'http://') !== false) {
1610
- $buffer .= '<input class="tnp-submit-image" type="image" src="' . esc_attr($options['save']) . '"></td></tr>';
1611
- } else {
1612
- $buffer .= '<input class="tnp-submit" type="submit" value="' . esc_attr($options['save']) . '"/></td></tr>';
1613
- }
1614
-
1615
- $buffer .= '</table></form></div>';
1616
-
1617
- return $buffer;
1618
- }
1619
-
1620
- function get_profile_form_html5($user) {
1621
- $options = get_option('newsletter_profile');
1622
-
1623
- $buffer = '';
1624
-
1625
- $buffer .= '<div class="tnp tnp-profile">';
1626
- $buffer .= '<form action="' . esc_attr(home_url('/') . '?na=ps') . '" method="post" onsubmit="return newsletter_check(this)">';
1627
- $buffer .= '<input type="hidden" name="nk" value="' . esc_attr($user->id . '-' . $user->token) . '">';
1628
-
1629
- $buffer .= '<div class="tnp-field tnp-field-email">';
1630
- $buffer .= '<label>' . esc_html($options['email']) . '</label>';
1631
- $buffer .= '<input class="tnp-email" type="text" name="ne" required value="' . esc_attr($user->email) . '">';
1632
- $buffer .= "</div>\n";
1633
-
1634
-
1635
- if ($options['name_status'] >= 1) {
1636
- $buffer .= '<div class="tnp-field tnp-field-firstname">';
1637
- $buffer .= '<label>' . esc_html($options['name']) . '</label>';
1638
- $buffer .= '<input class="tnp-firstname" type="text" name="nn" value="' . esc_attr($user->name) . '"' . ($options['name_rules'] == 1 ? ' required' : '') . '>';
1639
- $buffer .= "</div>\n";
1640
- }
1641
-
1642
- if ($options['surname_status'] >= 1) {
1643
- $buffer .= '<div class="tnp-field tnp-field-lastname">';
1644
- $buffer .= '<label>' . esc_html($options['surname']) . '</label>';
1645
- $buffer .= '<input class="tnp-lastname" type="text" name="ns" value="' . esc_attr($user->surname) . '"' . ($options['surname_rules'] == 1 ? ' required' : '') . '>';
1646
- $buffer .= "</div>\n";
1647
- }
1648
-
1649
- if ($options['sex_status'] >= 1) {
1650
- $buffer .= '<div class="tnp-field tnp-field-gender">';
1651
- $buffer .= '<label>' . esc_html($options['sex']) . '</label>';
1652
- $buffer .= '<select name="nx" class="tnp-gender">';
1653
- $buffer .= '<option value="f"' . ($user->sex == 'f' ? ' selected' : '') . '>' . esc_html($options['sex_female']) . '</option>';
1654
- $buffer .= '<option value="m"' . ($user->sex == 'm' ? ' selected' : '') . '>' . esc_html($options['sex_male']) . '</option>';
1655
- $buffer .= '<option value="n"' . ($user->sex == 'n' ? ' selected' : '') . '>' . esc_html($options['sex_none']) . '</option>';
1656
- $buffer .= '</select>';
1657
- $buffer .= "</div>\n";
1658
- }
1659
-
1660
- // Profile
1661
- for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
1662
- if ($options['profile_' . $i . '_status'] == 0) {
1663
- continue;
1664
- }
1665
-
1666
- $buffer .= '<div class="tnp-field tnp-field-profile">';
1667
- $buffer .= '<label>' . esc_html($options['profile_' . $i]) . '</label>';
1668
-
1669
- $field = 'profile_' . $i;
1670
-
1671
- if ($options['profile_' . $i . '_type'] == 'text') {
1672
- $buffer .= '<input class="tnp-profile tnp-profile-' . $i . '" type="text" name="np' . $i . '" value="' . esc_attr($user->$field) . '"' .
1673
- ($options['profile_' . $i . '_rules'] == 1 ? ' required' : '') . '>';
1674
- }
1675
-
1676
- if ($options['profile_' . $i . '_type'] == 'select') {
1677
- $buffer .= '<select class="tnp-profile tnp-profile-' . $i . '" name="np' . $i . '"' .
1678
- ($options['profile_' . $i . '_rules'] == 1 ? ' required' : '') . '>';
1679
- $opts = explode(',', $options['profile_' . $i . '_options']);
1680
- for ($j = 0; $j < count($opts); $j++) {
1681
- $opts[$j] = trim($opts[$j]);
1682
- $buffer .= '<option';
1683
- if ($opts[$j] == $user->$field)
1684
- $buffer .= ' selected';
1685
- $buffer .= '>' . esc_html($opts[$j]) . '</option>';
1686
- }
1687
- $buffer .= '</select>';
1688
- }
1689
-
1690
- $buffer .= "</div>\n";
1691
- }
1692
-
1693
- // Lists
1694
- $lists = '';
1695
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1696
- if ($options['list_' . $i . '_status'] == 0 || $options['list_' . $i . '_status'] == 3) {
1697
- continue;
1698
- }
1699
-
1700
- $lists .= '<div class="tnp-field tnp-field-list">';
1701
- $lists .= '<label><input class="tnp-list tnp-list-' . $i . '" type="checkbox" name="nl[]" value="' . $i . '"';
1702
- $field = 'list_' . $i;
1703
- if ($user->$field == 1) {
1704
- $lists .= ' checked';
1705
- }
1706
- $lists .= '><span class="tnp-list-label">' . esc_html($options['list_' . $i]) . '</span></label>';
1707
- $lists .= "</div>\n";
1708
- }
1709
-
1710
- if (!empty($lists)) {
1711
- $buffer .= '<div class="tnp-lists">' . "\n" . $lists . "\n" . '</div>';
1712
- }
1713
-
1714
- $extra = apply_filters('newsletter_profile_extra', array(), $user);
1715
- foreach ($extra as $x) {
1716
- $buffer .= '<div class="tnp-field">';
1717
- $buffer .= '<label>' . $x['label'] . "</label>";
1718
- $buffer .= $x['field'];
1719
- $buffer .= "</div>\n";
1720
- }
1721
-
1722
- $buffer .= '<div class="tnp-field tnp-field-button">';
1723
- $buffer .= '<input class="tnp-submit" type="submit" value="' . esc_attr($options['save']) . '">';
1724
- $buffer .= "</div>\n";
1725
-
1726
- $buffer .= "</form>\n</div>\n";
1727
-
1728
- return $buffer;
1729
  }
1730
 
1731
  function get_form($number) {
@@ -1756,12 +1619,11 @@ global $wpdb;
1756
  * @return string
1757
  */
1758
  function replace_lists($buffer) {
1759
- $options_profile = get_option('newsletter_profile');
1760
  $lists = '';
1761
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1762
- if ($options_profile['list_' . $i . '_status'] != 2)
1763
  continue;
1764
- $lists .= '<input type="checkbox" name="nl[]" value="' . $i . '"/>&nbsp;' . $options_profile['list_' . $i] . '<br />';
1765
  }
1766
  $buffer = str_replace('{lists}', $lists, $buffer);
1767
  $buffer = str_replace('{preferences}', $lists, $buffer);
@@ -1780,22 +1642,20 @@ global $wpdb;
1780
  "last name: " . $user->surname . "\n" .
1781
  "gender: " . $user->sex . "\n";
1782
 
1783
- $options_profile = get_option('newsletter_profile');
1784
-
1785
  for ($i = 0; $i < NEWSLETTER_LIST_MAX; $i++) {
1786
- if (empty($options_profile['list_' . $i])) {
1787
  continue;
1788
  }
1789
  $field = 'list_' . $i;
1790
- $message .= $options_profile['list_' . $i] . ': ' . (empty($user->$field) ? "NO" : "YES") . "\n";
1791
  }
1792
 
1793
  for ($i = 0; $i < NEWSLETTER_PROFILE_MAX; $i++) {
1794
- if (empty($options_profile['profile_' . $i])) {
1795
  continue;
1796
  }
1797
  $field = 'profile_' . $i;
1798
- $message .= $options_profile['profile_' . $i] . ': ' . $user->$field . "\n";
1799
  }
1800
 
1801
 
@@ -1811,18 +1671,27 @@ global $wpdb;
1811
  }
1812
 
1813
  function get_subscription_form_minimal($attrs) {
1814
- $options_profile = get_option('newsletter_profile');
1815
  if (!is_array($attrs)) {
1816
  $attrs = array();
1817
  }
1818
- $attrs = array_merge(array('class' => '', 'referrer' => 'minimal', 'button' => $options_profile['subscribe'], 'placeholder' => $options_profile['email']), $attrs);
1819
 
1820
  $form = '';
1821
  $form .= '<div class="tnp tnp-subscription-minimal ' . $attrs['class'] . '">';
1822
  $form .= '<form action="' . esc_attr(home_url('/')) . '?na=s" method="post">';
 
 
 
 
 
 
1823
  $form .= '<input type="hidden" name="nr" value="' . esc_attr($attrs['referrer']) . '">';
1824
  $form .= '<input class="tnp-email" type="email" required name="ne" value="" placeholder="' . esc_attr($attrs['placeholder']) . '">';
1825
  $form .= '<input class="tnp-submit" type="submit" value="' . esc_attr($attrs['button']) . '">';
 
 
 
1826
  $form .= "</form></div>\n";
1827
 
1828
  return $form;
@@ -1868,18 +1737,18 @@ global $wpdb;
1868
  $user = $module->get_user_from_request();
1869
  $message_key = $module->get_message_key_from_request();
1870
 
1871
- // if ($message_key != 'subscription' && $user == null) {
1872
- // die('Invalid subscriber');
1873
- // }
1874
 
 
 
1875
 
1876
- $message = $module->options[$message_key . '_text'];
1877
-
1878
- // TODO: the if can be removed
1879
- if ($message_key == 'confirmed') {
1880
- $message .= $module->options[$message_key . '_tracking'];
1881
  }
1882
 
 
1883
  // Now check what form must be added
1884
  if ($message_key == 'subscription') {
1885
 
@@ -1908,7 +1777,7 @@ global $wpdb;
1908
  $email = NewsletterSubscription::instance()->get_email_from_request();
1909
 
1910
  $message = $newsletter->replace($message, $user, $email, 'page');
1911
-
1912
  $message = do_shortcode($message);
1913
 
1914
  if (isset($_REQUEST['alert'])) {
8
  class NewsletterSubscription extends NewsletterModule {
9
 
10
  const MESSAGE_CONFIRMED = 'confirmed';
11
+ const OPTIN_DOUBLE = 0;
12
+ const OPTIN_SINGLE = 1;
13
 
14
  static $instance;
15
+ var $options_profile;
16
+ var $options_lists;
17
 
18
  /**
19
  * @return NewsletterSubscription
27
 
28
  function __construct() {
29
 
30
+ parent::__construct('subscription', '2.1.4', null, array('lists', 'template', 'profile'));
31
+ $this->options_profile = $this->get_options('profile');
32
+ $this->options_lists = $this->get_options('lists');
33
 
34
  // Must be called after the Newsletter::hook_init, since some constants are defined
35
  // there.
44
  add_action('wp_enqueue_scripts', array($this, 'hook_wp_enqueue_scripts'));
45
  add_shortcode('newsletter', array($this, 'shortcode_newsletter'));
46
  add_shortcode('newsletter_form', array($this, 'shortcode_newsletter_form'));
 
47
  add_shortcode('newsletter_field', array($this, 'shortcode_newsletter_field'));
48
  }
49
  }
63
  }
64
 
65
  wp_enqueue_script('newsletter-subscription', plugins_url('newsletter') . '/subscription/validate.js', array(), NEWSLETTER_VERSION, true);
66
+
67
  $data = array();
68
  $data['messages'] = array();
69
  if (isset($options['email_error'])) {
70
+ $data['messages']['email_error'] = $this->options_profile['email_error'];
71
  }
72
  if (isset($options['name_error'])) {
73
+ $data['messages']['name_error'] = $this->options_profile['name_error'];
74
  }
75
  if (isset($options['surname_error'])) {
76
+ $data['messages']['surname_error'] = $this->options_profile['surname_error'];
77
  }
78
  if (isset($options['profile_error'])) {
79
+ $data['messages']['profile_error'] = $this->options_profile['profile_error'];
80
  }
81
  if (isset($options['privacy_error'])) {
82
+ $data['messages']['privacy_error'] = $this->options_profile['privacy_error'];
83
  }
84
  $data['profile_max'] = NEWSLETTER_PROFILE_MAX;
85
  wp_localize_script('newsletter-subscription', 'newsletter', $data);
98
  }
99
  }
100
 
101
+ function is_address_blacklisted($email) {
102
+ if (empty($this->options['address_blacklist'])) {
103
+ return false;
104
+ }
105
+
106
+ $this->logger->debug('Address blacklist check');
107
+ $rev_email = strrev($email);
108
+ foreach ($this->options['address_blacklist'] as $item) {
109
+ if (strpos($rev_email, strrev($item)) === 0) {
110
+ return true;
111
+ }
112
+ }
113
+ return false;
114
+ }
115
+
116
+ function is_ip_blacklisted($ip) {
117
+ if (empty($this->options['ip_blacklist'])) {
118
+ return false;
119
+ }
120
+ $this->logger->debug('IP blacklist check');
121
+ foreach ($this->options['ip_blacklist'] as $item) {
122
+ if ($this->ip_match($ip, $item)) {
123
+ return true;
124
+ }
125
+ }
126
+ return false;
127
+ }
128
+
129
+ function is_missing_domain_mx($email) {
130
+ // Actually not fully implemented
131
+ return false;
132
+
133
+ if (empty($this->options['domain_check'])) {
134
+ return false;
135
+ }
136
+
137
+ $this->logger->debug('Domain MX check');
138
+ list($local, $domain) = explode('@', $email);
139
+
140
+ $hosts = array();
141
+ if (!getmxrr($domain, $hosts)) {
142
+ return true;
143
+ }
144
+ return false;
145
+ }
146
+
147
+ function is_flood($email, $ip) {
148
+ global $wpdb;
149
+
150
+ if (empty($this->options['antiflood'])) {
151
+ return false;
152
+ }
153
+
154
+ $this->logger->debug('Antiflood check');
155
+
156
+ $updated = $wpdb->get_var($wpdb->prepare("select updated from " . NEWSLETTER_USERS_TABLE . " where ip=%s or email=%s order by updated desc limit 1", $ip, $email));
157
+
158
+ if ($updated && time() - $updated < $this->options['antiflood']) {
159
+ return true;
160
+ }
161
+
162
+ return false;
163
+ }
164
+
165
+ function is_spam_text($text) {
166
+ if (stripos($text, 'http://') !== false || stripos($text, 'https://') !== false) {
167
+ return true;
168
+ }
169
+ return false;
170
+ }
171
+
172
+ function is_spam_by_akismet($email, $name, $ip, $agent, $referrer) {
173
+ if (empty($this->options['akismet'])) {
174
+ return false;
175
+ }
176
+ if (!class_exists('Akismet')) {
177
+ return false;
178
+ }
179
+
180
+ $this->logger->debug('Akismet check');
181
+ $request = 'blog=' . urlencode(home_url()) . '&referrer=' . urlencode($referrer) .
182
+ '&user_agent=' . urlencode($agent) .
183
+ '&comment_type=signup' .
184
+ '&comment_author_email=' . urlencode($email) .
185
+ '&user_ip=' . urlencode($ip);
186
+ if (!empty($name)) {
187
+ $request .= '&comment_author=' . urlencode($name);
188
+ }
189
+
190
+ $response = Akismet::http_post($request, 'comment-check');
191
+
192
+ if ($response && $response[1] == 'true') {
193
+ return true;
194
+ }
195
+ return false;
196
+ }
197
+
198
+ /**
199
+ *
200
+ * @global wpdb $wpdb
201
+ * @return mixed
202
+ */
203
  function hook_wp_loaded() {
204
+ global $wpdb;
205
+
206
+ $newsletter = Newsletter::instance();
207
 
208
  switch ($newsletter->action) {
209
  case 'profile-change':
223
 
224
  // Check if the list is public
225
  $list = $this->get_list($list_id);
226
+ if (!$list || $list->status == 0) {
227
  die('Private list.');
228
  }
229
 
230
  $url = $_REQUEST['redirect'];
231
 
232
  $this->set_user_list($user, $list_id, $_REQUEST['value']);
233
+
234
+ $user = $this->get_user($user->id);
235
+ $this->add_user_log($user, 'cta');
236
+ NewsletterStatistics::instance()->add_click($url, $user->id, $email->id);
237
+ wp_redirect($url);
238
  die();
239
  }
240
  } else {
244
  die();
245
 
246
  case 'm':
247
+ case 'message':
248
  include dirname(__FILE__) . '/page.php';
249
  die();
250
 
255
  $ip = $this->get_remote_ip();
256
  $email = $this->normalize_email($_REQUEST['ne']);
257
  $first_name = '';
258
+ if (isset($_REQUEST['nn']))
259
+ $first_name = $this->normalize_name($_REQUEST['nn']);
260
+
261
  $last_name = '';
262
+ if (isset($_REQUEST['ns']))
263
+ $last_name = $this->normalize_name($_REQUEST['ns']);
264
+
265
  $full_name = trim($first_name . ' ' . $last_name);
266
+
267
  $antibot_logger = new NewsletterLogger('antibot');
268
 
269
  if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
276
  if (!empty($this->options['antibot_disable']) || $this->antibot_form_check($captcha)) {
277
 
278
 
279
+ if ($this->is_spam_text($full_name)) {
280
  $antibot_logger->fatal($email . ' - ' . $ip . ' - Name with http: ' . $full_name);
281
  header("HTTP/1.0 404 Not Found");
282
  die();
283
  }
284
 
 
 
285
  // Cannot check for administrator here, too early.
286
  if (true) {
287
 
288
  $this->logger->debug('Subscription of: ' . $email);
289
+
290
+ // 404 is returned to attempt to make the bot believe the url has been changed
291
+
292
+ if ($this->is_missing_domain_mx($email)) {
293
+ $antibot_logger->fatal($email . ' - ' . $ip . ' - MX check failed');
294
+ header("HTTP/1.0 404 Not Found");
295
+ die();
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  }
297
 
298
+ if ($this->is_ip_blacklisted($ip)) {
299
+ $antibot_logger->fatal($email . ' - ' . $ip . ' - IP blacklisted');
300
+ header("HTTP/1.0 404 Not Found");
301
+ die();
302
+ }
303
+
304
+ if ($this->is_address_blacklisted($email)) {
305
+ $antibot_logger->fatal($email . ' - ' . $ip . ' - Address blacklisted');
306
+ header("HTTP/1.0 404 Not Found");
307
+ die();
308
  }
309
 
310
  // Akismet check
311
+ if ($this->is_spam_by_akismet($email, $full_name, $ip, $_SERVER['HTTP_USER_AGENT'], $_SERVER['HTTP_REFERER'])) {
312
+ $antibot_logger->fatal($email . ' - ' . $ip . ' - Akismet blocked');
313
+ header("HTTP/1.0 404 Not Found");
314
+ die();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  }
316
 
317
  // Flood check
318
+ if ($this->is_flood($email, $ip)) {
319
+ $antibot_logger->fatal($email . ' - ' . $ip . ' - Antiflood triggered');
320
+ header("HTTP/1.0 404 Not Found");
321
+ die('Too quick');
 
 
 
 
 
 
322
  }
323
 
324
  $user = $this->subscribe();
384
  }
385
  die();
386
  break;
 
 
 
 
 
 
 
387
 
388
+ case 'reactivate':
389
+ if ($this->antibot_form_check()) {
390
+ $user = $this->reactivate();
391
+ $this->show_message('reactivated', $user);
392
+ } else {
393
+ $this->request_to_antibot_form('Unsubscribe');
394
+ }
395
  die();
 
396
 
 
 
 
 
 
397
  break;
398
 
399
  case 'c':
418
  }
419
 
420
  function upgrade() {
421
+ global $wpdb, $charset_collate;
422
 
423
  parent::upgrade();
424
 
425
+ $newsletter = Newsletter::instance();
426
+ $lists_options = $this->get_options('lists');
427
+ $profile_options = $this->get_options('profile');
 
428
 
429
+ if (empty($lists_options)) {
430
+ foreach ($profile_options as $key => $value) {
431
+ if (strpos($key, 'list_') === 0) {
432
+ $lists_options[$key] = $value;
433
+ }
434
+ }
435
  }
436
 
437
+ for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
438
+ if (!isset($profile_options['list_' . $i . '_forced'])) {
439
+ $profile_options['list_' . $i . '_forced'] = empty($this->options['preferences_' . $i]) ? 0 : 1;
440
+ $lists_options['list_' . $i . '_forced'] = empty($this->options['preferences_' . $i]) ? 0 : 1;
 
441
  }
 
 
 
 
442
  }
443
 
444
+ $this->save_options($profile_options, 'profile');
445
+ $this->save_options($lists_options, 'lists');
446
+
447
+
448
+ $default_options = $this->get_default_options();
449
+
450
+ if (empty($this->options['error_text'])) {
451
+ $this->options['error_text'] = $default_options['error_text'];
452
  $this->save_options($this->options);
 
 
453
  }
454
 
455
  if ($this->old_version < '2.0.0') {
473
  }
474
 
475
  $this->init_options('template', false);
476
+
477
  global $wpdb, $charset_collate;
478
 
479
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
481
 
482
 
483
  $sql = "CREATE TABLE `" . $wpdb->prefix . "newsletter_user_logs` (
484
+ `id` int(11) NOT NULL AUTO_INCREMENT,
485
+ `user_id` int(11) NOT NULL DEFAULT 0,
486
+ `source` varchar(50) NOT NULL DEFAULT '',
487
+ `data` longtext,
488
+ `created` int(11) NOT NULL DEFAULT 0,
489
+ PRIMARY KEY (`id`)
490
+ ) $charset_collate;";
491
 
492
  dbDelta($sql);
493
 
504
  $this->add_admin_page('profile', 'Subscription Form');
505
  $this->add_admin_page('forms', 'Forms');
506
  $this->add_admin_page('lists', 'Lists');
507
+ $this->add_admin_page('lists-edit', 'List edit');
508
  $this->add_admin_page('template', 'Template');
509
  $this->add_admin_page('unsubscription', 'Unsubscription');
510
  }
520
  * @param array $options
521
  * @param string $sub
522
  */
523
+ function save_options($options, $sub = '', $autoload = null) {
524
  if ($sub == '') {
525
  // For compatibility the options are wrongly named
526
+ return update_option('newsletter', $options, $autoload);
527
  }
528
+
529
  if ($sub == 'profile') {
530
+ // For compatibility the options are wrongly named
531
+ $this->options_profile = $options;
532
+ return update_option('newsletter_profile', $options, $autoload);
533
+ }
534
+
535
+ if ($sub == 'forms') {
536
+ // For compatibility the options are wrongly named
537
+ return update_option('newsletter_forms', $options, $autoload);
538
  }
539
+
540
+ if ($sub == 'lists') {
541
+ $this->options_lists = $options;
542
+ }
543
+ return parent::save_options($options, $sub, $autoload);
544
  }
545
 
546
  function get_options($sub = '') {
555
  // For compatibility the options are wrongly named
556
  return get_option('newsletter_profile', array());
557
  }
558
+ if ($sub == 'forms') {
559
+ // For compatibility the options are wrongly named
560
+ return get_option('newsletter_forms', array());
561
+ }
562
  return parent::get_options($sub);
563
  }
564
 
568
  $time = time();
569
 
570
  if (!$ip)
571
+ $ip = $this->get_remote_ip();
572
 
573
  if (is_object($user))
574
  $id = $user->id;
592
  // Messages
593
  $options = get_option('newsletter', array());
594
 
 
 
 
595
  $opt_in = (int) $this->options['noconfirmation']; // 0 - double, 1 - single
596
+ if (!empty($this->options['optin_override']) && isset($_REQUEST['optin'])) {
597
  switch ($_REQUEST['optin']) {
598
+ case 'single': $opt_in = self::OPTIN_SINGLE;
599
  break;
600
+ case 'double': $opt_in = self::OPTIN_DOUBLE;
601
  break;
602
  }
603
  }
604
 
605
+ if ($status != null) {
606
+ // If a status is forced and it is requested to be "confirmed" is like a single opt in
607
+ // $status here can only be confirmed or not confirmed
608
+ // TODO: Add a check on status values
609
+ if ($status == Newsletter::STATUS_CONFIRMED) {
610
+ $opt_in = self::OPTIN_SINGLE;
611
+ } else {
612
+ $opt_in = self::OPTIN_DOUBLE;
613
+ }
614
+ }
615
+
616
  $email = $newsletter->normalize_email(stripslashes($_REQUEST['ne']));
617
 
618
  // Shound never reach this point without a valid email address
620
  die('Wrong email');
621
  }
622
 
623
+ $user = $this->get_user($email);
624
 
625
  if ($user != null) {
626
+ // Email already registered in our database
627
  $this->logger->info('Subscription of an address with status ' . $user->status);
628
 
629
  // Bounced
630
+ // TODO: Manage other cases when added
631
  if ($user->status == 'B') {
632
  // Non persistent status to decide which message to show (error)
633
  $user->status = 'E';
634
  return $user;
635
  }
636
 
637
+ // Is there any relevant data change? If so we can proceed otherwise if repeated subscriptions are disabled
638
+ // show an already subscribed message
639
 
640
+ if (empty($this->options['multiple'])) {
641
+ $user->status = 'E';
642
+ return $user;
643
+ }
644
 
645
+ if ($this->options['multiple'] == 2) {
646
+ $lists_changed = false;
647
+ if (isset($_REQUEST['nl']) && is_array($_REQUEST['nl'])) {
648
+ foreach ($_REQUEST['nl'] as $list_id) {
649
+ $list_id = (int) $list_id;
650
+ if ($list_id <= 0 || $list_id > NEWSLETTER_LIST_MAX)
651
+ continue;
652
+ $field = 'list_' . $list_id;
653
+ if ($user->$field == 0) {
654
+ $lists_changed = true;
655
+ break;
656
+ }
657
+ }
658
+ }
659
 
660
+ if (!$lists_changed) {
661
+ $user->status = 'E';
662
+ return $user;
663
+ }
664
+ }
665
 
666
+ // If the subscriber is confirmed, we cannot change his data in double opt in mode, we need to
667
+ // temporary store and wait for activation
668
+ if ($user->status == Newsletter::STATUS_CONFIRMED && $opt_in == self::OPTIN_DOUBLE) {
669
 
670
+ set_transient($this->get_user_key($user), $_REQUEST, 3600 * 48);
 
671
 
672
+ // This status is not stored it indicate a temporary status to show the correct messages
673
+ $user->status = 'S';
 
 
 
 
674
 
675
+ $this->send_message('confirmation', $user);
676
+
677
+ return $user;
678
  }
679
  }
680
 
681
+ // Here we have a new subscription or we can process the subscription even with a pre-existant user for example
682
+ // because it is not confirmed
683
  if ($user != null) {
684
  $this->logger->info("Email address subscribed but not confirmed");
685
  $user = array('id' => $user->id);
690
 
691
  $user = $this->update_user_from_request($user);
692
 
693
+
694
+ $user['token'] = $this->get_token();
695
+ $user['ip'] = $this->get_remote_ip();
696
+ $user['status'] = $opt_in == self::OPTIN_SINGLE ? Newsletter::STATUS_CONFIRMED : Newsletter::STATUS_NOT_CONFIRMED;
 
 
 
697
 
698
  $user['updated'] = time();
699
 
708
 
709
  $user = $this->save_user($user);
710
 
711
+ $this->add_user_log($user, 'subscribe');
712
+
713
  // Notification to admin (only for new confirmed subscriptions)
714
+ if ($user->status == Newsletter::STATUS_CONFIRMED) {
715
  do_action('newsletter_user_confirmed', $user);
716
  $this->notify_admin($user, 'Newsletter subscription');
717
  setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
718
  }
719
 
720
+ if ($emails) {
721
+ $this->send_message(($user->status == Newsletter::STATUS_CONFIRMED) ? 'confirmed' : 'confirmation', $user);
722
  }
723
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
724
  return $user;
725
  }
726
 
765
  // New profiles
766
  for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
767
  // If the profile cannot be set by subscriber, skip it.
768
+ if ($this->options_profile['profile_' . $i . '_status'] == 0) {
769
  continue;
770
  }
771
+ if (isset($_REQUEST['np' . $i])) {
772
+ $user['profile_' . $i] = trim(stripslashes($_REQUEST['np' . $i]));
773
+ }
774
  }
775
 
776
+ $lists = $this->get_lists_public();
777
+
778
  // Preferences (field names are nl[] and values the list number so special forms with radio button can work)
779
  if (isset($_REQUEST['nl']) && is_array($_REQUEST['nl'])) {
780
  $this->logger->debug($_REQUEST['nl']);
781
+ foreach ($lists as $list) {
782
+ if (in_array('' . $list->id, $_REQUEST['nl'])) {
783
+ $user['list_' . $list->id] = 1;
 
 
 
 
784
  }
785
  }
786
  } else {
787
  $this->logger->debug('No preferences received');
788
  }
789
 
790
+ // Forced lists
791
+ foreach ($lists as $list) {
792
+ if ($list->forced) {
793
+ $user['list_' . $i] = 1;
794
  }
 
795
  }
796
 
797
  // TODO: should be removed!!!
811
  */
812
  function mail($to, $subject, $message) {
813
  $options_template = $this->get_options('template');
814
+
815
+ $template = trim($options_template['template']);
816
+ if (empty($template) || strpos($template, '{message}') === false) {
817
+ $template = '{message}';
 
 
 
 
 
 
 
 
818
  }
819
+ $message = str_replace('{message}', $message, $template);
820
+
821
 
822
  $headers = array('Auto-Submitted' => 'auto-generated');
823
 
824
+ $message = $this->replace($message);
825
  return Newsletter::instance()->mail($to, $subject, $message, $headers);
826
  }
827
 
828
+ function reactivate() {
829
+ $user = $this->get_user_from_request();
830
+ if (!$user) {
831
+ die('No subscriber found.');
832
+ }
833
+
834
+ $this->set_user_status($user, Newsletter::STATUS_CONFIRMED);
835
+ $this->add_user_log($user, 'reactivate');
836
+
837
+ return $user;
838
+ }
839
+
840
  /**
841
  *
 
842
  * @param type $user
843
  * @return stdClass
844
  */
847
  if ($user_id == null) {
848
  $user = $this->get_user_from_request();
849
  if ($user) {
850
+ // Is there any temporary data from a subscription to be confirmed?
851
+ $data = get_transient($this->get_user_key($user));
852
  if ($data !== false) {
853
  $_REQUEST = $data;
854
  // Update the user profile since it's now confirmed
855
  $user = $this->update_user_from_request((array) $user);
856
  $user = $this->save_user($user);
857
+ delete_transient($this->get_user_key($user));
858
  // Forced a fake status so the welcome email is sent
859
+ $user->status = Newsletter::STATUS_NOT_CONFIRMED;
860
  }
861
  }
862
  } else {
868
  die('No subscriber found.');
869
  }
870
 
871
+ $this->update_user_last_activity($user);
872
+
873
  setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
874
 
875
+ if ($user->status == Newsletter::STATUS_CONFIRMED) {
876
+ $this->add_user_log($user, 'activate');
877
  do_action('newsletter_user_confirmed', $user);
878
  return $user;
879
  }
884
  // return $user;
885
  // }
886
 
887
+ $this->set_user_status($user->id, Newsletter::STATUS_CONFIRMED);
888
+
889
+ $user = $this->get_user($user->id);
890
+
891
+ $this->add_user_log($user, 'activate');
892
+
893
  do_action('newsletter_user_confirmed', $user);
894
  $this->notify_admin($user, 'Newsletter subscription');
895
 
896
+ if ($emails) {
897
+ $this->send_message('confirmed', $user);
898
  }
899
 
 
 
900
  return $user;
901
  }
902
 
903
+ /**
904
+ * Sends a message (activation, welcome, cancellation, ...) with the correct template
905
+ * and checking if the message itself is disabled
906
+ *
907
+ * @param string $type
908
+ * @param type $user
909
+ */
910
+ function send_message($type, $user, $force = false) {
911
+ if (!$force && !empty($this->options[$type . '_disabled']))
912
+ return true;
913
 
914
+ $message = $this->options[$type . '_message'];
915
+ if ($user->status == Newsletter::STATUS_NOT_CONFIRMED) {
916
+ $message = $this->add_microdata($message);
917
  }
918
+ $subject = $this->options[$type . '_subject'];
919
+
920
+ return $this->mail($user->email, $this->replace($subject, $user), $this->replace($message, $user));
921
  }
922
 
923
  /**
934
  return $user;
935
  }
936
 
937
+ $this->set_user_status($user->id, 'U');
938
+
939
+ $user->status = 'U';
940
+ $this->add_user_log($user, 'unsubscribe');
941
+
942
  do_action('newsletter_unsubscribed', $user);
943
 
944
  global $wpdb;
945
+
946
+ $email = $this->get_email_from_request();
947
+ if ($email) {
948
  $wpdb->update(NEWSLETTER_USERS_TABLE, array('unsub_email_id' => (int) $email_id, 'unsub_time' => time()), array('id' => $user->id));
949
  }
950
 
951
+ $this->send_message('unsubscribed', $user);
952
+
 
953
  $this->notify_admin($user, 'Newsletter unsubscription');
954
+
955
+ return $user;
956
  }
957
 
958
  /**
961
  * @return type
962
  */
963
  function save_profile() {
964
+ return NewsletterProfile::instance()->save_profile();
965
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
966
 
967
+ function is_double_optin() {
968
+ return $this->options['noconfirmation'] == 0;
969
+ }
 
 
 
 
 
 
 
 
 
970
 
971
+ /**
972
+ * Sends the activation email without conditions.
973
+ *
974
+ * @param stdClass $user
975
+ * @return bool
976
+ */
977
+ function send_activation_email($user) {
978
+ return $this->send_message('confirmation', $user, true);
979
  }
980
 
981
  /**
1008
  $params .= '&nek=' . $email->id . '-' . $email->token;
1009
  }
1010
 
1011
+ $url = apply_filters('newsletter_page_url', '', $key);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1012
 
1013
  if (empty($url)) {
1014
+ if (!empty($this->options[$key . '_url'])) {
1015
+ $url = $this->options[$key . '_url'];
1016
+ } else if (!empty($this->options['page'])) {
1017
+ $url = get_permalink($this->options['page']);
1018
+ } else if (!empty($this->options['url'])) {
1019
+ $url = $this->options['url'];
1020
+ } else {
1021
+ $url = home_url('/') . '?na=m';
1022
+ }
1023
  }
1024
 
1025
+ header('Location: ' . self::add_qs($url, 'nm=' . $key . '&nk=' . $this->get_user_key($user), false) . $params);
1026
  die();
1027
  }
1028
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1029
  function get_message_key_from_request() {
1030
  if (empty($_GET['nm'])) {
1031
  return 'subscription';
1043
  }
1044
  }
1045
 
1046
+ function get_privacy_url() {
1047
+ static $url = false;
1048
+
1049
+ if (!$url) {
1050
+ $url = $this->options_profile['privacy_url'];
1051
+ // TODO: Fine the new WP privacy page
1052
+ }
1053
+ return $url;
1054
+ }
1055
+
1056
  function get_form_javascript() {
1057
+
 
 
1058
  $buffer = "\n\n";
1059
  $buffer .= '<script type="text/javascript">' . "\n";
1060
  $buffer .= '//<![CDATA[' . "\n";
1062
  $buffer .= 'window.newsletter_check = function (f) {' . "\n";
1063
  $buffer .= ' var re = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-]{1,})+\.)+([a-zA-Z0-9]{2,})+$/;' . "\n";
1064
  $buffer .= ' if (!re.test(f.elements["ne"].value)) {' . "\n";
1065
+ $buffer .= ' alert("' . addslashes($this->options_profile['email_error']) . '");' . "\n";
1066
  $buffer .= ' return false;' . "\n";
1067
  $buffer .= ' }' . "\n";
1068
+ if ($this->options_profile['name_status'] == 2 && $this->options_profile['name_rules'] == 1) {
1069
  $buffer .= ' if (f.elements["nn"] && (f.elements["nn"].value == "" || f.elements["nn"].value == f.elements["nn"].defaultValue)) {' . "\n";
1070
+ $buffer .= ' alert("' . addslashes($this->options_profile['name_error']) . '");' . "\n";
1071
  $buffer .= ' return false;' . "\n";
1072
  $buffer .= ' }' . "\n";
1073
  }
1074
+ if ($this->options_profile['surname_status'] == 2 && $this->options_profile['surname_rules'] == 1) {
1075
  $buffer .= ' if (f.elements["ns"] && (f.elements["ns"].value == "" || f.elements["ns"].value == f.elements["ns"].defaultValue)) {' . "\n";
1076
+ $buffer .= ' alert("' . addslashes($this->options_profile['surname_error']) . '");' . "\n";
1077
  $buffer .= ' return false;' . "\n";
1078
  $buffer .= ' }' . "\n";
1079
  }
1080
  $buffer .= ' for (var i=1; i<' . NEWSLETTER_PROFILE_MAX . '; i++) {' . "\n";
1081
  $buffer .= ' if (f.elements["np" + i] && f.elements["np" + i].required && f.elements["np" + i].value == "") {' . "\n";
1082
+ $buffer .= ' alert("' . addslashes($this->options_profile['profile_error']) . '");' . "\n";
1083
  $buffer .= ' return false;' . "\n";
1084
  $buffer .= ' }' . "\n";
1085
  $buffer .= ' }' . "\n";
1086
 
1087
  $buffer .= ' if (f.elements["ny"] && !f.elements["ny"].checked) {' . "\n";
1088
+ $buffer .= ' alert("' . addslashes($this->options_profile['privacy_error']) . '");' . "\n";
1089
  $buffer .= ' return false;' . "\n";
1090
  $buffer .= ' }' . "\n";
1091
  $buffer .= ' return true;' . "\n";
1103
 
1104
  $attrs = array_merge(array('class' => 'newsletter', 'style' => ''), $attrs);
1105
 
 
1106
  $action = esc_attr(home_url('/') . '?na=s');
1107
  $class = esc_attr($attrs['class']);
1108
  $style = esc_attr($attrs['style']);
1129
  if (isset($attrs['button_label'])) {
1130
  $label = $attrs['button_label'];
1131
  } else {
1132
+ $label = $this->options_profile['subscribe'];
1133
  }
1134
 
1135
  if (!empty($label)) {
1151
  if (!$suffix) {
1152
  $suffix = $name;
1153
  }
 
1154
  $buffer = '<label for="tnp-' . $suffix . '">';
1155
  if (isset($attrs['label'])) {
1156
  if (empty($attrs['label'])) {
1159
  $buffer .= esc_html($attrs['label']);
1160
  }
1161
  } else {
1162
+ $buffer .= esc_html($this->options_profile[$name]);
1163
  }
1164
  $buffer .= "</label>\n";
1165
  return $buffer;
1166
  }
1167
 
1168
  function shortcode_newsletter_field($attrs, $content) {
 
1169
  $name = $attrs['name'];
1170
 
1171
  $buffer = '';
1197
  $buffer .= '<input class="tnp-name" type="text" name="nn" value=""';
1198
  if (isset($attrs['placeholder']))
1199
  $buffer .= ' placeholder="' . esc_attr($attrs['placeholder']) . '"';
1200
+ if ($this->options_profile['name_rules'] == 1) {
1201
  $buffer .= ' required';
1202
  }
1203
  $buffer .= '>';
1212
  $buffer .= '<input class="tnp-surname" type="text" name="ns" value=""';
1213
  if (isset($attrs['placeholder']))
1214
  $buffer .= ' placeholder="' . esc_attr($attrs['placeholder']) . '"';
1215
+ if ($this->options_profile['surname_rules'] == 1) {
1216
  $buffer .= ' required';
1217
  }
1218
  $buffer .= '>';
1221
  }
1222
 
1223
  if ($name == 'preference' || $name == 'list') {
1224
+ $list = $this->get_list($attrs['number']);
1225
+ if (!$list || $list->status == 0 || $list->forced) {
1226
+ return;
1227
+ }
1228
  if (isset($attrs['hidden'])) {
1229
+ return '<input type="hidden" name="nl[]" value="' . esc_attr($list->id) . '">';
1230
  }
1231
+ $buffer .= '<div class="tnp-field tnp-field-checkbox tnp-field-list"><label for="nl' . esc_attr($list->id) . '">';
1232
+ $buffer .= '<input type="checkbox" id="nl' . esc_attr($list->id) . '" name="nl[]" value="' . esc_attr($list->id) . '"';
1233
  if (isset($attrs['checked'])) {
1234
  $buffer .= ' checked';
1235
  }
1236
  $buffer .= '>';
1237
  if (isset($attrs['label'])) {
1238
  if ($attrs['label'] != '')
1239
+ $buffer .= '&nbsp;' . esc_html($attrs['label']) . '</label>';
1240
  } else {
1241
+ $buffer .= '&nbsp;' . esc_html($list->name) . '</label>';
1242
  }
1243
  $buffer .= "</div>\n";
1244
 
1247
 
1248
  // All the lists
1249
  if ($name == 'lists' || $name == 'preferences') {
1250
+ $tmp = '';
1251
+ $lists = $this->get_lists();
1252
+ foreach ($lists as $list) {
1253
+ if ($list->status != 2 || $list->forced) {
1254
  continue;
1255
  }
1256
+ //die('ddd');
1257
+ $tmp .= '<div class="tnp-field tnp-field-checkbox tnp-field-list"><label for="nl' . $list->id . '">';
1258
+ $tmp .= '<input type="checkbox" id="nl' . $list->id . '" name="nl[]" value="' . $list->id . '"';
1259
+ if ($list->checked)
1260
+ $tmp .= ' checked';
1261
+ $tmp .= '>&nbsp;' . esc_html($list->name) . '</label>';
1262
+ $tmp .= "</div>\n";
1263
  }
1264
+ return $tmp;
1265
  }
1266
 
1267
  // TODO: add the "not specified"
1271
  if ($attrs['label'] != '')
1272
  $buffer .= '<label for="">' . esc_html($attrs['label']) . '</label>';
1273
  } else {
1274
+ $buffer .= '<label for="">' . esc_html($this->options_profile['sex']) . '</label>';
1275
  }
1276
 
1277
  $buffer .= '<select name="nx" class="tnp-gender">';
1278
+ $buffer .= '<option value="m">' . esc_html($this->options_profile['sex_male']) . '</option>';
1279
+ $buffer .= '<option value="f">' . esc_html($this->options_profile['sex_female']) . '</option>';
1280
  $buffer .= '</select>';
1281
  $buffer .= "</div>\n";
1282
  return $buffer;
1284
 
1285
  if ($name == 'profile' && isset($attrs['number'])) {
1286
  $number = (int) $attrs['number'];
1287
+ $type = $this->options_profile['profile_' . $number . '_type'];
1288
  $size = isset($attrs['size']) ? $attrs['size'] : '';
1289
  $buffer .= '<div class="tnp-field tnp-field-profile">';
1290
  if (isset($attrs['label'])) {
1292
  $buffer .= '<label>' . esc_html($attrs['label']) . '</label>';
1293
  }
1294
  } else {
1295
+ $buffer .= '<label>' . esc_html($this->options_profile['profile_' . $number]) . '</label>';
1296
  }
1297
+ $placeholder = isset($attrs['placeholder']) ? $attrs['placeholder'] : $this->options_profile['profile_' . $number . '_placeholder'];
1298
 
1299
+ $required = $this->options_profile['profile_' . $number . '_rules'] == 1;
1300
 
1301
  // Text field
1302
  if ($type == 'text') {
1317
  if (!empty($placeholder)) {
1318
  $buffer .= '<option value="">' . esc_html($placeholder) . '</option>';
1319
  }
1320
+ $opts = explode(',', $this->options_profile['profile_' . $number . '_options']);
1321
  for ($j = 0; $j < count($opts); $j++) {
1322
  $buffer .= '<option>' . esc_html(trim($opts[$j])) . '</option>';
1323
  }
1332
  if (strpos($name, 'privacy') === 0) {
1333
 
1334
  if (!isset($attrs['url'])) {
1335
+ $attrs['url'] = $this->options_profile['privacy_url'];
1336
  }
1337
 
1338
  if (!isset($attrs['label'])) {
1339
+ $attrs['label'] = $this->options_profile['privacy_label'];
1340
  }
1341
 
1342
  $buffer .= '<div class="tnp-field tnp-field-checkbox tnp-field-privacy">';
1362
  *
1363
  * @return string The html code of the subscription form
1364
  */
1365
+ function get_subscription_form_html5($referrer = null, $action = null, $attrs = array()) {
1366
+ return $this->get_subscription_form($referrer, $action, $attrs);
1367
+ }
1368
+
1369
+ function get_privacy_field() {
1370
+ $privacy_status = (int) $this->options_profile['privacy_status'];
1371
+ $buffer = '<label>';
1372
+ if ($privacy_status === 1) {
1373
+ $buffer .= '<input type="checkbox" name="ny" required class="tnp-privacy">&nbsp;';
1374
+ }
1375
+ $url = $this->get_privacy_url();
1376
+ if (!empty($url)) {
1377
+ $buffer .= '<a target="_blank" href="' . esc_attr($url) . '">';
1378
+ $buffer .= esc_attr($this->options_profile['privacy']) . '</a>';
1379
+ } else {
1380
+ $buffer .= esc_html($this->options_profile['privacy']);
1381
+ }
1382
+
1383
+ $buffer .= "</label>";
1384
+
1385
+ return $buffer;
1386
  }
1387
 
1388
  /**
1393
  * @param type $attrs
1394
  * @return string
1395
  */
1396
+ function get_subscription_form($referrer = null, $action = null, $attrs = array()) {
1397
  if (isset($attrs['action'])) {
1398
  $action = $attrs['action'];
1399
  }
1401
  $referrer = $attrs['referrer'];
1402
  }
1403
 
 
 
 
1404
  $buffer = '';
1405
 
1406
  if (empty($action)) {
1423
  $buffer .= "<input type='hidden' name='ncu' value='" . esc_attr($attrs['confirmation_url']) . "'>\n";
1424
  }
1425
 
1426
+ // Compatibility
 
1427
  if (isset($attrs['list'])) {
1428
+ $attrs['lists'] = $attrs['list'];
1429
+ }
1430
+
1431
+ // Hidden lists
1432
+ if (isset($attrs['lists'])) {
1433
+ $arr = explode(',', $attrs['lists']);
1434
  foreach ($arr as $a) {
1435
  $buffer .= "<input type='hidden' name='nl[]' value='" . ((int) trim($a)) . "'>\n";
1436
  }
1437
  }
1438
 
1439
+ if ($this->options_profile['name_status'] == 2) {
1440
+ $buffer .= '<div class="tnp-field tnp-field-firstname"><label>' . esc_html($this->options_profile['name']) . '</label>';
1441
+ $buffer .= '<input class="tnp-firstname" type="text" name="nn" ' . ($this->options_profile['name_rules'] == 1 ? 'required' : '') . '></div>';
1442
  $buffer .= "\n";
1443
  }
1444
 
1445
+ if ($this->options_profile['surname_status'] == 2) {
1446
+ $buffer .= '<div class="tnp-field tnp-field-lastname"><label>' . esc_html($this->options_profile['surname']) . '</label>';
1447
+ $buffer .= '<input class="tnp-lastname" type="text" name="ns" ' . ($this->options_profile['surname_rules'] == 1 ? 'required' : '') . '></div>';
1448
  $buffer .= "\n";
1449
  }
1450
 
1451
+ $buffer .= '<div class="tnp-field tnp-field-email"><label>' . esc_html($this->options_profile['email']) . '</label>';
1452
  $buffer .= '<input class="tnp-email" type="email" name="ne" required></div>';
1453
  $buffer .= "\n";
1454
 
1455
+ if (isset($this->options_profile['sex_status']) && $this->options_profile['sex_status'] == 2) {
1456
+ $buffer .= '<div class="tnp-field tnp-field-gender"><label>' . esc_html($this->options_profile['sex']) . '</label>';
1457
  $buffer .= '<select name="nx" class="tnp-gender"';
1458
+ if ($this->options_profile['sex_rules'] == 1) {
1459
  $buffer .= ' required><option value=""></option>';
1460
  } else {
1461
+ $buffer .= '><option value="n">' . esc_html($this->options_profile['sex_none']) . '</option>';
1462
  }
1463
+ $buffer .= '<option value="m">' . esc_html($this->options_profile['sex_male']) . '</option>';
1464
+ $buffer .= '<option value="f">' . esc_html($this->options_profile['sex_female']) . '</option>';
1465
  $buffer .= '</select></div>';
1466
  $buffer .= "\n";
1467
  }
1468
 
1469
+ $tmp = '';
1470
+ $lists = $this->get_lists_for_subscription();
1471
  if (!empty($attrs['lists_field_layout']) && $attrs['lists_field_layout'] == 'dropdown') {
1472
+ foreach ($lists as $list) {
1473
+
1474
+ $tmp .= '<option value="' . $list->id . '"';
1475
+ if ($list->checked) {
1476
+ $tmp .= ' selected';
 
 
1477
  }
1478
+ $tmp .= '>' . esc_html($list->name) . '</option>';
1479
+ $tmp .= "\n";
1480
  }
1481
  if (!empty($attrs['lists_field_empty_label'])) {
1482
+ $tmp = '<option value="">' . $attrs['lists_field_empty_label'] . '</option>' . $tmp;
1483
  }
1484
+ if (!empty($tmp)) {
1485
+ $tmp = '<select class="tnp-lists" name="nl[]" required>' . $tmp . '</select>';
1486
  }
1487
+ if (!empty($tmp)) {
1488
+ $buffer .= '<div class="tnp-field tnp-lists">';
1489
+ if (!empty($attrs['lists_field_label'])) {
1490
+ $buffer .= '<label>' . $attrs['lists_field_label'] . '</label>';
1491
  }
1492
+ $buffer .= $tmp . '</div>';
 
 
 
 
1493
  }
1494
+ } else {
1495
+
1496
+ foreach ($lists as $list) {
1497
 
1498
+ $tmp .= '<div class="tnp-field tnp-field-list"><label><input class="tnp-preference" type="checkbox" name="nl[]" value="' . $list->id . '"';
1499
+ if ($list->checked) {
1500
+ $tmp .= ' checked';
1501
+ }
1502
+ $tmp .= '/>&nbsp;' . esc_html($list->name) . '</label></div>';
1503
+ }
1504
+ if (!empty($tmp)) {
1505
+ $buffer .= '<div class="tnp-lists">';
1506
+ if (!empty($attrs['lists_field_label'])) {
1507
+ $buffer .= '<label>' . $attrs['lists_field_label'] . '</label>';
1508
+ }
1509
+ $buffer .= $tmp . '</div>';
1510
  }
 
1511
  }
1512
 
1513
  // Extra profile fields
1514
  for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
1515
  // Not for subscription form
1516
+ if ($this->options_profile['profile_' . $i . '_status'] != 2) {
1517
  continue;
1518
  }
1519
 
1520
 
1521
  $buffer .= '<div class="tnp-field tnp-field-profile"><label>' .
1522
+ esc_html($this->options_profile['profile_' . $i]) . '</label>';
1523
 
1524
  // Text field
1525
+ if ($this->options_profile['profile_' . $i . '_type'] == 'text') {
1526
+ $buffer .= '<input class="tnp-profile tnp-profile-' . $i . '" type="text"' . ($this->options_profile['profile_' . $i . '_rules'] == 1 ? ' required' : '') . ' name="np' . $i . '">';
1527
  }
1528
 
1529
  // Select field
1530
+ if ($this->options_profile['profile_' . $i . '_type'] == 'select') {
1531
  $buffer .= '<select class="tnp-profile tnp-profile-' . $i . '" name="np' . $i . '" required>' . "\n";
1532
  $buffer .= "<option></option>\n";
1533
+ $opts = explode(',', $this->options_profile['profile_' . $i . '_options']);
1534
  for ($j = 0; $j < count($opts); $j++) {
1535
  $buffer .= "<option>" . esc_html(trim($opts[$j])) . "</option>\n";
1536
  }
1552
  $buffer .= '<div class="tnp-field tnp-field-' . $name . '"><label>' . $label . "</label>";
1553
  $buffer .= $x['field'] . "</div>\n";
1554
  }
1555
+
1556
+ $privacy_status = (int) $this->options_profile['privacy_status'];
1557
 
1558
  if ($privacy_status === 1 || $privacy_status === 2) {
1559
  $buffer .= '<div class="tnp-field tnp-field-privacy">';
1561
  if ($privacy_status === 1) {
1562
  $buffer .= '<input type="checkbox" name="ny" required class="tnp-privacy">&nbsp;';
1563
  }
1564
+ $url = $this->get_privacy_url();
1565
+ if (!empty($url)) {
1566
+ $buffer .= '<a target="_blank" href="' . esc_attr($url) . '">';
1567
+ $buffer .= esc_attr($this->options_profile['privacy']) . '</a>';
1568
  } else {
1569
+ $buffer .= esc_html($this->options_profile['privacy']);
1570
  }
1571
 
1572
  $buffer .= "</label></div>\n";
1573
+ }
1574
 
1575
  $buffer .= '<div class="tnp-field tnp-field-button">';
1576
 
1577
+ if (strpos($this->options_profile['subscribe'], 'http') === 0) {
1578
+ $buffer .= '<input class="tnp-submit-image" type="image" src="' . esc_attr($this->options_profile['subscribe']) . '">' . "\n";
1579
  } else {
1580
+ $buffer .= '<input class="tnp-submit" type="submit" value="' . esc_attr($this->options_profile['subscribe']) . '">' . "\n";
1581
  }
1582
 
1583
  $buffer .= "</div>\n</form>\n";
1587
  return $buffer;
1588
  }
1589
 
 
 
 
1590
  function get_profile_form($user) {
1591
+ return NewsletterProfile::instance()->get_profile_form($user);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1592
  }
1593
 
1594
  function get_form($number) {
1619
  * @return string
1620
  */
1621
  function replace_lists($buffer) {
 
1622
  $lists = '';
1623
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1624
+ if ($this->options_profile['list_' . $i . '_status'] != 2)
1625
  continue;
1626
+ $lists .= '<input type="checkbox" name="nl[]" value="' . $i . '"/>&nbsp;' . $this->options_profile['list_' . $i] . '<br />';
1627
  }
1628
  $buffer = str_replace('{lists}', $lists, $buffer);
1629
  $buffer = str_replace('{preferences}', $lists, $buffer);
1642
  "last name: " . $user->surname . "\n" .
1643
  "gender: " . $user->sex . "\n";
1644
 
 
 
1645
  for ($i = 0; $i < NEWSLETTER_LIST_MAX; $i++) {
1646
+ if (empty($this->options_profile['list_' . $i])) {
1647
  continue;
1648
  }
1649
  $field = 'list_' . $i;
1650
+ $message .= $this->options_profile['list_' . $i] . ': ' . (empty($user->$field) ? "NO" : "YES") . "\n";
1651
  }
1652
 
1653
  for ($i = 0; $i < NEWSLETTER_PROFILE_MAX; $i++) {
1654
+ if (empty($this->options_profile['profile_' . $i])) {
1655
  continue;
1656
  }
1657
  $field = 'profile_' . $i;
1658
+ $message .= $this->options_profile['profile_' . $i] . ': ' . $user->$field . "\n";
1659
  }
1660
 
1661
 
1671
  }
1672
 
1673
  function get_subscription_form_minimal($attrs) {
1674
+
1675
  if (!is_array($attrs)) {
1676
  $attrs = array();
1677
  }
1678
+ $attrs = array_merge(array('class' => '', 'referrer' => 'minimal', 'button' => $this->options_profile['subscribe'], 'placeholder' => $this->options_profile['email']), $attrs);
1679
 
1680
  $form = '';
1681
  $form .= '<div class="tnp tnp-subscription-minimal ' . $attrs['class'] . '">';
1682
  $form .= '<form action="' . esc_attr(home_url('/')) . '?na=s" method="post">';
1683
+ if (isset($attrs['lists'])) {
1684
+ $arr = explode(',', $attrs['lists']);
1685
+ foreach ($arr as $a) {
1686
+ $form .= "<input type='hidden' name='nl[]' value='" . ((int) trim($a)) . "'>\n";
1687
+ }
1688
+ }
1689
  $form .= '<input type="hidden" name="nr" value="' . esc_attr($attrs['referrer']) . '">';
1690
  $form .= '<input class="tnp-email" type="email" required name="ne" value="" placeholder="' . esc_attr($attrs['placeholder']) . '">';
1691
  $form .= '<input class="tnp-submit" type="submit" value="' . esc_attr($attrs['button']) . '">';
1692
+ if (!empty($this->options_profile['privacy_status'])) {
1693
+ $form .= '<div class="tnp-privacy-field">' . $this->get_privacy_field() . '</div>';
1694
+ }
1695
  $form .= "</form></div>\n";
1696
 
1697
  return $form;
1737
  $user = $module->get_user_from_request();
1738
  $message_key = $module->get_message_key_from_request();
1739
 
1740
+ $message = apply_filters('newsletter_page_text', '', $message_key);
 
 
1741
 
1742
+ if (empty($message)) {
1743
+ $message = $module->options[$message_key . '_text'];
1744
 
1745
+ // TODO: the if can be removed
1746
+ if ($message_key == 'confirmed') {
1747
+ $message .= $module->options[$message_key . '_tracking'];
1748
+ }
 
1749
  }
1750
 
1751
+
1752
  // Now check what form must be added
1753
  if ($message_key == 'subscription') {
1754
 
1777
  $email = NewsletterSubscription::instance()->get_email_from_request();
1778
 
1779
  $message = $newsletter->replace($message, $user, $email, 'page');
1780
+
1781
  $message = do_shortcode($message);
1782
 
1783
  if (isset($_REQUEST['alert'])) {
subscription/template.php CHANGED
@@ -1,6 +1,5 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
 
5
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
@@ -18,32 +17,34 @@ if (!$controls->is_action()) {
18
 
19
  $controls->add_message_saved();
20
  }
 
21
  if ($controls->is_action('reset')) {
22
  $controls->data['template'] = file_get_contents(dirname(__FILE__) . '/email.html');
 
23
  $controls->add_message_done();
24
  }
25
 
26
  if ($controls->is_action('test')) {
27
 
28
- $users = NewsletterUsers::instance()->get_test_users();
29
  if (count($users) == 0) {
30
  $controls->errors = __('No test subscribers found.', 'newsletter') . ' <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="_blank"><i class="fa fa-info-circle"></i></a>';
31
  } else {
32
  $template = $controls->data['template'];
33
- if (strpos($template, '{message}') === false) {
34
- $template .= '{message}';
35
- }
36
  $message = '<p>This is a generic example of message embedded inside the template.</p>';
37
- $message .= '<p>Subscriber data can be referenced by messages with tags. See the <a href="https://www.thenewsletterplugin.com">plugin documentation</a>.</p>';
38
  $message .= '<p>First name: {name}</p>';
39
  $message .= '<p>Last name: {surname}</p>';
40
  $message .= '<p>Email: {email}</p>';
41
-
 
 
42
  $message = str_replace('{message}', $message, $template);
43
  $addresses = array();
44
- foreach ($users as &$user) {
45
  $addresses[] = $user->email;
46
- Newsletter::instance()->mail($user->email, 'Newsletter Messages Template Test', $newsletter->replace($message, $user));
47
  }
48
  $controls->messages .= 'Test emails sent to ' . count($users) . ' test subscribers: ' .
49
  implode(', ', $addresses) . '.' . ' <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="_blank"><i class="fa fa-info-circle"></i></a>';
@@ -52,21 +53,21 @@ if (!$controls->is_action()) {
52
  }
53
  ?>
54
 
55
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.css" type="text/css">
56
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/addon/hint/show-hint.css">
57
  <style>
58
- .CodeMirror {
59
- height: 100%;
60
- }
61
  </style>
62
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.js"></script>
63
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/mode/xml/xml.js"></script>
64
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/mode/css/css.js"></script>
65
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/mode/javascript/javascript.js"></script>
66
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/mode/htmlmixed/htmlmixed.js"></script>
67
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/addon/hint/show-hint.js"></script>
68
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/addon/hint/xml-hint.js"></script>
69
- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/addon/hint/html-hint.js"></script>
70
  <script>
71
  jQuery(function () {
72
  templateEditor = CodeMirror.fromTextArea(document.getElementById("options-template"), {
@@ -97,29 +98,21 @@ if (!$controls->is_action()) {
97
  <?php $controls->init(); ?>
98
  <p>
99
  <?php $controls->button_save(); ?>
 
 
100
  </p>
101
- <table class="form-table">
102
- <tr>
103
- <th>Enabled?</th>
104
- <td>
105
- <?php $controls->yesno('enabled'); ?>
106
- <p class="description">
107
- When not enabled, the old templating system is used (see the file
108
- wp-content/plugins/newsletter/subscription/email.php).
109
- </p>
110
- </td>
111
- </tr>
112
- </table>
113
-
114
- <h3><?php _e('Template', 'newsletter')?></h3>
115
-
116
- <?php $controls->textarea_preview('template', '100%', '700px'); ?>
117
- <br><br>
118
- <?php $controls->button_reset(); ?>
119
- <?php $controls->button('test', 'Send a test'); ?>
120
-
121
  <p>
122
  <?php $controls->button_save(); ?>
 
 
123
  </p>
124
  </form>
125
  </div>
1
  <?php
2
+ defined('ABSPATH') || exit;
 
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
17
 
18
  $controls->add_message_saved();
19
  }
20
+
21
  if ($controls->is_action('reset')) {
22
  $controls->data['template'] = file_get_contents(dirname(__FILE__) . '/email.html');
23
+ $module->save_options($controls->data, 'template');
24
  $controls->add_message_done();
25
  }
26
 
27
  if ($controls->is_action('test')) {
28
 
29
+ $users = $module->get_test_users();
30
  if (count($users) == 0) {
31
  $controls->errors = __('No test subscribers found.', 'newsletter') . ' <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="_blank"><i class="fa fa-info-circle"></i></a>';
32
  } else {
33
  $template = $controls->data['template'];
34
+
 
 
35
  $message = '<p>This is a generic example of message embedded inside the template.</p>';
36
+ $message .= '<p>Subscriber data can be referenced using tags. See the <a href="https://www.thenewsletterplugin.com/documentation">plugin documentation</a>.</p>';
37
  $message .= '<p>First name: {name}</p>';
38
  $message .= '<p>Last name: {surname}</p>';
39
  $message .= '<p>Email: {email}</p>';
40
+ $message .= '<p>Here an image as well. Make them styled with the CSS rule "max-width: 100%"</p>';
41
+ $message .= '<p><img src="' . plugins_url('newsletter') . '/images/test.jpg" style="max-width: 100%"></p>';
42
+
43
  $message = str_replace('{message}', $message, $template);
44
  $addresses = array();
45
+ foreach ($users as $user) {
46
  $addresses[] = $user->email;
47
+ Newsletter::instance()->mail($user->email, 'Newsletter Messages Template Test', $module->replace($message, $user));
48
  }
49
  $controls->messages .= 'Test emails sent to ' . count($users) . ' test subscribers: ' .
50
  implode(', ', $addresses) . '.' . ' <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="_blank"><i class="fa fa-info-circle"></i></a>';
53
  }
54
  ?>
55
 
56
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/codemirror.css" type="text/css">
57
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/hint/show-hint.css">
58
  <style>
59
+ .CodeMirror {
60
+ height: 100%;
61
+ }
62
  </style>
63
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/codemirror.js"></script>
64
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/xml/xml.js"></script>
65
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/css/css.js"></script>
66
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/javascript/javascript.js"></script>
67
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/htmlmixed/htmlmixed.js"></script>
68
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/hint/show-hint.js"></script>
69
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/hint/xml-hint.js"></script>
70
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/hint/html-hint.js"></script>
71
  <script>
72
  jQuery(function () {
73
  templateEditor = CodeMirror.fromTextArea(document.getElementById("options-template"), {
98
  <?php $controls->init(); ?>
99
  <p>
100
  <?php $controls->button_save(); ?>
101
+ <?php $controls->button_reset(); ?>
102
+ <?php $controls->button('test', 'Send a test'); ?>
103
  </p>
104
+
105
+
106
+ <h3><?php _e('Template', 'newsletter') ?></h3>
107
+
108
+ <?php $controls->textarea_preview('template', '100%', '700px'); ?>
109
+ <br><br>
110
+
111
+
 
 
 
 
 
 
 
 
 
 
 
 
112
  <p>
113
  <?php $controls->button_save(); ?>
114
+ <?php $controls->button_reset(); ?>
115
+ <?php $controls->button('test', 'Send a test'); ?>
116
  </p>
117
  </form>
118
  </div>
subscription/unsubscription.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
 
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
@@ -53,19 +54,8 @@ if (!$controls->is_action()) {
53
 
54
  <div id="tnp-heading">
55
 
56
- <h2>Unsubscription</h2>
57
-
58
- <p>
59
- A user starts the cancellation process clicking the unsubscription link in
60
- a newsletter. This link contains the email to unsubscribe and some unique information
61
- to avoid hacking. The user are required to confirm the unsubscription: this is the last
62
- step where YOU can communicate with your almost missed user.
63
- </p>
64
- <p>
65
- To create immediate cancellation, you can use the <strong>{unsubscription_confirm_url}</strong>
66
- in your newsletters and upon click on that link goodbye message and email are used directly
67
- skipping the confirm request.
68
- </p>
69
 
70
  </div>
71
 
@@ -73,51 +63,70 @@ if (!$controls->is_action()) {
73
 
74
  <form method="post" action="">
75
  <?php $controls->init(); ?>
76
-
77
- <table class="form-table">
78
- <tr>
79
- <th><?php _e('Unsubscription message', 'newsletter') ?></th>
80
- <td>
81
- <?php $controls->wp_editor('unsubscription_text'); ?>
82
- <p class="description">
83
- This text is show to users who click on a "unsubscription link" in a newsletter
84
- email. You <strong>must</strong> insert a link in the text that user can follow to confirm the
85
- unsubscription request using the tag <strong>{unsubscription_confirm_url}</strong>.
86
- </p>
87
- </td>
88
- </tr>
89
-
90
- <tr>
91
- <th><?php _e('Goodbye message', 'newsletter') ?></th>
92
- <td>
93
- <?php $controls->wp_editor('unsubscribed_text'); ?>
94
- <p class="description">
95
- Shown to users after the cancellation has been completed.
96
- </p>
97
- </td>
98
- </tr>
99
-
100
- <tr>
101
- <th><?php _e('Goodbye email', 'newsletter') ?></th>
102
- <td>
103
- <?php $controls->email('unsubscribed', 'wordpress', true); ?>
104
- <p class="description">
105
- Sent after a cancellation, is the last message you send to the user before his removal
106
- from your newsletter subscribers.
107
- </p>
108
- </td>
109
- </tr>
110
- <tr>
111
- <th>Unsubscription error</th>
112
- <td>
113
- <?php $controls->wp_editor('unsubscription_error_text'); ?>
114
- <p class="description">
115
- When the unsubscription cannot be completed, for example because the
116
- subscriber has already been removed.
117
- </p>
118
- </td>
119
- </tr>
120
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
  <p>
123
  <?php $controls->button_save() ?>
1
  <?php
2
+ if (!defined('ABSPATH'))
3
+ exit;
4
 
5
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
54
 
55
  <div id="tnp-heading">
56
 
57
+ <h2><?php _e('Cancellation', 'newsletter')?></h2>
58
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/documentation/cancellation')?>
 
 
 
 
 
 
 
 
 
 
 
59
 
60
  </div>
61
 
63
 
64
  <form method="post" action="">
65
  <?php $controls->init(); ?>
66
+ <p>
67
+ <?php $controls->button_save() ?>
68
+ <?php $controls->button_reset() ?>
69
+ </p>
70
+ <div id="tabs">
71
+ <ul>
72
+ <li><a href="#tabs-cancellation"><?php _e('Cancellation', 'newsletter') ?></a></li>
73
+ <li><a href="#tabs-reactivation"><?php _e('Reactivation', 'newsletter') ?></a></li>
74
+
75
+ </ul>
76
+ <div id="tabs-cancellation">
77
+ <table class="form-table">
78
+ <tr>
79
+ <th><?php _e('Cancellation message', 'newsletter') ?></th>
80
+ <td>
81
+ <?php $controls->wp_editor('unsubscription_text', array('editor_height'=>250)); ?>
82
+ <p class="description">
83
+ </p>
84
+ </td>
85
+ </tr>
86
+
87
+ <tr>
88
+ <th><?php _e('Goodbye message', 'newsletter') ?></th>
89
+ <td>
90
+ <?php $controls->wp_editor('unsubscribed_text', array('editor_height'=>250)); ?>
91
+ <p class="description">
92
+ </p>
93
+ </td>
94
+ </tr>
95
+
96
+ <tr>
97
+ <th><?php _e('Goodbye email', 'newsletter') ?></th>
98
+ <td>
99
+ <?php $controls->email('unsubscribed', 'wordpress', true, array('editor_height'=>250)); ?>
100
+ <p class="description">
101
+
102
+ </p>
103
+ </td>
104
+ </tr>
105
+ <tr>
106
+ <th>Unsubscription error</th>
107
+ <td>
108
+ <?php $controls->wp_editor('unsubscription_error_text', array('editor_height'=>250)); ?>
109
+ <p class="description">
110
+
111
+ </p>
112
+ </td>
113
+ </tr>
114
+ </table>
115
+ </div>
116
+
117
+ <div id="tabs-reactivation">
118
+ <table class="form-table">
119
+ <tr>
120
+ <th><?php _e('Reactivated message', 'newsletter') ?></th>
121
+ <td>
122
+ <?php $controls->wp_editor('reactivated_text', array('editor_height'=>250)); ?>
123
+ <p class="description">
124
+ </p>
125
+ </td>
126
+ </tr>
127
+ </table>
128
+ </div>
129
+ </div>
130
 
131
  <p>
132
  <?php $controls->button_save() ?>
tnp-header.php CHANGED
@@ -1,8 +1,7 @@
1
  <?php
2
- global $current_user, $wpdb, $newsletter;
3
 
4
- if (!defined('ABSPATH'))
5
- exit;
6
 
7
  $dismissed = get_option('newsletter_dismissed', array());
8
 
@@ -16,7 +15,7 @@ function newsletter_print_entries($group) {
16
  echo $entry['url'];
17
  echo '">';
18
  echo $entry['label'];
19
- if (isset($entry['description'])) {
20
  echo '<small>';
21
  echo $entry['description'];
22
  echo '</small>';
@@ -31,7 +30,6 @@ $status_options = Newsletter::instance()->get_options('status');
31
  $warning = false;
32
 
33
  $warning |= empty($status_options['mail']);
34
-
35
  ?>
36
 
37
  <div class="tnp-drowpdown" id="tnp-header">
@@ -41,6 +39,9 @@ $warning |= empty($status_options['mail']);
41
  <ul>
42
  <li><a href="?page=newsletter_users_index"><i class="fa fa-search"></i> <?php _e('Search And Edit', 'newsletter') ?>
43
  <small><?php _e('Add, edit, search', 'newsletter') ?></small></a></li>
 
 
 
44
  <li><a href="?page=newsletter_users_import"><i class="fa fa-upload"></i> <?php _e('Import', 'newsletter') ?>
45
  <small><?php _e('Import from external sources', 'newsletter') ?></small></a></li>
46
  <li><a href="?page=newsletter_users_export"><i class="fa fa-download"></i> <?php _e('Export', 'newsletter') ?>
@@ -58,7 +59,7 @@ $warning |= empty($status_options['mail']);
58
  <ul>
59
  <li><a href="?page=newsletter_subscription_options"><i class="fa fa-sign-in"></i> <?php _e('Subscription', 'newsletter') ?>
60
  <small><?php _e('The subscription process in detail', 'newsletter') ?></small></a></li>
61
-
62
  <li><a href="?page=newsletter_subscription_antibot"><i class="fa fa-lock"></i> <?php _e('Security', 'newsletter') ?>
63
  <small><?php _e('Spam subscriptions control', 'newsletter') ?></small></a></li>
64
 
@@ -79,10 +80,7 @@ $warning |= empty($status_options['mail']);
79
  <a href="?page=newsletter_subscription_forms"><i class="fa fa-pencil"></i> <?php _e('Custom Forms', 'newsletter') ?>
80
  <small><?php _e('Hand coded form storage', 'newsletter') ?></small></a>
81
  </li>
82
- <li>
83
- <a href="?page=newsletter_subscription_template"><i class="fa fa-file-text-o"></i> <?php _e('Messages Template', 'newsletter') ?>
84
- <small><?php _e('Change the look of your service emails', 'newsletter') ?></small></a>
85
- </li>
86
  <?php
87
  newsletter_print_entries('subscription');
88
  ?>
@@ -105,13 +103,16 @@ $warning |= empty($status_options['mail']);
105
  <small><?php _e('Delivery speed, sender details, ...', 'newsletter') ?></small></a></li>
106
  <li><a href="?page=newsletter_main_info"><i class="fa fa-info"></i> <?php _e('Company Info', 'newsletter') ?>
107
  <small><?php _e('Social, address, logo and general info', 'newsletter') ?></small></a></li>
108
-
109
- <?php if (!class_exists('NewsletterSmtp')) { ?>
110
  <li>
111
- <a href="?page=newsletter_main_smtp"><i class="fa fa-envelope-o"></i> <?php _e('SMTP', 'newsletter') ?>
112
- <small><?php _e('External mail server', 'newsletter') ?></small>
113
- </a>
114
  </li>
 
 
 
 
 
 
115
  <?php } ?>
116
 
117
  <?php
@@ -122,9 +123,9 @@ $warning |= empty($status_options['mail']);
122
 
123
  <li>
124
  <a href="?page=newsletter_main_status"><i class="fa fa-thermometer"></i> <?php _e('Status', 'newsletter') ?>
125
- <?php if ($warning) { ?>
126
- <i class="fa fa-exclamation-triangle" style="color: red;"></i>
127
- <?php } ?>
128
  </a>
129
  </li>
130
 
@@ -153,6 +154,13 @@ $warning |= empty($status_options['mail']);
153
  </ul>
154
  </div>
155
 
 
 
 
 
 
 
 
156
 
157
  <?php if (isset($_GET['debug']) || !isset($dismissed['rate']) && $user_count > 300) { ?>
158
  <div class="tnp-notice">
@@ -164,7 +172,7 @@ $warning |= empty($status_options['mail']);
164
  </div>
165
  <?php } ?>
166
 
167
- <?php if (isset($_GET['debug']) || !isset($dismissed['newsletter-page']) && empty(NewsletterSubscription::instance()->options['page'])) { ?>
168
  <div class="tnp-notice">
169
  <a href="<?php echo $_SERVER['REQUEST_URI'] . '&noheader=1&dismiss=newsletter-page' ?>" class="tnp-dismiss">&times;</a>
170
 
1
  <?php
2
+ global $current_user, $wpdb;
3
 
4
+ defined('ABSPATH') || exit;
 
5
 
6
  $dismissed = get_option('newsletter_dismissed', array());
7
 
15
  echo $entry['url'];
16
  echo '">';
17
  echo $entry['label'];
18
+ if (!empty($entry['description'])) {
19
  echo '<small>';
20
  echo $entry['description'];
21
  echo '</small>';
30
  $warning = false;
31
 
32
  $warning |= empty($status_options['mail']);
 
33
  ?>
34
 
35
  <div class="tnp-drowpdown" id="tnp-header">
39
  <ul>
40
  <li><a href="?page=newsletter_users_index"><i class="fa fa-search"></i> <?php _e('Search And Edit', 'newsletter') ?>
41
  <small><?php _e('Add, edit, search', 'newsletter') ?></small></a></li>
42
+
43
+ <li><a href="?page=newsletter_profile_index"><i class="fa fa-user-circle-o"></i> <?php _e('Profile page', 'newsletter') ?>
44
+ <small><?php _e('The subscriber personal profile editing panel', 'newsletter') ?></small></a></li>
45
  <li><a href="?page=newsletter_users_import"><i class="fa fa-upload"></i> <?php _e('Import', 'newsletter') ?>
46
  <small><?php _e('Import from external sources', 'newsletter') ?></small></a></li>
47
  <li><a href="?page=newsletter_users_export"><i class="fa fa-download"></i> <?php _e('Export', 'newsletter') ?>
59
  <ul>
60
  <li><a href="?page=newsletter_subscription_options"><i class="fa fa-sign-in"></i> <?php _e('Subscription', 'newsletter') ?>
61
  <small><?php _e('The subscription process in detail', 'newsletter') ?></small></a></li>
62
+
63
  <li><a href="?page=newsletter_subscription_antibot"><i class="fa fa-lock"></i> <?php _e('Security', 'newsletter') ?>
64
  <small><?php _e('Spam subscriptions control', 'newsletter') ?></small></a></li>
65
 
80
  <a href="?page=newsletter_subscription_forms"><i class="fa fa-pencil"></i> <?php _e('Custom Forms', 'newsletter') ?>
81
  <small><?php _e('Hand coded form storage', 'newsletter') ?></small></a>
82
  </li>
83
+
 
 
 
84
  <?php
85
  newsletter_print_entries('subscription');
86
  ?>
103
  <small><?php _e('Delivery speed, sender details, ...', 'newsletter') ?></small></a></li>
104
  <li><a href="?page=newsletter_main_info"><i class="fa fa-info"></i> <?php _e('Company Info', 'newsletter') ?>
105
  <small><?php _e('Social, address, logo and general info', 'newsletter') ?></small></a></li>
 
 
106
  <li>
107
+ <a href="?page=newsletter_subscription_template"><i class="fa fa-file-text-o"></i> <?php _e('Messages Template', 'newsletter') ?>
108
+ <small><?php _e('Change the look of your service emails', 'newsletter') ?></small></a>
 
109
  </li>
110
+ <?php if (!class_exists('NewsletterSmtp')) { ?>
111
+ <li>
112
+ <a href="?page=newsletter_main_smtp"><i class="fa fa-envelope-o"></i> <?php _e('SMTP', 'newsletter') ?>
113
+ <small><?php _e('External mail server', 'newsletter') ?></small>
114
+ </a>
115
+ </li>
116
  <?php } ?>
117
 
118
  <?php
123
 
124
  <li>
125
  <a href="?page=newsletter_main_status"><i class="fa fa-thermometer"></i> <?php _e('Status', 'newsletter') ?>
126
+ <?php if ($warning) { ?>
127
+ <i class="fa fa-exclamation-triangle" style="color: red;"></i>
128
+ <?php } ?>
129
  </a>
130
  </li>
131
 
154
  </ul>
155
  </div>
156
 
157
+ <?php if (!empty(Newsletter::instance()->options['page']) && (!get_permalink(Newsletter::instance()->options['page']) || get_post_status(Newsletter::instance()->options['page']) != 'publish')) { ?>
158
+ <div class="tnp-error">
159
+ <?php _e('The Newsletter dedicated page is wrongly configured.', 'newsletter') ?>
160
+ <a href="admin.php?page=newsletter_main_main"><?php _e('Check it now', 'newsletter')?></a>.
161
+ </div>
162
+ <?php } ?>
163
+
164
 
165
  <?php if (isset($_GET['debug']) || !isset($dismissed['rate']) && $user_count > 300) { ?>
166
  <div class="tnp-notice">
172
  </div>
173
  <?php } ?>
174
 
175
+ <?php if (isset($_GET['debug']) || !isset($dismissed['newsletter-page']) && empty(Newsletter::instance()->options['page'])) { ?>
176
  <div class="tnp-notice">
177
  <a href="<?php echo $_SERVER['REQUEST_URI'] . '&noheader=1&dismiss=newsletter-page' ?>" class="tnp-dismiss">&times;</a>
178
 
users/edit.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
 
5
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
7
  $module = NewsletterUsers::instance();
8
 
9
  $id = (int) $_GET['id'];
 
10
 
11
  if ($controls->is_action('save')) {
12
 
@@ -19,8 +19,8 @@ if ($controls->is_action('save')) {
19
 
20
 
21
  if (empty($controls->errors)) {
22
- $user = $module->get_user($controls->data['email']);
23
- if ($user && $user->id != $id) {
24
  $controls->errors = __('The email address is already in use', 'newsletter');
25
  }
26
  }
@@ -38,12 +38,13 @@ if ($controls->is_action('save')) {
38
  }
39
 
40
  $controls->data['id'] = $id;
41
- $r = $module->save_user($controls->data);
42
- if ($r === false) {
 
43
  $controls->errors = __('Error. Check the log files.', 'newsletter');
44
  } else {
45
  $controls->add_message_saved();
46
- $controls->data = $module->get_user($id, ARRAY_A);
47
  }
48
  }
49
  }
@@ -55,22 +56,22 @@ if ($controls->is_action('delete')) {
55
  }
56
 
57
  if (!$controls->is_action()) {
58
- $controls->data = $module->get_user($id, ARRAY_A);
59
  }
60
 
61
- $options_profile = get_option('newsletter_profile');
62
-
63
- $panels = Newsletter::instance()->panels;
64
 
65
  function percent($value, $total) {
66
- if ($total == 0)
67
  return '-';
 
68
  return sprintf("%.2f", $value / $total * 100) . '%';
69
  }
70
 
71
  function percentValue($value, $total) {
72
- if ($total == 0)
73
  return 0;
 
74
  return round($value / $total * 100);
75
  }
76
  ?>
@@ -102,12 +103,12 @@ function percentValue($value, $total) {
102
  <div id="tabs">
103
 
104
  <ul>
105
- <li><a href="#tabs-general">General</a></li>
106
- <li><a href="#tabs-preferences">Lists</a></li>
107
- <li><a href="#tabs-profile">Profile</a></li>
108
- <li><a href="#tabs-other">Other</a></li>
109
- <li><a href="#tabs-newsletters">Newsletters</a></li>
110
- <li><a href="#tabs-history">History</a></li>
111
 
112
  </ul>
113
 
@@ -120,7 +121,7 @@ function percentValue($value, $total) {
120
  <tr>
121
  <th><?php _e ('Email', 'newsletter'); ?></th>
122
  <td>
123
- <?php $controls->text('email', 60); ?>
124
  </td>
125
  </tr>
126
  <tr>
@@ -244,7 +245,7 @@ function percentValue($value, $total) {
244
  <tr>
245
  <th><?php _e ('Profile URL', 'newsletter'); ?></th>
246
  <td>
247
- <?php $profile_url = esc_html(home_url('/') . '?na=pe&nk=' . $id . '-' . $controls->data['token']); ?>
248
  <a href='<?php echo $profile_url ?>' target="_blank"><?php echo $profile_url ?></a>
249
  </td>
250
  </tr>
@@ -252,7 +253,6 @@ function percentValue($value, $total) {
252
  </table>
253
  </div>
254
  <div id="tabs-newsletters" class="tnp-tab">
255
- <p>Newsletter sent to this subscriber.</p>
256
  <?php if (!has_action('newsletter_user_newsletters_tab') && !has_action('newsletter_users_edit_newsletters')) { ?>
257
  <div class="tnp-tab-notice">
258
  This panel requires the <a href="https://www.thenewsletterplugin.com/plugins/newsletter/reports-module" target="_blank">Reports Extension 4+</a>.
@@ -270,33 +270,32 @@ function percentValue($value, $total) {
270
  $logs = $wpdb->get_results($wpdb->prepare("select * from {$wpdb->prefix}newsletter_user_logs where user_id=%d order by id desc", $id));
271
  ?>
272
  <?php if (empty($logs)) { ?>
273
- <p>No logs available</p>;
274
  <?php } else { ?>
 
275
  <table class="widefat" style="width: auto">
276
  <thead>
277
  <tr>
278
  <th>Date</th>
279
- <th>Old data</th>
280
- <th>New data</th>
281
  </tr>
282
 
283
  <tbody>
284
  <?php foreach ($logs as $log) { ?>
285
  <?php
286
  $data = json_decode($log->data, ARRAY_A);
 
287
  ?>
288
  <tr>
289
  <td><?php echo $controls->print_date($log->created)?></td>
 
290
  <td>
291
  <?php
292
- foreach ($data['old'] as $key=>$value) {
 
293
  echo esc_html(str_replace('_', ' ', $key)), ': ', esc_html($value) . '<br>';
294
  }
295
- ?>
296
- </td>
297
- <td><?php
298
- foreach ($data['new'] as $key=>$value) {
299
- echo esc_html(str_replace('_', ' ', $key)), ': ', esc_html($value) . '<br>';
300
  }
301
  ?>
302
  </td>
@@ -310,14 +309,6 @@ function percentValue($value, $total) {
310
 
311
  </div>
312
 
313
- <?php
314
- if (isset($panels['user_edit'])) {
315
- foreach ($panels['user_edit'] as $panel) {
316
- call_user_func($panel['callback'], $id, $controls);
317
- }
318
- }
319
- ?>
320
-
321
  </div>
322
 
323
  <p>
1
  <?php
2
+ defined('ABSPATH') || exit;
 
3
 
4
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
6
  $module = NewsletterUsers::instance();
7
 
8
  $id = (int) $_GET['id'];
9
+ $user = $module->get_user($id);
10
 
11
  if ($controls->is_action('save')) {
12
 
19
 
20
 
21
  if (empty($controls->errors)) {
22
+ $u = $module->get_user($controls->data['email']);
23
+ if ($u && $u->id != $id) {
24
  $controls->errors = __('The email address is already in use', 'newsletter');
25
  }
26
  }
38
  }
39
 
40
  $controls->data['id'] = $id;
41
+ $user = $module->save_user($controls->data);
42
+ $module->add_user_log($user, 'edit');
43
+ if ($user === false) {
44
  $controls->errors = __('Error. Check the log files.', 'newsletter');
45
  } else {
46
  $controls->add_message_saved();
47
+ $controls->data = (array)$user;
48
  }
49
  }
50
  }
56
  }
57
 
58
  if (!$controls->is_action()) {
59
+ $controls->data = (array)$user;
60
  }
61
 
62
+ $options_profile = NewsletterSubscription::instance()->get_options('profile');
 
 
63
 
64
  function percent($value, $total) {
65
+ if ($total == 0) {
66
  return '-';
67
+ }
68
  return sprintf("%.2f", $value / $total * 100) . '%';
69
  }
70
 
71
  function percentValue($value, $total) {
72
+ if ($total == 0) {
73
  return 0;
74
+ }
75
  return round($value / $total * 100);
76
  }
77
  ?>
103
  <div id="tabs">
104
 
105
  <ul>
106
+ <li><a href="#tabs-general"><?php _e('General', 'newsletter')?></a></li>
107
+ <li><a href="#tabs-preferences"><?php _e('Lists', 'newsletter')?></a></li>
108
+ <li><a href="#tabs-profile"><?php _e('Extra fields', 'newsletter')?></a></li>
109
+ <li><a href="#tabs-other"><?php _e('Other', 'newsletter')?></a></li>
110
+ <li><a href="#tabs-newsletters"><?php _e('Newsletters', 'newsletter')?></a></li>
111
+ <li><a href="#tabs-history"><?php _e('Logs', 'newsletter')?></a></li>
112
 
113
  </ul>
114
 
121
  <tr>
122
  <th><?php _e ('Email', 'newsletter'); ?></th>
123
  <td>
124
+ <?php $controls->text_email('email', 60); ?>
125
  </td>
126
  </tr>
127
  <tr>
245
  <tr>
246
  <th><?php _e ('Profile URL', 'newsletter'); ?></th>
247
  <td>
248
+ <?php $profile_url = NewsletterProfile::instance()->get_profile_url($user) ?>
249
  <a href='<?php echo $profile_url ?>' target="_blank"><?php echo $profile_url ?></a>
250
  </td>
251
  </tr>
253
  </table>
254
  </div>
255
  <div id="tabs-newsletters" class="tnp-tab">
 
256
  <?php if (!has_action('newsletter_user_newsletters_tab') && !has_action('newsletter_users_edit_newsletters')) { ?>
257
  <div class="tnp-tab-notice">
258
  This panel requires the <a href="https://www.thenewsletterplugin.com/plugins/newsletter/reports-module" target="_blank">Reports Extension 4+</a>.
270
  $logs = $wpdb->get_results($wpdb->prepare("select * from {$wpdb->prefix}newsletter_user_logs where user_id=%d order by id desc", $id));
271
  ?>
272
  <?php if (empty($logs)) { ?>
273
+ <p>No logs available</p>
274
  <?php } else { ?>
275
+ <p>Only public lists are recorded.</p>
276
  <table class="widefat" style="width: auto">
277
  <thead>
278
  <tr>
279
  <th>Date</th>
280
+ <th>Source</th>
281
+ <th>Lists</th>
282
  </tr>
283
 
284
  <tbody>
285
  <?php foreach ($logs as $log) { ?>
286
  <?php
287
  $data = json_decode($log->data, ARRAY_A);
288
+ if (isset($data['new'])) $data = $data['new'];
289
  ?>
290
  <tr>
291
  <td><?php echo $controls->print_date($log->created)?></td>
292
+ <td><?php echo esc_html($log->source)?></td>
293
  <td>
294
  <?php
295
+ if (is_array($data)) {
296
+ foreach ($data as $key=>$value) {
297
  echo esc_html(str_replace('_', ' ', $key)), ': ', esc_html($value) . '<br>';
298
  }
 
 
 
 
 
299
  }
300
  ?>
301
  </td>
309
 
310
  </div>
311
 
 
 
 
 
 
 
 
 
312
  </div>
313
 
314
  <p>
users/export.php CHANGED
@@ -5,13 +5,6 @@ $options_profile = get_option('newsletter_profile');
5
  $controls = new NewsletterControls();
6
  $module = NewsletterUsers::instance();
7
 
8
- $lists = array('0' => 'All');
9
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
10
- if (!isset($options_profile['list_' . $i])) {
11
- $options_profile['list_' . $i] = '';
12
- }
13
- $lists['' . $i] = '(' . $i . ') ' . $options_profile['list_' . $i];
14
- }
15
  ?>
16
 
17
  <div class="wrap" id="tnp-wrap">
@@ -44,7 +37,7 @@ for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
44
  <tr>
45
  <th><?php _e('List', 'newsletter') ?></th>
46
  <td>
47
- <?php $controls->select('list', $lists); ?>
48
  </td>
49
  </tr>
50
  </table>
5
  $controls = new NewsletterControls();
6
  $module = NewsletterUsers::instance();
7
 
 
 
 
 
 
 
 
8
  ?>
9
 
10
  <div class="wrap" id="tnp-wrap">
37
  <tr>
38
  <th><?php _e('List', 'newsletter') ?></th>
39
  <td>
40
+ <?php $controls->lists_select('list'); ?>
41
  </td>
42
  </tr>
43
  </table>
users/images/map.png DELETED
Binary file
users/index.php CHANGED
@@ -1,6 +1,5 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
 
5
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
 
@@ -8,7 +7,6 @@ $controls = new NewsletterControls();
8
  $module = NewsletterUsers::instance();
9
 
10
  $options = $controls->data;
11
- $options_lists = get_option('newsletter_profile');
12
  $options_profile = get_option('newsletter_profile');
13
  $options_main = get_option('newsletter_main');
14
 
@@ -26,13 +24,6 @@ if ($controls->is_action()) {
26
  $controls->data['search_page'] = 0;
27
  }
28
 
29
- $lists = array('' => 'Any List');
30
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
31
- if (empty($options_lists['list_' . $i]))
32
- continue;
33
- $lists['' . $i] = '(' . $i . ') ' . $options_lists['list_' . $i];
34
- }
35
-
36
  if ($controls->is_action('resend')) {
37
  $user = NewsletterUsers::instance()->get_user($controls->button_data);
38
  $opts = get_option('newsletter');
@@ -48,7 +39,7 @@ if ($controls->is_action('resend_welcome')) {
48
  }
49
 
50
  if ($controls->is_action('remove')) {
51
- $wpdb->query($wpdb->prepare("delete from " . NEWSLETTER_USERS_TABLE . " where id=%d", (int) $controls->button_data));
52
  unset($controls->data['subscriber_id']);
53
  }
54
 
@@ -63,10 +54,6 @@ if ($text) {
63
  $where .= " and (email like %s or name like %s or surname like %s)";
64
  }
65
 
66
- //if (isset($controls->data['search_test'])) {
67
- // $where .= " and test=1";
68
- //}
69
-
70
  if (!empty($controls->data['search_status'])) {
71
  if ($controls->data['search_status'] == 'T') {
72
  $where .= " and test=1";
@@ -144,7 +131,7 @@ $controls->data['search_page'] ++;
144
 
145
  <?php _e('filter by', 'newsletter') ?>:
146
  <?php $controls->select('search_status', array('' => 'Any status', 'T' => 'Test subscribers', 'C' => 'Confirmed', 'S' => 'Not confirmed', 'U' => 'Unsubscribed', 'B' => 'Bounced')); ?>
147
- <?php $controls->select('search_list', $lists); ?>
148
 
149
  <?php $controls->button('search', __('Search', 'newsletter')); ?>
150
  <?php if ($where != "where 1=1") { ?>
@@ -221,12 +208,11 @@ $controls->data['search_page'] ++;
221
  <td>
222
  <small>
223
  <?php
224
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
225
- if (!isset($lists['' . $i]))
226
- continue;
227
- $l = 'list_' . $i;
228
  if ($s->$l == 1)
229
- echo esc_html($lists['' . $i]) . '<br />';
230
  }
231
  ?>
232
  </small>
@@ -237,13 +223,13 @@ $controls->data['search_page'] ++;
237
  <a class="button-secondary" href="<?php echo $module->get_admin_page_url('edit'); ?>&amp;id=<?php echo $s->id; ?>"><?php _e('Edit', 'newsletter') ?></a>
238
  </td>
239
  <td>
240
- <?php $controls->button_confirm('remove', __('Remove', 'newsletter'), __('Proceed?', 'newsletter'), $s->id); ?>
241
  </td>
242
  <td style="text-align: center">
243
  <?php if ($s->status == "C") { ?>
244
- <?php $controls->button_confirm('resend_welcome', __('Resend welcome', 'newsletter'), __('Proceed?', 'newsletter'), $s->id); ?>
245
  <?php } else { ?>
246
- <?php $controls->button_confirm('resend', __('Resend activation', 'newsletter'), __('Proceed?', 'newsletter'), $s->id); ?>
247
  <?php } ?>
248
  </td>
249
 
1
  <?php
2
+ defined('ABSPATH') || exit;
 
3
 
4
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
 
7
  $module = NewsletterUsers::instance();
8
 
9
  $options = $controls->data;
 
10
  $options_profile = get_option('newsletter_profile');
11
  $options_main = get_option('newsletter_main');
12
 
24
  $controls->data['search_page'] = 0;
25
  }
26
 
 
 
 
 
 
 
 
27
  if ($controls->is_action('resend')) {
28
  $user = NewsletterUsers::instance()->get_user($controls->button_data);
29
  $opts = get_option('newsletter');
39
  }
40
 
41
  if ($controls->is_action('remove')) {
42
+ $module->delete_user($controls->button_data);
43
  unset($controls->data['subscriber_id']);
44
  }
45
 
54
  $where .= " and (email like %s or name like %s or surname like %s)";
55
  }
56
 
 
 
 
 
57
  if (!empty($controls->data['search_status'])) {
58
  if ($controls->data['search_status'] == 'T') {
59
  $where .= " and test=1";
131
 
132
  <?php _e('filter by', 'newsletter') ?>:
133
  <?php $controls->select('search_status', array('' => 'Any status', 'T' => 'Test subscribers', 'C' => 'Confirmed', 'S' => 'Not confirmed', 'U' => 'Unsubscribed', 'B' => 'Bounced')); ?>
134
+ <?php $controls->lists_select('search_list', '-'); ?>
135
 
136
  <?php $controls->button('search', __('Search', 'newsletter')); ?>
137
  <?php if ($where != "where 1=1") { ?>
208
  <td>
209
  <small>
210
  <?php
211
+ $lists = $module->get_lists();
212
+ foreach ($lists as $item) {
213
+ $l = 'list_' . $item->id;
 
214
  if ($s->$l == 1)
215
+ echo esc_html($item->name) . '<br>';
216
  }
217
  ?>
218
  </small>
223
  <a class="button-secondary" href="<?php echo $module->get_admin_page_url('edit'); ?>&amp;id=<?php echo $s->id; ?>"><?php _e('Edit', 'newsletter') ?></a>
224
  </td>
225
  <td>
226
+ <?php $controls->button_confirm('remove', __('Remove', 'newsletter'), '', $s->id); ?>
227
  </td>
228
  <td style="text-align: center">
229
  <?php if ($s->status == "C") { ?>
230
+ <?php $controls->button_confirm('resend_welcome', __('Resend welcome', 'newsletter'), '', $s->id); ?>
231
  <?php } else { ?>
232
+ <?php $controls->button_confirm('resend', __('Resend activation', 'newsletter'), '', $s->id); ?>
233
  <?php } ?>
234
  </td>
235
 
users/massive.php CHANGED
@@ -8,15 +8,6 @@ defined('ABSPATH') || exit;
8
  $controls = new NewsletterControls();
9
  $module = NewsletterUsers::instance();
10
 
11
- $options_profile = get_option('newsletter_profile');
12
-
13
- $lists = array();
14
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
15
- if (!isset($options_profile['list_' . $i]))
16
- $options_profile['list_' . $i] = '';
17
- $lists['' . $i] = '(' . $i . ') ' . $options_profile['list_' . $i];
18
- }
19
-
20
  if ($controls->is_action('remove_unconfirmed')) {
21
  $r = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where status='S'");
22
  $controls->messages = __('Subscribers not confirmed deleted: ', 'newsletter') . $r . '.';
@@ -59,8 +50,9 @@ if ($controls->is_action('list_remove')) {
59
 
60
  if ($controls->is_action('list_delete')) {
61
  $count = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where list_" . ((int) $controls->data['list']) . "<>0");
62
- $wpdb->query("delete s from `{$wpdb->prefix}newsletter_sent` s left join `{$wpdb->prefix}newsletter` u on s.user_id=u.id where u.id is null");
63
- $wpdb->query("delete s from `{$wpdb->prefix}newsletter_stats` s left join `{$wpdb->prefix}newsletter` u on s.user_id=u.id where u.id is null");
 
64
  $controls->messages = $count . ' ' . __('deleted', 'newsletter');
65
  }
66
 
@@ -208,7 +200,7 @@ if ($controls->is_action('bounces')) {
208
  <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C'"); ?>
209
  </td>
210
  <td nowrap>
211
- <?php $controls->button_confirm('unconfirm_all', __('Unconfirm all', 'newsletter'), __('Are you sure?', 'newsletter')); ?>
212
  </td>
213
  </tr>
214
  <tr>
@@ -230,7 +222,7 @@ if ($controls->is_action('bounces')) {
230
  <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='U'"); ?>
231
  </td>
232
  <td>
233
- <?php $controls->button_confirm('remove_unsubscribed', __('Delete all unsubscribed', 'newsletter'), __('Are you sure?', 'newsletter')); ?>
234
  </td>
235
  </tr>
236
 
@@ -240,7 +232,7 @@ if ($controls->is_action('bounces')) {
240
  <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='B'"); ?>
241
  </td>
242
  <td>
243
- <?php $controls->button_confirm('remove_bounced', __('Delete all bounced', 'newsletter'), __('Are you sure?', 'newsletter')); ?>
244
  </td>
245
  </tr>
246
  <tr>
@@ -262,11 +254,11 @@ if ($controls->is_action('bounces')) {
262
  ))
263
  ?>
264
  to
265
- <?php $controls->select('list_inactive', $lists); ?>
266
 
267
  </td>
268
  <td>
269
- <?php $controls->button_confirm('update_inactive', __('Update', 'newsletter'), __('Are you sure?', 'newsletter')); ?>
270
  </td>
271
  </tr>
272
  </table>
@@ -280,10 +272,15 @@ if ($controls->is_action('bounces')) {
280
  <tr>
281
  <th>&nbsp;</th>
282
  <td>
283
- <?php $controls->select('list', $lists) ?>:
284
- <?php $controls->button_confirm('list_add', 'Activate for everyone', __('Are you sure?', 'newsletter')); ?>
285
- <?php $controls->button_confirm('list_remove', 'Deactivate for everyone', __('Are you sure?', 'newsletter')); ?>
286
- <?php $controls->button_confirm('list_delete', 'Delete everyone in that list', __('Are you sure?', 'newsletter')); ?>
 
 
 
 
 
287
  <p class="description">
288
  If you choose to <strong>delete</strong> users in a list, they will be
289
  <strong>physically deleted</strong> from the database (no way back).
@@ -293,17 +290,8 @@ if ($controls->is_action('bounces')) {
293
  <tr>
294
  <th>&nbsp;</th>
295
  <td>
296
- <?php $controls->select('list_action', array('move' => 'Move', 'add' => 'Add')); ?>
297
- <?php _e('all subscribers in', 'newsletter') ?> <?php $controls->select('list_1', $lists); ?>
298
- <?php _e('to', 'newsletter') ?> <?php $controls->select('list_2', $lists); ?>
299
- <?php $controls->button_confirm('list_manage', 'Go!', 'Are you sure?'); ?>
300
- </td>
301
- </tr>
302
- <tr>
303
- <th>&nbsp;</th>
304
- <td>
305
- <?php _e('Add to', 'newsletter') ?>
306
- <?php $controls->select('list_3', $lists) ?> <?php _e('subscribers without a list', 'newsletter') ?> <?php $controls->button_confirm('list_none', '&raquo;', __('Are you sure?', 'newsletter')); ?>
307
  </td>
308
  </tr>
309
 
@@ -330,7 +318,7 @@ if ($controls->is_action('bounces')) {
330
  </tr>
331
  </table>
332
 
333
- <?php $controls->button_confirm('bounces', 'Mark those emails as bounced', __('Are you sure?', 'newsletter')); ?>
334
  </div>
335
 
336
  </div>
@@ -340,4 +328,4 @@ if ($controls->is_action('bounces')) {
340
 
341
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
342
 
343
- </div>
8
  $controls = new NewsletterControls();
9
  $module = NewsletterUsers::instance();
10
 
 
 
 
 
 
 
 
 
 
11
  if ($controls->is_action('remove_unconfirmed')) {
12
  $r = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where status='S'");
13
  $controls->messages = __('Subscribers not confirmed deleted: ', 'newsletter') . $r . '.';
50
 
51
  if ($controls->is_action('list_delete')) {
52
  $count = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where list_" . ((int) $controls->data['list']) . "<>0");
53
+ $module->clean_sent_table();
54
+ $module->clean_stats_table();
55
+
56
  $controls->messages = $count . ' ' . __('deleted', 'newsletter');
57
  }
58
 
200
  <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C'"); ?>
201
  </td>
202
  <td nowrap>
203
+ <?php $controls->button_confirm('unconfirm_all', __('Unconfirm all', 'newsletter')); ?>
204
  </td>
205
  </tr>
206
  <tr>
222
  <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='U'"); ?>
223
  </td>
224
  <td>
225
+ <?php $controls->button_confirm('remove_unsubscribed', __('Delete all unsubscribed', 'newsletter')); ?>
226
  </td>
227
  </tr>
228
 
232
  <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='B'"); ?>
233
  </td>
234
  <td>
235
+ <?php $controls->button_confirm('remove_bounced', __('Delete all bounced', 'newsletter')); ?>
236
  </td>
237
  </tr>
238
  <tr>
254
  ))
255
  ?>
256
  to
257
+ <?php $controls->lists_select('list_inactive'); ?>
258
 
259
  </td>
260
  <td>
261
+ <?php $controls->button_confirm('update_inactive', __('Update', 'newsletter')); ?>
262
  </td>
263
  </tr>
264
  </table>
272
  <tr>
273
  <th>&nbsp;</th>
274
  <td>
275
+ <?php $controls->lists_select('list') ?>:
276
+ <?php $controls->button_confirm('list_add', 'Activate for everyone'); ?>
277
+ <?php $controls->button_confirm('list_remove', 'Deactivate for everyone'); ?>
278
+ <?php $controls->button_confirm('list_delete', 'Delete everyone in that list'); ?>
279
+ <br><br>
280
+ <?php $controls->select('list_action', array('move' => 'Change', 'add' => 'Add')); ?>
281
+ <?php _e('all subscribers in', 'newsletter') ?> <?php $controls->lists_select('list_1'); ?>
282
+ <?php _e('to', 'newsletter') ?> <?php $controls->lists_select('list_2'); ?>
283
+ <?php $controls->button_confirm('list_manage', '&raquo;'); ?>
284
  <p class="description">
285
  If you choose to <strong>delete</strong> users in a list, they will be
286
  <strong>physically deleted</strong> from the database (no way back).
290
  <tr>
291
  <th>&nbsp;</th>
292
  <td>
293
+ <?php _e('Add to list', 'newsletter') ?>
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
 
318
  </tr>
319
  </table>
320
 
321
+ <?php $controls->button_confirm('bounces', 'Mark those emails as bounced'); ?>
322
  </div>
323
 
324
  </div>
328
 
329
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
330
 
331
+ </div>
users/new.php CHANGED
@@ -1,6 +1,5 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
 
5
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
1
  <?php
2
+ defined('ABSPATH') || exit;
 
3
 
4
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
users/statistics-time.php CHANGED
@@ -1,6 +1,5 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
  ?>
5
 
6
  <div class="row">
1
  <?php
2
+ defined('ABSPATH') || exit;
 
3
  ?>
4
 
5
  <div class="row">
users/statistics.php CHANGED
@@ -103,13 +103,13 @@ $controls = new NewsletterControls();
103
  </tr>
104
  </thead>
105
  <tbody>
106
- <?php for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) { ?>
107
- <?php if (empty($options_profile['list_' . $i])) continue; ?>
108
  <tr>
109
- <td><?php echo $i ?></td>
110
- <td><?php echo esc_html($options_profile['list_' . $i]) ?></td>
111
  <td>
112
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where list_" . $i . "=1 and status='C'"); ?>
113
  </td>
114
  </tr>
115
  <?php } ?>
103
  </tr>
104
  </thead>
105
  <tbody>
106
+ <?php $lists = $module->get_lists(); ?>
107
+ <?php foreach ($lists as $list) { ?>
108
  <tr>
109
+ <td><?php echo $list->id ?></td>
110
+ <td><?php echo esc_html($list->name) ?></td>
111
  <td>
112
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where list_" . $list->id . "=1 and status='C'"); ?>
113
  </td>
114
  </tr>
115
  <?php } ?>
users/users.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
 
3
- if (!defined('ABSPATH'))
4
- exit;
5
 
6
  require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
7
 
@@ -20,7 +19,7 @@ class NewsletterUsers extends NewsletterModule {
20
  }
21
 
22
  function __construct() {
23
- parent::__construct('users', '1.1.5');
24
  add_action('init', array($this, 'hook_init'));
25
  }
26
 
@@ -33,11 +32,12 @@ class NewsletterUsers extends NewsletterModule {
33
  function hook_wp_ajax_newsletter_users_export() {
34
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
35
  $controls = new NewsletterControls();
 
36
  if (current_user_can('manage_options') || ($newsletter->options['editor'] == 1 && current_user_can('manage_categories'))) {
37
  $controls = new NewsletterControls();
38
 
39
  if ($controls->is_action('export')) {
40
- NewsletterUsers::instance()->export($controls->data);
41
  }
42
  } else {
43
  die('Not allowed.');
@@ -55,7 +55,6 @@ class NewsletterUsers extends NewsletterModule {
55
  `token` varchar(50) NOT NULL DEFAULT '',
56
  `status` varchar(1) NOT NULL DEFAULT 'S',
57
  `id` int(11) NOT NULL AUTO_INCREMENT,
58
- `list` int(11) NOT NULL DEFAULT '0',
59
  `profile` mediumtext,
60
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
61
  `updated` int(11) NOT NULL DEFAULT '0',
@@ -91,7 +90,6 @@ class NewsletterUsers extends NewsletterModule {
91
  $sql .= "PRIMARY KEY (`id`),\nUNIQUE KEY `email` (`email`),\nKEY `wp_user_id` (`wp_user_id`)\n) $charset_collate;";
92
 
93
  dbDelta($sql);
94
- $this->upgrade_query("alter table " . NEWSLETTER_USERS_TABLE . " convert to character set $charset_collate");
95
 
96
  }
97
 
@@ -123,7 +121,7 @@ class NewsletterUsers extends NewsletterModule {
123
  }
124
 
125
  // CSV header
126
- echo '"Email"' . $sep . '"Name"' . $sep . '"Surname"' . $sep . '"Sex"' . $sep . '"Status"' . $sep . '"Date"' . $sep . '"Token"' . $sep;
127
 
128
  // In table profiles
129
  for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
1
  <?php
2
 
3
+ defined('ABSPATH') || exit;
 
4
 
5
  require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
6
 
19
  }
20
 
21
  function __construct() {
22
+ parent::__construct('users', '1.2.2');
23
  add_action('init', array($this, 'hook_init'));
24
  }
25
 
32
  function hook_wp_ajax_newsletter_users_export() {
33
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
34
  $controls = new NewsletterControls();
35
+ $newsletter = Newsletter::instance();
36
  if (current_user_can('manage_options') || ($newsletter->options['editor'] == 1 && current_user_can('manage_categories'))) {
37
  $controls = new NewsletterControls();
38
 
39
  if ($controls->is_action('export')) {
40
+ $this->export($controls->data);
41
  }
42
  } else {
43
  die('Not allowed.');
55
  `token` varchar(50) NOT NULL DEFAULT '',
56
  `status` varchar(1) NOT NULL DEFAULT 'S',
57
  `id` int(11) NOT NULL AUTO_INCREMENT,
 
58
  `profile` mediumtext,
59
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
60
  `updated` int(11) NOT NULL DEFAULT '0',
90
  $sql .= "PRIMARY KEY (`id`),\nUNIQUE KEY `email` (`email`),\nKEY `wp_user_id` (`wp_user_id`)\n) $charset_collate;";
91
 
92
  dbDelta($sql);
 
93
 
94
  }
95
 
121
  }
122
 
123
  // CSV header
124
+ echo '"Email"' . $sep . '"Name"' . $sep . '"Surname"' . $sep . '"Gender"' . $sep . '"Status"' . $sep . '"Date"' . $sep . '"Token"' . $sep;
125
 
126
  // In table profiles
127
  for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
widget/minimal.php CHANGED
@@ -1,8 +1,9 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
- if (version_compare(phpversion(), '5.3', '<'))
5
  return;
 
6
 
7
  class NewsletterWidgetMinimal extends WP_Widget {
8
 
@@ -85,17 +86,15 @@ class NewsletterWidgetMinimal extends WP_Widget {
85
  <p>
86
  <?php _e('Automatically subscribe to', 'newsletter') ?>
87
  <br>
88
- <?php
89
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
90
- if (empty($options_profile['list_' . $i]) || empty($options_profile['list_' . $i . '_status'])) {
91
- continue;
92
- }
93
  ?>
94
- <label for="nl<?php echo $i ?>">
95
- <input type="checkbox" value="<?php echo $i ?>" name="<?php echo $this->get_field_name('nl[]') ?>" <?php echo array_search($i, $instance['nl']) !== false ? 'checked' : '' ?>> <?php echo esc_html($options_profile['list_' . $i]) ?>
96
  </label>
97
  <br>
98
- <?php } ?>
99
  </p>
100
 
101
  <?php
1
  <?php
2
+ defined('ABSPATH') || exit;
3
+
4
+ if (version_compare(phpversion(), '5.3', '<')) {
5
  return;
6
+ }
7
 
8
  class NewsletterWidgetMinimal extends WP_Widget {
9
 
86
  <p>
87
  <?php _e('Automatically subscribe to', 'newsletter') ?>
88
  <br>
89
+ <?php
90
+ $lists = Newsletter::instance()->get_lists_public();
91
+ foreach ($lists as $list) {
 
 
92
  ?>
93
+ <label for="nl<?php echo $list->id ?>">
94
+ <input type="checkbox" value="<?php echo $list->id ?>" name="<?php echo $this->get_field_name('nl[]') ?>" <?php echo array_search($list->id, $instance['nl']) !== false ? 'checked' : '' ?>> <?php echo esc_html($list->name) ?>
95
  </label>
96
  <br>
97
+ <?php } ?>
98
  </p>
99
 
100
  <?php
widget/standard.php CHANGED
@@ -1,6 +1,9 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
3
- if (version_compare(phpversion(), '5.3', '<')) return;
 
 
 
4
 
5
  /**
6
  * Newsletter widget version 2.0: it'll replace the old version left for compatibility.
@@ -14,114 +17,25 @@ class NewsletterWidget extends WP_Widget {
14
  static function get_widget_form($instance) {
15
 
16
  $field_wrapper_tag = 'div';
17
- if (!isset($instance['nl']) || !is_array($instance['nl'])) $instance['nl'] = array();
 
18
 
19
  $instance = array_merge(array('lists_layout' => '',
20
- 'lists_empty_label' => '',
21
  'lists_field_label' => ''), $instance);
22
-
23
  $options_profile = get_option('newsletter_profile');
24
  //$form = NewsletterSubscription::instance()->get_form_javascript();
25
  $form = '';
26
-
27
  $form .= '<div class="tnp tnp-widget">';
28
  $form .= NewsletterSubscription::instance()->get_subscription_form_html5('widget', null, array(
29
- 'list'=> implode(',', $instance['nl']),
30
  'lists_field_layout' => $instance['lists_layout'],
31
  'lists_field_empty_label' => $instance['lists_empty_label'],
32
  'lists_field_label' => $instance['lists_field_label'],
33
-
34
- ));
35
  $form .= "</div>\n";
36
-
37
- return $form;
38
- }
39
-
40
- static function get_old_widget_form($instance) {
41
- $options_profile = get_option('newsletter_profile');
42
- $form = NewsletterSubscription::instance()->get_form_javascript();
43
-
44
- $form .= '<div class="tnp tnp-widget">';
45
- $form .= '<form action="' . home_url('/') . '?na=s" onsubmit="return newsletter_check(this)" method="post">';
46
- // Referrer
47
- $form .= '<input type="hidden" name="nr" value="widget"/>';
48
-
49
- if (isset($instance['nl']) && is_array($instance['nl'])) {
50
- foreach ($instance['nl'] as $a) {
51
- $form .= "<input type='hidden' name='nl[]' value='" . ((int) trim($a)) . "'>\n";
52
- }
53
- }
54
-
55
- if ($options_profile['name_status'] == 2) {
56
- $form .= '<p><input class="tnp-firstname" type="text" name="nn" value="' . esc_attr($options_profile['name']) . '" onclick="if (this.defaultValue==this.value) this.value=\'\'" onblur="if (this.value==\'\') this.value=this.defaultValue"/></p>';
57
- }
58
-
59
- if ($options_profile['surname_status'] == 2) {
60
- $form .= '<p><input class="tnp-lastname" type="text" name="ns" value="' . esc_attr($options_profile['surname']) . '" onclick="if (this.defaultValue==this.value) this.value=\'\'" onblur="if (this.value==\'\') this.value=this.defaultValue"/></p>';
61
- }
62
-
63
- $form .= '<p><input class="tnp-email" type="email" required name="ne" value="' . esc_attr($options_profile['email']) . '" onclick="if (this.defaultValue==this.value) this.value=\'\'" onblur="if (this.value==\'\') this.value=this.defaultValue"/></p>';
64
-
65
- if (isset($options_profile['sex_status']) && $options_profile['sex_status'] == 2) {
66
- $form .= '<p><select name="nx" class="tnp-gender">';
67
- $form .= '<option value="m">' . $options_profile['sex_male'] . '</option>';
68
- $form .= '<option value="f">' . $options_profile['sex_female'] . '</option>';
69
- $form .= '</select></p>';
70
- }
71
-
72
- // Extra profile fields
73
- for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
74
- if ($options_profile['profile_' . $i . '_status'] != 2)
75
- continue;
76
- if ($options_profile['profile_' . $i . '_type'] == 'text') {
77
- $form .= '<p><input class="tnp-profile tnp-profile-' . $i . '" type="text" name="np' . $i . '" value="' . $options_profile['profile_' . $i] . '" onclick="if (this.defaultValue==this.value) this.value=\'\'" onblur="if (this.value==\'\') this.value=this.defaultValue"/></p>';
78
- }
79
- if ($options_profile['profile_' . $i . '_type'] == 'select') {
80
- $form .= '<p>' . $options_profile['profile_' . $i] . '<br /><select class="tnp-profile tnp-profile-' . $i . '" name="np' . $i . '">';
81
- $opts = explode(',', $options_profile['profile_' . $i . '_options']);
82
- for ($t = 0; $t < count($opts); $t++) {
83
- $form .= '<option>' . trim($opts[$t]) . '</option>';
84
- }
85
- $form .= '</select></p>';
86
- }
87
- }
88
-
89
- $lists = '';
90
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
91
- if ($options_profile['list_' . $i . '_status'] != 2)
92
- continue;
93
- $lists .= '<input type="checkbox" name="nl[]" value="' . $i . '"';
94
- if ($options_profile['list_' . $i . '_checked'] == 1)
95
- $lists .= ' checked';
96
- $lists .= '/>&nbsp;' . $options_profile['list_' . $i] . '<br />';
97
- }
98
- if (!empty($lists))
99
- $form .= '<p>' . $lists . '</p>';
100
-
101
-
102
- $extra = apply_filters('newsletter_subscription_extra', array());
103
- foreach ($extra as &$x) {
104
- $form .= "<p>";
105
- if (!empty($x['label']))
106
- $form .= $x['label'] . "<br/>";
107
- $form .= $x['field'] . "</p>";
108
- }
109
-
110
- if ($options_profile['privacy_status'] == 1) {
111
- if (!empty($options_profile['privacy_url'])) {
112
- $form .= '<p><input type="checkbox" name="ny"/>&nbsp;<a target="_blank" href="' . $options_profile['privacy_url'] . '">' . $options_profile['privacy'] . '</a></p>';
113
- } else
114
- $form .= '<p><input type="checkbox" name="ny"/>&nbsp;' . $options_profile['privacy'] . '</p>';
115
- }
116
-
117
- if (strpos($options_profile['subscribe'], 'http://') !== false) {
118
- $form .= '<p><input class="tnp-submit" type="image" src="' . $options_profile['subscribe'] . '"/></p>';
119
- } else {
120
- $form .= '<p><input class="tnp-submit" type="submit" value="' . $options_profile['subscribe'] . '"/></p>';
121
- }
122
-
123
- $form .= '</form>';
124
- $form .= '</div>';
125
 
126
  return $form;
127
  }
@@ -150,11 +64,7 @@ class NewsletterWidget extends WP_Widget {
150
 
151
  if (stripos($instance['text'], '<form') === false) {
152
 
153
- if (isset($instance['old_form'])) {
154
- $form = NewsletterWidget::get_old_widget_form($instance);
155
- } else {
156
- $form = NewsletterWidget::get_widget_form($instance);
157
- }
158
 
159
  // Canot user directly the replace, since the form is different on the widget...
160
  if (strpos($buffer, '{subscription_form}') !== false)
@@ -187,9 +97,10 @@ class NewsletterWidget extends WP_Widget {
187
  if (!is_array($instance)) {
188
  $instance = array();
189
  }
190
- $instance = array_merge(array('title' => '', 'text' => '', 'lists_layout'=>'', 'lists_empty_label'=>'', 'lists_field_label'=>''), $instance);
191
  $options_profile = get_option('newsletter_profile');
192
- if (!isset($instance['nl']) || !is_array($instance['nl'])) $instance['nl'] = array();
 
193
  ?>
194
  <p>
195
  <label for="<?php echo $this->get_field_id('title'); ?>">
@@ -201,12 +112,12 @@ class NewsletterWidget extends WP_Widget {
201
  Introduction:
202
  <textarea class="widefat" rows="10" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo esc_html($instance['text']); ?></textarea>
203
  </label>
204
-
205
  <label>
206
  Show lists as:
207
  <select name="<?php echo $this->get_field_name('lists_layout'); ?>" id="<?php echo $this->get_field_id('lists_layout'); ?>" style="width: 100%">
208
  <option value="">Checkboxes</option>
209
- <option value="dropdown" <?php echo $instance['lists_layout']=='dropdown'?'selected':''?>>Dropdown</option>
210
  </select>
211
  </label>
212
  <br>
@@ -219,28 +130,23 @@ class NewsletterWidget extends WP_Widget {
219
  Lists field label:
220
  <input class="widefat" id="<?php echo $this->get_field_id('lists_field_label'); ?>" name="<?php echo $this->get_field_name('lists_field_label'); ?>" type="text" value="<?php echo esc_attr($instance['lists_field_label']); ?>" />
221
  </label>
222
-
223
  <br><br>
224
- <?php _e('Automatically subscribe to', 'newsletter')?>
225
  <br>
226
  <?php
227
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
228
- if (empty($options_profile['list_' . $i])) continue;
229
- if (empty($options_profile['list_' . $i . '_status'])) continue;
230
- ?>
231
- <label for="nl<?php echo $i?>">
232
- <input type="checkbox" value="<?php echo $i?>" name="<?php echo $this->get_field_name('nl[]') ?>" <?php echo array_search($i, $instance['nl']) !== false?'checked':''?>> <?php echo esc_html($options_profile['list_' . $i]) ?>
233
- </label>
234
- <br>
235
  <?php } ?>
236
-
237
-
238
- <br>
239
-
240
- <label for="<?php echo $this->get_field_id('old_form'); ?>">
241
- <input type="checkbox" id="<?php echo $this->get_field_id('old_form'); ?>" name="<?php echo $this->get_field_name('old_form'); ?>" <?php echo isset($instance['old_form']) ? 'checked' : '' ?>>
242
- Use the old form (will be removed in future versions)
243
- </label>
244
  </p>
245
 
246
  <p>
@@ -251,5 +157,7 @@ class NewsletterWidget extends WP_Widget {
251
 
252
  }
253
 
254
- add_action('widgets_init', function () {return register_widget("NewsletterWidget");});
 
 
255
  ?>
1
  <?php
2
+ defined('ABSPATH') || exit;
3
+
4
+ if (version_compare(phpversion(), '5.3', '<')) {
5
+ return;
6
+ }
7
 
8
  /**
9
  * Newsletter widget version 2.0: it'll replace the old version left for compatibility.
17
  static function get_widget_form($instance) {
18
 
19
  $field_wrapper_tag = 'div';
20
+ if (!isset($instance['nl']) || !is_array($instance['nl']))
21
+ $instance['nl'] = array();
22
 
23
  $instance = array_merge(array('lists_layout' => '',
24
+ 'lists_field_empty_label' => '',
25
  'lists_field_label' => ''), $instance);
26
+
27
  $options_profile = get_option('newsletter_profile');
28
  //$form = NewsletterSubscription::instance()->get_form_javascript();
29
  $form = '';
30
+
31
  $form .= '<div class="tnp tnp-widget">';
32
  $form .= NewsletterSubscription::instance()->get_subscription_form_html5('widget', null, array(
33
+ 'list' => implode(',', $instance['nl']),
34
  'lists_field_layout' => $instance['lists_layout'],
35
  'lists_field_empty_label' => $instance['lists_empty_label'],
36
  'lists_field_label' => $instance['lists_field_label'],
37
+ ));
 
38
  $form .= "</div>\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  return $form;
41
  }
64
 
65
  if (stripos($instance['text'], '<form') === false) {
66
 
67
+ $form = NewsletterWidget::get_widget_form($instance);
 
 
 
 
68
 
69
  // Canot user directly the replace, since the form is different on the widget...
70
  if (strpos($buffer, '{subscription_form}') !== false)
97
  if (!is_array($instance)) {
98
  $instance = array();
99
  }
100
+ $instance = array_merge(array('title' => '', 'text' => '', 'lists_layout' => '', 'lists_empty_label' => '', 'lists_field_label' => ''), $instance);
101
  $options_profile = get_option('newsletter_profile');
102
+ if (!isset($instance['nl']) || !is_array($instance['nl']))
103
+ $instance['nl'] = array();
104
  ?>
105
  <p>
106
  <label for="<?php echo $this->get_field_id('title'); ?>">
112
  Introduction:
113
  <textarea class="widefat" rows="10" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo esc_html($instance['text']); ?></textarea>
114
  </label>
115
+
116
  <label>
117
  Show lists as:
118
  <select name="<?php echo $this->get_field_name('lists_layout'); ?>" id="<?php echo $this->get_field_id('lists_layout'); ?>" style="width: 100%">
119
  <option value="">Checkboxes</option>
120
+ <option value="dropdown" <?php echo $instance['lists_layout'] == 'dropdown' ? 'selected' : '' ?>>Dropdown</option>
121
  </select>
122
  </label>
123
  <br>
130
  Lists field label:
131
  <input class="widefat" id="<?php echo $this->get_field_id('lists_field_label'); ?>" name="<?php echo $this->get_field_name('lists_field_label'); ?>" type="text" value="<?php echo esc_attr($instance['lists_field_label']); ?>" />
132
  </label>
133
+
134
  <br><br>
135
+ <?php _e('Automatically subscribe to', 'newsletter') ?>
136
  <br>
137
  <?php
138
+ $lists = Newsletter::instance()->get_lists_public();
139
+ foreach ($lists as $list) {
140
+ ?>
141
+ <label for="nl<?php echo $list->id ?>">
142
+ <input type="checkbox" value="<?php echo $list->id ?>" name="<?php echo $this->get_field_name('nl[]') ?>" <?php echo array_search($list->id, $instance['nl']) !== false ? 'checked' : '' ?>> <?php echo esc_html($list->name) ?>
143
+ </label>
144
+ <br>
 
145
  <?php } ?>
146
+
147
+
148
+ <br>
149
+
 
 
 
 
150
  </p>
151
 
152
  <p>
157
 
158
  }
159
 
160
+ add_action('widgets_init', function () {
161
+ return register_widget("NewsletterWidget");
162
+ });
163
  ?>