Subscribe2 - Version 10.26

Version Description

Download this release

Release Info

Developer Collizo4sky
Plugin Icon 128x128 Subscribe2
Version 10.26
Comparing to
See all releases

Code changes from version 10.22.1 to 10.26

Files changed (46) hide show
  1. ChangeLog.txt +47 -5
  2. ReadMe.txt +52 -7
  3. admin/send-email.php +23 -21
  4. admin/settings.php +86 -75
  5. admin/subscribers.php +107 -58
  6. admin/your-subscriptions.php +4 -5
  7. classes/class-s2-admin.php +534 -367
  8. classes/class-s2-ajax.php +34 -35
  9. classes/class-s2-core.php +671 -547
  10. classes/class-s2-counter-widget.php +45 -45
  11. classes/class-s2-form-widget.php +70 -66
  12. classes/class-s2-forms.php +82 -64
  13. classes/class-s2-frontend.php +163 -95
  14. classes/class-s2-list-table-legacy.php +182 -109
  15. classes/class-s2-list-table.php +190 -110
  16. classes/class-s2-multisite.php +37 -30
  17. classes/class-s2-upgrade.php +188 -106
  18. classes/mo-notice.php +180 -0
  19. include/options.php +3 -8
  20. include/s2-ajax.js +32 -23
  21. include/s2-ajax.min.js +1 -1
  22. include/s2-button.js +3 -2
  23. include/s2-checkbox.js +33 -28
  24. include/s2-checkbox.min.js +1 -1
  25. include/s2-colorpicker.js +25 -17
  26. include/s2-colorpicker.min.js +1 -1
  27. include/s2-date-time.js +7 -5
  28. include/s2-dismiss.js +5 -4
  29. include/s2-dismiss.min.js +1 -1
  30. include/s2-edit.js +19 -17
  31. include/s2-edit.min.js +1 -1
  32. include/s2-ip-updater.js +6 -3
  33. include/s2-ip-updater.min.js +1 -1
  34. include/s2-subscribers.js +33 -28
  35. include/s2-subscribers.min.js +1 -1
  36. include/s2-user-admin.css +76 -53
  37. include/s2-user-admin.min.css +1 -0
  38. subscribe2.php +17 -20
  39. subscribe2.pot +1669 -0
  40. tinymce/css/content.css +12 -9
  41. tinymce/css/content.min.css +0 -1
  42. tinymce/editor-plugin3.js +36 -35
  43. tinymce/editor-plugin3.min.js +1 -1
  44. tinymce/editor-plugin4.js +30 -29
  45. tinymce/editor-plugin4.min.js +1 -1
  46. uninstall.php +1 -4
ChangeLog.txt CHANGED
@@ -1,3 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  = 10.22.1 =
2
 
3
  * Minor release with some bug fixes that really needed fixing - thanks to @doyousoft and @tastymouse
@@ -198,7 +240,7 @@
198
  * Fixes for database connectivity in the upgrade class file - thanks to rushu25
199
  * Fix for bug when antispam measures are disabled - thanks to serinx
200
  * Add option to Sidebar Widget to not wrap the button below the form
201
- * Straightened quotes in the changelog
202
  * Remove all uses of PHP extract() function as per core ticket (https://core.trac.wordpress.org/ticket/22400)
203
 
204
  = Version 9.4 by Matthew Robinson =
@@ -386,7 +428,7 @@
386
  * Rename js files consistently with core ticket 21633
387
  * Add width parameter to comment form text to fix issues with some themes - proposed by mharpen
388
  * Added option to include Sticky Posts at the top of all Digest Notifications - proposed by pkhatmedia
389
- * Fixed some Markdown errors in the readme
390
 
391
  = Version 8.4 by Matthew Robinson =
392
 
@@ -531,7 +573,7 @@
531
  = Version 6.2 by Matthew Robinson =
532
 
533
  * Pass email address to add() function explicitly
534
- * Fix typos in the readme
535
  * Added warning on the Options page to avoid using the Subscribe2 KEYWORDS in posts as they will get substituted
536
  * Added HTML LABEL tags to the Subscribe2 form to support WCAG
537
  * SSL friendly with WordPress admin areas
@@ -637,7 +679,7 @@
637
  * Fixed a bug in TinyURL encoding introduced when links were click enabled
638
  * Removed BurnURL from the plugin as it appears to be no longer operational
639
  * Added urlencode to email addresses in Tools->Subscribers when editing other user preferences
640
- * Restored several FAQs to the readme file and the [WordPress.org FAQ section](http://wordpress.org/extend/plugins/subscribe2/faq/)
641
 
642
  = Version 5.1 by Matthew Robinson =
643
 
@@ -679,7 +721,7 @@
679
  * Improved Bulk Subscribe and Unsubscribe routines to avoid database artefacts
680
  * Moved Select/Deselect All check box to the top of the category list in admin pages
681
  * Fixed small layout glitch in Manage->Subscribers screen
682
- * Added changelog section to readme to support WordPress.org/extend development
683
 
684
  = Version 4.17 by Matthew Robinson =
685
 
1
+ = 10.26 =
2
+
3
+ * Fixed a bug in barred domain checking
4
+ * Updated to latest PHP Code sniff standards and cleansed files
5
+ * Other minor bug fixes and enhancements
6
+
7
+ = 10.25 =
8
+
9
+ * Dropped use of the 'Precedence' email header as use is controversial and not widely supported
10
+ * Fix for date appearing in wrong language when authors use different language in WordPress admin to the main site language
11
+ * Fixed warning message on Your Subscriptions page
12
+ * Further Coding Standard improvements
13
+ * Add GDPR warning to Settings page for certain settings
14
+ * Fixed error message in older version of WordPress where get_user_locale() function is not available
15
+ * Extended 's2_form' filter to include shortcode attributes to allow more accurate filtering
16
+ * Extended Widget to pass attribute to indicate Widget use over standard form use
17
+ * Fix some notices generated by undefined variables
18
+ * Ensure Editor buttons loads when Classic Editor plugin in use with WordPress 5.0
19
+
20
+ = 10.24 =
21
+
22
+ * Fixes for the Subscribers page - sorting and Multisite improvements
23
+ * Code layout improvements
24
+ * Other minor bug fixes and enhancements
25
+
26
+ = 10.23 =
27
+
28
+ * Improve REGEX for the old Subscribe2 token - props @pik256
29
+ * Applied Grunt to packing for distribution so files are minified differently
30
+ * Load external javascripts asynchronously
31
+ * Improve Bulk Management user experience
32
+ * Move Display options for Subscriber page to screen option
33
+ * Fixed error messages when using 's2_custom_keyword' hook in digest mode - thanks to Bryan Fogarty
34
+ * Ported several features from Subscribe2 HTML including Remote IP checking and email address validation
35
+ * Other minor big fixes
36
+
37
+ = 10.22.2 =
38
+
39
+ * Fix JavaScript issue when toggling subscribers
40
+ * Fix to correct display of Registered Subscribers on multisite installs
41
+ * Fix for Content Type in plaintext emails
42
+
43
  = 10.22.1 =
44
 
45
  * Minor release with some bug fixes that really needed fixing - thanks to @doyousoft and @tastymouse
240
  * Fixes for database connectivity in the upgrade class file - thanks to rushu25
241
  * Fix for bug when antispam measures are disabled - thanks to serinx
242
  * Add option to Sidebar Widget to not wrap the button below the form
243
+ * Straightened quotes in the ChangeLog
244
  * Remove all uses of PHP extract() function as per core ticket (https://core.trac.wordpress.org/ticket/22400)
245
 
246
  = Version 9.4 by Matthew Robinson =
428
  * Rename js files consistently with core ticket 21633
429
  * Add width parameter to comment form text to fix issues with some themes - proposed by mharpen
430
  * Added option to include Sticky Posts at the top of all Digest Notifications - proposed by pkhatmedia
431
+ * Fixed some Markdown errors in the ReadMe
432
 
433
  = Version 8.4 by Matthew Robinson =
434
 
573
  = Version 6.2 by Matthew Robinson =
574
 
575
  * Pass email address to add() function explicitly
576
+ * Fix typos in the ReadMe
577
  * Added warning on the Options page to avoid using the Subscribe2 KEYWORDS in posts as they will get substituted
578
  * Added HTML LABEL tags to the Subscribe2 form to support WCAG
579
  * SSL friendly with WordPress admin areas
679
  * Fixed a bug in TinyURL encoding introduced when links were click enabled
680
  * Removed BurnURL from the plugin as it appears to be no longer operational
681
  * Added urlencode to email addresses in Tools->Subscribers when editing other user preferences
682
+ * Restored several FAQs to the ReadMe file and the [WordPress.org FAQ section](http://wordpress.org/extend/plugins/subscribe2/faq/)
683
 
684
  = Version 5.1 by Matthew Robinson =
685
 
721
  * Improved Bulk Subscribe and Unsubscribe routines to avoid database artefacts
722
  * Moved Select/Deselect All check box to the top of the category list in admin pages
723
  * Fixed small layout glitch in Manage->Subscribers screen
724
+ * Added ChangeLog section to ReadMe to support WordPress.org/extend development
725
 
726
  = Version 4.17 by Matthew Robinson =
727
 
ReadMe.txt CHANGED
@@ -1,10 +1,9 @@
1
  === Subscribe2 ===
2
-
3
- Contributors: Dabelon, wenzhixue, tanaylakhani
4
- Tags: posts, subscription, email, subscribe, notify, notification
5
- Requires at least: 3.3
6
- Tested up to: 4.8.1
7
- Stable tag: 10.22.1
8
  License: GPLv3
9
 
10
  Sends a list of subscribers an email notification when you publish new posts.
@@ -32,7 +31,7 @@ The format of the email can also be customised for per-post notifications, Subsc
32
  * HTML excerpt (Registered Users only).
33
  * HTML full post (Registered Users only).
34
 
35
- If you want to send full content HTML emails to Public Subscribers too then upgrade to [Subscribe2 HTML](http://semperplugins.com/plugins/subscribe2-html/).
36
 
37
  == Installation ==
38
 
@@ -66,4 +65,50 @@ This token will automatically be replaced by dynamic subscription information an
66
 
67
  == Changelog ==
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  See complete changelog installed in the same folder as this readme.
1
  === Subscribe2 ===
2
+ Contributors: collizo4sky
3
+ Donate link: https://mailoptin.io
4
+ Tags: posts, subscription, email, subscribe, notify, notification, newsletter, post notification, email marketing
5
+ Requires at least: 4.0
6
+ Tested up to: 5.0.3
 
7
  License: GPLv3
8
 
9
  Sends a list of subscribers an email notification when you publish new posts.
31
  * HTML excerpt (Registered Users only).
32
  * HTML full post (Registered Users only).
33
 
34
+ If you want to send new post notification or daily, weekly or monthly email digest of published posts to your email list in MailChimp, AWeber, Constant Contact etc, upgrade to [MailOptin](https://mailoptin.io).
35
 
36
  == Installation ==
37
 
65
 
66
  == Changelog ==
67
 
68
+ = 10.26 =
69
+
70
+ * Fixed a bug in barred domain checking
71
+ * Updated to latest PHP Code sniff standards and cleansed files
72
+ * Other minor bug fixes and enhancements
73
+
74
+ = 10.25 =
75
+
76
+ * Dropped use of the 'Precedence' email header as use is controversial and not widely supported
77
+ * Fix for date appearing in wrong language when authors use different language in WordPress admin to the main site language
78
+ * Fixed warning message on Your Subscriptions page
79
+ * Further Coding Standard improvements
80
+ * Add GDPR warning to Settings page for certain settings
81
+ * Fixed error message in older version of WordPress where get_user_locale() function is not available
82
+ * Extended 's2_form' filter to include shortcode attributes to allow more accurate filtering
83
+ * Extended Widget to pass attribute to indicate Widget use over standard form use
84
+ * Fix some notices generated by undefined variables
85
+ * Ensure Editor buttons loads when Classic Editor plugin in use with WordPress 5.0
86
+
87
+ = 10.24 =
88
+
89
+ * Fixes for the Subscribers page - sorting and Multisite improvements
90
+ * Code layout improvements
91
+ * Other minor bug fixes and enhancements
92
+
93
+ = 10.23 =
94
+
95
+ * Improve REGEX for the old Subscribe2 token - props @pik256
96
+ * Applied Grunt to packing for distribution so files are minified differently
97
+ * Load external javascripts asynchronously
98
+ * Improve Bulk Management user experience
99
+ * Move Display options for Subscriber page to screen option
100
+ * Fixed error messages when using 's2_custom_keyword' hook in digest mode - thanks to Bryan Fogarty
101
+ * Ported several features from Subscribe2 HTML including Remote IP checking and email address validation
102
+ * Other minor big fixes
103
+
104
+ = 10.22.2 =
105
+
106
+ * Fix JavaScript issue when toggling subscribers
107
+ * Fix to correct display of Registered Subscribers on multisite installs
108
+ * Fix for Content Type in plaintext emails
109
+
110
+ = 10.22.1 =
111
+
112
+ * Minor release with some bug fixes that really needed fixing - thanks to @doyousoft and @tastymouse
113
+
114
  See complete changelog installed in the same folder as this readme.
admin/send-email.php CHANGED
@@ -6,15 +6,15 @@ if ( ! function_exists( 'add_action' ) ) {
6
  global $wpdb, $current_user;
7
 
8
  // was anything POSTed?
9
- if ( ( isset( $_POST['s2_admin'] ) && 'mail' === $_POST['s2_admin'] ) || isset( $_GET['delete-draft'] ) ) {
10
  if ( false === wp_verify_nonce( $_REQUEST['_wpnonce'], 'subscribe2-write_subscribers' . S2VERSION ) ) {
11
  die( '<p>' . __( 'Security error! Your request cannot be completed.', 'subscribe2' ) . '</p>' );
12
  }
13
 
14
  $subject = html_entity_decode( stripslashes( wp_kses( $this->substitute( $_POST['subject'] ), '' ) ), ENT_QUOTES );
15
- $body = wpautop( $this->substitute( stripslashes( $_POST['content'] ) ), true );
16
  if ( '' !== $current_user->display_name || '' !== $current_user->user_email ) {
17
- $this->myname = html_entity_decode( $current_user->display_name, ENT_QUOTES );
18
  $this->myemail = $current_user->user_email;
19
  }
20
  if ( isset( $_POST['send'] ) ) {
@@ -23,19 +23,19 @@ if ( ( isset( $_POST['s2_admin'] ) && 'mail' === $_POST['s2_admin'] ) || isset(
23
  } elseif ( 'unconfirmed' === $_POST['what'] ) {
24
  $recipients = $this->get_public( 0 );
25
  } elseif ( 'public' === $_POST['what'] ) {
26
- $confirmed = $this->get_public();
27
  $unconfirmed = $this->get_public( 0 );
28
- $recipients = array_merge( (array) $confirmed, (array) $unconfirmed );
29
  } elseif ( is_numeric( $_POST['what'] ) ) {
30
- $cat = intval( $_POST['what'] );
31
  $recipients = $this->get_registered( "cats=$cat" );
32
  } elseif ( 'all_users' === $_POST['what'] ) {
33
  $recipients = $this->get_all_registered();
34
  } elseif ( 'all' === $_POST['what'] ) {
35
- $confirmed = $this->get_public();
36
  $unconfirmed = $this->get_public( 0 );
37
- $registered = $this->get_all_registered();
38
- $recipients = array_merge( (array) $confirmed, (array) $unconfirmed, (array) $registered );
39
  } else {
40
  $recipients = $this->get_registered();
41
  }
@@ -55,9 +55,12 @@ if ( ( isset( $_POST['s2_admin'] ) && 'mail' === $_POST['s2_admin'] ) || isset(
55
  'error' => $_FILES['file']['error'][ $key ],
56
  'size' => $_FILES['file']['size'][ $key ],
57
  );
58
- $uploads[] = wp_handle_upload( $file, array(
59
- 'test_form' => false,
60
- ) );
 
 
 
61
  }
62
  }
63
  }
@@ -74,12 +77,12 @@ if ( ( isset( $_POST['s2_admin'] ) && 'mail' === $_POST['s2_admin'] ) || isset(
74
 
75
  if ( empty( $body ) ) {
76
  $error_message = __( 'Your email was empty', 'subscribe2' );
77
- $status = false;
78
  } elseif ( isset( $upload_error ) ) {
79
  $error_message = $upload_error;
80
- $status = false;
81
  } else {
82
- $status = $this->mail( $recipients, $subject, $body, 'text', $attachments );
83
  $error_message = __( 'Check your settings and check with your hosting provider', 'subscribe2' );
84
  }
85
 
@@ -126,15 +129,14 @@ echo '<div style="clear: both;"><p>&nbsp;</p></div>';
126
  <script type="text/javascript">
127
  //<![CDATA[
128
  function add_file_upload() {
129
- var div = document.getElementById('upload_files');
130
- var field = div.getElementsByTagName('input')[0];
131
- div.appendChild(document.createElement("br"));
132
- div.appendChild(field.cloneNode(false));
133
  }
134
  //]]>
135
  </script>
136
  <?php
137
- include( ABSPATH . 'wp-admin/admin-footer.php' );
138
  // just to be sure
139
  die;
140
- ?>
6
  global $wpdb, $current_user;
7
 
8
  // was anything POSTed?
9
+ if ( isset( $_POST['s2_admin'] ) && 'mail' === $_POST['s2_admin'] ) {
10
  if ( false === wp_verify_nonce( $_REQUEST['_wpnonce'], 'subscribe2-write_subscribers' . S2VERSION ) ) {
11
  die( '<p>' . __( 'Security error! Your request cannot be completed.', 'subscribe2' ) . '</p>' );
12
  }
13
 
14
  $subject = html_entity_decode( stripslashes( wp_kses( $this->substitute( $_POST['subject'] ), '' ) ), ENT_QUOTES );
15
+ $body = wpautop( $this->substitute( stripslashes( $_POST['content'] ) ), true );
16
  if ( '' !== $current_user->display_name || '' !== $current_user->user_email ) {
17
+ $this->myname = html_entity_decode( $current_user->display_name, ENT_QUOTES );
18
  $this->myemail = $current_user->user_email;
19
  }
20
  if ( isset( $_POST['send'] ) ) {
23
  } elseif ( 'unconfirmed' === $_POST['what'] ) {
24
  $recipients = $this->get_public( 0 );
25
  } elseif ( 'public' === $_POST['what'] ) {
26
+ $confirmed = $this->get_public();
27
  $unconfirmed = $this->get_public( 0 );
28
+ $recipients = array_merge( (array) $confirmed, (array) $unconfirmed );
29
  } elseif ( is_numeric( $_POST['what'] ) ) {
30
+ $cat = intval( $_POST['what'] );
31
  $recipients = $this->get_registered( "cats=$cat" );
32
  } elseif ( 'all_users' === $_POST['what'] ) {
33
  $recipients = $this->get_all_registered();
34
  } elseif ( 'all' === $_POST['what'] ) {
35
+ $confirmed = $this->get_public();
36
  $unconfirmed = $this->get_public( 0 );
37
+ $registered = $this->get_all_registered();
38
+ $recipients = array_merge( (array) $confirmed, (array) $unconfirmed, (array) $registered );
39
  } else {
40
  $recipients = $this->get_registered();
41
  }
55
  'error' => $_FILES['file']['error'][ $key ],
56
  'size' => $_FILES['file']['size'][ $key ],
57
  );
58
+
59
+ $uploads[] = wp_handle_upload(
60
+ $file, array(
61
+ 'test_form' => false,
62
+ )
63
+ );
64
  }
65
  }
66
  }
77
 
78
  if ( empty( $body ) ) {
79
  $error_message = __( 'Your email was empty', 'subscribe2' );
80
+ $status = false;
81
  } elseif ( isset( $upload_error ) ) {
82
  $error_message = $upload_error;
83
+ $status = false;
84
  } else {
85
+ $status = $this->mail( $recipients, $subject, $body, 'html', $attachments );
86
  $error_message = __( 'Check your settings and check with your hosting provider', 'subscribe2' );
87
  }
88
 
129
  <script type="text/javascript">
130
  //<![CDATA[
131
  function add_file_upload() {
132
+ var div = document.getElementById( 'upload_files' );
133
+ var field = div.getElementsByTagName( 'input' )[0];
134
+ div.appendChild( document.createElement( 'br' ) );
135
+ div.appendChild( field.cloneNode( false ) );
136
  }
137
  //]]>
138
  </script>
139
  <?php
140
+ require ABSPATH . 'wp-admin/admin-footer.php';
141
  // just to be sure
142
  die;
 
admin/settings.php CHANGED
@@ -12,14 +12,17 @@ if ( isset( $_POST['s2_admin'] ) ) {
12
  }
13
 
14
  if ( isset( $_POST['reset'] ) ) {
15
- $this->reset();
 
 
 
16
  echo '<div id="message" class="updated fade"><p><strong>' . __( 'Options reset!', 'subscribe2' ) . '</strong></p></div>';
17
  } elseif ( isset( $_POST['preview'] ) ) {
18
  global $user_email, $post;
19
  $this->preview_email = true;
20
  if ( 'never' === $this->subscribe2_options['email_freq'] ) {
21
  $posts = get_posts( 'numberposts=1' );
22
- $post = $posts[0];
23
  $this->publish( $post, $user_email );
24
  } else {
25
  do_action( 's2_digest_preview', $user_email );
@@ -35,22 +38,19 @@ if ( isset( $_POST['s2_admin'] ) ) {
35
  }
36
  } elseif ( isset( $_POST['submit'] ) ) {
37
  foreach ( $_POST as $key => $value ) {
38
- if ( in_array( $key, array( 'bcclimit', 's2page', 'entries' ) ) ) {
39
  // numerical inputs fixed for old option names
40
- if ( 'entries' === $key && is_numeric( $_POST[ $key ] ) && $_POST[ $key ] > 0 ) {
41
- $this->subscribe2_options[ $key ] = (int) $_POST[ $key ];
42
- } elseif ( 'entries' !== $key && is_numeric( $_POST[ $key ] ) && $_POST[ $key ] >= 0 ) {
43
  $this->subscribe2_options[ $key ] = (int) $_POST[ $key ];
44
  }
45
  } elseif ( in_array( $key, array( 'show_meta', 'show_button', 'ajax', 'widget', 'counterwidget', 's2meta_default', 'reg_override' ) ) ) {
46
  // check box entries
47
- ( isset( $_POST[ $key ] ) && '1' === $_POST[ $key ] ) ? $newvalue = '1' : $newvalue = '0';
48
- $this->subscribe2_options[ $key ] = $newvalue;
49
- } elseif ( 'appearance_users_tab' === $key ) {
50
  $options = array( 'show_meta', 'show_button', 'ajax', 'widget', 'counterwidget', 's2meta_default' );
51
  foreach ( $options as $option ) {
52
  if ( ! isset( $_POST[ $option ] ) ) {
53
- $this->subscribe2_options[ $option ] = '';
54
  }
55
  }
56
  } elseif ( in_array( $key, array( 'notification_subject', 'mailtext', 'confirm_subject', 'confirm_email', 'remind_subject', 'remind_email', 's2_license_key' ) ) && ! empty( $_POST[ $key ] ) ) {
@@ -78,24 +78,24 @@ if ( isset( $_POST['s2_admin'] ) ) {
78
  }
79
  } elseif ( 'email_freq' === $key ) {
80
  // send per-post or digest emails
81
- $email_freq = $_POST['email_freq'];
82
- $scheduled_time = wp_next_scheduled( 's2_digest_cron' );
83
  $timestamp_offset = get_option( 'gmt_offset' ) * 60 * 60;
84
- $crondate = ( isset( $_POST['crondate'] ) ) ? $_POST['crondate'] : 0;
85
- $crontime = ( isset( $_POST['crondate'] ) ) ? $_POST['crontime'] : 0;
86
  if ( $email_freq !== $this->subscribe2_options['email_freq'] || date_i18n( get_option( 'date_format' ), $scheduled_time + $timestamp_offset ) !== $crondate || date( 'G', $scheduled_time + $timestamp_offset ) !== $crontime ) {
87
  $this->subscribe2_options['email_freq'] = $email_freq;
88
  wp_clear_scheduled_hook( 's2_digest_cron' );
89
- $scheds = (array) wp_get_schedules();
90
  $interval = ( isset( $scheds[ $email_freq ]['interval'] ) ) ? (int) $scheds[ $email_freq ]['interval'] : 0;
91
  if ( 0 === $interval ) {
92
  // if we are on per-post emails remove last_cron entry
93
  unset( $this->subscribe2_options['last_s2cron'] );
94
  } else {
95
  // if we are using digest schedule the event and prime last_cron as now
96
- $time = time() + $interval;
97
- $srttimestamp = strtotime( $crondate ) + ($crontime * 60 * 60);
98
- if ( false === $srttimestamp || 0 === $srttimestamp ) {
99
  $srttimestamp = time();
100
  }
101
  $timestamp = $srttimestamp - $timestamp_offset;
@@ -123,12 +123,18 @@ if ( isset( $_POST['s2_admin'] ) ) {
123
  }
124
 
125
  // send error message if no WordPress page exists
126
- $sql = "SELECT ID FROM $wpdb->posts WHERE post_type='page' AND post_status='publish' LIMIT 1";
127
- $id = $wpdb->get_var( $sql );
128
  if ( empty( $id ) ) {
129
  echo '<div id="page_message" class="error"><p class="s2_error"><strong>' . __( 'You must create a WordPress page for this plugin to work correctly.', 'subscribe2' ) . '</strong></p></div>';
130
  }
131
 
 
 
 
 
 
 
 
132
  if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
133
  $disallowed_keywords = array( '{TITLE}', '{TITLETEXT}', '{PERMALINK}', '{PERMAURL}', '{DATE}', '{TIME}', '{LINK}', '{ACTION}', '{REFERENCELINKS}' );
134
  } else {
@@ -152,10 +158,11 @@ if ( 'blogname' === $this->subscribe2_options['sender'] ) {
152
  $sender = get_bloginfo( 'admin_email' );
153
  } else {
154
  $userdata = $this->get_userdata( $this->subscribe2_options['sender'] );
155
- $sender = $userdata->user_email;
156
  }
157
  list( $user, $domain ) = explode( '@', $sender, 2 );
158
  if ( ! stristr( esc_html( $_SERVER['SERVER_NAME'] ), $domain ) && 'author' !== $this->subscribe2_options['sender'] && '0' === $this->subscribe2_options['dismiss_sender_warning'] ) {
 
159
  echo '<div id="sender_message" class="error notice is-dismissible"><p class="s2_error"><strong>' . sprintf( __( 'You appear to be sending notifications from %1$s, which has a different domain name than your blog server %2$s. This may result in failed emails.', 'subscribe2' ), $sender, $_SERVER['SERVER_NAME'] ) . '</strong></p></div>';
160
  }
161
 
@@ -166,15 +173,15 @@ $current_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'email';
166
  echo '<div class="wrap">';
167
  echo '<h1>' . __( 'Settings', 'subscribe2' ) . '</h1>' . "\r\n";
168
  $tabs = array(
169
- 'email' => __( 'Email Settings', 'subscribe2' ),
170
- 'templates' => __( 'Templates', 'subscribe2' ),
171
  'registered' => __( 'Registered Users', 'subscribe2' ),
172
  'appearance' => __( 'Appearance', 'subscribe2' ),
173
- 'misc' => __( 'Miscellaneous', 'subscribe2' ),
174
- );
175
  echo '<h2 class="nav-tab-wrapper">';
176
  foreach ( $tabs as $tab_key => $tab_caption ) {
177
- $active = ($current_tab === $tab_key) ? 'nav-tab-active' : '';
178
  echo '<a class="nav-tab ' . $active . '" href="?page=s2_settings&amp;tab=' . $tab_key . '">' . $tab_caption . '</a>';
179
  }
180
  echo '</h2>';
@@ -185,7 +192,6 @@ wp_nonce_field( 'subscribe2-options_subscribers' . S2VERSION );
185
 
186
  echo '<input type="hidden" name="s2_admin" value="options" />' . "\r\n";
187
  echo '<input type="hidden" id="jsbcclimit" value="' . $this->subscribe2_options['bcclimit'] . '" />';
188
- echo '<input type="hidden" id="jsentries" value="' . $this->subscribe2_options['entries'] . '" />';
189
 
190
  switch ( $current_tab ) {
191
  case 'email':
@@ -194,11 +200,11 @@ switch ( $current_tab ) {
194
  echo '<p>' . "\r\n";
195
  echo __( 'Restrict the number of <strong>recipients per email</strong> to (0 for unlimited)', 'subscribe2' ) . ': ';
196
  echo '<span id="s2bcclimit_1"><span id="s2bcclimit" style="background-color: #FFFBCC">' . $this->subscribe2_options['bcclimit'] . '</span> ';
197
- echo '<a href="#" onclick="s2_show(\'bcclimit\'); return false;">' . __( 'Edit', 'subscribe2' ) . '</a></span>' . "\r\n";
198
  echo '<span id="s2bcclimit_2">' . "\r\n";
199
  echo '<input type="text" name="bcclimit" value="' . $this->subscribe2_options['bcclimit'] . '" size="3" />' . "\r\n";
200
- echo '<a href="#" onclick="s2_update(\'bcclimit\'); return false;">' . __( 'Update', 'subscribe2' ) . '</a>' . "\r\n";
201
- echo '<a href="#" onclick="s2_revert(\'bcclimit\'); return false;">' . __( 'Revert', 'subscribe2' ) . '</a></span>' . "\n";
202
 
203
  echo '<br /><br />' . __( 'Send Admins notifications for new', 'subscribe2' ) . ': ';
204
  echo '<label><input type="radio" name="admin_email" value="subs"' . checked( $this->subscribe2_options['admin_email'], 'subs', false ) . ' />' . "\r\n";
@@ -226,7 +232,7 @@ switch ( $current_tab ) {
226
  $types = '';
227
  echo __( 'Subscribe2 will send email notifications for the following custom post types', 'subscribe2' ) . ': <strong>';
228
  foreach ( $s2_post_types as $type ) {
229
- ('' === $types) ? $types = ucwords( $type ) : $types .= ', ' . ucwords( $type );
230
  }
231
  echo $types . '</strong><br /><br />' . "\r\n";
232
  }
@@ -240,11 +246,13 @@ switch ( $current_tab ) {
240
  echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
241
  echo '<label><input type="radio" name="private" value="no"' . checked( $this->subscribe2_options['private'], 'no', false ) . ' /> ';
242
  echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
243
- echo __( 'Include Sticky Posts at the top of all Digest Notifications', 'subscribe2' ) . ': ';
244
- echo '<label><input type="radio" name="stickies" value="yes"' . checked( $this->subscribe2_options['stickies'], 'yes', false ) . ' /> ';
245
- echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
246
- echo '<label><input type="radio" name="stickies" value="no"' . checked( $this->subscribe2_options['stickies'], 'no', false ) . ' /> ';
247
- echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
 
 
248
  echo __( 'Send Email From', 'subscribe2' ) . ': ';
249
  echo '<label>' . "\r\n";
250
  $this->admin_dropdown( true );
@@ -263,7 +271,7 @@ switch ( $current_tab ) {
263
  echo '<br />' . __( 'eg. utm_source=subscribe2&amp;utm_medium=email&amp;utm_campaign=postnotify&amp;utm_id={ID}&amp;utm_title={TITLE}', 'subscribe2' ) . "\r\n";
264
  echo '</p>' . "\r\n";
265
  echo '</div>' . "\r\n";
266
- break;
267
 
268
  case 'templates':
269
  // email templates
@@ -280,7 +288,7 @@ switch ( $current_tab ) {
280
  echo '<p class="submit"><input type="submit" class="button-secondary" name="preview" value="' . __( 'Send Email Preview', 'subscribe2' ) . '" /></p>' . "\r\n";
281
  echo '<h3>' . __( 'Message substitutions', 'subscribe2' ) . '</h3>' . "\r\n";
282
  echo '<dl>';
283
- echo '<dt><b><em style="color: red">' . __( 'IF THE FOLLOWING KEYWORDS ARE ALSO IN YOUR POST THEY WILL BE SUBSTITUTED' ,'subscribe2' ) . '</em></b></dt><dd></dd>' . "\r\n";
284
  echo '<dt><b>{BLOGNAME}</b></dt><dd>' . get_option( 'blogname' ) . '</dd>' . "\r\n";
285
  echo '<dt><b>{BLOGLINK}</b></dt><dd>' . get_option( 'home' ) . '</dd>' . "\r\n";
286
  echo '<dt><b>{TITLE}</b></dt><dd>' . __( "the post's title<br />(<i>for per-post emails only</i>)", 'subscribe2' ) . '</dd>' . "\r\n";
@@ -315,12 +323,12 @@ switch ( $current_tab ) {
315
  echo '<textarea rows="9" cols="60" name="remind_email">' . stripslashes( $this->subscribe2_options['remind_email'] ) . '</textarea><br /><br />' . "\r\n";
316
  echo '</td></tr></table>' . "\r\n";
317
  echo '</div>' . "\r\n";
318
- break;
319
 
320
  case 'registered':
321
  // Access function to allow display for form elements
322
- require_once( S2PATH . 'classes/class-s2-forms.php' );
323
- $s2_forms = new s2_forms;
324
 
325
  // compulsory categories
326
  echo '<div class="s2_admin" id="s2_compulsory_categories">' . "\r\n";
@@ -361,8 +369,10 @@ switch ( $current_tab ) {
361
  echo '<h3>' . __( 'Auto-Subscribe', 'subscribe2' ) . '</h3>' . "\r\n";
362
  echo '<p>' . "\r\n";
363
  echo __( 'Subscribe new users registering with your blog', 'subscribe2' ) . ':<br />' . "\r\n";
364
- echo '<label><input type="radio" name="autosub" value="yes"' . checked( $this->subscribe2_options['autosub'], 'yes', false ) . ' /> ';
365
- echo __( 'Automatically', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
 
 
366
  echo '<label><input type="radio" name="autosub" value="wpreg"' . checked( $this->subscribe2_options['autosub'], 'wpreg', false ) . ' /> ';
367
  echo __( 'Display option on Registration Form', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
368
  echo '<label><input type="radio" name="autosub" value="no"' . checked( $this->subscribe2_options['autosub'], 'no', false ) . ' /> ';
@@ -372,11 +382,13 @@ switch ( $current_tab ) {
372
  echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
373
  echo '<label><input type="radio" name="newreg_override" value="no"' . checked( $this->subscribe2_options['newreg_override'], 'no', false ) . ' /> ';
374
  echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
375
- echo __( 'Registration Form option is checked by default', 'subscribe2' ) . ':<br />' . "\r\n";
376
- echo '<label><input type="radio" name="wpregdef" value="yes"' . checked( $this->subscribe2_options['wpregdef'], 'yes', false ) . ' /> ';
377
- echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
378
- echo '<label><input type="radio" name="wpregdef" value="no"' . checked( $this->subscribe2_options['wpregdef'], 'no', false ) . ' /> ';
379
- echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
 
 
380
  echo __( 'Auto-subscribe users to receive email as', 'subscribe2' ) . ': <br />' . "\r\n";
381
  echo '<label><input type="radio" name="autoformat" value="html"' . checked( $this->subscribe2_options['autoformat'], 'html', false ) . ' /> ';
382
  echo __( 'HTML - Full', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
@@ -393,11 +405,13 @@ switch ( $current_tab ) {
393
  echo __( 'No', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
394
  echo '<label><input type="radio" name="show_autosub" value="exclude"' . checked( $this->subscribe2_options['show_autosub'], 'exclude', false ) . ' /> ';
395
  echo __( 'New categories are immediately excluded', 'subscribe2' ) . '</label><br /><br />';
396
- echo __( 'Option for Registered Users to auto-subscribe to new categories is checked by default', 'subscribe2' ) . ': <br />' . "\r\n";
397
- echo '<label><input type="radio" name="autosub_def" value="yes"' . checked( $this->subscribe2_options['autosub_def'], 'yes', false ) . ' /> ';
398
- echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
399
- echo '<label><input type="radio" name="autosub_def" value="no"' . checked( $this->subscribe2_options['autosub_def'], 'no', false ) . ' /> ';
400
- echo __( 'No', 'subscribe2' ) . '</label><br /><br />';
 
 
401
  // Hide these options if using Jetpack Comments
402
  if ( ! class_exists( 'Jetpack_Comments' ) ) {
403
  echo __( 'Display checkbox to allow subscriptions from the comment form', 'subscribe2' ) . ': <br />' . "\r\n";
@@ -407,11 +421,13 @@ switch ( $current_tab ) {
407
  echo __( 'After the Comment Submit button', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
408
  echo '<label><input type="radio" name="comment_subs" value="no"' . checked( $this->subscribe2_options['comment_subs'], 'no', false ) . ' /> ';
409
  echo __( 'No', 'subscribe2' ) . '</label><br /><br />';
410
- echo __( 'Comment form checkbox is checked by default', 'subscribe2' ) . ': <br />' . "\r\n";
411
- echo '<label><input type="radio" name="comment_def" value="yes"' . checked( $this->subscribe2_options['comment_def'], 'yes', false ) . ' /> ';
412
- echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
413
- echo '<label><input type="radio" name="comment_def" value="no"' . checked( $this->subscribe2_options['comment_def'], 'no', false ) . ' /> ';
414
- echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
 
 
415
  }
416
  echo __( 'Show one-click subscription on profile page', 'subscribe2' ) . ':<br />' . "\r\n";
417
  echo '<label><input type="radio" name="one_click_profile" value="yes"' . checked( $this->subscribe2_options['one_click_profile'], 'yes', false ) . ' /> ';
@@ -419,12 +435,12 @@ switch ( $current_tab ) {
419
  echo '<label><input type="radio" name="one_click_profile" value="no"' . checked( $this->subscribe2_options['one_click_profile'], 'no', false ) . ' /> ';
420
  echo __( 'No', 'subscribe2' ) . '</label>' . "\r\n";
421
  echo '</p></div>' . "\r\n";
422
- break;
423
 
424
  case 'appearance':
425
  // Appearance options
426
  echo '<div class="s2_admin" id="s2_appearance_settings">' . "\r\n";
427
- echo '<input type="hidden" name="appearance_users_tab" value="options" />' . "\r\n";
428
  echo '<p>' . "\r\n";
429
 
430
  // WordPress page ID where subscribe2 token is used
@@ -434,15 +450,6 @@ switch ( $current_tab ) {
434
  $this->pages_dropdown( $this->subscribe2_options['s2page'] );
435
  echo '</select>' . "\r\n";
436
 
437
- // Number of subscribers per page
438
- echo '<br /><br />' . __( 'Set the number of Subscribers displayed per page', 'subscribe2' ) . ': ';
439
- echo '<span id="s2entries_1"><span id="s2entries" style="background-color: #FFFBCC">' . $this->subscribe2_options['entries'] . '</span> ';
440
- echo '<a href="#" onclick="s2_show(\'entries\'); return false;">' . __( 'Edit', 'subscribe2' ) . '</a></span>' . "\r\n";
441
- echo '<span id="s2entries_2">' . "\r\n";
442
- echo '<input type="text" name="entries" value="' . $this->subscribe2_options['entries'] . '" size="3" />' . "\r\n";
443
- echo '<a href="#" onclick="s2_update(\'entries\'); return false;">' . __( 'Update', 'subscribe2' ) . '</a>' . "\r\n";
444
- echo '<a href="#" onclick="s2_revert(\'entries\'); return false;">' . __( 'Revert', 'subscribe2' ) . '</a></span>' . "\r\n";
445
-
446
  // show link to WordPress page in meta
447
  echo '<br /><br /><label><input type="checkbox" name="show_meta" value="1"' . checked( $this->subscribe2_options['show_meta'], '1', false ) . ' /> ';
448
  echo __( 'Show a link to your subscription page in "meta"?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
@@ -466,25 +473,30 @@ switch ( $current_tab ) {
466
  // s2_meta checked by default
467
  echo '<label><input type="checkbox" name="s2meta_default" value="1"' . checked( $this->subscribe2_options['s2meta_default'], '1', false ) . ' /> ';
468
  echo __( 'Disable email notifications is checked by default on authoring pages?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
 
 
 
 
469
  echo '</p>';
470
  echo '</div>' . "\r\n";
471
- break;
472
 
473
  case 'misc':
474
  //barred domains
475
  echo '<div class="s2_admin" id="s2_barred_domains">' . "\r\n";
476
  echo '<h3>' . __( 'Barred Domains', 'subscribe2' ) . '</h3>' . "\r\n";
477
  echo '<p>' . "\r\n";
478
- echo __( 'Enter domains to bar from public subscriptions (wildcards allowed): <br /> (Use a new line for each entry and omit the "@" symbol, for example *.email.com or yahoo.*)', 'subscribe2' );
 
479
  echo "\r\n" . '<br /><textarea style="width: 98%;" rows="4" cols="60" name="barred">' . esc_textarea( $this->subscribe2_options['barred'] ) . '</textarea>';
480
  echo '</p>';
481
  echo '<h3>' . __( 'Links', 'subscribe2' ) . '</h3>' . "\r\n";
482
- echo '<a href="http://wordpress.org/extend/plugins/subscribe2/">' . __( 'Plugin Site', 'subscribe2' ) . '</a><br />';
483
  echo '<a href="http://wordpress.org/support/plugin/subscribe2">' . __( 'Plugin Forum', 'subscribe2' ) . '</a><br />';
484
  echo '<a href="http://subscribe2.wordpress.com/">' . __( 'Plugin Blog', 'subscribe2' ) . '</a><br />';
485
  echo '<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=2387904">' . __( 'Make a donation via PayPal', 'subscribe2' ) . '</a>';
486
  echo '</div>' . "\r\n";
487
- break;
488
 
489
  }
490
  // submit
@@ -500,7 +512,6 @@ if ( 'misc' === $current_tab ) {
500
  }
501
  echo '</form></div>' . "\r\n";
502
 
503
- include( ABSPATH . 'wp-admin/admin-footer.php' );
504
  // just to be sure
505
  die;
506
- ?>
12
  }
13
 
14
  if ( isset( $_POST['reset'] ) ) {
15
+ require_once S2PATH . 'classes/class-s2-upgrade.php';
16
+ global $s2_upgrade;
17
+ $s2_upgrade = new S2_Upgrade();
18
+ $s2_upgrade->reset();
19
  echo '<div id="message" class="updated fade"><p><strong>' . __( 'Options reset!', 'subscribe2' ) . '</strong></p></div>';
20
  } elseif ( isset( $_POST['preview'] ) ) {
21
  global $user_email, $post;
22
  $this->preview_email = true;
23
  if ( 'never' === $this->subscribe2_options['email_freq'] ) {
24
  $posts = get_posts( 'numberposts=1' );
25
+ $post = $posts[0];
26
  $this->publish( $post, $user_email );
27
  } else {
28
  do_action( 's2_digest_preview', $user_email );
38
  }
39
  } elseif ( isset( $_POST['submit'] ) ) {
40
  foreach ( $_POST as $key => $value ) {
41
+ if ( in_array( $key, array( 'bcclimit', 's2page' ) ) ) {
42
  // numerical inputs fixed for old option names
43
+ if ( is_numeric( $_POST[ $key ] ) && $_POST[ $key ] >= 0 ) {
 
 
44
  $this->subscribe2_options[ $key ] = (int) $_POST[ $key ];
45
  }
46
  } elseif ( in_array( $key, array( 'show_meta', 'show_button', 'ajax', 'widget', 'counterwidget', 's2meta_default', 'reg_override' ) ) ) {
47
  // check box entries
48
+ ( isset( $_POST[ $key ] ) && '1' === $_POST[ $key ] ) ? $this->subscribe2_options[ $key ] = '1' : $this->subscribe2_options[ $key ] = '0';
49
+ } elseif ( 'appearance_tab' === $key ) {
 
50
  $options = array( 'show_meta', 'show_button', 'ajax', 'widget', 'counterwidget', 's2meta_default' );
51
  foreach ( $options as $option ) {
52
  if ( ! isset( $_POST[ $option ] ) ) {
53
+ $this->subscribe2_options[ $option ] = '0';
54
  }
55
  }
56
  } elseif ( in_array( $key, array( 'notification_subject', 'mailtext', 'confirm_subject', 'confirm_email', 'remind_subject', 'remind_email', 's2_license_key' ) ) && ! empty( $_POST[ $key ] ) ) {
78
  }
79
  } elseif ( 'email_freq' === $key ) {
80
  // send per-post or digest emails
81
+ $email_freq = $_POST['email_freq'];
82
+ $scheduled_time = wp_next_scheduled( 's2_digest_cron' );
83
  $timestamp_offset = get_option( 'gmt_offset' ) * 60 * 60;
84
+ $crondate = ( isset( $_POST['crondate'] ) ) ? $_POST['crondate'] : 0;
85
+ $crontime = ( isset( $_POST['crondate'] ) ) ? $_POST['crontime'] : 0;
86
  if ( $email_freq !== $this->subscribe2_options['email_freq'] || date_i18n( get_option( 'date_format' ), $scheduled_time + $timestamp_offset ) !== $crondate || date( 'G', $scheduled_time + $timestamp_offset ) !== $crontime ) {
87
  $this->subscribe2_options['email_freq'] = $email_freq;
88
  wp_clear_scheduled_hook( 's2_digest_cron' );
89
+ $scheds = (array) wp_get_schedules();
90
  $interval = ( isset( $scheds[ $email_freq ]['interval'] ) ) ? (int) $scheds[ $email_freq ]['interval'] : 0;
91
  if ( 0 === $interval ) {
92
  // if we are on per-post emails remove last_cron entry
93
  unset( $this->subscribe2_options['last_s2cron'] );
94
  } else {
95
  // if we are using digest schedule the event and prime last_cron as now
96
+ $time = time() + $interval;
97
+ $srttimestamp = strtotime( $crondate ) + ( $crontime * 60 * 60 );
98
+ if ( false === $srttimestamp || 0 === $srttimestamp ) {
99
  $srttimestamp = time();
100
  }
101
  $timestamp = $srttimestamp - $timestamp_offset;
123
  }
124
 
125
  // send error message if no WordPress page exists
126
+ $id = $wpdb->get_var( "SELECT ID FROM `{$wpdb->prefix}posts` WHERE post_type='page' AND post_status='publish' LIMIT 1" );
 
127
  if ( empty( $id ) ) {
128
  echo '<div id="page_message" class="error"><p class="s2_error"><strong>' . __( 'You must create a WordPress page for this plugin to work correctly.', 'subscribe2' ) . '</strong></p></div>';
129
  }
130
 
131
+ // display error message for GDPR
132
+ if ( defined( 'S2GDPR' ) && true === S2GDPR ) {
133
+ if ( 'yes' === $this->subscribe2_options['wpregdef'] || 'yes' === $this->subscribe2_options['autosub_def'] || 'yes' === $this->subscribe2_options['autosub_def'] || 'yes' === $this->subscribe2_options['comment_def'] ) {
134
+ echo '<div id="gdpr_message" class="error"><p class="s2_error"><strong>' . __( 'Your Settings may breach GDPR', 'subscribe2' ) . '</strong></p></div>';
135
+ }
136
+ }
137
+
138
  if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
139
  $disallowed_keywords = array( '{TITLE}', '{TITLETEXT}', '{PERMALINK}', '{PERMAURL}', '{DATE}', '{TIME}', '{LINK}', '{ACTION}', '{REFERENCELINKS}' );
140
  } else {
158
  $sender = get_bloginfo( 'admin_email' );
159
  } else {
160
  $userdata = $this->get_userdata( $this->subscribe2_options['sender'] );
161
+ $sender = $userdata->user_email;
162
  }
163
  list( $user, $domain ) = explode( '@', $sender, 2 );
164
  if ( ! stristr( esc_html( $_SERVER['SERVER_NAME'] ), $domain ) && 'author' !== $this->subscribe2_options['sender'] && '0' === $this->subscribe2_options['dismiss_sender_warning'] ) {
165
+ // Translators: Warning message
166
  echo '<div id="sender_message" class="error notice is-dismissible"><p class="s2_error"><strong>' . sprintf( __( 'You appear to be sending notifications from %1$s, which has a different domain name than your blog server %2$s. This may result in failed emails.', 'subscribe2' ), $sender, $_SERVER['SERVER_NAME'] ) . '</strong></p></div>';
167
  }
168
 
173
  echo '<div class="wrap">';
174
  echo '<h1>' . __( 'Settings', 'subscribe2' ) . '</h1>' . "\r\n";
175
  $tabs = array(
176
+ 'email' => __( 'Email Settings', 'subscribe2' ),
177
+ 'templates' => __( 'Templates', 'subscribe2' ),
178
  'registered' => __( 'Registered Users', 'subscribe2' ),
179
  'appearance' => __( 'Appearance', 'subscribe2' ),
180
+ 'misc' => __( 'Miscellaneous', 'subscribe2' ),
181
+ );
182
  echo '<h2 class="nav-tab-wrapper">';
183
  foreach ( $tabs as $tab_key => $tab_caption ) {
184
+ $active = ( $current_tab === $tab_key ) ? 'nav-tab-active' : '';
185
  echo '<a class="nav-tab ' . $active . '" href="?page=s2_settings&amp;tab=' . $tab_key . '">' . $tab_caption . '</a>';
186
  }
187
  echo '</h2>';
192
 
193
  echo '<input type="hidden" name="s2_admin" value="options" />' . "\r\n";
194
  echo '<input type="hidden" id="jsbcclimit" value="' . $this->subscribe2_options['bcclimit'] . '" />';
 
195
 
196
  switch ( $current_tab ) {
197
  case 'email':
200
  echo '<p>' . "\r\n";
201
  echo __( 'Restrict the number of <strong>recipients per email</strong> to (0 for unlimited)', 'subscribe2' ) . ': ';
202
  echo '<span id="s2bcclimit_1"><span id="s2bcclimit" style="background-color: #FFFBCC">' . $this->subscribe2_options['bcclimit'] . '</span> ';
203
+ echo '<a href="#" onclick="s2Show(\'bcclimit\'); return false;">' . __( 'Edit', 'subscribe2' ) . '</a></span>' . "\r\n";
204
  echo '<span id="s2bcclimit_2">' . "\r\n";
205
  echo '<input type="text" name="bcclimit" value="' . $this->subscribe2_options['bcclimit'] . '" size="3" />' . "\r\n";
206
+ echo '<a href="#" onclick="s2Update(\'bcclimit\'); return false;">' . __( 'Update', 'subscribe2' ) . '</a>' . "\r\n";
207
+ echo '<a href="#" onclick="s2Revert(\'bcclimit\'); return false;">' . __( 'Revert', 'subscribe2' ) . '</a></span>' . "\n";
208
 
209
  echo '<br /><br />' . __( 'Send Admins notifications for new', 'subscribe2' ) . ': ';
210
  echo '<label><input type="radio" name="admin_email" value="subs"' . checked( $this->subscribe2_options['admin_email'], 'subs', false ) . ' />' . "\r\n";
232
  $types = '';
233
  echo __( 'Subscribe2 will send email notifications for the following custom post types', 'subscribe2' ) . ': <strong>';
234
  foreach ( $s2_post_types as $type ) {
235
+ ( '' === $types ) ? $types = ucwords( $type ) : $types .= ', ' . ucwords( $type );
236
  }
237
  echo $types . '</strong><br /><br />' . "\r\n";
238
  }
246
  echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
247
  echo '<label><input type="radio" name="private" value="no"' . checked( $this->subscribe2_options['private'], 'no', false ) . ' /> ';
248
  echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
249
+ if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
250
+ echo __( 'Include Sticky Posts at the top of all Digest Notifications', 'subscribe2' ) . ': ';
251
+ echo '<label><input type="radio" name="stickies" value="yes"' . checked( $this->subscribe2_options['stickies'], 'yes', false ) . ' /> ';
252
+ echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
253
+ echo '<label><input type="radio" name="stickies" value="no"' . checked( $this->subscribe2_options['stickies'], 'no', false ) . ' /> ';
254
+ echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
255
+ }
256
  echo __( 'Send Email From', 'subscribe2' ) . ': ';
257
  echo '<label>' . "\r\n";
258
  $this->admin_dropdown( true );
271
  echo '<br />' . __( 'eg. utm_source=subscribe2&amp;utm_medium=email&amp;utm_campaign=postnotify&amp;utm_id={ID}&amp;utm_title={TITLE}', 'subscribe2' ) . "\r\n";
272
  echo '</p>' . "\r\n";
273
  echo '</div>' . "\r\n";
274
+ break;
275
 
276
  case 'templates':
277
  // email templates
288
  echo '<p class="submit"><input type="submit" class="button-secondary" name="preview" value="' . __( 'Send Email Preview', 'subscribe2' ) . '" /></p>' . "\r\n";
289
  echo '<h3>' . __( 'Message substitutions', 'subscribe2' ) . '</h3>' . "\r\n";
290
  echo '<dl>';
291
+ echo '<dt><b><em style="color: red">' . __( 'IF THE FOLLOWING KEYWORDS ARE ALSO IN YOUR POST THEY WILL BE SUBSTITUTED', 'subscribe2' ) . '</em></b></dt><dd></dd>' . "\r\n";
292
  echo '<dt><b>{BLOGNAME}</b></dt><dd>' . get_option( 'blogname' ) . '</dd>' . "\r\n";
293
  echo '<dt><b>{BLOGLINK}</b></dt><dd>' . get_option( 'home' ) . '</dd>' . "\r\n";
294
  echo '<dt><b>{TITLE}</b></dt><dd>' . __( "the post's title<br />(<i>for per-post emails only</i>)", 'subscribe2' ) . '</dd>' . "\r\n";
323
  echo '<textarea rows="9" cols="60" name="remind_email">' . stripslashes( $this->subscribe2_options['remind_email'] ) . '</textarea><br /><br />' . "\r\n";
324
  echo '</td></tr></table>' . "\r\n";
325
  echo '</div>' . "\r\n";
326
+ break;
327
 
328
  case 'registered':
329
  // Access function to allow display for form elements
330
+ require_once S2PATH . 'classes/class-s2-forms.php';
331
+ $s2_forms = new s2_forms();
332
 
333
  // compulsory categories
334
  echo '<div class="s2_admin" id="s2_compulsory_categories">' . "\r\n";
369
  echo '<h3>' . __( 'Auto-Subscribe', 'subscribe2' ) . '</h3>' . "\r\n";
370
  echo '<p>' . "\r\n";
371
  echo __( 'Subscribe new users registering with your blog', 'subscribe2' ) . ':<br />' . "\r\n";
372
+ if ( defined( 'S2GDPR' ) && ( true === S2GDPR && 'yes' === $this->subscribe2_options['autosub'] ) || ( false === S2GDPR ) ) {
373
+ echo '<label><input type="radio" name="autosub" value="yes"' . checked( $this->subscribe2_options['autosub'], 'yes', false ) . ' /> ';
374
+ echo __( 'Automatically', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
375
+ }
376
  echo '<label><input type="radio" name="autosub" value="wpreg"' . checked( $this->subscribe2_options['autosub'], 'wpreg', false ) . ' /> ';
377
  echo __( 'Display option on Registration Form', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
378
  echo '<label><input type="radio" name="autosub" value="no"' . checked( $this->subscribe2_options['autosub'], 'no', false ) . ' /> ';
382
  echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
383
  echo '<label><input type="radio" name="newreg_override" value="no"' . checked( $this->subscribe2_options['newreg_override'], 'no', false ) . ' /> ';
384
  echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
385
+ if ( defined( 'S2GDPR' ) && ( true === S2GDPR && 'yes' === $this->subscribe2_options['wpregdef'] ) || ( false === S2GDPR ) ) {
386
+ echo __( 'Registration Form option is checked by default', 'subscribe2' ) . ':<br />' . "\r\n";
387
+ echo '<label><input type="radio" name="wpregdef" value="yes"' . checked( $this->subscribe2_options['wpregdef'], 'yes', false ) . ' /> ';
388
+ echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
389
+ echo '<label><input type="radio" name="wpregdef" value="no"' . checked( $this->subscribe2_options['wpregdef'], 'no', false ) . ' /> ';
390
+ echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
391
+ }
392
  echo __( 'Auto-subscribe users to receive email as', 'subscribe2' ) . ': <br />' . "\r\n";
393
  echo '<label><input type="radio" name="autoformat" value="html"' . checked( $this->subscribe2_options['autoformat'], 'html', false ) . ' /> ';
394
  echo __( 'HTML - Full', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
405
  echo __( 'No', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
406
  echo '<label><input type="radio" name="show_autosub" value="exclude"' . checked( $this->subscribe2_options['show_autosub'], 'exclude', false ) . ' /> ';
407
  echo __( 'New categories are immediately excluded', 'subscribe2' ) . '</label><br /><br />';
408
+ if ( defined( 'S2GDPR' ) && ( true === S2GDPR && 'yes' === $this->subscribe2_options['autosub_def'] ) || ( false === S2GDPR ) ) {
409
+ echo __( 'Option for Registered Users to auto-subscribe to new categories is checked by default', 'subscribe2' ) . ': <br />' . "\r\n";
410
+ echo '<label><input type="radio" name="autosub_def" value="yes"' . checked( $this->subscribe2_options['autosub_def'], 'yes', false ) . ' /> ';
411
+ echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
412
+ echo '<label><input type="radio" name="autosub_def" value="no"' . checked( $this->subscribe2_options['autosub_def'], 'no', false ) . ' /> ';
413
+ echo __( 'No', 'subscribe2' ) . '</label><br /><br />';
414
+ }
415
  // Hide these options if using Jetpack Comments
416
  if ( ! class_exists( 'Jetpack_Comments' ) ) {
417
  echo __( 'Display checkbox to allow subscriptions from the comment form', 'subscribe2' ) . ': <br />' . "\r\n";
421
  echo __( 'After the Comment Submit button', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
422
  echo '<label><input type="radio" name="comment_subs" value="no"' . checked( $this->subscribe2_options['comment_subs'], 'no', false ) . ' /> ';
423
  echo __( 'No', 'subscribe2' ) . '</label><br /><br />';
424
+ if ( defined( 'S2GDPR' ) && ( true === S2GDPR && 'yes' === $this->subscribe2_options['comment_def'] ) || ( false === S2GDPR ) ) {
425
+ echo __( 'Comment form checkbox is checked by default', 'subscribe2' ) . ': <br />' . "\r\n";
426
+ echo '<label><input type="radio" name="comment_def" value="yes"' . checked( $this->subscribe2_options['comment_def'], 'yes', false ) . ' /> ';
427
+ echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
428
+ echo '<label><input type="radio" name="comment_def" value="no"' . checked( $this->subscribe2_options['comment_def'], 'no', false ) . ' /> ';
429
+ echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
430
+ }
431
  }
432
  echo __( 'Show one-click subscription on profile page', 'subscribe2' ) . ':<br />' . "\r\n";
433
  echo '<label><input type="radio" name="one_click_profile" value="yes"' . checked( $this->subscribe2_options['one_click_profile'], 'yes', false ) . ' /> ';
435
  echo '<label><input type="radio" name="one_click_profile" value="no"' . checked( $this->subscribe2_options['one_click_profile'], 'no', false ) . ' /> ';
436
  echo __( 'No', 'subscribe2' ) . '</label>' . "\r\n";
437
  echo '</p></div>' . "\r\n";
438
+ break;
439
 
440
  case 'appearance':
441
  // Appearance options
442
  echo '<div class="s2_admin" id="s2_appearance_settings">' . "\r\n";
443
+ echo '<input type="hidden" name="appearance_tab" value="options" />' . "\r\n";
444
  echo '<p>' . "\r\n";
445
 
446
  // WordPress page ID where subscribe2 token is used
450
  $this->pages_dropdown( $this->subscribe2_options['s2page'] );
451
  echo '</select>' . "\r\n";
452
 
 
 
 
 
 
 
 
 
 
453
  // show link to WordPress page in meta
454
  echo '<br /><br /><label><input type="checkbox" name="show_meta" value="1"' . checked( $this->subscribe2_options['show_meta'], '1', false ) . ' /> ';
455
  echo __( 'Show a link to your subscription page in "meta"?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
473
  // s2_meta checked by default
474
  echo '<label><input type="checkbox" name="s2meta_default" value="1"' . checked( $this->subscribe2_options['s2meta_default'], '1', false ) . ' /> ';
475
  echo __( 'Disable email notifications is checked by default on authoring pages?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
476
+
477
+ // Subscription form for Registered Users on Frontend
478
+ echo '<label><input type="checkbox" name="js_ip_updater" value="1"' . checked( $this->subscribe2_options['js_ip_updater'], '1', false ) . ' /> ';
479
+ echo __( 'Use javascript to update IP address in Subscribe2 HTML form data? (useful if caching is enabled)', 'subscribe2' ) . '</label>' . "\r\n";
480
  echo '</p>';
481
  echo '</div>' . "\r\n";
482
+ break;
483
 
484
  case 'misc':
485
  //barred domains
486
  echo '<div class="s2_admin" id="s2_barred_domains">' . "\r\n";
487
  echo '<h3>' . __( 'Barred Domains', 'subscribe2' ) . '</h3>' . "\r\n";
488
  echo '<p>' . "\r\n";
489
+ echo __( 'Enter domains to bar for public subscriptions, wildcards (*) and exceptions (!) are allowed', 'subscribe2' ) . '<br />' . "\r\n";
490
+ echo __( 'Use a new line for each entry and omit the "@" symbol, for example !email.com, hotmail.com, yahoo.*', 'subscribe2' );
491
  echo "\r\n" . '<br /><textarea style="width: 98%;" rows="4" cols="60" name="barred">' . esc_textarea( $this->subscribe2_options['barred'] ) . '</textarea>';
492
  echo '</p>';
493
  echo '<h3>' . __( 'Links', 'subscribe2' ) . '</h3>' . "\r\n";
494
+ echo '<a href="http://wordpress.org/plugins/subscribe2/">' . __( 'Plugin Site', 'subscribe2' ) . '</a><br />';
495
  echo '<a href="http://wordpress.org/support/plugin/subscribe2">' . __( 'Plugin Forum', 'subscribe2' ) . '</a><br />';
496
  echo '<a href="http://subscribe2.wordpress.com/">' . __( 'Plugin Blog', 'subscribe2' ) . '</a><br />';
497
  echo '<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=2387904">' . __( 'Make a donation via PayPal', 'subscribe2' ) . '</a>';
498
  echo '</div>' . "\r\n";
499
+ break;
500
 
501
  }
502
  // submit
512
  }
513
  echo '</form></div>' . "\r\n";
514
 
515
+ require ABSPATH . 'wp-admin/admin-footer.php';
516
  // just to be sure
517
  die;
 
admin/subscribers.php CHANGED
@@ -9,64 +9,73 @@ global $wpdb, $subscribers, $what, $current_tab;
9
  $current_tab = isset( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'public';
10
 
11
  // Access function to allow display for form elements
12
- require_once( S2PATH . 'classes/class-s2-forms.php' );
13
- $s2_forms = new s2_forms;
14
 
15
  // Instantiate and prepare our table data - this also runs the bulk actions
16
  if ( ! class_exists( 'WP_List_Table' ) ) {
17
- require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
18
  }
19
  if ( ! class_exists( 'Subscribe2_List_Table' ) ) {
20
  if ( version_compare( $GLOBALS['wp_version'], '4.3', '<' ) ) {
21
- require_once( S2PATH . 'classes/class-s2-list-table-legacy.php' );
22
- $S2ListTable = new S2_List_Table_Legacy;
23
  } else {
24
- require_once( S2PATH . 'classes/class-s2-list-table.php' );
25
- $S2ListTable = new S2_List_Table;
26
  }
27
  }
28
 
29
  // was anything POSTed ?
30
  if ( isset( $_POST['s2_admin'] ) ) {
31
- if ( false === wp_verify_nonce( $_REQUEST['_wpnonce'], 'bulk-' . $S2ListTable->_args['plural'] ) ) {
32
  die( '<p>' . __( 'Security error! Your request cannot be completed.', 'subscribe2' ) . '</p>' );
33
  }
34
 
35
  if ( ! empty( $_POST['addresses'] ) ) {
36
  $reg_sub_error = '';
37
  $pub_sub_error = '';
38
- $unsub_error = '';
39
- $message = '';
 
40
  foreach ( preg_split( '/[\s,]+/', $_POST['addresses'] ) as $email ) {
41
  $email = $this->sanitize_email( $email );
42
- if ( is_email( $email ) && isset( $_POST['subscribe'] ) ) {
43
- if ( false !== $this->is_public( $email ) ) {
44
- ('' === $pub_sub_error) ? $pub_sub_error = "$email" : $pub_sub_error .= ", $email";
45
  continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
- if ( $this->is_registered( $email ) ) {
48
- ('' === $reg_sub_error) ? $reg_sub_error = "$email" : $reg_sub_error .= ", $email";
49
- continue;
50
- }
51
- $this->add( $email, true );
52
- $message = '<div id="message" class="updated fade"><p><strong>' . __( 'Address(es) subscribed!', 'subscribe2' ) . '</strong></p></div>';
53
- } elseif ( is_email( $email ) && isset( $_POST['unsubscribe'] ) ) {
54
- if ( false === $this->is_public( $email ) || $this->is_registered( $email ) ) {
55
- ('' === $unsub_error) ? $unsub_error = "$email" : $unsub_error .= ", $email";
56
- continue;
57
- }
58
- $this->delete( $email );
59
- $message = '<div id="message" class="updated fade"><p><strong>' . __( 'Address(es) unsubscribed!', 'subscribe2' ) . '</strong></p></div>';
60
  }
61
  }
62
  if ( '' !== $reg_sub_error ) {
63
- echo '<div id="message" class="error"><p><strong>' . __( 'Some emails were not processed, the following are already Registered Subscribers' , 'subscribe2' ) . ':<br />' . $reg_sub_error . '</strong></p></div>';
64
  }
65
  if ( '' !== $pub_sub_error ) {
66
- echo '<div id="message" class="error"><p><strong>' . __( 'Some emails were not processed, the following are already Public Subscribers' , 'subscribe2' ) . ':<br />' . $pub_sub_error . '</strong></p></div>';
67
  }
68
  if ( '' !== $unsub_error ) {
69
- echo '<div id="message" class="error"><p><strong>' . __( 'Some emails were not processed, the following were not in the database' , 'subscribe2' ) . ':<br /> ' . $unsub_error . '</strong></p></div>';
 
 
 
70
  }
71
  if ( '' !== $message ) {
72
  echo $message;
@@ -75,56 +84,93 @@ if ( isset( $_POST['s2_admin'] ) ) {
75
  } elseif ( isset( $_POST['remind'] ) ) {
76
  $this->remind( $_POST['reminderemails'] );
77
  echo '<div id="message" class="updated fade"><p><strong>' . __( 'Reminder Email(s) Sent!', 'subscribe2' ) . '</strong></p></div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  }
79
  }
80
 
81
  if ( 'registered' === $current_tab ) {
82
  // Get Registered Subscribers
83
  $registered = $this->get_registered( 'return=emailid' );
84
- $all_users = $this->get_all_registered( 'emailid' );
 
85
  // safety check for our arrays
86
- if ( '' === $registered ) { $registered = array(); }
87
- if ( '' === $all_users ) { $all_users = array(); }
 
 
 
 
88
  } else {
89
  //Get Public Subscribers
90
- $confirmed = $this->get_public();
91
  $unconfirmed = $this->get_public( 0 );
92
  // safety check for our arrays
93
- if ( '' === $confirmed ) { $confirmed = array(); }
94
- if ( '' === $unconfirmed ) { $unconfirmed = array(); }
 
 
 
 
95
  }
96
 
97
  $reminderform = false;
98
  if ( isset( $_REQUEST['what'] ) ) {
99
  if ( 'public' === $_REQUEST['what'] ) {
100
- $what = 'public';
101
  $subscribers = array_merge( (array) $confirmed, (array) $unconfirmed );
102
  } elseif ( 'confirmed' === $_REQUEST['what'] ) {
103
- $what = 'confirmed';
104
  $subscribers = $confirmed;
105
  } elseif ( 'unconfirmed' === $_REQUEST['what'] ) {
106
- $what = 'unconfirmed';
107
  $subscribers = $unconfirmed;
108
  if ( ! empty( $subscribers ) ) {
109
  $reminderemails = implode( ',', $subscribers );
110
- $reminderform = true;
111
  }
112
  } elseif ( is_numeric( $_REQUEST['what'] ) ) {
113
- $what = intval( $_REQUEST['what'] );
114
  $subscribers = $this->get_registered( "cats=$what&return=emailid" );
115
  } elseif ( 'registered' === $_REQUEST['what'] ) {
116
- $what = 'registered';
117
  $subscribers = $registered;
118
  } elseif ( 'all_users' === $_REQUEST['what'] ) {
119
- $what = 'all_users';
120
  $subscribers = $all_users;
121
  }
122
  } else {
123
  if ( 'public' === $current_tab ) {
124
- $what = 'public';
125
  $subscribers = array_merge( (array) $confirmed, (array) $unconfirmed );
126
  } else {
127
- $what = 'all_users';
128
  $subscribers = $all_users;
129
  }
130
  }
@@ -146,18 +192,18 @@ if ( ! empty( $_POST['s'] ) ) {
146
  $subscribers = $result;
147
  }
148
 
149
- $S2ListTable->prepare_items();
150
 
151
  // show our form
152
  echo '<div class="wrap">';
153
  echo '<h1>' . __( 'Subscribers', 'subscribe2' ) . '</h1>' . "\r\n";
154
  $tabs = array(
155
- 'public' => __( 'Public Subscribers', 'subscribe2' ),
156
  'registered' => __( 'Registered Subscribers', 'subscribe2' ),
157
  );
158
  echo '<h2 class="nav-tab-wrapper">';
159
  foreach ( $tabs as $tab_key => $tab_caption ) {
160
- $active = ($current_tab === $tab_key) ? 'nav-tab-active' : '';
161
  echo '<a class="nav-tab ' . $active . '" href="?page=s2_tools&amp;tab=' . $tab_key . '">' . $tab_caption . '</a>';
162
  }
163
  echo '</h2>';
@@ -180,7 +226,7 @@ switch ( $current_tab ) {
180
  echo '<div class="s2_admin" id="s2_current_subscribers">' . "\r\n";
181
  echo '<h2>' . __( 'Current Subscribers', 'subscribe2' ) . '</h2>' . "\r\n";
182
  echo '<br />';
183
- $cats = $this->all_cats();
184
  $cat_ids = array();
185
  foreach ( $cats as $cat ) {
186
  $cat_ids[] = $cat->term_id;
@@ -221,7 +267,7 @@ if ( ! empty( $subscribers ) ) {
221
  } else {
222
  $exportcsv = '';
223
  foreach ( $subscribers as $subscriber ) {
224
- ('' === $exportcsv) ? $exportcsv = $subscriber['user_email'] : $exportcsv .= ",\r\n" . $subscriber['user_email'];
225
  }
226
  }
227
  echo '<td style="width: 25%; text-align: right;"><input type="hidden" name="exportcsv" value="' . $exportcsv . '" />' . "\r\n";
@@ -232,8 +278,8 @@ if ( ! empty( $subscribers ) ) {
232
  echo '</tr></table>';
233
 
234
  // output our subscriber table
235
- $S2ListTable->search_box( __( 'Search', 'subscribe2' ), 'search_id' );
236
- $S2ListTable->display();
237
  echo '</div>' . "\r\n";
238
 
239
  // show bulk management form if filtered in some Registered Users
@@ -245,6 +291,10 @@ if ( 'registered' === $current_tab ) {
245
  if ( isset( $_POST['category'] ) ) {
246
  $categories = $_POST['category'];
247
  }
 
 
 
 
248
  $format = '';
249
  if ( isset( $_POST['format'] ) ) {
250
  $format = $_POST['format'];
@@ -252,20 +302,20 @@ if ( 'registered' === $current_tab ) {
252
  echo __( 'Preferences for Registered Users selected above can be changed using this section.', 'subscribe2' ) . '<br />' . "\r\n";
253
  echo '<strong><em style="color: red">' . __( 'Consider User Privacy as changes cannot be undone', 'subscribe2' ) . '</em></strong><br />' . "\r\n";
254
  echo '<br />' . __( 'Action to perform', 'subscribe2' ) . ':' . "\r\n";
255
- echo '<label><input type="radio" name="manage" value="subscribe" checked="checked" /> ' . __( 'Subscribe', 'subscribe2' ) . '</label>&nbsp;&nbsp;' . "\r\n";
256
- echo '<label><input type="radio" name="manage" value="unsubscribe" /> ' . __( 'Unsubscribe', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
257
  if ( '1' === $this->subscribe2_options['reg_override'] ) {
258
  $s2_forms->display_category_form( $categories, 1 );
259
  } else {
260
  $s2_forms->display_category_form( $categories, 0 );
261
  }
262
- echo '<p class="submit"><button class="button-primary" name="sub_categories" onclick="bu_cats();">' . __( 'Bulk Update Categories', 'subscribe2' ) . '</button></p>';
263
  echo '<br />' . __( 'Send email as', 'subscribe2' ) . ':' . "\r\n";
264
  echo '<label><input type="radio" name="format" value="html"' . checked( $format, 'html', false ) . ' /> ' . __( 'HTML - Full', 'subscribe2' ) . '</label>&nbsp;&nbsp;' . "\r\n";
265
  echo '<label><input type="radio" name="format" value="html_excerpt"' . checked( $format, 'html_excerpt', false ) . ' /> ' . __( 'HTML - Excerpt', 'subscribe2' ) . '</label>&nbsp;&nbsp;' . "\r\n";
266
  echo '<label><input type="radio" name="format" value="post"' . checked( $format, 'post', false ) . ' /> ' . __( 'Plain Text - Full', 'subscribe2' ) . '</label>&nbsp;&nbsp;' . "\r\n";
267
  echo '<label><input type="radio" name="format" value="excerpt"' . checked( $format, 'excerpt', false ) . '/> ' . __( 'Plain Text - Excerpt', 'subscribe2' ) . '</label>' . "\r\n";
268
- echo '<p class="submit"><button class="button-primary" name="sub_format" onclick="bu_format();">' . __( 'Bulk Update Format', 'subscribe2' ) . '</button></p>';
269
  } else {
270
  $sub_cats = '';
271
  if ( isset( $_POST['sub_category'] ) ) {
@@ -278,13 +328,12 @@ if ( 'registered' === $current_tab ) {
278
  echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;' . "\r\n";
279
  echo '<label><input type="radio" name="sub_category" value="-1"' . checked( $sub_cats, '-1', false ) . ' /> ';
280
  echo __( 'No', 'subscribe2' ) . '</label>';
281
- echo '<p class="submit"><button class="button-primary" name="sub_digest" onclick="bu_digest();">' . __( 'Bulk Update Digest Subscription', 'subscribe2' ) . '</button></p>';
282
  }
283
  echo '</div>' . "\r\n";
284
  }
285
  echo '</form></div>' . "\r\n";
286
 
287
- include( ABSPATH . 'wp-admin/admin-footer.php' );
288
  // just to be sure
289
  die;
290
- ?>
9
  $current_tab = isset( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'public';
10
 
11
  // Access function to allow display for form elements
12
+ require_once S2PATH . 'classes/class-s2-forms.php';
13
+ $s2_forms = new s2_forms();
14
 
15
  // Instantiate and prepare our table data - this also runs the bulk actions
16
  if ( ! class_exists( 'WP_List_Table' ) ) {
17
+ require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
18
  }
19
  if ( ! class_exists( 'Subscribe2_List_Table' ) ) {
20
  if ( version_compare( $GLOBALS['wp_version'], '4.3', '<' ) ) {
21
+ require_once S2PATH . 'classes/class-s2-list-table-legacy.php';
22
+ $s2_list_table = new S2_List_Table_Legacy();
23
  } else {
24
+ require_once S2PATH . 'classes/class-s2-list-table.php';
25
+ $s2_list_table = new S2_List_Table();
26
  }
27
  }
28
 
29
  // was anything POSTed ?
30
  if ( isset( $_POST['s2_admin'] ) ) {
31
+ if ( false === wp_verify_nonce( $_REQUEST['_wpnonce'], 'bulk-' . $s2_list_table->_args['plural'] ) ) {
32
  die( '<p>' . __( 'Security error! Your request cannot be completed.', 'subscribe2' ) . '</p>' );
33
  }
34
 
35
  if ( ! empty( $_POST['addresses'] ) ) {
36
  $reg_sub_error = '';
37
  $pub_sub_error = '';
38
+ $unsub_error = '';
39
+ $email_error = '';
40
+ $message = '';
41
  foreach ( preg_split( '/[\s,]+/', $_POST['addresses'] ) as $email ) {
42
  $email = $this->sanitize_email( $email );
43
+ if ( false === $this->validate_email( $email ) ) {
44
+ ( '' === $email_error ) ? $email_error = "$email" : $email_error .= ", $email";
 
45
  continue;
46
+ } else {
47
+ if ( isset( $_POST['subscribe'] ) ) {
48
+ if ( false !== $this->is_public( $email ) ) {
49
+ ( '' === $pub_sub_error ) ? $pub_sub_error = "$email" : $pub_sub_error .= ", $email";
50
+ continue;
51
+ }
52
+ if ( $this->is_registered( $email ) ) {
53
+ ( '' === $reg_sub_error ) ? $reg_sub_error = "$email" : $reg_sub_error .= ", $email";
54
+ continue;
55
+ }
56
+ $this->add( $email, true );
57
+ $message = '<div id="message" class="updated fade"><p><strong>' . __( 'Address(es) subscribed!', 'subscribe2' ) . '</strong></p></div>';
58
+ } elseif ( isset( $_POST['unsubscribe'] ) ) {
59
+ if ( false === $this->is_public( $email ) || $this->is_registered( $email ) ) {
60
+ ( '' === $unsub_error ) ? $unsub_error = "$email" : $unsub_error .= ", $email";
61
+ continue;
62
+ }
63
+ $this->delete( $email );
64
+ $message = '<div id="message" class="updated fade"><p><strong>' . __( 'Address(es) unsubscribed!', 'subscribe2' ) . '</strong></p></div>';
65
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  }
67
  }
68
  if ( '' !== $reg_sub_error ) {
69
+ echo '<div id="message" class="error"><p><strong>' . __( 'Some emails were not processed, the following are already Registered Subscribers', 'subscribe2' ) . ':<br />' . $reg_sub_error . '</strong></p></div>';
70
  }
71
  if ( '' !== $pub_sub_error ) {
72
+ echo '<div id="message" class="error"><p><strong>' . __( 'Some emails were not processed, the following are already Public Subscribers', 'subscribe2' ) . ':<br />' . $pub_sub_error . '</strong></p></div>';
73
  }
74
  if ( '' !== $unsub_error ) {
75
+ echo '<div id="message" class="error"><p><strong>' . __( 'Some emails were not processed, the following were not in the database', 'subscribe2' ) . ':<br /> ' . $unsub_error . '</strong></p></div>';
76
+ }
77
+ if ( '' !== $email_error ) {
78
+ echo '<div id="message" class="error"><p><strong>' . __( 'Some emails were not processed, the following were invalid email addresses', 'subscribe2' ) . ':<br /> ' . $email_error . '</strong></p></div>';
79
  }
80
  if ( '' !== $message ) {
81
  echo $message;
84
  } elseif ( isset( $_POST['remind'] ) ) {
85
  $this->remind( $_POST['reminderemails'] );
86
  echo '<div id="message" class="updated fade"><p><strong>' . __( 'Reminder Email(s) Sent!', 'subscribe2' ) . '</strong></p></div>';
87
+ } elseif ( isset( $_POST['sub_categories'] ) && 'subscribe' === $_POST['manage'] ) {
88
+ if ( isset( $_REQUEST['subscriber'] ) ) {
89
+ $this->subscribe_registered_users( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['category'] );
90
+ } else {
91
+ $this->subscribe_registered_users( $_POST['exportcsv'], $_POST['category'] );
92
+ }
93
+ echo '<div id="message" class="updated fade"><p><strong>' . __( 'Registered Users Subscribed!', 'subscribe2' ) . '</strong></p></div>';
94
+ } elseif ( isset( $_POST['sub_categories'] ) && 'unsubscribe' === $_POST['manage'] ) {
95
+ if ( isset( $_REQUEST['subscriber'] ) ) {
96
+ $this->unsubscribe_registered_users( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['category'] );
97
+ } else {
98
+ $this->unsubscribe_registered_users( $_POST['exportcsv'], $_POST['category'] );
99
+ }
100
+ echo '<div id="message" class="updated fade"><p><strong>' . __( 'Registered Users Unsubscribed!', 'subscribe2' ) . '</strong></p></div>';
101
+ } elseif ( isset( $_POST['sub_format'] ) ) {
102
+ if ( isset( $_REQUEST['subscriber'] ) ) {
103
+ $this->format_change( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['format'] );
104
+ } else {
105
+ $this->format_change( $_POST['exportcsv'], $_POST['format'] );
106
+ }
107
+ echo '<div id="message" class="updated fade"><p><strong>' . __( 'Format updated for Selected Registered Users!', 'subscribe2' ) . '</strong></p></div>';
108
+ } elseif ( isset( $_POST['sub_digest'] ) ) {
109
+ if ( isset( $_REQUEST['subscriber'] ) ) {
110
+ $this->digest_change( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['sub_category'] );
111
+ } else {
112
+ $this->digest_change( $_POST['exportcsv'], $_POST['sub_category'] );
113
+ }
114
+ echo '<div id="message" class="updated fade"><p><strong>' . __( 'Digest Subscription updated for Selected Registered Users!', 'subscribe2' ) . '</strong></p></div>';
115
  }
116
  }
117
 
118
  if ( 'registered' === $current_tab ) {
119
  // Get Registered Subscribers
120
  $registered = $this->get_registered( 'return=emailid' );
121
+ $all_users = $this->get_all_registered( 'emailid' );
122
+
123
  // safety check for our arrays
124
+ if ( '' === $registered ) {
125
+ $registered = array();
126
+ }
127
+ if ( '' === $all_users ) {
128
+ $all_users = array();
129
+ }
130
  } else {
131
  //Get Public Subscribers
132
+ $confirmed = $this->get_public();
133
  $unconfirmed = $this->get_public( 0 );
134
  // safety check for our arrays
135
+ if ( '' === $confirmed ) {
136
+ $confirmed = array();
137
+ }
138
+ if ( '' === $unconfirmed ) {
139
+ $unconfirmed = array();
140
+ }
141
  }
142
 
143
  $reminderform = false;
144
  if ( isset( $_REQUEST['what'] ) ) {
145
  if ( 'public' === $_REQUEST['what'] ) {
146
+ $what = 'public';
147
  $subscribers = array_merge( (array) $confirmed, (array) $unconfirmed );
148
  } elseif ( 'confirmed' === $_REQUEST['what'] ) {
149
+ $what = 'confirmed';
150
  $subscribers = $confirmed;
151
  } elseif ( 'unconfirmed' === $_REQUEST['what'] ) {
152
+ $what = 'unconfirmed';
153
  $subscribers = $unconfirmed;
154
  if ( ! empty( $subscribers ) ) {
155
  $reminderemails = implode( ',', $subscribers );
156
+ $reminderform = true;
157
  }
158
  } elseif ( is_numeric( $_REQUEST['what'] ) ) {
159
+ $what = intval( $_REQUEST['what'] );
160
  $subscribers = $this->get_registered( "cats=$what&return=emailid" );
161
  } elseif ( 'registered' === $_REQUEST['what'] ) {
162
+ $what = 'registered';
163
  $subscribers = $registered;
164
  } elseif ( 'all_users' === $_REQUEST['what'] ) {
165
+ $what = 'all_users';
166
  $subscribers = $all_users;
167
  }
168
  } else {
169
  if ( 'public' === $current_tab ) {
170
+ $what = 'public';
171
  $subscribers = array_merge( (array) $confirmed, (array) $unconfirmed );
172
  } else {
173
+ $what = 'all_users';
174
  $subscribers = $all_users;
175
  }
176
  }
192
  $subscribers = $result;
193
  }
194
 
195
+ $s2_list_table->prepare_items();
196
 
197
  // show our form
198
  echo '<div class="wrap">';
199
  echo '<h1>' . __( 'Subscribers', 'subscribe2' ) . '</h1>' . "\r\n";
200
  $tabs = array(
201
+ 'public' => __( 'Public Subscribers', 'subscribe2' ),
202
  'registered' => __( 'Registered Subscribers', 'subscribe2' ),
203
  );
204
  echo '<h2 class="nav-tab-wrapper">';
205
  foreach ( $tabs as $tab_key => $tab_caption ) {
206
+ $active = ( $current_tab === $tab_key ) ? 'nav-tab-active' : '';
207
  echo '<a class="nav-tab ' . $active . '" href="?page=s2_tools&amp;tab=' . $tab_key . '">' . $tab_caption . '</a>';
208
  }
209
  echo '</h2>';
226
  echo '<div class="s2_admin" id="s2_current_subscribers">' . "\r\n";
227
  echo '<h2>' . __( 'Current Subscribers', 'subscribe2' ) . '</h2>' . "\r\n";
228
  echo '<br />';
229
+ $cats = $this->all_cats();
230
  $cat_ids = array();
231
  foreach ( $cats as $cat ) {
232
  $cat_ids[] = $cat->term_id;
267
  } else {
268
  $exportcsv = '';
269
  foreach ( $subscribers as $subscriber ) {
270
+ ( '' === $exportcsv ) ? $exportcsv = $subscriber['user_email'] : $exportcsv .= ",\r\n" . $subscriber['user_email'];
271
  }
272
  }
273
  echo '<td style="width: 25%; text-align: right;"><input type="hidden" name="exportcsv" value="' . $exportcsv . '" />' . "\r\n";
278
  echo '</tr></table>';
279
 
280
  // output our subscriber table
281
+ $s2_list_table->search_box( __( 'Search', 'subscribe2' ), 'search_id' );
282
+ $s2_list_table->display();
283
  echo '</div>' . "\r\n";
284
 
285
  // show bulk management form if filtered in some Registered Users
291
  if ( isset( $_POST['category'] ) ) {
292
  $categories = $_POST['category'];
293
  }
294
+ $manage = '';
295
+ if ( isset( $_POST['manage'] ) ) {
296
+ $manage = $_POST['manage'];
297
+ }
298
  $format = '';
299
  if ( isset( $_POST['format'] ) ) {
300
  $format = $_POST['format'];
302
  echo __( 'Preferences for Registered Users selected above can be changed using this section.', 'subscribe2' ) . '<br />' . "\r\n";
303
  echo '<strong><em style="color: red">' . __( 'Consider User Privacy as changes cannot be undone', 'subscribe2' ) . '</em></strong><br />' . "\r\n";
304
  echo '<br />' . __( 'Action to perform', 'subscribe2' ) . ':' . "\r\n";
305
+ echo '<label><input type="radio" name="manage" value="subscribe"' . checked( $manage, 'subscribe', false ) . ' /> ' . __( 'Subscribe', 'subscribe2' ) . '</label>&nbsp;&nbsp;' . "\r\n";
306
+ echo '<label><input type="radio" name="manage" value="unsubscribe"' . checked( $manage, 'unsubscribe', false ) . ' /> ' . __( 'Unsubscribe', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
307
  if ( '1' === $this->subscribe2_options['reg_override'] ) {
308
  $s2_forms->display_category_form( $categories, 1 );
309
  } else {
310
  $s2_forms->display_category_form( $categories, 0 );
311
  }
312
+ echo '<p class="submit"><button class="button-primary" name="sub_categories" onclick="return bmCheck();">' . __( 'Bulk Update Categories', 'subscribe2' ) . '</button></p>';
313
  echo '<br />' . __( 'Send email as', 'subscribe2' ) . ':' . "\r\n";
314
  echo '<label><input type="radio" name="format" value="html"' . checked( $format, 'html', false ) . ' /> ' . __( 'HTML - Full', 'subscribe2' ) . '</label>&nbsp;&nbsp;' . "\r\n";
315
  echo '<label><input type="radio" name="format" value="html_excerpt"' . checked( $format, 'html_excerpt', false ) . ' /> ' . __( 'HTML - Excerpt', 'subscribe2' ) . '</label>&nbsp;&nbsp;' . "\r\n";
316
  echo '<label><input type="radio" name="format" value="post"' . checked( $format, 'post', false ) . ' /> ' . __( 'Plain Text - Full', 'subscribe2' ) . '</label>&nbsp;&nbsp;' . "\r\n";
317
  echo '<label><input type="radio" name="format" value="excerpt"' . checked( $format, 'excerpt', false ) . '/> ' . __( 'Plain Text - Excerpt', 'subscribe2' ) . '</label>' . "\r\n";
318
+ echo '<p class="submit"><button class="button-primary" name="sub_format" onclick="return bmCheck();">' . __( 'Bulk Update Format', 'subscribe2' ) . '</button></p>';
319
  } else {
320
  $sub_cats = '';
321
  if ( isset( $_POST['sub_category'] ) ) {
328
  echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;' . "\r\n";
329
  echo '<label><input type="radio" name="sub_category" value="-1"' . checked( $sub_cats, '-1', false ) . ' /> ';
330
  echo __( 'No', 'subscribe2' ) . '</label>';
331
+ echo '<p class="submit"><button class="button-primary" name="sub_digest" onclick="return bmCheck();">' . __( 'Bulk Update Digest Subscription', 'subscribe2' ) . '</button></p>';
332
  }
333
  echo '</div>' . "\r\n";
334
  }
335
  echo '</form></div>' . "\r\n";
336
 
337
+ require ABSPATH . 'wp-admin/admin-footer.php';
338
  // just to be sure
339
  die;
 
admin/your-subscriptions.php CHANGED
@@ -3,8 +3,8 @@ if ( ! function_exists( 'add_action' ) ) {
3
  exit();
4
  }
5
 
6
- require_once( S2PATH . 'classes/class-s2-forms.php' );
7
- $s2_forms = new S2_Forms;
8
  $s2_forms->init();
9
 
10
  // was anything POSTed?
@@ -20,7 +20,7 @@ echo '<div class="wrap">';
20
 
21
  global $user_ID;
22
  $userid = $s2_forms->get_userid();
23
- $user = get_userdata( $userid );
24
 
25
  if ( $userid === $user_ID ) {
26
  echo '<h1>' . __( 'Your Notification Settings', 'subscribe2' ) . "</h1>\r\n";
@@ -42,7 +42,6 @@ echo '</form>' . "\r\n";
42
 
43
  echo '</div>' . "\r\n";
44
 
45
- include( ABSPATH . 'wp-admin/admin-footer.php' );
46
  // just to be sure
47
  die;
48
- ?>
3
  exit();
4
  }
5
 
6
+ require_once S2PATH . 'classes/class-s2-forms.php';
7
+ $s2_forms = new S2_Forms();
8
  $s2_forms->init();
9
 
10
  // was anything POSTed?
20
 
21
  global $user_ID;
22
  $userid = $s2_forms->get_userid();
23
+ $user = get_userdata( $userid );
24
 
25
  if ( $userid === $user_ID ) {
26
  echo '<h1>' . __( 'Your Notification Settings', 'subscribe2' ) . "</h1>\r\n";
42
 
43
  echo '</div>' . "\r\n";
44
 
45
+ require ABSPATH . 'wp-admin/admin-footer.php';
46
  // just to be sure
47
  die;
 
classes/class-s2-admin.php CHANGED
@@ -2,9 +2,9 @@
2
  class S2_Admin extends S2_Core {
3
  /* ===== WordPress menu registration and scripts ===== */
4
  /**
5
- Hook the menu
6
- */
7
- function admin_menu() {
8
  add_menu_page( __( 'Subscribe2', 'subscribe2' ), __( 'Subscribe2', 'subscribe2' ), apply_filters( 's2_capability', 'read', 'user' ), 's2', null, S2URL . 'include/email-edit.png' );
9
 
10
  $s2user = add_submenu_page( 's2', __( 'Your Subscriptions', 'subscribe2' ), __( 'Your Subscriptions', 'subscribe2' ), apply_filters( 's2_capability', 'read', 'user' ), 's2', array( &$this, 'user_menu' ), S2URL . 'include/email-edit.png' );
@@ -15,7 +15,9 @@ class S2_Admin extends S2_Core {
15
  $s2subscribers = add_submenu_page( 's2', __( 'Subscribers', 'subscribe2' ), __( 'Subscribers', 'subscribe2' ), apply_filters( 's2_capability', 'manage_options', 'manage' ), 's2_tools', array( &$this, 'subscribers_menu' ) );
16
  add_action( "admin_print_scripts-$s2subscribers", array( &$this, 'checkbox_form_js' ) );
17
  add_action( "admin_print_scripts-$s2subscribers", array( &$this, 'subscribers_form_js' ) );
 
18
  add_action( 'load-' . $s2subscribers, array( &$this, 'subscribers_help' ) );
 
19
 
20
  $s2settings = add_submenu_page( 's2', __( 'Settings', 'subscribe2' ), __( 'Settings', 'subscribe2' ), apply_filters( 's2_capability', 'manage_options', 'settings' ), 's2_settings', array( &$this, 'settings_menu' ) );
21
  add_action( "admin_print_scripts-$s2settings", array( &$this, 'checkbox_form_js' ) );
@@ -26,215 +28,281 @@ class S2_Admin extends S2_Core {
26
 
27
  $s2mail = add_submenu_page( 's2', __( 'Send Email', 'subscribe2' ), __( 'Send Email', 'subscribe2' ), apply_filters( 's2_capability', 'publish_posts', 'send' ), 's2_posts', array( &$this, 'write_menu' ) );
28
  add_action( 'load-' . $s2mail, array( &$this, 'mail_help' ) );
29
- } // end admin_menu()
30
 
31
  /**
32
- Contextual Help
33
- */
34
- function user_help() {
35
  $screen = get_current_screen();
36
  if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
37
- $screen->add_help_tab( array(
38
- 'id' => 's2-user-help1',
39
- 'title' => __( 'Overview', 'subscribe2' ),
40
- 'content' => '<p>' . __( 'From this page you can opt in or out of receiving a periodical digest style email of blog posts.', 'subscribe2' ) . '</p>',
41
- ) );
 
 
42
  } else {
43
- $screen->add_help_tab( array(
44
- 'id' => 's2-user-help1',
45
- 'title' => __( 'Overview', 'subscribe2' ),
46
- 'content' => '<p>' . __( 'From this page you can control your subscription preferences. Choose the email format you wish to receive, which categories you would like to receive notification for and depending on the site settings which authors you would like to read.', 'subscribe2' ) . '</p>',
47
- ) );
 
 
48
  }
49
- } // end user_help()
50
 
51
- function subscribers_help() {
52
  $screen = get_current_screen();
53
- $screen->add_help_tab( array(
54
- 'id' => 's2-subscribers-help1',
55
- 'title' => __( 'Overview', 'subscribe2' ),
56
- 'content' => '<p>' . __( 'From this page you can manage your subscribers.', 'subscribe2' ) . '</p>',
57
- ) );
58
- $screen->add_help_tab( array(
59
- 'id' => 's2-subscribers-help2',
60
- 'title' => __( 'Public Subscribers', 'subscribe2' ),
61
- 'content' => '<p>' . __( 'Public Subscribers are subscribers who have used the plugin form and only provided their email address.', 'subscribe2' ) . '</p><p>' . __( 'On this page public subscribers can be viewed, searched, deleted and also toggled between Confirmed and Unconfirmed status.', 'subscribe2' ) . '</p>',
62
- ) );
63
- $screen->add_help_tab( array(
64
- 'id' => 's2-subscribers-help3',
65
- 'title' => __( 'Registered Subscribers', 'subscribe2' ),
66
- 'content' => '<p>' . __( 'Registered Subscribers are subscribers who have registered in WordPress and have a username and password.', 'subscribe2' ) .
67
- '</p><p>' . __( 'Registered Subscribers have greater personal control over their subscription. They can change the format of the email and also select which categories and authors they want to receive notifications about.', 'subscribe2' ) .
68
- '</p><p>' . __( 'On this page registered subscribers can be viewed and searched. User accounts can be deleted from here with any posts created by those users being assigned to the currently logged in user. Bulk changes can be applied to all user settings changing their subscription email format and categories.', 'subscribe2' ) . '</p>',
69
- ) );
70
- } // end subscribers_help()
71
-
72
- function settings_help() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  $screen = get_current_screen();
74
- $screen->add_help_tab( array(
75
- 'id' => 's2-settings-help1',
76
- 'title' => __( 'Overview', 'subscribe2' ),
77
- 'content' => '<p>' . __( 'From this page you can adjust the Settings for Subscribe2.', 'subscribe2' ) . '</p>',
78
- ) );
79
- $screen->add_help_tab( array(
80
- 'id' => 's2-settings-help2',
81
- 'title' => __( 'Email Settings', 'subscribe2' ),
82
- 'content' => '<p>' . __( 'This section allows you to specify settings that apply to the emails generated by the site.', 'subscribe2' ) .
83
- '</p><p>' . __( 'Emails can be sent to individual subscribers by setting the number of recipients per email to 1. A setting greater than one will group recipients together and make use of the BCC emails header. A setting of 0 sends a single email with all subscribers in one large BCC group. A setting of 1 looks less like spam email to filters but takes longer to process.', 'subscribe2' ) .
84
- '</p><p>' . __( 'This section is also where the sender of the email on this page is chosen. You can choose Post Author or your Blogname but it is recommended to create a user account with an email address that really exists and shares the same domain name as your site (the bit after the @ should be the same as your sites web address) and then use this account.', 'subscribe2' ) .
85
- '</p><p>' . __( 'This page also configures the frequency of emails. This can be at the time new posts are made (per post) or periodically with an excerpt of each post made (digest). Additionally the post types (pages, private, password protected) can also be configured here.', 'subscribe2' ) . '</p>',
86
- ) );
87
- $screen->add_help_tab( array(
88
- 'id' => 's2-settings-help3',
89
- 'title' => __( 'Templates', 'subscribe2' ),
90
- 'content' => '<p>' . __( 'This section allows you to customise the content of your notification emails.', 'subscribe2' ) .
91
- '</p><p>' . __( 'There are special {KEYWORDS} that are used by Subscribe2 to place content into the final email. The template also accepts regular text and HTML as desired in the final emails.', 'subscribe2' ) .
92
- '</p><p>' . __( 'The {KEYWORDS} are listed on the right of the templates, note that some are for per post emails only and some are for digest emails only. Make sure the correct keywords are used based upon the Email Settings.', 'subscribe2' ) .
93
- '</p><p>' . __( 'The Notification Email template is used for sending notifications of new posts. The Subscribe / Unsubscribe confirmation template is sent when a new subscription or unsubscription request is made. The Reminder template is used to send reminder emails; this is done automatically or can be done manually.', 'subscribe2' ) . '</p>',
94
- ) );
95
- $screen->add_help_tab( array(
96
- 'id' => 's2-settings-help4',
97
- 'title' => __( 'Registered Users', 'subscribe2' ),
98
- 'content' => '<p>' . __( 'This section allows settings that apply to Registered Subscribers to be configured.', 'subscribe2' ) .
99
- '</p><p>' . __( 'Categories can be made compulsory so emails are always sent for posts in these categories. They can also be excludes so that emails are not generated. Excluded categories take precedence over Compulsory categories.', 'subscribe2' ) .
100
- '</p><p>' . __( 'A set of default settings for new users can also be specified using the Auto Subscribe section. Settings specified here will be applied to any newly created user accounts while Subscribe2 is activated.', 'subscribe2' ) . '</p>',
101
- ) );
102
- $screen->add_help_tab( array(
103
- 'id' => 's2-settings-help5',
104
- 'title' => __( 'Appearance', 'subscribe2' ),
105
- 'content' => '<p>' . __( 'This section allows you to enable several aspect of the plugin such as Widgets and editor buttons.', 'subscribe2' ) .
106
- '</p><p>' . __( 'AJAX mode can be enabled that is intended to work with the shortcode link parameter so that a dialog opens in the centre of the browser rather then using the regular form.', 'subscribe2' ) .
107
- '</p><p>' . __( 'The email over ride check box can be set to be automatically checked for every new post and page from here to, this may be useful if you will only want to send very occasional notifications for specific posts. You can then uncheck this box just before you publish your content.', 'subscribe2' ) . '</p>',
108
- ) );
109
- $screen->add_help_tab( array(
110
- 'id' => 's2-settings-help6',
111
- 'title' => __( 'Miscellaneous', 'subscribe2' ),
112
- 'content' => '<p>' . __( 'This section contains a place to bar specified domains from becoming Public Subscribers and links to help and support pages.', 'subscribe2' ) .
113
- '</p><p>' . __( 'In the paid Subscribe2 HTML version there is also a place here to enter a license code so that updates can be accessed automatically.', 'subscribe2' ) .
114
- '</p>',
115
- ) );
116
- } // end settings_help()
117
-
118
- function mail_help() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  $screen = get_current_screen();
120
- $screen->add_help_tab( array(
121
- 'id' => 's2-send-mail-help1',
122
- 'title' => __( 'Overview', 'subscribe2' ),
123
- 'content' => '<p>' . __( 'From this page you can send emails to the recipients in the group selected in the drop down.', 'subscribe2' ) .
124
- '</p><p>' . __( '<strong>Preview</strong> will send a preview of the email to the currently logged in user. <strong>Send</strong> will send the email to the recipient list.', 'subscribe2' ) . '</p>',
125
- ) );
126
- } // end send_email_help()
127
-
128
- /**
129
- Hook for Admin Drop Down Icons
130
- */
131
- function ozh_s2_icon() {
 
 
132
  return S2URL . 'include/email-edit.png';
133
- } // end ozh_s2_icon()
134
 
135
  /**
136
- Insert Javascript and CSS into admin_headers
137
- */
138
- function checkbox_form_js() {
139
- wp_register_script( 's2_checkbox', S2URL . 'include/s2-checkbox' . $this->script_debug . '.js', array( 'jquery' ), '1.3' );
140
  wp_enqueue_script( 's2_checkbox' );
141
- } //end checkbox_form_js()
142
 
143
- function user_admin_css() {
144
- wp_register_style( 's2_user_admin', S2URL . 'include/s2-user-admin.css', array(), '1.0' );
145
  wp_enqueue_style( 's2_user_admin' );
146
- } // end user_admin_css()
147
 
148
- function option_form_js() {
149
- wp_register_script( 's2_edit', S2URL . 'include/s2-edit' . $this->script_debug . '.js', array( 'jquery' ), '1.2' );
150
  wp_enqueue_script( 's2_edit' );
151
  if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
152
  wp_enqueue_script( 'jquery-ui-datepicker' );
153
  wp_enqueue_style( 'jquery-style', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css' );
154
- wp_register_script( 's2_date_time', S2URL . 'include/s2-date-time' . $this->script_debug . '.js', array( 'jquery-ui-datepicker' ), '1.0' );
155
  wp_enqueue_script( 's2_date_time' );
156
  }
157
- } // end option_form_js()
158
 
159
- function dismiss_js() {
160
- wp_register_script( 's2_dismiss', S2URL . 'include/s2-dismiss' . $this->script_debug . '.js', array( 'jquery' ), '1.0', true );
161
  $translation_array = array(
162
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
163
- 'nonce' => wp_create_nonce( 's2_dismiss_nonce' ),
164
  );
165
- wp_localize_script( 's2_dismiss', 's2_dismiss_script_strings', $translation_array );
166
  wp_enqueue_script( 's2_dismiss' );
167
- } // end dismiss_js()
168
 
169
- function s2_dismiss_notice_handler() {
170
  if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 's2_dismiss_nonce' ) ) {
171
  return false;
172
  }
173
  $this->subscribe2_options['dismiss_sender_warning'] = '1';
174
  update_option( 'subscribe2_options', $this->subscribe2_options );
175
  wp_die();
176
- } // end s2_dismiss_notice_handler()
177
 
178
- function subscribers_form_js() {
179
- wp_register_script( 's2_subscribers', S2URL . 'include/s2-subscribers' . $this->script_debug . '.js', array(), '1.2' );
180
  $translation_array = array(
181
  'registered_confirm_single' => __( 'You are about to delete a registered user account, any posts made by this user will be assigned to you. Are you sure?', 'subscribe2' ),
182
  'registered_confirm_plural' => __( 'You are about to delete registered user accounts, any posts made by these users will be assigned to you. Are you sure?', 'subscribe2' ),
183
- 'public_confirm_single' => __( 'You are about to delete a public subscriber. Are you sure?', 'subscribe2' ),
184
- 'public_confirm_plural' => __( 'You are about to delete public subscribers. Are you sure?', 'subscribe2' ),
 
 
 
185
  );
186
- wp_localize_script( 's2_subscribers', 's2_script_strings', $translation_array );
187
  wp_enqueue_script( 's2_subscribers' );
188
- } // end subscribers_form_js()
 
 
 
 
 
 
189
 
190
  /**
191
- Adds a links directly to the settings page from the plugin page
192
- */
193
- function plugin_links( $links, $file ) {
194
  if ( S2DIR . 'subscribe2.php' === $file ) {
195
  $links[] = '<a href="admin.php?page=s2_settings">' . __( 'Settings', 'subscribe2' ) . '</a>';
196
  $links[] = '<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=2387904"><b>' . __( 'Donate', 'subscribe2' ) . '</b></a>';
197
  }
198
  return $links;
199
- } // end plugin_links()
200
 
201
  /* ===== Menus ===== */
202
  /**
203
- Our subscriber management page
204
- */
205
- function subscribers_menu() {
206
- require_once( S2PATH . 'admin/subscribers.php' );
207
- } // end subscribers_menu()
208
 
209
  /**
210
- Our settings page
211
- */
212
- function settings_menu() {
213
- require_once( S2PATH . 'admin/settings.php' );
214
- } // end settings_menu()
215
 
216
  /**
217
- Our profile menu
218
- */
219
- function user_menu() {
220
- require_once( S2PATH . 'admin/your-subscriptions.php' );
221
- } // end user_menu()
222
 
223
  /**
224
- Display the Write sub-menu
225
- */
226
- function write_menu() {
227
- require_once( S2PATH . 'admin/send-email.php' );
228
- } // end write_menu()
229
 
230
  /* ===== Write Toolbar Button Functions ===== */
231
  /**
232
- Register our button in the QuickTags bar
233
- */
234
- function button_init() {
235
  global $pagenow;
236
- if ( ! in_array( $pagenow, array( 'post-new.php', 'post.php', 'page-new.php', 'page.php' ) ) && ! strpos( esc_url( $_SERVER['REQUEST_URI'] ), 'page=s2_posts' ) ) { return; }
237
- if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) { return; }
 
 
 
 
238
  if ( 'true' === get_user_option( 'rich_editing' ) ) {
239
  // Hook into the rich text editor
240
  add_filter( 'mce_external_plugins', array( &$this, 'mce_plugin' ) );
@@ -242,12 +310,12 @@ class S2_Admin extends S2_Core {
242
  } else {
243
  wp_enqueue_script( 'subscribe2_button', S2URL . 'include/s2-button' . $this->script_debug . '.js', array( 'quicktags' ), '2.0' );
244
  }
245
- } // end button_init()
246
 
247
  /**
248
- Add buttons for Rich Text Editor
249
- */
250
- function mce_plugin( $arr ) {
251
  if ( version_compare( $this->wp_release, '3.9', '<' ) ) {
252
  $path = S2URL . 'tinymce/editor-plugin3' . $this->script_debug . '.js';
253
  } else {
@@ -255,47 +323,63 @@ class S2_Admin extends S2_Core {
255
  }
256
  $arr['subscribe2'] = $path;
257
  return $arr;
258
- } // end mce_plugin()
259
 
260
- function mce_button( $arr ) {
261
  $arr[] = 'subscribe2';
262
  return $arr;
263
- } // end mce_button()
264
 
265
  /* ===== widget functions ===== */
266
  /**
267
- Function to add css and js files to admin header
268
- */
269
- function widget_s2counter_css_and_js() {
270
  // ensure we only add colorpicker js to widgets page
271
  if ( false !== stripos( esc_url( $_SERVER['REQUEST_URI'] ), 'widgets.php' ) ) {
272
  wp_enqueue_style( 'farbtastic' );
273
  wp_enqueue_script( 'farbtastic' );
274
- wp_register_script( 's2_colorpicker', S2URL . 'include/s2-colorpicker' . $this->script_debug . '.js', array( 'farbtastic' ), '1.2' );
275
  wp_enqueue_script( 's2_colorpicker' );
276
  }
277
- } // end widget_s2_counter_css_and_js()
278
 
279
  /* ===== meta box functions to allow per-post override ===== */
280
  /**
281
- Create meta box on write pages
282
- */
283
- function s2_meta_init() {
 
 
 
 
284
  if ( 'yes' === $this->subscribe2_options['pages'] ) {
285
  $s2_post_types = array( 'page', 'post' );
286
  } else {
287
  $s2_post_types = array( 'post' );
288
  }
 
289
  $s2_post_types = apply_filters( 's2_post_types', $s2_post_types );
 
290
  foreach ( $s2_post_types as $s2_post_type ) {
291
- add_meta_box( 'subscribe2', __( 'Subscribe2 Notification Override', 'subscribe2' ), array( &$this, 's2_override_meta' ), $s2_post_type, 'advanced' );
 
 
 
 
 
 
 
 
 
 
292
  }
293
- } // end s2_meta_init()
294
 
295
  /**
296
- Meta override box code
297
- */
298
- function s2_override_meta() {
299
  global $post_ID;
300
  $s2mail = get_post_meta( $post_ID, '_s2mail', true );
301
  echo '<input type="hidden" name="s2meta_nonce" id="s2meta_nonce" value="' . wp_create_nonce( wp_hash( plugin_basename( __FILE__ ) ) ) . '" />';
@@ -305,18 +389,24 @@ class S2_Admin extends S2_Core {
305
  echo ' checked="checked"';
306
  }
307
  echo ' />';
308
- } // end s2_override_meta()
309
 
310
  /**
311
- Meta override box form handler
312
- */
313
- function s2_meta_handler( $post_id ) {
314
- if ( ! isset( $_POST['s2meta_nonce'] ) || ! wp_verify_nonce( $_POST['s2meta_nonce'], wp_hash( plugin_basename( __FILE__ ) ) ) ) { return $post_id; }
 
 
315
 
316
  if ( 'page' === $_POST['post_type'] ) {
317
- if ( ! current_user_can( 'edit_page', $post_id ) ) { return $post_id; }
 
 
318
  } else {
319
- if ( ! current_user_can( 'edit_post', $post_id ) ) { return $post_id; }
 
 
320
  }
321
 
322
  if ( isset( $_POST['s2_meta_field'] ) && 'no' === $_POST['s2_meta_field'] ) {
@@ -324,71 +414,97 @@ class S2_Admin extends S2_Core {
324
  } else {
325
  update_post_meta( $post_id, '_s2mail', 'yes' );
326
  }
327
- } // end s2_meta_box_handler()
328
 
329
  /* ===== WordPress menu helper functions ===== */
330
  /**
331
- Collects the signup date for all public subscribers
332
- */
333
- function signup_date( $email = '' ) {
334
- if ( '' === $email ) { return false; }
 
 
335
 
336
  global $wpdb;
337
  if ( ! empty( $this->signup_dates ) ) {
338
  return $this->signup_dates[ $email ];
339
  } else {
340
- $results = $wpdb->get_results( "SELECT email, date FROM $this->public", ARRAY_N );
341
  foreach ( $results as $result ) {
342
  $this->signup_dates[ $result[0] ] = $result[1];
343
  }
344
  return $this->signup_dates[ $email ];
345
  }
346
- } // end signup_date()
347
 
348
  /**
349
- Collects the ip address for all public subscribers
350
- */
351
- function signup_ip( $email = '' ) {
352
- if ( '' === $email ) {return false; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
 
354
  global $wpdb;
355
  if ( ! empty( $this->signup_ips ) ) {
356
  return $this->signup_ips[ $email ];
357
  } else {
358
- $results = $wpdb->get_results( "SELECT email, ip FROM $this->public", ARRAY_N );
359
  foreach ( $results as $result ) {
360
  $this->signup_ips[ $result[0] ] = $result[1];
361
  }
362
  return $this->signup_ips[ $email ];
363
  }
364
- } // end signup_ip()
365
 
366
  /**
367
- Export subscriber emails and other details to CSV
368
- */
369
- function prepare_export( $subscribers ) {
370
- if ( empty( $subscribers ) ) { return; }
 
 
371
  $subscribers = explode( ",\r\n", $subscribers );
372
  natcasesort( $subscribers );
373
 
374
- $exportcsv = _x( 'User Email,User Type,User Name,Confirm Date,IP', 'Comma Separated Column Header names for CSV Export' , 'subscribe2' );
375
- $all_cats = $this->all_cats( false, 'ID' );
376
 
377
  foreach ( $all_cats as $cat ) {
378
  $exportcsv .= ',' . html_entity_decode( $cat->cat_name, ENT_QUOTES );
379
- $cat_ids[] = $cat->term_id;
380
  }
381
  $exportcsv .= "\r\n";
382
 
383
  foreach ( $subscribers as $subscriber ) {
384
  if ( $this->is_registered( $subscriber ) ) {
385
- $user_ID = $this->get_user_id( $subscriber );
386
- $user_info = get_userdata( $user_ID );
387
 
388
- $cats = explode( ',', get_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
389
  $subscribed_cats = '';
390
  foreach ( $cat_ids as $cat ) {
391
- (in_array( $cat, $cats )) ? $subscribed_cats .= ',Yes' : $subscribed_cats .= ',No';
392
  }
393
 
394
  $exportcsv .= $subscriber . ',';
@@ -405,15 +521,15 @@ class S2_Admin extends S2_Core {
405
  }
406
 
407
  return $exportcsv;
408
- } // end prepare_export()
409
 
410
  /**
411
- Display a table of post formats supported by the currently active theme
412
- */
413
- function display_format_form( $formats, $selected = array() ) {
414
- $half = (count( $formats[0] ) / 2);
415
- $i = 0;
416
- $j = 0;
417
  echo '<table style="width: 100%; border-collapse: separate; border-spacing: 2px; *border-collapse: expression(\'separate\', cellSpacing = \'2px\');" class="editform">' . "\r\n";
418
  echo '<tr><td style="text-align: left;" colspan="2">' . "\r\n";
419
  echo '<label><input type="checkbox" name="checkall" value="checkall_format" /> ' . __( 'Select / Unselect All', 'subscribe2' ) . '</label>' . "\r\n";
@@ -442,36 +558,36 @@ class S2_Admin extends S2_Core {
442
  }
443
  echo '</td></tr>' . "\r\n";
444
  echo '</table>' . "\r\n";
445
- } // end display_format_form()
446
 
447
  /**
448
- Display a drop-down form to select subscribers
449
- $selected is the option to select
450
- $submit is the text to use on the Submit button
451
- */
452
- function display_subscriber_dropdown( $selected = 'registered', $submit = '', $exclude = array() ) {
453
  global $wpdb;
454
 
455
  $who = array(
456
- 'all' => __( 'All Users and Subscribers', 'subscribe2' ),
457
- 'public' => __( 'Public Subscribers', 'subscribe2' ),
458
- 'confirmed' => ' &nbsp;&nbsp;' . __( 'Confirmed', 'subscribe2' ),
459
  'unconfirmed' => ' &nbsp;&nbsp;' . __( 'Unconfirmed', 'subscribe2' ),
460
- 'all_users' => __( 'All Registered Users', 'subscribe2' ),
461
- 'registered' => __( 'Registered Subscribers', 'subscribe2' ),
462
  );
463
 
464
  $all_cats = $this->all_cats( false );
465
 
466
  // count the number of subscribers
467
- $count['confirmed'] = $wpdb->get_var( "SELECT COUNT(id) FROM $this->public WHERE active='1'" );
468
- $count['unconfirmed'] = $wpdb->get_var( "SELECT COUNT(id) FROM $this->public WHERE active='0'" );
469
  if ( in_array( 'unconfirmed', $exclude ) ) {
470
  $count['public'] = $count['confirmed'];
471
  } elseif ( in_array( 'confirmed', $exclude ) ) {
472
  $count['public'] = $count['unconfirmed'];
473
  } else {
474
- $count['public'] = ($count['confirmed'] + $count['unconfirmed']);
475
  }
476
  if ( $this->s2_mu ) {
477
  $count['all_users'] = $wpdb->get_var( "SELECT COUNT(meta_key) FROM $wpdb->usermeta WHERE meta_key='" . $wpdb->prefix . "capabilities'" );
@@ -483,7 +599,7 @@ class S2_Admin extends S2_Core {
483
  } else {
484
  $count['registered'] = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(meta_key) FROM $wpdb->usermeta WHERE meta_key=%s AND meta_value <> ''", $this->get_usermeta_keyname( 's2_subscribed' ) ) );
485
  }
486
- $count['all'] = ($count['confirmed'] + $count['unconfirmed'] + $count['all_users']);
487
  // get subscribers to individual categories but only if we are using per-post notifications
488
  if ( 'never' === $this->subscribe2_options['email_freq'] ) {
489
  $compulsory = explode( ',', $this->subscribe2_options['compulsory'] );
@@ -508,18 +624,26 @@ class S2_Admin extends S2_Core {
508
 
509
  echo '<select name="what">' . "\r\n";
510
  foreach ( $who as $whom => $display ) {
511
- if ( in_array( $whom, $exclude ) ) { continue; }
 
 
512
 
513
  echo '<option value="' . $whom . '"';
514
- if ( $whom === $selected ) { echo ' selected="selected" '; }
515
- echo '>' . $display . ' (' . ($count[ $whom ]) . ')</option>' . "\r\n";
 
 
516
  }
517
 
518
  if ( $count['registered'] > 0 && 'never' === $this->subscribe2_options['email_freq'] ) {
519
  foreach ( $all_cats as $cat ) {
520
- if ( in_array( $cat->term_id, $exclude ) ) { continue; }
 
 
521
  echo '<option value="' . $cat->term_id . '"';
522
- if ( $cat->term_id === $selected ) { echo ' selected="selected" '; }
 
 
523
  echo '> &nbsp;&nbsp;' . $cat->name . '&nbsp;(' . $count[ $cat->name ] . ') </option>' . "\r\n";
524
  }
525
  }
@@ -527,13 +651,13 @@ class S2_Admin extends S2_Core {
527
  if ( false !== $submit ) {
528
  echo '&nbsp;<input type="submit" class="button-secondary" value="' . $submit . '" />' . "\r\n";
529
  }
530
- } // end display_subscriber_dropdown()
531
 
532
  /**
533
- Display a drop down list of administrator level users and
534
- optionally include a choice for Post Author
535
- */
536
- function admin_dropdown( $inc_author = false ) {
537
  global $wpdb;
538
 
539
  $args = array(
@@ -541,8 +665,9 @@ class S2_Admin extends S2_Core {
541
  'ID',
542
  'display_name',
543
  ),
544
- 'role' => 'administrator',
545
  );
 
546
  $wp_user_query = get_users( $args );
547
  if ( ! empty( $wp_user_query ) ) {
548
  foreach ( $wp_user_query as $user ) {
@@ -554,14 +679,14 @@ class S2_Admin extends S2_Core {
554
 
555
  if ( $inc_author ) {
556
  $author[] = (object) array(
557
- 'ID' => 'author',
558
  'display_name' => __( 'Post Author', 'subscribe2' ),
559
  );
560
  $author[] = (object) array(
561
- 'ID' => 'blogname',
562
  'display_name' => html_entity_decode( get_option( 'blogname' ), ENT_QUOTES ),
563
  );
564
- $admins = array_merge( $author, $admins );
565
  }
566
 
567
  echo '<select name="sender">' . "\r\n";
@@ -573,27 +698,31 @@ class S2_Admin extends S2_Core {
573
  echo '>' . $admin->display_name . '</option>' . "\r\n";
574
  }
575
  echo '</select>' . "\r\n";
576
- } // end admin_dropdown()
577
 
578
  /**
579
- Display a dropdown of choices for digest email frequency
580
- and give user details of timings when event is scheduled
581
- */
582
- function display_digest_choices() {
583
  global $wpdb;
584
  $cron_file = ABSPATH . 'wp-cron.php';
585
  if ( ! is_readable( $cron_file ) ) {
586
  echo '<strong><em style="color: red">' . __( 'The WordPress cron functions may be disabled on this server. Digest notifications may not work.', 'subscribe2' ) . '</em></strong><br />' . "\r\n";
587
  }
588
  $scheduled_time = wp_next_scheduled( 's2_digest_cron' );
589
- $offset = get_option( 'gmt_offset' ) * 60 * 60;
590
- $schedule = (array) wp_get_schedules();
591
- $schedule = array_merge( array(
592
- 'never' => array(
593
- 'interval' => 0,
594
- 'display' => __( 'For each Post', 'subscribe2' ),
 
 
595
  ),
596
- ), $schedule );
 
 
597
  $sort = array();
598
  foreach ( (array) $schedule as $key => $value ) {
599
  $sort[ $key ] = $value['interval'];
@@ -619,10 +748,10 @@ class S2_Admin extends S2_Core {
619
  echo '<input type="hidden" id="jscrontime" value="' . date_i18n( $time_format, $scheduled_time + $offset ) . '" />';
620
  echo '<span id="s2cron_1"><span id="s2crondate" style="background-color: #FFFBCC">' . date_i18n( $date_format, $scheduled_time + $offset ) . '</span>';
621
  echo ' @ <span id="s2crontime" style="background-color: #FFFBCC">' . date_i18n( $time_format, $scheduled_time + $offset ) . '</span> ';
622
- echo '<a href="#" onclick="s2_show(\'cron\'); return false;">' . __( 'Edit', 'subscribe2' ) . '</a></span>' . "\r\n";
623
  echo '<span id="s2cron_2">' . "\r\n";
624
  echo '<input id="s2datepicker" name="crondate" value="' . date_i18n( $date_format, $scheduled_time + $offset ) . '">' . "\r\n";
625
- $hours = array( '12:00 am', '1:00 am', '2:00 am', '3:00 am', '4:00 am', '5:00 am', '6:00 am', '7:00 am', '8:00 am', '9:00 am', '10:00 am', '11:00 am', '12:00 pm', '1:00 pm', '2:00 pm', '3:00 pm', '4:00 pm', '5:00 pm', '6:00 pm', '7:00 pm', '8:00 pm', '9:00 pm', '10:00 pm', '11:00 pm' );
626
  $current_hour = intval( date_i18n( 'G', $scheduled_time + $offset ) );
627
  echo '<select name="crontime">' . "\r\n";
628
  foreach ( $hours as $key => $value ) {
@@ -633,8 +762,8 @@ class S2_Admin extends S2_Core {
633
  echo '>' . $value . '</option>' . "\r\n";
634
  }
635
  echo '</select>' . "\r\n";
636
- echo '<a href="#" onclick="s2_cron_update(\'cron\'); return false;">' . __( 'Update', 'subscribe2' ) . '</a>' . "\r\n";
637
- echo '<a href="#" onclick="s2_cron_revert(\'cron\'); return false;">' . __( 'Revert', 'subscribe2' ) . '</a></span>' . "\r\n";
638
  if ( ! empty( $this->subscribe2_options['last_s2cron'] ) ) {
639
  echo '<p>' . __( 'Attempt to resend the last Digest Notification email', 'subscribe2' ) . ': ';
640
  echo '<input type="submit" class="button-secondary" name="resend" value="' . __( 'Resend Digest', 'subscribe2' ) . '" /></p>' . "\r\n";
@@ -642,14 +771,16 @@ class S2_Admin extends S2_Core {
642
  } else {
643
  echo '<br />';
644
  }
645
- } // end display_digest_choices()
646
 
647
  /**
648
- Create and display a dropdown list of pages
649
- */
650
- function pages_dropdown( $s2page ) {
651
  $pages = get_pages();
652
- if ( empty( $pages ) ) { return; }
 
 
653
 
654
  $option = '';
655
  foreach ( $pages as $page ) {
@@ -668,100 +799,105 @@ class S2_Admin extends S2_Core {
668
  }
669
 
670
  echo $option;
671
- } // end pages_dropdown()
672
 
673
  /**
674
- Subscribe all registered users to category selected on Admin Manage Page
675
- */
676
- function subscribe_registered_users( $emails = '', $cats = array() ) {
677
- if ( '' === $emails || '' === $cats ) { return false; }
 
 
678
  global $wpdb;
679
 
680
  $useremails = explode( ",\r\n", $emails );
681
  $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
682
 
683
- $sql = "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)";
684
- $user_IDs = $wpdb->get_col( $sql );
685
 
686
- foreach ( $user_IDs as $user_ID ) {
687
- $old_cats = get_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), true );
688
  if ( ! empty( $old_cats ) ) {
689
  $old_cats = explode( ',', $old_cats );
690
- $newcats = array_unique( array_merge( $cats, $old_cats ) );
691
  } else {
692
  $newcats = $cats;
693
  }
694
  if ( ! empty( $newcats ) && $newcats !== $old_cats ) {
695
  // add subscription to these cat IDs
696
  foreach ( $newcats as $id ) {
697
- update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_cat' ) . $id, $id );
698
  }
699
- update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
700
  }
701
  unset( $newcats );
702
  }
703
- } // end subscribe_registered_users()
704
 
705
  /**
706
- Unsubscribe all registered users to category selected on Admin Manage Page
707
- */
708
- function unsubscribe_registered_users( $emails = '', $cats = array() ) {
709
- if ( '' === $emails || '' === $cats ) { return false; }
 
 
710
  global $wpdb;
711
 
712
  $useremails = explode( ",\r\n", $emails );
713
  $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
714
 
715
- $sql = "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)";
716
- $user_IDs = $wpdb->get_col( $sql );
717
 
718
- foreach ( $user_IDs as $user_ID ) {
719
- $old_cats = explode( ',', get_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
720
- $remain = array_diff( $old_cats, $cats );
721
  if ( ! empty( $remain ) && $remain !== $old_cats ) {
722
  // remove subscription to these cat IDs and update s2_subscribed
723
  foreach ( $cats as $id ) {
724
- delete_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_cat' ) . $id );
725
  }
726
- update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $remain ) );
727
  } else {
728
  // remove subscription to these cat IDs and update s2_subscribed to ''
729
  foreach ( $cats as $id ) {
730
- delete_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_cat' ) . $id );
731
  }
732
- delete_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ) );
733
  }
734
  unset( $remain );
735
  }
736
- } // end unsubscribe_registered_users()
737
 
738
  /**
739
- Handles bulk changes to email format for Registered Subscribers
740
- */
741
- function format_change( $emails, $format ) {
742
- if ( empty( $format ) ) { return; }
 
 
743
 
744
  global $wpdb;
745
  $useremails = explode( ",\r\n", $emails );
746
  $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
747
- $ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" );
748
- $ids = implode( ',', array_map( array( $this, 'prepare_in_data' ), $ids ) );
749
- $sql = "UPDATE $wpdb->usermeta SET meta_value='{$format}' WHERE meta_key='" . $this->get_usermeta_keyname( 's2_format' ) . "' AND user_id IN ($ids)";
750
- $wpdb->query( $sql );
751
- } // end format_change()
752
 
753
  /**
754
- Handles bulk update to digest preferences
755
- */
756
- function digest_change( $emails, $digest ) {
757
- if ( empty( $digest ) ) { return; }
 
 
758
 
759
  global $wpdb;
760
  $useremails = explode( ",\r\n", $emails );
761
  $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
762
 
763
- $sql = "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)";
764
- $user_IDs = $wpdb->get_col( $sql );
765
 
766
  if ( 'digest' === $digest ) {
767
  $exclude = explode( ',', $this->subscribe2_options['exclude'] );
@@ -773,149 +909,180 @@ class S2_Admin extends S2_Core {
773
 
774
  $cats_string = '';
775
  foreach ( $all_cats as $cat ) {
776
- ('' === $cats_string) ? $cats_string = "$cat->term_id" : $cats_string .= ",$cat->term_id";
777
  }
778
 
779
- foreach ( $user_IDs as $user_ID ) {
780
  foreach ( $all_cats as $cat ) {
781
- update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_cat' ) . $cat->term_id, $cat->term_id );
782
  }
783
- update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), $cats_string );
784
  }
785
  } elseif ( '-1' === $digest ) {
786
- foreach ( $user_IDs as $user_ID ) {
787
- $cats = explode( ',', get_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
788
  foreach ( $cats as $id ) {
789
- delete_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_cat' ) . $id );
790
  }
791
- delete_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ) );
792
  }
793
  }
794
- } // end digest_change()
795
 
796
  /* ===== functions to handle addition and removal of WordPress categories ===== */
797
  /**
798
- Autosubscribe registered users to newly created categories
799
- if registered user has selected this option
800
- */
801
- function new_category( $new_category = '' ) {
802
- if ( 'no' === $this->subscribe2_options['show_autosub'] ) { return; }
 
 
803
 
804
  global $wpdb;
805
  if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
806
  // if we are doing digests add new categories to users who are currently opted in
807
- $sql = $wpdb->prepare( "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key=%s AND meta_value<>''", $this->get_usermeta_keyname( 's2_subscribed' ) );
808
- $user_IDs = $wpdb->get_col( $sql );
809
- foreach ( $user_IDs as $user_ID ) {
810
- $old_cats = get_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), true );
 
 
 
 
811
  $old_cats = explode( ',', $old_cats );
812
- $newcats = array_merge( $old_cats, (array) $new_category );
813
- update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_cat' ) . $new_category, $new_category );
814
- update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
815
  }
816
  return;
817
  }
818
 
819
  if ( 'yes' === $this->subscribe2_options['show_autosub'] ) {
820
  if ( $this->s2_mu ) {
821
- $sql = $wpdb->prepare( "SELECT DISTINCT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b WHERE a.user_id = b.user_id AND a.meta_key=%s AND a.meta_value='yes' AND b.meta_key=%s", $this->get_usermeta_keyname( 's2_autosub' ), $this->get_usermeta_keyname( 's2_subscribed' ) );
 
 
 
 
 
 
822
  } else {
823
- $sql = $wpdb->prepare( "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE $wpdb->usermeta.meta_key=%s AND $wpdb->usermeta.meta_value='yes'", $this->get_usermeta_keyname( 's2_autosub' ) );
 
 
 
 
 
 
 
 
824
  }
825
- $user_IDs = $wpdb->get_col( $sql );
826
- if ( '' === $user_IDs ) { return; }
827
 
828
- foreach ( $user_IDs as $user_ID ) {
829
- $old_cats = get_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), true );
830
  if ( empty( $old_cats ) ) {
831
  $newcats = (array) $new_category;
832
  } else {
833
  $old_cats = explode( ',', $old_cats );
834
- $newcats = array_merge( $old_cats, (array) $new_category );
835
  }
836
  // add subscription to these cat IDs
837
- update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_cat' ) . $new_category, $new_category );
838
- update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
839
  }
840
  } elseif ( 'exclude' === $this->subscribe2_options['show_autosub'] ) {
841
- $excluded_cats = explode( ',', $this->subscribe2_options['exclude'] );
842
- $excluded_cats[] = $new_category;
843
  $this->subscribe2_options['exclude'] = implode( ',', $excluded_cats );
844
  update_option( 'subscribe2_options', $this->subscribe2_options );
845
  }
846
- } // end new_category()
847
 
848
  /**
849
- Automatically delete subscriptions to a category when it is deleted
850
- */
851
- function delete_category( $deleted_category = '' ) {
852
  global $wpdb;
853
 
854
  if ( $this->s2_mu ) {
855
- $sql = $wpdb->prepare( "SELECT DISTINCT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b WHERE a.user_id = b.user_id AND a.meta_key=%s AND b.meta_key=%s", $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category, $this->get_usermeta_keyname( 's2_subscribed' ) );
 
 
 
 
 
 
856
  } else {
857
- $sql = $wpdb->prepare( "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key=%s", $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category );
 
 
 
 
 
 
 
 
858
  }
859
- $user_IDs = $wpdb->get_col( $sql );
860
- if ( '' === $user_IDs ) { return; }
861
 
862
- foreach ( $user_IDs as $user_ID ) {
863
- $old_cats = explode( ',', get_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
864
  if ( ! is_array( $old_cats ) ) {
865
  $old_cats = array( $old_cats );
866
  }
867
  // add subscription to these cat IDs
868
- delete_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category );
869
  $remain = array_diff( $old_cats, (array) $deleted_category );
870
- update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $remain ) );
871
  }
872
- } // end delete_category()
873
 
874
  /* ===== functions to show & handle one-click subscription ===== */
875
  /**
876
- Show form for one-click subscription on user profile page
877
- */
878
- function one_click_profile_form( $user ) {
879
  echo '<h3>' . __( 'Email subscription', 'subscribe2' ) . '</h3>' . "\r\n";
880
  echo '<table class="form-table">' . "\r\n";
881
  echo '<tr><th scope="row">' . __( 'Subscribe / Unsubscribe', 'subscribe2' ) . '</th>' . "\r\n";
882
  echo '<td><label><input type="checkbox" name="sub2-one-click-subscribe" value="1" ' . checked( ! get_user_meta( $user->ID, $this->get_usermeta_keyname( 's2_subscribed' ), true ), false, false ) . ' /> ' . __( 'Receive notifications', 'subscribe2' ) . '</label><br />' . "\r\n";
883
  echo '<span class="description">' . __( 'Check if you want to receive email notification when new posts are published', 'subscribe2' ) . '</span>' . "\r\n";
884
  echo '</td></tr></table>' . "\r\n";
885
- } // end one_click_profile_form()
886
 
887
  /**
888
- Handle submission from profile one-click subscription
889
- */
890
- function one_click_profile_form_save( $user_ID ) {
891
- if ( ! current_user_can( 'edit_user', $user_ID ) ) {
892
  return false;
893
  }
894
 
895
  if ( isset( $_POST['sub2-one-click-subscribe'] ) && 1 === $_POST['sub2-one-click-subscribe'] ) {
896
  // Subscribe
897
- $this->one_click_handler( $user_ID, 'subscribe' );
898
  } else {
899
  // Unsubscribe
900
- $this->one_click_handler( $user_ID, 'unsubscribe' );
901
  }
902
- } // end one_click_profile_form_save()
903
 
904
  /**
905
- Core function to hook the digest email preview to the action on the Settings page
906
- */
907
- function digest_preview( $user_email = '' ) {
908
- if ( ! is_email( $user_email ) ) { return; }
 
 
909
  $this->subscribe2_cron( $user_email );
910
- } // end digest_preview()
911
 
912
  /**
913
- Core function to hook the resent digest email to the action on the Settings page
914
- */
915
- function digest_resend( $resend ) {
916
  if ( 'resend' === $resend ) {
917
  $this->subscribe2_cron( '', 'resend' );
918
  }
919
- } // end digest_resend()
920
  }
921
- ?>
2
  class S2_Admin extends S2_Core {
3
  /* ===== WordPress menu registration and scripts ===== */
4
  /**
5
+ * Hook the menu
6
+ */
7
+ public function admin_menu() {
8
  add_menu_page( __( 'Subscribe2', 'subscribe2' ), __( 'Subscribe2', 'subscribe2' ), apply_filters( 's2_capability', 'read', 'user' ), 's2', null, S2URL . 'include/email-edit.png' );
9
 
10
  $s2user = add_submenu_page( 's2', __( 'Your Subscriptions', 'subscribe2' ), __( 'Your Subscriptions', 'subscribe2' ), apply_filters( 's2_capability', 'read', 'user' ), 's2', array( &$this, 'user_menu' ), S2URL . 'include/email-edit.png' );
15
  $s2subscribers = add_submenu_page( 's2', __( 'Subscribers', 'subscribe2' ), __( 'Subscribers', 'subscribe2' ), apply_filters( 's2_capability', 'manage_options', 'manage' ), 's2_tools', array( &$this, 'subscribers_menu' ) );
16
  add_action( "admin_print_scripts-$s2subscribers", array( &$this, 'checkbox_form_js' ) );
17
  add_action( "admin_print_scripts-$s2subscribers", array( &$this, 'subscribers_form_js' ) );
18
+ add_action( "admin_print_scripts-$s2subscribers", array( &$this, 'subscribers_css' ) );
19
  add_action( 'load-' . $s2subscribers, array( &$this, 'subscribers_help' ) );
20
+ add_action( 'load-' . $s2subscribers, array( &$this, 'subscribers_options' ) );
21
 
22
  $s2settings = add_submenu_page( 's2', __( 'Settings', 'subscribe2' ), __( 'Settings', 'subscribe2' ), apply_filters( 's2_capability', 'manage_options', 'settings' ), 's2_settings', array( &$this, 'settings_menu' ) );
23
  add_action( "admin_print_scripts-$s2settings", array( &$this, 'checkbox_form_js' ) );
28
 
29
  $s2mail = add_submenu_page( 's2', __( 'Send Email', 'subscribe2' ), __( 'Send Email', 'subscribe2' ), apply_filters( 's2_capability', 'publish_posts', 'send' ), 's2_posts', array( &$this, 'write_menu' ) );
30
  add_action( 'load-' . $s2mail, array( &$this, 'mail_help' ) );
31
+ }
32
 
33
  /**
34
+ * Contextual Help
35
+ */
36
+ public function user_help() {
37
  $screen = get_current_screen();
38
  if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
39
+ $screen->add_help_tab(
40
+ array(
41
+ 'id' => 's2-user-help1',
42
+ 'title' => __( 'Overview', 'subscribe2' ),
43
+ 'content' => '<p>' . __( 'From this page you can opt in or out of receiving a periodical digest style email of blog posts.', 'subscribe2' ) . '</p>',
44
+ )
45
+ );
46
  } else {
47
+ $screen->add_help_tab(
48
+ array(
49
+ 'id' => 's2-user-help1',
50
+ 'title' => __( 'Overview', 'subscribe2' ),
51
+ 'content' => '<p>' . __( 'From this page you can control your subscription preferences. Choose the email format you wish to receive, which categories you would like to receive notification for and depending on the site settings which authors you would like to read.', 'subscribe2' ) . '</p>',
52
+ )
53
+ );
54
  }
55
+ }
56
 
57
+ public function subscribers_help() {
58
  $screen = get_current_screen();
59
+ $screen->add_help_tab(
60
+ array(
61
+ 'id' => 's2-subscribers-help1',
62
+ 'title' => __( 'Overview', 'subscribe2' ),
63
+ 'content' => '<p>' . __( 'From this page you can manage your subscribers.', 'subscribe2' ) . '</p>',
64
+ )
65
+ );
66
+ $screen->add_help_tab(
67
+ array(
68
+ 'id' => 's2-subscribers-help2',
69
+ 'title' => __( 'Public Subscribers', 'subscribe2' ),
70
+ 'content' => '<p>' . __( 'Public Subscribers are subscribers who have used the plugin form and only provided their email address.', 'subscribe2' ) . '</p><p>' . __( 'On this page public subscribers can be viewed, searched, deleted and also toggled between Confirmed and Unconfirmed status.', 'subscribe2' ) . '</p>',
71
+ )
72
+ );
73
+ $screen->add_help_tab(
74
+ array(
75
+ 'id' => 's2-subscribers-help3',
76
+ 'title' => __( 'Registered Subscribers', 'subscribe2' ),
77
+ 'content' => '<p>' . __( 'Registered Subscribers are subscribers who have registered in WordPress and have a username and password.', 'subscribe2' ) .
78
+ '</p><p>' . __( 'Registered Subscribers have greater personal control over their subscription. They can change the format of the email and also select which categories and authors they want to receive notifications about.', 'subscribe2' ) .
79
+ '</p><p>' . __( 'On this page registered subscribers can be viewed and searched. User accounts can be deleted from here with any posts created by those users being assigned to the currently logged in user. Bulk changes can be applied to all user settings changing their subscription email format and categories.', 'subscribe2' ) . '</p>',
80
+ )
81
+ );
82
+ }
83
+
84
+ public function subscribers_options() {
85
+ $option = 'per_page';
86
+
87
+ $args = array(
88
+ 'label' => __( 'Number of subscribers per page: ', 'subscribe2' ),
89
+ 'default' => 25,
90
+ 'option' => 'subscribers_per_page',
91
+ );
92
+ add_screen_option( $option, $args );
93
+ }
94
+
95
+ public function subscribers_set_screen_option( $status, $option, $value ) {
96
+ if ( 'subscribers_per_page' === $option && false === $status ) {
97
+ if ( $value < 1 || $value > 999 ) {
98
+ return;
99
+ }
100
+ return $value;
101
+ }
102
+ }
103
+
104
+ public function settings_help() {
105
  $screen = get_current_screen();
106
+ $screen->add_help_tab(
107
+ array(
108
+ 'id' => 's2-settings-help1',
109
+ 'title' => __( 'Overview', 'subscribe2' ),
110
+ 'content' => '<p>' . __( 'From this page you can adjust the Settings for Subscribe2.', 'subscribe2' ) . '</p>',
111
+ )
112
+ );
113
+ $screen->add_help_tab(
114
+ array(
115
+ 'id' => 's2-settings-help2',
116
+ 'title' => __( 'Email Settings', 'subscribe2' ),
117
+ 'content' => '<p>' . __( 'This section allows you to specify settings that apply to the emails generated by the site.', 'subscribe2' ) .
118
+ '</p><p>' . __( 'Emails can be sent to individual subscribers by setting the number of recipients per email to 1. A setting greater than one will group recipients together and make use of the BCC emails header. A setting of 0 sends a single email with all subscribers in one large BCC group. A setting of 1 looks less like spam email to filters but takes longer to process.', 'subscribe2' ) .
119
+ '</p><p>' . __( 'This section is also where the sender of the email on this page is chosen. You can choose Post Author or your Blogname but it is recommended to create a user account with an email address that really exists and shares the same domain name as your site (the bit after the @ should be the same as your sites web address) and then use this account.', 'subscribe2' ) .
120
+ '</p><p>' . __( 'This page also configures the frequency of emails. This can be at the time new posts are made (per post) or periodically with an excerpt of each post made (digest). Additionally the post types (pages, private, password protected) can also be configured here.', 'subscribe2' ) . '</p>',
121
+ )
122
+ );
123
+ $screen->add_help_tab(
124
+ array(
125
+ 'id' => 's2-settings-help3',
126
+ 'title' => __( 'Templates', 'subscribe2' ),
127
+ 'content' => '<p>' . __( 'This section allows you to customise the content of your notification emails.', 'subscribe2' ) .
128
+ '</p><p>' . __( 'There are special {KEYWORDS} that are used by Subscribe2 to place content into the final email. The template also accepts regular text and HTML as desired in the final emails.', 'subscribe2' ) .
129
+ '</p><p>' . __( 'The {KEYWORDS} are listed on the right of the templates, note that some are for per post emails only and some are for digest emails only. Make sure the correct keywords are used based upon the Email Settings.', 'subscribe2' ) .
130
+ '</p><p>' . __( 'The Notification Email template is used for sending notifications of new posts. The Subscribe / Unsubscribe confirmation template is sent when a new subscription or unsubscription request is made. The Reminder template is used to send reminder emails; this is done automatically or can be done manually.', 'subscribe2' ) . '</p>',
131
+ )
132
+ );
133
+ $screen->add_help_tab(
134
+ array(
135
+ 'id' => 's2-settings-help4',
136
+ 'title' => __( 'Registered Users', 'subscribe2' ),
137
+ 'content' => '<p>' . __( 'This section allows settings that apply to Registered Subscribers to be configured.', 'subscribe2' ) .
138
+ '</p><p>' . __( 'Categories can be made compulsory so emails are always sent for posts in these categories. They can also be excludes so that emails are not generated. Excluded categories take precedence over Compulsory categories.', 'subscribe2' ) .
139
+ '</p><p>' . __( 'A set of default settings for new users can also be specified using the Auto Subscribe section. Settings specified here will be applied to any newly created user accounts while Subscribe2 is activated.', 'subscribe2' ) . '</p>',
140
+ )
141
+ );
142
+ $screen->add_help_tab(
143
+ array(
144
+ 'id' => 's2-settings-help5',
145
+ 'title' => __( 'Appearance', 'subscribe2' ),
146
+ 'content' => '<p>' . __( 'This section allows you to enable several aspect of the plugin such as Widgets and editor buttons.', 'subscribe2' ) .
147
+ '</p><p>' . __( 'AJAX mode can be enabled that is intended to work with the shortcode link parameter so that a dialog opens in the centre of the browser rather then using the regular form.', 'subscribe2' ) .
148
+ '</p><p>' . __( 'The email over ride check box can be set to be automatically checked for every new post and page from here to, this may be useful if you will only want to send very occasional notifications for specific posts. You can then uncheck this box just before you publish your content.', 'subscribe2' ) . '</p>',
149
+ )
150
+ );
151
+ $screen->add_help_tab(
152
+ array(
153
+ 'id' => 's2-settings-help6',
154
+ 'title' => __( 'ReCaptcha', 'subscribe2' ),
155
+ 'content' => '<p>' . __( 'This section holds site and secret keys for using Google ReCaptcha.', 'subscribe2' ) .
156
+ '</p><p>' . __( 'V2 ReCaptcha takes precedence over Invisible ReCaptcha. To use Invisible ReCaptcha, leave the V2 ReCaptcha key fields empty.', 'subscribe2' ) .
157
+ '</p><p>' . __( 'Both key files needs populating for V2 ReCaptcha or Invisible ReCaptcha, failure to complete both fields will result in ReCaptcha not working.', 'subscribe2' ) . '</p>',
158
+ )
159
+ );
160
+ $screen->add_help_tab(
161
+ array(
162
+ 'id' => 's2-settings-help7',
163
+ 'title' => __( 'Miscellaneous', 'subscribe2' ),
164
+ 'content' => '<p>' . __( 'This section contains a place to bar specified domains from becoming Public Subscribers and links to help and support pages.', 'subscribe2' ) .
165
+ '</p><p>' . __( 'In the paid Subscribe2 HTML version there is also a place here to enter a license code so that updates can be accessed automatically.', 'subscribe2' ) .
166
+ '</p>',
167
+ )
168
+ );
169
+ }
170
+
171
+ public function mail_help() {
172
  $screen = get_current_screen();
173
+ $screen->add_help_tab(
174
+ array(
175
+ 'id' => 's2-send-mail-help1',
176
+ 'title' => __( 'Overview', 'subscribe2' ),
177
+ 'content' => '<p>' . __( 'From this page you can send emails to the recipients in the group selected in the drop down.', 'subscribe2' ) .
178
+ '</p><p>' . __( '<strong>Preview</strong> will send a preview of the email to the currently logged in user. <strong>Send</strong> will send the email to the recipient list.', 'subscribe2' ) . '</p>',
179
+ )
180
+ );
181
+ }
182
+
183
+ /**
184
+ * Hook for Admin Drop Down Icons
185
+ */
186
+ public function ozh_s2_icon() {
187
  return S2URL . 'include/email-edit.png';
188
+ }
189
 
190
  /**
191
+ * Insert Javascript and CSS into admin_headers
192
+ */
193
+ public function checkbox_form_js() {
194
+ wp_register_script( 's2_checkbox', S2URL . 'include/s2-checkbox' . $this->script_debug . '.js', array( 'jquery' ), '1.4' );
195
  wp_enqueue_script( 's2_checkbox' );
196
+ }
197
 
198
+ public function user_admin_css() {
199
+ wp_register_style( 's2_user_admin', S2URL . 'include/s2-user-admin' . $this->script_debug . '.css', array(), '1.0' );
200
  wp_enqueue_style( 's2_user_admin' );
201
+ }
202
 
203
+ public function option_form_js() {
204
+ wp_register_script( 's2_edit', S2URL . 'include/s2-edit' . $this->script_debug . '.js', array( 'jquery' ), '1.3' );
205
  wp_enqueue_script( 's2_edit' );
206
  if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
207
  wp_enqueue_script( 'jquery-ui-datepicker' );
208
  wp_enqueue_style( 'jquery-style', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css' );
209
+ wp_register_script( 's2_date_time', S2URL . 'include/s2-date-time' . $this->script_debug . '.js', array( 'jquery-ui-datepicker' ), '1.1' );
210
  wp_enqueue_script( 's2_date_time' );
211
  }
212
+ }
213
 
214
+ public function dismiss_js() {
215
+ wp_register_script( 's2_dismiss', S2URL . 'include/s2-dismiss' . $this->script_debug . '.js', array( 'jquery' ), '1.1', true );
216
  $translation_array = array(
217
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
218
+ 'nonce' => wp_create_nonce( 's2_dismiss_nonce' ),
219
  );
220
+ wp_localize_script( 's2_dismiss', 's2DismissScriptStrings', $translation_array );
221
  wp_enqueue_script( 's2_dismiss' );
222
+ }
223
 
224
+ public function s2_dismiss_notice_handler() {
225
  if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 's2_dismiss_nonce' ) ) {
226
  return false;
227
  }
228
  $this->subscribe2_options['dismiss_sender_warning'] = '1';
229
  update_option( 'subscribe2_options', $this->subscribe2_options );
230
  wp_die();
231
+ }
232
 
233
+ public function subscribers_form_js() {
234
+ wp_register_script( 's2_subscribers', S2URL . 'include/s2-subscribers' . $this->script_debug . '.js', array(), '1.5' );
235
  $translation_array = array(
236
  'registered_confirm_single' => __( 'You are about to delete a registered user account, any posts made by this user will be assigned to you. Are you sure?', 'subscribe2' ),
237
  'registered_confirm_plural' => __( 'You are about to delete registered user accounts, any posts made by these users will be assigned to you. Are you sure?', 'subscribe2' ),
238
+ 'public_confirm_single' => __( 'You are about to delete a public subscriber. Are you sure?', 'subscribe2' ),
239
+ 'public_confirm_plural' => __( 'You are about to delete public subscribers. Are you sure?', 'subscribe2' ),
240
+ 'bulk_manage_all' => __( 'You are about to make Bulk Management changes to all Registered Users. Are you sure?', 'subscribe2' ),
241
+ 'bulk_manage_single' => __( 'You are about to make Bulk Management changes to the selected Registered User. Are you sure?', 'subscribe2' ),
242
+ 'bulk_manage_plural' => __( 'You are about to make Bulk Management changes to the selected Registered Users. Are you sure?', 'subscribe2' ),
243
  );
244
+ wp_localize_script( 's2_subscribers', 's2ScriptStrings', $translation_array );
245
  wp_enqueue_script( 's2_subscribers' );
246
+ }
247
+
248
+ public function subscribers_css() {
249
+ echo '<style type="text/css">';
250
+ echo '.wp-list-table .column-date { width: 15%; }';
251
+ echo '</style>';
252
+ }
253
 
254
  /**
255
+ * Adds a links directly to the settings page from the plugin page
256
+ */
257
+ public function plugin_links( $links, $file ) {
258
  if ( S2DIR . 'subscribe2.php' === $file ) {
259
  $links[] = '<a href="admin.php?page=s2_settings">' . __( 'Settings', 'subscribe2' ) . '</a>';
260
  $links[] = '<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=2387904"><b>' . __( 'Donate', 'subscribe2' ) . '</b></a>';
261
  }
262
  return $links;
263
+ }
264
 
265
  /* ===== Menus ===== */
266
  /**
267
+ * Our subscriber management page
268
+ */
269
+ public function subscribers_menu() {
270
+ require_once S2PATH . 'admin/subscribers.php';
271
+ }
272
 
273
  /**
274
+ * Our settings page
275
+ */
276
+ public function settings_menu() {
277
+ require_once S2PATH . 'admin/settings.php';
278
+ }
279
 
280
  /**
281
+ * Our profile menu
282
+ */
283
+ public function user_menu() {
284
+ require_once S2PATH . 'admin/your-subscriptions.php';
285
+ }
286
 
287
  /**
288
+ * Display the Write sub-menu
289
+ */
290
+ public function write_menu() {
291
+ require_once S2PATH . 'admin/send-email.php';
292
+ }
293
 
294
  /* ===== Write Toolbar Button Functions ===== */
295
  /**
296
+ * Register our button in the QuickTags bar
297
+ */
298
+ public function button_init() {
299
  global $pagenow;
300
+ if ( ! in_array( $pagenow, array( 'post-new.php', 'post.php', 'page-new.php', 'page.php' ) ) && ! strpos( esc_url( $_SERVER['REQUEST_URI'] ), 'page=s2_posts' ) ) {
301
+ return;
302
+ }
303
+ if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) {
304
+ return;
305
+ }
306
  if ( 'true' === get_user_option( 'rich_editing' ) ) {
307
  // Hook into the rich text editor
308
  add_filter( 'mce_external_plugins', array( &$this, 'mce_plugin' ) );
310
  } else {
311
  wp_enqueue_script( 'subscribe2_button', S2URL . 'include/s2-button' . $this->script_debug . '.js', array( 'quicktags' ), '2.0' );
312
  }
313
+ }
314
 
315
  /**
316
+ * Add buttons for Rich Text Editor
317
+ */
318
+ public function mce_plugin( $arr ) {
319
  if ( version_compare( $this->wp_release, '3.9', '<' ) ) {
320
  $path = S2URL . 'tinymce/editor-plugin3' . $this->script_debug . '.js';
321
  } else {
323
  }
324
  $arr['subscribe2'] = $path;
325
  return $arr;
326
+ }
327
 
328
+ public function mce_button( $arr ) {
329
  $arr[] = 'subscribe2';
330
  return $arr;
331
+ }
332
 
333
  /* ===== widget functions ===== */
334
  /**
335
+ * Function to add css and js files to admin header
336
+ */
337
+ public function widget_s2counter_css_and_js() {
338
  // ensure we only add colorpicker js to widgets page
339
  if ( false !== stripos( esc_url( $_SERVER['REQUEST_URI'] ), 'widgets.php' ) ) {
340
  wp_enqueue_style( 'farbtastic' );
341
  wp_enqueue_script( 'farbtastic' );
342
+ wp_register_script( 's2_colorpicker', S2URL . 'include/s2-colorpicker' . $this->script_debug . '.js', array( 'farbtastic' ), '1.3' );
343
  wp_enqueue_script( 's2_colorpicker' );
344
  }
345
+ }
346
 
347
  /* ===== meta box functions to allow per-post override ===== */
348
  /**
349
+ * Create meta box on write pages
350
+ */
351
+ public function s2_meta_init() {
352
+ if ( true === $this->block_editor ) {
353
+ return;
354
+ }
355
+
356
  if ( 'yes' === $this->subscribe2_options['pages'] ) {
357
  $s2_post_types = array( 'page', 'post' );
358
  } else {
359
  $s2_post_types = array( 'post' );
360
  }
361
+
362
  $s2_post_types = apply_filters( 's2_post_types', $s2_post_types );
363
+
364
  foreach ( $s2_post_types as $s2_post_type ) {
365
+ add_meta_box(
366
+ 'subscribe2',
367
+ __( 'Subscribe2 Notification Override', 'subscribe2' ),
368
+ array( &$this, 's2_override_meta' ),
369
+ $s2_post_type,
370
+ 'advanced',
371
+ 'default',
372
+ array(
373
+ '__block_editor_compatible_meta_box' => false,
374
+ )
375
+ );
376
  }
377
+ }
378
 
379
  /**
380
+ * Meta override box code
381
+ */
382
+ public function s2_override_meta() {
383
  global $post_ID;
384
  $s2mail = get_post_meta( $post_ID, '_s2mail', true );
385
  echo '<input type="hidden" name="s2meta_nonce" id="s2meta_nonce" value="' . wp_create_nonce( wp_hash( plugin_basename( __FILE__ ) ) ) . '" />';
389
  echo ' checked="checked"';
390
  }
391
  echo ' />';
392
+ }
393
 
394
  /**
395
+ * Meta override box form handler
396
+ */
397
+ public function s2_meta_handler( $post_id ) {
398
+ if ( ! isset( $_POST['s2meta_nonce'] ) || ! wp_verify_nonce( $_POST['s2meta_nonce'], wp_hash( plugin_basename( __FILE__ ) ) ) ) {
399
+ return $post_id;
400
+ }
401
 
402
  if ( 'page' === $_POST['post_type'] ) {
403
+ if ( ! current_user_can( 'edit_page', $post_id ) ) {
404
+ return $post_id;
405
+ }
406
  } else {
407
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
408
+ return $post_id;
409
+ }
410
  }
411
 
412
  if ( isset( $_POST['s2_meta_field'] ) && 'no' === $_POST['s2_meta_field'] ) {
414
  } else {
415
  update_post_meta( $post_id, '_s2mail', 'yes' );
416
  }
417
+ }
418
 
419
  /* ===== WordPress menu helper functions ===== */
420
  /**
421
+ * Collects the signup date for all public subscribers
422
+ */
423
+ public function signup_date( $email = '' ) {
424
+ if ( '' === $email ) {
425
+ return false;
426
+ }
427
 
428
  global $wpdb;
429
  if ( ! empty( $this->signup_dates ) ) {
430
  return $this->signup_dates[ $email ];
431
  } else {
432
+ $results = $wpdb->get_results( "SELECT email, date FROM $wpdb->subscribe2", ARRAY_N );
433
  foreach ( $results as $result ) {
434
  $this->signup_dates[ $result[0] ] = $result[1];
435
  }
436
  return $this->signup_dates[ $email ];
437
  }
438
+ }
439
 
440
  /**
441
+ * Collects the signup time for all public subscribers
442
+ */
443
+ public function signup_time( $email = '' ) {
444
+ if ( '' === $email ) {
445
+ return false;
446
+ }
447
+
448
+ global $wpdb;
449
+ if ( ! empty( $this->signup_times ) ) {
450
+ return $this->signup_times[ $email ];
451
+ } else {
452
+ $results = $wpdb->get_results( "SELECT email, time FROM $wpdb->subscribe2", ARRAY_N );
453
+ foreach ( $results as $result ) {
454
+ $this->signup_times[ $result[0] ] = $result[1];
455
+ }
456
+ return $this->signup_times[ $email ];
457
+ }
458
+ }
459
+
460
+ /**
461
+ * Collects the ip address for all public subscribers
462
+ */
463
+ public function signup_ip( $email = '' ) {
464
+ if ( '' === $email ) {
465
+ return false;
466
+ }
467
 
468
  global $wpdb;
469
  if ( ! empty( $this->signup_ips ) ) {
470
  return $this->signup_ips[ $email ];
471
  } else {
472
+ $results = $wpdb->get_results( "SELECT email, ip FROM $wpdb->subscribe2", ARRAY_N );
473
  foreach ( $results as $result ) {
474
  $this->signup_ips[ $result[0] ] = $result[1];
475
  }
476
  return $this->signup_ips[ $email ];
477
  }
478
+ }
479
 
480
  /**
481
+ * Export subscriber emails and other details to CSV
482
+ */
483
+ public function prepare_export( $subscribers ) {
484
+ if ( empty( $subscribers ) ) {
485
+ return;
486
+ }
487
  $subscribers = explode( ",\r\n", $subscribers );
488
  natcasesort( $subscribers );
489
 
490
+ $exportcsv = _x( 'User Email,User Type,User Name,Confirm Date,IP', 'Comma Separated Column Header names for CSV Export', 'subscribe2' );
491
+ $all_cats = $this->all_cats( false, 'ID' );
492
 
493
  foreach ( $all_cats as $cat ) {
494
  $exportcsv .= ',' . html_entity_decode( $cat->cat_name, ENT_QUOTES );
495
+ $cat_ids[] = $cat->term_id;
496
  }
497
  $exportcsv .= "\r\n";
498
 
499
  foreach ( $subscribers as $subscriber ) {
500
  if ( $this->is_registered( $subscriber ) ) {
501
+ $user_id = $this->get_user_id( $subscriber );
502
+ $user_info = get_userdata( $user_id );
503
 
504
+ $cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
505
  $subscribed_cats = '';
506
  foreach ( $cat_ids as $cat ) {
507
+ ( in_array( $cat, $cats ) ) ? $subscribed_cats .= ',Yes' : $subscribed_cats .= ',No';
508
  }
509
 
510
  $exportcsv .= $subscriber . ',';
521
  }
522
 
523
  return $exportcsv;
524
+ }
525
 
526
  /**
527
+ * Display a table of post formats supported by the currently active theme
528
+ */
529
+ public function display_format_form( $formats, $selected = array() ) {
530
+ $half = ( count( $formats[0] ) / 2 );
531
+ $i = 0;
532
+ $j = 0;
533
  echo '<table style="width: 100%; border-collapse: separate; border-spacing: 2px; *border-collapse: expression(\'separate\', cellSpacing = \'2px\');" class="editform">' . "\r\n";
534
  echo '<tr><td style="text-align: left;" colspan="2">' . "\r\n";
535
  echo '<label><input type="checkbox" name="checkall" value="checkall_format" /> ' . __( 'Select / Unselect All', 'subscribe2' ) . '</label>' . "\r\n";
558
  }
559
  echo '</td></tr>' . "\r\n";
560
  echo '</table>' . "\r\n";
561
+ }
562
 
563
  /**
564
+ * Display a drop-down form to select subscribers
565
+ * $selected is the option to select
566
+ * $submit is the text to use on the Submit button
567
+ */
568
+ public function display_subscriber_dropdown( $selected = 'registered', $submit = '', $exclude = array() ) {
569
  global $wpdb;
570
 
571
  $who = array(
572
+ 'all' => __( 'All Users and Subscribers', 'subscribe2' ),
573
+ 'public' => __( 'Public Subscribers', 'subscribe2' ),
574
+ 'confirmed' => ' &nbsp;&nbsp;' . __( 'Confirmed', 'subscribe2' ),
575
  'unconfirmed' => ' &nbsp;&nbsp;' . __( 'Unconfirmed', 'subscribe2' ),
576
+ 'all_users' => __( 'All Registered Users', 'subscribe2' ),
577
+ 'registered' => __( 'Registered Subscribers', 'subscribe2' ),
578
  );
579
 
580
  $all_cats = $this->all_cats( false );
581
 
582
  // count the number of subscribers
583
+ $count['confirmed'] = $wpdb->get_var( "SELECT COUNT(id) FROM $wpdb->subscribe2 WHERE active='1'" );
584
+ $count['unconfirmed'] = $wpdb->get_var( "SELECT COUNT(id) FROM $wpdb->subscribe2 WHERE active='0'" );
585
  if ( in_array( 'unconfirmed', $exclude ) ) {
586
  $count['public'] = $count['confirmed'];
587
  } elseif ( in_array( 'confirmed', $exclude ) ) {
588
  $count['public'] = $count['unconfirmed'];
589
  } else {
590
+ $count['public'] = ( $count['confirmed'] + $count['unconfirmed'] );
591
  }
592
  if ( $this->s2_mu ) {
593
  $count['all_users'] = $wpdb->get_var( "SELECT COUNT(meta_key) FROM $wpdb->usermeta WHERE meta_key='" . $wpdb->prefix . "capabilities'" );
599
  } else {
600
  $count['registered'] = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(meta_key) FROM $wpdb->usermeta WHERE meta_key=%s AND meta_value <> ''", $this->get_usermeta_keyname( 's2_subscribed' ) ) );
601
  }
602
+ $count['all'] = ( $count['confirmed'] + $count['unconfirmed'] + $count['all_users'] );
603
  // get subscribers to individual categories but only if we are using per-post notifications
604
  if ( 'never' === $this->subscribe2_options['email_freq'] ) {
605
  $compulsory = explode( ',', $this->subscribe2_options['compulsory'] );
624
 
625
  echo '<select name="what">' . "\r\n";
626
  foreach ( $who as $whom => $display ) {
627
+ if ( in_array( $whom, $exclude ) ) {
628
+ continue;
629
+ }
630
 
631
  echo '<option value="' . $whom . '"';
632
+ if ( $whom === $selected ) {
633
+ echo ' selected="selected" ';
634
+ }
635
+ echo '>' . $display . ' (' . ( $count[ $whom ] ) . ')</option>' . "\r\n";
636
  }
637
 
638
  if ( $count['registered'] > 0 && 'never' === $this->subscribe2_options['email_freq'] ) {
639
  foreach ( $all_cats as $cat ) {
640
+ if ( in_array( $cat->term_id, $exclude ) ) {
641
+ continue;
642
+ }
643
  echo '<option value="' . $cat->term_id . '"';
644
+ if ( $cat->term_id === $selected ) {
645
+ echo ' selected="selected" ';
646
+ }
647
  echo '> &nbsp;&nbsp;' . $cat->name . '&nbsp;(' . $count[ $cat->name ] . ') </option>' . "\r\n";
648
  }
649
  }
651
  if ( false !== $submit ) {
652
  echo '&nbsp;<input type="submit" class="button-secondary" value="' . $submit . '" />' . "\r\n";
653
  }
654
+ }
655
 
656
  /**
657
+ * Display a drop down list of administrator level users and
658
+ * optionally include a choice for Post Author
659
+ */
660
+ public function admin_dropdown( $inc_author = false ) {
661
  global $wpdb;
662
 
663
  $args = array(
665
  'ID',
666
  'display_name',
667
  ),
668
+ 'role' => 'administrator',
669
  );
670
+
671
  $wp_user_query = get_users( $args );
672
  if ( ! empty( $wp_user_query ) ) {
673
  foreach ( $wp_user_query as $user ) {
679
 
680
  if ( $inc_author ) {
681
  $author[] = (object) array(
682
+ 'ID' => 'author',
683
  'display_name' => __( 'Post Author', 'subscribe2' ),
684
  );
685
  $author[] = (object) array(
686
+ 'ID' => 'blogname',
687
  'display_name' => html_entity_decode( get_option( 'blogname' ), ENT_QUOTES ),
688
  );
689
+ $admins = array_merge( $author, $admins );
690
  }
691
 
692
  echo '<select name="sender">' . "\r\n";
698
  echo '>' . $admin->display_name . '</option>' . "\r\n";
699
  }
700
  echo '</select>' . "\r\n";
701
+ }
702
 
703
  /**
704
+ * Display a dropdown of choices for digest email frequency
705
+ * and give user details of timings when event is scheduled
706
+ */
707
+ public function display_digest_choices() {
708
  global $wpdb;
709
  $cron_file = ABSPATH . 'wp-cron.php';
710
  if ( ! is_readable( $cron_file ) ) {
711
  echo '<strong><em style="color: red">' . __( 'The WordPress cron functions may be disabled on this server. Digest notifications may not work.', 'subscribe2' ) . '</em></strong><br />' . "\r\n";
712
  }
713
  $scheduled_time = wp_next_scheduled( 's2_digest_cron' );
714
+ $offset = get_option( 'gmt_offset' ) * 60 * 60;
715
+ $schedule = (array) wp_get_schedules();
716
+ $schedule = array_merge(
717
+ array(
718
+ 'never' => array(
719
+ 'interval' => 0,
720
+ 'display' => __( 'For each Post', 'subscribe2' ),
721
+ ),
722
  ),
723
+ $schedule
724
+ );
725
+
726
  $sort = array();
727
  foreach ( (array) $schedule as $key => $value ) {
728
  $sort[ $key ] = $value['interval'];
748
  echo '<input type="hidden" id="jscrontime" value="' . date_i18n( $time_format, $scheduled_time + $offset ) . '" />';
749
  echo '<span id="s2cron_1"><span id="s2crondate" style="background-color: #FFFBCC">' . date_i18n( $date_format, $scheduled_time + $offset ) . '</span>';
750
  echo ' @ <span id="s2crontime" style="background-color: #FFFBCC">' . date_i18n( $time_format, $scheduled_time + $offset ) . '</span> ';
751
+ echo '<a href="#" onclick="s2Show(\'cron\'); return false;">' . __( 'Edit', 'subscribe2' ) . '</a></span>' . "\r\n";
752
  echo '<span id="s2cron_2">' . "\r\n";
753
  echo '<input id="s2datepicker" name="crondate" value="' . date_i18n( $date_format, $scheduled_time + $offset ) . '">' . "\r\n";
754
+ $hours = array( '12:00 am', '1:00 am', '2:00 am', '3:00 am', '4:00 am', '5:00 am', '6:00 am', '7:00 am', '8:00 am', '9:00 am', '10:00 am', '11:00 am', '12:00 pm', '1:00 pm', '2:00 pm', '3:00 pm', '4:00 pm', '5:00 pm', '6:00 pm', '7:00 pm', '8:00 pm', '9:00 pm', '10:00 pm', '11:00 pm' );
755
  $current_hour = intval( date_i18n( 'G', $scheduled_time + $offset ) );
756
  echo '<select name="crontime">' . "\r\n";
757
  foreach ( $hours as $key => $value ) {
762
  echo '>' . $value . '</option>' . "\r\n";
763
  }
764
  echo '</select>' . "\r\n";
765
+ echo '<a href="#" onclick="s2CronUpdate(\'cron\'); return false;">' . __( 'Update', 'subscribe2' ) . '</a>' . "\r\n";
766
+ echo '<a href="#" onclick="s2CronRevert(\'cron\'); return false;">' . __( 'Revert', 'subscribe2' ) . '</a></span>' . "\r\n";
767
  if ( ! empty( $this->subscribe2_options['last_s2cron'] ) ) {
768
  echo '<p>' . __( 'Attempt to resend the last Digest Notification email', 'subscribe2' ) . ': ';
769
  echo '<input type="submit" class="button-secondary" name="resend" value="' . __( 'Resend Digest', 'subscribe2' ) . '" /></p>' . "\r\n";
771
  } else {
772
  echo '<br />';
773
  }
774
+ }
775
 
776
  /**
777
+ * Create and display a dropdown list of pages
778
+ */
779
+ public function pages_dropdown( $s2page ) {
780
  $pages = get_pages();
781
+ if ( empty( $pages ) ) {
782
+ return;
783
+ }
784
 
785
  $option = '';
786
  foreach ( $pages as $page ) {
799
  }
800
 
801
  echo $option;
802
+ }
803
 
804
  /**
805
+ * Subscribe all registered users to category selected on Admin Manage Page
806
+ */
807
+ public function subscribe_registered_users( $emails = '', $cats = array() ) {
808
+ if ( '' === $emails || '' === $cats ) {
809
+ return false;
810
+ }
811
  global $wpdb;
812
 
813
  $useremails = explode( ",\r\n", $emails );
814
  $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
815
 
816
+ $user_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" );
 
817
 
818
+ foreach ( $user_ids as $user_id ) {
819
+ $old_cats = get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true );
820
  if ( ! empty( $old_cats ) ) {
821
  $old_cats = explode( ',', $old_cats );
822
+ $newcats = array_unique( array_merge( $cats, $old_cats ) );
823
  } else {
824
  $newcats = $cats;
825
  }
826
  if ( ! empty( $newcats ) && $newcats !== $old_cats ) {
827
  // add subscription to these cat IDs
828
  foreach ( $newcats as $id ) {
829
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id, $id );
830
  }
831
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
832
  }
833
  unset( $newcats );
834
  }
835
+ }
836
 
837
  /**
838
+ * Unsubscribe all registered users to category selected on Admin Manage Page
839
+ */
840
+ public function unsubscribe_registered_users( $emails = '', $cats = array() ) {
841
+ if ( '' === $emails || '' === $cats ) {
842
+ return false;
843
+ }
844
  global $wpdb;
845
 
846
  $useremails = explode( ",\r\n", $emails );
847
  $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
848
 
849
+ $user_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // WPCS: unprepared SQL OK.
 
850
 
851
+ foreach ( $user_ids as $user_id ) {
852
+ $old_cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
853
+ $remain = array_diff( $old_cats, $cats );
854
  if ( ! empty( $remain ) && $remain !== $old_cats ) {
855
  // remove subscription to these cat IDs and update s2_subscribed
856
  foreach ( $cats as $id ) {
857
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id );
858
  }
859
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $remain ) );
860
  } else {
861
  // remove subscription to these cat IDs and update s2_subscribed to ''
862
  foreach ( $cats as $id ) {
863
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id );
864
  }
865
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ) );
866
  }
867
  unset( $remain );
868
  }
869
+ }
870
 
871
  /**
872
+ * Handles bulk changes to email format for Registered Subscribers
873
+ */
874
+ public function format_change( $emails, $format ) {
875
+ if ( empty( $format ) ) {
876
+ return;
877
+ }
878
 
879
  global $wpdb;
880
  $useremails = explode( ",\r\n", $emails );
881
  $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
882
+ $ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // WPCS: unprepared SQL OK.
883
+ $ids = implode( ',', array_map( array( $this, 'prepare_in_data' ), $ids ) );
884
+ $sql = "UPDATE $wpdb->usermeta SET meta_value='{$format}' WHERE meta_key='" . $this->get_usermeta_keyname( 's2_format' ) . "' AND user_id IN ($ids)";
885
+ $wpdb->query( $sql ); // WPCS: unprepared SQL OK.
886
+ }
887
 
888
  /**
889
+ * Handles bulk update to digest preferences
890
+ */
891
+ public function digest_change( $emails, $digest ) {
892
+ if ( empty( $digest ) ) {
893
+ return;
894
+ }
895
 
896
  global $wpdb;
897
  $useremails = explode( ",\r\n", $emails );
898
  $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
899
 
900
+ $user_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // WPCS: unprepared SQL OK.
 
901
 
902
  if ( 'digest' === $digest ) {
903
  $exclude = explode( ',', $this->subscribe2_options['exclude'] );
909
 
910
  $cats_string = '';
911
  foreach ( $all_cats as $cat ) {
912
+ ( '' === $cats_string ) ? $cats_string = "$cat->term_id" : $cats_string .= ",$cat->term_id";
913
  }
914
 
915
+ foreach ( $user_ids as $user_id ) {
916
  foreach ( $all_cats as $cat ) {
917
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $cat->term_id, $cat->term_id );
918
  }
919
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), $cats_string );
920
  }
921
  } elseif ( '-1' === $digest ) {
922
+ foreach ( $user_ids as $user_id ) {
923
+ $cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
924
  foreach ( $cats as $id ) {
925
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id );
926
  }
927
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ) );
928
  }
929
  }
930
+ }
931
 
932
  /* ===== functions to handle addition and removal of WordPress categories ===== */
933
  /**
934
+ * Autosubscribe registered users to newly created categories
935
+ * if registered user has selected this option
936
+ */
937
+ public function new_category( $new_category = '' ) {
938
+ if ( 'no' === $this->subscribe2_options['show_autosub'] ) {
939
+ return;
940
+ }
941
 
942
  global $wpdb;
943
  if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
944
  // if we are doing digests add new categories to users who are currently opted in
945
+ $user_ids = $wpdb->get_col(
946
+ $wpdb->prepare(
947
+ "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key=%s AND meta_value<>''",
948
+ $this->get_usermeta_keyname( 's2_subscribed' )
949
+ )
950
+ );
951
+ foreach ( $user_ids as $user_id ) {
952
+ $old_cats = get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true );
953
  $old_cats = explode( ',', $old_cats );
954
+ $newcats = array_merge( $old_cats, (array) $new_category );
955
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $new_category, $new_category );
956
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
957
  }
958
  return;
959
  }
960
 
961
  if ( 'yes' === $this->subscribe2_options['show_autosub'] ) {
962
  if ( $this->s2_mu ) {
963
+ $user_ids = $wpdb->get_col(
964
+ $wpdb->prepare(
965
+ "SELECT DISTINCT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b WHERE a.user_id = b.user_id AND a.meta_key=%s AND a.meta_value='yes' AND b.meta_key=%s",
966
+ $this->get_usermeta_keyname( 's2_autosub' ),
967
+ $this->get_usermeta_keyname( 's2_subscribed' )
968
+ )
969
+ );
970
  } else {
971
+ $user_ids = $wpdb->get_col(
972
+ $wpdb->prepare(
973
+ "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE $wpdb->usermeta.meta_key=%s AND $wpdb->usermeta.meta_value='yes'",
974
+ $this->get_usermeta_keyname( 's2_autosub' )
975
+ )
976
+ );
977
+ }
978
+ if ( '' === $user_ids ) {
979
+ return;
980
  }
 
 
981
 
982
+ foreach ( $user_ids as $user_id ) {
983
+ $old_cats = get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true );
984
  if ( empty( $old_cats ) ) {
985
  $newcats = (array) $new_category;
986
  } else {
987
  $old_cats = explode( ',', $old_cats );
988
+ $newcats = array_merge( $old_cats, (array) $new_category );
989
  }
990
  // add subscription to these cat IDs
991
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $new_category, $new_category );
992
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
993
  }
994
  } elseif ( 'exclude' === $this->subscribe2_options['show_autosub'] ) {
995
+ $excluded_cats = explode( ',', $this->subscribe2_options['exclude'] );
996
+ $excluded_cats[] = $new_category;
997
  $this->subscribe2_options['exclude'] = implode( ',', $excluded_cats );
998
  update_option( 'subscribe2_options', $this->subscribe2_options );
999
  }
1000
+ }
1001
 
1002
  /**
1003
+ * Automatically delete subscriptions to a category when it is deleted
1004
+ */
1005
+ public function delete_category( $deleted_category = '' ) {
1006
  global $wpdb;
1007
 
1008
  if ( $this->s2_mu ) {
1009
+ $user_ids = $wpdb->get_col(
1010
+ $wpdb->prepare(
1011
+ "SELECT DISTINCT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b WHERE a.user_id = b.user_id AND a.meta_key=%s AND b.meta_key=%s",
1012
+ $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category,
1013
+ $this->get_usermeta_keyname( 's2_subscribed' )
1014
+ )
1015
+ );
1016
  } else {
1017
+ $user_ids = $wpdb->get_col(
1018
+ $wpdb->prepare(
1019
+ "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key=%s",
1020
+ $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category
1021
+ )
1022
+ );
1023
+ }
1024
+ if ( '' === $user_ids ) {
1025
+ return;
1026
  }
 
 
1027
 
1028
+ foreach ( $user_ids as $user_id ) {
1029
+ $old_cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
1030
  if ( ! is_array( $old_cats ) ) {
1031
  $old_cats = array( $old_cats );
1032
  }
1033
  // add subscription to these cat IDs
1034
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category );
1035
  $remain = array_diff( $old_cats, (array) $deleted_category );
1036
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $remain ) );
1037
  }
1038
+ }
1039
 
1040
  /* ===== functions to show & handle one-click subscription ===== */
1041
  /**
1042
+ * Show form for one-click subscription on user profile page
1043
+ */
1044
+ public function one_click_profile_form( $user ) {
1045
  echo '<h3>' . __( 'Email subscription', 'subscribe2' ) . '</h3>' . "\r\n";
1046
  echo '<table class="form-table">' . "\r\n";
1047
  echo '<tr><th scope="row">' . __( 'Subscribe / Unsubscribe', 'subscribe2' ) . '</th>' . "\r\n";
1048
  echo '<td><label><input type="checkbox" name="sub2-one-click-subscribe" value="1" ' . checked( ! get_user_meta( $user->ID, $this->get_usermeta_keyname( 's2_subscribed' ), true ), false, false ) . ' /> ' . __( 'Receive notifications', 'subscribe2' ) . '</label><br />' . "\r\n";
1049
  echo '<span class="description">' . __( 'Check if you want to receive email notification when new posts are published', 'subscribe2' ) . '</span>' . "\r\n";
1050
  echo '</td></tr></table>' . "\r\n";
1051
+ }
1052
 
1053
  /**
1054
+ * Handle submission from profile one-click subscription
1055
+ */
1056
+ public function one_click_profile_form_save( $user_id ) {
1057
+ if ( ! current_user_can( 'edit_user', $user_id ) ) {
1058
  return false;
1059
  }
1060
 
1061
  if ( isset( $_POST['sub2-one-click-subscribe'] ) && 1 === $_POST['sub2-one-click-subscribe'] ) {
1062
  // Subscribe
1063
+ $this->one_click_handler( $user_id, 'subscribe' );
1064
  } else {
1065
  // Unsubscribe
1066
+ $this->one_click_handler( $user_id, 'unsubscribe' );
1067
  }
1068
+ }
1069
 
1070
  /**
1071
+ * Core function to hook the digest email preview to the action on the Settings page
1072
+ */
1073
+ public function digest_preview( $user_email = '' ) {
1074
+ if ( false === $this->validate_email( $user_email ) ) {
1075
+ return;
1076
+ }
1077
  $this->subscribe2_cron( $user_email );
1078
+ }
1079
 
1080
  /**
1081
+ * Core function to hook the resent digest email to the action on the Settings page
1082
+ */
1083
+ public function digest_resend( $resend ) {
1084
  if ( 'resend' === $resend ) {
1085
  $this->subscribe2_cron( '', 'resend' );
1086
  }
1087
+ }
1088
  }
 
classes/class-s2-ajax.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
  class S2_Ajax {
3
  /**
4
- Constructor
5
- */
6
- function __construct() {
7
- // if SCRIPT_DEBUG is true, use dev scripts
8
  $this->script_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
9
  if ( is_admin() ) {
10
  add_action( 'wp_ajax_nopriv_subscribe2_form', array( &$this, 's2_ajax_form_handler' ) );
@@ -12,22 +12,21 @@ class S2_Ajax {
12
  add_filter( 's2_ajax_form', array( &$this, 's2_ajax_form_class' ), 1 );
13
 
14
  global $s2_frontend;
15
- require_once( S2PATH . 'classes/class-s2-core.php' );
16
- require_once( S2PATH . 'classes/class-s2-frontend.php' );
17
- $s2_frontend = new S2_Frontend;
 
18
  $s2_frontend->subscribe2_options = get_option( 'subscribe2_options' );
19
- global $wpdb;
20
- $s2_frontend->public = $wpdb->prefix . 'subscribe2';
21
  } else {
22
  // add actions for ajax form if enabled
23
  add_action( 'wp_enqueue_scripts', array( &$this, 'add_ajax' ) );
24
  }
25
- } // end __construct
26
 
27
  /**
28
- Add jQuery code and CSS to front pages for ajax form
29
- */
30
- function add_ajax() {
31
  // enqueue the jQuery script we need and let WordPress handle the dependencies
32
  wp_enqueue_script( 'jquery-ui-dialog' );
33
  $css = apply_filters( 's2_jqueryui_css', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/ui-darkness/jquery-ui.css' );
@@ -36,21 +35,21 @@ class S2_Ajax {
36
  }
37
  wp_register_style( 'jquery-ui-style', $css );
38
  wp_enqueue_style( 'jquery-ui-style' );
39
- wp_register_script( 's2-ajax', S2URL . 'include/s2-ajax' . $this->script_debug . '.js', array(), '1.2' );
40
  $translation_array = array(
41
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
42
- 'title' => __( 'Subscribe to this blog', 'subscribe2' ),
43
- 'nonce' => wp_create_nonce( 's2_ajax_form_nonce' ),
44
  );
45
- wp_localize_script( 's2-ajax', 's2_ajax_script_strings', $translation_array );
46
  wp_enqueue_script( 's2-ajax' );
47
- } // end add_ajax()
48
 
49
  /**
50
- Ajax form handler
51
- */
52
- function s2_ajax_form_handler() {
53
- require_once( ABSPATH . '/wp-includes/shortcodes.php' );
54
 
55
  $response = str_replace( ':', '&', $_POST['data'] );
56
  $response = str_replace( '-', '=', $response );
@@ -61,12 +60,12 @@ class S2_Ajax {
61
  $content = apply_filters( 's2_ajax_form', $content );
62
  echo $content;
63
  exit();
64
- } // end s2_ajax_handler()
65
 
66
  /**
67
- Ajax submit handler
68
- */
69
- function s2_ajax_submit_handler() {
70
  if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 's2_ajax_form_nonce' ) ) {
71
  echo '<p>' . __( 'There was an error validating your request. Please try again later.', 'subscribe2' ) . '</p>';
72
  wp_die();
@@ -80,21 +79,22 @@ class S2_Ajax {
80
 
81
  global $s2_frontend, $wpdb;
82
  $s2_frontend->email = $s2_frontend->sanitize_email( $data['email'] );
83
- $s2_frontend->ip = $data['ip'];
84
- if ( ! is_email( $s2_frontend->email ) ) {
85
  echo '<p>' . __( 'Sorry, but that does not look like an email address to me.', 'subscribe2' ) . '</p>';
86
  } elseif ( $s2_frontend->is_barred( $s2_frontend->email ) ) {
87
  echo '<p>' . __( 'Sorry, email addresses at that domain are currently barred due to spam, please use an alternative email address.', 'subscribe2' ) . '</p>';
88
  } else {
89
  if ( is_int( $s2_frontend->lockout ) && $s2_frontend->lockout > 0 ) {
90
  $date = date( 'H:i:s.u', $s2_frontend->lockout );
91
- $ips = $wpdb->get_col( $wpdb->prepare( "SELECT ip FROM $s2_frontend->public WHERE date = CURDATE() AND time > SUBTIME(CURTIME(), %s)", $date ) );
92
  if ( in_array( $s2_frontend->ip, $ips ) ) {
93
  echo '<p>' . __( 'Slow down, you move too fast.', 'subscribe2' ) . '</p>';
94
  }
95
  }
96
  $check = $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM $wpdb->users WHERE user_email = %s", $s2_frontend->email ) );
97
  if ( null !== $check ) {
 
98
  printf( __( 'To manage your subscription options please <a href="%1$s">login.</a>', 'subscribe2' ), get_option( 'siteurl' ) . '/wp-login.php' );
99
  }
100
  if ( 'subscribe' === $data['button'] ) {
@@ -125,15 +125,14 @@ class S2_Ajax {
125
  }
126
  }
127
  wp_die();
128
- } // end s2_ajax_submit_handler()
129
 
130
  /**
131
- Filter to add ajax id to form
132
- */
133
- function s2_ajax_form_class( $content ) {
134
  $content = str_replace( '<form', '<form id="s2ajaxform"', $content );
135
  $content = str_replace( 'wp-login.php"', 'wp-login.php" style="text-decoration: underline;"', $content );
136
  return $content;
137
- } // end s2_ajax_form_class()
138
  }
139
- ?>
1
  <?php
2
  class S2_Ajax {
3
  /**
4
+ * Constructor
5
+ */
6
+ public function __construct() {
7
+ // maybe use dev scripts
8
  $this->script_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
9
  if ( is_admin() ) {
10
  add_action( 'wp_ajax_nopriv_subscribe2_form', array( &$this, 's2_ajax_form_handler' ) );
12
  add_filter( 's2_ajax_form', array( &$this, 's2_ajax_form_class' ), 1 );
13
 
14
  global $s2_frontend;
15
+ require_once S2PATH . 'classes/class-s2-core.php';
16
+ require_once S2PATH . 'classes/class-s2-frontend.php';
17
+ $s2_frontend = new S2_Frontend();
18
+
19
  $s2_frontend->subscribe2_options = get_option( 'subscribe2_options' );
 
 
20
  } else {
21
  // add actions for ajax form if enabled
22
  add_action( 'wp_enqueue_scripts', array( &$this, 'add_ajax' ) );
23
  }
24
+ }
25
 
26
  /**
27
+ * Add jQuery code and CSS to front pages for ajax form
28
+ */
29
+ public function add_ajax() {
30
  // enqueue the jQuery script we need and let WordPress handle the dependencies
31
  wp_enqueue_script( 'jquery-ui-dialog' );
32
  $css = apply_filters( 's2_jqueryui_css', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/ui-darkness/jquery-ui.css' );
35
  }
36
  wp_register_style( 'jquery-ui-style', $css );
37
  wp_enqueue_style( 'jquery-ui-style' );
38
+ wp_register_script( 's2-ajax', S2URL . 'include/s2-ajax' . $this->script_debug . '.js', array(), '1.3' );
39
  $translation_array = array(
40
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
41
+ 'title' => __( 'Subscribe to this blog', 'subscribe2' ),
42
+ 'nonce' => wp_create_nonce( 's2_ajax_form_nonce' ),
43
  );
44
+ wp_localize_script( 's2-ajax', 's2AjaxScriptStrings', $translation_array );
45
  wp_enqueue_script( 's2-ajax' );
46
+ }
47
 
48
  /**
49
+ * Ajax form handler
50
+ */
51
+ public function s2_ajax_form_handler() {
52
+ require_once ABSPATH . '/wp-includes/shortcodes.php';
53
 
54
  $response = str_replace( ':', '&', $_POST['data'] );
55
  $response = str_replace( '-', '=', $response );
60
  $content = apply_filters( 's2_ajax_form', $content );
61
  echo $content;
62
  exit();
63
+ }
64
 
65
  /**
66
+ * Ajax submit handler
67
+ */
68
+ public function s2_ajax_submit_handler() {
69
  if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 's2_ajax_form_nonce' ) ) {
70
  echo '<p>' . __( 'There was an error validating your request. Please try again later.', 'subscribe2' ) . '</p>';
71
  wp_die();
79
 
80
  global $s2_frontend, $wpdb;
81
  $s2_frontend->email = $s2_frontend->sanitize_email( $data['email'] );
82
+ $s2_frontend->ip = $data['ip'];
83
+ if ( false === $s2_frontend->validate_email( $s2_frontend->email ) ) {
84
  echo '<p>' . __( 'Sorry, but that does not look like an email address to me.', 'subscribe2' ) . '</p>';
85
  } elseif ( $s2_frontend->is_barred( $s2_frontend->email ) ) {
86
  echo '<p>' . __( 'Sorry, email addresses at that domain are currently barred due to spam, please use an alternative email address.', 'subscribe2' ) . '</p>';
87
  } else {
88
  if ( is_int( $s2_frontend->lockout ) && $s2_frontend->lockout > 0 ) {
89
  $date = date( 'H:i:s.u', $s2_frontend->lockout );
90
+ $ips = $wpdb->get_col( $wpdb->prepare( "SELECT ip FROM $wpdb->subscribe2 WHERE date = CURDATE() AND time > SUBTIME(CURTIME(), %s)", $date ) );
91
  if ( in_array( $s2_frontend->ip, $ips ) ) {
92
  echo '<p>' . __( 'Slow down, you move too fast.', 'subscribe2' ) . '</p>';
93
  }
94
  }
95
  $check = $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM $wpdb->users WHERE user_email = %s", $s2_frontend->email ) );
96
  if ( null !== $check ) {
97
+ // Translators: Link to login page
98
  printf( __( 'To manage your subscription options please <a href="%1$s">login.</a>', 'subscribe2' ), get_option( 'siteurl' ) . '/wp-login.php' );
99
  }
100
  if ( 'subscribe' === $data['button'] ) {
125
  }
126
  }
127
  wp_die();
128
+ }
129
 
130
  /**
131
+ * Filter to add ajax id to form
132
+ */
133
+ public function s2_ajax_form_class( $content ) {
134
  $content = str_replace( '<form', '<form id="s2ajaxform"', $content );
135
  $content = str_replace( 'wp-login.php"', 'wp-login.php" style="text-decoration: underline;"', $content );
136
  return $content;
137
+ }
138
  }
 
classes/class-s2-core.php CHANGED
@@ -2,91 +2,25 @@
2
  class S2_Core {
3
  // variables and constructor are declared at the end
4
  /**
5
- Load translations
6
- */
7
- function load_translations() {
8
  load_plugin_textdomain( 'subscribe2', false, S2DIR );
9
  load_plugin_textdomain( 'subscribe2', false, S2DIR . 'languages/' );
10
- $mofile = WP_LANG_DIR . '/subscribe2-' . apply_filters( 'plugin_locale', get_locale(), 'subscribe2' ) . '.mo';
11
- load_textdomain( 'subscribe2', $mofile );
12
- } // end load_translations()
13
-
14
- /* ===== Install and reset ===== */
15
- /**
16
- Install our table
17
- */
18
- function install() {
19
- global $wpdb;
20
- // load our translations and strings
21
- $this->load_translations();
22
-
23
- // include upgrade-functions for maybe_create_table;
24
- if ( ! function_exists( 'maybe_create_table' ) ) {
25
- require_once( ABSPATH . 'wp-admin/install-helper.php' );
26
- }
27
- $charset_collate = '';
28
- if ( ! empty( $wpdb->charset ) ) {
29
- $charset_collate = "DEFAULT CHARACTER SET {$wpdb->charset}";
30
- }
31
-
32
- if ( ! empty( $wpdb->collate ) ) {
33
- $charset_collate .= " COLLATE {$wpdb->collate}";
34
- }
35
-
36
- $date = date( 'Y-m-d' );
37
- $sql = "CREATE TABLE $this->public (
38
- id int(11) NOT NULL auto_increment,
39
- email varchar(64) NOT NULL default '',
40
- active tinyint(1) default 0,
41
- date DATE default '$date' NOT NULL,
42
- time TIME DEFAULT '00:00:00' NOT NULL,
43
- ip char(64) NOT NULL default 'admin',
44
- conf_date DATE,
45
- conf_time TIME,
46
- conf_ip char(64),
47
- PRIMARY KEY (id) ) $charset_collate";
48
-
49
- // create the table, as needed
50
- maybe_create_table( $this->public, $sql );
51
-
52
- // safety check if options exist and if not create them
53
- if ( ! is_array( $this->subscribe2_options ) ) {
54
- $this->reset();
55
- }
56
-
57
- // create table entries for registered users
58
- $users = $this->get_all_registered( 'ID' );
59
- if ( ! empty( $users ) ) {
60
- foreach ( $users as $user_ID ) {
61
- $check_format = get_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_format' ), true );
62
- if ( empty( $check_format ) ) {
63
- // no prior settings so create them
64
- $this->register( $user_ID );
65
- }
66
- }
67
  }
68
- } // end install()
69
-
70
- /**
71
- Reset our options
72
- */
73
- function reset() {
74
- // load our translations and strings
75
- $this->load_translations();
76
-
77
- delete_option( 'subscribe2_options' );
78
- wp_clear_scheduled_hook( 's2_digest_cron' );
79
- unset( $this->subscribe2_options );
80
- require( S2PATH . 'include/options.php' );
81
- $this->subscribe2_options['version'] = S2VERSION;
82
- update_option( 'subscribe2_options', $this->subscribe2_options );
83
- } // end reset()
84
 
85
  /* ===== mail handling ===== */
86
  /**
87
- Performs string substitutions for subscribe2 mail tags
88
- */
89
- function substitute( $string = '' ) {
90
  if ( '' === $string ) {
91
  return;
92
  }
@@ -95,12 +29,15 @@ class S2_Core {
95
  $string = str_replace( '{TITLE}', stripslashes( $this->post_title ), $string );
96
  $string = str_replace( '{TITLETEXT}', stripslashes( $this->post_title_text ), $string );
97
  $string = str_replace( '{PERMAURL}', $this->get_tracking_link( $this->permalink ), $string );
98
- $link = '<a href="' . $this->get_tracking_link( $this->permalink ) . '">' . $this->get_tracking_link( $this->permalink ) . '</a>';
99
  $string = str_replace( '{PERMALINK}', $link, $string );
100
  if ( strstr( $string, '{TINYLINK}' ) ) {
101
- $tinylink = file_get_contents( 'http://tinyurl.com/api-create.php?url=' . urlencode( $this->get_tracking_link( $this->permalink ) ) );
102
- if ( 'Error' !== $tinylink && false !== $tinylink ) {
103
- $tlink = '<a href="' . $tinylink . '">' . $tinylink . '</a>';
 
 
 
104
  $string = str_replace( '{TINYLINK}', $tlink, $string );
105
  } else {
106
  $string = str_replace( '{TINYLINK}', $link, $string );
@@ -115,21 +52,28 @@ class S2_Core {
115
  $string = str_replace( '{TAGS}', $this->post_tag_names, $string );
116
  $string = str_replace( '{COUNT}', $this->post_count, $string );
117
 
118
- return apply_filters( 's2_custom_keywords', $string );
119
- } // end substitute()
 
 
 
 
120
 
121
  /**
122
- Delivers email to recipients in HTML or plaintext
123
- */
124
- function mail( $recipients = array(), $subject = '', $message = '', $type = 'text', $attachments = array() ) {
125
- if ( empty( $recipients ) || '' === $message ) { return; }
 
 
126
 
127
  // Replace any escaped html symbols in subject then apply filter
128
- $subject = strip_tags( html_entity_decode( $subject, ENT_QUOTES ) );
129
  $subject = apply_filters( 's2_email_subject', $subject );
130
 
131
  if ( 'html' === $type ) {
132
  $headers = $this->headers( 'html' );
 
133
  add_filter( 'wp_mail_content_type', array( $this, 'html_email' ) );
134
  if ( 'yes' === $this->subscribe2_options['stylesheet'] ) {
135
  $mailtext = apply_filters( 's2_html_email', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>' . $subject . '</title><link rel="stylesheet" href="' . get_stylesheet_directory_uri() . apply_filters( 's2_stylesheet_name', '/style.css' ) . '" type="text/css" media="screen" /><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>' . $message . '</body></html>', $subject, $message );
@@ -138,7 +82,9 @@ class S2_Core {
138
  }
139
  } else {
140
  $headers = $this->headers( 'text' );
141
- $message = html_entity_decode( strip_tags( $message ), ENT_NOQUOTES, 'UTF-8' );
 
 
142
  $mailtext = apply_filters( 's2_plain_email', $message );
143
  }
144
 
@@ -150,12 +96,14 @@ class S2_Core {
150
  foreach ( $recipients as $recipient ) {
151
  $recipient = trim( $recipient );
152
  // sanity check -- make sure we have a valid email
153
- if ( ! is_email( $recipient ) || empty( $recipient ) ) { continue; }
 
 
154
  // Use the mail queue provided we are not sending a preview
155
- if ( function_exists( 'wpmq_mail' ) && ! $this->preview_email ) {
156
- @wp_mail( $recipient, $subject, $mailtext, $headers, $attachments, 0 );
157
  } else {
158
- @wp_mail( $recipient, $subject, $mailtext, $headers, $attachments );
159
  }
160
  }
161
  return true;
@@ -164,10 +112,12 @@ class S2_Core {
164
  foreach ( $recipients as $recipient ) {
165
  $recipient = trim( $recipient );
166
  // sanity check -- make sure we have a valid email
167
- if ( ! is_email( $recipient ) ) { continue; }
 
 
168
  // and NOT the sender's email, since they'll get a copy anyway
169
  if ( ! empty( $recipient ) && $this->myemail !== $recipient ) {
170
- ('' === $bcc) ? $bcc = "Bcc: $recipient" : $bcc .= ", $recipient";
171
  // Bcc Headers now constructed by phpmailer class
172
  }
173
  }
@@ -179,16 +129,18 @@ class S2_Core {
179
  foreach ( $recipients as $recipient ) {
180
  $recipient = trim( $recipient );
181
  // sanity check -- make sure we have a valid email
182
- if ( ! is_email( $recipient ) ) { continue; }
 
 
183
  // and NOT the sender's email, since they'll get a copy anyway
184
  if ( ! empty( $recipient ) && $this->myemail !== $recipient ) {
185
- ('' === $bcc) ? $bcc = "Bcc: $recipient" : $bcc .= ", $recipient";
186
  // Bcc Headers now constructed by phpmailer class
187
  }
188
  if ( $this->subscribe2_options['bcclimit'] === $count ) {
189
- $count = 0;
190
  $batch[] = $bcc;
191
- $bcc = '';
192
  }
193
  $count++;
194
  }
@@ -207,25 +159,25 @@ class S2_Core {
207
  if ( isset( $batch ) && ! empty( $batch ) ) {
208
  foreach ( $batch as $bcc ) {
209
  $newheaders = $headers . "$bcc\n";
210
- $status = @wp_mail( $this->myemail, $subject, $mailtext, $newheaders, $attachments );
211
  }
212
  } else {
213
- $status = @wp_mail( $this->myemail, $subject, $mailtext, $headers, $attachments );
214
  }
215
  return $status;
216
- } // end mail()
217
 
218
  /**
219
- Construct standard set of email headers
220
- */
221
- function headers( $type = 'text' ) {
222
  if ( empty( $this->myname ) || empty( $this->myemail ) ) {
223
  if ( 'blogname' === $this->subscribe2_options['sender'] ) {
224
- $this->myname = html_entity_decode( get_option( 'blogname' ), ENT_QUOTES );
225
  $this->myemail = get_option( 'admin_email' );
226
  } else {
227
- $admin = $this->get_userdata( $this->subscribe2_options['sender'] );
228
- $this->myname = html_entity_decode( $admin->display_name, ENT_QUOTES );
229
  $this->myemail = $admin->user_email;
230
  // fail safe to ensure sender details are not empty
231
  if ( empty( $this->myname ) ) {
@@ -244,14 +196,14 @@ class S2_Core {
244
 
245
  $char_set = get_option( 'blog_charset' );
246
  if ( function_exists( 'mb_encode_mimeheader' ) ) {
247
- $header['From'] = mb_encode_mimeheader( $this->myname, $char_set, 'Q' ) . ' <' . $this->myemail . '>';
248
  $header['Reply-To'] = mb_encode_mimeheader( $this->myname, $char_set, 'Q' ) . ' <' . $this->myemail . '>';
249
  } else {
250
- $header['From'] = $this->myname . ' <' . $this->myemail . '>';
251
  $header['Reply-To'] = $this->myname . ' <' . $this->myemail . '>';
252
  }
253
  $header['Return-Path'] = '<' . $this->myemail . '>';
254
- $header['Precedence'] = "list\nList-Id: " . html_entity_decode( get_option( 'blogname' ), ENT_QUOTES );
255
  if ( 'html' === $type ) {
256
  // To send HTML mail, the Content-Type header must be set
257
  $header['Content-Type'] = get_option( 'html_type' ) . '; charset="' . $char_set . '"';
@@ -265,60 +217,78 @@ class S2_Core {
265
  foreach ( $header as $key => $value ) {
266
  $headers[ $key ] = $key . ': ' . $value;
267
  }
268
- $headers = implode( "\n", $headers );
269
  $headers .= "\n";
270
 
271
  return $headers;
272
- } // end headers()
273
 
274
  /**
275
- Function to set HTML Email in wp_mail()
276
- */
277
- function html_email() {
278
  return 'text/html';
279
  }
280
 
281
  /**
282
- Function to add UTM tracking details to links
283
- */
284
- function get_tracking_link( $link ) {
285
- if ( empty( $link ) ) { return; }
 
 
 
 
 
 
 
 
 
286
  if ( ! empty( $this->subscribe2_options['tracking'] ) ) {
287
- (strpos( $link, '?' ) > 0) ? $delimiter .= '&' : $delimiter = '?';
 
288
  $tracking = $this->subscribe2_options['tracking'];
289
  if ( strpos( $tracking, '{ID}' ) ) {
290
- $id = url_to_postid( $link );
291
  $tracking = str_replace( '{ID}', $id, $tracking );
292
  }
293
  if ( strpos( $tracking, '{TITLE}' ) ) {
294
- $id = url_to_postid( $link );
295
- $title = urlencode( htmlentities( get_the_title( $id ), 1 ) );
296
  $tracking = str_replace( '{TITLE}', $title, $tracking );
297
  }
298
  return $link . $delimiter . $tracking;
299
  } else {
300
  return $link;
301
  }
302
- } // end get_tracking_link()
303
 
304
  /**
305
- Sends an email notification of a new post
306
- */
307
- function publish( $post, $preview = '' ) {
308
- if ( ! $post ) { return $post; }
 
 
309
 
310
  if ( $this->s2_mu && ! apply_filters( 's2_allow_site_switching', $this->site_switching ) ) {
311
  global $switched;
312
- if ( $switched ) { return; }
 
 
313
  }
314
 
315
  if ( '' === $preview ) {
316
  // we aren't sending a Preview to the current user so carry out checks
317
  $s2mail = get_post_meta( $post->ID, '_s2mail', true );
318
- if ( ( isset( $_POST['s2_meta_field'] ) && 'no' === $_POST['s2_meta_field'] ) || 'no' === strtolower( trim( $s2mail ) ) ) { return $post; }
 
 
319
 
320
  // are we doing daily digests? If so, don't send anything now
321
- if ( 'never' !== $this->subscribe2_options['email_freq'] ) { return $post; }
 
 
322
 
323
  // is the current post of a type that should generate a notification email?
324
  // uses s2_post_types filter to allow for custom post types in WP 3.0
@@ -338,16 +308,20 @@ class S2_Core {
338
  }
339
 
340
  // Is the post assigned to a format for which we should not be sending posts
341
- $post_format = get_post_format( $post->ID );
342
  $excluded_formats = explode( ',', $this->subscribe2_options['exclude_formats'] );
343
  if ( false !== $post_format && in_array( $post_format, $excluded_formats ) ) {
344
  return $post;
345
  }
346
 
347
  $s2_taxonomies = apply_filters( 's2_taxonomies', array( 'category' ) );
348
- $post_cats = wp_get_object_terms( $post->ID, $s2_taxonomies, array(
349
- 'fields' => 'ids',
350
- ) );
 
 
 
 
351
  // Fail gracefully if we have a post but no category assigned or a taxonomy error
352
  if ( is_wp_error( $post_cats ) || ( empty( $post_cats ) && 'post' === $post->post_type ) ) {
353
  return $post;
@@ -387,7 +361,16 @@ class S2_Core {
387
  $public = $this->get_public();
388
  }
389
  if ( 'page' === $post->post_type ) {
390
- $post_cats_string = implode( ',', get_all_category_ids() );
 
 
 
 
 
 
 
 
 
391
  } else {
392
  $post_cats_string = implode( ',', $post_cats );
393
  }
@@ -403,39 +386,62 @@ class S2_Core {
403
  $s2_taxonomies = apply_filters( 's2_taxonomies', array( 'category' ) );
404
  }
405
 
 
 
 
 
 
 
406
  // we set these class variables so that we can avoid
407
  // passing them in function calls a little later
408
- $this->post_title = '<a href="' . $this->get_tracking_link( get_permalink( $post->ID ) ) . '">' . html_entity_decode( __( $post->post_title ), ENT_QUOTES ) . '</a>';
409
- $this->post_title_text = html_entity_decode( __( $post->post_title ), ENT_QUOTES );
410
- $this->permalink = get_permalink( $post->ID );
411
- $this->post_date = get_the_time( get_option( 'date_format' ), $post );
412
- $this->post_time = get_the_time( '', $post );
 
 
 
 
413
 
414
- $author = get_userdata( $post->post_author );
415
  $this->authorname = html_entity_decode( apply_filters( 'the_author', $author->display_name ), ENT_QUOTES );
416
 
417
- // do we send as admin, or post author?
418
  if ( 'author' === $this->subscribe2_options['sender'] ) {
419
  // get author details
420
- $user = &$author;
421
  $this->myemail = $user->user_email;
422
- $this->myname = html_entity_decode( $user->display_name, ENT_QUOTES );
423
  } elseif ( 'blogname' === $this->subscribe2_options['sender'] ) {
424
  $this->myemail = get_option( 'admin_email' );
425
- $this->myname = html_entity_decode( get_option( 'blogname' ), ENT_QUOTES );
426
  } else {
427
  // get admin details
428
- $user = $this->get_userdata( $this->subscribe2_options['sender'] );
429
  $this->myemail = $user->user_email;
430
- $this->myname = html_entity_decode( $user->display_name, ENT_QUOTES );
431
  }
432
 
433
- $this->post_cat_names = implode( ', ', wp_get_object_terms( $post->ID, $s2_taxonomies, array(
434
- 'fields' => 'names',
435
- ) ) );
436
- $this->post_tag_names = implode( ', ', wp_get_post_tags( $post->ID, array(
437
- 'fields' => 'names',
438
- ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
439
 
440
  // Get email subject
441
  $subject = html_entity_decode( stripslashes( wp_kses( $this->substitute( $this->subscribe2_options['notification_subject'] ), '' ) ) );
@@ -446,15 +452,15 @@ class S2_Core {
446
  $plaintext = $post->post_content;
447
  $plaintext = strip_shortcodes( $plaintext );
448
 
449
- $plaintext = preg_replace( '/<s[^>]*>(.*)<\/s>/Ui','', $plaintext );
450
- $plaintext = preg_replace( '/<strike[^>]*>(.*)<\/strike>/Ui','', $plaintext );
451
- $plaintext = preg_replace( '/<del[^>]*>(.*)<\/del>/Ui','', $plaintext );
452
  $excerpttext = $plaintext;
453
 
454
  if ( strstr( $mailtext, '{REFERENCELINKS}' ) ) {
455
- $mailtext = str_replace( '{REFERENCELINKS}', '', $mailtext );
456
  $plaintext_links = '';
457
- $i = 0;
458
  while ( preg_match( '/<a([^>]*)>(.*)<\/a>/Ui', $plaintext, $matches ) ) {
459
  if ( preg_match( '/href="([^"]*)"/', $matches[1], $link_matches ) ) {
460
  $plaintext_links .= sprintf( "[%d] %s\r\n", ++$i, $link_matches[1] );
@@ -466,13 +472,13 @@ class S2_Core {
466
  }
467
  }
468
 
469
- $plaintext = trim( strip_tags( $plaintext ) );
470
 
471
  if ( isset( $plaintext_links ) && '' !== $plaintext_links ) {
472
  $plaintext .= "\r\n\r\n" . trim( $plaintext_links );
473
  }
474
 
475
- $gallid = '[gallery id="' . $post->ID . '"';
476
  $content = str_replace( '[gallery', $gallid, $post->post_content );
477
 
478
  // remove the autoembed filter to remove iframes from notification emails
@@ -493,11 +499,11 @@ class S2_Core {
493
  if ( false !== strpos( $excerpttext, '<!--more-->' ) ) {
494
  list( $excerpt, $more ) = explode( '<!--more-->', $excerpttext, 2 );
495
  // strip tags and trailing whitespace
496
- $excerpt = trim( strip_tags( $excerpt ) );
497
  } else {
498
  // no <!--more-->, so grab the first 55 words
499
- $excerpt = trim( strip_tags( $excerpttext ) );
500
- $words = explode( ' ', $excerpt, $this->excerpt_length + 1 );
501
  if ( count( $words ) > $this->excerpt_length ) {
502
  array_pop( $words );
503
  array_push( $words, '[...]' );
@@ -528,20 +534,22 @@ class S2_Core {
528
  }
529
 
530
  // remove excess white space from with $excerpt and $plaintext
531
- $excerpt = preg_replace( '/[ ]+/', ' ', $excerpt );
532
  $plaintext = preg_replace( '/[ ]+/', ' ', $plaintext );
533
 
534
  // prepare mail body texts
535
  $plain_excerpt_body = str_replace( '{POST}', $excerpt, $mailtext );
536
- $plain_body = str_replace( '{POST}', $plaintext, $mailtext );
537
- $html_body = str_replace( "\r\n", "<br />\r\n", $mailtext );
538
- $html_body = str_replace( '{POST}', $content, $html_body );
539
- $html_excerpt_body = str_replace( "\r\n", "<br />\r\n", $mailtext );
540
- $html_excerpt_body = str_replace( '{POST}', $html_excerpt, $html_excerpt_body );
541
 
542
  if ( '' !== $preview ) {
 
 
543
  $this->myemail = $preview;
544
- $this->myname = __( 'Plain Text Excerpt Preview', 'subscribe2' );
545
  $this->mail( array( $preview ), $subject, $plain_excerpt_body );
546
  $this->myname = __( 'Plain Text Full Preview', 'subscribe2' );
547
  $this->mail( array( $preview ), $subject, $plain_body );
@@ -575,14 +583,18 @@ class S2_Core {
575
  $recipients = apply_filters( 's2_send_public_subscribers', $public, $post->ID );
576
  $this->mail( $recipients, $subject, $plain_excerpt_body, 'text' );
577
  }
578
- } // end publish()
579
 
580
  /**
581
  Send confirmation email to a public subscriber
582
  */
583
- function send_confirm( $action = '', $is_remind = false ) {
584
- if ( 1 === $this->filtered ) { return true; }
585
- if ( ! $this->email || empty( $action ) ) { return false; }
 
 
 
 
586
  $id = $this->get_id( $this->email );
587
  if ( ! $id ) {
588
  return false;
@@ -592,7 +604,7 @@ class S2_Core {
592
  // ACTION = 1 to subscribe, 0 to unsubscribe
593
  // HASH = wp_hash of email address
594
  // ID = user's ID in the subscribe2 table
595
- // use home instead of siteurl incase index.php is not in core wordpress directory
596
  $link = apply_filters( 's2_confirm_link', get_option( 'home' ) ) . '/?s2=';
597
 
598
  if ( 'add' === $action ) {
@@ -607,16 +619,16 @@ class S2_Core {
607
  $mailheaders = $this->headers();
608
 
609
  if ( true === $is_remind ) {
610
- $body = $this->substitute( stripslashes( $this->subscribe2_options['remind_email'] ) );
611
  $subject = $this->substitute( stripslashes( $this->subscribe2_options['remind_subject'] ) );
612
  } else {
613
- $body = apply_filters( 's2_confirm_email', stripslashes( $this->subscribe2_options['confirm_email'] ), $action );
614
  $body = $this->substitute( $body );
615
  if ( 'add' === $action ) {
616
- $body = str_replace( '{ACTION}', $this->subscribe, $body );
617
  $subject = str_replace( '{ACTION}', $this->subscribe, $this->subscribe2_options['confirm_subject'] );
618
  } elseif ( 'del' === $action ) {
619
- $body = str_replace( '{ACTION}', $this->unsubscribe, $body );
620
  $subject = str_replace( '{ACTION}', $this->unsubscribe, $this->subscribe2_options['confirm_subject'] );
621
  }
622
  $subject = html_entity_decode( $this->substitute( stripslashes( $subject ) ), ENT_QUOTES );
@@ -626,121 +638,140 @@ class S2_Core {
626
 
627
  if ( true === $is_remind && function_exists( 'wpmq_mail' ) ) {
628
  // could be sending lots of reminders so queue them if wpmq is enabled
629
- @wp_mail( $this->email, $subject, $body, $mailheaders, '', 0 );
630
  } else {
631
- return @wp_mail( $this->email, $subject, $body, $mailheaders );
632
  }
633
- } // end send_confirm()
634
 
635
  /* ===== Public Subscriber functions ===== */
636
  /**
637
- Return an array of all the public subscribers
638
- */
639
- function get_public( $confirmed = 1 ) {
640
  global $wpdb;
 
 
 
641
  if ( 1 === $confirmed ) {
642
- if ( '' === $this->all_confirmed ) {
643
- $this->all_confirmed = $wpdb->get_col( "SELECT email FROM $this->public WHERE active='1'" );
644
  }
645
- return $this->all_confirmed;
646
  } else {
647
- if ( '' === $this->all_unconfirmed ) {
648
- $this->all_unconfirmed = $wpdb->get_col( "SELECT email FROM $this->public WHERE active='0'" );
649
  }
650
- return $this->all_unconfirmed;
651
  }
652
- } // end get_public()
653
 
654
  /**
655
- Given a public subscriber ID, returns the email address
656
- */
657
- function get_email( $id = 0 ) {
658
  global $wpdb;
659
 
660
  if ( ! $id ) {
661
  return false;
662
  }
663
- return $wpdb->get_var( $wpdb->prepare( "SELECT email FROM $this->public WHERE id=%d", $id ) );
664
- } // end get_email()
665
 
666
  /**
667
- Given a public subscriber email, returns the subscriber ID
668
- */
669
- function get_id( $email = '' ) {
670
  global $wpdb;
671
 
672
  if ( ! $email ) {
673
  return false;
674
  }
675
- return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $this->public WHERE email=%s", $email ) );
676
- } // end get_id()
677
 
678
  /**
679
- Add an public subscriber to the subscriber table
680
- If added by admin it is immediately confirmed, otherwise as unconfirmed
681
- */
682
- function add( $email = '', $confirm = false ) {
683
- if ( 1 === $this->filtered ) { return; }
 
 
684
  global $wpdb;
685
 
686
- if ( ! is_email( $email ) ) { return false; }
 
 
687
 
688
  if ( false !== $this->is_public( $email ) ) {
689
  // is this an email for a registered user
690
  $check = $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM $wpdb->users WHERE user_email=%s", $this->email ) );
691
- if ( $check ) { return; }
 
 
692
  if ( $confirm ) {
693
- $wpdb->query( $wpdb->prepare( "UPDATE $this->public SET active='1', ip=%s WHERE CAST(email as binary)=%s", $this->ip, $email ) );
694
  } else {
695
- $wpdb->query( $wpdb->prepare( "UPDATE $this->public SET date=CURDATE(), time=CURTIME() WHERE CAST(email as binary)=%s", $email ) );
696
  }
697
  } else {
698
  if ( $confirm ) {
699
  global $current_user;
700
- $wpdb->query( $wpdb->prepare( "INSERT INTO $this->public (email, active, date, time, ip) VALUES (%s, %d, CURDATE(), CURTIME(), %s)", $email, 1, $current_user->user_login ) );
701
  } else {
702
- $wpdb->query( $wpdb->prepare( "INSERT INTO $this->public (email, active, date, time, ip) VALUES (%s, %d, CURDATE(), CURTIME(), %s)", $email, 0, $this->ip ) );
703
  }
704
  }
705
- } // end add()
706
 
707
  /**
708
- Remove a public subscriber user from the subscription table
709
- */
710
- function delete( $email = '' ) {
711
  global $wpdb;
712
 
713
- if ( ! is_email( $email ) ) { return false; }
714
- $wpdb->query( $wpdb->prepare( "DELETE FROM $this->public WHERE CAST(email as binary)=%s LIMIT 1", $email ) );
715
- } // end delete()
 
 
716
 
717
  /**
718
- Toggle a public subscriber's status
719
- */
720
- function toggle( $email = '' ) {
721
  global $wpdb;
722
 
723
- if ( '' === $email || ! is_email( $email ) ) { return false; }
 
 
724
 
725
  // let's see if this is a public user
726
  $status = $this->is_public( $email );
727
- if ( false === $status ) { return false; }
 
 
728
 
729
  if ( '0' === $status ) {
730
- $wpdb->query( $wpdb->prepare( "UPDATE $this->public SET active='1', conf_date=CURDATE(), conf_time=CURTIME(), conf_ip=%s WHERE CAST(email as binary)=%s LIMIT 1", $this->ip, $email ) );
731
  } else {
732
- $wpdb->query( $wpdb->prepare( "UPDATE $this->public SET active='0', conf_date=CURDATE(), conf_time=CURTIME(), conf_ip=%s WHERE CAST(email as binary)=%s LIMIT 1", $this->ip, $email ) );
733
  }
734
- } // end toggle()
735
 
736
  /**
737
- Send reminder email to unconfirmed public subscribers
738
- */
739
- function remind( $emails = '' ) {
740
- if ( '' === $emails ) { return false; }
 
 
741
 
742
  $recipients = explode( ',', $emails );
743
- if ( ! is_array( $recipients ) ) { $recipients = (array) $recipients; }
 
 
744
  foreach ( $recipients as $recipient ) {
745
  $this->email = $recipient;
746
  $this->send_confirm( 'add', true );
@@ -748,30 +779,34 @@ class S2_Core {
748
  } //end remind()
749
 
750
  /**
751
- Is the supplied email address a public subscriber?
752
- */
753
- function is_public( $email = '' ) {
754
  global $wpdb;
755
 
756
- if ( '' === $email ) { return false; }
 
 
757
 
758
  // run the query and force case sensitivity
759
- $check = $wpdb->get_var( $wpdb->prepare( "SELECT active FROM $this->public WHERE CAST(email as binary)=%s", $email ) );
760
  if ( '0' === $check || '1' === $check ) {
761
  return $check;
762
  } else {
763
  return false;
764
  }
765
- } // end is_public()
766
 
767
  /* ===== Registered User and Subscriber functions ===== */
768
  /**
769
- Is the supplied email address a registered user of the blog?
770
- */
771
- function is_registered( $email = '' ) {
772
  global $wpdb;
773
 
774
- if ( '' === $email ) { return false; }
 
 
775
 
776
  $check = $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM $wpdb->users WHERE user_email=%s", $email ) );
777
  if ( $check ) {
@@ -779,62 +814,74 @@ class S2_Core {
779
  } else {
780
  return false;
781
  }
782
- } // end is_registered()
783
 
784
  /**
785
- Return Registered User ID from email
786
- */
787
- function get_user_id( $email = '' ) {
788
  global $wpdb;
789
 
790
- if ( '' === $email ) { return false; }
 
 
791
 
792
  $id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->users WHERE user_email=%s", $email ) );
793
 
794
  return $id;
795
- } // end get_user_id()
796
 
797
  /**
798
- Return an array of all subscribers emails or IDs
799
- */
800
- function get_all_registered( $return = 'email' ) {
801
  global $wpdb;
 
 
 
802
 
803
  if ( $this->s2_mu ) {
804
  if ( 'ID' === $return ) {
805
- if ( '' === $this->all_registered_id ) {
806
- $this->all_registered_id = $wpdb->get_col( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key='" . $wpdb->prefix . "capabilities'" );
807
  }
808
- return $this->all_registered_id;
 
 
 
 
 
809
  } else {
810
- if ( '' === $this->all_registered_email ) {
811
- $this->all_registered_email = $wpdb->get_col( "SELECT a.user_email FROM $wpdb->users AS a INNER JOIN $wpdb->usermeta AS b ON a.ID = b.user_id WHERE b.meta_key='" . $wpdb->prefix . "capabilities'" );
812
  }
813
- return $this->all_registered_email;
814
  }
815
  } else {
816
  if ( 'ID' === $return ) {
817
- if ( '' === $this->all_registered_id ) {
818
- $this->all_registered_id = $wpdb->get_col( "SELECT ID FROM $wpdb->users" );
819
  }
820
- return $this->all_registered_id;
821
  } elseif ( 'emailid' === $return ) {
822
- $this->all_registered_email_id = $wpdb->get_results( "SELECT user_email, ID FROM $wpdb->users", ARRAY_A );
823
- return $this->all_registered_email_id;
 
 
824
  } else {
825
- if ( '' === $this->all_registered_email ) {
826
- $this->all_registered_email = $wpdb->get_col( "SELECT user_email FROM $wpdb->users" );
827
  }
828
- return $this->all_registered_email;
829
  }
830
  }
831
- } // end get_all_registered()
832
 
833
  /**
834
- Return an array of registered subscribers
835
- Collect all the registered users of the blog who are subscribed to the specified categories
836
- */
837
- function get_registered( $args = '' ) {
838
  global $wpdb;
839
 
840
  parse_str( $args, $r );
@@ -859,44 +906,45 @@ class S2_Core {
859
  }
860
  }
861
 
862
- $JOIN = ''; $AND = '';
 
863
  // text or HTML subscribers
864
  if ( 'all' !== $r['format'] ) {
865
- $JOIN .= "INNER JOIN $wpdb->usermeta AS b ON a.user_id = b.user_id ";
866
- $AND .= $wpdb->prepare( ' AND b.meta_key=%s AND b.meta_value=', $this->get_usermeta_keyname( 's2_format' ) );
867
- if ( 'html' === $r['format'] ) {
868
- $AND .= "'html'";
869
- } elseif ( 'html_excerpt' === $r['format'] ) {
870
- $AND .= "'html_excerpt'";
871
- } elseif ( 'post' === $r['format'] ) {
872
- $AND .= "'post'";
873
- } elseif ( 'excerpt' === $r['format'] ) {
874
- $AND .= "'excerpt'";
875
- }
876
  }
877
 
878
  // specific category subscribers
879
  if ( '' !== $r['cats'] ) {
880
- $JOIN .= "INNER JOIN $wpdb->usermeta AS c ON a.user_id = c.user_id ";
881
- $and = '';
882
  foreach ( explode( ',', $r['cats'] ) as $cat ) {
883
- ('' === $and) ? $and = $wpdb->prepare( 'c.meta_key=%s', $this->get_usermeta_keyname( 's2_cat' ) . $cat ) : $and .= $wpdb->prepare( ' OR c.meta_key=%s', $this->get_usermeta_keyname( 's2_cat' ) . $cat );
884
  }
885
- $AND .= " AND ($and)";
886
  }
887
 
888
  // specific authors
889
  if ( '' !== $r['author'] ) {
890
- $JOIN .= "INNER JOIN $wpdb->usermeta AS d ON a.user_id = d.user_id ";
891
- $AND .= $wpdb->prepare( ' AND (d.meta_key=%s AND NOT FIND_IN_SET(%s, d.meta_value))', $this->get_usermeta_keyname( 's2_authors' ), $r['author'] );
892
  }
893
 
894
  if ( $this->s2_mu ) {
895
- $sql = $wpdb->prepare( "SELECT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS e ON a.user_id = e.user_id " . $JOIN . "WHERE a.meta_key='" . $wpdb->prefix . "capabilities' AND e.meta_key=%s AND e.meta_value <> ''" . $AND, $this->get_usermeta_keyname( 's2_subscribed' ) );
 
 
 
 
 
896
  } else {
897
- $sql = $wpdb->prepare( "SELECT a.user_id FROM $wpdb->usermeta AS a " . $JOIN . "WHERE a.meta_key=%s AND a.meta_value <> ''" . $AND, $this->get_usermeta_keyname( 's2_subscribed' ) );
 
 
 
 
 
898
  }
899
- $result = $wpdb->get_col( $sql );
900
 
901
  if ( empty( $result ) || false === $result ) {
902
  return array();
@@ -910,33 +958,59 @@ class S2_Core {
910
  $registered = $wpdb->get_col( "SELECT user_email FROM $wpdb->users WHERE ID IN ($ids)" );
911
  }
912
 
913
- if ( empty( $registered ) ) { return array(); }
 
 
914
 
915
  // apply filter to registered users to add or remove additional addresses, pass args too for additional control
916
  $registered = apply_filters( 's2_registered_subscribers', $registered, $args );
917
  return $registered;
918
- } // end get_registered()
919
 
920
  /**
921
- Function to ensure email is compliant with internet messaging standards
922
- */
923
- function sanitize_email( $email ) {
924
- $email = trim( $email );
925
- if ( ! is_email( $email ) ) { return; }
 
 
926
 
927
  // ensure that domain is in lowercase as per internet email standards http://www.ietf.org/rfc/rfc5321.txt
928
  list( $name, $domain ) = explode( '@', $email, 2 );
929
  return apply_filters( 's2_sanitize_email', $name . '@' . strtolower( $domain ) );
930
- } // end sanitize_email()
931
 
932
  /**
933
- Create the appropriate usermeta values when a user registers
934
- If the registering user had previously subscribed to notifications, this function will delete them from the public subscriber list first
935
- */
936
- function register( $user_ID = 0, $consent = false ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
937
  global $wpdb;
938
 
939
- if ( 0 === $user_ID ) { return $user_ID; }
 
 
940
  $user = get_userdata( $user_ID );
941
 
942
  // Subscribe registered users to categories obeying excluded categories
@@ -948,7 +1022,7 @@ class S2_Core {
948
 
949
  $cats = '';
950
  foreach ( $all_cats as $cat ) {
951
- ('' === $cats) ? $cats = "$cat->term_id" : $cats .= ",$cat->term_id";
952
  }
953
 
954
  if ( '' === $cats ) {
@@ -985,12 +1059,12 @@ class S2_Core {
985
  update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_authors' ), '' );
986
  }
987
  return $user_ID;
988
- } // end register()
989
 
990
  /**
991
- Get admin data from record 1 or first user with admin rights
992
- */
993
- function get_userdata( $admin_id ) {
994
  global $wpdb, $userdata;
995
 
996
  if ( is_numeric( $admin_id ) ) {
@@ -1006,18 +1080,21 @@ class S2_Core {
1006
  $role = array(
1007
  'role' => 'administrator',
1008
  );
 
1009
  $wp_user_query = get_users( $role );
1010
- $admin = $wp_user_query[0];
1011
  }
1012
 
1013
  return $admin;
1014
  } //end get_userdata()
1015
 
1016
  /**
1017
- Subscribe/unsubscribe user from one-click submission
1018
- */
1019
- function one_click_handler( $user_ID, $action ) {
1020
- if ( ! isset( $user_ID ) || ! isset( $action ) ) { return; }
 
 
1021
 
1022
  $all_cats = $this->all_cats( true );
1023
 
@@ -1047,19 +1124,24 @@ class S2_Core {
1047
 
1048
  /* ===== helper functions: forms and stuff ===== */
1049
  /**
1050
- Get an object of all categories, include default and custom type
1051
- */
1052
- function all_cats( $exclude = false, $orderby = 'slug' ) {
1053
- $all_cats = array();
1054
  $s2_taxonomies = apply_filters( 's2_taxonomies', array( 'category' ) );
1055
 
1056
  foreach ( $s2_taxonomies as $taxonomy ) {
1057
  if ( taxonomy_exists( $taxonomy ) ) {
1058
- $all_cats = array_merge( $all_cats, get_categories( array(
1059
- 'hide_empty' => false,
1060
- 'orderby' => $orderby,
1061
- 'taxonomy' => $taxonomy,
1062
- ) ) );
 
 
 
 
 
1063
  }
1064
  }
1065
 
@@ -1078,20 +1160,20 @@ class S2_Core {
1078
  }
1079
 
1080
  return $all_cats;
1081
- } // end all_cats()
1082
 
1083
  /**
1084
- Function to sanitise array of data for SQL
1085
- */
1086
- function prepare_in_data( $data ) {
1087
  global $wpdb;
1088
  return $wpdb->prepare( '%s', $data );
1089
- } // end prepare_in_data()
1090
 
1091
  /**
1092
- Filter for usermeta table key names to adjust them if needed for WPMU blogs
1093
- */
1094
- function get_usermeta_keyname( $metaname ) {
1095
  global $wpdb;
1096
 
1097
  // Is this WordPressMU or not?
@@ -1103,18 +1185,21 @@ class S2_Core {
1103
  case 's2_autosub':
1104
  case 's2_authors':
1105
  return $wpdb->prefix . $metaname;
 
1106
  break;
1107
  }
1108
  }
1109
  // Not MU or not a prefixed option name
1110
  return $metaname;
1111
- } // end get_usermeta_keyname()
1112
 
1113
  /**
1114
- Adds information to the WordPress registration screen for new users
1115
- */
1116
- function register_form() {
1117
- if ( 'no' === $this->subscribe2_options['autosub'] ) { return; }
 
 
1118
  if ( 'wpreg' === $this->subscribe2_options['autosub'] ) {
1119
  echo '<p><label>';
1120
  echo __( 'Check here to Subscribe to email notifications for new posts', 'subscribe2' ) . ':<br />' . "\r\n";
@@ -1125,26 +1210,28 @@ class S2_Core {
1125
  echo __( 'By registering with this blog you are also agreeing to receive email notifications for new posts but you can unsubscribe at anytime', 'subscribe2' ) . '.<br />' . "\r\n";
1126
  echo '</center></p>' . "\r\n";
1127
  }
1128
- } // end register_form()
1129
 
1130
  /**
1131
- Process function to add action if user selects to subscribe to posts during registration
1132
- */
1133
- function register_post( $user_ID = 0 ) {
1134
  global $_POST;
1135
- if ( 0 === $user_ID ) { return; }
 
 
1136
  if ( 'yes' === $this->subscribe2_options['autosub'] || ( isset( $_POST['reg_subscribe'] ) && 'on' === $_POST['reg_subscribe'] && 'wpreg' === $this->subscribe2_options['autosub'] ) ) {
1137
  $this->register( $user_ID, true );
1138
  } else {
1139
  $this->register( $user_ID, false );
1140
  }
1141
- } // end register_post()
1142
 
1143
  /* ===== comment subscriber functions ===== */
1144
  /**
1145
- Display check box on comment page
1146
- */
1147
- function s2_comment_meta_form( $submit_field ) {
1148
  if ( is_user_logged_in() ) {
1149
  $comment_meta_form = $this->profile;
1150
  } else {
@@ -1155,23 +1242,25 @@ class S2_Core {
1155
  } else {
1156
  return $submit_field . '<br />' . $comment_meta_form;
1157
  }
1158
- } // end s2_comment_meta_form()
1159
 
1160
  /**
1161
- Process comment meta data
1162
- */
1163
- function s2_comment_meta( $comment_ID, $approved = 0 ) {
1164
  // return if email is empty - can happen if setting to require name and email for comments is disabled
1165
- if ( isset( $_POST['email'] ) && empty( $_POST['email'] ) ) { return; }
 
 
1166
  if ( isset( $_POST['s2_comment_request'] ) && '1' === $_POST['s2_comment_request'] ) {
1167
  switch ( $approved ) {
1168
  case '0':
1169
  // Unapproved so hold in meta data pending moderation
1170
- add_comment_meta( $comment_ID, 's2_comment_request', $_POST['s2_comment_request'] );
1171
  break;
1172
  case '1':
1173
  // Approved so add
1174
- $comment = get_comment( $comment_ID );
1175
  $is_public = $this->is_public( $comment->comment_author_email );
1176
  if ( 0 === $is_public ) {
1177
  $this->toggle( $comment->comment_author_email );
@@ -1181,26 +1270,35 @@ class S2_Core {
1181
  $this->add( $comment->comment_author_email, true );
1182
  }
1183
  break;
1184
- default :
1185
  break;
1186
  }
1187
  }
1188
- } // end s2_comment_meta()
1189
 
1190
  /**
1191
- Action subscribe requests made on comment forms when comments are approved
1192
- */
1193
- function comment_status( $comment_ID = 0 ) {
1194
  global $wpdb;
1195
 
1196
  // get meta data
1197
- $subscribe = get_comment_meta( $comment_ID, 's2_comment_request', true );
1198
- if ( '1' !== $subscribe ) { return $comment_ID; }
 
 
1199
 
1200
  // Retrieve the information about the comment
1201
- $sql = $wpdb->prepare( "SELECT comment_author_email, comment_approved FROM $wpdb->comments WHERE comment_ID=%s LIMIT 1", $comment_ID );
1202
- $comment = $wpdb->get_row( $sql, OBJECT );
1203
- if ( empty( $comment ) ) { return $comment_ID; }
 
 
 
 
 
 
 
1204
 
1205
  switch ( $comment->comment_approved ) {
1206
  case '0': // Unapproved
@@ -1214,38 +1312,38 @@ class S2_Core {
1214
  if ( ! $is_public && ! $is_registered ) {
1215
  $this->add( $comment->comment_author_email, true );
1216
  }
1217
- delete_comment_meta( $comment_ID, 's2_comment_request' );
1218
  break;
1219
  default: // post is trash, spam or deleted
1220
- delete_comment_meta( $comment_ID, 's2_comment_request' );
1221
  break;
1222
  }
1223
 
1224
- return $comment_ID;
1225
- } // end comment_status()
1226
 
1227
  /* ===== widget functions ===== */
1228
  /**
1229
- Register the form widget
1230
- */
1231
- function subscribe2_widget() {
1232
- require_once( S2PATH . 'classes/class-s2-form-widget.php' );
1233
  register_widget( 'S2_Form_Widget' );
1234
- } // end subscribe2_widget()
1235
 
1236
  /**
1237
- Register the counter widget
1238
- */
1239
- function counter_widget() {
1240
- require_once( S2PATH . 'classes/class-s2-counter-widget.php' );
1241
  register_widget( 'S2_Counter_Widget' );
1242
- } // end counter_widget()
1243
 
1244
  /* ===== wp-cron functions ===== */
1245
  /**
1246
- Add a weekly event to cron
1247
- */
1248
- function add_weekly_sched( $scheds ) {
1249
  $exists = false;
1250
  foreach ( $scheds as $sched ) {
1251
  if ( array_search( 604800, $sched ) ) {
@@ -1256,18 +1354,20 @@ class S2_Core {
1256
  if ( ! $exists ) {
1257
  $scheds['weekly'] = array(
1258
  'interval' => 604800,
1259
- 'display' => __( 'Weekly', 'subscribe2' ),
1260
  );
1261
  }
1262
 
1263
  return $scheds;
1264
- } // end add_weekly_sched()
1265
 
1266
  /**
1267
- Handle post transitions for the digest email
1268
- */
1269
- function digest_post_transitions( $new_status, $old_status, $post ) {
1270
- if ( $new_status === $old_status ) { return; }
 
 
1271
 
1272
  if ( 'yes' === $this->subscribe2_options['pages'] ) {
1273
  $s2_post_types = array( 'page', 'post' );
@@ -1275,23 +1375,27 @@ class S2_Core {
1275
  $s2_post_types = array( 'post' );
1276
  }
1277
  $s2_post_types = apply_filters( 's2_post_types', $s2_post_types );
1278
- if ( ! in_array( $post->post_type, $s2_post_types ) ) { return; }
 
 
1279
 
1280
  update_post_meta( $post->ID, '_s2_digest_post_status', ( 'publish' === $new_status ) ? 'pending' : 'draft' );
1281
- } // end digest_post_transitions()
1282
 
1283
  /**
1284
- Send a daily digest of today's new posts
1285
- */
1286
- function subscribe2_cron( $preview = '', $resend = '' ) {
1287
- if ( defined( 'DOING_S2_CRON' ) && DOING_S2_CRON ) { return; }
 
 
1288
  define( 'DOING_S2_CRON', true );
1289
  global $wpdb, $post;
1290
 
1291
  if ( '' === $preview ) {
1292
  // set up SQL query based on options
1293
  if ( 'yes' === $this->subscribe2_options['private'] ) {
1294
- $status = "'publish', 'private'";
1295
  } else {
1296
  $status = "'publish'";
1297
  }
@@ -1314,15 +1418,17 @@ class S2_Core {
1314
 
1315
  // collect posts
1316
  if ( 'resend' === $resend ) {
1317
- $query = new WP_Query( array(
1318
- 'post__in' => explode( ',', $this->subscribe2_options['last_s2cron'] ),
1319
- 'ignore_sticky_posts' => 1,
1320
- 'order' => ( 'desc' === $this->subscribe2_options['cron_order'] ) ? 'DESC' : 'ASC',
1321
- ) );
 
 
1322
  $posts = $query->posts;
1323
  } else {
1324
- $sql = "SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts AS a INNER JOIN $wpdb->postmeta AS b ON b.post_id = a.ID";
1325
- $sql .= " AND b.meta_key = '_s2_digest_post_status' AND b.meta_value = 'pending' WHERE post_status IN ($status) AND post_type IN ($type) ORDER BY post_date " . ( ( 'desc' === $this->subscribe2_options['cron_order'] ) ? 'DESC' : 'ASC' );
1326
  $posts = $wpdb->get_results( $sql );
1327
  }
1328
  } else {
@@ -1335,15 +1441,19 @@ class S2_Core {
1335
  if ( 'yes' === $this->subscribe2_options['stickies'] ) {
1336
  $sticky_ids = get_option( 'sticky_posts' );
1337
  if ( ! empty( $sticky_ids ) ) {
1338
- $sticky_posts = get_posts( array(
1339
- 'post__in' => $sticky_ids,
1340
- ) );
1341
- $posts = array_merge( (array) $sticky_posts, (array) $posts );
 
 
1342
  }
1343
  }
1344
 
1345
  // do we have any posts?
1346
- if ( empty( $posts ) && ! has_filter( 's2_digest_email' ) ) { return false; }
 
 
1347
 
1348
  // remove the autoembed filter to remove iframes from notification emails
1349
  if ( get_option( 'embed_autourls' ) ) {
@@ -1356,27 +1466,33 @@ class S2_Core {
1356
 
1357
  // if we have posts, let's prepare the digest
1358
  // define some variables needed for the digest
1359
- $datetime = get_option( 'date_format' ) . ' @ ' . get_option( 'time_format' );
1360
- $all_post_cats = array();
1361
- $ids = array();
1362
- $digest_post_ids = array();
1363
- $mailtext = apply_filters( 's2_email_template', $this->subscribe2_options['mailtext'] );
1364
- $table = '';
1365
- $tablelinks = '';
1366
- $message_post = '';
1367
  $message_posttime = '';
1368
  $this->post_count = count( $posts );
1369
- $s2_taxonomies = apply_filters( 's2_taxonomies', array( 'category' ) );
1370
 
1371
  foreach ( $posts as $post ) {
1372
  // keep an array of post ids and skip if we've already done it once
1373
- if ( in_array( $post->ID, $ids ) ) { continue; }
1374
- $ids[] = $post->ID;
1375
- $post_cats = wp_get_object_terms( $post->ID, $s2_taxonomies, array(
1376
- 'fields' => 'ids',
1377
- ) );
 
 
 
 
 
 
1378
  $post_cats_string = implode( ',', $post_cats );
1379
- $all_post_cats = array_unique( array_merge( $all_post_cats, $post_cats ) );
1380
 
1381
  // make sure we exclude posts from live emails if so configured
1382
  $check = false;
@@ -1405,7 +1521,7 @@ class S2_Core {
1405
  }
1406
  // is the post assigned a format that should
1407
  // not be included in the notification email?
1408
- $post_format = get_post_format( $post->ID );
1409
  $excluded_formats = explode( ',', $this->subscribe2_options['exclude_formats'] );
1410
  if ( false !== $post_format && in_array( $post_format, $excluded_formats ) ) {
1411
  $check = true;
@@ -1430,7 +1546,7 @@ class S2_Core {
1430
  }
1431
  // is the post assigned a format that should
1432
  // not be included in the notification email?
1433
- $post_format = get_post_format( $post->ID );
1434
  $excluded_formats = explode( ',', $this->subscribe2_options['exclude_formats'] );
1435
  if ( false !== $post_format && in_array( $post_format, $excluded_formats ) ) {
1436
  $check = true;
@@ -1443,19 +1559,19 @@ class S2_Core {
1443
 
1444
  $digest_post_ids[] = $post->ID;
1445
 
1446
- $post_title = html_entity_decode( __( $post->post_title ), ENT_QUOTES );
1447
- ('' === $table) ? $table .= '* ' . $post_title : $table .= "\r\n* " . $post_title;
1448
- ('' === $tablelinks) ? $tablelinks .= '* ' . $post_title : $tablelinks .= "\r\n* " . $post_title;
1449
- $message_post .= $post_title;
1450
- $message_posttime .= $post_title;
1451
  if ( strstr( $mailtext, '{AUTHORNAME}' ) ) {
1452
  $author = get_userdata( $post->post_author );
1453
  if ( '' !== $author->display_name ) {
1454
- $message_post .= ' (' . __( 'Author', 'subscribe2' ) . ': ' . html_entity_decode( apply_filters( 'the_author', $author->display_name ), ENT_QUOTES ) . ')';
1455
  $message_posttime .= ' (' . __( 'Author', 'subscribe2' ) . ': ' . html_entity_decode( apply_filters( 'the_author', $author->display_name ), ENT_QUOTES ) . ')';
1456
  }
1457
  }
1458
- $message_post .= "\r\n";
1459
  $message_posttime .= "\r\n";
1460
 
1461
  $message_posttime .= __( 'Posted on', 'subscribe2' ) . ': ' . mysql2date( $datetime, $post->post_date ) . "\r\n";
@@ -1465,32 +1581,40 @@ class S2_Core {
1465
  $tinylink = false;
1466
  }
1467
  if ( strstr( $mailtext, '{TINYLINK}' ) && 'Error' !== $tinylink && false !== $tinylink ) {
1468
- $tablelinks .= "\r\n" . $tinylink . "\r\n";
1469
- $message_post .= $tinylink . "\r\n";
1470
  $message_posttime .= $tinylink . "\r\n";
1471
  } else {
1472
- $tablelinks .= "\r\n" . $this->get_tracking_link( get_permalink( $post->ID ) ) . "\r\n";
1473
- $message_post .= $this->get_tracking_link( get_permalink( $post->ID ) ) . "\r\n";
1474
  $message_posttime .= $this->get_tracking_link( get_permalink( $post->ID ) ) . "\r\n";
1475
  }
1476
 
1477
  if ( strstr( $mailtext, '{CATS}' ) ) {
1478
- $post_cat_names = implode( ', ', wp_get_object_terms( $post->ID, $s2_taxonomies, array(
1479
- 'fields' => 'names',
1480
- ) ) );
1481
- $message_post .= __( 'Posted in', 'subscribe2' ) . ': ' . $post_cat_names . "\r\n";
 
 
 
 
1482
  $message_posttime .= __( 'Posted in', 'subscribe2' ) . ': ' . $post_cat_names . "\r\n";
1483
  }
1484
  if ( strstr( $mailtext, '{TAGS}' ) ) {
1485
- $post_tag_names = implode( ', ', wp_get_post_tags( $post->ID, array(
1486
- 'fields' => 'names',
1487
- ) ) );
 
 
 
 
1488
  if ( '' !== $post_tag_names ) {
1489
- $message_post .= __( 'Tagged as', 'subscribe2' ) . ': ' . $post_tag_names . "\r\n";
1490
  $message_posttime .= __( 'Tagged as', 'subscribe2' ) . ': ' . $post_tag_names . "\r\n";
1491
  }
1492
  }
1493
- $message_post .= "\r\n";
1494
  $message_posttime .= "\r\n";
1495
 
1496
  ( ! empty( $post->post_excerpt ) ) ? $excerpt = trim( $post->post_excerpt ) : $excerpt = '';
@@ -1499,12 +1623,12 @@ class S2_Core {
1499
  // no excerpt, is there a <!--more--> ?
1500
  if ( false !== strpos( $post->post_content, '<!--more-->' ) ) {
1501
  list($excerpt, $more) = explode( '<!--more-->', $post->post_content, 2 );
1502
- $excerpt = strip_tags( $excerpt );
1503
- $excerpt = strip_shortcodes( $excerpt );
1504
  } else {
1505
  $excerpt = strip_tags( $post->post_content );
1506
  $excerpt = strip_shortcodes( $excerpt );
1507
- $words = explode( ' ', $excerpt, $this->excerpt_length + 1 );
1508
  if ( count( $words ) > $this->excerpt_length ) {
1509
  array_pop( $words );
1510
  array_push( $words, '[...]' );
@@ -1514,7 +1638,7 @@ class S2_Core {
1514
  // strip leading and trailing whitespace
1515
  $excerpt = trim( $excerpt );
1516
  }
1517
- $message_post .= $excerpt . "\r\n\r\n";
1518
  $message_posttime .= $excerpt . "\r\n\r\n";
1519
  }
1520
 
@@ -1532,16 +1656,16 @@ class S2_Core {
1532
  }
1533
 
1534
  // we add a blank line after each post excerpt now trim white space that occurs for the last post
1535
- $message_post = trim( $message_post );
1536
  $message_posttime = trim( $message_posttime );
1537
  // remove excess white space from within $message_post and $message_posttime
1538
- $message_post = preg_replace( '/[ ]+/', ' ', $message_post );
1539
  $message_posttime = preg_replace( '/[ ]+/', ' ', $message_posttime );
1540
- $message_post = preg_replace( "/[\r\n]{3,}/", "\r\n\r\n", $message_post );
1541
  $message_posttime = preg_replace( "/[\r\n]{3,}/", "\r\n\r\n", $message_posttime );
1542
 
1543
  // apply filter to allow external content to be inserted or content manipulated
1544
- $message_post = apply_filters( 's2_digest_email', $message_post );
1545
  $message_posttime = apply_filters( 's2_digest_email', $message_posttime );
1546
 
1547
  //sanity check - don't send a mail if the content is empty
@@ -1551,18 +1675,20 @@ class S2_Core {
1551
 
1552
  // get sender details
1553
  if ( 'blogname' === $this->subscribe2_options['sender'] ) {
1554
- $this->myname = html_entity_decode( get_option( 'blogname' ), ENT_QUOTES );
1555
  $this->myemail = get_bloginfo( 'admin_email' );
1556
  } else {
1557
- $user = $this->get_userdata( $this->subscribe2_options['sender'] );
1558
  $this->myemail = $user->user_email;
1559
- $this->myname = html_entity_decode( $user->display_name, ENT_QUOTES );
1560
  }
1561
 
1562
- $scheds = (array) wp_get_schedules();
1563
  $email_freq = $this->subscribe2_options['email_freq'];
1564
- $display = $scheds[ $email_freq ]['display'];
 
1565
  ( '' === get_option( 'blogname' ) ) ? $subject = '' : $subject = '[' . stripslashes( html_entity_decode( get_option( 'blogname' ), ENT_QUOTES ) ) . '] ';
 
1566
  $subject .= $display . ' ' . __( 'Digest Email', 'subscribe2' );
1567
  $mailtext = str_replace( '{TABLELINKS}', $tablelinks, $mailtext );
1568
  $mailtext = str_replace( '{TABLE}', $table, $mailtext );
@@ -1576,26 +1702,32 @@ class S2_Core {
1576
  // prepare recipients
1577
  if ( '' !== $preview ) {
1578
  $this->myemail = $preview;
1579
- $this->myname = __( 'Digest Preview', 'subscribe2' );
1580
  $this->mail( array( $preview ), $subject, $mailtext );
1581
  } else {
1582
- $public = $this->get_public();
1583
  $all_post_cats_string = implode( ',', $all_post_cats );
1584
- $registered = $this->get_registered( "cats=$all_post_cats_string" );
1585
- $recipients = array_merge( (array) $public, (array) $registered );
1586
- $this->mail( $recipients, $subject, $mailtext );
1587
  }
1588
- } // end subscribe2_cron()
1589
 
1590
  /**
1591
- Task to delete unconfirmed public subscribers after a defined interval
1592
- */
1593
- function s2cleaner_task() {
1594
  $unconfirmed = $this->get_public( 0 );
1595
- if ( empty( $unconfirmed ) ) { return; }
 
 
1596
  global $wpdb;
1597
- $sql = $wpdb->prepare( "SELECT email FROM $this->public WHERE active='0' AND date < DATE_SUB(CURDATE(), INTERVAL %d DAY) AND conf_date IS NULL", $this->clean_interval );
1598
- $old_unconfirmed = $wpdb->get_col( $sql );
 
 
 
 
1599
  if ( empty( $old_unconfirmed ) ) {
1600
  return;
1601
  } else {
@@ -1603,26 +1735,27 @@ class S2_Core {
1603
  $this->delete( $email );
1604
  }
1605
  }
1606
- return;
1607
- } // end s2cleaner_task()
1608
 
1609
  /**
1610
  Jetpack comments doesn't play nice, this function kills that module
1611
  */
1612
- function s2_hide_jetpack_comments( $modules ) {
1613
  unset( $modules['comments'] );
1614
  return $modules;
1615
- } // end s2_kill_jetpack_comments()
1616
 
1617
  /* ===== Our constructor ===== */
1618
  /**
1619
- Subscribe2 constructor
1620
- */
1621
- function s2init() {
1622
  global $wpdb, $wp_version, $wpmu_version;
 
1623
  // load the options
1624
  $this->subscribe2_options = get_option( 'subscribe2_options' );
1625
- // if SCRIPT_DEBUG is true, use dev scripts
 
1626
  $this->script_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
1627
 
1628
  $this->word_wrap = apply_filters( 's2_word_wrap', 78 );
@@ -1635,14 +1768,14 @@ class S2_Core {
1635
  $this->excerpt_length = apply_filters( 's2_excerpt_length', 55 );
1636
  $this->site_switching = apply_filters( 's2_allow_site_switching', false );
1637
  $this->clean_interval = apply_filters( 's2_clean_interval', 28 );
1638
- $this->lockout = apply_filters( 's2_lockout', 0 );
1639
  // lockout is for a maximum of 24 hours so cap the value
1640
  if ( $this->lockout > 86399 ) {
1641
  $this->lockout > 86399;
1642
  }
1643
 
1644
  // get the WordPress release number for in code version comparisons
1645
- $tmp = explode( '-', $wp_version, 2 );
1646
  $this->wp_release = $tmp[0];
1647
 
1648
  // Is this WordPressMU or not?
@@ -1655,28 +1788,39 @@ class S2_Core {
1655
 
1656
  // add action to handle WPMU subscriptions and unsubscriptions
1657
  if ( true === $this->s2_mu ) {
1658
- require_once( S2PATH . 'classes/class-s2-multisite.php' );
1659
  global $s2class_multisite;
1660
- $s2class_multisite = new S2_Multisite;
1661
  if ( isset( $_GET['s2mu_subscribe'] ) || isset( $_GET['s2mu_unsubscribe'] ) ) {
1662
  add_action( 'init', array( &$s2class_multisite, 'wpmu_subscribe' ) );
1663
  }
1664
  }
1665
 
1666
  // load our translations
1667
- add_action( 'plugins_loaded', array( &$this, 'load_translations' ) );
 
 
 
 
 
 
 
1668
 
1669
  // do we need to install anything?
1670
- $this->public = $wpdb->prefix . 'subscribe2';
1671
- if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $this->public ) ) !== $this->public ) {
1672
- $this->install();
 
 
1673
  }
1674
 
1675
  //do we need to upgrade anything?
1676
  if ( false === $this->subscribe2_options || is_array( $this->subscribe2_options ) && S2VERSION !== $this->subscribe2_options['version'] ) {
1677
- require_once( S2PATH . 'classes/class-s2-upgrade.php' );
1678
  global $s2_upgrade;
1679
- $s2_upgrade = new S2_Upgrade;
 
 
 
1680
  add_action( 'shutdown', array( &$s2_upgrade, 'upgrade' ) );
1681
  }
1682
 
@@ -1733,9 +1877,14 @@ class S2_Core {
1733
 
1734
  // add ajax class if enabled
1735
  if ( '1' === $this->subscribe2_options['ajax'] ) {
1736
- require_once( S2PATH . 'classes/class-s2-ajax.php' );
1737
  global $mysubscribe2_ajax;
1738
- $mysubscribe2_ajax = new S2_Ajax;
 
 
 
 
 
1739
  }
1740
 
1741
  // Add actions specific to admin or frontend
@@ -1749,14 +1898,14 @@ class S2_Core {
1749
 
1750
  // Add filters for Ozh Admin Menu
1751
  if ( function_exists( 'wp_ozh_adminmenu' ) ) {
 
1752
  add_filter( 'ozh_adminmenu_icon_s2_posts', array( &$this, 'ozh_s2_icon' ) );
1753
- add_filter( 'ozh_adminmenu_icon_s2_users', array( &$this, 'ozh_s2_icon' ) );
1754
  add_filter( 'ozh_adminmenu_icon_s2_tools', array( &$this, 'ozh_s2_icon' ) );
1755
  add_filter( 'ozh_adminmenu_icon_s2_settings', array( &$this, 'ozh_s2_icon' ) );
1756
  }
1757
 
1758
  // add write button
1759
- if ( '1' === $this->subscribe2_options['show_button'] ) {
1760
  add_action( 'admin_init', array( &$this, 'button_init' ) );
1761
  }
1762
 
@@ -1780,6 +1929,9 @@ class S2_Core {
1780
  // add handler to dismiss sender error notice
1781
  add_action( 'wp_ajax_s2_dismiss_notice', array( &$this, 's2_dismiss_notice_handler' ) );
1782
 
 
 
 
1783
  // capture CSV export
1784
  if ( isset( $_POST['s2_admin'] ) && isset( $_POST['csv'] ) ) {
1785
  $date = date( 'Y-m-d' );
@@ -1817,59 +1969,31 @@ class S2_Core {
1817
  add_action( 'wp_footer', array( &$this, 'js_ip_library_script' ), 20 );
1818
  }
1819
  }
1820
- } // end s2init()
1821
-
1822
- /* ===== our variables ===== */
1823
- // cache variables
1824
- var $subscribe2_options = array();
1825
- var $all_confirmed = '';
1826
- var $all_unconfirmed = '';
1827
- var $all_registered_id = '';
1828
- var $all_registered_email = '';
1829
- var $all_registered_email_id = '';
1830
- var $excluded_cats = '';
1831
- var $post_title = '';
1832
- var $post_title_text = '';
1833
- var $permalink = '';
1834
- var $post_date = '';
1835
- var $post_time = '';
1836
- var $myname = '';
1837
- var $myemail = '';
1838
- var $authorname = '';
1839
- var $post_cat_names = '';
1840
- var $post_tag_names = '';
1841
- var $post_count = '';
1842
- var $signup_dates = array();
1843
- var $filtered = 0;
1844
- var $preview_email = false;
1845
 
1846
  // state variables used to affect processing
1847
- var $s2_mu = false;
1848
- var $action = '';
1849
- var $email = '';
1850
- var $message = '';
1851
- var $word_wrap;
1852
- var $excerpt_length;
1853
- var $site_switching;
1854
- var $clean_interval;
1855
-
1856
- // some messages
1857
- var $please_log_in = '';
1858
- var $profile = '';
1859
- var $confirmation_sent = '';
1860
- var $already_subscribed = '';
1861
- var $not_subscribed = '';
1862
- var $not_an_email = '';
1863
- var $barred_domain = '';
1864
- var $error = '';
1865
- var $mail_sent = '';
1866
- var $mail_failed = '';
1867
- var $form = '';
1868
- var $no_such_email = '';
1869
- var $added = '';
1870
- var $deleted = '';
1871
- var $subscribe = '';
1872
- var $unsubscribe = '';
1873
- var $confirm_subject = '';
1874
- } // end class subscribe2
1875
- ?>
2
  class S2_Core {
3
  // variables and constructor are declared at the end
4
  /**
5
+ * Load translations
6
+ */
7
+ public function load_translations() {
8
  load_plugin_textdomain( 'subscribe2', false, S2DIR );
9
  load_plugin_textdomain( 'subscribe2', false, S2DIR . 'languages/' );
10
+ if ( is_admin() && function_exists( 'get_user_locale' ) ) {
11
+ $locale = get_user_locale();
12
+ } else {
13
+ $locale = get_locale();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  }
15
+ $mofile = WP_LANG_DIR . '/subscribe2-' . apply_filters( 'plugin_locale', $locale, 'subscribe2' ) . '.mo';
16
+ load_textdomain( 'subscribe2', $mofile );
17
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  /* ===== mail handling ===== */
20
  /**
21
+ * Performs string substitutions for subscribe2 mail tags
22
+ */
23
+ public function substitute( $string = '', $digest_post_ids = array() ) {
24
  if ( '' === $string ) {
25
  return;
26
  }
29
  $string = str_replace( '{TITLE}', stripslashes( $this->post_title ), $string );
30
  $string = str_replace( '{TITLETEXT}', stripslashes( $this->post_title_text ), $string );
31
  $string = str_replace( '{PERMAURL}', $this->get_tracking_link( $this->permalink ), $string );
32
+ $link = '<a href="' . $this->get_tracking_link( $this->permalink ) . '">' . $this->get_tracking_link( $this->permalink ) . '</a>';
33
  $string = str_replace( '{PERMALINK}', $link, $string );
34
  if ( strstr( $string, '{TINYLINK}' ) ) {
35
+ $response = wp_safe_remote_get( 'http://tinyurl.com/api-create.php?url=' . rawurlencode( $this->get_tracking_link( $this->permalink ) ) );
36
+ if ( ! is_wp_error( $response ) ) {
37
+ $tinylink = wp_remote_retrieve_body( $response );
38
+ }
39
+ if ( false !== $tinylink ) {
40
+ $tlink = '<a href="' . $tinylink . '">' . $tinylink . '</a>';
41
  $string = str_replace( '{TINYLINK}', $tlink, $string );
42
  } else {
43
  $string = str_replace( '{TINYLINK}', $link, $string );
52
  $string = str_replace( '{TAGS}', $this->post_tag_names, $string );
53
  $string = str_replace( '{COUNT}', $this->post_count, $string );
54
 
55
+ if ( ! empty( $digest_post_ids ) ) {
56
+ return apply_filters( 's2_custom_keywords', $string, $digest_post_ids );
57
+ } else {
58
+ return apply_filters( 's2_custom_keywords', $string );
59
+ }
60
+ }
61
 
62
  /**
63
+ * Delivers email to recipients in HTML or plaintext
64
+ */
65
+ public function mail( $recipients = array(), $subject = '', $message = '', $type = 'text', $attachments = array() ) {
66
+ if ( empty( $recipients ) || '' === $message ) {
67
+ return;
68
+ }
69
 
70
  // Replace any escaped html symbols in subject then apply filter
71
+ $subject = wp_strip_all_tags( html_entity_decode( $subject, ENT_QUOTES ) );
72
  $subject = apply_filters( 's2_email_subject', $subject );
73
 
74
  if ( 'html' === $type ) {
75
  $headers = $this->headers( 'html' );
76
+ remove_all_filters( 'wp_mail_content_type' );
77
  add_filter( 'wp_mail_content_type', array( $this, 'html_email' ) );
78
  if ( 'yes' === $this->subscribe2_options['stylesheet'] ) {
79
  $mailtext = apply_filters( 's2_html_email', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>' . $subject . '</title><link rel="stylesheet" href="' . get_stylesheet_directory_uri() . apply_filters( 's2_stylesheet_name', '/style.css' ) . '" type="text/css" media="screen" /><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>' . $message . '</body></html>', $subject, $message );
82
  }
83
  } else {
84
  $headers = $this->headers( 'text' );
85
+ remove_all_filters( 'wp_mail_content_type' );
86
+ add_filter( 'wp_mail_content_type', array( $this, 'plain_email' ) );
87
+ $message = wp_strip_all_tags( html_entity_decode( $message, ENT_NOQUOTES ) );
88
  $mailtext = apply_filters( 's2_plain_email', $message );
89
  }
90
 
96
  foreach ( $recipients as $recipient ) {
97
  $recipient = trim( $recipient );
98
  // sanity check -- make sure we have a valid email
99
+ if ( false === $this->validate_email( $recipient ) || empty( $recipient ) ) {
100
+ continue;
101
+ }
102
  // Use the mail queue provided we are not sending a preview
103
+ if ( function_exists( 'wpmq_mail' ) && ! isset( $this->preview_email ) ) {
104
+ $status = wp_mail( $recipient, $subject, $mailtext, $headers, $attachments, 0 );
105
  } else {
106
+ $status = wp_mail( $recipient, $subject, $mailtext, $headers, $attachments );
107
  }
108
  }
109
  return true;
112
  foreach ( $recipients as $recipient ) {
113
  $recipient = trim( $recipient );
114
  // sanity check -- make sure we have a valid email
115
+ if ( false === $this->validate_email( $recipient ) ) {
116
+ continue;
117
+ }
118
  // and NOT the sender's email, since they'll get a copy anyway
119
  if ( ! empty( $recipient ) && $this->myemail !== $recipient ) {
120
+ ( '' === $bcc ) ? $bcc = "Bcc: $recipient" : $bcc .= ", $recipient";
121
  // Bcc Headers now constructed by phpmailer class
122
  }
123
  }
129
  foreach ( $recipients as $recipient ) {
130
  $recipient = trim( $recipient );
131
  // sanity check -- make sure we have a valid email
132
+ if ( false === $this->validate_email( $recipient ) ) {
133
+ continue;
134
+ }
135
  // and NOT the sender's email, since they'll get a copy anyway
136
  if ( ! empty( $recipient ) && $this->myemail !== $recipient ) {
137
+ ( '' === $bcc ) ? $bcc = "Bcc: $recipient" : $bcc .= ", $recipient";
138
  // Bcc Headers now constructed by phpmailer class
139
  }
140
  if ( $this->subscribe2_options['bcclimit'] === $count ) {
141
+ $count = 0;
142
  $batch[] = $bcc;
143
+ $bcc = '';
144
  }
145
  $count++;
146
  }
159
  if ( isset( $batch ) && ! empty( $batch ) ) {
160
  foreach ( $batch as $bcc ) {
161
  $newheaders = $headers . "$bcc\n";
162
+ $status = wp_mail( $this->myemail, $subject, $mailtext, $newheaders, $attachments );
163
  }
164
  } else {
165
+ $status = wp_mail( $this->myemail, $subject, $mailtext, $headers, $attachments );
166
  }
167
  return $status;
168
+ }
169
 
170
  /**
171
+ * Construct standard set of email headers
172
+ */
173
+ public function headers( $type = 'text' ) {
174
  if ( empty( $this->myname ) || empty( $this->myemail ) ) {
175
  if ( 'blogname' === $this->subscribe2_options['sender'] ) {
176
+ $this->myname = html_entity_decode( get_option( 'blogname' ), ENT_QUOTES );
177
  $this->myemail = get_option( 'admin_email' );
178
  } else {
179
+ $admin = $this->get_userdata( $this->subscribe2_options['sender'] );
180
+ $this->myname = html_entity_decode( $admin->display_name, ENT_QUOTES );
181
  $this->myemail = $admin->user_email;
182
  // fail safe to ensure sender details are not empty
183
  if ( empty( $this->myname ) ) {
196
 
197
  $char_set = get_option( 'blog_charset' );
198
  if ( function_exists( 'mb_encode_mimeheader' ) ) {
199
+ $header['From'] = mb_encode_mimeheader( $this->myname, $char_set, 'Q' ) . ' <' . $this->myemail . '>';
200
  $header['Reply-To'] = mb_encode_mimeheader( $this->myname, $char_set, 'Q' ) . ' <' . $this->myemail . '>';
201
  } else {
202
+ $header['From'] = $this->myname . ' <' . $this->myemail . '>';
203
  $header['Reply-To'] = $this->myname . ' <' . $this->myemail . '>';
204
  }
205
  $header['Return-Path'] = '<' . $this->myemail . '>';
206
+ $header['List-ID'] = html_entity_decode( get_option( 'blogname' ), ENT_QUOTES ) . ' <' . strtolower( esc_html( $_SERVER['SERVER_NAME'] ) ) . '>';
207
  if ( 'html' === $type ) {
208
  // To send HTML mail, the Content-Type header must be set
209
  $header['Content-Type'] = get_option( 'html_type' ) . '; charset="' . $char_set . '"';
217
  foreach ( $header as $key => $value ) {
218
  $headers[ $key ] = $key . ': ' . $value;
219
  }
220
+ $headers = implode( "\n", $headers );
221
  $headers .= "\n";
222
 
223
  return $headers;
224
+ }
225
 
226
  /**
227
+ * Function to set HTML Email in wp_mail()
228
+ */
229
+ public function html_email() {
230
  return 'text/html';
231
  }
232
 
233
  /**
234
+ * Function to set plain text Email in wp_mail()
235
+ */
236
+ public function plain_email() {
237
+ return 'text/plain';
238
+ }
239
+
240
+ /**
241
+ * Function to add UTM tracking details to links
242
+ */
243
+ public function get_tracking_link( $link ) {
244
+ if ( empty( $link ) ) {
245
+ return;
246
+ }
247
  if ( ! empty( $this->subscribe2_options['tracking'] ) ) {
248
+ ( strpos( $link, '?' ) > 0 ) ? $delimiter .= '&' : $delimiter = '?';
249
+
250
  $tracking = $this->subscribe2_options['tracking'];
251
  if ( strpos( $tracking, '{ID}' ) ) {
252
+ $id = url_to_postid( $link );
253
  $tracking = str_replace( '{ID}', $id, $tracking );
254
  }
255
  if ( strpos( $tracking, '{TITLE}' ) ) {
256
+ $id = url_to_postid( $link );
257
+ $title = rawurlencode( htmlentities( get_the_title( $id ), 1 ) );
258
  $tracking = str_replace( '{TITLE}', $title, $tracking );
259
  }
260
  return $link . $delimiter . $tracking;
261
  } else {
262
  return $link;
263
  }
264
+ }
265
 
266
  /**
267
+ * Sends an email notification of a new post
268
+ */
269
+ public function publish( $post, $preview = '' ) {
270
+ if ( ! $post ) {
271
+ return $post;
272
+ }
273
 
274
  if ( $this->s2_mu && ! apply_filters( 's2_allow_site_switching', $this->site_switching ) ) {
275
  global $switched;
276
+ if ( $switched ) {
277
+ return;
278
+ }
279
  }
280
 
281
  if ( '' === $preview ) {
282
  // we aren't sending a Preview to the current user so carry out checks
283
  $s2mail = get_post_meta( $post->ID, '_s2mail', true );
284
+ if ( ( isset( $_POST['s2_meta_field'] ) && 'no' === $_POST['s2_meta_field'] ) || 'no' === strtolower( trim( $s2mail ) ) ) {
285
+ return $post;
286
+ }
287
 
288
  // are we doing daily digests? If so, don't send anything now
289
+ if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
290
+ return $post;
291
+ }
292
 
293
  // is the current post of a type that should generate a notification email?
294
  // uses s2_post_types filter to allow for custom post types in WP 3.0
308
  }
309
 
310
  // Is the post assigned to a format for which we should not be sending posts
311
+ $post_format = get_post_format( $post->ID );
312
  $excluded_formats = explode( ',', $this->subscribe2_options['exclude_formats'] );
313
  if ( false !== $post_format && in_array( $post_format, $excluded_formats ) ) {
314
  return $post;
315
  }
316
 
317
  $s2_taxonomies = apply_filters( 's2_taxonomies', array( 'category' ) );
318
+ $post_cats = wp_get_object_terms(
319
+ $post->ID,
320
+ $s2_taxonomies,
321
+ array(
322
+ 'fields' => 'ids',
323
+ )
324
+ );
325
  // Fail gracefully if we have a post but no category assigned or a taxonomy error
326
  if ( is_wp_error( $post_cats ) || ( empty( $post_cats ) && 'post' === $post->post_type ) ) {
327
  return $post;
361
  $public = $this->get_public();
362
  }
363
  if ( 'page' === $post->post_type ) {
364
+ $post_cats_string = implode(
365
+ ',',
366
+ get_terms(
367
+ 'category',
368
+ array(
369
+ 'fields' => 'ids',
370
+ 'get' => 'all',
371
+ )
372
+ )
373
+ );
374
  } else {
375
  $post_cats_string = implode( ',', $post_cats );
376
  }
386
  $s2_taxonomies = apply_filters( 's2_taxonomies', array( 'category' ) );
387
  }
388
 
389
+ // get_the_time() uses the current locale of the admin user which may differ from the site locale
390
+ if ( function_exists( 'get_user_locale' ) && get_user_locale() !== get_locale() ) {
391
+ switch_to_locale( get_locale() );
392
+ $locale_switched = true;
393
+ }
394
+
395
  // we set these class variables so that we can avoid
396
  // passing them in function calls a little later
397
+ $this->post_title = '<a href="' . $this->get_tracking_link( get_permalink( $post->ID ) ) . '">' . html_entity_decode( $post->post_title, ENT_QUOTES ) . '</a>';
398
+ $this->post_title_text = html_entity_decode( $post->post_title, ENT_QUOTES );
399
+ $this->permalink = get_permalink( $post->ID );
400
+ $this->post_date = get_the_time( get_option( 'date_format' ), $post );
401
+ $this->post_time = get_the_time( '', $post );
402
+
403
+ if ( isset( $locale_switched ) && true === $locale_switched ) {
404
+ switch_to_locale( get_user_locale() );
405
+ }
406
 
407
+ $author = get_userdata( $post->post_author );
408
  $this->authorname = html_entity_decode( apply_filters( 'the_author', $author->display_name ), ENT_QUOTES );
409
 
410
+ // do we send as admin or post author?
411
  if ( 'author' === $this->subscribe2_options['sender'] ) {
412
  // get author details
413
+ $user = &$author;
414
  $this->myemail = $user->user_email;
415
+ $this->myname = html_entity_decode( $user->display_name, ENT_QUOTES );
416
  } elseif ( 'blogname' === $this->subscribe2_options['sender'] ) {
417
  $this->myemail = get_option( 'admin_email' );
418
+ $this->myname = html_entity_decode( get_option( 'blogname' ), ENT_QUOTES );
419
  } else {
420
  // get admin details
421
+ $user = $this->get_userdata( $this->subscribe2_options['sender'] );
422
  $this->myemail = $user->user_email;
423
+ $this->myname = html_entity_decode( $user->display_name, ENT_QUOTES );
424
  }
425
 
426
+ $this->post_cat_names = implode(
427
+ ', ',
428
+ wp_get_object_terms(
429
+ $post->ID,
430
+ $s2_taxonomies,
431
+ array(
432
+ 'fields' => 'names',
433
+ )
434
+ )
435
+ );
436
+ $this->post_tag_names = implode(
437
+ ', ',
438
+ wp_get_post_tags(
439
+ $post->ID,
440
+ array(
441
+ 'fields' => 'names',
442
+ )
443
+ )
444
+ );
445
 
446
  // Get email subject
447
  $subject = html_entity_decode( stripslashes( wp_kses( $this->substitute( $this->subscribe2_options['notification_subject'] ), '' ) ) );
452
  $plaintext = $post->post_content;
453
  $plaintext = strip_shortcodes( $plaintext );
454
 
455
+ $plaintext = preg_replace( '/<s[^>]*>(.*)<\/s>/Ui', '', $plaintext );
456
+ $plaintext = preg_replace( '/<strike[^>]*>(.*)<\/strike>/Ui', '', $plaintext );
457
+ $plaintext = preg_replace( '/<del[^>]*>(.*)<\/del>/Ui', '', $plaintext );
458
  $excerpttext = $plaintext;
459
 
460
  if ( strstr( $mailtext, '{REFERENCELINKS}' ) ) {
461
+ $mailtext = str_replace( '{REFERENCELINKS}', '', $mailtext );
462
  $plaintext_links = '';
463
+ $i = 0;
464
  while ( preg_match( '/<a([^>]*)>(.*)<\/a>/Ui', $plaintext, $matches ) ) {
465
  if ( preg_match( '/href="([^"]*)"/', $matches[1], $link_matches ) ) {
466
  $plaintext_links .= sprintf( "[%d] %s\r\n", ++$i, $link_matches[1] );
472
  }
473
  }
474
 
475
+ $plaintext = trim( wp_strip_all_tags( $plaintext ) );
476
 
477
  if ( isset( $plaintext_links ) && '' !== $plaintext_links ) {
478
  $plaintext .= "\r\n\r\n" . trim( $plaintext_links );
479
  }
480
 
481
+ $gallid = '[gallery id="' . $post->ID . '"';
482
  $content = str_replace( '[gallery', $gallid, $post->post_content );
483
 
484
  // remove the autoembed filter to remove iframes from notification emails
499
  if ( false !== strpos( $excerpttext, '<!--more-->' ) ) {
500
  list( $excerpt, $more ) = explode( '<!--more-->', $excerpttext, 2 );
501
  // strip tags and trailing whitespace
502
+ $excerpt = trim( wp_strip_all_tags( $excerpt ) );
503
  } else {
504
  // no <!--more-->, so grab the first 55 words
505
+ $excerpt = trim( wp_strip_all_tags( $excerpttext ) );
506
+ $words = explode( ' ', $excerpt, $this->excerpt_length + 1 );
507
  if ( count( $words ) > $this->excerpt_length ) {
508
  array_pop( $words );
509
  array_push( $words, '[...]' );
534
  }
535
 
536
  // remove excess white space from with $excerpt and $plaintext
537
+ $excerpt = preg_replace( '/[ ]+/', ' ', $excerpt );
538
  $plaintext = preg_replace( '/[ ]+/', ' ', $plaintext );
539
 
540
  // prepare mail body texts
541
  $plain_excerpt_body = str_replace( '{POST}', $excerpt, $mailtext );
542
+ $plain_body = str_replace( '{POST}', $plaintext, $mailtext );
543
+ $html_body = str_replace( "\r\n", "<br />\r\n", $mailtext );
544
+ $html_body = str_replace( '{POST}', $content, $html_body );
545
+ $html_excerpt_body = str_replace( "\r\n", "<br />\r\n", $mailtext );
546
+ $html_excerpt_body = str_replace( '{POST}', $html_excerpt, $html_excerpt_body );
547
 
548
  if ( '' !== $preview ) {
549
+ $this->preview_email = true;
550
+
551
  $this->myemail = $preview;
552
+ $this->myname = __( 'Plain Text Excerpt Preview', 'subscribe2' );
553
  $this->mail( array( $preview ), $subject, $plain_excerpt_body );
554
  $this->myname = __( 'Plain Text Full Preview', 'subscribe2' );
555
  $this->mail( array( $preview ), $subject, $plain_body );
583
  $recipients = apply_filters( 's2_send_public_subscribers', $public, $post->ID );
584
  $this->mail( $recipients, $subject, $plain_excerpt_body, 'text' );
585
  }
586
+ }
587
 
588
  /**
589
  Send confirmation email to a public subscriber
590
  */
591
+ public function send_confirm( $action = '', $is_remind = false ) {
592
+ if ( 1 === $this->filtered ) {
593
+ return true;
594
+ }
595
+ if ( ! $this->email || empty( $action ) ) {
596
+ return false;
597
+ }
598
  $id = $this->get_id( $this->email );
599
  if ( ! $id ) {
600
  return false;
604
  // ACTION = 1 to subscribe, 0 to unsubscribe
605
  // HASH = wp_hash of email address
606
  // ID = user's ID in the subscribe2 table
607
+ // use home instead of siteurl incase index.php is not in core WordPress directory
608
  $link = apply_filters( 's2_confirm_link', get_option( 'home' ) ) . '/?s2=';
609
 
610
  if ( 'add' === $action ) {
619
  $mailheaders = $this->headers();
620
 
621
  if ( true === $is_remind ) {
622
+ $body = $this->substitute( stripslashes( $this->subscribe2_options['remind_email'] ) );
623
  $subject = $this->substitute( stripslashes( $this->subscribe2_options['remind_subject'] ) );
624
  } else {
625
+ $body = apply_filters( 's2_confirm_email', stripslashes( $this->subscribe2_options['confirm_email'] ), $what );
626
  $body = $this->substitute( $body );
627
  if ( 'add' === $action ) {
628
+ $body = str_replace( '{ACTION}', $this->subscribe, $body );
629
  $subject = str_replace( '{ACTION}', $this->subscribe, $this->subscribe2_options['confirm_subject'] );
630
  } elseif ( 'del' === $action ) {
631
+ $body = str_replace( '{ACTION}', $this->unsubscribe, $body );
632
  $subject = str_replace( '{ACTION}', $this->unsubscribe, $this->subscribe2_options['confirm_subject'] );
633
  }
634
  $subject = html_entity_decode( $this->substitute( stripslashes( $subject ) ), ENT_QUOTES );
638
 
639
  if ( true === $is_remind && function_exists( 'wpmq_mail' ) ) {
640
  // could be sending lots of reminders so queue them if wpmq is enabled
641
+ $status = wp_mail( $this->email, $subject, $body, $mailheaders, '', 0 );
642
  } else {
643
+ return wp_mail( $this->email, $subject, $body, $mailheaders );
644
  }
645
+ }
646
 
647
  /* ===== Public Subscriber functions ===== */
648
  /**
649
+ * Return an array of all the public subscribers
650
+ */
651
+ public function get_public( $confirmed = 1 ) {
652
  global $wpdb;
653
+ static $all_confirmed = '';
654
+ static $all_unconfirmed = '';
655
+
656
  if ( 1 === $confirmed ) {
657
+ if ( '' === $all_confirmed ) {
658
+ $all_confirmed = $wpdb->get_col( "SELECT email FROM $wpdb->subscribe2 WHERE active='1'" );
659
  }
660
+ return $all_confirmed;
661
  } else {
662
+ if ( '' === $all_unconfirmed ) {
663
+ $all_unconfirmed = $wpdb->get_col( "SELECT email FROM $wpdb->subscribe2 WHERE active='0'" );
664
  }
665
+ return $all_unconfirmed;
666
  }
667
+ }
668
 
669
  /**
670
+ * Given a public subscriber ID, returns the email address
671
+ */
672
+ public function get_email( $id = 0 ) {
673
  global $wpdb;
674
 
675
  if ( ! $id ) {
676
  return false;
677
  }
678
+ return $wpdb->get_var( $wpdb->prepare( "SELECT email FROM $wpdb->subscribe2 WHERE id=%d", $id ) );
679
+ }
680
 
681
  /**
682
+ * Given a public subscriber email, returns the subscriber ID
683
+ */
684
+ public function get_id( $email = '' ) {
685
  global $wpdb;
686
 
687
  if ( ! $email ) {
688
  return false;
689
  }
690
+ return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->subscribe2 WHERE email=%s", $email ) );
691
+ }
692
 
693
  /**
694
+ * Add an public subscriber to the subscriber table
695
+ * If added by admin it is immediately confirmed, otherwise as unconfirmed
696
+ */
697
+ public function add( $email = '', $confirm = false ) {
698
+ if ( 1 === $this->filtered ) {
699
+ return;
700
+ }
701
  global $wpdb;
702
 
703
+ if ( false === $this->validate_email( $email ) ) {
704
+ return false;
705
+ }
706
 
707
  if ( false !== $this->is_public( $email ) ) {
708
  // is this an email for a registered user
709
  $check = $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM $wpdb->users WHERE user_email=%s", $this->email ) );
710
+ if ( $check ) {
711
+ return;
712
+ }
713
  if ( $confirm ) {
714
+ $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->subscribe2 SET active='1', ip=%s WHERE CAST(email as binary)=%s", $this->ip, $email ) );
715
  } else {
716
+ $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->subscribe2 SET date=CURDATE(), time=CURTIME() WHERE CAST(email as binary)=%s", $email ) );
717
  }
718
  } else {
719
  if ( $confirm ) {
720
  global $current_user;
721
+ $wpdb->query( $wpdb->prepare( "INSERT INTO $wpdb->subscribe2 (email, active, date, time, ip) VALUES (%s, %d, CURDATE(), CURTIME(), %s)", $email, 1, $current_user->user_login ) );
722
  } else {
723
+ $wpdb->query( $wpdb->prepare( "INSERT INTO $wpdb->subscribe2 (email, active, date, time, ip) VALUES (%s, %d, CURDATE(), CURTIME(), %s)", $email, 0, $this->ip ) );
724
  }
725
  }
726
+ }
727
 
728
  /**
729
+ * Remove a public subscriber user from the subscription table
730
+ */
731
+ public function delete( $email = '' ) {
732
  global $wpdb;
733
 
734
+ if ( false === $this->validate_email( $email ) ) {
735
+ return false;
736
+ }
737
+ $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->subscribe2 WHERE CAST(email as binary)=%s LIMIT 1", $email ) );
738
+ }
739
 
740
  /**
741
+ * Toggle a public subscriber's status
742
+ */
743
+ public function toggle( $email = '' ) {
744
  global $wpdb;
745
 
746
+ if ( '' === $email || false === $this->validate_email( $email ) ) {
747
+ return false;
748
+ }
749
 
750
  // let's see if this is a public user
751
  $status = $this->is_public( $email );
752
+ if ( false === $status ) {
753
+ return false;
754
+ }
755
 
756
  if ( '0' === $status ) {
757
+ $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->subscribe2 SET active='1', conf_date=CURDATE(), conf_time=CURTIME(), conf_ip=%s WHERE CAST(email as binary)=%s LIMIT 1", $this->ip, $email ) );
758
  } else {
759
+ $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->subscribe2 SET active='0', conf_date=CURDATE(), conf_time=CURTIME(), conf_ip=%s WHERE CAST(email as binary)=%s LIMIT 1", $this->ip, $email ) );
760
  }
761
+ }
762
 
763
  /**
764
+ * Send reminder email to unconfirmed public subscribers
765
+ */
766
+ public function remind( $emails = '' ) {
767
+ if ( '' === $emails ) {
768
+ return false;
769
+ }
770
 
771
  $recipients = explode( ',', $emails );
772
+ if ( ! is_array( $recipients ) ) {
773
+ $recipients = (array) $recipients;
774
+ }
775
  foreach ( $recipients as $recipient ) {
776
  $this->email = $recipient;
777
  $this->send_confirm( 'add', true );
779
  } //end remind()
780
 
781
  /**
782
+ * Is the supplied email address a public subscriber?
783
+ */
784
+ public function is_public( $email = '' ) {
785
  global $wpdb;
786
 
787
+ if ( '' === $email ) {
788
+ return false;
789
+ }
790
 
791
  // run the query and force case sensitivity
792
+ $check = $wpdb->get_var( $wpdb->prepare( "SELECT active FROM $wpdb->subscribe2 WHERE CAST(email as binary)=%s", $email ) );
793
  if ( '0' === $check || '1' === $check ) {
794
  return $check;
795
  } else {
796
  return false;
797
  }
798
+ }
799
 
800
  /* ===== Registered User and Subscriber functions ===== */
801
  /**
802
+ * Is the supplied email address a registered user of the blog?
803
+ */
804
+ public function is_registered( $email = '' ) {
805
  global $wpdb;
806
 
807
+ if ( '' === $email ) {
808
+ return false;
809
+ }
810
 
811
  $check = $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM $wpdb->users WHERE user_email=%s", $email ) );
812
  if ( $check ) {
814
  } else {
815
  return false;
816
  }
817
+ }
818
 
819
  /**
820
+ * Return Registered User ID from email
821
+ */
822
+ public function get_user_id( $email = '' ) {
823
  global $wpdb;
824
 
825
+ if ( '' === $email ) {
826
+ return false;
827
+ }
828
 
829
  $id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->users WHERE user_email=%s", $email ) );
830
 
831
  return $id;
832
+ }
833
 
834
  /**
835
+ * Return an array of all subscribers emails or IDs
836
+ */
837
+ public function get_all_registered( $return = 'email' ) {
838
  global $wpdb;
839
+ static $all_registered_id = '';
840
+ static $all_registered_email_id = '';
841
+ static $all_registered_email = '';
842
 
843
  if ( $this->s2_mu ) {
844
  if ( 'ID' === $return ) {
845
+ if ( '' === $all_registered_id ) {
846
+ $all_registered_id = $wpdb->get_col( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key='{$wpdb->prefix}capabilities'" );
847
  }
848
+ return $all_registered_id;
849
+ } elseif ( 'emailid' === $return ) {
850
+ if ( '' === $all_registered_email_id ) {
851
+ $all_registered_email_id = $wpdb->get_results( "SELECT a.user_email, a.ID FROM $wpdb->users AS a INNER JOIN $wpdb->usermeta AS b on a.ID = b.user_id WHERE b.meta_key ='{$wpdb->prefix}capabilities'", ARRAY_A );
852
+ }
853
+ return $all_registered_email_id;
854
  } else {
855
+ if ( '' === $all_registered_email ) {
856
+ $all_registered_email = $wpdb->get_col( "SELECT a.user_email FROM $wpdb->users AS a INNER JOIN $wpdb->usermeta AS b ON a.ID = b.user_id WHERE b.meta_key='{$wpdb->prefix}capabilities'" );
857
  }
858
+ return $all_registered_email;
859
  }
860
  } else {
861
  if ( 'ID' === $return ) {
862
+ if ( '' === $all_registered_id ) {
863
+ $all_registered_id = $wpdb->get_col( "SELECT ID FROM $wpdb->users" );
864
  }
865
+ return $all_registered_id;
866
  } elseif ( 'emailid' === $return ) {
867
+ if ( '' === $all_registered_email_id ) {
868
+ $all_registered_email_id = $wpdb->get_results( "SELECT user_email, ID FROM $wpdb->users", ARRAY_A );
869
+ }
870
+ return $all_registered_email_id;
871
  } else {
872
+ if ( '' === $all_registered_email ) {
873
+ $all_registered_email = $wpdb->get_col( "SELECT user_email FROM $wpdb->users" );
874
  }
875
+ return $all_registered_email;
876
  }
877
  }
878
+ }
879
 
880
  /**
881
+ * Return an array of registered subscribers
882
+ * Collect all the registered users of the blog who are subscribed to the specified categories
883
+ */
884
+ public function get_registered( $args = '' ) {
885
  global $wpdb;
886
 
887
  parse_str( $args, $r );
906
  }
907
  }
908
 
909
+ $join = '';
910
+ $and = '';
911
  // text or HTML subscribers
912
  if ( 'all' !== $r['format'] ) {
913
+ $join .= "INNER JOIN $wpdb->usermeta AS b ON a.user_id = b.user_id ";
914
+ $and .= $wpdb->prepare( ' AND b.meta_key=%s AND b.meta_value=%s', $this->get_usermeta_keyname( 's2_format' ), $r['format'] );
 
 
 
 
 
 
 
 
 
915
  }
916
 
917
  // specific category subscribers
918
  if ( '' !== $r['cats'] ) {
919
+ $join .= "INNER JOIN $wpdb->usermeta AS c ON a.user_id = c.user_id ";
920
+ $cats_and = '';
921
  foreach ( explode( ',', $r['cats'] ) as $cat ) {
922
+ ( '' === $cats_and ) ? $cats_and = $wpdb->prepare( 'c.meta_key=%s', $this->get_usermeta_keyname( 's2_cat' ) . $cat ) : $cats_and .= $wpdb->prepare( ' OR c.meta_key=%s', $this->get_usermeta_keyname( 's2_cat' ) . $cat );
923
  }
924
+ $and .= " AND ($cats_and)";
925
  }
926
 
927
  // specific authors
928
  if ( '' !== $r['author'] ) {
929
+ $join .= "INNER JOIN $wpdb->usermeta AS d ON a.user_id = d.user_id ";
930
+ $and .= $wpdb->prepare( ' AND (d.meta_key=%s AND NOT FIND_IN_SET(%s, d.meta_value))', $this->get_usermeta_keyname( 's2_authors' ), $r['author'] );
931
  }
932
 
933
  if ( $this->s2_mu ) {
934
+ $result = $wpdb->get_col(
935
+ $wpdb->prepare(
936
+ "SELECT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS e ON a.user_id = e.user_id " . $join . "WHERE a.meta_key='{$wpdb->prefix}capabilities' AND e.meta_key=%s AND e.meta_value <> ''" . $and,
937
+ $this->get_usermeta_keyname( 's2_subscribed' )
938
+ )
939
+ );
940
  } else {
941
+ $result = $wpdb->get_col(
942
+ $wpdb->prepare(
943
+ "SELECT a.user_id FROM $wpdb->usermeta AS a " . $join . "WHERE a.meta_key=%s AND a.meta_value <> ''" . $and,
944
+ $this->get_usermeta_keyname( 's2_subscribed' )
945
+ )
946
+ );
947
  }
 
948
 
949
  if ( empty( $result ) || false === $result ) {
950
  return array();
958
  $registered = $wpdb->get_col( "SELECT user_email FROM $wpdb->users WHERE ID IN ($ids)" );
959
  }
960
 
961
+ if ( empty( $registered ) ) {
962
+ return array();
963
+ }
964
 
965
  // apply filter to registered users to add or remove additional addresses, pass args too for additional control
966
  $registered = apply_filters( 's2_registered_subscribers', $registered, $args );
967
  return $registered;
968
+ }
969
 
970
  /**
971
+ * Function to ensure email is compliant with internet messaging standards
972
+ */
973
+ public function sanitize_email( $email ) {
974
+ $email = trim( stripslashes( $email ) );
975
+ if ( false === $email ) {
976
+ return false;
977
+ }
978
 
979
  // ensure that domain is in lowercase as per internet email standards http://www.ietf.org/rfc/rfc5321.txt
980
  list( $name, $domain ) = explode( '@', $email, 2 );
981
  return apply_filters( 's2_sanitize_email', $name . '@' . strtolower( $domain ) );
982
+ }
983
 
984
  /**
985
+ * Check email is valid
986
+ */
987
+ public function validate_email( $email ) {
988
+ // Check the formatting is correct
989
+ if ( function_exists( 'filter_var' ) ) {
990
+ if ( false === filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
991
+ return false;
992
+ }
993
+ $domain = explode( '@', $email, 2 );
994
+ if ( true === checkdnsrr( $domain[1] ) ) {
995
+ return $email;
996
+ } else {
997
+ return false;
998
+ }
999
+ } else {
1000
+ return is_email( $email );
1001
+ }
1002
+ }
1003
+
1004
+ /**
1005
+ * Create the appropriate usermeta values when a user registers
1006
+ * If the registering user had previously subscribed to notifications, this function will delete them from the public subscriber list first
1007
+ */
1008
+ public function register( $user_ID = 0, $consent = false ) {
1009
  global $wpdb;
1010
 
1011
+ if ( 0 === $user_ID ) {
1012
+ return $user_ID;
1013
+ }
1014
  $user = get_userdata( $user_ID );
1015
 
1016
  // Subscribe registered users to categories obeying excluded categories
1022
 
1023
  $cats = '';
1024
  foreach ( $all_cats as $cat ) {
1025
+ ( '' === $cats ) ? $cats = "$cat->term_id" : $cats .= ",$cat->term_id";
1026
  }
1027
 
1028
  if ( '' === $cats ) {
1059
  update_user_meta( $user_ID, $this->get_usermeta_keyname( 's2_authors' ), '' );
1060
  }
1061
  return $user_ID;
1062
+ }
1063
 
1064
  /**
1065
+ * Get admin data from record 1 or first user with admin rights
1066
+ */
1067
+ public function get_userdata( $admin_id ) {
1068
  global $wpdb, $userdata;
1069
 
1070
  if ( is_numeric( $admin_id ) ) {
1080
  $role = array(
1081
  'role' => 'administrator',
1082
  );
1083
+
1084
  $wp_user_query = get_users( $role );
1085
+ $admin = $wp_user_query[0];
1086
  }
1087
 
1088
  return $admin;
1089
  } //end get_userdata()
1090
 
1091
  /**
1092
+ * Subscribe/unsubscribe user from one-click submission
1093
+ */
1094
+ public function one_click_handler( $user_ID, $action ) {
1095
+ if ( ! isset( $user_ID ) || ! isset( $action ) ) {
1096
+ return;
1097
+ }
1098
 
1099
  $all_cats = $this->all_cats( true );
1100
 
1124
 
1125
  /* ===== helper functions: forms and stuff ===== */
1126
  /**
1127
+ * Get an object of all categories, include default and custom type
1128
+ */
1129
+ public function all_cats( $exclude = false, $orderby = 'slug' ) {
1130
+ $all_cats = array();
1131
  $s2_taxonomies = apply_filters( 's2_taxonomies', array( 'category' ) );
1132
 
1133
  foreach ( $s2_taxonomies as $taxonomy ) {
1134
  if ( taxonomy_exists( $taxonomy ) ) {
1135
+ $all_cats = array_merge(
1136
+ $all_cats,
1137
+ get_categories(
1138
+ array(
1139
+ 'hide_empty' => false,
1140
+ 'orderby' => $orderby,
1141
+ 'taxonomy' => $taxonomy,
1142
+ )
1143
+ )
1144
+ );
1145
  }
1146
  }
1147
 
1160
  }
1161
 
1162
  return $all_cats;
1163
+ }
1164
 
1165
  /**
1166
+ * Function to sanitise array of data for SQL
1167
+ */
1168
+ public function prepare_in_data( $data ) {
1169
  global $wpdb;
1170
  return $wpdb->prepare( '%s', $data );
1171
+ }
1172
 
1173
  /**
1174
+ * Filter for usermeta table key names to adjust them if needed for WPMU blogs
1175
+ */
1176
+ public function get_usermeta_keyname( $metaname ) {
1177
  global $wpdb;
1178
 
1179
  // Is this WordPressMU or not?
1185
  case 's2_autosub':
1186
  case 's2_authors':
1187
  return $wpdb->prefix . $metaname;
1188
+ default:
1189
  break;
1190
  }
1191
  }
1192
  // Not MU or not a prefixed option name
1193
  return $metaname;
1194
+ }
1195
 
1196
  /**
1197
+ * Adds information to the WordPress registration screen for new users
1198
+ */
1199
+ public function register_form() {
1200
+ if ( 'no' === $this->subscribe2_options['autosub'] ) {
1201
+ return;
1202
+ }
1203
  if ( 'wpreg' === $this->subscribe2_options['autosub'] ) {
1204
  echo '<p><label>';
1205
  echo __( 'Check here to Subscribe to email notifications for new posts', 'subscribe2' ) . ':<br />' . "\r\n";
1210
  echo __( 'By registering with this blog you are also agreeing to receive email notifications for new posts but you can unsubscribe at anytime', 'subscribe2' ) . '.<br />' . "\r\n";
1211
  echo '</center></p>' . "\r\n";
1212
  }
1213
+ }
1214
 
1215
  /**
1216
+ * Process function to add action if user selects to subscribe to posts during registration
1217
+ */
1218
+ public function register_post( $user_ID = 0 ) {
1219
  global $_POST;
1220
+ if ( 0 === $user_ID ) {
1221
+ return;
1222
+ }
1223
  if ( 'yes' === $this->subscribe2_options['autosub'] || ( isset( $_POST['reg_subscribe'] ) && 'on' === $_POST['reg_subscribe'] && 'wpreg' === $this->subscribe2_options['autosub'] ) ) {
1224
  $this->register( $user_ID, true );
1225
  } else {
1226
  $this->register( $user_ID, false );
1227
  }
1228
+ }
1229
 
1230
  /* ===== comment subscriber functions ===== */
1231
  /**
1232
+ * Display check box on comment page
1233
+ */
1234
+ public function s2_comment_meta_form( $submit_field ) {
1235
  if ( is_user_logged_in() ) {
1236
  $comment_meta_form = $this->profile;
1237
  } else {
1242
  } else {
1243
  return $submit_field . '<br />' . $comment_meta_form;
1244
  }
1245
+ }
1246
 
1247
  /**
1248
+ * Process comment meta data
1249
+ */
1250
+ public function s2_comment_meta( $comment_id, $approved = 0 ) {
1251
  // return if email is empty - can happen if setting to require name and email for comments is disabled
1252
+ if ( isset( $_POST['email'] ) && empty( $_POST['email'] ) ) {
1253
+ return;
1254
+ }
1255
  if ( isset( $_POST['s2_comment_request'] ) && '1' === $_POST['s2_comment_request'] ) {
1256
  switch ( $approved ) {
1257
  case '0':
1258
  // Unapproved so hold in meta data pending moderation
1259
+ add_comment_meta( $comment_id, 's2_comment_request', $_POST['s2_comment_request'] );
1260
  break;
1261
  case '1':
1262
  // Approved so add
1263
+ $comment = get_comment( $comment_id );
1264
  $is_public = $this->is_public( $comment->comment_author_email );
1265
  if ( 0 === $is_public ) {
1266
  $this->toggle( $comment->comment_author_email );
1270
  $this->add( $comment->comment_author_email, true );
1271
  }
1272
  break;
1273
+ default:
1274
  break;
1275
  }
1276
  }
1277
+ }
1278
 
1279
  /**
1280
+ * Action subscribe requests made on comment forms when comments are approved
1281
+ */
1282
+ public function comment_status( $comment_id = 0 ) {
1283
  global $wpdb;
1284
 
1285
  // get meta data
1286
+ $subscribe = get_comment_meta( $comment_id, 's2_comment_request', true );
1287
+ if ( '1' !== $subscribe ) {
1288
+ return $comment_id;
1289
+ }
1290
 
1291
  // Retrieve the information about the comment
1292
+ $comment = $wpdb->get_row(
1293
+ $wpdb->prepare(
1294
+ "SELECT comment_author_email, comment_approved FROM $wpdb->comments WHERE comment_ID=%s LIMIT 1",
1295
+ $comment_id
1296
+ ),
1297
+ OBJECT
1298
+ );
1299
+ if ( empty( $comment ) ) {
1300
+ return $comment_id;
1301
+ }
1302
 
1303
  switch ( $comment->comment_approved ) {
1304
  case '0': // Unapproved
1312
  if ( ! $is_public && ! $is_registered ) {
1313
  $this->add( $comment->comment_author_email, true );
1314
  }
1315
+ delete_comment_meta( $comment_id, 's2_comment_request' );
1316
  break;
1317
  default: // post is trash, spam or deleted
1318
+ delete_comment_meta( $comment_id, 's2_comment_request' );
1319
  break;
1320
  }
1321
 
1322
+ return $comment_id;
1323
+ }
1324
 
1325
  /* ===== widget functions ===== */
1326
  /**
1327
+ * Register the form widget
1328
+ */
1329
+ public function subscribe2_widget() {
1330
+ require_once S2PATH . 'classes/class-s2-form-widget.php';
1331
  register_widget( 'S2_Form_Widget' );
1332
+ }
1333
 
1334
  /**
1335
+ * Register the counter widget
1336
+ */
1337
+ public function counter_widget() {
1338
+ require_once S2PATH . 'classes/class-s2-counter-widget.php';
1339
  register_widget( 'S2_Counter_Widget' );
1340
+ }
1341
 
1342
  /* ===== wp-cron functions ===== */
1343
  /**
1344
+ * Add a weekly event to cron
1345
+ */
1346
+ public function add_weekly_sched( $scheds ) {
1347
  $exists = false;
1348
  foreach ( $scheds as $sched ) {
1349
  if ( array_search( 604800, $sched ) ) {
1354
  if ( ! $exists ) {
1355
  $scheds['weekly'] = array(
1356
  'interval' => 604800,
1357
+ 'display' => __( 'Weekly', 'subscribe2' ),
1358
  );
1359
  }
1360
 
1361
  return $scheds;
1362
+ }
1363
 
1364
  /**
1365
+ * Handle post transitions for the digest email
1366
+ */
1367
+ public function digest_post_transitions( $new_status, $old_status, $post ) {
1368
+ if ( $new_status === $old_status ) {
1369
+ return;
1370
+ }
1371
 
1372
  if ( 'yes' === $this->subscribe2_options['pages'] ) {
1373
  $s2_post_types = array( 'page', 'post' );
1375
  $s2_post_types = array( 'post' );
1376
  }
1377
  $s2_post_types = apply_filters( 's2_post_types', $s2_post_types );
1378
+ if ( ! in_array( $post->post_type, $s2_post_types ) ) {
1379
+ return;
1380
+ }
1381
 
1382
  update_post_meta( $post->ID, '_s2_digest_post_status', ( 'publish' === $new_status ) ? 'pending' : 'draft' );
1383
+ }
1384
 
1385
  /**
1386
+ * Send a daily digest of today's new posts
1387
+ */
1388
+ public function subscribe2_cron( $preview = '', $resend = '' ) {
1389
+ if ( defined( 'DOING_S2_CRON' ) && DOING_S2_CRON ) {
1390
+ return;
1391
+ }
1392
  define( 'DOING_S2_CRON', true );
1393
  global $wpdb, $post;
1394
 
1395
  if ( '' === $preview ) {
1396
  // set up SQL query based on options
1397
  if ( 'yes' === $this->subscribe2_options['private'] ) {
1398
+ $status = "'publish', 'private'";
1399
  } else {
1400
  $status = "'publish'";
1401
  }
1418
 
1419
  // collect posts
1420
  if ( 'resend' === $resend ) {
1421
+ $query = new WP_Query(
1422
+ array(
1423
+ 'post__in' => explode( ',', $this->subscribe2_options['last_s2cron'] ),
1424
+ 'ignore_sticky_posts' => 1,
1425
+ 'order' => ( 'desc' === $this->subscribe2_options['cron_order'] ) ? 'DESC' : 'ASC',
1426
+ )
1427
+ );
1428
  $posts = $query->posts;
1429
  } else {
1430
+ $sql = "SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts AS a INNER JOIN $wpdb->postmeta AS b ON b.post_id = a.ID";
1431
+ $sql .= " AND b.meta_key = '_s2_digest_post_status' AND b.meta_value = 'pending' WHERE post_status IN ($status) AND post_type IN ($type) ORDER BY post_date " . ( ( 'desc' === $this->subscribe2_options['cron_order'] ) ? 'DESC' : 'ASC' );
1432
  $posts = $wpdb->get_results( $sql );
1433
  }
1434
  } else {
1441
  if ( 'yes' === $this->subscribe2_options['stickies'] ) {
1442
  $sticky_ids = get_option( 'sticky_posts' );
1443
  if ( ! empty( $sticky_ids ) ) {
1444
+ $sticky_posts = get_posts(
1445
+ array(
1446
+ 'post__in' => $sticky_ids,
1447
+ )
1448
+ );
1449
+ $posts = array_merge( (array) $sticky_posts, (array) $posts );
1450
  }
1451
  }
1452
 
1453
  // do we have any posts?
1454
+ if ( empty( $posts ) && ! has_filter( 's2_digest_email' ) ) {
1455
+ return false;
1456
+ }
1457
 
1458
  // remove the autoembed filter to remove iframes from notification emails
1459
  if ( get_option( 'embed_autourls' ) ) {
1466
 
1467
  // if we have posts, let's prepare the digest
1468
  // define some variables needed for the digest
1469
+ $datetime = get_option( 'date_format' ) . ' @ ' . get_option( 'time_format' );
1470
+ $all_post_cats = array();
1471
+ $ids = array();
1472
+ $digest_post_ids = array();
1473
+ $mailtext = apply_filters( 's2_email_template', $this->subscribe2_options['mailtext'] );
1474
+ $table = '';
1475
+ $tablelinks = '';
1476
+ $message_post = '';
1477
  $message_posttime = '';
1478
  $this->post_count = count( $posts );
1479
+ $s2_taxonomies = apply_filters( 's2_taxonomies', array( 'category' ) );
1480
 
1481
  foreach ( $posts as $post ) {
1482
  // keep an array of post ids and skip if we've already done it once
1483
+ if ( in_array( $post->ID, $ids ) ) {
1484
+ continue;
1485
+ }
1486
+ $ids[] = $post->ID;
1487
+ $post_cats = wp_get_object_terms(
1488
+ $post->ID,
1489
+ $s2_taxonomies,
1490
+ array(
1491
+ 'fields' => 'ids',
1492
+ )
1493
+ );
1494
  $post_cats_string = implode( ',', $post_cats );
1495
+ $all_post_cats = array_unique( array_merge( $all_post_cats, $post_cats ) );
1496
 
1497
  // make sure we exclude posts from live emails if so configured
1498
  $check = false;
1521
  }
1522
  // is the post assigned a format that should
1523
  // not be included in the notification email?
1524
+ $post_format = get_post_format( $post->ID );
1525
  $excluded_formats = explode( ',', $this->subscribe2_options['exclude_formats'] );
1526
  if ( false !== $post_format && in_array( $post_format, $excluded_formats ) ) {
1527
  $check = true;
1546
  }
1547
  // is the post assigned a format that should
1548
  // not be included in the notification email?
1549
+ $post_format = get_post_format( $post->ID );
1550
  $excluded_formats = explode( ',', $this->subscribe2_options['exclude_formats'] );
1551
  if ( false !== $post_format && in_array( $post_format, $excluded_formats ) ) {
1552
  $check = true;
1559
 
1560
  $digest_post_ids[] = $post->ID;
1561
 
1562
+ $post_title = html_entity_decode( $post->post_title, ENT_QUOTES );
1563
+ ( '' === $table ) ? $table .= '* ' . $post_title : $table .= "\r\n* " . $post_title;
1564
+ ( '' === $tablelinks ) ? $tablelinks .= '* ' . $post_title : $tablelinks .= "\r\n* " . $post_title;
1565
+ $message_post .= $post_title;
1566
+ $message_posttime .= $post_title;
1567
  if ( strstr( $mailtext, '{AUTHORNAME}' ) ) {
1568
  $author = get_userdata( $post->post_author );
1569
  if ( '' !== $author->display_name ) {
1570
+ $message_post .= ' (' . __( 'Author', 'subscribe2' ) . ': ' . html_entity_decode( apply_filters( 'the_author', $author->display_name ), ENT_QUOTES ) . ')';
1571
  $message_posttime .= ' (' . __( 'Author', 'subscribe2' ) . ': ' . html_entity_decode( apply_filters( 'the_author', $author->display_name ), ENT_QUOTES ) . ')';
1572
  }
1573
  }
1574
+ $message_post .= "\r\n";
1575
  $message_posttime .= "\r\n";
1576
 
1577
  $message_posttime .= __( 'Posted on', 'subscribe2' ) . ': ' . mysql2date( $datetime, $post->post_date ) . "\r\n";
1581
  $tinylink = false;
1582
  }
1583
  if ( strstr( $mailtext, '{TINYLINK}' ) && 'Error' !== $tinylink && false !== $tinylink ) {
1584
+ $tablelinks .= "\r\n" . $tinylink . "\r\n";
1585
+ $message_post .= $tinylink . "\r\n";
1586
  $message_posttime .= $tinylink . "\r\n";
1587
  } else {
1588
+ $tablelinks .= "\r\n" . $this->get_tracking_link( get_permalink( $post->ID ) ) . "\r\n";
1589
+ $message_post .= $this->get_tracking_link( get_permalink( $post->ID ) ) . "\r\n";
1590
  $message_posttime .= $this->get_tracking_link( get_permalink( $post->ID ) ) . "\r\n";
1591
  }
1592
 
1593
  if ( strstr( $mailtext, '{CATS}' ) ) {
1594
+ $post_cat_names = implode(
1595
+ ', ', wp_get_object_terms(
1596
+ $post->ID, $s2_taxonomies, array(
1597
+ 'fields' => 'names',
1598
+ )
1599
+ )
1600
+ );
1601
+ $message_post .= __( 'Posted in', 'subscribe2' ) . ': ' . $post_cat_names . "\r\n";
1602
  $message_posttime .= __( 'Posted in', 'subscribe2' ) . ': ' . $post_cat_names . "\r\n";
1603
  }
1604
  if ( strstr( $mailtext, '{TAGS}' ) ) {
1605
+ $post_tag_names = implode(
1606
+ ', ', wp_get_post_tags(
1607
+ $post->ID, array(
1608
+ 'fields' => 'names',
1609
+ )
1610
+ )
1611
+ );
1612
  if ( '' !== $post_tag_names ) {
1613
+ $message_post .= __( 'Tagged as', 'subscribe2' ) . ': ' . $post_tag_names . "\r\n";
1614
  $message_posttime .= __( 'Tagged as', 'subscribe2' ) . ': ' . $post_tag_names . "\r\n";
1615
  }
1616
  }
1617
+ $message_post .= "\r\n";
1618
  $message_posttime .= "\r\n";
1619
 
1620
  ( ! empty( $post->post_excerpt ) ) ? $excerpt = trim( $post->post_excerpt ) : $excerpt = '';
1623
  // no excerpt, is there a <!--more--> ?
1624
  if ( false !== strpos( $post->post_content, '<!--more-->' ) ) {
1625
  list($excerpt, $more) = explode( '<!--more-->', $post->post_content, 2 );
1626
+ $excerpt = strip_tags( $excerpt );
1627
+ $excerpt = strip_shortcodes( $excerpt );
1628
  } else {
1629
  $excerpt = strip_tags( $post->post_content );
1630
  $excerpt = strip_shortcodes( $excerpt );
1631
+ $words = explode( ' ', $excerpt, $this->excerpt_length + 1 );
1632
  if ( count( $words ) > $this->excerpt_length ) {
1633
  array_pop( $words );
1634
  array_push( $words, '[...]' );
1638
  // strip leading and trailing whitespace
1639
  $excerpt = trim( $excerpt );
1640
  }
1641
+ $message_post .= $excerpt . "\r\n\r\n";
1642
  $message_posttime .= $excerpt . "\r\n\r\n";
1643
  }
1644
 
1656
  }
1657
 
1658
  // we add a blank line after each post excerpt now trim white space that occurs for the last post
1659
+ $message_post = trim( $message_post );
1660
  $message_posttime = trim( $message_posttime );
1661
  // remove excess white space from within $message_post and $message_posttime
1662
+ $message_post = preg_replace( '/[ ]+/', ' ', $message_post );
1663
  $message_posttime = preg_replace( '/[ ]+/', ' ', $message_posttime );
1664
+ $message_post = preg_replace( "/[\r\n]{3,}/", "\r\n\r\n", $message_post );
1665
  $message_posttime = preg_replace( "/[\r\n]{3,}/", "\r\n\r\n", $message_posttime );
1666
 
1667
  // apply filter to allow external content to be inserted or content manipulated
1668
+ $message_post = apply_filters( 's2_digest_email', $message_post );
1669
  $message_posttime = apply_filters( 's2_digest_email', $message_posttime );
1670
 
1671
  //sanity check - don't send a mail if the content is empty
1675
 
1676
  // get sender details
1677
  if ( 'blogname' === $this->subscribe2_options['sender'] ) {
1678
+ $this->myname = html_entity_decode( get_option( 'blogname' ), ENT_QUOTES );
1679
  $this->myemail = get_bloginfo( 'admin_email' );
1680
  } else {
1681
+ $user = $this->get_userdata( $this->subscribe2_options['sender'] );
1682
  $this->myemail = $user->user_email;
1683
+ $this->myname = html_entity_decode( $user->display_name, ENT_QUOTES );
1684
  }
1685
 
1686
+ $scheds = (array) wp_get_schedules();
1687
  $email_freq = $this->subscribe2_options['email_freq'];
1688
+ $display = $scheds[ $email_freq ]['display'];
1689
+
1690
  ( '' === get_option( 'blogname' ) ) ? $subject = '' : $subject = '[' . stripslashes( html_entity_decode( get_option( 'blogname' ), ENT_QUOTES ) ) . '] ';
1691
+
1692
  $subject .= $display . ' ' . __( 'Digest Email', 'subscribe2' );
1693
  $mailtext = str_replace( '{TABLELINKS}', $tablelinks, $mailtext );
1694
  $mailtext = str_replace( '{TABLE}', $table, $mailtext );
1702
  // prepare recipients
1703
  if ( '' !== $preview ) {
1704
  $this->myemail = $preview;
1705
+ $this->myname = __( 'Digest Preview', 'subscribe2' );
1706
  $this->mail( array( $preview ), $subject, $mailtext );
1707
  } else {
1708
+ $public = $this->get_public();
1709
  $all_post_cats_string = implode( ',', $all_post_cats );
1710
+ $registered = $this->get_registered( "cats=$all_post_cats_string" );
1711
+ $recipients = array_merge( (array) $public, (array) $registered );
1712
+ $this->mail( $recipients, $subject, $mailtext, $digest_format );
1713
  }
1714
+ }
1715
 
1716
  /**
1717
+ * Task to delete unconfirmed public subscribers after a defined interval
1718
+ */
1719
+ public function s2cleaner_task() {
1720
  $unconfirmed = $this->get_public( 0 );
1721
+ if ( empty( $unconfirmed ) ) {
1722
+ return;
1723
+ }
1724
  global $wpdb;
1725
+ $old_unconfirmed = $wpdb->get_col(
1726
+ $wpdb->prepare(
1727
+ "SELECT email FROM $wpdb->subscribe2 WHERE active='0' AND date < DATE_SUB(CURDATE(), INTERVAL %d DAY) AND conf_date IS NULL",
1728
+ $this->clean_interval
1729
+ )
1730
+ );
1731
  if ( empty( $old_unconfirmed ) ) {
1732
  return;
1733
  } else {
1735
  $this->delete( $email );
1736
  }
1737
  }
1738
+ }
 
1739
 
1740
  /**
1741
  Jetpack comments doesn't play nice, this function kills that module
1742
  */
1743
+ public function s2_hide_jetpack_comments( $modules ) {
1744
  unset( $modules['comments'] );
1745
  return $modules;
1746
+ }
1747
 
1748
  /* ===== Our constructor ===== */
1749
  /**
1750
+ * Subscribe2 constructor
1751
+ */
1752
+ public function s2init() {
1753
  global $wpdb, $wp_version, $wpmu_version;
1754
+
1755
  // load the options
1756
  $this->subscribe2_options = get_option( 'subscribe2_options' );
1757
+
1758
+ // maybe use dev scripts
1759
  $this->script_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
1760
 
1761
  $this->word_wrap = apply_filters( 's2_word_wrap', 78 );
1768
  $this->excerpt_length = apply_filters( 's2_excerpt_length', 55 );
1769
  $this->site_switching = apply_filters( 's2_allow_site_switching', false );
1770
  $this->clean_interval = apply_filters( 's2_clean_interval', 28 );
1771
+ $this->lockout = apply_filters( 's2_lockout', 0 );
1772
  // lockout is for a maximum of 24 hours so cap the value
1773
  if ( $this->lockout > 86399 ) {
1774
  $this->lockout > 86399;
1775
  }
1776
 
1777
  // get the WordPress release number for in code version comparisons
1778
+ $tmp = explode( '-', $wp_version, 2 );
1779
  $this->wp_release = $tmp[0];
1780
 
1781
  // Is this WordPressMU or not?
1788
 
1789
  // add action to handle WPMU subscriptions and unsubscriptions
1790
  if ( true === $this->s2_mu ) {
1791
+ require_once S2PATH . 'classes/class-s2-multisite.php';
1792
  global $s2class_multisite;
1793
+ $s2class_multisite = new S2_Multisite();
1794
  if ( isset( $_GET['s2mu_subscribe'] ) || isset( $_GET['s2mu_unsubscribe'] ) ) {
1795
  add_action( 'init', array( &$s2class_multisite, 'wpmu_subscribe' ) );
1796
  }
1797
  }
1798
 
1799
  // load our translations
1800
+ add_action( 'init', array( &$this, 'load_translations' ) );
1801
+
1802
+ // define and register table name
1803
+ $s2_table = $wpdb->prefix . 'subscribe2';
1804
+ if ( ! isset( $wpdb->subscribe2 ) ) {
1805
+ $wpdb->subscribe2 = $s2_table;
1806
+ $wpdb->tables[] = 'subscribe2';
1807
+ }
1808
 
1809
  // do we need to install anything?
1810
+ if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->subscribe2 ) ) !== $wpdb->subscribe2 ) {
1811
+ require_once S2PATH . 'classes/class-s2-upgrade.php';
1812
+ global $s2_upgrade;
1813
+ $s2_upgrade = new S2_Upgrade();
1814
+ $s2_upgrade->install();
1815
  }
1816
 
1817
  //do we need to upgrade anything?
1818
  if ( false === $this->subscribe2_options || is_array( $this->subscribe2_options ) && S2VERSION !== $this->subscribe2_options['version'] ) {
 
1819
  global $s2_upgrade;
1820
+ if ( ! is_a( $s2_upgrade, 'S2_Upgrade' ) ) {
1821
+ require_once S2PATH . 'classes/class-s2-upgrade.php';
1822
+ $s2_upgrade = new S2_Upgrade();
1823
+ }
1824
  add_action( 'shutdown', array( &$s2_upgrade, 'upgrade' ) );
1825
  }
1826
 
1877
 
1878
  // add ajax class if enabled
1879
  if ( '1' === $this->subscribe2_options['ajax'] ) {
1880
+ require_once S2PATH . 'classes/class-s2-ajax.php';
1881
  global $mysubscribe2_ajax;
1882
+ $mysubscribe2_ajax = new S2_Ajax();
1883
+ }
1884
+
1885
+ // Check if Block Editor is in use
1886
+ if ( function_exists( 'register_block_type' ) && ! class_exists( 'Classic_Editor' ) && false === has_filter( 'use_block_editor_for_post', '__return_false' ) ) {
1887
+ $this->block_editor = true;
1888
  }
1889
 
1890
  // Add actions specific to admin or frontend
1898
 
1899
  // Add filters for Ozh Admin Menu
1900
  if ( function_exists( 'wp_ozh_adminmenu' ) ) {
1901
+ add_filter( 'ozh_adminmenu_icon_s2', array( &$this, 'ozh_s2_icon' ) );
1902
  add_filter( 'ozh_adminmenu_icon_s2_posts', array( &$this, 'ozh_s2_icon' ) );
 
1903
  add_filter( 'ozh_adminmenu_icon_s2_tools', array( &$this, 'ozh_s2_icon' ) );
1904
  add_filter( 'ozh_adminmenu_icon_s2_settings', array( &$this, 'ozh_s2_icon' ) );
1905
  }
1906
 
1907
  // add write button
1908
+ if ( '1' === $this->subscribe2_options['show_button'] && false === $this->block_editor ) {
1909
  add_action( 'admin_init', array( &$this, 'button_init' ) );
1910
  }
1911
 
1929
  // add handler to dismiss sender error notice
1930
  add_action( 'wp_ajax_s2_dismiss_notice', array( &$this, 's2_dismiss_notice_handler' ) );
1931
 
1932
+ // subscriber page options handler
1933
+ add_filter( 'set-screen-option', array( &$this, 'subscribers_set_screen_option' ), 10, 3 );
1934
+
1935
  // capture CSV export
1936
  if ( isset( $_POST['s2_admin'] ) && isset( $_POST['csv'] ) ) {
1937
  $date = date( 'Y-m-d' );
1969
  add_action( 'wp_footer', array( &$this, 'js_ip_library_script' ), 20 );
1970
  }
1971
  }
1972
+
1973
+ require_once S2PATH . 'classes/mo-notice.php';
1974
+ }
1975
+
1976
+ /* ===== define some variables ===== */
1977
+ // options
1978
+ public $subscribe2_options = array();
1979
+
1980
+ // check for block editor
1981
+ public $block_editor = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1982
 
1983
  // state variables used to affect processing
1984
+ public $s2_mu = false;
1985
+ public $filtered = 0;
1986
+ public $post_count;
1987
+
1988
+ // state variable used in substitute() function
1989
+ public $post_title;
1990
+ public $post_title_text;
1991
+ public $permalink;
1992
+ public $post_date;
1993
+ public $post_time;
1994
+ public $myname;
1995
+ public $myemail;
1996
+ public $authorname;
1997
+ public $post_cat_names;
1998
+ public $post_tag_names;
1999
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/class-s2-counter-widget.php CHANGED
@@ -1,31 +1,32 @@
1
  <?php
2
  class S2_Counter_Widget extends WP_Widget {
3
  /**
4
- Declares the S2_Counter_widget class.
5
- */
6
- function __construct() {
7
  $widget_options = array(
8
- 'classname' => 's2_counter',
9
- 'description' => esc_html__( 'Subscriber Counter widget for Subscribe2', 'subscribe2' ),
10
  'customize_selective_refresh' => true,
11
  );
 
12
  $control_options = array(
13
- 'width' => 250,
14
  'height' => 500,
15
  );
16
  parent::__construct( 's2_counter', esc_html__( 'Subscribe2 Counter', 'subscribe2' ), $widget_options, $control_options );
17
  }
18
 
19
  /**
20
- Displays the Widget
21
- */
22
- function widget( $args, $instance ) {
23
- $title = empty( $instance['title'] ) ? 'Subscriber Count' : $instance['title'];
24
- $s2w_bg = empty( $instance['s2w_bg'] ) ? '#e3dacf' : $instance['s2w_bg'];
25
- $s2w_fg = empty( $instance['s2w_fg'] ) ? '#345797' : $instance['s2w_fg'];
26
- $s2w_width = empty( $instance['s2w_width'] ) ? '82' : $instance['s2w_width'];
27
  $s2w_height = empty( $instance['s2w_height'] ) ? '16' : $instance['s2w_height'];
28
- $s2w_font = empty( $instance['s2w_font'] ) ? '11' : $instance['s2w_font'];
29
 
30
  echo $args['before_widget'];
31
  if ( ! empty( $title ) ) {
@@ -33,8 +34,8 @@ class S2_Counter_Widget extends WP_Widget {
33
  }
34
  global $mysubscribe2;
35
  $registered = $mysubscribe2->get_registered();
36
- $confirmed = $mysubscribe2->get_public();
37
- $count = (count( $registered ) + count( $confirmed ));
38
  echo '<ul><div style="text-align:center; background-color:' . $s2w_bg . '; color:' . $s2w_fg . '; width:' . $s2w_width . 'px; height:' . $s2w_height . 'px; font:' . $s2w_font . 'pt Verdana, Arial, Helvetica, sans-serif; vertical-align:middle; padding:3px; border:1px solid #444;">';
39
  echo $count;
40
  echo '</div></ul>';
@@ -42,54 +43,54 @@ class S2_Counter_Widget extends WP_Widget {
42
  }
43
 
44
  /**
45
- Saves the widgets settings.
46
- */
47
- function update( $new_instance, $old_instance ) {
48
- $instance = $old_instance;
49
- $instance['title'] = strip_tags( stripslashes( $new_instance['title'] ) );
50
- $instance['s2w_bg'] = strip_tags( stripslashes( $new_instance['s2w_bg'] ) );
51
- $instance['s2w_fg'] = strip_tags( stripslashes( $new_instance['s2w_fg'] ) );
52
- $instance['s2w_width'] = strip_tags( stripslashes( $new_instance['s2w_width'] ) );
53
- $instance['s2w_height'] = strip_tags( stripslashes( $new_instance['s2w_height'] ) );
54
- $instance['s2w_font'] = strip_tags( stripslashes( $new_instance['s2w_font'] ) );
55
 
56
  return $instance;
57
  }
58
 
59
  /**
60
- Creates the edit form for the widget.
61
- */
62
- function form( $instance ) {
63
  // set some defaults
64
  $options = get_option( 'widget_s2counter' );
65
  if ( false === $options ) {
66
  $defaults = array(
67
- 'title' => 'Subscriber Count',
68
- 's2w_bg' => '#e3dacf',
69
- 's2w_fg' => '#345797',
70
- 's2w_width' => '82',
71
  's2w_height' => '16',
72
- 's2w_font' => '11',
73
  );
74
  } else {
75
  $defaults = array(
76
- 'title' => $options['title'],
77
- 's2w_bg' => $options['s2w_bg'],
78
- 's2w_fg' => $options['s2w_fg'],
79
- 's2w_width' => $options['s2w_width'],
80
  's2w_height' => $options['s2w_height'],
81
- 's2w_font' => $options['s2w_font'],
82
  );
83
  delete_option( 'widget_s2counter' );
84
  }
85
  $instance = wp_parse_args( (array) $instance, $defaults );
86
  // Be sure you format your options to be valid HTML attributes.
87
- $s2w_title = htmlspecialchars( $instance['title'], ENT_QUOTES );
88
- $s2w_bg = htmlspecialchars( $instance['s2w_bg'], ENT_QUOTES );
89
- $s2w_fg = htmlspecialchars( $instance['s2w_fg'], ENT_QUOTES );
90
- $s2w_width = htmlspecialchars( $instance['s2w_width'], ENT_QUOTES );
91
  $s2w_height = htmlspecialchars( $instance['s2w_height'], ENT_QUOTES );
92
- $s2w_font = htmlspecialchars( $instance['s2w_font'], ENT_QUOTES );
93
  echo '<div>' . "\r\n";
94
  echo '<fieldset><legend><label for="' . esc_attr( $this->get_field_id( 'title' ) ) . '">' . esc_html__( 'Widget Title', 'subscribe2' ) . '</label></legend>' . "\r\n";
95
  echo '<input type="text" name="' . esc_attr( $this->get_field_name( 'title' ) ) . '" id="' . esc_attr( $this->get_field_id( 'title' ) ) . '" value="' . esc_attr( $s2w_title ) . '" />' . "\r\n";
@@ -116,4 +117,3 @@ class S2_Counter_Widget extends WP_Widget {
116
  echo '</table></fieldset></div>' . "\r\n";
117
  }
118
  }// end S2_Counter_widget class
119
- ?>
1
  <?php
2
  class S2_Counter_Widget extends WP_Widget {
3
  /**
4
+ * Declares the S2_Counter_widget class.
5
+ */
6
+ public function __construct() {
7
  $widget_options = array(
8
+ 'classname' => 's2_counter',
9
+ 'description' => esc_html__( 'Subscriber Counter widget for Subscribe2', 'subscribe2' ),
10
  'customize_selective_refresh' => true,
11
  );
12
+
13
  $control_options = array(
14
+ 'width' => 250,
15
  'height' => 500,
16
  );
17
  parent::__construct( 's2_counter', esc_html__( 'Subscribe2 Counter', 'subscribe2' ), $widget_options, $control_options );
18
  }
19
 
20
  /**
21
+ * Displays the Widget
22
+ */
23
+ public function widget( $args, $instance ) {
24
+ $title = empty( $instance['title'] ) ? 'Subscriber Count' : $instance['title'];
25
+ $s2w_bg = empty( $instance['s2w_bg'] ) ? '#e3dacf' : $instance['s2w_bg'];
26
+ $s2w_fg = empty( $instance['s2w_fg'] ) ? '#345797' : $instance['s2w_fg'];
27
+ $s2w_width = empty( $instance['s2w_width'] ) ? '82' : $instance['s2w_width'];
28
  $s2w_height = empty( $instance['s2w_height'] ) ? '16' : $instance['s2w_height'];
29
+ $s2w_font = empty( $instance['s2w_font'] ) ? '11' : $instance['s2w_font'];
30
 
31
  echo $args['before_widget'];
32
  if ( ! empty( $title ) ) {
34
  }
35
  global $mysubscribe2;
36
  $registered = $mysubscribe2->get_registered();
37
+ $confirmed = $mysubscribe2->get_public();
38
+ $count = ( count( $registered ) + count( $confirmed ) );
39
  echo '<ul><div style="text-align:center; background-color:' . $s2w_bg . '; color:' . $s2w_fg . '; width:' . $s2w_width . 'px; height:' . $s2w_height . 'px; font:' . $s2w_font . 'pt Verdana, Arial, Helvetica, sans-serif; vertical-align:middle; padding:3px; border:1px solid #444;">';
40
  echo $count;
41
  echo '</div></ul>';
43
  }
44
 
45
  /**
46
+ * Saves the widgets settings.
47
+ */
48
+ public function update( $new_instance, $old_instance ) {
49
+ $instance = $old_instance;
50
+ $instance['title'] = wp_strip_all_tags( stripslashes( $new_instance['title'] ) );
51
+ $instance['s2w_bg'] = wp_strip_all_tags( stripslashes( $new_instance['s2w_bg'] ) );
52
+ $instance['s2w_fg'] = wp_strip_all_tags( stripslashes( $new_instance['s2w_fg'] ) );
53
+ $instance['s2w_width'] = wp_strip_all_tags( stripslashes( $new_instance['s2w_width'] ) );
54
+ $instance['s2w_height'] = wp_strip_all_tags( stripslashes( $new_instance['s2w_height'] ) );
55
+ $instance['s2w_font'] = wp_strip_all_tags( stripslashes( $new_instance['s2w_font'] ) );
56
 
57
  return $instance;
58
  }
59
 
60
  /**
61
+ * Creates the edit form for the widget.
62
+ */
63
+ public function form( $instance ) {
64
  // set some defaults
65
  $options = get_option( 'widget_s2counter' );
66
  if ( false === $options ) {
67
  $defaults = array(
68
+ 'title' => 'Subscriber Count',
69
+ 's2w_bg' => '#e3dacf',
70
+ 's2w_fg' => '#345797',
71
+ 's2w_width' => '82',
72
  's2w_height' => '16',
73
+ 's2w_font' => '11',
74
  );
75
  } else {
76
  $defaults = array(
77
+ 'title' => $options['title'],
78
+ 's2w_bg' => $options['s2w_bg'],
79
+ 's2w_fg' => $options['s2w_fg'],
80
+ 's2w_width' => $options['s2w_width'],
81
  's2w_height' => $options['s2w_height'],
82
+ 's2w_font' => $options['s2w_font'],
83
  );
84
  delete_option( 'widget_s2counter' );
85
  }
86
  $instance = wp_parse_args( (array) $instance, $defaults );
87
  // Be sure you format your options to be valid HTML attributes.
88
+ $s2w_title = htmlspecialchars( $instance['title'], ENT_QUOTES );
89
+ $s2w_bg = htmlspecialchars( $instance['s2w_bg'], ENT_QUOTES );
90
+ $s2w_fg = htmlspecialchars( $instance['s2w_fg'], ENT_QUOTES );
91
+ $s2w_width = htmlspecialchars( $instance['s2w_width'], ENT_QUOTES );
92
  $s2w_height = htmlspecialchars( $instance['s2w_height'], ENT_QUOTES );
93
+ $s2w_font = htmlspecialchars( $instance['s2w_font'], ENT_QUOTES );
94
  echo '<div>' . "\r\n";
95
  echo '<fieldset><legend><label for="' . esc_attr( $this->get_field_id( 'title' ) ) . '">' . esc_html__( 'Widget Title', 'subscribe2' ) . '</label></legend>' . "\r\n";
96
  echo '<input type="text" name="' . esc_attr( $this->get_field_name( 'title' ) ) . '" id="' . esc_attr( $this->get_field_id( 'title' ) ) . '" value="' . esc_attr( $s2w_title ) . '" />' . "\r\n";
117
  echo '</table></fieldset></div>' . "\r\n";
118
  }
119
  }// end S2_Counter_widget class
 
classes/class-s2-form-widget.php CHANGED
@@ -1,36 +1,37 @@
1
  <?php
2
  class S2_Form_Widget extends WP_Widget {
3
  /**
4
- Declares the Subscribe2 widget class.
5
- */
6
- function __construct() {
7
  $widget_ops = array(
8
- 'classname' => 's2_form_widget',
9
- 'description' => esc_html__( 'Sidebar Widget for Subscribe2', 'subscribe2' ),
10
  'customize_selective_refresh' => true,
11
  );
 
12
  $control_ops = array(
13
- 'width' => 250,
14
  'height' => 300,
15
  );
16
  parent::__construct( 's2_form_widget', esc_html__( 'Subscribe2 Widget', 'subscribe2' ), $widget_ops, $control_ops );
17
  }
18
 
19
  /**
20
- Displays the Widget
21
- */
22
- function widget( $args, $instance ) {
23
- $title = empty( $instance['title'] ) ? __( 'Subscribe2', 'subscribe2' ) : $instance['title'];
24
- $div = empty( $instance['div'] ) ? 'search' : $instance['div'];
25
- $widgetprecontent = empty( $instance['widgetprecontent'] ) ? '' : $instance['widgetprecontent'];
26
  $widgetpostcontent = empty( $instance['widgetpostcontent'] ) ? '' : $instance['widgetpostcontent'];
27
- $textbox_size = empty( $instance['size'] ) ? 20 : $instance['size'];
28
- $hidebutton = empty( $instance['hidebutton'] ) ? 'none' : $instance['hidebutton'];
29
- $postto = empty( $instance['postto'] ) ? '' : $instance['postto'];
30
- $js = empty( $instance['js'] ) ? '' : $instance['js'];
31
- $noantispam = empty( $instance['noantispam'] ) ? '' : $instance['noantispam'];
32
- $nowrap = empty( $instance['nowrap'] ) ? '' : $instance['nowrap'];
33
- $hide = '';
34
  if ( 'subscribe' === $hidebutton || 'unsubscribe' === $hidebutton ) {
35
  $hide = ' hide="' . $hidebutton . '"';
36
  } elseif ( 'link' === $hidebutton ) {
@@ -51,7 +52,7 @@ class S2_Form_Widget extends WP_Widget {
51
  if ( $nowrap ) {
52
  $nowrap = ' wrap="false"';
53
  }
54
- $shortcode = '[subscribe2' . $hide . $postid . $size . $nojs . $noantispam . $nowrap . ']';
55
  echo $args['before_widget'];
56
  if ( ! empty( $title ) ) {
57
  echo $args['before_title'] . esc_attr( $title ) . $args['after_title'];
@@ -70,71 +71,71 @@ class S2_Form_Widget extends WP_Widget {
70
  }
71
 
72
  /**
73
- Saves the widgets settings.
74
- */
75
- function update( $new_instance, $old_instance ) {
76
- $instance = $old_instance;
77
- $instance['title'] = strip_tags( stripslashes( $new_instance['title'] ) );
78
- $instance['div'] = strip_tags( stripslashes( $new_instance['div'] ) );
79
- $instance['widgetprecontent'] = stripslashes( $new_instance['widgetprecontent'] );
80
  $instance['widgetpostcontent'] = stripslashes( $new_instance['widgetpostcontent'] );
81
- $instance['size'] = intval( stripslashes( $new_instance['size'] ) );
82
- $instance['hidebutton'] = strip_tags( stripslashes( $new_instance['hidebutton'] ) );
83
- $instance['postto'] = stripslashes( $new_instance['postto'] );
84
- $instance['js'] = stripslashes( $new_instance['js'] );
85
- $instance['noantispam'] = stripslashes( $new_instance['noantispam'] );
86
- $instance['nowrap'] = stripslashes( $new_instance['nowrap'] );
87
 
88
  return $instance;
89
  }
90
 
91
  /**
92
- Creates the edit form for the widget.
93
- */
94
- function form( $instance ) {
95
  // set some defaults, getting any old options first
96
  $options = get_option( 'widget_subscribe2widget' );
97
  if ( false === $options ) {
98
  $defaults = array(
99
- 'title' => 'Subscribe2',
100
- 'div' => 'search',
101
- 'widgetprecontent' => '',
102
  'widgetpostcontent' => '',
103
- 'size' => 20,
104
- 'hidebutton' => 'none',
105
- 'postto' => '',
106
- 'js' => '',
107
- 'noantispam' => '',
108
- 'nowrap' => '',
109
  );
110
  } else {
111
  $defaults = array(
112
- 'title' => $options['title'],
113
- 'div' => $options['div'],
114
- 'widgetprecontent' => $options['widgetprecontent'],
115
  'widgetpostcontent' => $options['widgetpostcontent'],
116
- 'size' => $options['size'],
117
- 'hidebutton' => $options['hidebutton'],
118
- 'postto' => $options['postto'],
119
- 'js' => $options['js'],
120
- 'noantispam' => $options['noantispam'],
121
- 'nowrap' => $options['nowrap'],
122
  );
123
  delete_option( 'widget_subscribe2widget' );
124
  }
125
  // code to obtain old settings too
126
  $instance = wp_parse_args( (array) $instance, $defaults );
127
 
128
- $title = htmlspecialchars( $instance['title'], ENT_QUOTES );
129
- $div = htmlspecialchars( $instance['div'], ENT_QUOTES );
130
- $widgetprecontent = htmlspecialchars( $instance['widgetprecontent'], ENT_QUOTES );
131
  $widgetpostcontent = htmlspecialchars( $instance['widgetpostcontent'], ENT_QUOTES );
132
- $size = htmlspecialchars( $instance['size'], ENT_QUOTES );
133
- $hidebutton = htmlspecialchars( $instance['hidebutton'], ENT_QUOTES );
134
- $postto = htmlspecialchars( $instance['postto'], ENT_QUOTES );
135
- $js = htmlspecialchars( $instance['js'], ENT_QUOTES );
136
- $noantispam = htmlspecialchars( $instance['noantispam'], ENT_QUOTES );
137
- $nowrap = htmlspecialchars( $instance['nowrap'], ENT_QUOTES );
138
 
139
  global $wpdb, $mysubscribe2;
140
  $sql = "SELECT ID, post_title FROM $wpdb->posts WHERE post_type='page' AND post_status='publish'";
@@ -162,10 +163,14 @@ class S2_Form_Widget extends WP_Widget {
162
  echo '<select class="widefat" id="' . esc_attr( $this->get_field_id( 'postto' ) ) . '" name="' . esc_attr( $this->get_field_name( 'postto' ) ) . '">' . "\r\n";
163
  echo '<option value="' . esc_attr( $mysubscribe2->subscribe2_options['s2page'] ) . '">' . esc_html__( 'Use Subscribe2 Default', 'subscribe2' ) . '</option>' . "\r\n";
164
  echo '<option value="home"';
165
- if ( 'home' === $postto ) { echo ' selected="selected"'; }
 
 
166
  echo '>' . esc_html__( 'Use Home Page', 'subscribe2' ) . '</option>' . "\r\n";
167
  echo '<option value="self"';
168
- if ( 'self' === $postto ) { echo ' selected="selected"'; }
 
 
169
  echo '>' . esc_html__( 'Use Referring Page', 'subscribe2' ) . '</option>' . "\r\n";
170
  $mysubscribe2->pages_dropdown( $postto );
171
  echo '</select></label></p>' . "\r\n";
@@ -181,4 +186,3 @@ class S2_Form_Widget extends WP_Widget {
181
  echo '</div>' . "\r\n";
182
  }
183
  } // End S2_Form_widget class
184
- ?>
1
  <?php
2
  class S2_Form_Widget extends WP_Widget {
3
  /**
4
+ * Declares the Subscribe2 widget class.
5
+ */
6
+ public function __construct() {
7
  $widget_ops = array(
8
+ 'classname' => 's2_form_widget',
9
+ 'description' => esc_html__( 'Sidebar Widget for Subscribe2', 'subscribe2' ),
10
  'customize_selective_refresh' => true,
11
  );
12
+
13
  $control_ops = array(
14
+ 'width' => 250,
15
  'height' => 300,
16
  );
17
  parent::__construct( 's2_form_widget', esc_html__( 'Subscribe2 Widget', 'subscribe2' ), $widget_ops, $control_ops );
18
  }
19
 
20
  /**
21
+ * Displays the Widget
22
+ */
23
+ public function widget( $args, $instance ) {
24
+ $title = empty( $instance['title'] ) ? __( 'Subscribe2', 'subscribe2' ) : $instance['title'];
25
+ $div = empty( $instance['div'] ) ? 'search' : $instance['div'];
26
+ $widgetprecontent = empty( $instance['widgetprecontent'] ) ? '' : $instance['widgetprecontent'];
27
  $widgetpostcontent = empty( $instance['widgetpostcontent'] ) ? '' : $instance['widgetpostcontent'];
28
+ $textbox_size = empty( $instance['size'] ) ? 20 : $instance['size'];
29
+ $hidebutton = empty( $instance['hidebutton'] ) ? 'none' : $instance['hidebutton'];
30
+ $postto = empty( $instance['postto'] ) ? '' : $instance['postto'];
31
+ $js = empty( $instance['js'] ) ? '' : $instance['js'];
32
+ $noantispam = empty( $instance['noantispam'] ) ? '' : $instance['noantispam'];
33
+ $nowrap = empty( $instance['nowrap'] ) ? '' : $instance['nowrap'];
34
+ $hide = '';
35
  if ( 'subscribe' === $hidebutton || 'unsubscribe' === $hidebutton ) {
36
  $hide = ' hide="' . $hidebutton . '"';
37
  } elseif ( 'link' === $hidebutton ) {
52
  if ( $nowrap ) {
53
  $nowrap = ' wrap="false"';
54
  }
55
+ $shortcode = '[subscribe2' . $hide . $postid . $size . $nojs . $noantispam . $nowrap . ' widget="true"]';
56
  echo $args['before_widget'];
57
  if ( ! empty( $title ) ) {
58
  echo $args['before_title'] . esc_attr( $title ) . $args['after_title'];
71
  }
72
 
73
  /**
74
+ * Saves the widgets settings.
75
+ */
76
+ public function update( $new_instance, $old_instance ) {
77
+ $instance = $old_instance;
78
+ $instance['title'] = wp_strip_all_tags( stripslashes( $new_instance['title'] ) );
79
+ $instance['div'] = wp_strip_all_tags( stripslashes( $new_instance['div'] ) );
80
+ $instance['widgetprecontent'] = stripslashes( $new_instance['widgetprecontent'] );
81
  $instance['widgetpostcontent'] = stripslashes( $new_instance['widgetpostcontent'] );
82
+ $instance['size'] = intval( stripslashes( $new_instance['size'] ) );
83
+ $instance['hidebutton'] = wp_strip_all_tags( stripslashes( $new_instance['hidebutton'] ) );
84
+ $instance['postto'] = stripslashes( $new_instance['postto'] );
85
+ $instance['js'] = stripslashes( $new_instance['js'] );
86
+ $instance['noantispam'] = stripslashes( $new_instance['noantispam'] );
87
+ $instance['nowrap'] = stripslashes( $new_instance['nowrap'] );
88
 
89
  return $instance;
90
  }
91
 
92
  /**
93
+ * Creates the edit form for the widget.
94
+ */
95
+ public function form( $instance ) {
96
  // set some defaults, getting any old options first
97
  $options = get_option( 'widget_subscribe2widget' );
98
  if ( false === $options ) {
99
  $defaults = array(
100
+ 'title' => 'Subscribe2',
101
+ 'div' => 'search',
102
+ 'widgetprecontent' => '',
103
  'widgetpostcontent' => '',
104
+ 'size' => 20,
105
+ 'hidebutton' => 'none',
106
+ 'postto' => '',
107
+ 'js' => '',
108
+ 'noantispam' => '',
109
+ 'nowrap' => '',
110
  );
111
  } else {
112
  $defaults = array(
113
+ 'title' => $options['title'],
114
+ 'div' => $options['div'],
115
+ 'widgetprecontent' => $options['widgetprecontent'],
116
  'widgetpostcontent' => $options['widgetpostcontent'],
117
+ 'size' => $options['size'],
118
+ 'hidebutton' => $options['hidebutton'],
119
+ 'postto' => $options['postto'],
120
+ 'js' => $options['js'],
121
+ 'noantispam' => $options['noantispam'],
122
+ 'nowrap' => $options['nowrap'],
123
  );
124
  delete_option( 'widget_subscribe2widget' );
125
  }
126
  // code to obtain old settings too
127
  $instance = wp_parse_args( (array) $instance, $defaults );
128
 
129
+ $title = htmlspecialchars( $instance['title'], ENT_QUOTES );
130
+ $div = htmlspecialchars( $instance['div'], ENT_QUOTES );
131
+ $widgetprecontent = htmlspecialchars( $instance['widgetprecontent'], ENT_QUOTES );
132
  $widgetpostcontent = htmlspecialchars( $instance['widgetpostcontent'], ENT_QUOTES );
133
+ $size = htmlspecialchars( $instance['size'], ENT_QUOTES );
134
+ $hidebutton = htmlspecialchars( $instance['hidebutton'], ENT_QUOTES );
135
+ $postto = htmlspecialchars( $instance['postto'], ENT_QUOTES );
136
+ $js = htmlspecialchars( $instance['js'], ENT_QUOTES );
137
+ $noantispam = htmlspecialchars( $instance['noantispam'], ENT_QUOTES );
138
+ $nowrap = htmlspecialchars( $instance['nowrap'], ENT_QUOTES );
139
 
140
  global $wpdb, $mysubscribe2;
141
  $sql = "SELECT ID, post_title FROM $wpdb->posts WHERE post_type='page' AND post_status='publish'";
163
  echo '<select class="widefat" id="' . esc_attr( $this->get_field_id( 'postto' ) ) . '" name="' . esc_attr( $this->get_field_name( 'postto' ) ) . '">' . "\r\n";
164
  echo '<option value="' . esc_attr( $mysubscribe2->subscribe2_options['s2page'] ) . '">' . esc_html__( 'Use Subscribe2 Default', 'subscribe2' ) . '</option>' . "\r\n";
165
  echo '<option value="home"';
166
+ if ( 'home' === $postto ) {
167
+ echo ' selected="selected"';
168
+ }
169
  echo '>' . esc_html__( 'Use Home Page', 'subscribe2' ) . '</option>' . "\r\n";
170
  echo '<option value="self"';
171
+ if ( 'self' === $postto ) {
172
+ echo ' selected="selected"';
173
+ }
174
  echo '>' . esc_html__( 'Use Referring Page', 'subscribe2' ) . '</option>' . "\r\n";
175
  $mysubscribe2->pages_dropdown( $postto );
176
  echo '</select></label></p>' . "\r\n";
186
  echo '</div>' . "\r\n";
187
  }
188
  } // End S2_Form_widget class
 
classes/class-s2-forms.php CHANGED
@@ -1,31 +1,44 @@
1
  <?php
2
  class S2_Forms {
3
  /**
4
- Functions to Display content of Your Subscriptions page and process any input
5
- */
6
- function init() {
7
  add_action( 's2_subscription_submit', array( &$this, 's2_your_subscription_submit' ) );
8
  add_action( 's2_subscription_form', array( &$this, 's2_your_subscription_form' ), 10, 2 );
9
- } // end init()
10
 
11
  /**
12
- Return appropriate user ID if user can edit other users subscriptions
13
- */
14
- function get_userid() {
15
- global $user_ID;
16
- if ( current_user_can( apply_filters( 's2_capability', 'manage_options', 'manage' ) ) && isset( $_GET['id'] ) ) {
17
- $userid = (int) $_GET['id'];
 
 
 
 
 
 
 
 
 
 
18
  } else {
19
- $userid = $user_ID;
 
20
  }
21
  return $userid;
22
- } // end get_userid()
23
 
24
  /**
25
- Display the form to allow Regsitered users to amend their subscription
26
- */
27
- function s2_your_subscription_form( $userid ) {
28
- if ( ! is_int( $userid ) ) { return false; }
 
 
29
  global $mysubscribe2;
30
 
31
  echo '<input type="hidden" name="s2_admin" value="user" />';
@@ -99,14 +112,14 @@ class S2_Forms {
99
  echo '</div>' . "\r\n";
100
  }
101
 
102
- // list of subscribed blogs on wordpress mu
103
  if ( $mysubscribe2->s2_mu && ! isset( $_GET['email'] ) ) {
104
  global $blog_id, $current_user, $s2class_multisite;
105
- $s2blog_id = $blog_id;
106
  $current_user = wp_get_current_user();
107
- $blogs = $s2class_multisite->get_mu_blog_list();
108
 
109
- $blogs_subscribed = array();
110
  $blogs_notsubscribed = array();
111
 
112
  foreach ( $blogs as $blog ) {
@@ -131,8 +144,8 @@ class S2_Forms {
131
  } else {
132
  $blog['blogname'] = $blogname;
133
  }
134
- $blog['description'] = get_option( 'blogdescription' );
135
- $blog['blogurl'] = get_option( 'home' );
136
  $blog['subscribe_page'] = get_option( 'home' ) . '/wp-admin/admin.php?page=s2';
137
 
138
  $key = strtolower( $blog['blogname'] . '-' . $blog['blog_id'] );
@@ -188,12 +201,12 @@ class S2_Forms {
188
  }
189
  echo '</div>' . "\r\n";
190
  }
191
- } // end s2_your_subscription_form()
192
 
193
  /**
194
- Process input from the form that allows Regsitered users to amend their subscription
195
- */
196
- function s2_your_subscription_submit() {
197
  global $mysubscribe2, $user_ID;
198
 
199
  $userid = $this->get_userid();
@@ -229,7 +242,7 @@ class S2_Forms {
229
  } elseif ( 'digest' === $cats ) {
230
  $all_cats = $mysubscribe2->all_cats( false, 'ID' );
231
  foreach ( $all_cats as $cat ) {
232
- ('' === $catids) ? $catids = "$cat->term_id" : $catids .= ",$cat->term_id";
233
  update_user_meta( $userid, $mysubscribe2->get_usermeta_keyname( 's2_cat' ) . $cat->term_id, $cat->term_id );
234
  }
235
  update_user_meta( $userid, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), $catids );
@@ -239,8 +252,8 @@ class S2_Forms {
239
  }
240
  sort( $cats );
241
  $old_cats = explode( ',', get_user_meta( $userid, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), true ) );
242
- $remove = array_diff( $old_cats, $cats );
243
- $new = array_diff( $cats, $old_cats );
244
  if ( ! empty( $remove ) ) {
245
  // remove subscription to these cat IDs
246
  foreach ( $remove as $id ) {
@@ -270,13 +283,13 @@ class S2_Forms {
270
  }
271
 
272
  echo '<div id="message" class="updated fade"><p><strong>' . __( 'Subscription preferences updated.', 'subscribe2' ) . '</strong></p></div>' . "\r\n";
273
- } // end s2_your_subscription_submit()
274
 
275
  /**
276
- Display a table of categories with checkboxes
277
- Optionally pre-select those categories specified
278
- */
279
- function display_category_form( $selected = array(), $override = 1, $compulsory = array(), $name = 'category' ) {
280
  global $wpdb, $mysubscribe2;
281
 
282
  if ( 0 === $override ) {
@@ -285,9 +298,9 @@ class S2_Forms {
285
  $all_cats = $mysubscribe2->all_cats( false );
286
  }
287
 
288
- $half = (count( $all_cats ) / 2);
289
- $i = 0;
290
- $j = 0;
291
  echo '<table style="width: 100%; border-collapse: separate; border-spacing: 2px; *border-collapse: expression(\'separate\', cellSpacing = \'2px\');" class="editform">' . "\r\n";
292
  echo '<tr><td style="text-align: left;" colspan="2">' . "\r\n";
293
  echo '<label><input type="checkbox" name="checkall" value="checkall_' . $name . '" /> ' . __( 'Select / Unselect All', 'subscribe2' ) . '</label>' . "\r\n";
@@ -298,15 +311,15 @@ class S2_Forms {
298
  echo '</td><td style="width: 50%; text-align: left;">' . "\r\n";
299
  $j++;
300
  }
301
- $catName = '';
302
- $parents = array_reverse( get_ancestors( $cat->term_id, $cat->taxonomy ) );
303
  if ( $parents ) {
304
  foreach ( $parents as $parent ) {
305
- $parent = get_term( $parent, $cat->taxonomy );
306
- $catName .= $parent->name . ' &raquo; ';
307
  }
308
  }
309
- $catName .= $cat->name;
310
 
311
  if ( 0 === $j ) {
312
  echo '<label><input class="checkall_' . $name . '" type="checkbox" name="' . $name . '[]" value="' . $cat->term_id . '"';
@@ -316,7 +329,7 @@ class S2_Forms {
316
  if ( in_array( $cat->term_id, $compulsory ) && 'category' === $name ) {
317
  echo ' DISABLED';
318
  }
319
- echo ' /> <abbr title="' . $cat->slug . '">' . $catName . '</abbr></label><br />' . "\r\n";
320
  } else {
321
  echo '<label><input class="checkall_' . $name . '" type="checkbox" name="' . $name . '[]" value="' . $cat->term_id . '"';
322
  if ( in_array( $cat->term_id, $selected ) || in_array( $cat->term_id, $compulsory ) ) {
@@ -325,7 +338,7 @@ class S2_Forms {
325
  if ( in_array( $cat->term_id, $compulsory ) && 'category' === $name ) {
326
  echo ' DISABLED';
327
  }
328
- echo ' /> <abbr title="' . $cat->slug . '">' . $catName . '</abbr></label><br />' . "\r\n";
329
  }
330
  $i++;
331
  }
@@ -336,18 +349,18 @@ class S2_Forms {
336
  }
337
  echo '</td></tr>' . "\r\n";
338
  echo '</table>' . "\r\n";
339
- } // end display_category_form()
340
 
341
  /**
342
- Display a table of authors with checkboxes
343
- Optionally pre-select those authors specified
344
- */
345
- function display_author_form( $selected = array() ) {
346
  $all_authors = $this->get_authors();
347
 
348
- $half = (count( $all_authors ) / 2);
349
- $i = 0;
350
- $j = 0;
351
  echo '<table style="width: 100%; border-collapse: separate; border-spacing: 2px; *border-collapse: expression(\'separate\', cellSpacing = \'2px\');" class="editform">' . "\r\n";
352
  echo '<tr><td style="text-align: left;" colspan="2">' . "\r\n";
353
  echo '<label><input type="checkbox" name="checkall" value="checkall_author" /> ' . __( 'Select / Unselect All', 'subscribe2' ) . '</label>' . "\r\n";
@@ -375,36 +388,41 @@ class S2_Forms {
375
  }
376
  echo '</td></tr>' . "\r\n";
377
  echo '</table>' . "\r\n";
378
- } // end display_author_form()
379
 
380
  /**
381
- Collect an array of all author level users and above
382
- */
383
- function get_authors() {
384
  if ( '' === $this->all_authors ) {
385
  $role = array(
386
  'fields' => array( 'ID', 'display_name' ),
387
- 'role' => 'administrator',
388
  );
 
389
  $administrators = get_users( $role );
 
390
  $role = array(
391
  'fields' => array( 'ID', 'display_name' ),
392
- 'role' => 'editor',
393
  );
 
394
  $editors = get_users( $role );
 
395
  $role = array(
396
  'fields' => array( 'ID', 'display_name' ),
397
- 'role' => 'author',
398
  );
 
399
  $authors = get_users( $role );
400
 
401
  $this->all_authors = array_merge( $administrators, $editors, $authors );
402
  }
403
  return apply_filters( 's2_authors', $this->all_authors );
404
- } // end get_authors()
405
 
406
- /* ===== our variables ===== */
407
- // cache variables
408
- var $all_authors = '';
 
409
  }
410
- ?>
1
  <?php
2
  class S2_Forms {
3
  /**
4
+ * Functions to Display content of Your Subscriptions page and process any input
5
+ */
6
+ public function init() {
7
  add_action( 's2_subscription_submit', array( &$this, 's2_your_subscription_submit' ) );
8
  add_action( 's2_subscription_form', array( &$this, 's2_your_subscription_form' ), 10, 2 );
9
+ }
10
 
11
  /**
12
+ * Return appropriate user ID if user can edit other users subscriptions
13
+ */
14
+ public function get_userid() {
15
+ if ( isset( $_GET['id'] ) ) {
16
+ if ( ! current_user_can( apply_filters( 's2_capability', 'manage_options', 'manage' ) ) ) {
17
+ die( '<p>' . __( 'Permission error! Your request cannot be completed.', 'subscribe2' ) . '</p>' );
18
+ }
19
+ if ( is_multisite() ) {
20
+ if ( ! is_user_member_of_blog( $_GET['id'], get_current_blog_id() ) ) {
21
+ die( '<p>' . __( 'Permission error! Your request cannot be completed.', 'subscribe2' ) . '</p>' );
22
+ } else {
23
+ $userid = (int) $_GET['id'];
24
+ }
25
+ } else {
26
+ $userid = (int) $_GET['id'];
27
+ }
28
  } else {
29
+ global $user_ID;
30
+ return $user_ID;
31
  }
32
  return $userid;
33
+ }
34
 
35
  /**
36
+ * Display the form to allow Regsitered users to amend their subscription
37
+ */
38
+ public function s2_your_subscription_form( $userid ) {
39
+ if ( ! is_int( $userid ) ) {
40
+ return false;
41
+ }
42
  global $mysubscribe2;
43
 
44
  echo '<input type="hidden" name="s2_admin" value="user" />';
112
  echo '</div>' . "\r\n";
113
  }
114
 
115
+ // list of subscribed blogs on WordPress mu
116
  if ( $mysubscribe2->s2_mu && ! isset( $_GET['email'] ) ) {
117
  global $blog_id, $current_user, $s2class_multisite;
118
+ $s2blog_id = $blog_id;
119
  $current_user = wp_get_current_user();
120
+ $blogs = $s2class_multisite->get_mu_blog_list();
121
 
122
+ $blogs_subscribed = array();
123
  $blogs_notsubscribed = array();
124
 
125
  foreach ( $blogs as $blog ) {
144
  } else {
145
  $blog['blogname'] = $blogname;
146
  }
147
+ $blog['description'] = get_option( 'blogdescription' );
148
+ $blog['blogurl'] = get_option( 'home' );
149
  $blog['subscribe_page'] = get_option( 'home' ) . '/wp-admin/admin.php?page=s2';
150
 
151
  $key = strtolower( $blog['blogname'] . '-' . $blog['blog_id'] );
201
  }
202
  echo '</div>' . "\r\n";
203
  }
204
+ }
205
 
206
  /**
207
+ * Process input from the form that allows Regsitered users to amend their subscription
208
+ */
209
+ public function s2_your_subscription_submit() {
210
  global $mysubscribe2, $user_ID;
211
 
212
  $userid = $this->get_userid();
242
  } elseif ( 'digest' === $cats ) {
243
  $all_cats = $mysubscribe2->all_cats( false, 'ID' );
244
  foreach ( $all_cats as $cat ) {
245
+ ( '' === $catids ) ? $catids = "$cat->term_id" : $catids .= ",$cat->term_id";
246
  update_user_meta( $userid, $mysubscribe2->get_usermeta_keyname( 's2_cat' ) . $cat->term_id, $cat->term_id );
247
  }
248
  update_user_meta( $userid, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), $catids );
252
  }
253
  sort( $cats );
254
  $old_cats = explode( ',', get_user_meta( $userid, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), true ) );
255
+ $remove = array_diff( $old_cats, $cats );
256
+ $new = array_diff( $cats, $old_cats );
257
  if ( ! empty( $remove ) ) {
258
  // remove subscription to these cat IDs
259
  foreach ( $remove as $id ) {
283
  }
284
 
285
  echo '<div id="message" class="updated fade"><p><strong>' . __( 'Subscription preferences updated.', 'subscribe2' ) . '</strong></p></div>' . "\r\n";
286
+ }
287
 
288
  /**
289
+ * Display a table of categories with checkboxes
290
+ * Optionally pre-select those categories specified
291
+ */
292
+ public function display_category_form( $selected = array(), $override = 1, $compulsory = array(), $name = 'category' ) {
293
  global $wpdb, $mysubscribe2;
294
 
295
  if ( 0 === $override ) {
298
  $all_cats = $mysubscribe2->all_cats( false );
299
  }
300
 
301
+ $half = ( count( $all_cats ) / 2 );
302
+ $i = 0;
303
+ $j = 0;
304
  echo '<table style="width: 100%; border-collapse: separate; border-spacing: 2px; *border-collapse: expression(\'separate\', cellSpacing = \'2px\');" class="editform">' . "\r\n";
305
  echo '<tr><td style="text-align: left;" colspan="2">' . "\r\n";
306
  echo '<label><input type="checkbox" name="checkall" value="checkall_' . $name . '" /> ' . __( 'Select / Unselect All', 'subscribe2' ) . '</label>' . "\r\n";
311
  echo '</td><td style="width: 50%; text-align: left;">' . "\r\n";
312
  $j++;
313
  }
314
+ $cat_name = '';
315
+ $parents = array_reverse( get_ancestors( $cat->term_id, $cat->taxonomy ) );
316
  if ( $parents ) {
317
  foreach ( $parents as $parent ) {
318
+ $parent = get_term( $parent, $cat->taxonomy );
319
+ $cat_name .= $parent->name . ' &raquo; ';
320
  }
321
  }
322
+ $cat_name .= $cat->name;
323
 
324
  if ( 0 === $j ) {
325
  echo '<label><input class="checkall_' . $name . '" type="checkbox" name="' . $name . '[]" value="' . $cat->term_id . '"';
329
  if ( in_array( $cat->term_id, $compulsory ) && 'category' === $name ) {
330
  echo ' DISABLED';
331
  }
332
+ echo ' /> <abbr title="' . $cat->slug . '">' . $cat_name . '</abbr></label><br />' . "\r\n";
333
  } else {
334
  echo '<label><input class="checkall_' . $name . '" type="checkbox" name="' . $name . '[]" value="' . $cat->term_id . '"';
335
  if ( in_array( $cat->term_id, $selected ) || in_array( $cat->term_id, $compulsory ) ) {
338
  if ( in_array( $cat->term_id, $compulsory ) && 'category' === $name ) {
339
  echo ' DISABLED';
340
  }
341
+ echo ' /> <abbr title="' . $cat->slug . '">' . $cat_name . '</abbr></label><br />' . "\r\n";
342
  }
343
  $i++;
344
  }
349
  }
350
  echo '</td></tr>' . "\r\n";
351
  echo '</table>' . "\r\n";
352
+ }
353
 
354
  /**
355
+ * Display a table of authors with checkboxes
356
+ * Optionally pre-select those authors specified
357
+ */
358
+ public function display_author_form( $selected = array() ) {
359
  $all_authors = $this->get_authors();
360
 
361
+ $half = ( count( $all_authors ) / 2 );
362
+ $i = 0;
363
+ $j = 0;
364
  echo '<table style="width: 100%; border-collapse: separate; border-spacing: 2px; *border-collapse: expression(\'separate\', cellSpacing = \'2px\');" class="editform">' . "\r\n";
365
  echo '<tr><td style="text-align: left;" colspan="2">' . "\r\n";
366
  echo '<label><input type="checkbox" name="checkall" value="checkall_author" /> ' . __( 'Select / Unselect All', 'subscribe2' ) . '</label>' . "\r\n";
388
  }
389
  echo '</td></tr>' . "\r\n";
390
  echo '</table>' . "\r\n";
391
+ }
392
 
393
  /**
394
+ * Collect an array of all author level users and above
395
+ */
396
+ public function get_authors() {
397
  if ( '' === $this->all_authors ) {
398
  $role = array(
399
  'fields' => array( 'ID', 'display_name' ),
400
+ 'role' => 'administrator',
401
  );
402
+
403
  $administrators = get_users( $role );
404
+
405
  $role = array(
406
  'fields' => array( 'ID', 'display_name' ),
407
+ 'role' => 'editor',
408
  );
409
+
410
  $editors = get_users( $role );
411
+
412
  $role = array(
413
  'fields' => array( 'ID', 'display_name' ),
414
+ 'role' => 'author',
415
  );
416
+
417
  $authors = get_users( $role );
418
 
419
  $this->all_authors = array_merge( $administrators, $editors, $authors );
420
  }
421
  return apply_filters( 's2_authors', $this->all_authors );
422
+ }
423
 
424
+ /**
425
+ * Define some variables
426
+ */
427
+ private $all_authors = '';
428
  }
 
classes/class-s2-frontend.php CHANGED
@@ -1,12 +1,14 @@
1
  <?php
2
  class S2_Frontend extends S2_Core {
3
  /**
4
- Load all our strings
5
- */
6
- function load_strings() {
 
7
  $this->please_log_in = '<p class="s2_message">' . sprintf( __( 'To manage your subscription options please <a href="%1$s">login.</a>', 'subscribe2' ), get_option( 'siteurl' ) . '/wp-login.php' ) . '</p>';
8
 
9
  $profile = apply_filters( 's2_profile_link', get_option( 'siteurl' ) . '/wp-admin/admin.php?page=s2' );
 
10
  $this->profile = '<p class="s2_message">' . sprintf( __( 'You may manage your subscription options from your <a href="%1$s">profile</a>', 'subscribe2' ), $profile ) . '</p>';
11
  if ( true === $this->s2_mu ) {
12
  global $blog_id;
@@ -14,6 +16,7 @@ class S2_Frontend extends S2_Core {
14
  if ( ! is_user_member_of_blog( $user_ID, $blog_id ) ) {
15
  // if we are on multisite and the user is not a member of this blog change the link
16
  $mu_profile = apply_filters( 's2_mu_profile_link', get_option( 'siteurl' ) . '/wp-admin/?s2mu_subscribe=' . $blog_id );
 
17
  $this->profile = '<p class="s2_message">' . sprintf( __( '<a href="%1$s">Subscribe</a> to email notifications when this blog posts new content.', 'subscribe2' ), $mu_profile ) . '</p>';
18
  }
19
  }
@@ -40,22 +43,26 @@ class S2_Frontend extends S2_Core {
40
  $this->subscribe = __( 'subscribe', 'subscribe2' ); //ACTION replacement in subscribing confirmation email
41
 
42
  $this->unsubscribe = __( 'unsubscribe', 'subscribe2' ); //ACTION replacement in unsubscribing in confirmation email
43
- } // end load_strings()
44
 
45
  /* ===== template and filter functions ===== */
46
  /**
47
- Display our form; also handles (un)subscribe requests
48
- */
49
- function shortcode( $atts ) {
50
- $args = shortcode_atts( array(
51
- 'hide' => '',
52
- 'id' => '',
53
- 'nojs' => 'false',
54
- 'noantispam' => 'false',
55
- 'link' => '',
56
- 'size' => 20,
57
- 'wrap' => 'true',
58
- ), $atts );
 
 
 
 
59
 
60
  // if link is true return a link to the page with the ajax class
61
  if ( '1' === $this->subscribe2_options['ajax'] && '' !== $args['link'] && ! is_user_logged_in() ) {
@@ -74,7 +81,7 @@ class S2_Frontend extends S2_Core {
74
 
75
  // Apply filters to button text
76
  $unsubscribe_button_value = apply_filters( 's2_unsubscribe_button', __( 'Unsubscribe', 'subscribe2' ) );
77
- $subscribe_button_value = apply_filters( 's2_subscribe_button', __( 'Subscribe', 'subscribe2' ) );
78
 
79
  // if a button is hidden, show only other
80
  $hide = strtolower( $args['hide'] );
@@ -96,7 +103,7 @@ class S2_Frontend extends S2_Core {
96
  } elseif ( 'self' === $args['id'] ) {
97
  // Correct for Static front page redirect behaviour
98
  if ( 'page' === get_option( 'show_on_front' ) && is_front_page() ) {
99
- $post = get_post( get_option( 'page_on_front' ) );
100
  $action = ' action="' . get_option( 'home' ) . '/' . $post->post_name . '/"';
101
  } else {
102
  $action = '';
@@ -106,8 +113,11 @@ class S2_Frontend extends S2_Core {
106
  }
107
 
108
  // allow remote setting of email in form
109
- if ( isset( $_REQUEST['email'] ) && is_email( $_REQUEST['email'] ) ) {
110
- $value = $this->sanitize_email( $_REQUEST['email'] );
 
 
 
111
  } elseif ( 'true' === strtolower( $args['nojs'] ) ) {
112
  $value = '';
113
  } else {
@@ -123,7 +133,7 @@ class S2_Frontend extends S2_Core {
123
  // deploy some anti-spam measures
124
  $antispam_text = '';
125
  if ( 'true' !== strtolower( $args['noantispam'] ) ) {
126
- $antispam_text = '<span style="display:none !important">';
127
  $antispam_text .= '<label for="firstname">Leave This Blank:</label><input type="text" id="firstname" name="firstname" />';
128
  $antispam_text .= '<label for="lastname">Leave This Blank Too:</label><input type="text" id="lastname" name="lastname" />';
129
  $antispam_text .= '<label for="uri">Do Not Change This:</label><input type="text" id="uri" name="uri" value="http://" />';
@@ -133,17 +143,29 @@ class S2_Frontend extends S2_Core {
133
  // get remote IP address
134
  $remote_ip = $this->get_remote_ip();
135
 
 
 
 
 
 
 
 
136
  // build default form
137
  if ( 'true' === strtolower( $args['nojs'] ) ) {
138
- $this->form = '<form name="s2form" method="post"' . $action . '><input type="hidden" name="ip" value="' . esc_html( $_SERVER['REMOTE_ADDR'] ) . '" />' . $antispam_text . '<p><label for="s2email">' . __( 'Your email:', 'subscribe2' ) . '</label><br /><input type="text" name="email" id="s2email" value="' . $value . '" size="' . $args['size'] . '" />' . $wrap_text . $this->input_form_action . '</p></form>';
139
  } else {
140
- $this->form = '<form name="s2form" method="post"' . $action . '><input type="hidden" name="ip" value="' . esc_html( $_SERVER['REMOTE_ADDR'] ) . '" />' . $antispam_text . '<p><label for="s2email">' . __( 'Your email:', 'subscribe2' ) . '</label><br /><input type="text" name="email" id="s2email" value="' . $value . '" size="' . $args['size'] . '" onfocus="if (this.value === \'' . $value . '\') {this.value = \'\';}" onblur="if (this.value === \'\') {this.value = \'' . $value . '\';}" />' . $wrap_text . $this->input_form_action . '</p></form>' . "\r\n";
141
  }
142
- $this->s2form = apply_filters( 's2_form', $this->form );
143
 
144
  global $user_ID;
145
- if ( $user_ID ) {
146
- $this->s2form = $this->profile;
 
 
 
 
 
147
  }
148
 
149
  if ( isset( $_POST['subscribe'] ) || isset( $_POST['unsubscribe'] ) ) {
@@ -152,9 +174,13 @@ class S2_Frontend extends S2_Core {
152
  // looks like some invisible-to-user fields were changed; falsely report success
153
  return $this->confirmation_sent;
154
  }
 
 
 
 
155
  global $wpdb;
156
  $this->email = $this->sanitize_email( $_POST['email'] );
157
- if ( ! is_email( $this->email ) ) {
158
  $this->s2form = $this->s2form . $this->not_an_email;
159
  } elseif ( $this->is_barred( $this->email ) ) {
160
  $this->s2form = $this->s2form . $this->barred_domain;
@@ -162,7 +188,7 @@ class S2_Frontend extends S2_Core {
162
  $this->ip = $_POST['ip'];
163
  if ( is_int( $this->lockout ) && $this->lockout > 0 ) {
164
  $date = date( 'H:i:s.u', $this->lockout );
165
- $ips = $wpdb->get_col( $wpdb->prepare( "SELECT ip FROM $this->public WHERE date = CURDATE() AND time > SUBTIME(CURTIME(), %s)", $date ) );
166
  if ( in_array( $this->ip, $ips ) ) {
167
  return __( 'Slow down, you move too fast.', 'subscribe2' );
168
  }
@@ -214,25 +240,29 @@ class S2_Frontend extends S2_Core {
214
  }
215
  }
216
  return $this->s2form;
217
- } // end shortcode()
218
 
219
  /**
220
- Display form when deprecated <!--subscribe2--> is used
221
- */
222
- function filter( $content = '' ) {
223
- if ( '' === $content || ! strstr( $content, '<!--subscribe2-->' ) ) { return $content; }
 
 
224
 
225
- return preg_replace( '/(<p>)?(\n)*<!--subscribe2-->(\n)*(</p>)?/', do_shortcode( '[subscribe2]' ), $content );
226
- } // end filter()
227
 
228
  /**
229
- Overrides the default query when handling a (un)subscription confirmation
230
- This is basically a trick: if the s2 variable is in the query string, just grab the first
231
- static page and override it's contents later with title_filter()
232
- */
233
- function query_filter() {
234
  // don't interfere if we've already done our thing
235
- if ( 1 === $this->filtered ) { return; }
 
 
236
 
237
  global $wpdb;
238
 
@@ -258,14 +288,14 @@ class S2_Frontend extends S2_Core {
258
  );
259
  }
260
  }
261
- } // end query_filter()
262
 
263
  /**
264
- Overrides the page title
265
- */
266
- function title_filter( $title ) {
267
  if ( in_the_loop() ) {
268
- $code = $_GET['s2'];
269
  $action = intval( substr( $code, 0, 1 ) );
270
  if ( 1 === $action ) {
271
  return __( 'Subscription Confirmation', 'subscribe2' );
@@ -275,12 +305,12 @@ class S2_Frontend extends S2_Core {
275
  } else {
276
  return $title;
277
  }
278
- } // end title_filter()
279
 
280
  /**
281
- Confirm request from the link emailed to the user and email the admin
282
- */
283
- function confirm( $content = '' ) {
284
  global $wpdb;
285
 
286
  if ( 1 === $this->filtered && '' !== $this->message ) {
@@ -289,10 +319,10 @@ class S2_Frontend extends S2_Core {
289
  return $content;
290
  }
291
 
292
- $code = $_GET['s2'];
293
  $action = substr( $code, 0, 1 );
294
- $hash = substr( $code, 1, 32 );
295
- $id = intval( substr( $code, 33 ) );
296
  if ( $id ) {
297
  $this->email = $this->sanitize_email( $this->get_email( $id ) );
298
  if ( ! $this->email || wp_hash( $this->email ) !== $hash ) {
@@ -331,12 +361,12 @@ class S2_Frontend extends S2_Core {
331
  if ( '' !== $this->message ) {
332
  return $this->message;
333
  }
334
- } // end confirm()
335
 
336
  /**
337
- Prepare and send emails to admins on new subscriptions and unsubsriptions
338
- */
339
- function admin_email( $action ) {
340
  if ( ! in_array( $action, array( 'subscribe', 'unsubscribe' ) ) ) {
341
  return false;
342
  }
@@ -344,51 +374,57 @@ class S2_Frontend extends S2_Core {
344
  ( '' === get_option( 'blogname' ) ) ? $subject = '' : $subject = '[' . stripslashes( html_entity_decode( get_option( 'blogname' ), ENT_QUOTES ) ) . '] ';
345
  if ( 'subscribe' === $action ) {
346
  $subject .= __( 'New Subscription', 'subscribe2' );
347
- $message = $this->email . ' ' . __( 'subscribed to email notifications!', 'subscribe2' );
348
  } elseif ( 'unsubscribe' === $action ) {
349
  $subject .= __( 'New Unsubscription', 'subscribe2' );
350
- $message = $this->email . ' ' . __( 'unsubscribed from email notifications!', 'subscribe2' );
351
  }
 
352
  $subject = html_entity_decode( $subject, ENT_QUOTES );
353
- $role = array(
354
  'fields' => array(
355
  'user_email',
356
  ),
357
- 'role' => 'administrator',
358
  );
 
359
  $wp_user_query = get_users( $role );
360
  foreach ( $wp_user_query as $user ) {
361
  $recipients[] = $user->user_email;
362
  }
 
363
  $recipients = apply_filters( 's2_admin_email', $recipients, $action );
364
- $headers = $this->headers();
365
  // send individual emails so we don't reveal admin emails to each other
366
  foreach ( $recipients as $recipient ) {
367
- @wp_mail( $recipient, $subject, $message, $headers );
368
  }
369
- } // end admin_email()
370
 
371
  /**
372
- Add hook for Minimeta Widget plugin
373
- */
374
- function add_minimeta() {
375
  if ( 0 !== $this->subscribe2_options['s2page'] ) {
376
  echo '<li><a href="' . get_permalink( $this->subscribe2_options['s2page'] ) . '">' . __( '[Un]Subscribe to Posts', 'subscribe2' ) . '</a></li>' . "\r\n";
377
  }
378
- } // end add_minimeta()
379
 
380
  /**
381
- Check email is not from a barred domain
382
- */
383
- function is_barred( $email = '' ) {
384
- if ( '' === $email ) { return false; }
 
 
385
 
386
  list( $user, $domain ) = explode( '@', $email, 2 );
 
387
  $domain = '@' . $domain;
 
388
  foreach ( preg_split( '/[\s,]+/', $this->subscribe2_options['barred'] ) as $barred_domain ) {
389
- if ( false !== strpos( $barred_domain, '*' ) ) {
390
- // wildcard domain checking
391
- $url = explode( '.', $barred_domain );
392
  $count = count( $url );
393
  // make sure our exploded domain has at least 2 components e.g. yahoo.*
394
  if ( $count < 2 ) {
@@ -399,7 +435,36 @@ class S2_Frontend extends S2_Core {
399
  unset( $url[ $i ] );
400
  }
401
  }
 
402
  $new_barred_domain = '@' . strtolower( trim( implode( '.', $url ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
  $new_barred_subdomain = '.' . strtolower( trim( implode( '.', $url ) ) );
404
 
405
  if ( false !== stripos( $domain, $new_barred_domain ) || false !== stripos( $domain, $new_barred_subdomain ) ) {
@@ -413,13 +478,14 @@ class S2_Frontend extends S2_Core {
413
  }
414
  }
415
  }
 
416
  return false;
417
- } // end is_barred()
418
 
419
  /**
420
- Collect and return the IP address of the remote client machine
421
- */
422
- function get_remote_ip() {
423
  $remote_ip = false;
424
 
425
  // In order of preference, with the best ones for this purpose first
@@ -439,27 +505,29 @@ class S2_Frontend extends S2_Core {
439
  // addresses. The first one is the original client. It can't be
440
  // trusted for authenticity, but we don't need to for this purpose.
441
  $address_chain = explode( ',', $_SERVER[ $header ] );
442
- $remote_ip = trim( $address_chain[0] );
443
  break;
444
  }
445
  }
446
 
447
  return $remote_ip;
448
- } // end get_remote_ip()
449
 
450
- /*
451
- Enqueue javascript ip updater code
452
- */
453
- function js_ip_script() {
454
- wp_register_script( 's2_ip_updater', S2URL . 'include/s2-ip-updater' . $this->script_debug . '.js', array(), '1.0', true );
455
  wp_enqueue_script( 's2_ip_updater' );
456
- } // end js_ip_script()
457
-
458
- /*
459
- Add ip updater library to footer
460
- */
461
- function js_ip_library_script() {
462
- echo '<script type="application/javascript" src="https://api.ipify.org?format=jsonp&callback=getip"></script>' . "\r\n";
463
- } // end js_ip_library_script()
 
 
 
464
  }
465
- ?>
1
  <?php
2
  class S2_Frontend extends S2_Core {
3
  /**
4
+ * Load all our strings
5
+ */
6
+ public function load_strings() {
7
+ // Translators: Link to login page
8
  $this->please_log_in = '<p class="s2_message">' . sprintf( __( 'To manage your subscription options please <a href="%1$s">login.</a>', 'subscribe2' ), get_option( 'siteurl' ) . '/wp-login.php' ) . '</p>';
9
 
10
  $profile = apply_filters( 's2_profile_link', get_option( 'siteurl' ) . '/wp-admin/admin.php?page=s2' );
11
+ // Translators: Link to Profile page
12
  $this->profile = '<p class="s2_message">' . sprintf( __( 'You may manage your subscription options from your <a href="%1$s">profile</a>', 'subscribe2' ), $profile ) . '</p>';
13
  if ( true === $this->s2_mu ) {
14
  global $blog_id;
16
  if ( ! is_user_member_of_blog( $user_ID, $blog_id ) ) {
17
  // if we are on multisite and the user is not a member of this blog change the link
18
  $mu_profile = apply_filters( 's2_mu_profile_link', get_option( 'siteurl' ) . '/wp-admin/?s2mu_subscribe=' . $blog_id );
19
+ // Translators: Link to Profile page
20
  $this->profile = '<p class="s2_message">' . sprintf( __( '<a href="%1$s">Subscribe</a> to email notifications when this blog posts new content.', 'subscribe2' ), $mu_profile ) . '</p>';
21
  }
22
  }
43
  $this->subscribe = __( 'subscribe', 'subscribe2' ); //ACTION replacement in subscribing confirmation email
44
 
45
  $this->unsubscribe = __( 'unsubscribe', 'subscribe2' ); //ACTION replacement in unsubscribing in confirmation email
46
+ }
47
 
48
  /* ===== template and filter functions ===== */
49
  /**
50
+ * Display our form; also handles (un)subscribe requests
51
+ */
52
+ public function shortcode( $atts ) {
53
+ $args = shortcode_atts(
54
+ array(
55
+ 'hide' => '',
56
+ 'id' => '',
57
+ 'nojs' => 'false',
58
+ 'noantispam' => 'false',
59
+ 'link' => '',
60
+ 'size' => 20,
61
+ 'wrap' => 'true',
62
+ 'widget' => 'false',
63
+ ),
64
+ $atts
65
+ );
66
 
67
  // if link is true return a link to the page with the ajax class
68
  if ( '1' === $this->subscribe2_options['ajax'] && '' !== $args['link'] && ! is_user_logged_in() ) {
81
 
82
  // Apply filters to button text
83
  $unsubscribe_button_value = apply_filters( 's2_unsubscribe_button', __( 'Unsubscribe', 'subscribe2' ) );
84
+ $subscribe_button_value = apply_filters( 's2_subscribe_button', __( 'Subscribe', 'subscribe2' ) );
85
 
86
  // if a button is hidden, show only other
87
  $hide = strtolower( $args['hide'] );
103
  } elseif ( 'self' === $args['id'] ) {
104
  // Correct for Static front page redirect behaviour
105
  if ( 'page' === get_option( 'show_on_front' ) && is_front_page() ) {
106
+ $post = get_post( get_option( 'page_on_front' ) );
107
  $action = ' action="' . get_option( 'home' ) . '/' . $post->post_name . '/"';
108
  } else {
109
  $action = '';
113
  }
114
 
115
  // allow remote setting of email in form
116
+ if ( isset( $_REQUEST['email'] ) ) {
117
+ $email = $this->sanitize_email( $_REQUEST['email'] );
118
+ }
119
+ if ( isset( $_REQUEST['email'] ) && false !== $this->validate_email( $email ) ) {
120
+ $value = $email;
121
  } elseif ( 'true' === strtolower( $args['nojs'] ) ) {
122
  $value = '';
123
  } else {
133
  // deploy some anti-spam measures
134
  $antispam_text = '';
135
  if ( 'true' !== strtolower( $args['noantispam'] ) ) {
136
+ $antispam_text = '<span style="display:none !important">';
137
  $antispam_text .= '<label for="firstname">Leave This Blank:</label><input type="text" id="firstname" name="firstname" />';
138
  $antispam_text .= '<label for="lastname">Leave This Blank Too:</label><input type="text" id="lastname" name="lastname" />';
139
  $antispam_text .= '<label for="uri">Do Not Change This:</label><input type="text" id="uri" name="uri" value="http://" />';
143
  // get remote IP address
144
  $remote_ip = $this->get_remote_ip();
145
 
146
+ // form name
147
+ if ( 'true' === $args['widget'] ) {
148
+ $form_name = 's2formwidget';
149
+ } else {
150
+ $form_name = 's2form';
151
+ }
152
+
153
  // build default form
154
  if ( 'true' === strtolower( $args['nojs'] ) ) {
155
+ $this->form = '<form name="' . $form_name . '" method="post"' . $action . '><input type="hidden" name="ip" value="' . esc_html( $_SERVER['REMOTE_ADDR'] ) . '" />' . $antispam_text . '<p><label for="s2email">' . __( 'Your email:', 'subscribe2' ) . '</label><br /><input type="email" name="email" id="s2email" value="' . $value . '" size="' . $args['size'] . '" />' . $wrap_text . $this->input_form_action . '</p></form>';
156
  } else {
157
+ $this->form = '<form name="' . $form_name . '" method="post"' . $action . '><input type="hidden" name="ip" value="' . esc_html( $_SERVER['REMOTE_ADDR'] ) . '" />' . $antispam_text . '<p><label for="s2email">' . __( 'Your email:', 'subscribe2' ) . '</label><br /><input type="email" name="email" id="s2email" value="' . $value . '" size="' . $args['size'] . '" onfocus="if (this.value === \'' . $value . '\') {this.value = \'\';}" onblur="if (this.value === \'\') {this.value = \'' . $value . '\';}" />' . $wrap_text . $this->input_form_action . '</p></form>' . "\r\n";
158
  }
159
+ $this->s2form = apply_filters( 's2_form', $this->form, $args );
160
 
161
  global $user_ID;
162
+ if ( 0 !== $user_ID ) {
163
+ if ( in_the_loop() && '1' === $this->subscribe2_options['frontend_form'] ) {
164
+ global $s2_frontend_form;
165
+ return $s2_frontend_form->frontend_form( $this->profile );
166
+ } else {
167
+ return $this->profile;
168
+ }
169
  }
170
 
171
  if ( isset( $_POST['subscribe'] ) || isset( $_POST['unsubscribe'] ) ) {
174
  // looks like some invisible-to-user fields were changed; falsely report success
175
  return $this->confirmation_sent;
176
  }
177
+ $validation = apply_filters( 's2_form_submission', true );
178
+ if ( true !== $validation ) {
179
+ return apply_filters( 's2_form_failed_validation', $this->s2form );
180
+ }
181
  global $wpdb;
182
  $this->email = $this->sanitize_email( $_POST['email'] );
183
+ if ( false === $this->validate_email( $this->email ) ) {
184
  $this->s2form = $this->s2form . $this->not_an_email;
185
  } elseif ( $this->is_barred( $this->email ) ) {
186
  $this->s2form = $this->s2form . $this->barred_domain;
188
  $this->ip = $_POST['ip'];
189
  if ( is_int( $this->lockout ) && $this->lockout > 0 ) {
190
  $date = date( 'H:i:s.u', $this->lockout );
191
+ $ips = $wpdb->get_col( $wpdb->prepare( "SELECT ip FROM $wpdb->subscribe2 WHERE date = CURDATE() AND time > SUBTIME(CURTIME(), %s)", $date ) );
192
  if ( in_array( $this->ip, $ips ) ) {
193
  return __( 'Slow down, you move too fast.', 'subscribe2' );
194
  }
240
  }
241
  }
242
  return $this->s2form;
243
+ }
244
 
245
  /**
246
+ * Display form when deprecated <!--subscribe2--> is used
247
+ */
248
+ public function filter( $content = '' ) {
249
+ if ( '' === $content || ! strstr( $content, '<!--subscribe2-->' ) ) {
250
+ return $content;
251
+ }
252
 
253
+ return preg_replace( '/(<p>)?(\n)*<!--subscribe2-->(\n)*(<\/p>)?/', do_shortcode( '[subscribe2]' ), $content );
254
+ }
255
 
256
  /**
257
+ * Overrides the default query when handling a (un)subscription confirmation
258
+ * This is basically a trick: if the s2 variable is in the query string, just grab the first
259
+ * static page and override it's contents later with title_filter()
260
+ */
261
+ public function query_filter() {
262
  // don't interfere if we've already done our thing
263
+ if ( 1 === $this->filtered ) {
264
+ return;
265
+ }
266
 
267
  global $wpdb;
268
 
288
  );
289
  }
290
  }
291
+ }
292
 
293
  /**
294
+ * Overrides the page title
295
+ */
296
+ public function title_filter( $title ) {
297
  if ( in_the_loop() ) {
298
+ $code = $_GET['s2'];
299
  $action = intval( substr( $code, 0, 1 ) );
300
  if ( 1 === $action ) {
301
  return __( 'Subscription Confirmation', 'subscribe2' );
305
  } else {
306
  return $title;
307
  }
308
+ }
309
 
310
  /**
311
+ * Confirm request from the link emailed to the user and email the admin
312
+ */
313
+ public function confirm( $content = '' ) {
314
  global $wpdb;
315
 
316
  if ( 1 === $this->filtered && '' !== $this->message ) {
319
  return $content;
320
  }
321
 
322
+ $code = $_GET['s2'];
323
  $action = substr( $code, 0, 1 );
324
+ $hash = substr( $code, 1, 32 );
325
+ $id = intval( substr( $code, 33 ) );
326
  if ( $id ) {
327
  $this->email = $this->sanitize_email( $this->get_email( $id ) );
328
  if ( ! $this->email || wp_hash( $this->email ) !== $hash ) {
361
  if ( '' !== $this->message ) {
362
  return $this->message;
363
  }
364
+ }
365
 
366
  /**
367
+ * Prepare and send emails to admins on new subscriptions and unsubsriptions
368
+ */
369
+ public function admin_email( $action ) {
370
  if ( ! in_array( $action, array( 'subscribe', 'unsubscribe' ) ) ) {
371
  return false;
372
  }
374
  ( '' === get_option( 'blogname' ) ) ? $subject = '' : $subject = '[' . stripslashes( html_entity_decode( get_option( 'blogname' ), ENT_QUOTES ) ) . '] ';
375
  if ( 'subscribe' === $action ) {
376
  $subject .= __( 'New Subscription', 'subscribe2' );
377
+ $message = $this->email . ' ' . __( 'subscribed to email notifications!', 'subscribe2' );
378
  } elseif ( 'unsubscribe' === $action ) {
379
  $subject .= __( 'New Unsubscription', 'subscribe2' );
380
+ $message = $this->email . ' ' . __( 'unsubscribed from email notifications!', 'subscribe2' );
381
  }
382
+
383
  $subject = html_entity_decode( $subject, ENT_QUOTES );
384
+ $role = array(
385
  'fields' => array(
386
  'user_email',
387
  ),
388
+ 'role' => 'administrator',
389
  );
390
+
391
  $wp_user_query = get_users( $role );
392
  foreach ( $wp_user_query as $user ) {
393
  $recipients[] = $user->user_email;
394
  }
395
+
396
  $recipients = apply_filters( 's2_admin_email', $recipients, $action );
397
+ $headers = $this->headers();
398
  // send individual emails so we don't reveal admin emails to each other
399
  foreach ( $recipients as $recipient ) {
400
+ $status = wp_mail( $recipient, $subject, $message, $headers );
401
  }
402
+ }
403
 
404
  /**
405
+ * Add hook for Minimeta Widget plugin
406
+ */
407
+ public function add_minimeta() {
408
  if ( 0 !== $this->subscribe2_options['s2page'] ) {
409
  echo '<li><a href="' . get_permalink( $this->subscribe2_options['s2page'] ) . '">' . __( '[Un]Subscribe to Posts', 'subscribe2' ) . '</a></li>' . "\r\n";
410
  }
411
+ }
412
 
413
  /**
414
+ * Check email is not from a barred domain
415
+ */
416
+ public function is_barred( $email = '' ) {
417
+ if ( '' === $email ) {
418
+ return false;
419
+ }
420
 
421
  list( $user, $domain ) = explode( '@', $email, 2 );
422
+
423
  $domain = '@' . $domain;
424
+
425
  foreach ( preg_split( '/[\s,]+/', $this->subscribe2_options['barred'] ) as $barred_domain ) {
426
+ if ( false !== strpos( $barred_domain, '!' ) ) {
427
+ $url = explode( '.', str_replace( '!', '', $barred_domain ) );
 
428
  $count = count( $url );
429
  // make sure our exploded domain has at least 2 components e.g. yahoo.*
430
  if ( $count < 2 ) {
435
  unset( $url[ $i ] );
436
  }
437
  }
438
+
439
  $new_barred_domain = '@' . strtolower( trim( implode( '.', $url ) ) );
440
+
441
+ if ( false !== strpos( $barred_domain, '*' ) ) {
442
+ $new_barred_subdomain = '.' . strtolower( trim( implode( '.', $url ) ) );
443
+ if ( false !== stripos( $domain, $new_barred_domain ) || false !== stripos( $domain, $new_barred_subdomain ) ) {
444
+ return false;
445
+ }
446
+ } else {
447
+ if ( false !== stripos( $domain, $new_barred_domain ) ) {
448
+ return false;
449
+ }
450
+ }
451
+ }
452
+
453
+ if ( false === strpos( $barred_domain, '!' ) && false !== strpos( $barred_domain, '*' ) ) {
454
+ // wildcard and explictly allowed checking
455
+ $url = explode( '.', str_replace( '!', '', $barred_domain ) );
456
+ $count = count( $url );
457
+ // make sure our exploded domain has at least 2 components e.g. yahoo.*
458
+ if ( $count < 2 ) {
459
+ continue;
460
+ }
461
+ for ( $i = 0; $i < $count; $i++ ) {
462
+ if ( '*' === $url[ $i ] ) {
463
+ unset( $url[ $i ] );
464
+ }
465
+ }
466
+
467
+ $new_barred_domain = '@' . strtolower( trim( implode( '.', $url ) ) );
468
  $new_barred_subdomain = '.' . strtolower( trim( implode( '.', $url ) ) );
469
 
470
  if ( false !== stripos( $domain, $new_barred_domain ) || false !== stripos( $domain, $new_barred_subdomain ) ) {
478
  }
479
  }
480
  }
481
+
482
  return false;
483
+ }
484
 
485
  /**
486
+ * Collect and return the IP address of the remote client machine
487
+ */
488
+ public function get_remote_ip() {
489
  $remote_ip = false;
490
 
491
  // In order of preference, with the best ones for this purpose first
505
  // addresses. The first one is the original client. It can't be
506
  // trusted for authenticity, but we don't need to for this purpose.
507
  $address_chain = explode( ',', $_SERVER[ $header ] );
508
+ $remote_ip = trim( $address_chain[0] );
509
  break;
510
  }
511
  }
512
 
513
  return $remote_ip;
514
+ }
515
 
516
+ /**
517
+ * Enqueue javascript ip updater code
518
+ */
519
+ public function js_ip_script() {
520
+ wp_register_script( 's2_ip_updater', S2URL . 'include/s2-ip-updater' . $this->script_debug . '.js', array(), '1.1', true );
521
  wp_enqueue_script( 's2_ip_updater' );
522
+ }
523
+
524
+ /**
525
+ * Add ip updater library to footer
526
+ */
527
+ public function js_ip_library_script() {
528
+ echo '<script async="async" src="https://api.ipify.org?format=jsonp&callback=getip"></script>' . "\r\n";
529
+ }
530
+
531
+ /* ===== define some variables ===== */
532
+ public $profile = '';
533
  }
 
classes/class-s2-list-table-legacy.php CHANGED
@@ -1,19 +1,26 @@
1
  <?php
2
  /**
3
- List Table class used in WordPress 4.2.x and below
4
- */
5
  class S2_List_Table_Legacy extends WP_List_Table {
6
- function __construct() {
 
 
 
7
  global $status, $page;
8
 
9
- parent::__construct( array(
10
- 'singular' => 'subscriber',
11
- 'plural' => 'subscribers',
12
- 'ajax' => false,
13
- ) );
 
 
 
 
14
  }
15
 
16
- function column_default( $item, $column_name ) {
17
  global $current_tab;
18
  if ( 'registered' === $current_tab ) {
19
  switch ( $column_name ) {
@@ -29,51 +36,55 @@ class S2_List_Table_Legacy extends WP_List_Table {
29
  }
30
  }
31
 
32
- function column_email( $item ) {
33
  global $current_tab;
34
  if ( 'registered' === $current_tab ) {
35
  $actions = array(
36
- 'edit' => sprintf( '<a href="?page=%s&amp;id=%d">%s</a>', 's2', urlencode( $item['id'] ), __( 'Edit', 'subscribe2' ) ),
37
  );
38
  return sprintf( '%1$s %2$s', $item['email'], $this->row_actions( $actions ) );
39
  } else {
40
  global $mysubscribe2;
41
  if ( '0' === $mysubscribe2->is_public( $item['email'] ) ) {
42
- return sprintf( '<span style="color:#FF0000"><abbr title="' . $mysubscribe2->signup_ip( $item['email'] ) . '">%1$s</abbr></span>', $item['email'] );
43
  } else {
44
- return sprintf( '<abbr title="' . $mysubscribe2->signup_ip( $item['email'] ) . '">%1$s</abbr>', $item['email'] );
45
  }
46
  }
47
  }
48
 
49
- function column_cb( $item ) {
 
 
 
 
 
 
 
 
 
 
50
  return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', $this->_args['singular'], $item['email'] );
51
  }
52
 
53
- function get_columns() {
54
  global $current_tab;
55
  if ( 'registered' === $current_tab ) {
56
- if ( is_multisite() ) {
57
- $columns = array(
58
- 'email' => _x( 'Email', 'column name', 'subscribe2' ),
59
- );
60
- } else {
61
- $columns = array(
62
- 'cb' => '<input type="checkbox" />',
63
- 'email' => _x( 'Email', 'column name', 'subscribe2' ),
64
- );
65
- }
66
  } else {
67
  $columns = array(
68
- 'cb' => '<input type="checkbox" />',
69
- 'email' => _x( 'Email', 'column name', 'subscribe2' ),
70
- 'date' => _x( 'Date', 'column name', 'subscribe2' ),
71
  );
72
  }
73
  return $columns;
74
  }
75
 
76
- function get_sortable_columns() {
77
  global $current_tab;
78
  if ( 'registered' === $current_tab ) {
79
  $sortable_columns = array(
@@ -81,47 +92,110 @@ class S2_List_Table_Legacy extends WP_List_Table {
81
  );
82
  } else {
83
  $sortable_columns = array(
84
- 'email' => array( 'email', true ),
85
- 'date' => array( 'date', false ),
86
  );
87
  }
88
  return $sortable_columns;
89
  }
90
 
91
- function get_bulk_actions() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  global $current_tab;
93
  if ( 'registered' === $current_tab ) {
94
  if ( is_multisite() ) {
95
  return array();
96
  } else {
97
- global $mysubscribe2;
98
- if ( 'never' === $mysubscribe2->subscribe2_options['email_freq'] ) {
99
- return array(
100
- 'delete' => __( 'Delete', 'subscribe2' ),
101
- 'subscribe' => __( 'Subscribe', 'subscribe2' ),
102
- 'unsubscribe' => __( 'Unsubscribe', 'subscribe2' ),
103
- 'format' => __( 'Change Email Format', 'subscribe2' ),
104
- );
105
- } else {
106
- return array(
107
- 'delete' => __( 'Delete', 'subscribe2' ),
108
- 'digest' => __( 'Change Digest Subscription', 'subscribe2' ),
109
- );
110
- }
111
  }
112
  } else {
113
  $actions = array(
114
- 'delete' => __( 'Delete', 'subscribe2' ),
115
- 'toggle' => __( 'Toggle', 'subscribe2' ),
116
  );
117
  return $actions;
118
  }
119
  }
120
 
121
- function process_bulk_action() {
122
- if ( in_array( $this->current_action(), array( 'delete', 'toggle', 'subscribe', 'unsubscribe', 'format', 'digest' ) ) ) {
123
  if ( ! isset( $_REQUEST['subscriber'] ) ) {
124
- echo '<div id="message" class="error"><p><strong>' . __( 'No users were selected.' , 'subscribe2' ) . '</strong></p></div>';
125
  return;
126
  }
127
  }
@@ -129,6 +203,7 @@ class S2_List_Table_Legacy extends WP_List_Table {
129
  global $mysubscribe2, $current_user, $subscribers;
130
  $message = array();
131
  foreach ( $_REQUEST['subscriber'] as $address ) {
 
132
  if ( false !== $mysubscribe2->is_public( $address ) ) {
133
  $mysubscribe2->delete( $address );
134
  $key = array_search( $address, $subscribers );
@@ -157,6 +232,7 @@ class S2_List_Table_Legacy extends WP_List_Table {
157
  global $mysubscribe2, $current_user, $subscribers;
158
  $mysubscribe2->ip = $current_user->user_login;
159
  foreach ( $_REQUEST['subscriber'] as $address ) {
 
160
  $mysubscribe2->toggle( $address );
161
  if ( 'confirmed' === $_POST['what'] || 'unconfirmed' === $_POST['what'] ) {
162
  $key = array_search( $address, $subscribers );
@@ -165,40 +241,21 @@ class S2_List_Table_Legacy extends WP_List_Table {
165
  }
166
  echo '<div id="message" class="updated fade"><p><strong>' . __( 'Status changed!', 'subscribe2' ) . '</strong></p></div>';
167
  }
168
- if ( 'subscribe' === $this->current_action() ) {
169
- global $mysubscribe2;
170
- $mysubscribe2->subscribe_registered_users( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['category'] );
171
- echo '<div id="message" class="updated fade"><p><strong>' . __( 'Registered Users Subscribed!', 'subscribe2' ) . '</strong></p></div>';
172
- }
173
- if ( 'unsubscribe' === $this->current_action() ) {
174
- global $mysubscribe2;
175
- $mysubscribe2->unsubscribe_registered_users( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['category'] );
176
- echo '<div id="message" class="updated fade"><p><strong>' . __( 'Registered Users Unsubscribed!', 'subscribe2' ) . '</strong></p></div>';
177
- }
178
- if ( 'format' === $this->current_action() ) {
179
- global $mysubscribe2;
180
- $mysubscribe2->format_change( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['format'] );
181
- echo '<div id="message" class="updated fade"><p><strong>' . __( 'Format updated for Selected Registered Users!', 'subscribe2' ) . '</strong></p></div>';
182
- }
183
- if ( 'digest' === $this->current_action() ) {
184
- global $mysubscribe2;
185
- $mysubscribe2->digest_change( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['sub_category'] );
186
- echo '<div id="message" class="error"><p><strong>' . __( 'Digest Subscription updated for Selected Registered Users!', 'subscribe2' ) . '</strong></p></div>';
187
- }
188
  }
189
 
190
- function pagination( $which ) {
191
  if ( empty( $this->_pagination_args ) ) {
192
  return;
193
  }
194
 
195
- $total_items = intval( $this->_pagination_args['total_items'] );
196
- $total_pages = intval( $this->_pagination_args['total_pages'] );
197
  $infinite_scroll = false;
198
  if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
199
  $infinite_scroll = $this->_pagination_args['infinite_scroll'];
200
  }
201
 
 
202
  $output = '<span class="displaying-num">' . sprintf( _n( '%s item', '%s items', $total_items, 'subscribe2' ), number_format_i18n( $total_items ) ) . '</span>';
203
 
204
  if ( isset( $_POST['what'] ) ) {
@@ -215,25 +272,28 @@ class S2_List_Table_Legacy extends WP_List_Table {
215
 
216
  $current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url );
217
 
218
- if ( isset( $what ) ) {
219
- $current_url = add_query_arg( array(
220
- 'what' => $what,
221
- ), $current_url );
222
- } elseif ( isset( $_REQUEST['what'] ) ) {
223
- $current_url = add_query_arg( array(
224
- 'what' => $_REQUEST['what'],
225
- ), $current_url );
226
  }
227
 
228
  if ( isset( $_POST['s'] ) ) {
229
- $current_url = add_query_arg( array(
230
- 's' => $_POST['s'],
231
- ), $current_url );
 
 
 
232
  }
233
 
234
  $page_links = array();
235
 
236
- $disable_first = $disable_last = '';
 
237
  if ( 1 === $current ) {
238
  $disable_first = ' disabled';
239
  }
@@ -241,14 +301,16 @@ class S2_List_Table_Legacy extends WP_List_Table {
241
  $disable_last = ' disabled';
242
  }
243
 
244
- $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
 
245
  'first-page' . $disable_first,
246
  esc_attr__( 'Go to the first page', 'subscribe2' ),
247
  remove_query_arg( 'paged', $current_url ),
248
  '&laquo;'
249
  );
250
 
251
- $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
 
252
  'prev-page' . $disable_first,
253
  esc_attr__( 'Go to the previous page', 'subscribe2' ),
254
  add_query_arg( 'paged', max( 1, $current - 1 ), $current_url ),
@@ -258,7 +320,8 @@ class S2_List_Table_Legacy extends WP_List_Table {
258
  if ( 'bottom' === $which ) {
259
  $html_current_page = $current;
260
  } else {
261
- $html_current_page = sprintf( "<input class='current-page' title='%s' type='text' name='paged' value='%s' size='%d' />",
 
262
  esc_attr__( 'Current page', 'subscribe2' ),
263
  $current,
264
  strlen( $total_pages )
@@ -266,16 +329,19 @@ class S2_List_Table_Legacy extends WP_List_Table {
266
  }
267
 
268
  $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
 
269
  $page_links[] = '<span class="paging-input">' . sprintf( _x( '%1$s of %2$s', 'paging', 'subscribe2' ), $html_current_page, $html_total_pages ) . '</span>';
270
 
271
- $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
 
272
  'next-page' . $disable_last,
273
  esc_attr__( 'Go to the next page', 'subscribe2' ),
274
  add_query_arg( 'paged', min( $total_pages, $current + 1 ), $current_url ),
275
  '&rsaquo;'
276
  );
277
 
278
- $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
 
279
  'last-page' . $disable_last,
280
  esc_attr__( 'Go to the last page', 'subscribe2' ),
281
  add_query_arg( 'paged', $total_pages, $current_url ),
@@ -299,17 +365,21 @@ class S2_List_Table_Legacy extends WP_List_Table {
299
  echo $this->_pagination;
300
  }
301
 
302
- function prepare_items() {
303
  global $mysubscribe2, $subscribers, $current_tab;
304
- if ( is_int( $mysubscribe2->subscribe2_options['entries'] ) ) {
305
- $per_page = $mysubscribe2->subscribe2_options['entries'];
306
- } else {
307
- $per_page = 25;
 
 
 
308
  }
309
 
310
- $columns = $this->get_columns();
311
- $hidden = array();
312
  $sortable = $this->get_sortable_columns();
 
313
  $this->_column_headers = array( $columns, $hidden, $sortable );
314
 
315
  $this->process_bulk_action();
@@ -319,22 +389,24 @@ class S2_List_Table_Legacy extends WP_List_Table {
319
  foreach ( (array) $subscribers as $email ) {
320
  $data[] = array(
321
  'email' => $email,
322
- 'date' => $mysubscribe2->signup_date( $email ),
 
 
323
  );
324
  }
325
  } else {
326
  foreach ( (array) $subscribers as $subscriber ) {
327
  $data[] = array(
328
  'email' => $subscriber['user_email'],
329
- 'id' => $subscriber['ID'],
330
  );
331
  }
332
  }
333
 
334
  function usort_reorder( $a, $b ) {
335
  $orderby = ( ! empty( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : 'email';
336
- $order = ( ! empty( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : 'asc';
337
- $result = strcasecmp( $a[ $orderby ], $b[ $orderby ] );
338
  return ( 'asc' === $order ) ? $result : -$result;
339
  }
340
  usort( $data, 'usort_reorder' );
@@ -345,14 +417,15 @@ class S2_List_Table_Legacy extends WP_List_Table {
345
  $current_page = $this->get_pagenum();
346
  }
347
  $total_items = count( $data );
348
- $data = array_slice( $data,( ($current_page -1 ) * $per_page ), $per_page );
349
  $this->items = $data;
350
 
351
- $this->set_pagination_args( array(
352
- 'total_items' => $total_items,
353
- 'per_page' => $per_page,
354
- 'total_pages' => ceil( $total_items / $per_page ),
355
- ) );
 
 
356
  }
357
  }
358
- ?>
1
  <?php
2
  /**
3
+ * List Table class used in WordPress 4.2.x and below
4
+ */
5
  class S2_List_Table_Legacy extends WP_List_Table {
6
+ private $date_format = '';
7
+ private $time_format = '';
8
+
9
+ public function __construct() {
10
  global $status, $page;
11
 
12
+ parent::__construct(
13
+ array(
14
+ 'singular' => 'subscriber',
15
+ 'plural' => 'subscribers',
16
+ 'ajax' => false,
17
+ )
18
+ );
19
+ $this->date_format = get_option( 'date_format' );
20
+ $this->time_format = get_option( 'time_format' );
21
  }
22
 
23
+ public function column_default( $item, $column_name ) {
24
  global $current_tab;
25
  if ( 'registered' === $current_tab ) {
26
  switch ( $column_name ) {
36
  }
37
  }
38
 
39
+ public function column_email( $item ) {
40
  global $current_tab;
41
  if ( 'registered' === $current_tab ) {
42
  $actions = array(
43
+ 'edit' => sprintf( '<a href="?page=%s&amp;id=%d">%s</a>', 's2', rawurlencode( $item['id'] ), __( 'Edit', 'subscribe2' ) ),
44
  );
45
  return sprintf( '%1$s %2$s', $item['email'], $this->row_actions( $actions ) );
46
  } else {
47
  global $mysubscribe2;
48
  if ( '0' === $mysubscribe2->is_public( $item['email'] ) ) {
49
+ return sprintf( '<span style="color:#FF0000"><abbr title="%2$s">%1$s</abbr></span>', $item['email'], $item['ip'] );
50
  } else {
51
+ return sprintf( '<abbr title="%2$s">%1$s</abbr>', $item['email'], $item['ip'] );
52
  }
53
  }
54
  }
55
 
56
+ public function column_date( $item ) {
57
+ global $current_tab;
58
+ if ( 'registered' === $current_tab ) {
59
+ return $item['date'];
60
+ } else {
61
+ $timestamp = strtotime( $item['date'] . ' ' . $item['time'] );
62
+ return sprintf( '<abbr title="%2$s">%1$s</abbr>', date_i18n( $this->date_format, $timestamp ), date_i18n( $this->time_format, $timestamp ) );
63
+ }
64
+ }
65
+
66
+ public function column_cb( $item ) {
67
  return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', $this->_args['singular'], $item['email'] );
68
  }
69
 
70
+ public function get_columns() {
71
  global $current_tab;
72
  if ( 'registered' === $current_tab ) {
73
+ $columns = array(
74
+ 'cb' => '<input type="checkbox" />',
75
+ 'email' => _x( 'Email', 'column name', 'subscribe2' ),
76
+ );
 
 
 
 
 
 
77
  } else {
78
  $columns = array(
79
+ 'cb' => '<input type="checkbox" />',
80
+ 'email' => _x( 'Email', 'column name', 'subscribe2' ),
81
+ 'date' => _x( 'Date', 'column name', 'subscribe2' ),
82
  );
83
  }
84
  return $columns;
85
  }
86
 
87
+ public function get_sortable_columns() {
88
  global $current_tab;
89
  if ( 'registered' === $current_tab ) {
90
  $sortable_columns = array(
92
  );
93
  } else {
94
  $sortable_columns = array(
95
+ 'email' => array( 'email', true ),
96
+ 'date' => array( 'date', false ),
97
  );
98
  }
99
  return $sortable_columns;
100
  }
101
 
102
+ public function print_column_headers( $with_id = true ) {
103
+ list( $columns, $hidden, $sortable ) = $this->get_column_info();
104
+
105
+ $current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
106
+ $current_url = remove_query_arg( 'paged', $current_url );
107
+
108
+ if ( isset( $_REQUEST['what'] ) ) {
109
+ $current_url = add_query_arg(
110
+ array(
111
+ 'what' => $_REQUEST['what'],
112
+ ),
113
+ $current_url
114
+ );
115
+ }
116
+
117
+ if ( isset( $_GET['orderby'] ) ) {
118
+ $current_orderby = $_GET['orderby'];
119
+ } else {
120
+ $current_orderby = '';
121
+ }
122
+
123
+ if ( isset( $_GET['order'] ) && 'desc' === $_GET['order'] ) {
124
+ $current_order = 'desc';
125
+ } else {
126
+ $current_order = 'asc';
127
+ }
128
+
129
+ if ( ! empty( $columns['cb'] ) ) {
130
+ static $cb_counter = 1;
131
+ $columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All', 'subscribe2' ) . '</label>'
132
+ . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
133
+ $cb_counter++;
134
+ }
135
+
136
+ foreach ( $columns as $column_key => $column_display_name ) {
137
+ $class = array( 'manage-column', "column-$column_key" );
138
+
139
+ $style = '';
140
+ if ( in_array( $column_key, $hidden ) ) {
141
+ $style = 'display:none;';
142
+ }
143
+
144
+ $style = ' style="' . $style . '"';
145
+
146
+ if ( 'cb' === $column_key ) {
147
+ $class[] = 'check-column';
148
+ }
149
+
150
+ if ( isset( $sortable[ $column_key ] ) ) {
151
+ list( $orderby, $desc_first ) = $sortable[ $column_key ];
152
+
153
+ if ( $current_orderby === $orderby ) {
154
+ $order = 'asc' === $current_order ? 'desc' : 'asc';
155
+ $class[] = 'sorted';
156
+ $class[] = $current_order;
157
+ } else {
158
+ $order = $desc_first ? 'desc' : 'asc';
159
+ $class[] = 'sortable';
160
+ $class[] = $desc_first ? 'asc' : 'desc';
161
+ }
162
+
163
+ $column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
164
+ }
165
+
166
+ $id = $with_id ? "id='$column_key'" : '';
167
+
168
+ if ( ! empty( $class ) ) {
169
+ $class = "class='" . join( ' ', $class ) . "'";
170
+ }
171
+
172
+ echo "<th scope='col' $id $class $style>$column_display_name</th>";
173
+ }
174
+ }
175
+
176
+ public function get_bulk_actions() {
177
  global $current_tab;
178
  if ( 'registered' === $current_tab ) {
179
  if ( is_multisite() ) {
180
  return array();
181
  } else {
182
+ return array(
183
+ 'delete' => __( 'Delete', 'subscribe2' ),
184
+ );
 
 
 
 
 
 
 
 
 
 
 
185
  }
186
  } else {
187
  $actions = array(
188
+ 'delete' => __( 'Delete', 'subscribe2' ),
189
+ 'toggle' => __( 'Toggle', 'subscribe2' ),
190
  );
191
  return $actions;
192
  }
193
  }
194
 
195
+ public function process_bulk_action() {
196
+ if ( in_array( $this->current_action(), array( 'delete', 'toggle' ) ) ) {
197
  if ( ! isset( $_REQUEST['subscriber'] ) ) {
198
+ echo '<div id="message" class="error"><p><strong>' . __( 'No users were selected.', 'subscribe2' ) . '</strong></p></div>';
199
  return;
200
  }
201
  }
203
  global $mysubscribe2, $current_user, $subscribers;
204
  $message = array();
205
  foreach ( $_REQUEST['subscriber'] as $address ) {
206
+ $address = trim( stripslashes( $address ) );
207
  if ( false !== $mysubscribe2->is_public( $address ) ) {
208
  $mysubscribe2->delete( $address );
209
  $key = array_search( $address, $subscribers );
232
  global $mysubscribe2, $current_user, $subscribers;
233
  $mysubscribe2->ip = $current_user->user_login;
234
  foreach ( $_REQUEST['subscriber'] as $address ) {
235
+ $address = trim( stripslashes( $address ) );
236
  $mysubscribe2->toggle( $address );
237
  if ( 'confirmed' === $_POST['what'] || 'unconfirmed' === $_POST['what'] ) {
238
  $key = array_search( $address, $subscribers );
241
  }
242
  echo '<div id="message" class="updated fade"><p><strong>' . __( 'Status changed!', 'subscribe2' ) . '</strong></p></div>';
243
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  }
245
 
246
+ public function pagination( $which ) {
247
  if ( empty( $this->_pagination_args ) ) {
248
  return;
249
  }
250
 
251
+ $total_items = intval( $this->_pagination_args['total_items'] );
252
+ $total_pages = intval( $this->_pagination_args['total_pages'] );
253
  $infinite_scroll = false;
254
  if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
255
  $infinite_scroll = $this->_pagination_args['infinite_scroll'];
256
  }
257
 
258
+ // Translators: Pagination
259
  $output = '<span class="displaying-num">' . sprintf( _n( '%s item', '%s items', $total_items, 'subscribe2' ), number_format_i18n( $total_items ) ) . '</span>';
260
 
261
  if ( isset( $_POST['what'] ) ) {
272
 
273
  $current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url );
274
 
275
+ if ( isset( $_REQUEST['what'] ) ) {
276
+ $current_url = add_query_arg(
277
+ array(
278
+ 'what' => $_REQUEST['what'],
279
+ ),
280
+ $current_url
281
+ );
 
282
  }
283
 
284
  if ( isset( $_POST['s'] ) ) {
285
+ $current_url = add_query_arg(
286
+ array(
287
+ 's' => $_POST['s'],
288
+ ),
289
+ $current_url
290
+ );
291
  }
292
 
293
  $page_links = array();
294
 
295
+ $disable_first = '';
296
+ $disable_last = '';
297
  if ( 1 === $current ) {
298
  $disable_first = ' disabled';
299
  }
301
  $disable_last = ' disabled';
302
  }
303
 
304
+ $page_links[] = sprintf(
305
+ "<a class='%s' title='%s' href='%s'>%s</a>",
306
  'first-page' . $disable_first,
307
  esc_attr__( 'Go to the first page', 'subscribe2' ),
308
  remove_query_arg( 'paged', $current_url ),
309
  '&laquo;'
310
  );
311
 
312
+ $page_links[] = sprintf(
313
+ "<a class='%s' title='%s' href='%s'>%s</a>",
314
  'prev-page' . $disable_first,
315
  esc_attr__( 'Go to the previous page', 'subscribe2' ),
316
  add_query_arg( 'paged', max( 1, $current - 1 ), $current_url ),
320
  if ( 'bottom' === $which ) {
321
  $html_current_page = $current;
322
  } else {
323
+ $html_current_page = sprintf(
324
+ "<input class='current-page' title='%s' type='text' name='paged' value='%s' size='%d' />",
325
  esc_attr__( 'Current page', 'subscribe2' ),
326
  $current,
327
  strlen( $total_pages )
329
  }
330
 
331
  $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
332
+ // Translators: Pagination
333
  $page_links[] = '<span class="paging-input">' . sprintf( _x( '%1$s of %2$s', 'paging', 'subscribe2' ), $html_current_page, $html_total_pages ) . '</span>';
334
 
335
+ $page_links[] = sprintf(
336
+ "<a class='%s' title='%s' href='%s'>%s</a>",
337
  'next-page' . $disable_last,
338
  esc_attr__( 'Go to the next page', 'subscribe2' ),
339
  add_query_arg( 'paged', min( $total_pages, $current + 1 ), $current_url ),
340
  '&rsaquo;'
341
  );
342
 
343
+ $page_links[] = sprintf(
344
+ "<a class='%s' title='%s' href='%s'>%s</a>",
345
  'last-page' . $disable_last,
346
  esc_attr__( 'Go to the last page', 'subscribe2' ),
347
  add_query_arg( 'paged', $total_pages, $current_url ),
365
  echo $this->_pagination;
366
  }
367
 
368
+ public function prepare_items() {
369
  global $mysubscribe2, $subscribers, $current_tab;
370
+
371
+ $user = get_current_user_id();
372
+ $screen = get_current_screen();
373
+ $screen_option = $screen->get_option( 'per_page', 'option' );
374
+ $per_page = get_user_meta( $user, $screen_option, true );
375
+ if ( empty( $per_page ) || $per_page < 1 ) {
376
+ $per_page = $screen->get_option( 'per_page', 'default' );
377
  }
378
 
379
+ $columns = $this->get_columns();
380
+ $hidden = array();
381
  $sortable = $this->get_sortable_columns();
382
+
383
  $this->_column_headers = array( $columns, $hidden, $sortable );
384
 
385
  $this->process_bulk_action();
389
  foreach ( (array) $subscribers as $email ) {
390
  $data[] = array(
391
  'email' => $email,
392
+ 'date' => $mysubscribe2->signup_date( $email ),
393
+ 'time' => $mysubscribe2->signup_time( $email ),
394
+ 'ip' => $mysubscribe2->signup_ip( $email ),
395
  );
396
  }
397
  } else {
398
  foreach ( (array) $subscribers as $subscriber ) {
399
  $data[] = array(
400
  'email' => $subscriber['user_email'],
401
+ 'id' => $subscriber['ID'],
402
  );
403
  }
404
  }
405
 
406
  function usort_reorder( $a, $b ) {
407
  $orderby = ( ! empty( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : 'email';
408
+ $order = ( ! empty( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : 'asc';
409
+ $result = strcasecmp( $a[ $orderby ], $b[ $orderby ] );
410
  return ( 'asc' === $order ) ? $result : -$result;
411
  }
412
  usort( $data, 'usort_reorder' );
417
  $current_page = $this->get_pagenum();
418
  }
419
  $total_items = count( $data );
420
+ $data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );
421
  $this->items = $data;
422
 
423
+ $this->set_pagination_args(
424
+ array(
425
+ 'total_items' => $total_items,
426
+ 'per_page' => $per_page,
427
+ 'total_pages' => ceil( $total_items / $per_page ),
428
+ )
429
+ );
430
  }
431
  }
 
classes/class-s2-list-table.php CHANGED
@@ -1,19 +1,26 @@
1
  <?php
2
  /**
3
- List Table class used in WordPress 4.3.x and above
4
- */
5
  class S2_List_Table extends WP_List_Table {
6
- function __construct() {
 
 
 
7
  global $status, $page;
8
 
9
- parent::__construct( array(
10
- 'singular' => 'subscriber',
11
- 'plural' => 'subscribers',
12
- 'ajax' => false,
13
- ) );
 
 
 
 
14
  }
15
 
16
- function column_default( $item, $column_name ) {
17
  global $current_tab;
18
  if ( 'registered' === $current_tab ) {
19
  switch ( $column_name ) {
@@ -29,51 +36,55 @@ class S2_List_Table extends WP_List_Table {
29
  }
30
  }
31
 
32
- function column_email( $item ) {
33
  global $current_tab;
34
  if ( 'registered' === $current_tab ) {
35
  $actions = array(
36
- 'edit' => sprintf( '<a href="?page=%s&amp;id=%d">%s</a>', 's2', urlencode( $item['id'] ), __( 'Edit', 'subscribe2' ) ),
37
  );
38
  return sprintf( '%1$s %2$s', $item['email'], $this->row_actions( $actions ) );
39
  } else {
40
  global $mysubscribe2;
41
  if ( '0' === $mysubscribe2->is_public( $item['email'] ) ) {
42
- return sprintf( '<span style="color:#FF0000"><abbr title="' . $mysubscribe2->signup_ip( $item['email'] ) . '">%1$s</abbr></span>', $item['email'] );
43
  } else {
44
- return sprintf( '<abbr title="' . $mysubscribe2->signup_ip( $item['email'] ) . '">%1$s</abbr>', $item['email'] );
45
  }
46
  }
47
  }
48
 
49
- function column_cb( $item ) {
 
 
 
 
 
 
 
 
 
 
50
  return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', $this->_args['singular'], $item['email'] );
51
  }
52
 
53
- function get_columns() {
54
  global $current_tab;
55
  if ( 'registered' === $current_tab ) {
56
- if ( is_multisite() ) {
57
- $columns = array(
58
- 'email' => _x( 'Email', 'column name', 'subscribe2' ),
59
- );
60
- } else {
61
- $columns = array(
62
- 'cb' => '<input type="checkbox" />',
63
- 'email' => _x( 'Email', 'column name', 'subscribe2' ),
64
- );
65
- }
66
  } else {
67
  $columns = array(
68
- 'cb' => '<input type="checkbox" />',
69
- 'email' => _x( 'Email', 'column name', 'subscribe2' ),
70
- 'date' => _x( 'Date', 'column name', 'subscribe2' ),
71
  );
72
  }
73
  return $columns;
74
  }
75
 
76
- function get_sortable_columns() {
77
  global $current_tab;
78
  if ( 'registered' === $current_tab ) {
79
  $sortable_columns = array(
@@ -81,47 +92,113 @@ class S2_List_Table extends WP_List_Table {
81
  );
82
  } else {
83
  $sortable_columns = array(
84
- 'email' => array( 'email', true ),
85
- 'date' => array( 'date', false ),
86
  );
87
  }
88
  return $sortable_columns;
89
  }
90
 
91
- function get_bulk_actions() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  global $current_tab;
93
  if ( 'registered' === $current_tab ) {
94
  if ( is_multisite() ) {
95
  return array();
96
  } else {
97
- global $mysubscribe2;
98
- if ( 'never' === $mysubscribe2->subscribe2_options['email_freq'] ) {
99
- return array(
100
- 'delete' => __( 'Delete', 'subscribe2' ),
101
- 'subscribe' => __( 'Subscribe', 'subscribe2' ),
102
- 'unsubscribe' => __( 'Unsubscribe', 'subscribe2' ),
103
- 'format' => __( 'Change Email Format', 'subscribe2' ),
104
- );
105
- } else {
106
- return array(
107
- 'delete' => __( 'Delete', 'subscribe2' ),
108
- 'digest' => __( 'Change Digest Subscription', 'subscribe2' ),
109
- );
110
- }
111
  }
112
  } else {
113
  $actions = array(
114
- 'delete' => __( 'Delete', 'subscribe2' ),
115
- 'toggle' => __( 'Toggle', 'subscribe2' ),
116
  );
117
  return $actions;
118
  }
119
  }
120
 
121
- function process_bulk_action() {
122
- if ( in_array( $this->current_action(), array( 'delete', 'toggle', 'subscribe', 'unsubscribe', 'format', 'digest' ) ) ) {
123
  if ( ! isset( $_REQUEST['subscriber'] ) ) {
124
- echo '<div id="message" class="error"><p><strong>' . __( 'No users were selected.' , 'subscribe2' ) . '</strong></p></div>';
125
  return;
126
  }
127
  }
@@ -129,6 +206,7 @@ class S2_List_Table extends WP_List_Table {
129
  global $mysubscribe2, $current_user, $subscribers;
130
  $message = array();
131
  foreach ( $_REQUEST['subscriber'] as $address ) {
 
132
  if ( false !== $mysubscribe2->is_public( $address ) ) {
133
  $mysubscribe2->delete( $address );
134
  $key = array_search( $address, $subscribers );
@@ -157,6 +235,7 @@ class S2_List_Table extends WP_List_Table {
157
  global $mysubscribe2, $current_user, $subscribers;
158
  $mysubscribe2->ip = $current_user->user_login;
159
  foreach ( $_REQUEST['subscriber'] as $address ) {
 
160
  $mysubscribe2->toggle( $address );
161
  if ( 'confirmed' === $_POST['what'] || 'unconfirmed' === $_POST['what'] ) {
162
  $key = array_search( $address, $subscribers );
@@ -165,35 +244,15 @@ class S2_List_Table extends WP_List_Table {
165
  }
166
  echo '<div id="message" class="updated fade"><p><strong>' . __( 'Status changed!', 'subscribe2' ) . '</strong></p></div>';
167
  }
168
- if ( 'subscribe' === $this->current_action() ) {
169
- global $mysubscribe2;
170
- $mysubscribe2->subscribe_registered_users( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['category'] );
171
- echo '<div id="message" class="updated fade"><p><strong>' . __( 'Registered Users Subscribed!', 'subscribe2' ) . '</strong></p></div>';
172
- }
173
- if ( 'unsubscribe' === $this->current_action() ) {
174
- global $mysubscribe2;
175
- $mysubscribe2->unsubscribe_registered_users( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['category'] );
176
- echo '<div id="message" class="updated fade"><p><strong>' . __( 'Registered Users Unsubscribed!', 'subscribe2' ) . '</strong></p></div>';
177
- }
178
- if ( 'format' === $this->current_action() ) {
179
- global $mysubscribe2;
180
- $mysubscribe2->format_change( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['format'] );
181
- echo '<div id="message" class="updated fade"><p><strong>' . __( 'Format updated for Selected Registered Users!', 'subscribe2' ) . '</strong></p></div>';
182
- }
183
- if ( 'digest' === $this->current_action() ) {
184
- global $mysubscribe2;
185
- $mysubscribe2->digest_change( implode( ",\r\n", $_REQUEST['subscriber'] ), $_POST['sub_category'] );
186
- echo '<div id="message" class="error"><p><strong>' . __( 'Digest Subscription updated for Selected Registered Users!', 'subscribe2' ) . '</strong></p></div>';
187
- }
188
  }
189
 
190
- function pagination( $which ) {
191
  if ( empty( $this->_pagination_args ) ) {
192
  return;
193
  }
194
 
195
- $total_items = intval( $this->_pagination_args['total_items'] );
196
- $total_pages = intval( $this->_pagination_args['total_pages'] );
197
  $infinite_scroll = false;
198
  if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
199
  $infinite_scroll = $this->_pagination_args['infinite_scroll'];
@@ -203,6 +262,7 @@ class S2_List_Table extends WP_List_Table {
203
  $this->screen->render_screen_reader_content( 'heading_pagination' );
204
  }
205
 
 
206
  $output = '<span class="displaying-num">' . sprintf( _n( '%s item', '%s items', $total_items, 'subscribe2' ), number_format_i18n( $total_items ) ) . '</span>';
207
 
208
  if ( isset( $_POST['what'] ) ) {
@@ -215,20 +275,22 @@ class S2_List_Table extends WP_List_Table {
215
 
216
  $current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url );
217
 
218
- if ( isset( $what ) ) {
219
- $current_url = add_query_arg( array(
220
- 'what' => $what,
221
- ), $current_url );
222
- } elseif ( isset( $_REQUEST['what'] ) ) {
223
- $current_url = add_query_arg( array(
224
- 'what' => $_REQUEST['what'],
225
- ), $current_url );
226
  }
227
 
228
  if ( isset( $_POST['s'] ) ) {
229
- $current_url = add_query_arg( array(
230
- 's' => $_POST['s'],
231
- ), $current_url );
 
 
 
232
  }
233
 
234
  $page_links = array();
@@ -236,11 +298,14 @@ class S2_List_Table extends WP_List_Table {
236
  $total_pages_before = '<span class="paging-input">';
237
  $total_pages_after = '</span>';
238
 
239
- $disable_first = $disable_last = $disable_prev = $disable_next = false;
 
 
 
240
 
241
  if ( 1 === $current ) {
242
  $disable_first = true;
243
- $disable_prev = true;
244
  }
245
  if ( 2 === $current ) {
246
  $disable_first = true;
@@ -256,7 +321,8 @@ class S2_List_Table extends WP_List_Table {
256
  if ( $disable_first ) {
257
  $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&laquo;</span>';
258
  } else {
259
- $page_links[] = sprintf( "<a class='first-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
 
260
  esc_url( remove_query_arg( 'paged', $current_url ) ),
261
  __( 'First page', 'subscribe2' ),
262
  '&laquo;'
@@ -266,7 +332,8 @@ class S2_List_Table extends WP_List_Table {
266
  if ( $disable_prev ) {
267
  $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&lsaquo;</span>';
268
  } else {
269
- $page_links[] = sprintf( "<a class='prev-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
 
270
  esc_url( add_query_arg( 'paged', max( 1, $current - 1 ), $current_url ) ),
271
  __( 'Previous page', 'subscribe2' ),
272
  '&lsaquo;'
@@ -277,19 +344,23 @@ class S2_List_Table extends WP_List_Table {
277
  $html_current_page = $current;
278
  $total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page', 'subscribe2' ) . '</span><span id="table-paging" class="paging-input">';
279
  } else {
280
- $html_current_page = sprintf( "%s<input class='current-page' id='current-page-selector' type='text' name='paged' value='%s' size='%d' aria-describedby='table-paging' />",
 
281
  '<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page', 'subscribe2' ) . '</label>',
282
  $current,
283
  strlen( $total_pages )
284
  );
285
  }
 
286
  $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
 
287
  $page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging', 'subscribe2' ), $html_current_page, $html_total_pages ) . $total_pages_after;
288
 
289
  if ( $disable_next ) {
290
  $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&rsaquo;</span>';
291
  } else {
292
- $page_links[] = sprintf( "<a class='next-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
 
293
  esc_url( add_query_arg( 'paged', min( $total_pages, $current + 1 ), $current_url ) ),
294
  __( 'Next page', 'subscribe2' ),
295
  '&rsaquo;'
@@ -299,7 +370,8 @@ class S2_List_Table extends WP_List_Table {
299
  if ( $disable_last ) {
300
  $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&raquo;</span>';
301
  } else {
302
- $page_links[] = sprintf( "<a class='last-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
 
303
  esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
304
  __( 'Last page', 'subscribe2' ),
305
  '&raquo;'
@@ -317,22 +389,27 @@ class S2_List_Table extends WP_List_Table {
317
  } else {
318
  $page_class = ' no-pages';
319
  }
 
320
  $this->_pagination = "<div class='tablenav-pages{$page_class}'>$output</div>";
321
 
322
  echo $this->_pagination;
323
  }
324
 
325
- function prepare_items() {
326
  global $mysubscribe2, $subscribers, $current_tab;
327
- if ( is_int( $mysubscribe2->subscribe2_options['entries'] ) ) {
328
- $per_page = $mysubscribe2->subscribe2_options['entries'];
329
- } else {
330
- $per_page = 25;
 
 
 
331
  }
332
 
333
- $columns = $this->get_columns();
334
- $hidden = array();
335
  $sortable = $this->get_sortable_columns();
 
336
  $this->_column_headers = array( $columns, $hidden, $sortable );
337
 
338
  $this->process_bulk_action();
@@ -342,22 +419,24 @@ class S2_List_Table extends WP_List_Table {
342
  foreach ( (array) $subscribers as $email ) {
343
  $data[] = array(
344
  'email' => $email,
345
- 'date' => $mysubscribe2->signup_date( $email ),
 
 
346
  );
347
  }
348
  } else {
349
  foreach ( (array) $subscribers as $subscriber ) {
350
  $data[] = array(
351
  'email' => $subscriber['user_email'],
352
- 'id' => $subscriber['ID'],
353
  );
354
  }
355
  }
356
 
357
  function usort_reorder( $a, $b ) {
358
  $orderby = ( ! empty( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : 'email';
359
- $order = ( ! empty( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : 'asc';
360
- $result = strcasecmp( $a[ $orderby ], $b[ $orderby ] );
361
  return ( 'asc' === $order ) ? $result : -$result;
362
  }
363
  usort( $data, 'usort_reorder' );
@@ -368,14 +447,15 @@ class S2_List_Table extends WP_List_Table {
368
  $current_page = $this->get_pagenum();
369
  }
370
  $total_items = count( $data );
371
- $data = array_slice( $data,( ($current_page -1 ) * $per_page ), $per_page );
372
  $this->items = $data;
373
 
374
- $this->set_pagination_args( array(
375
- 'total_items' => $total_items,
376
- 'per_page' => $per_page,
377
- 'total_pages' => ceil( $total_items / $per_page ),
378
- ) );
 
 
379
  }
380
  }
381
- ?>
1
  <?php
2
  /**
3
+ * List Table class used in WordPress 4.3.x and above
4
+ */
5
  class S2_List_Table extends WP_List_Table {
6
+ private $date_format = '';
7
+ private $time_format = '';
8
+
9
+ public function __construct() {
10
  global $status, $page;
11
 
12
+ parent::__construct(
13
+ array(
14
+ 'singular' => 'subscriber',
15
+ 'plural' => 'subscribers',
16
+ 'ajax' => false,
17
+ )
18
+ );
19
+ $this->date_format = get_option( 'date_format' );
20
+ $this->time_format = get_option( 'time_format' );
21
  }
22
 
23
+ public function column_default( $item, $column_name ) {
24
  global $current_tab;
25
  if ( 'registered' === $current_tab ) {
26
  switch ( $column_name ) {
36
  }
37
  }
38
 
39
+ public function column_email( $item ) {
40
  global $current_tab;
41
  if ( 'registered' === $current_tab ) {
42
  $actions = array(
43
+ 'edit' => sprintf( '<a href="?page=%s&amp;id=%d">%s</a>', 's2', rawurlencode( $item['id'] ), __( 'Edit', 'subscribe2' ) ),
44
  );
45
  return sprintf( '%1$s %2$s', $item['email'], $this->row_actions( $actions ) );
46
  } else {
47
  global $mysubscribe2;
48
  if ( '0' === $mysubscribe2->is_public( $item['email'] ) ) {
49
+ return sprintf( '<span style="color:#FF0000"><abbr title="%2$s">%1$s</abbr></span>', $item['email'], $item['ip'] );
50
  } else {
51
+ return sprintf( '<abbr title="%2$s">%1$s</abbr>', $item['email'], $item['ip'] );
52
  }
53
  }
54
  }
55
 
56
+ public function column_date( $item ) {
57
+ global $current_tab;
58
+ if ( 'registered' === $current_tab ) {
59
+ return $item['date'];
60
+ } else {
61
+ $timestamp = strtotime( $item['date'] . ' ' . $item['time'] );
62
+ return sprintf( '<abbr title="%2$s">%1$s</abbr>', date_i18n( $this->date_format, $timestamp ), date_i18n( $this->time_format, $timestamp ) );
63
+ }
64
+ }
65
+
66
+ public function column_cb( $item ) {
67
  return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', $this->_args['singular'], $item['email'] );
68
  }
69
 
70
+ public function get_columns() {
71
  global $current_tab;
72
  if ( 'registered' === $current_tab ) {
73
+ $columns = array(
74
+ 'cb' => '<input type="checkbox" />',
75
+ 'email' => _x( 'Email', 'column name', 'subscribe2' ),
76
+ );
 
 
 
 
 
 
77
  } else {
78
  $columns = array(
79
+ 'cb' => '<input type="checkbox" />',
80
+ 'email' => _x( 'Email', 'column name', 'subscribe2' ),
81
+ 'date' => _x( 'Date', 'column name', 'subscribe2' ),
82
  );
83
  }
84
  return $columns;
85
  }
86
 
87
+ public function get_sortable_columns() {
88
  global $current_tab;
89
  if ( 'registered' === $current_tab ) {
90
  $sortable_columns = array(
92
  );
93
  } else {
94
  $sortable_columns = array(
95
+ 'email' => array( 'email', true ),
96
+ 'date' => array( 'date', false ),
97
  );
98
  }
99
  return $sortable_columns;
100
  }
101
 
102
+ public function print_column_headers( $with_id = true ) {
103
+ list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
104
+
105
+ $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
106
+ $current_url = remove_query_arg( 'paged', $current_url );
107
+
108
+ if ( isset( $_REQUEST['what'] ) ) {
109
+ $current_url = add_query_arg(
110
+ array(
111
+ 'what' => $_REQUEST['what'],
112
+ ),
113
+ $current_url
114
+ );
115
+ }
116
+
117
+ if ( isset( $_GET['orderby'] ) ) {
118
+ $current_orderby = $_GET['orderby'];
119
+ } else {
120
+ $current_orderby = '';
121
+ }
122
+
123
+ if ( isset( $_GET['order'] ) && 'desc' === $_GET['order'] ) {
124
+ $current_order = 'desc';
125
+ } else {
126
+ $current_order = 'asc';
127
+ }
128
+
129
+ if ( ! empty( $columns['cb'] ) ) {
130
+ static $cb_counter = 1;
131
+ $columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All', 'subscribe2' ) . '</label>'
132
+ . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
133
+ $cb_counter++;
134
+ }
135
+
136
+ foreach ( $columns as $column_key => $column_display_name ) {
137
+ $class = array( 'manage-column', "column-$column_key" );
138
+
139
+ if ( in_array( $column_key, $hidden ) ) {
140
+ $class[] = 'hidden';
141
+ }
142
+
143
+ if ( 'cb' === $column_key ) {
144
+ $class[] = 'check-column';
145
+ }
146
+
147
+ if ( $column_key === $primary ) {
148
+ $class[] = 'column-primary';
149
+ }
150
+
151
+ if ( isset( $sortable[ $column_key ] ) ) {
152
+ list( $orderby, $desc_first ) = $sortable[ $column_key ];
153
+
154
+ if ( $current_orderby === $orderby ) {
155
+ $order = 'asc' === $current_order ? 'desc' : 'asc';
156
+ $class[] = 'sorted';
157
+ $class[] = $current_order;
158
+ } else {
159
+ $order = $desc_first ? 'desc' : 'asc';
160
+ $class[] = 'sortable';
161
+ $class[] = $desc_first ? 'asc' : 'desc';
162
+ }
163
+
164
+ $column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
165
+ }
166
+
167
+ $tag = ( 'cb' === $column_key ) ? 'td' : 'th';
168
+ $scope = ( 'th' === $tag ) ? 'scope="col"' : '';
169
+ $id = $with_id ? "id='$column_key'" : '';
170
+
171
+ if ( ! empty( $class ) ) {
172
+ $class = "class='" . join( ' ', $class ) . "'";
173
+ }
174
+
175
+ echo "<$tag $scope $id $class>$column_display_name</$tag>";
176
+ }
177
+ }
178
+
179
+ public function get_bulk_actions() {
180
  global $current_tab;
181
  if ( 'registered' === $current_tab ) {
182
  if ( is_multisite() ) {
183
  return array();
184
  } else {
185
+ return array(
186
+ 'delete' => __( 'Delete', 'subscribe2' ),
187
+ );
 
 
 
 
 
 
 
 
 
 
 
188
  }
189
  } else {
190
  $actions = array(
191
+ 'delete' => __( 'Delete', 'subscribe2' ),
192
+ 'toggle' => __( 'Toggle', 'subscribe2' ),
193
  );
194
  return $actions;
195
  }
196
  }
197
 
198
+ public function process_bulk_action() {
199
+ if ( in_array( $this->current_action(), array( 'delete', 'toggle' ) ) ) {
200
  if ( ! isset( $_REQUEST['subscriber'] ) ) {
201
+ echo '<div id="message" class="error"><p><strong>' . __( 'No users were selected.', 'subscribe2' ) . '</strong></p></div>';
202
  return;
203
  }
204
  }
206
  global $mysubscribe2, $current_user, $subscribers;
207
  $message = array();
208
  foreach ( $_REQUEST['subscriber'] as $address ) {
209
+ $address = trim( stripslashes( $address ) );
210
  if ( false !== $mysubscribe2->is_public( $address ) ) {
211
  $mysubscribe2->delete( $address );
212
  $key = array_search( $address, $subscribers );
235
  global $mysubscribe2, $current_user, $subscribers;
236
  $mysubscribe2->ip = $current_user->user_login;
237
  foreach ( $_REQUEST['subscriber'] as $address ) {
238
+ $address = trim( stripslashes( $address ) );
239
  $mysubscribe2->toggle( $address );
240
  if ( 'confirmed' === $_POST['what'] || 'unconfirmed' === $_POST['what'] ) {
241
  $key = array_search( $address, $subscribers );
244
  }
245
  echo '<div id="message" class="updated fade"><p><strong>' . __( 'Status changed!', 'subscribe2' ) . '</strong></p></div>';
246
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
248
 
249
+ public function pagination( $which ) {
250
  if ( empty( $this->_pagination_args ) ) {
251
  return;
252
  }
253
 
254
+ $total_items = intval( $this->_pagination_args['total_items'] );
255
+ $total_pages = intval( $this->_pagination_args['total_pages'] );
256
  $infinite_scroll = false;
257
  if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
258
  $infinite_scroll = $this->_pagination_args['infinite_scroll'];
262
  $this->screen->render_screen_reader_content( 'heading_pagination' );
263
  }
264
 
265
+ // Translators: Pagination
266
  $output = '<span class="displaying-num">' . sprintf( _n( '%s item', '%s items', $total_items, 'subscribe2' ), number_format_i18n( $total_items ) ) . '</span>';
267
 
268
  if ( isset( $_POST['what'] ) ) {
275
 
276
  $current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url );
277
 
278
+ if ( isset( $_REQUEST['what'] ) ) {
279
+ $current_url = add_query_arg(
280
+ array(
281
+ 'what' => $_REQUEST['what'],
282
+ ),
283
+ $current_url
284
+ );
 
285
  }
286
 
287
  if ( isset( $_POST['s'] ) ) {
288
+ $current_url = add_query_arg(
289
+ array(
290
+ 's' => $_POST['s'],
291
+ ),
292
+ $current_url
293
+ );
294
  }
295
 
296
  $page_links = array();
298
  $total_pages_before = '<span class="paging-input">';
299
  $total_pages_after = '</span>';
300
 
301
+ $disable_first = false;
302
+ $disable_last = false;
303
+ $disable_prev = false;
304
+ $disable_next = false;
305
 
306
  if ( 1 === $current ) {
307
  $disable_first = true;
308
+ $disable_prev = true;
309
  }
310
  if ( 2 === $current ) {
311
  $disable_first = true;
321
  if ( $disable_first ) {
322
  $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&laquo;</span>';
323
  } else {
324
+ $page_links[] = sprintf(
325
+ "<a class='first-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
326
  esc_url( remove_query_arg( 'paged', $current_url ) ),
327
  __( 'First page', 'subscribe2' ),
328
  '&laquo;'
332
  if ( $disable_prev ) {
333
  $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&lsaquo;</span>';
334
  } else {
335
+ $page_links[] = sprintf(
336
+ "<a class='prev-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
337
  esc_url( add_query_arg( 'paged', max( 1, $current - 1 ), $current_url ) ),
338
  __( 'Previous page', 'subscribe2' ),
339
  '&lsaquo;'
344
  $html_current_page = $current;
345
  $total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page', 'subscribe2' ) . '</span><span id="table-paging" class="paging-input">';
346
  } else {
347
+ $html_current_page = sprintf(
348
+ "%s<input class='current-page' id='current-page-selector' type='text' name='paged' value='%s' size='%d' aria-describedby='table-paging' />",
349
  '<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page', 'subscribe2' ) . '</label>',
350
  $current,
351
  strlen( $total_pages )
352
  );
353
  }
354
+
355
  $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
356
+ // Translators: Pagination
357
  $page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging', 'subscribe2' ), $html_current_page, $html_total_pages ) . $total_pages_after;
358
 
359
  if ( $disable_next ) {
360
  $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&rsaquo;</span>';
361
  } else {
362
+ $page_links[] = sprintf(
363
+ "<a class='next-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
364
  esc_url( add_query_arg( 'paged', min( $total_pages, $current + 1 ), $current_url ) ),
365
  __( 'Next page', 'subscribe2' ),
366
  '&rsaquo;'
370
  if ( $disable_last ) {
371
  $page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">&raquo;</span>';
372
  } else {
373
+ $page_links[] = sprintf(
374
+ "<a class='last-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
375
  esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
376
  __( 'Last page', 'subscribe2' ),
377
  '&raquo;'
389
  } else {
390
  $page_class = ' no-pages';
391
  }
392
+
393
  $this->_pagination = "<div class='tablenav-pages{$page_class}'>$output</div>";
394
 
395
  echo $this->_pagination;
396
  }
397
 
398
+ public function prepare_items() {
399
  global $mysubscribe2, $subscribers, $current_tab;
400
+
401
+ $user = get_current_user_id();
402
+ $screen = get_current_screen();
403
+ $screen_option = $screen->get_option( 'per_page', 'option' );
404
+ $per_page = get_user_meta( $user, $screen_option, true );
405
+ if ( empty( $per_page ) || $per_page < 1 ) {
406
+ $per_page = $screen->get_option( 'per_page', 'default' );
407
  }
408
 
409
+ $columns = $this->get_columns();
410
+ $hidden = array();
411
  $sortable = $this->get_sortable_columns();
412
+
413
  $this->_column_headers = array( $columns, $hidden, $sortable );
414
 
415
  $this->process_bulk_action();
419
  foreach ( (array) $subscribers as $email ) {
420
  $data[] = array(
421
  'email' => $email,
422
+ 'date' => $mysubscribe2->signup_date( $email ),
423
+ 'time' => $mysubscribe2->signup_time( $email ),
424
+ 'ip' => $mysubscribe2->signup_ip( $email ),
425
  );
426
  }
427
  } else {
428
  foreach ( (array) $subscribers as $subscriber ) {
429
  $data[] = array(
430
  'email' => $subscriber['user_email'],
431
+ 'id' => $subscriber['ID'],
432
  );
433
  }
434
  }
435
 
436
  function usort_reorder( $a, $b ) {
437
  $orderby = ( ! empty( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : 'email';
438
+ $order = ( ! empty( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : 'asc';
439
+ $result = strcasecmp( $a[ $orderby ], $b[ $orderby ] );
440
  return ( 'asc' === $order ) ? $result : -$result;
441
  }
442
  usort( $data, 'usort_reorder' );
447
  $current_page = $this->get_pagenum();
448
  }
449
  $total_items = count( $data );
450
+ $data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );
451
  $this->items = $data;
452
 
453
+ $this->set_pagination_args(
454
+ array(
455
+ 'total_items' => $total_items,
456
+ 'per_page' => $per_page,
457
+ 'total_pages' => ceil( $total_items / $per_page ),
458
+ )
459
+ );
460
  }
461
  }
 
classes/class-s2-multisite.php CHANGED
@@ -2,9 +2,9 @@
2
  class S2_Multisite {
3
  /* === WP Multisite specific functions === */
4
  /**
5
- Handles subscriptions and unsubscriptions for different blogs on WPMU installs
6
- */
7
- function wpmu_subscribe() {
8
  global $mysubscribe2;
9
  // subscribe to new blog
10
  if ( ! empty( $_GET['s2mu_subscribe'] ) ) {
@@ -31,7 +31,7 @@ class S2_Multisite {
31
 
32
  $cats_string = '';
33
  foreach ( $all_cats as $cat ) {
34
- ('' === $cats_string) ? $cats_string = "$cat->term_id" : $cats_string .= ",$cat->term_id";
35
  update_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_cat' ) . $cat->term_id, $cat->term_id );
36
  }
37
  if ( empty( $cats_string ) ) {
@@ -73,22 +73,22 @@ class S2_Multisite {
73
  switch_to_blog( key( $user_blogs ) );
74
  } else {
75
  // no longer a member of a blog
76
- wp_redirect( get_option( 'siteurl' ) ); // redirect to front page
77
  exit( 0 );
78
  }
79
  }
80
 
81
  // redirect to profile page
82
  $url = get_option( 'siteurl' ) . '/wp-admin/admin.php?page=s2';
83
- wp_redirect( $url );
84
  exit( 0 );
85
- } // end wpmu_subscribe()
86
 
87
  /**
88
- Obtain a list of current WordPress multiuser blogs
89
- Note this may affect performance but there is no alternative
90
- */
91
- function get_mu_blog_list() {
92
  global $wpdb;
93
  $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC", $wpdb->siteid ), ARRAY_A );
94
 
@@ -102,27 +102,31 @@ class S2_Multisite {
102
  }
103
 
104
  return apply_filters( 's2_mu_blog_list', $blog_list );
105
- } // end get_mu_blog_list()
106
 
107
  /**
108
- Register user details when new user is added to a multisite blog
109
- */
110
- function wpmu_add_user( $user_ID = 0 ) {
111
  global $mysubscribe2;
112
- if ( 0 === $user_ID ) { return; }
 
 
113
  if ( 'yes' === $mysubscribe2->subscribe2_options['autosub'] ) {
114
  $mysubscribe2->register( $user_ID, true );
115
  } else {
116
  $mysubscribe2->register( $user_ID, false );
117
  }
118
- } // end wpmu_add_user()
119
 
120
  /**
121
- Delete user details when a user is removed from a multisite blog
122
- */
123
- function wpmu_remove_user( $user_ID ) {
124
  global $mysubscribe2;
125
- if ( 0 === $user_ID ) { return; }
 
 
126
  delete_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_format' ) );
127
  delete_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_autosub' ) );
128
  $cats = get_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), true );
@@ -133,12 +137,12 @@ class S2_Multisite {
133
  }
134
  }
135
  delete_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ) );
136
- } // end wpmu_remove_user()
137
 
138
  /**
139
- Rename WPMU widgets on upgrade without requiring user to re-enable
140
- */
141
- function namechange_subscribe2_widget() {
142
  global $wpdb;
143
  $blogs = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs}" );
144
 
@@ -146,14 +150,18 @@ class S2_Multisite {
146
  switch_to_blog( $blog );
147
 
148
  $sidebars = get_option( 'sidebars_widgets' );
149
- if ( empty( $sidebars ) || ! is_array( $sidebars ) ) { return; }
 
 
150
  $changed = false;
151
  foreach ( $sidebars as $s => $sidebar ) {
152
- if ( empty( $sidebar ) || ! is_array( $sidebar ) ) { break; }
 
 
153
  foreach ( $sidebar as $w => $widget ) {
154
  if ( 'subscribe2widget' === $widget ) {
155
  $sidebars[ $s ][ $w ] = 'subscribe2';
156
- $changed = true;
157
  }
158
  }
159
  }
@@ -162,6 +170,5 @@ class S2_Multisite {
162
  }
163
  restore_current_blog();
164
  }
165
- } // end namechange_subscribe2_widget()
166
  }
167
- ?>
2
  class S2_Multisite {
3
  /* === WP Multisite specific functions === */
4
  /**
5
+ * Handles subscriptions and unsubscriptions for different blogs on WPMU installs
6
+ */
7
+ public function wpmu_subscribe() {
8
  global $mysubscribe2;
9
  // subscribe to new blog
10
  if ( ! empty( $_GET['s2mu_subscribe'] ) ) {
31
 
32
  $cats_string = '';
33
  foreach ( $all_cats as $cat ) {
34
+ ( '' === $cats_string ) ? $cats_string = "$cat->term_id" : $cats_string .= ",$cat->term_id";
35
  update_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_cat' ) . $cat->term_id, $cat->term_id );
36
  }
37
  if ( empty( $cats_string ) ) {
73
  switch_to_blog( key( $user_blogs ) );
74
  } else {
75
  // no longer a member of a blog
76
+ wp_safe_redirect( get_option( 'siteurl' ) ); // redirect to front page
77
  exit( 0 );
78
  }
79
  }
80
 
81
  // redirect to profile page
82
  $url = get_option( 'siteurl' ) . '/wp-admin/admin.php?page=s2';
83
+ wp_safe_redirect( $url );
84
  exit( 0 );
85
+ }
86
 
87
  /**
88
+ * Obtain a list of current WordPress multiuser blogs
89
+ * Note this may affect performance but there is no alternative
90
+ */
91
+ public function get_mu_blog_list() {
92
  global $wpdb;
93
  $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC", $wpdb->siteid ), ARRAY_A );
94
 
102
  }
103
 
104
  return apply_filters( 's2_mu_blog_list', $blog_list );
105
+ }
106
 
107
  /**
108
+ * Register user details when new user is added to a multisite blog
109
+ */
110
+ public function wpmu_add_user( $user_ID = 0 ) {
111
  global $mysubscribe2;
112
+ if ( 0 === $user_ID ) {
113
+ return;
114
+ }
115
  if ( 'yes' === $mysubscribe2->subscribe2_options['autosub'] ) {
116
  $mysubscribe2->register( $user_ID, true );
117
  } else {
118
  $mysubscribe2->register( $user_ID, false );
119
  }
120
+ }
121
 
122
  /**
123
+ * Delete user details when a user is removed from a multisite blog
124
+ */
125
+ public function wpmu_remove_user( $user_ID ) {
126
  global $mysubscribe2;
127
+ if ( 0 === $user_ID ) {
128
+ return;
129
+ }
130
  delete_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_format' ) );
131
  delete_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_autosub' ) );
132
  $cats = get_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), true );
137
  }
138
  }
139
  delete_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ) );
140
+ }
141
 
142
  /**
143
+ * Rename WPMU widgets on upgrade without requiring user to re-enable
144
+ */
145
+ public function namechange_subscribe2_widget() {
146
  global $wpdb;
147
  $blogs = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs}" );
148
 
150
  switch_to_blog( $blog );
151
 
152
  $sidebars = get_option( 'sidebars_widgets' );
153
+ if ( empty( $sidebars ) || ! is_array( $sidebars ) ) {
154
+ return;
155
+ }
156
  $changed = false;
157
  foreach ( $sidebars as $s => $sidebar ) {
158
+ if ( empty( $sidebar ) || ! is_array( $sidebar ) ) {
159
+ break;
160
+ }
161
  foreach ( $sidebar as $w => $widget ) {
162
  if ( 'subscribe2widget' === $widget ) {
163
  $sidebars[ $s ][ $w ] = 'subscribe2';
164
+ $changed = true;
165
  }
166
  }
167
  }
170
  }
171
  restore_current_blog();
172
  }
173
+ }
174
  }
 
classes/class-s2-upgrade.php CHANGED
@@ -1,15 +1,87 @@
1
  <?php
2
  class S2_Upgrade {
 
3
  /**
4
- Core upgrade function for the database and settings
5
- */
6
- function upgrade() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  global $mysubscribe2;
8
  // load our translations and strings
9
  $mysubscribe2->load_translations();
10
 
11
  // ensure that the options are in the database
12
- require( S2PATH . 'include/options.php' );
13
  // catch older versions that didn't use serialised options
14
  if ( ! isset( $mysubscribe2->subscribe2_options['version'] ) ) {
15
  $mysubscribe2->subscribe2_options['version'] = '2.0';
@@ -18,73 +90,71 @@ class S2_Upgrade {
18
  // let's take the time to ensure that database entries exist for all registered users
19
  $this->upgrade_core();
20
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '2.3', '<' ) ) {
21
- $this->upgrade23();
22
  $mysubscribe2->subscribe2_options['version'] = '2.3';
23
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
24
  }
25
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '5.1', '<' ) ) {
26
- $this->upgrade51();
27
  $mysubscribe2->subscribe2_options['version'] = '5.1';
28
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
29
  }
30
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '5.6', '<' ) ) {
31
- $this->upgrade56();
32
  $mysubscribe2->subscribe2_options['version'] = '5.6';
33
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
34
  }
35
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '5.9', '<' ) ) {
36
- $this->upgrade59();
37
  $mysubscribe2->subscribe2_options['version'] = '5.9';
38
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
39
  }
40
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '6.4', '<' ) ) {
41
- $this->upgrade64();
42
  $mysubscribe2->subscribe2_options['version'] = '6.4';
43
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
44
  }
45
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '7.0', '<' ) ) {
46
- $this->upgrade70();
47
  $mysubscribe2->subscribe2_options['version'] = '7.0';
48
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
49
  }
50
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '8.5', '<' ) ) {
51
- $this->upgrade85();
52
  $mysubscribe2->subscribe2_options['version'] = '8.5';
53
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
54
  }
55
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '8.6', '<' ) ) {
56
- $this->upgrade86();
57
  $mysubscribe2->subscribe2_options['version'] = '8.6';
58
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
59
  }
60
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '8.8', '<' ) ) {
61
- $this->upgrade88();
62
  $mysubscribe2->subscribe2_options['version'] = '8.8';
63
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
64
  }
65
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '9.5', '<' ) ) {
66
- $this->upgrade95();
67
  $mysubscribe2->subscribe2_options['version'] = '9.5';
68
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
69
  }
70
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '10.14', '<' ) ) {
71
- $this->upgrade1014();
72
  $mysubscribe2->subscribe2_options['version'] = '10.14';
73
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
74
  }
75
- if ( version_compare( $mysubscribe2->subscribe2_options['version'], '10.15', '<' ) ) {
76
- $this->upgrade1015();
77
- $mysubscribe2->subscribe2_options['version'] = '10.15';
78
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
79
  }
80
 
81
  $mysubscribe2->subscribe2_options['version'] = S2VERSION;
82
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
83
-
84
- return;
85
  } // end upgrade()
86
 
87
- function upgrade_core() {
88
  // let's take the time to double check data for registered users
89
  global $mysubscribe2;
90
  if ( version_compare( $mysubscribe2->wp_release, '3.5', '<' ) ) {
@@ -99,14 +169,14 @@ class S2_Upgrade {
99
  $args = array(
100
  'meta_query' => array(
101
  array(
102
- 'key' => $mysubscribe2->get_usermeta_keyname( 's2_format' ),
103
  'compare' => 'NOT EXISTS',
104
  ),
105
  ),
106
  );
107
 
108
  $user_query = new WP_User_Query( $args );
109
- $users = $user_query->get_results();
110
  if ( ! empty( $users ) ) {
111
  foreach ( $users as $user ) {
112
  $mysubscribe2->register( $user->ID );
@@ -114,43 +184,43 @@ class S2_Upgrade {
114
  }
115
  }
116
  // let's make sure that the 's2_authors' key exists on every site for all Registered Users too
117
- $this->upgrade70();
118
- } // end upgrade_core()
119
 
120
- function upgrade23() {
121
  global $mysubscribe2, $wpdb;
122
 
123
- // include upgrade-functions for maybe_add_column;
124
  if ( ! function_exists( 'maybe_add_column' ) ) {
125
- require_once( ABSPATH . 'wp-admin/install-helper.php' );
126
  }
127
  $date = date( 'Y-m-d' );
128
- maybe_add_column( $mysubscribe2->public, 'date', "ALTER TABLE $mysubscribe2->public ADD date DATE DEFAULT '$date' NOT NULL AFTER active" );
129
 
130
  // update the options table to serialized format
131
- $old_options = $wpdb->get_col( "SELECT option_name from $wpdb->options where option_name LIKE 's2%' AND option_name !== 's2_future_posts'" );
132
 
133
  if ( ! empty( $old_options ) ) {
134
  foreach ( $old_options as $option ) {
135
- $value = get_option( $option );
136
  $option_array = substr( $option, 3 );
137
  $mysubscribe2->subscribe2_options[ $option_array ] = $value;
138
  delete_option( $option );
139
  }
140
  }
141
- } // end upgrade23()
142
 
143
- function upgrade51() {
144
- global $mysubscribe2;
145
 
146
- // include upgrade-functions for maybe_add_column;
147
  if ( ! function_exists( 'maybe_add_column' ) ) {
148
- require_once( ABSPATH . 'wp-admin/install-helper.php' );
149
  }
150
- maybe_add_column( $mysubscribe2->public, 'ip', "ALTER TABLE $mysubscribe2->public ADD ip char(64) DEFAULT 'admin' NOT NULL AFTER date" );
151
- } // end upgrade51()
152
 
153
- function upgrade56() {
154
  global $mysubscribe2;
155
  // correct autoformat to upgrade from pre 5.6
156
  if ( 'text' === $mysubscribe2->subscribe2_options['autoformat'] ) {
@@ -159,36 +229,37 @@ class S2_Upgrade {
159
  if ( 'full' === $mysubscribe2->subscribe2_options['autoformat'] ) {
160
  $mysubscribe2->subscribe2_options['autoformat'] = 'post';
161
  }
162
- } // end upgrade56()
163
 
164
- function upgrade59() {
165
  global $mysubscribe2, $wpdb;
166
  // ensure existing public subscriber emails are all sanitized
167
- $confirmed = $mysubscribe2->get_public();
168
- $unconfirmed = $mysubscribe2->get_public( 0 );
169
  $public_subscribers = array_merge( (array) $confirmed, (array) $unconfirmed );
170
 
171
  foreach ( $public_subscribers as $email ) {
172
  $new_email = $mysubscribe2->sanitize_email( $email );
173
  if ( $email !== $new_email ) {
174
- $wpdb->get_results( $wpdb->prepare( "UPDATE $mysubscribe2->public SET email=%s WHERE CAST(email as binary)=%s", $new_email, $email ) );
175
  }
176
  }
177
- } // end upgrade59()
178
 
179
- function upgrade64() {
180
  global $mysubscribe2;
181
  // change old CAPITALISED keywords to those in {PARENTHESES}; since version 6.4
182
  $keywords = array( 'BLOGNAME', 'BLOGLINK', 'TITLE', 'POST', 'POSTTIME', 'TABLE', 'TABLELINKS', 'PERMALINK', 'TINYLINK', 'DATE', 'TIME', 'MYNAME', 'EMAIL', 'AUTHORNAME', 'LINK', 'CATS', 'TAGS', 'COUNT', 'ACTION' );
183
- $keyword = implode( '|', $keywords );
184
- $regex = '/(?<!\{)\b(' . $keyword . ')\b(?!\{)/xm';
185
- $replace = '{\1}';
186
- $mysubscribe2->subscribe2_options['mailtext'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['mailtext'] );
 
187
  $mysubscribe2->subscribe2_options['notification_subject'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['notification_subject'] );
188
- $mysubscribe2->subscribe2_options['confirm_email'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['confirm_email'] );
189
- $mysubscribe2->subscribe2_options['confirm_subject'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['confirm_subject'] );
190
- $mysubscribe2->subscribe2_options['remind_email'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['remind_email'] );
191
- $mysubscribe2->subscribe2_options['remind_subject'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['remind_subject'] );
192
 
193
  if ( version_compare( $mysubscribe2->wp_release, '3.5', '<' ) ) {
194
  $users = $mysubscribe2->get_all_registered( 'ID' );
@@ -205,7 +276,7 @@ class S2_Upgrade {
205
  if ( strstr( $subscribed, '-1' ) ) {
206
  // make sure we remove '-1' from any settings
207
  $old_cats = explode( ',', $subscribed );
208
- $pos = array_search( '-1', $old_cats );
209
  unset( $old_cats[ $pos ] );
210
  $cats = implode( ',', $old_cats );
211
  update_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), $cats );
@@ -213,23 +284,23 @@ class S2_Upgrade {
213
  }
214
  } else {
215
  $args = array(
216
- 'relation' => 'AND',
217
  'meta_query' => array(
218
  array(
219
- 'key' => $mysubscribe2->get_usermeta_keyname( 's2_format' ),
220
  'value' => 'html',
221
  ),
222
  ),
223
  'meta_query' => array(
224
  array(
225
- 'key' => 's2_excerpt',
226
  'compare' => 'EXISTS',
227
  ),
228
  ),
229
  );
230
 
231
  $user_query = new WP_User_Query( $args );
232
- $users = $user_query->get_results();
233
  if ( ! empty( $users ) ) {
234
  foreach ( $users as $user ) {
235
  delete_user_meta( $user->ID, 's2_excerpt' );
@@ -237,23 +308,23 @@ class S2_Upgrade {
237
  }
238
 
239
  $args = array(
240
- 'relation' => 'AND',
241
  'meta_query' => array(
242
  array(
243
- 'key' => $mysubscribe2->get_usermeta_keyname( 's2_format' ),
244
  'value' => 'text',
245
  ),
246
  ),
247
  'meta_query' => array(
248
  array(
249
- 'key' => 's2_excerpt',
250
  'compare' => 'EXISTS',
251
  ),
252
  ),
253
  );
254
 
255
  $user_query = new WP_User_Query( $args );
256
- $users = $user_query->get_results();
257
  if ( ! empty( $users ) ) {
258
  foreach ( $users as $user ) {
259
  update_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_format' ), get_user_meta( $user->ID, 's2_excerpt' ) );
@@ -264,20 +335,20 @@ class S2_Upgrade {
264
  $args = array(
265
  'meta_query' => array(
266
  array(
267
- 'key' => $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ),
268
- 'value' => '-1',
269
  'compare' => 'LIKE',
270
  ),
271
  ),
272
  );
273
 
274
  $user_query = new WP_User_Query( $args );
275
- $users = $user_query->get_results();
276
  if ( ! empty( $users ) ) {
277
  foreach ( $users as $user ) {
278
  $subscribed = get_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), true );
279
- $old_cats = explode( ',', $subscribed );
280
- $pos = array_search( '-1', $old_cats );
281
  unset( $old_cats[ $pos ] );
282
  $cats = implode( ',', $old_cats );
283
  update_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), $cats );
@@ -294,8 +365,8 @@ class S2_Upgrade {
294
  // get categories which the user is subscribed to (old ones)
295
  $categories = get_user_meta( $user_ID, 's2_subscribed', true );
296
  $categories = explode( ',', $categories );
297
- $format = get_user_meta( $user_ID, 's2_format', true );
298
- $autosub = get_user_meta( $user_ID, 's2_autosub', true );
299
 
300
  // load blogs of user (only if we need them)
301
  $blogs = array();
@@ -306,7 +377,7 @@ class S2_Upgrade {
306
  foreach ( $blogs as $blog ) {
307
  switch_to_blog( $blog->userblog_id );
308
 
309
- $blog_categories = (array) $wpdb->get_col( "SELECT term_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'category'" );
310
  $subscribed_categories = array_intersect( $categories, $blog_categories );
311
  if ( ! empty( $subscribed_categories ) ) {
312
  foreach ( $subscribed_categories as $subscribed_category ) {
@@ -332,9 +403,9 @@ class S2_Upgrade {
332
  }
333
  }
334
  }
335
- } // end upgrade64()
336
 
337
- function upgrade70() {
338
  global $mysubscribe2, $wpdb;
339
  if ( version_compare( $mysubscribe2->wp_release, '3.5', '<' ) ) {
340
  $users = $wpdb->get_col( $wpdb->prepare( "SELECT ID from $wpdb->users WHERE ID NOT IN (SELECT user_id from $wpdb->usermeta WHERE meta_key=%s", $mysubscribe2->get_usermeta_keyname( 's2_authors' ) ) );
@@ -348,64 +419,69 @@ class S2_Upgrade {
348
  $args = array(
349
  'meta_query' => array(
350
  array(
351
- 'key' => $mysubscribe2->get_usermeta_keyname( 's2_authors' ),
352
  'compare' => 'NOT EXISTS',
353
  ),
354
  ),
355
  );
356
 
357
  $user_query = new WP_User_Query( $args );
358
- $users = $user_query->get_results();
359
  if ( ! empty( $users ) ) {
360
  foreach ( $users as $user ) {
361
  update_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_authors' ), '' );
362
  }
363
  }
364
  }
365
- } // end upgrade70()
366
 
367
- function upgrade85() {
368
  global $mysubscribe2, $wpdb;
369
 
370
- // include upgrade-functions for maybe_add_column;
371
  if ( ! function_exists( 'maybe_add_column' ) ) {
372
- require_once( ABSPATH . 'wp-admin/install-helper.php' );
373
  }
374
- maybe_add_column( $mysubscribe2->public, 'time', "ALTER TABLE $mysubscribe2->public ADD time TIME DEFAULT '00:00:00' NOT NULL AFTER date" );
375
 
376
  // update postmeta field to a protected name, from version 8.5
377
  $wpdb->query( "UPDATE $wpdb->postmeta SET meta_key = '_s2mail' WHERE meta_key = 's2mail'" );
378
- } // end upgrade85()
379
 
380
- function upgrade86() {
381
  global $mysubscribe2, $wpdb;
382
 
383
- // include upgrade-functions for maybe_add_column;
384
  if ( ! function_exists( 'maybe_add_column' ) ) {
385
- require_once( ABSPATH . 'wp-admin/install-helper.php' );
386
  }
387
- maybe_add_column( $mysubscribe2->public, 'conf_date', "ALTER TABLE $mysubscribe2->public ADD conf_date DATE AFTER ip" );
388
- maybe_add_column( $mysubscribe2->public, 'conf_time', "ALTER TABLE $mysubscribe2->public ADD conf_time TIME AFTER conf_date" );
389
- maybe_add_column( $mysubscribe2->public, 'conf_ip', "ALTER TABLE $mysubscribe2->public ADD conf_ip char(64) AFTER conf_time" );
390
 
391
  // remove unnecessary table data
392
  $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 's2_cat'" );
393
 
394
- $sql = "SELECT ID FROM $wpdb->users INNER JOIN $wpdb->usermeta ON ( $wpdb->users.ID = $wpdb->usermeta.user_id) WHERE ( $wpdb->usermeta.meta_key = '" . $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ) . "' AND $wpdb->usermeta.meta_value LIKE ',%' )";
395
- $users = $wpdb->get_results( $sql );
 
 
 
 
 
396
  foreach ( $users as $user ) {
397
  // make sure we remove leading ',' from this setting
398
  $subscribed = get_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), true );
399
- $old_cats = explode( ',', $subscribed );
400
  unset( $old_cats[0] );
401
  $cats = implode( ',', $old_cats );
402
  update_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), $cats );
403
  }
404
- } // end upgrade86()
405
 
406
- function upgrade88() {
407
  // to ensure compulsory category collects all users we need there to be s2_subscribed meta-keys for all users
408
- global $mysubscribe2;
409
 
410
  if ( version_compare( $mysubscribe2->wp_release, '3.5', '<' ) ) {
411
  $all_registered = $mysubscribe2->get_all_registered( 'ID' );
@@ -421,14 +497,14 @@ class S2_Upgrade {
421
  $args = array(
422
  'meta_query' => array(
423
  array(
424
- 'key' => $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ),
425
  'compare' => 'NOT EXISTS',
426
  ),
427
  ),
428
  );
429
 
430
  $user_query = new WP_User_Query( $args );
431
- $users = $user_query->get_results();
432
  if ( ! empty( $users ) ) {
433
  foreach ( $users as $user ) {
434
  update_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), '' );
@@ -436,23 +512,23 @@ class S2_Upgrade {
436
  }
437
  }
438
 
439
- // check the time column again as the upgrade86() function contained a bug
440
  // include upgrade-functions for maybe_add_column;
441
  if ( ! function_exists( 'maybe_add_column' ) ) {
442
- require_once( ABSPATH . 'wp-admin/install-helper.php' );
443
  }
444
- maybe_add_column( $mysubscribe2->public, 'time', "ALTER TABLE $mysubscribe2->public ADD time TIME DEFAULT '00:00:00' NOT NULL AFTER date" );
445
- } // end upgrade88()
446
 
447
- function upgrade95() {
448
  global $mysubscribe2;
449
  if ( 'never' !== $mysubscribe2->subscribe2_options['email_freq'] ) {
450
  $mysubscribe2->subscribe2_options['last_s2cron'] = '';
451
  unset( $mysubscribe2->subscribe2_options['previous_s2cron'] );
452
  }
453
- } // end upgrade95()
454
 
455
- function upgrade1014() {
456
  global $mysubscribe2;
457
  if ( ! isset( $mysubscribe2->subscribe2_options['frontend_form'] ) ) {
458
  $mysubscribe2->subscribe2_options['frontend_form'] = '0';
@@ -460,13 +536,19 @@ class S2_Upgrade {
460
  if ( ! isset( $mysubscribe2->subscribe2_options['dismiss_sender_warning'] ) ) {
461
  $mysubscribe2->subscribe2_options['dismiss_sender_warning'] = '0';
462
  }
463
- } // end upgrade1014()
464
 
465
- function upgrade1015() {
466
  global $mysubscribe2;
467
  if ( ! isset( $mysubscribe2->subscribe2_options['js_ip_updater'] ) ) {
468
  $mysubscribe2->subscribe2_options['js_ip_updater'] = '0';
469
  }
470
- } // end upgrade1015()
 
 
 
 
 
 
 
471
  }
472
- ?>
1
  <?php
2
  class S2_Upgrade {
3
+ /* ===== Install and reset ===== */
4
  /**
5
+ * Install our table
6
+ */
7
+ public function install() {
8
+ global $wpdb, $mysubscribe2;
9
+ // load our translations and strings
10
+ $mysubscribe2->load_translations();
11
+
12
+ // include upgrade functions
13
+ if ( ! function_exists( 'maybe_create_table' ) ) {
14
+ require_once ABSPATH . 'wp-admin/install-helper.php';
15
+ }
16
+ $charset_collate = '';
17
+ if ( ! empty( $wpdb->charset ) ) {
18
+ $charset_collate = "DEFAULT CHARACTER SET {$wpdb->charset}";
19
+ }
20
+
21
+ if ( ! empty( $wpdb->collate ) ) {
22
+ $charset_collate .= " COLLATE {$wpdb->collate}";
23
+ }
24
+
25
+ $date = date( 'Y-m-d' );
26
+ $sql = "CREATE TABLE $wpdb->subscribe2 (
27
+ id int(11) NOT NULL auto_increment,
28
+ email varchar(64) NOT NULL default '',
29
+ active tinyint(1) default 0,
30
+ date DATE default '$date' NOT NULL,
31
+ time TIME DEFAULT '00:00:00' NOT NULL,
32
+ ip char(64) NOT NULL default 'admin',
33
+ conf_date DATE,
34
+ conf_time TIME,
35
+ conf_ip char(64),
36
+ PRIMARY KEY (id) ) $charset_collate";
37
+
38
+ // create the table, as needed
39
+ maybe_create_table( $wpdb->subscribe2, $sql );
40
+
41
+ // safety check if options exist and if not create them
42
+ if ( ! is_array( $mysubscribe2->subscribe2_options ) ) {
43
+ $this->reset();
44
+ }
45
+
46
+ // create table entries for registered users
47
+ $users = $mysubscribe2->get_all_registered( 'ID' );
48
+ if ( ! empty( $users ) ) {
49
+ foreach ( $users as $user_ID ) {
50
+ $check_format = get_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_format' ), true );
51
+ if ( empty( $check_format ) ) {
52
+ // no prior settings so create them
53
+ $mysubscribe2->register( $user_ID );
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Reset our options
61
+ */
62
+ public function reset() {
63
+ // load our translations and strings
64
+ global $mysubscribe2;
65
+ $mysubscribe2->load_translations();
66
+
67
+ delete_option( 'subscribe2_options' );
68
+ wp_clear_scheduled_hook( 's2_digest_cron' );
69
+ unset( $mysubscribe2->subscribe2_options );
70
+ require S2PATH . 'include/options.php';
71
+ $mysubscribe2->subscribe2_options['version'] = S2VERSION;
72
+ update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
73
+ }
74
+
75
+ /**
76
+ * Core upgrade function for the database and settings
77
+ */
78
+ public function upgrade() {
79
  global $mysubscribe2;
80
  // load our translations and strings
81
  $mysubscribe2->load_translations();
82
 
83
  // ensure that the options are in the database
84
+ require S2PATH . 'include/options.php';
85
  // catch older versions that didn't use serialised options
86
  if ( ! isset( $mysubscribe2->subscribe2_options['version'] ) ) {
87
  $mysubscribe2->subscribe2_options['version'] = '2.0';
90
  // let's take the time to ensure that database entries exist for all registered users
91
  $this->upgrade_core();
92
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '2.3', '<' ) ) {
93
+ $this->upgrade2_3();
94
  $mysubscribe2->subscribe2_options['version'] = '2.3';
95
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
96
  }
97
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '5.1', '<' ) ) {
98
+ $this->upgrade5_1();
99
  $mysubscribe2->subscribe2_options['version'] = '5.1';
100
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
101
  }
102
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '5.6', '<' ) ) {
103
+ $this->upgrade5_6();
104
  $mysubscribe2->subscribe2_options['version'] = '5.6';
105
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
106
  }
107
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '5.9', '<' ) ) {
108
+ $this->upgrade5_9();
109
  $mysubscribe2->subscribe2_options['version'] = '5.9';
110
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
111
  }
112
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '6.4', '<' ) ) {
113
+ $this->upgrade6_4();
114
  $mysubscribe2->subscribe2_options['version'] = '6.4';
115
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
116
  }
117
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '7.0', '<' ) ) {
118
+ $this->upgrade7_0();
119
  $mysubscribe2->subscribe2_options['version'] = '7.0';
120
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
121
  }
122
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '8.5', '<' ) ) {
123
+ $this->upgrade8_5();
124
  $mysubscribe2->subscribe2_options['version'] = '8.5';
125
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
126
  }
127
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '8.6', '<' ) ) {
128
+ $this->upgrade8_6();
129
  $mysubscribe2->subscribe2_options['version'] = '8.6';
130
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
131
  }
132
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '8.8', '<' ) ) {
133
+ $this->upgrade8_8();
134
  $mysubscribe2->subscribe2_options['version'] = '8.8';
135
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
136
  }
137
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '9.5', '<' ) ) {
138
+ $this->upgrade9_5();
139
  $mysubscribe2->subscribe2_options['version'] = '9.5';
140
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
141
  }
142
  if ( version_compare( $mysubscribe2->subscribe2_options['version'], '10.14', '<' ) ) {
143
+ $this->upgrade10_14();
144
  $mysubscribe2->subscribe2_options['version'] = '10.14';
145
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
146
  }
147
+ if ( version_compare( $mysubscribe2->subscribe2_options['version'], '10.23', '<' ) ) {
148
+ $this->upgrade10_23();
149
+ $mysubscribe2->subscribe2_options['version'] = '10.23';
150
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
151
  }
152
 
153
  $mysubscribe2->subscribe2_options['version'] = S2VERSION;
154
  update_option( 'subscribe2_options', $mysubscribe2->subscribe2_options );
 
 
155
  } // end upgrade()
156
 
157
+ private function upgrade_core() {
158
  // let's take the time to double check data for registered users
159
  global $mysubscribe2;
160
  if ( version_compare( $mysubscribe2->wp_release, '3.5', '<' ) ) {
169
  $args = array(
170
  'meta_query' => array(
171
  array(
172
+ 'key' => $mysubscribe2->get_usermeta_keyname( 's2_format' ),
173
  'compare' => 'NOT EXISTS',
174
  ),
175
  ),
176
  );
177
 
178
  $user_query = new WP_User_Query( $args );
179
+ $users = $user_query->get_results();
180
  if ( ! empty( $users ) ) {
181
  foreach ( $users as $user ) {
182
  $mysubscribe2->register( $user->ID );
184
  }
185
  }
186
  // let's make sure that the 's2_authors' key exists on every site for all Registered Users too
187
+ $this->upgrade7_0();
188
+ }
189
 
190
+ private function upgrade2_3() {
191
  global $mysubscribe2, $wpdb;
192
 
193
+ // include upgrade functions
194
  if ( ! function_exists( 'maybe_add_column' ) ) {
195
+ require_once ABSPATH . 'wp-admin/install-helper.php';
196
  }
197
  $date = date( 'Y-m-d' );
198
+ maybe_add_column( $wpdb->subscribe2, 'date', "ALTER TABLE $wpdb->subscribe2 ADD date DATE DEFAULT '$date' NOT NULL AFTER active" );
199
 
200
  // update the options table to serialized format
201
+ $old_options = $wpdb->get_col( "SELECT option_name from $wpdb->options where option_name LIKE 's2%' AND option_name <> 's2_future_posts'" );
202
 
203
  if ( ! empty( $old_options ) ) {
204
  foreach ( $old_options as $option ) {
205
+ $value = get_option( $option );
206
  $option_array = substr( $option, 3 );
207
  $mysubscribe2->subscribe2_options[ $option_array ] = $value;
208
  delete_option( $option );
209
  }
210
  }
211
+ }
212
 
213
+ private function upgrade5_1() {
214
+ global $mysubscribe2, $wpdb;
215
 
216
+ // include upgrade functions
217
  if ( ! function_exists( 'maybe_add_column' ) ) {
218
+ require_once ABSPATH . 'wp-admin/install-helper.php';
219
  }
220
+ maybe_add_column( $wpdb->subscribe2, 'ip', "ALTER TABLE $wpdb->subscribe2 ADD ip char(64) DEFAULT 'admin' NOT NULL AFTER date" );
221
+ }
222
 
223
+ private function upgrade5_6() {
224
  global $mysubscribe2;
225
  // correct autoformat to upgrade from pre 5.6
226
  if ( 'text' === $mysubscribe2->subscribe2_options['autoformat'] ) {
229
  if ( 'full' === $mysubscribe2->subscribe2_options['autoformat'] ) {
230
  $mysubscribe2->subscribe2_options['autoformat'] = 'post';
231
  }
232
+ }
233
 
234
+ private function upgrade5_9() {
235
  global $mysubscribe2, $wpdb;
236
  // ensure existing public subscriber emails are all sanitized
237
+ $confirmed = $mysubscribe2->get_public();
238
+ $unconfirmed = $mysubscribe2->get_public( 0 );
239
  $public_subscribers = array_merge( (array) $confirmed, (array) $unconfirmed );
240
 
241
  foreach ( $public_subscribers as $email ) {
242
  $new_email = $mysubscribe2->sanitize_email( $email );
243
  if ( $email !== $new_email ) {
244
+ $wpdb->get_results( $wpdb->prepare( "UPDATE $wpdb->subscribe2 SET email=%s WHERE CAST(email as binary)=%s", $new_email, $email ) );
245
  }
246
  }
247
+ }
248
 
249
+ private function upgrade6_4() {
250
  global $mysubscribe2;
251
  // change old CAPITALISED keywords to those in {PARENTHESES}; since version 6.4
252
  $keywords = array( 'BLOGNAME', 'BLOGLINK', 'TITLE', 'POST', 'POSTTIME', 'TABLE', 'TABLELINKS', 'PERMALINK', 'TINYLINK', 'DATE', 'TIME', 'MYNAME', 'EMAIL', 'AUTHORNAME', 'LINK', 'CATS', 'TAGS', 'COUNT', 'ACTION' );
253
+ $keyword = implode( '|', $keywords );
254
+ $regex = '/(?<!\{)\b(' . $keyword . ')\b(?!\{)/xm';
255
+ $replace = '{\1}';
256
+
257
+ $mysubscribe2->subscribe2_options['mailtext'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['mailtext'] );
258
  $mysubscribe2->subscribe2_options['notification_subject'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['notification_subject'] );
259
+ $mysubscribe2->subscribe2_options['confirm_email'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['confirm_email'] );
260
+ $mysubscribe2->subscribe2_options['confirm_subject'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['confirm_subject'] );
261
+ $mysubscribe2->subscribe2_options['remind_email'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['remind_email'] );
262
+ $mysubscribe2->subscribe2_options['remind_subject'] = preg_replace( $regex, $replace, $mysubscribe2->subscribe2_options['remind_subject'] );
263
 
264
  if ( version_compare( $mysubscribe2->wp_release, '3.5', '<' ) ) {
265
  $users = $mysubscribe2->get_all_registered( 'ID' );
276
  if ( strstr( $subscribed, '-1' ) ) {
277
  // make sure we remove '-1' from any settings
278
  $old_cats = explode( ',', $subscribed );
279
+ $pos = array_search( '-1', $old_cats );
280
  unset( $old_cats[ $pos ] );
281
  $cats = implode( ',', $old_cats );
282
  update_user_meta( $user_ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), $cats );
284
  }
285
  } else {
286
  $args = array(
287
+ 'relation' => 'AND',
288
  'meta_query' => array(
289
  array(
290
+ 'key' => $mysubscribe2->get_usermeta_keyname( 's2_format' ),
291
  'value' => 'html',
292
  ),
293
  ),
294
  'meta_query' => array(
295
  array(
296
+ 'key' => 's2_excerpt',
297
  'compare' => 'EXISTS',
298
  ),
299
  ),
300
  );
301
 
302
  $user_query = new WP_User_Query( $args );
303
+ $users = $user_query->get_results();
304
  if ( ! empty( $users ) ) {
305
  foreach ( $users as $user ) {
306
  delete_user_meta( $user->ID, 's2_excerpt' );
308
  }
309
 
310
  $args = array(
311
+ 'relation' => 'AND',
312
  'meta_query' => array(
313
  array(
314
+ 'key' => $mysubscribe2->get_usermeta_keyname( 's2_format' ),
315
  'value' => 'text',
316
  ),
317
  ),
318
  'meta_query' => array(
319
  array(
320
+ 'key' => 's2_excerpt',
321
  'compare' => 'EXISTS',
322
  ),
323
  ),
324
  );
325
 
326
  $user_query = new WP_User_Query( $args );
327
+ $users = $user_query->get_results();
328
  if ( ! empty( $users ) ) {
329
  foreach ( $users as $user ) {
330
  update_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_format' ), get_user_meta( $user->ID, 's2_excerpt' ) );
335
  $args = array(
336
  'meta_query' => array(
337
  array(
338
+ 'key' => $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ),
339
+ 'value' => '-1',
340
  'compare' => 'LIKE',
341
  ),
342
  ),
343
  );
344
 
345
  $user_query = new WP_User_Query( $args );
346
+ $users = $user_query->get_results();
347
  if ( ! empty( $users ) ) {
348
  foreach ( $users as $user ) {
349
  $subscribed = get_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), true );
350
+ $old_cats = explode( ',', $subscribed );
351
+ $pos = array_search( '-1', $old_cats );
352
  unset( $old_cats[ $pos ] );
353
  $cats = implode( ',', $old_cats );
354
  update_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), $cats );
365
  // get categories which the user is subscribed to (old ones)
366
  $categories = get_user_meta( $user_ID, 's2_subscribed', true );
367
  $categories = explode( ',', $categories );
368
+ $format = get_user_meta( $user_ID, 's2_format', true );
369
+ $autosub = get_user_meta( $user_ID, 's2_autosub', true );
370
 
371
  // load blogs of user (only if we need them)
372
  $blogs = array();
377
  foreach ( $blogs as $blog ) {
378
  switch_to_blog( $blog->userblog_id );
379
 
380
+ $blog_categories = (array) $wpdb->get_col( "SELECT term_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'category'" );
381
  $subscribed_categories = array_intersect( $categories, $blog_categories );
382
  if ( ! empty( $subscribed_categories ) ) {
383
  foreach ( $subscribed_categories as $subscribed_category ) {
403
  }
404
  }
405
  }
406
+ }
407
 
408
+ private function upgrade7_0() {
409
  global $mysubscribe2, $wpdb;
410
  if ( version_compare( $mysubscribe2->wp_release, '3.5', '<' ) ) {
411
  $users = $wpdb->get_col( $wpdb->prepare( "SELECT ID from $wpdb->users WHERE ID NOT IN (SELECT user_id from $wpdb->usermeta WHERE meta_key=%s", $mysubscribe2->get_usermeta_keyname( 's2_authors' ) ) );
419
  $args = array(
420
  'meta_query' => array(
421
  array(
422
+ 'key' => $mysubscribe2->get_usermeta_keyname( 's2_authors' ),
423
  'compare' => 'NOT EXISTS',
424
  ),
425
  ),
426
  );
427
 
428
  $user_query = new WP_User_Query( $args );
429
+ $users = $user_query->get_results();
430
  if ( ! empty( $users ) ) {
431
  foreach ( $users as $user ) {
432
  update_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_authors' ), '' );
433
  }
434
  }
435
  }
436
+ }
437
 
438
+ private function upgrade8_5() {
439
  global $mysubscribe2, $wpdb;
440
 
441
+ // include upgrade functions
442
  if ( ! function_exists( 'maybe_add_column' ) ) {
443
+ require_once ABSPATH . 'wp-admin/install-helper.php';
444
  }
445
+ maybe_add_column( $wpdb->subscribe2, 'time', "ALTER TABLE $wpdb->subscribe2 ADD time TIME DEFAULT '00:00:00' NOT NULL AFTER date" );
446
 
447
  // update postmeta field to a protected name, from version 8.5
448
  $wpdb->query( "UPDATE $wpdb->postmeta SET meta_key = '_s2mail' WHERE meta_key = 's2mail'" );
449
+ }
450
 
451
+ private function upgrade8_6() {
452
  global $mysubscribe2, $wpdb;
453
 
454
+ // include upgrade functions
455
  if ( ! function_exists( 'maybe_add_column' ) ) {
456
+ require_once ABSPATH . 'wp-admin/install-helper.php';
457
  }
458
+ maybe_add_column( $wpdb->subscribe2, 'conf_date', "ALTER TABLE $wpdb->subscribe2 ADD conf_date DATE AFTER ip" );
459
+ maybe_add_column( $wpdb->subscribe2, 'conf_time', "ALTER TABLE $wpdb->subscribe2 ADD conf_time TIME AFTER conf_date" );
460
+ maybe_add_column( $wpdb->subscribe2, 'conf_ip', "ALTER TABLE $wpdb->subscribe2 ADD conf_ip char(64) AFTER conf_time" );
461
 
462
  // remove unnecessary table data
463
  $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 's2_cat'" );
464
 
465
+ $users = $wpdb->get_results(
466
+ $wpdb->prepare(
467
+ "SELECT ID FROM $wpdb->users INNER JOIN $wpdb->usermeta ON ( $wpdb->users.ID = $wpdb->usermeta.user_id) WHERE ( $wpdb->usermeta.meta_key = %s AND $wpdb->usermeta.meta_value LIKE %s )",
468
+ $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ),
469
+ $wpdb->esc_like( ',' ) . '%'
470
+ )
471
+ );
472
  foreach ( $users as $user ) {
473
  // make sure we remove leading ',' from this setting
474
  $subscribed = get_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), true );
475
+ $old_cats = explode( ',', $subscribed );
476
  unset( $old_cats[0] );
477
  $cats = implode( ',', $old_cats );
478
  update_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), $cats );
479
  }
480
+ }
481
 
482
+ private function upgrade8_8() {
483
  // to ensure compulsory category collects all users we need there to be s2_subscribed meta-keys for all users
484
+ global $mysubscribe2, $wpdb;
485
 
486
  if ( version_compare( $mysubscribe2->wp_release, '3.5', '<' ) ) {
487
  $all_registered = $mysubscribe2->get_all_registered( 'ID' );
497
  $args = array(
498
  'meta_query' => array(
499
  array(
500
+ 'key' => $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ),
501
  'compare' => 'NOT EXISTS',
502
  ),
503
  ),
504
  );
505
 
506
  $user_query = new WP_User_Query( $args );
507
+ $users = $user_query->get_results();
508
  if ( ! empty( $users ) ) {
509
  foreach ( $users as $user ) {
510
  update_user_meta( $user->ID, $mysubscribe2->get_usermeta_keyname( 's2_subscribed' ), '' );
512
  }
513
  }
514
 
515
+ // check the time column again as the upgrade8_6() function contained a bug
516
  // include upgrade-functions for maybe_add_column;
517
  if ( ! function_exists( 'maybe_add_column' ) ) {
518
+ require_once ABSPATH . 'wp-admin/install-helper.php';
519
  }
520
+ maybe_add_column( $wpdb->subscribe2, 'time', "ALTER TABLE $wpdb->subscribe2 ADD time TIME DEFAULT '00:00:00' NOT NULL AFTER date" );
521
+ }
522
 
523
+ private function upgrade9_5() {
524
  global $mysubscribe2;
525
  if ( 'never' !== $mysubscribe2->subscribe2_options['email_freq'] ) {
526
  $mysubscribe2->subscribe2_options['last_s2cron'] = '';
527
  unset( $mysubscribe2->subscribe2_options['previous_s2cron'] );
528
  }
529
+ }
530
 
531
+ private function upgrade10_14() {
532
  global $mysubscribe2;
533
  if ( ! isset( $mysubscribe2->subscribe2_options['frontend_form'] ) ) {
534
  $mysubscribe2->subscribe2_options['frontend_form'] = '0';
536
  if ( ! isset( $mysubscribe2->subscribe2_options['dismiss_sender_warning'] ) ) {
537
  $mysubscribe2->subscribe2_options['dismiss_sender_warning'] = '0';
538
  }
539
+ }
540
 
541
+ private function upgrade10_15() {
542
  global $mysubscribe2;
543
  if ( ! isset( $mysubscribe2->subscribe2_options['js_ip_updater'] ) ) {
544
  $mysubscribe2->subscribe2_options['js_ip_updater'] = '0';
545
  }
546
+ }
547
+
548
+ private function upgrade10_23() {
549
+ global $mysubscribe2;
550
+ if ( isset( $mysubscribe2->subscribe2_options['entries'] ) ) {
551
+ unset( $mysubscribe2->subscribe2_options['entries'] );
552
+ }
553
+ }
554
  }
 
classes/mo-notice.php ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! class_exists( 'MO_Admin_Notice' ) ) {
4
+
5
+ class MO_Admin_Notice {
6
+ public function __construct() {
7
+ add_action( 'admin_notices', array( $this, 'admin_notice' ) );
8
+ add_action( 'network_admin_notices', array( $this, 'admin_notice' ) );
9
+
10
+ add_action( 'admin_init', array( $this, 'dismiss_admin_notice' ) );
11
+ }
12
+
13
+ public function dismiss_admin_notice() {
14
+ if ( ! isset( $_GET['mo-adaction'] ) || $_GET['mo-adaction'] != 'mo_dismiss_adnotice' ) {
15
+ return;
16
+ }
17
+
18
+ $url = admin_url();
19
+ update_option( 'mo_dismiss_adnotice', 'true' );
20
+
21
+ wp_redirect( $url );
22
+ exit;
23
+ }
24
+
25
+ public function admin_notice() {
26
+
27
+ global $pagenow;
28
+
29
+ if($pagenow == 'index.php' || (isset($_GET['page']) && strpos($_GET['page'], 's2_') !== false)) {
30
+
31
+ if (get_option('mo_dismiss_adnotice', 'false') == 'true') {
32
+ return;
33
+ }
34
+
35
+ if ($this->is_plugin_installed() && $this->is_plugin_active()) {
36
+ return;
37
+ }
38
+
39
+ $dismiss_url = esc_url_raw(
40
+ add_query_arg(
41
+ array(
42
+ 'mo-adaction' => 'mo_dismiss_adnotice'
43
+ ),
44
+ admin_url()
45
+ )
46
+ );
47
+ $this->notice_css();
48
+ $install_url = wp_nonce_url(
49
+ admin_url('update.php?action=install-plugin&plugin=mailoptin'),
50
+ 'install-plugin_mailoptin'
51
+ );
52
+
53
+ $activate_url = wp_nonce_url(admin_url('plugins.php?action=activate&plugin=mailoptin%2Fmailoptin.php'), 'activate-plugin_mailoptin/mailoptin.php');
54
+ ?>
55
+ <div class="mo-admin-notice notice notice-success">
56
+ <div class="mo-notice-first-half">
57
+ <p>
58
+ <?php
59
+ printf(
60
+ __('Free optin form plugin that will %1$sincrease your email list subscribers%2$s and keep them engaged with %1$sautomated and schedule newsletters%2$s.'),
61
+ '<span class="mo-stylize"><strong>', '</strong></span>');
62
+ ?>
63
+ </p>
64
+ <p style="text-decoration: underline;font-size: 12px;">Recommended by Subscribe2 plugin</p>
65
+ </div>
66
+ <div class="mo-notice-other-half">
67
+ <?php if ( ! $this->is_plugin_installed()) : ?>
68
+ <a class="button button-primary button-hero" id="mo-install-mailoptin-plugin" href="<?php echo $install_url; ?>">
69
+ <?php _e('Install MailOptin Now for Free!'); ?>
70
+ </a>
71
+ <?php endif; ?>
72
+ <?php if ($this->is_plugin_installed() && ! $this->is_plugin_active()) : ?>
73
+ <a class="button button-primary button-hero" id="mo-activate-mailoptin-plugin" href="<?php echo $activate_url; ?>">
74
+ <?php _e('Activate MailOptin Now!'); ?>
75
+ </a>
76
+ <?php endif; ?>
77
+ <div class="mo-notice-learn-more">
78
+ <a target="_blank" href="https://mailoptin.io">Learn more</a>
79
+ </div>
80
+ </div>
81
+ <a href="<?php echo $dismiss_url; ?>">
82
+ <button type="button" class="notice-dismiss">
83
+ <span class="screen-reader-text"><?php _e('Dismiss this notice'); ?>.</span>
84
+ </button>
85
+ </a>
86
+ </div>
87
+ <?php
88
+ }
89
+ }
90
+
91
+ public function current_admin_url() {
92
+ $parts = parse_url( home_url() );
93
+ $uri = $parts['scheme'] . '://' . $parts['host'];
94
+
95
+ if ( array_key_exists( 'port', $parts ) ) {
96
+ $uri .= ':' . $parts['port'];
97
+ }
98
+
99
+ $uri .= add_query_arg( array() );
100
+
101
+ return $uri;
102
+ }
103
+
104
+ public function is_plugin_installed() {
105
+ $installed_plugins = get_plugins();
106
+
107
+ return isset( $installed_plugins['mailoptin/mailoptin.php'] );
108
+ }
109
+
110
+ public function is_plugin_active() {
111
+ return is_plugin_active( 'mailoptin/mailoptin.php' );
112
+ }
113
+
114
+ public function notice_css() {
115
+ ?>
116
+ <style type="text/css">
117
+ .mo-admin-notice {
118
+ background: #fff;
119
+ color: #000;
120
+ border-left-color: #46b450;
121
+ position: relative;
122
+ }
123
+
124
+ .mo-admin-notice .notice-dismiss:before {
125
+ color: #72777c;
126
+ }
127
+
128
+ .mo-admin-notice .mo-stylize {
129
+ line-height: 2;
130
+ }
131
+
132
+ .mo-admin-notice .button-primary {
133
+ background: #006799;
134
+ text-shadow: none;
135
+ border: 0;
136
+ box-shadow: none;
137
+ }
138
+
139
+ .mo-notice-first-half {
140
+ width: 66%;
141
+ display: inline-block;
142
+ margin: 10px 0;
143
+ }
144
+
145
+ .mo-notice-other-half {
146
+ width: 33%;
147
+ display: inline-block;
148
+ padding: 20px 0;
149
+ position: absolute;
150
+ text-align: center;
151
+ }
152
+
153
+ .mo-notice-first-half p {
154
+ font-size: 14px;
155
+ }
156
+
157
+ .mo-notice-learn-more a {
158
+ margin: 10px;
159
+ }
160
+
161
+ .mo-notice-learn-more {
162
+ margin-top: 10px;
163
+ }
164
+ </style>
165
+ <?php
166
+ }
167
+
168
+ public static function instance() {
169
+ static $instance = null;
170
+
171
+ if ( is_null( $instance ) ) {
172
+ $instance = new self();
173
+ }
174
+
175
+ return $instance;
176
+ }
177
+ }
178
+
179
+ MO_Admin_Notice::instance();
180
+ }
include/options.php CHANGED
@@ -25,7 +25,7 @@ if ( ! isset( $mysubscribe2->subscribe2_options['show_autosub'] ) ) {
25
  } // option to display auto-subscription option to registered users
26
 
27
  if ( ! isset( $mysubscribe2->subscribe2_options['autosub_def'] ) ) {
28
- $mysubscribe2->subscribe2_options['autosub_def'] = 'yes';
29
  } // option for user default auto-subscription to new categories
30
 
31
  if ( ! isset( $mysubscribe2->subscribe2_options['comment_subs'] ) ) {
@@ -128,10 +128,6 @@ if ( ! isset( $mysubscribe2->subscribe2_options['s2meta_default'] ) ) {
128
  $mysubscribe2->subscribe2_options['s2meta_default'] = '0';
129
  } // option for Subscribe2 over ride postmeta to be checked by default
130
 
131
- if ( ! isset( $mysubscribe2->subscribe2_options['entries'] ) ) {
132
- $mysubscribe2->subscribe2_options['entries'] = 25;
133
- } // option for the number of subscribers displayed on each page
134
-
135
  if ( ! isset( $mysubscribe2->subscribe2_options['barred'] ) ) {
136
  $mysubscribe2->subscribe2_options['barred'] = '';
137
  } // option containing domains barred from public registration
@@ -165,10 +161,9 @@ if ( ! isset( $mysubscribe2->subscribe2_options['remind_subject'] ) ) {
165
  } // Default reminder email subject
166
 
167
  if ( ! isset( $mysubscribe2->subscribe2_options['ajax'] ) ) {
168
- $mysubscribe2->subscribe2_options['ajax'] = '0';
169
  } // Default frontend form setting
170
 
171
  if ( ! isset( $mysubscribe2->subscribe2_options['js_ip_updater'] ) ) {
172
- $mysubscribe2->subscribe2_options['js_ip_updater'] = '0';
173
  } // Default setting for using javascript to update form ip address
174
- ?>
25
  } // option to display auto-subscription option to registered users
26
 
27
  if ( ! isset( $mysubscribe2->subscribe2_options['autosub_def'] ) ) {
28
+ $mysubscribe2->subscribe2_options['autosub_def'] = 'no';
29
  } // option for user default auto-subscription to new categories
30
 
31
  if ( ! isset( $mysubscribe2->subscribe2_options['comment_subs'] ) ) {
128
  $mysubscribe2->subscribe2_options['s2meta_default'] = '0';
129
  } // option for Subscribe2 over ride postmeta to be checked by default
130
 
 
 
 
 
131
  if ( ! isset( $mysubscribe2->subscribe2_options['barred'] ) ) {
132
  $mysubscribe2->subscribe2_options['barred'] = '';
133
  } // option containing domains barred from public registration
161
  } // Default reminder email subject
162
 
163
  if ( ! isset( $mysubscribe2->subscribe2_options['ajax'] ) ) {
164
+ $mysubscribe2->subscribe2_options['ajax'] = '';
165
  } // Default frontend form setting
166
 
167
  if ( ! isset( $mysubscribe2->subscribe2_options['js_ip_updater'] ) ) {
168
+ $mysubscribe2->subscribe2_options['js_ip_updater'] = '';
169
  } // Default setting for using javascript to update form ip address
 
include/s2-ajax.js CHANGED
@@ -1,72 +1,81 @@
1
- /* global s2_ajax_script_strings */
2
  // Version 1.0 - original version
3
  // Version 1.1 - added position and minimum width and height attributes to .dialog
4
  // Version 1.2 - added nonce use for form submission
 
5
 
6
  var s2jQuery = jQuery.noConflict();
7
  s2jQuery( document ).ready( function() {
8
  var dialog = s2jQuery( '<div></div>' );
9
- var ajaxurl = s2_ajax_script_strings.ajaxurl;
10
- s2jQuery( 'a.s2popup' ).click( function( event ){
11
- event.preventDefault();
12
  var data = {
13
  'action': 'subscribe2_form',
14
  'data': s2jQuery( 'a.s2popup' ).attr( 'id' )
15
  };
 
16
  jQuery.post( ajaxurl, data, function( response ) {
17
  dialog.html( response );
18
- });
19
  dialog.dialog( {
20
  modal: true,
21
  zIndex: 10000,
22
  minWidth: 350,
23
  minHeight: 300,
24
- title: s2_ajax_script_strings.title
25
- });
26
  dialog.dialog( 'open' );
27
- });
28
  s2jQuery( document ).on( 'submit', '#s2ajaxform', function( event ) {
29
- event.preventDefault();
30
  var email = s2jQuery( '#s2ajaxform input[name=email]' ).val();
31
  var ip = s2jQuery( '#s2ajaxform input[name=ip]' ).val();
32
  var firstname = s2jQuery( '#s2ajaxform input[name=firstname]' ).val();
33
- if ( typeof firstname === 'undefined' ) {
 
 
 
 
 
 
 
34
  firstname = '';
35
  }
36
- var lastname = s2jQuery( '#s2ajaxform input[name=lastname]' ).val();
37
- if ( typeof lastname === 'undefined' ) {
38
  lastname = '';
39
  }
40
- var uri = s2jQuery( '#s2ajaxform input[name=uri]' ).val();
41
- if ( typeof uri === 'undefined' ) {
42
  uri = 'http://';
43
  }
44
- var btn = s2jQuery( this ).find( 'input[type=submit][clicked=true]' );
45
  if ( btn.length && s2jQuery( '#s2ajaxform' ).has( btn ) ) {
46
- var data = {
47
  'action': 'subscribe2_submit',
48
- 'nonce': s2_ajax_script_strings.nonce,
49
  'data': {
50
  'email': email,
51
  'ip': ip,
52
  'firstname': firstname,
53
  'lastname': lastname,
54
  'uri': uri,
55
- 'button': btn.attr( 'name' ),
56
  }
57
  };
58
  jQuery.post( ajaxurl, data, function( response ) {
59
  dialog.html( response );
60
- });
61
  }
62
- });
 
63
  // Allows detection of which button was clicked
64
  s2jQuery( document ).on( 'click', '#s2ajaxform input[type=submit]', function() {
65
  s2jQuery( '#s2ajaxform input[type=submit]' ).removeAttr( 'clicked' );
66
  s2jQuery( this ).attr( 'clicked', 'true' );
67
- });
 
68
  // when form is closed return to default
69
  s2jQuery( document ).on( 'dialogclose', function() {
70
  dialog.html( dialog );
71
- });
72
- });
1
+ /* global s2AjaxScriptStrings */
2
  // Version 1.0 - original version
3
  // Version 1.1 - added position and minimum width and height attributes to .dialog
4
  // Version 1.2 - added nonce use for form submission
5
+ // Version 1.3 - eslinted
6
 
7
  var s2jQuery = jQuery.noConflict();
8
  s2jQuery( document ).ready( function() {
9
  var dialog = s2jQuery( '<div></div>' );
10
+ var ajaxurl = s2AjaxScriptStrings.ajaxurl;
11
+ s2jQuery( 'a.s2popup' ).click( function( event ) {
 
12
  var data = {
13
  'action': 'subscribe2_form',
14
  'data': s2jQuery( 'a.s2popup' ).attr( 'id' )
15
  };
16
+ event.preventDefault();
17
  jQuery.post( ajaxurl, data, function( response ) {
18
  dialog.html( response );
19
+ } );
20
  dialog.dialog( {
21
  modal: true,
22
  zIndex: 10000,
23
  minWidth: 350,
24
  minHeight: 300,
25
+ title: s2AjaxScriptStrings.title
26
+ } );
27
  dialog.dialog( 'open' );
28
+ } );
29
  s2jQuery( document ).on( 'submit', '#s2ajaxform', function( event ) {
 
30
  var email = s2jQuery( '#s2ajaxform input[name=email]' ).val();
31
  var ip = s2jQuery( '#s2ajaxform input[name=ip]' ).val();
32
  var firstname = s2jQuery( '#s2ajaxform input[name=firstname]' ).val();
33
+ var lastname = s2jQuery( '#s2ajaxform input[name=lastname]' ).val();
34
+ var uri = s2jQuery( '#s2ajaxform input[name=uri]' ).val();
35
+ var btn = s2jQuery( this ).find( 'input[type=submit][clicked=true]' );
36
+ var data;
37
+
38
+ event.preventDefault();
39
+
40
+ if ( 'undefined' === typeof firstname ) {
41
  firstname = '';
42
  }
43
+
44
+ if ( 'undefined' === typeof lastname ) {
45
  lastname = '';
46
  }
47
+
48
+ if ( 'undefined' === typeof uri ) {
49
  uri = 'http://';
50
  }
51
+
52
  if ( btn.length && s2jQuery( '#s2ajaxform' ).has( btn ) ) {
53
+ data = {
54
  'action': 'subscribe2_submit',
55
+ 'nonce': s2AjaxScriptStrings.nonce,
56
  'data': {
57
  'email': email,
58
  'ip': ip,
59
  'firstname': firstname,
60
  'lastname': lastname,
61
  'uri': uri,
62
+ 'button': btn.attr( 'name' )
63
  }
64
  };
65
  jQuery.post( ajaxurl, data, function( response ) {
66
  dialog.html( response );
67
+ } );
68
  }
69
+ } );
70
+
71
  // Allows detection of which button was clicked
72
  s2jQuery( document ).on( 'click', '#s2ajaxform input[type=submit]', function() {
73
  s2jQuery( '#s2ajaxform input[type=submit]' ).removeAttr( 'clicked' );
74
  s2jQuery( this ).attr( 'clicked', 'true' );
75
+ } );
76
+
77
  // when form is closed return to default
78
  s2jQuery( document ).on( 'dialogclose', function() {
79
  dialog.html( dialog );
80
+ } );
81
+ } );
include/s2-ajax.min.js CHANGED
@@ -1 +1 @@
1
- var s2jQuery=jQuery.noConflict();s2jQuery(document).ready(function(){var dialog=s2jQuery('<div></div>');var ajaxurl=s2_ajax_script_strings.ajaxurl;s2jQuery('a.s2popup').click(function(event){event.preventDefault();var data={'action':'subscribe2_form','data':s2jQuery('a.s2popup').attr('id')};jQuery.post(ajaxurl,data,function(response){dialog.html(response)});dialog.dialog({modal:true,zIndex:10000,minWidth:350,minHeight:300,title:s2_ajax_script_strings.title});dialog.dialog('open')});s2jQuery(document).on('submit','#s2ajaxform',function(event){event.preventDefault();var email=s2jQuery('#s2ajaxform input[name=email]').val();var ip=s2jQuery('#s2ajaxform input[name=ip]').val();var firstname=s2jQuery('#s2ajaxform input[name=firstname]').val();if(typeof firstname==='undefined'){firstname=''}var lastname=s2jQuery('#s2ajaxform input[name=lastname]').val();if(typeof lastname==='undefined'){lastname=''}var uri=s2jQuery('#s2ajaxform input[name=uri]').val();if(typeof uri==='undefined'){uri='http://'}var btn=s2jQuery(this).find('input[type=submit][clicked=true]');if(btn.length&&s2jQuery('#s2ajaxform').has(btn)){var data={'action':'subscribe2_submit','nonce':s2_ajax_script_strings.nonce,'data':{'email':email,'ip':ip,'firstname':firstname,'lastname':lastname,'uri':uri,'button':btn.attr('name'),}};jQuery.post(ajaxurl,data,function(response){dialog.html(response)})}});s2jQuery(document).on('click','#s2ajaxform input[type=submit]',function(){s2jQuery('#s2ajaxform input[type=submit]').removeAttr('clicked');s2jQuery(this).attr('clicked','true')});s2jQuery(document).on('dialogclose',function(){dialog.html(dialog)})});
1
+ var s2jQuery=jQuery.noConflict();s2jQuery(document).ready(function(){var t=s2jQuery("<div></div>"),a=s2AjaxScriptStrings.ajaxurl;s2jQuery("a.s2popup").click(function(e){var i={action:"subscribe2_form",data:s2jQuery("a.s2popup").attr("id")};e.preventDefault(),jQuery.post(a,i,function(a){t.html(a)}),t.dialog({modal:!0,zIndex:1e4,minWidth:350,minHeight:300,title:s2AjaxScriptStrings.title}),t.dialog("open")}),s2jQuery(document).on("submit","#s2ajaxform",function(e){var i,n=s2jQuery("#s2ajaxform input[name=email]").val(),r=s2jQuery("#s2ajaxform input[name=ip]").val(),u=s2jQuery("#s2ajaxform input[name=firstname]").val(),s=s2jQuery("#s2ajaxform input[name=lastname]").val(),o=s2jQuery("#s2ajaxform input[name=uri]").val(),m=s2jQuery(this).find("input[type=submit][clicked=true]");e.preventDefault(),void 0===u&&(u=""),void 0===s&&(s=""),void 0===o&&(o="http://"),m.length&&s2jQuery("#s2ajaxform").has(m)&&(i={action:"subscribe2_submit",nonce:s2AjaxScriptStrings.nonce,data:{email:n,ip:r,firstname:u,lastname:s,uri:o,button:m.attr("name")}},jQuery.post(a,i,function(a){t.html(a)}))}),s2jQuery(document).on("click","#s2ajaxform input[type=submit]",function(){s2jQuery("#s2ajaxform input[type=submit]").removeAttr("clicked"),s2jQuery(this).attr("clicked","true")}),s2jQuery(document).on("dialogclose",function(){t.html(t)})});
include/s2-button.js CHANGED
@@ -1,3 +1,4 @@
1
  /* global QTags */
2
- // version 2.0 - original version for WordPress versions 3.3 and greater
3
- QTags.addButton( 'Subscribe2', 'Subscribe2', '[subscribe2]' );
 
1
  /* global QTags */
2
+ // Version 2.0 - original version for WordPress versions 3.3 and greater
3
+
4
+ QTags.addButton( 'Subscribe2', 'Subscribe2', '[subscribe2]' );
include/s2-checkbox.js CHANGED
@@ -1,39 +1,44 @@
1
- // version 1.0 - original version
2
- // version 1.1 - Updated with function fixes and for WordPress 3.2 / jQuery 1.6
3
- // version 1.2 - Update to work when DISABLED is specified for changes in version 8.5
4
- // version 1.3 - Update for Subscribe2 9.0 to remove unecessary code now WordPress 3.3 is minimum requirement
5
- jQuery( document ).ready(function () {
 
 
 
6
  // function to check or uncheck all when 'checkall' box it toggled
7
- jQuery( 'input[name="checkall"]' ).click(function () {
8
- var checked_status = this.checked;
9
- jQuery( 'input[class="' + this.value + '"]' ).each(function () {
10
  if ( false === jQuery( this ).prop( 'disabled' ) ) {
11
- this.checked = checked_status;
12
  }
13
- });
14
- });
 
15
  // function to check or uncheck 'checkall' box when individual boxes are toggled
16
- jQuery( 'input[class^="checkall"]' ).click(function () {
17
- var checked_status = true;
18
- jQuery( 'input[class="' + this.className + '"]' ).each(function () {
19
- if ( ( true === this.checked ) && ( true === checked_status ) ) {
20
- checked_status = true;
21
  } else {
22
- checked_status = false;
23
  }
24
  jQuery( 'input[value="' + this.className + '"]' )
25
- .prop( 'checked', checked_status );
26
- });
27
- });
 
28
  // function to check or uncheck 'checkall' box when page is loaded
29
- var checked_status = true;
30
- jQuery( 'input[class^="checkall"]' ).each(function () {
31
- if ( ( true === this.checked ) && ( true === checked_status ) ) {
32
- checked_status = true;
33
  } else {
34
- checked_status = false;
35
  }
36
  jQuery( 'input[value="' + this.className + '"]' )
37
- .prop( 'checked', checked_status );
38
- });
39
- });
1
+ // Version 1.0 - original version
2
+ // Version 1.1 - Updated with function fixes and for WordPress 3.2 / jQuery 1.6
3
+ // Version 1.2 - Update to work when DISABLED is specified for changes in version 8.5
4
+ // Version 1.3 - Update for Subscribe2 9.0 to remove unecessary code now WordPress 3.3 is minimum requirement
5
+ // Version 1.4 - eslinted
6
+
7
+ jQuery( document ).ready( function() {
8
+
9
  // function to check or uncheck all when 'checkall' box it toggled
10
+ jQuery( 'input[name="checkall"]' ).click( function() {
11
+ var checkedStatus = this.checked;
12
+ jQuery( 'input[class="' + this.value + '"]' ).each( function() {
13
  if ( false === jQuery( this ).prop( 'disabled' ) ) {
14
+ this.checked = checkedStatus;
15
  }
16
+ } );
17
+ } );
18
+
19
  // function to check or uncheck 'checkall' box when individual boxes are toggled
20
+ jQuery( 'input[class^="checkall"]' ).click( function() {
21
+ var checkedStatus = true;
22
+ jQuery( 'input[class="' + this.className + '"]' ).each( function() {
23
+ if ( ( true === this.checked ) && ( true === checkedStatus ) ) {
24
+ checkedStatus = true;
25
  } else {
26
+ checkedStatus = false;
27
  }
28
  jQuery( 'input[value="' + this.className + '"]' )
29
+ .prop( 'checked', checkedStatus );
30
+ } );
31
+ } );
32
+
33
  // function to check or uncheck 'checkall' box when page is loaded
34
+ jQuery( 'input[class^="checkall"]' ).each( function() {
35
+ var checkedStatus = true;
36
+ if ( ( true === this.checked ) && ( true === checkedStatus ) ) {
37
+ checkedStatus = true;
38
  } else {
39
+ checkedStatus = false;
40
  }
41
  jQuery( 'input[value="' + this.className + '"]' )
42
+ .prop( 'checked', checkedStatus );
43
+ } );
44
+ } );
include/s2-checkbox.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(){jQuery('input[name="checkall"]').click(function(){var a=this.checked;jQuery('input[class="'+this.value+'"]').each(function(){!1===jQuery(this).prop("disabled")&&(this.checked=a)})}),jQuery('input[class^="checkall"]').click(function(){var a=!0;jQuery('input[class="'+this.className+'"]').each(function(){a=!0===this.checked&&!0===a?!0:!1,jQuery('input[value="'+this.className+'"]').prop("checked",a)})});var a=!0;jQuery('input[class^="checkall"]').each(function(){a=!0===this.checked&&!0===a?!0:!1,jQuery('input[value="'+this.className+'"]').prop("checked",a)})});
1
+ jQuery(document).ready(function(){jQuery('input[name="checkall"]').click(function(){var c=this.checked;jQuery('input[class="'+this.value+'"]').each(function(){!1===jQuery(this).prop("disabled")&&(this.checked=c)})}),jQuery('input[class^="checkall"]').click(function(){var c=!0;jQuery('input[class="'+this.className+'"]').each(function(){c=!0===this.checked&&!0===c,jQuery('input[value="'+this.className+'"]').prop("checked",c)})}),jQuery('input[class^="checkall"]').each(function(){var c=!0;c=!0===this.checked&&!0===c,jQuery('input[value="'+this.className+'"]').prop("checked",c)})});
include/s2-colorpicker.js CHANGED
@@ -1,31 +1,39 @@
1
- // version 1.0 - original version
2
- // version 1.1 - Update for Subscribe2 9.0 to remove unecessary code now WordPress 3.3 is minimum requirement
3
- // version 1.2 - Initialise the colour fields on page load so they are the correct colour
4
- jQuery( document ).ready(function () {
5
- jQuery( document ).on( 'focus', '.colorpickerField', function () {
 
 
 
 
 
6
  if ( jQuery( this ).is( '.s2_initialised' ) || -1 !== this.id.search( '__i__' ) ) {
7
  return; // exit early, already initialized or not activated
8
  }
 
9
  jQuery( this ).addClass( 's2_initialised' );
10
- var picker,
11
- field = this.id.substr( 0, 20 );
12
- jQuery( '.s2_colorpicker' ).each(function () {
13
  if ( -1 !== this.id.search( field ) ) {
14
  picker = this.id;
15
  return false; // stop looping
16
  }
17
- });
18
- jQuery( this ).on( 'focusin', function () {
 
19
  jQuery( '.s2_colorpicker' ).slideUp();
20
  jQuery.farbtastic( '#' + picker ).linkTo( this );
21
  jQuery( '#' + picker ).slideDown();
22
- });
23
- jQuery( this ).on( 'focusout', function () {
 
24
  jQuery( '#' + picker ).slideUp();
25
- });
 
26
  jQuery( this ).trigger( 'focus' );
27
- });
28
- jQuery( '.colorpickerField' ).each(function () {
29
  jQuery.farbtastic( '#' + this.id ).linkTo( this );
30
- });
31
- });
1
+ // Version 1.0 - original version
2
+ // Version 1.1 - Update for Subscribe2 9.0 to remove unecessary code now WordPress 3.3 is minimum requirement
3
+ // Version 1.2 - Initialise the colour fields on page load so they are the correct colour
4
+ // Version 1.3 - eslinted
5
+
6
+ jQuery( document ).ready( function() {
7
+ jQuery( document ).on( 'focus', '.colorpickerField', function() {
8
+ var picker,
9
+ field = this.id.substr( 0, 20 );
10
+
11
  if ( jQuery( this ).is( '.s2_initialised' ) || -1 !== this.id.search( '__i__' ) ) {
12
  return; // exit early, already initialized or not activated
13
  }
14
+
15
  jQuery( this ).addClass( 's2_initialised' );
16
+
17
+ jQuery( '.s2_colorpicker' ).each( function() {
 
18
  if ( -1 !== this.id.search( field ) ) {
19
  picker = this.id;
20
  return false; // stop looping
21
  }
22
+ } );
23
+
24
+ jQuery( this ).on( 'focusin', function() {
25
  jQuery( '.s2_colorpicker' ).slideUp();
26
  jQuery.farbtastic( '#' + picker ).linkTo( this );
27
  jQuery( '#' + picker ).slideDown();
28
+ } );
29
+
30
+ jQuery( this ).on( 'focusout', function() {
31
  jQuery( '#' + picker ).slideUp();
32
+ } );
33
+
34
  jQuery( this ).trigger( 'focus' );
35
+ } );
36
+ jQuery( '.colorpickerField' ).each( function() {
37
  jQuery.farbtastic( '#' + this.id ).linkTo( this );
38
+ } );
39
+ } );
include/s2-colorpicker.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(){jQuery(document).on("focus",".colorpickerField",function(){if(!jQuery(this).is(".s2_initialised")&&-1===this.id.search("__i__")){jQuery(this).addClass("s2_initialised");var a,b=this.id.substr(0,20);jQuery(".s2_colorpicker").each(function(){return-1!==this.id.search(b)?(a=this.id,!1):void 0}),jQuery(this).on("focusin",function(){jQuery(".s2_colorpicker").slideUp(),jQuery.farbtastic("#"+a).linkTo(this),jQuery("#"+a).slideDown()}),jQuery(this).on("focusout",function(){jQuery("#"+a).slideUp()}),jQuery(this).trigger("focus")}}),jQuery(".colorpickerField").each(function(){jQuery.farbtastic("#"+this.id).linkTo(this)})});
1
+ jQuery(document).ready(function(){jQuery(document).on("focus",".colorpickerField",function(){var i,e=this.id.substr(0,20);jQuery(this).is(".s2_initialised")||-1!==this.id.search("__i__")||(jQuery(this).addClass("s2_initialised"),jQuery(".s2_colorpicker").each(function(){if(-1!==this.id.search(e))return i=this.id,!1}),jQuery(this).on("focusin",function(){jQuery(".s2_colorpicker").slideUp(),jQuery.farbtastic("#"+i).linkTo(this),jQuery("#"+i).slideDown()}),jQuery(this).on("focusout",function(){jQuery("#"+i).slideUp()}),jQuery(this).trigger("focus"))}),jQuery(".colorpickerField").each(function(){jQuery.farbtastic("#"+this.id).linkTo(this)})});
include/s2-date-time.js CHANGED
@@ -1,6 +1,8 @@
1
  // Version 1.0 - original version
2
- jQuery( document ).ready(function() {
3
- jQuery( '#s2datepicker' ).datepicker({
4
- dateFormat : 'MM d, yy'
5
- });
6
- });
 
 
1
  // Version 1.0 - original version
2
+ // Version 1.1 - eslinted
3
+
4
+ jQuery( document ).ready( function() {
5
+ jQuery( '#s2datepicker' ).datepicker( {
6
+ dateFormat: 'MM d, yy'
7
+ } );
8
+ } );
include/s2-dismiss.js CHANGED
@@ -1,12 +1,13 @@
1
- /* global s2_dismiss_script_strings */
2
  // Version 1.0 - original version
 
3
 
4
  jQuery( document ).on( 'click', '#sender_message .notice-dismiss', function() {
5
- var ajaxurl = s2_dismiss_script_strings.ajaxurl;
6
  var data = {
7
  'action': 's2_dismiss_notice',
8
- 'nonce': s2_dismiss_script_strings.nonce
9
 
10
  };
11
  jQuery.post( ajaxurl, data );
12
- });
1
+ /* global s2DismissScriptStrings */
2
  // Version 1.0 - original version
3
+ // Version 1.1 - eslinted
4
 
5
  jQuery( document ).on( 'click', '#sender_message .notice-dismiss', function() {
6
+ var ajaxurl = s2DismissScriptStrings.ajaxurl;
7
  var data = {
8
  'action': 's2_dismiss_notice',
9
+ 'nonce': s2DismissScriptStrings.nonce
10
 
11
  };
12
  jQuery.post( ajaxurl, data );
13
+ } );
include/s2-dismiss.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).on('click','#sender_message .notice-dismiss',function(){var ajaxurl=s2_dismiss_script_strings.ajaxurl;var data={'action':'s2_dismiss_notice','nonce':s2_dismiss_script_strings.nonce};jQuery.post(ajaxurl,data)});
1
+ jQuery(document).on("click","#sender_message .notice-dismiss",function(){var s=s2DismissScriptStrings.ajaxurl,i={action:"s2_dismiss_notice",nonce:s2DismissScriptStrings.nonce};jQuery.post(s,i)});
include/s2-edit.js CHANGED
@@ -1,59 +1,61 @@
1
- /* exported s2_show, s2_hide, s2_update, s2_revert, s2_cron_update, s2_cron_revert */
2
  // Version 1.0 - original version
3
  // Version 1.1 - updated for Subscribe2 8.6
4
  // Version 1.2 - updated for Subscribe2 9.0
5
- jQuery( document ).ready(function () {
6
- // hide our span before page loads
 
 
7
  jQuery( '#s2bcclimit_2' ).hide();
8
  jQuery( '#s2entries_2' ).hide();
9
  jQuery( '#s2cron_2' ).hide();
10
- });
11
 
12
  //show span on clicking the edit link
13
- function s2_show( id ) {
14
  jQuery( '#s2' + id + '_2' ).show();
15
  jQuery( '#s2' + id + '_1' ).hide();
16
  return false;
17
  }
18
 
19
  // hide span on clicking the hide link
20
- function s2_hide( id ) {
21
  jQuery( '#s2' + id + '_1' ).show();
22
  jQuery( '#s2' + id + '_2' ).hide();
23
  return false;
24
  }
25
 
26
- function s2_update( id ) {
27
  var input = jQuery( 'input[name="' + id + '"]' ).val();
28
  jQuery( '#s2' + id ).html( input );
29
- s2_hide( id );
30
  }
31
 
32
- function s2_revert( id ) {
33
  var option = jQuery( '#js' + id ).val();
34
  jQuery( 'input[name="' + id + '"]' ).val( option );
35
  jQuery( '#s2' + id ).html( option );
36
- s2_hide( id );
37
  }
38
 
39
- function s2_cron_update( id ) {
40
  var date, time;
41
  date = jQuery( 'input[name="' + id + 'date"]' ).val();
42
  jQuery( '#s2' + id + 'date' ).html( date );
43
  time = jQuery( 'select[name="' + id + 'time"] option:selected' ).html();
44
  jQuery( '#s2' + id + 'time' ).html( time );
45
- s2_hide( id );
46
  }
47
 
48
- function s2_cron_revert( id ) {
49
  var date, time;
50
  date = jQuery( '#js' + id + 'date' ).val();
51
  jQuery( 'input[name="' + id + 'date"]' ).val( date );
52
  jQuery( '#s2' + id + 'date' ).html( date );
53
  time = jQuery( '#js' + id + 'time' ).val();
54
- jQuery( '[name=' + id + 'time] option' ).filter(function() {
55
  return ( this.text === time );
56
- }).prop( 'selected', true ).parent().focus();
57
  jQuery( '#s2' + id + 'time' ).html( time );
58
- s2_hide( id );
59
- }
1
+ /* exported s2Show, s2Hide, s2Update, s2Revert, s2CronUpdate, s2CronRevert */
2
  // Version 1.0 - original version
3
  // Version 1.1 - updated for Subscribe2 8.6
4
  // Version 1.2 - updated for Subscribe2 9.0
5
+ // Version 1.3 - eslinted
6
+
7
+ // hide our span before page loads
8
+ jQuery( document ).ready( function() {
9
  jQuery( '#s2bcclimit_2' ).hide();
10
  jQuery( '#s2entries_2' ).hide();
11
  jQuery( '#s2cron_2' ).hide();
12
+ } );
13
 
14
  //show span on clicking the edit link
15
+ function s2Show( id ) {
16
  jQuery( '#s2' + id + '_2' ).show();
17
  jQuery( '#s2' + id + '_1' ).hide();
18
  return false;
19
  }
20
 
21
  // hide span on clicking the hide link
22
+ function s2Hide( id ) {
23
  jQuery( '#s2' + id + '_1' ).show();
24
  jQuery( '#s2' + id + '_2' ).hide();
25
  return false;
26
  }
27
 
28
+ function s2Update( id ) {
29
  var input = jQuery( 'input[name="' + id + '"]' ).val();
30
  jQuery( '#s2' + id ).html( input );
31
+ s2Hide( id );
32
  }
33
 
34
+ function s2Revert( id ) {
35
  var option = jQuery( '#js' + id ).val();
36
  jQuery( 'input[name="' + id + '"]' ).val( option );
37
  jQuery( '#s2' + id ).html( option );
38
+ s2Hide( id );
39
  }
40
 
41
+ function s2CronUpdate( id ) {
42
  var date, time;
43
  date = jQuery( 'input[name="' + id + 'date"]' ).val();
44
  jQuery( '#s2' + id + 'date' ).html( date );
45
  time = jQuery( 'select[name="' + id + 'time"] option:selected' ).html();
46
  jQuery( '#s2' + id + 'time' ).html( time );
47
+ s2Hide( id );
48
  }
49
 
50
+ function s2CronRevert( id ) {
51
  var date, time;
52
  date = jQuery( '#js' + id + 'date' ).val();
53
  jQuery( 'input[name="' + id + 'date"]' ).val( date );
54
  jQuery( '#s2' + id + 'date' ).html( date );
55
  time = jQuery( '#js' + id + 'time' ).val();
56
+ jQuery( '[name=' + id + 'time] option' ).filter( function() {
57
  return ( this.text === time );
58
+ } ).prop( 'selected', true ).parent().focus();
59
  jQuery( '#s2' + id + 'time' ).html( time );
60
+ s2Hide( id );
61
+ }
include/s2-edit.min.js CHANGED
@@ -1 +1 @@
1
- function s2_show(a){return jQuery("#s2"+a+"_2").show(),jQuery("#s2"+a+"_1").hide(),!1}function s2_hide(a){return jQuery("#s2"+a+"_1").show(),jQuery("#s2"+a+"_2").hide(),!1}function s2_update(a){var b=jQuery('input[name="'+a+'"]').val();jQuery("#s2"+a).html(b),s2_hide(a)}function s2_revert(a){var b=jQuery("#js"+a).val();jQuery('input[name="'+a+'"]').val(b),jQuery("#s2"+a).html(b),s2_hide(a)}function s2_cron_update(a){var b,c;b=jQuery('input[name="'+a+'date"]').val(),jQuery("#s2"+a+"date").html(b),c=jQuery('select[name="'+a+'time"] option:selected').html(),jQuery("#s2"+a+"time").html(c),s2_hide(a)}function s2_cron_revert(a){var b,c;b=jQuery("#js"+a+"date").val(),jQuery('input[name="'+a+'date"]').val(b),jQuery("#s2"+a+"date").html(b),c=jQuery("#js"+a+"time").val(),jQuery("[name="+a+"time] option").filter(function(){return this.text===c}).prop("selected",!0).parent().focus(),jQuery("#s2"+a+"time").html(c),s2_hide(a)}jQuery(document).ready(function(){jQuery("#s2bcclimit_2").hide(),jQuery("#s2entries_2").hide(),jQuery("#s2cron_2").hide()});
1
+ function s2Show(e){return jQuery("#s2"+e+"_2").show(),jQuery("#s2"+e+"_1").hide(),!1}function s2Hide(e){return jQuery("#s2"+e+"_1").show(),jQuery("#s2"+e+"_2").hide(),!1}function s2Update(e){var t=jQuery('input[name="'+e+'"]').val();jQuery("#s2"+e).html(t),s2Hide(e)}function s2Revert(e){var t=jQuery("#js"+e).val();jQuery('input[name="'+e+'"]').val(t),jQuery("#s2"+e).html(t),s2Hide(e)}function s2CronUpdate(e){var t,r;t=jQuery('input[name="'+e+'date"]').val(),jQuery("#s2"+e+"date").html(t),r=jQuery('select[name="'+e+'time"] option:selected').html(),jQuery("#s2"+e+"time").html(r),s2Hide(e)}function s2CronRevert(e){var t,r;t=jQuery("#js"+e+"date").val(),jQuery('input[name="'+e+'date"]').val(t),jQuery("#s2"+e+"date").html(t),r=jQuery("#js"+e+"time").val(),jQuery("[name="+e+"time] option").filter(function(){return this.text===r}).prop("selected",!0).parent().focus(),jQuery("#s2"+e+"time").html(r),s2Hide(e)}jQuery(document).ready(function(){jQuery("#s2bcclimit_2").hide(),jQuery("#s2entries_2").hide(),jQuery("#s2cron_2").hide()});
include/s2-ip-updater.js CHANGED
@@ -1,12 +1,15 @@
 
1
  // Version 1.0 - original version
 
2
 
3
  function getip( json ) {
4
- if ( true === document.body.contains( document.forms['s2form'] ) ) {
5
- var ip = document.getElementsByName( 'ip' );
 
6
  for ( i = 0; i < ip.length; i++ ) {
7
  if ( 's2form' === ip[i].parentElement.name ) {
8
  ip[i].value = json.ip;
9
  }
10
  }
11
  }
12
- }
1
+ /* exported getip */
2
  // Version 1.0 - original version
3
+ // Version 1.1 - eslinted and fixed for Widget form name change
4
 
5
  function getip( json ) {
6
+ var ip, i;
7
+ if ( true === document.body.contains( document.forms.s2form ) || true === document.body.contains( document.forms.s2formwidget ) ) {
8
+ ip = document.getElementsByName( 'ip' );
9
  for ( i = 0; i < ip.length; i++ ) {
10
  if ( 's2form' === ip[i].parentElement.name ) {
11
  ip[i].value = json.ip;
12
  }
13
  }
14
  }
15
+ }
include/s2-ip-updater.min.js CHANGED
@@ -1 +1 @@
1
- function getip(json){if(true===document.body.contains(document.forms['s2form'])){var ip=document.getElementsByName('ip');for(i=0;i<ip.length;i++){if('s2form'===ip[i].parentElement.name){ip[i].value=json.ip}}}}
1
+ function getip(e){var n,o;if(!0===document.body.contains(document.forms.s2form)||!0===document.body.contains(document.forms.s2formwidget))for(n=document.getElementsByName("ip"),o=0;o<n.length;o++)"s2form"===n[o].parentElement.name&&(n[o].value=e.ip)}
include/s2-subscribers.js CHANGED
@@ -1,12 +1,17 @@
1
- /* global s2_script_strings */
2
- /* exported s2_delete_check, bu_cats, bu_format, bu_digest, s2_script_strings */
3
  // Version 1.0 - original version
4
  // Version 1.1 - context specific delete warnings for registered or public subscribers
5
  // Version 1.2 - single and plural string confirmation messages
 
 
 
6
 
7
- function s2_delete_check() {
8
- document.getElementById( 'doaction' ).onclick = submitHandler;
9
- document.getElementById( 'doaction2' ).onclick = submitHandler;
 
 
10
  }
11
  function submitHandler() {
12
  var location, action1, action2, agree, selected;
@@ -15,39 +20,39 @@ function submitHandler() {
15
  action2 = document.getElementById( 'bulk-action-selector-bottom' );
16
  agree = false;
17
  selected = document.querySelectorAll( 'input[name="subscriber[]"]:checked' ).length;
 
 
 
18
  if ( 'delete' === action1.value || 'delete' === action2.value ) {
19
  if ( 'registered' === location.value ) {
20
- if ( selected > 1 ) {
21
- agree = window.confirm( s2_script_strings.registered_confirm_plural );
22
  } else {
23
- agree = window.confirm( s2_script_strings.registered_confirm_single );
24
  }
25
  } else if ( 'public' === location.value ) {
26
- if ( selected > 1 ) {
27
- agree = window.confirm( s2_script_strings.public_confirm_plural );
28
  } else {
29
- agree = window.confirm( s2_script_strings.public_confirm_single );
30
  }
31
  }
 
 
32
  }
33
  return agree;
34
  }
35
- function bu_cats() {
36
- var action, actions = document.getElementsByName( 'manage' );
37
- for ( var i = 0; i < actions.length; i++ ) {
38
- if ( actions[i].checked ) {
39
- action = actions[i].value;
40
- }
 
 
 
 
41
  }
42
- document.getElementById( 'bulk-action-selector-top' ).value = action;
43
- document.getElementById( 'doaction' ).click();
44
- }
45
- function bu_format() {
46
- document.getElementById( 'bulk-action-selector-top' ).value = 'format';
47
- document.getElementById( 'doaction' ).click();
48
- }
49
- function bu_digest() {
50
- document.getElementById( 'bulk-action-selector-top' ).value = 'digest';
51
- document.getElementById( 'doaction' ).click();
52
  }
53
- window.onload = s2_delete_check;
1
+ /* global s2ScriptStrings */
2
+ /* exported s2BulkActionCheck, submitHandler, bmCheck, s2ScriptStrings */
3
  // Version 1.0 - original version
4
  // Version 1.1 - context specific delete warnings for registered or public subscribers
5
  // Version 1.2 - single and plural string confirmation messages
6
+ // Version 1.3 - fix suppressed form processing for Toggle action, JavaScript binding only if elements exist & more effecient handling when no users selected
7
+ // Version 1.4 - improve Bulk Management user experience and functions
8
+ // Version 1.5 - eslinted
9
 
10
+ function s2BulkActionCheck() {
11
+ if ( null !== document.getElementById( 'doaction' ) ) {
12
+ document.getElementById( 'doaction' ).onclick = submitHandler;
13
+ document.getElementById( 'doaction2' ).onclick = submitHandler;
14
+ }
15
  }
16
  function submitHandler() {
17
  var location, action1, action2, agree, selected;
20
  action2 = document.getElementById( 'bulk-action-selector-bottom' );
21
  agree = false;
22
  selected = document.querySelectorAll( 'input[name="subscriber[]"]:checked' ).length;
23
+ if ( 0 === selected ) {
24
+ return true;
25
+ }
26
  if ( 'delete' === action1.value || 'delete' === action2.value ) {
27
  if ( 'registered' === location.value ) {
28
+ if ( 1 < selected ) {
29
+ agree = window.confirm( s2ScriptStrings.registered_confirm_plural );
30
  } else {
31
+ agree = window.confirm( s2ScriptStrings.registered_confirm_single );
32
  }
33
  } else if ( 'public' === location.value ) {
34
+ if ( 1 < selected ) {
35
+ agree = window.confirm( s2ScriptStrings.public_confirm_plural );
36
  } else {
37
+ agree = window.confirm( s2ScriptStrings.public_confirm_single );
38
  }
39
  }
40
+ } else if ( 'toggle' === action1.value || 'toggle' === action2.value ) {
41
+ agree = true;
42
  }
43
  return agree;
44
  }
45
+ function bmCheck() {
46
+ var agree, selected;
47
+ agree = false;
48
+ selected = document.querySelectorAll( 'input[name="subscriber[]"]:checked' ).length;
49
+ if ( 0 === selected ) {
50
+ agree = window.confirm( s2ScriptStrings.bulk_manage_all );
51
+ } else if ( 1 < selected ) {
52
+ agree = window.confirm( s2ScriptStrings.bulk_manage_single );
53
+ } else {
54
+ agree = window.confirm( s2ScriptStrings.bulk_manage_plural );
55
  }
56
+ return agree;
 
 
 
 
 
 
 
 
 
57
  }
58
+ window.onload = s2BulkActionCheck;
include/s2-subscribers.min.js CHANGED
@@ -1 +1 @@
1
- function s2_delete_check(){document.getElementById("doaction").onclick=submitHandler,document.getElementById("doaction2").onclick=submitHandler}function submitHandler(){var a,b,c,d,e;return a=document.getElementById("s2_location"),b=document.getElementById("bulk-action-selector-top"),c=document.getElementById("bulk-action-selector-bottom"),d=!1,e=document.querySelectorAll('input[name="subscriber[]"]:checked').length,"delete"!==b.value&&"delete"!==c.value||("registered"===a.value?d=e>1?window.confirm(s2_script_strings.registered_confirm_plural):window.confirm(s2_script_strings.registered_confirm_single):"public"===a.value&&(d=e>1?window.confirm(s2_script_strings.public_confirm_plural):window.confirm(s2_script_strings.public_confirm_single))),d}function bu_cats(){for(var a,b=document.getElementsByName("manage"),c=0;c<b.length;c++)b[c].checked&&(a=b[c].value);document.getElementById("bulk-action-selector-top").value=a,document.getElementById("doaction").click()}function bu_format(){document.getElementById("bulk-action-selector-top").value="format",document.getElementById("doaction").click()}function bu_digest(){document.getElementById("bulk-action-selector-top").value="digest",document.getElementById("doaction").click()}window.onload=s2_delete_check;
1
+ function s2BulkActionCheck(){null!==document.getElementById("doaction")&&(document.getElementById("doaction").onclick=submitHandler,document.getElementById("doaction2").onclick=submitHandler)}function submitHandler(){var e,n,t,i,c;return e=document.getElementById("s2_location"),n=document.getElementById("bulk-action-selector-top"),t=document.getElementById("bulk-action-selector-bottom"),i=!1,0===(c=document.querySelectorAll('input[name="subscriber[]"]:checked').length)||("delete"===n.value||"delete"===t.value?"registered"===e.value?i=1<c?window.confirm(s2ScriptStrings.registered_confirm_plural):window.confirm(s2ScriptStrings.registered_confirm_single):"public"===e.value&&(i=1<c?window.confirm(s2ScriptStrings.public_confirm_plural):window.confirm(s2ScriptStrings.public_confirm_single)):"toggle"!==n.value&&"toggle"!==t.value||(i=!0),i)}function bmCheck(){var e;return!1,0===(e=document.querySelectorAll('input[name="subscriber[]"]:checked').length)?window.confirm(s2ScriptStrings.bulk_manage_all):1<e?window.confirm(s2ScriptStrings.bulk_manage_single):window.confirm(s2ScriptStrings.bulk_manage_plural)}window.onload=s2BulkActionCheck;
include/s2-user-admin.css CHANGED
@@ -1,69 +1,92 @@
1
- ul.s2_blogs {
2
- float: left;
3
- width: 99%;
 
 
4
  }
5
 
6
- ul.s2_blogs li {
7
- position: relative;
8
- display: block;
9
- float: left;
10
- margin: 3px;
11
- padding: 0.5em;
12
- width: 47%;
13
- border: 1px solid #E0E0E0;
14
- background-color: #E3E3E3;
15
- white-space: nowrap;
 
 
 
 
 
16
  }
17
 
18
- ul.s2_blogs li: hover {
19
- border-color: #666;
 
20
  }
21
 
22
- ul.s2_blogs li .name {
23
- display: block;
24
- float: left;
 
25
  }
26
 
27
- ul.s2_blogs li .buttons {
28
- display: block;
29
- float: right;
30
- margin-left: -6px;
31
- white-space: nowrap;
32
- font-size: .8em;
 
 
 
 
33
  }
34
 
35
- ul.s2_blogs li .buttons a {
36
- display: block;
37
- float: left;
38
- margin: 0 0 0 1em;
39
- padding: .1em .5em;
40
- background-color: #666;
41
- color: white;
 
 
 
42
  }
43
 
44
- ul.s2_blogs li .buttons a:hover {
45
- background-color: whitesmoke;
46
- color: #666;
 
47
  }
48
 
49
- ul.s2_blogs div.additional_info {
50
- position: absolute;
51
- bottom: 2.4em;
52
- left: -2px;
53
- z-index: 9;
54
- display: none;
55
- margin-bottom: 2px;
56
- padding: .5em 1em;
57
- width: 75%;
58
- border: 1px solid white;
59
- border-bottom: medium none;
60
- background-color: #666;
61
- color: #fff;
62
- font-style: italic;
63
- -moz-border-radius-topright: .5em;
64
- -moz-border-radius-topleft: .5em;
 
 
 
 
 
65
  }
66
 
67
- ul.s2_blogs li:hover div.additional_info {
68
- display: block;
69
- }
 
1
+ ul.s2_blogs
2
+ {
3
+ float: left;
4
+
5
+ width: 99%;
6
  }
7
 
8
+ ul.s2_blogs li
9
+ {
10
+ position: relative;
11
+
12
+ display: block;
13
+ float: left;
14
+
15
+ width: 47%;
16
+ margin: 3px;
17
+ padding: .5em;
18
+
19
+ white-space: nowrap;
20
+
21
+ border: 1px solid #e0e0e0;
22
+ background-color: #e3e3e3;
23
  }
24
 
25
+ ul.s2_blogs li:hover
26
+ {
27
+ border-color: #666;
28
  }
29
 
30
+ ul.s2_blogs li .name
31
+ {
32
+ display: block;
33
+ float: left;
34
  }
35
 
36
+ ul.s2_blogs li .buttons
37
+ {
38
+ font-size: .8em;
39
+
40
+ display: block;
41
+ float: right;
42
+
43
+ margin-left: -6px;
44
+
45
+ white-space: nowrap;
46
  }
47
 
48
+ ul.s2_blogs li .buttons a
49
+ {
50
+ display: block;
51
+ float: left;
52
+
53
+ margin: 0 0 0 1em;
54
+ padding: .1em .5em;
55
+
56
+ color: white;
57
+ background-color: #666;
58
  }
59
 
60
+ ul.s2_blogs li .buttons a:hover
61
+ {
62
+ color: #666;
63
+ background-color: whitesmoke;
64
  }
65
 
66
+ ul.s2_blogs div.additional_info
67
+ {
68
+ font-style: italic;
69
+
70
+ position: absolute;
71
+ z-index: 9;
72
+ bottom: 2.4em;
73
+ left: -2px;
74
+
75
+ display: none;
76
+
77
+ width: 75%;
78
+ margin-bottom: 2px;
79
+ padding: .5em 1em;
80
+
81
+ color: #fff;
82
+ border: 1px solid white;
83
+ border-bottom: medium none;
84
+ -moz-border-radius-topleft: .5em;
85
+ -moz-border-radius-topright: .5em;
86
+ background-color: #666;
87
  }
88
 
89
+ ul.s2_blogs li:hover div.additional_info
90
+ {
91
+ display: block;
92
+ }
include/s2-user-admin.min.css ADDED
@@ -0,0 +1 @@
 
1
+ ul.s2_blogs{float:left;width:99%}ul.s2_blogs li{position:relative;display:block;float:left;width:47%;margin:3px;padding:.5em;white-space:nowrap;border:1px solid #e0e0e0;background-color:#e3e3e3}ul.s2_blogs li:hover{border-color:#666}ul.s2_blogs li .name{display:block;float:left}ul.s2_blogs li .buttons{font-size:.8em;display:block;float:right;margin-left:-6px;white-space:nowrap}ul.s2_blogs li .buttons a{display:block;float:left;margin:0 0 0 1em;padding:.1em .5em;color:#fff;background-color:#666}ul.s2_blogs li .buttons a:hover{color:#666;background-color:#f5f5f5}ul.s2_blogs div.additional_info{font-style:italic;position:absolute;z-index:9;bottom:2.4em;left:-2px;display:none;width:75%;margin-bottom:2px;padding:.5em 1em;color:#fff;border:1px solid #fff;border-bottom:medium none;-moz-border-radius-topleft:.5em;-moz-border-radius-topright:.5em;background-color:#666}ul.s2_blogs li:hover div.additional_info{display:block}
subscribe2.php CHANGED
@@ -3,15 +3,15 @@
3
  Plugin Name: Subscribe2
4
  Plugin URI: https://subscribe2.wordpress.com/
5
  Description: Notifies an email list when new entries are posted.
6
- Version: 10.22.1
7
- Author: Matthew Robinson, Tanay Lakhani
8
  Author URI: https://subscribe2.wordpress.com/
9
  Licence: GPLv3
10
  Text Domain: subscribe2
11
  */
12
 
13
  /*
14
- Copyright (C) 2006-14 Matthew Robinson
15
  Based on the Original Subscribe2 plugin by
16
  Copyright (C) 2005 Scott Merrill (skippy@skippy.net)
17
 
@@ -35,45 +35,42 @@ if ( version_compare( $GLOBALS['wp_version'], '3.3', '<' ) || ! function_exists(
35
  if ( ! function_exists( 'add_action' ) ) {
36
  $exit_msg = __( "I'm just a plugin, please don't call me directly", 'subscribe2' );
37
  } else {
38
- // Subscribe2 needs WordPress 3.3 or above, exit if not on a compatible version
39
- $exit_msg = sprintf( __( 'This version of Subscribe2 requires WordPress 3.3 or greater. Please update %1$s or use an older version of %2$s.', 'subscribe2' ), '<a href="http://codex.wordpress.org/Updating_WordPress">Wordpress</a>', '<a href="http://wordpress.org/extend/plugins/subscribe2/download/">Subscribe2</a>' );
40
  }
41
  exit( $exit_msg );
42
  }
43
 
44
  // stop Subscribe2 being activated site wide on Multisite installs
45
  if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
46
- require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
47
  }
48
 
49
  if ( is_plugin_active_for_network( plugin_basename( __FILE__ ) ) ) {
50
  deactivate_plugins( plugin_basename( __FILE__ ) );
51
- $exit_msg = __( 'Subscribe2 cannot be activated as a network plugin. Please activate it on a site level', 'subscribe2' );
52
  exit( $exit_msg );
53
  }
54
 
55
  // our version number. Don't touch this or any line below
56
  // unless you know exactly what you are doing
57
- define( 'S2VERSION', '10.22' );
58
  define( 'S2PATH', trailingslashit( dirname( __FILE__ ) ) );
59
  define( 'S2DIR', trailingslashit( dirname( plugin_basename( __FILE__ ) ) ) );
60
  define( 'S2URL', plugin_dir_url( dirname( __FILE__ ) ) . S2DIR );
 
61
 
62
- // Set maximum execution time to 5 minutes - won't affect safe mode
63
- $safe_mode = array( 'On', 'ON', 'on', 1 );
64
- if ( ! in_array( ini_get( 'safe_mode' ), $safe_mode ) && ini_get( 'max_execution_time' ) < 300 ) {
65
- @ini_set( 'max_execution_time', 300 );
66
- }
67
 
68
- require_once( S2PATH . 'classes/class-s2-core.php' );
69
  if ( is_admin() ) {
70
- require_once( S2PATH . 'classes/class-s2-admin.php' );
71
  global $mysubscribe2;
72
- $mysubscribe2 = new S2_Admin;
73
  } else {
74
- require_once( S2PATH . 'classes/class-s2-frontend.php' );
75
  global $mysubscribe2;
76
- $mysubscribe2 = new S2_Frontend;
77
  }
78
- add_action( 'plugins_loaded', array( $mysubscribe2, 's2init' ) );
79
- ?>
3
  Plugin Name: Subscribe2
4
  Plugin URI: https://subscribe2.wordpress.com/
5
  Description: Notifies an email list when new entries are posted.
6
+ Version: 10.26
7
+ Author: Subscribe2
8
  Author URI: https://subscribe2.wordpress.com/
9
  Licence: GPLv3
10
  Text Domain: subscribe2
11
  */
12
 
13
  /*
14
+ Copyright (C) 2006-19 Matthew Robinson
15
  Based on the Original Subscribe2 plugin by
16
  Copyright (C) 2005 Scott Merrill (skippy@skippy.net)
17
 
35
  if ( ! function_exists( 'add_action' ) ) {
36
  $exit_msg = __( "I'm just a plugin, please don't call me directly", 'subscribe2' );
37
  } else {
38
+ // Translators: Subscribe2 needs WordPress 3.3 or above, exit if not on a compatible version
39
+ $exit_msg = sprintf( __( 'This version of Subscribe2 requires WordPress 3.3 or greater. Please update %1$s or use an older version of %2$s.', 'subscribe2' ), '<a href="http://codex.wordpress.org/Updating_WordPress">WordPress</a>', '<a href="https://semperplugins.com/subscribe2-html/">Subscribe2</a>' );
40
  }
41
  exit( $exit_msg );
42
  }
43
 
44
  // stop Subscribe2 being activated site wide on Multisite installs
45
  if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
46
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
47
  }
48
 
49
  if ( is_plugin_active_for_network( plugin_basename( __FILE__ ) ) ) {
50
  deactivate_plugins( plugin_basename( __FILE__ ) );
51
+ $exit_msg = __( 'Subscribe2 HTML cannot be activated as a network plugin. Please activate it on a site level', 'subscribe2' );
52
  exit( $exit_msg );
53
  }
54
 
55
  // our version number. Don't touch this or any line below
56
  // unless you know exactly what you are doing
57
+ define( 'S2VERSION', '10.26' );
58
  define( 'S2PATH', trailingslashit( dirname( __FILE__ ) ) );
59
  define( 'S2DIR', trailingslashit( dirname( plugin_basename( __FILE__ ) ) ) );
60
  define( 'S2URL', plugin_dir_url( dirname( __FILE__ ) ) . S2DIR );
61
+ define( 'S2GDPR', true );
62
 
63
+ // Set maximum execution time to 5 minutes
64
+ set_time_limit( 600 );
 
 
 
65
 
66
+ require_once S2PATH . 'classes/class-s2-core.php';
67
  if ( is_admin() ) {
68
+ require_once S2PATH . 'classes/class-s2-admin.php';
69
  global $mysubscribe2;
70
+ $mysubscribe2 = new S2_Admin();
71
  } else {
72
+ require_once S2PATH . 'classes/class-s2-frontend.php';
73
  global $mysubscribe2;
74
+ $mysubscribe2 = new S2_Frontend();
75
  }
76
+ add_action( 'plugins_loaded', array( $mysubscribe2, 's2init' ) );
 
subscribe2.pot ADDED
@@ -0,0 +1,1669 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #, fuzzy
2
+ msgid ""
3
+ msgstr ""
4
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
5
+ "Project-Id-Version: Subscribe2\n"
6
+ "POT-Creation-Date: 2019-01-25 22:59+0100\n"
7
+ "PO-Revision-Date: 2019-01-25 22:54+0100\n"
8
+ "Last-Translator: \n"
9
+ "Language-Team: \n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "X-Generator: Poedit 1.8.12\n"
14
+ "X-Poedit-Basepath: .\n"
15
+ "X-Poedit-WPHeader: subscribe2.php\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
18
+ "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
19
+ "_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
20
+ "X-Poedit-SearchPath-0: .\n"
21
+ "X-Poedit-SearchPathExcluded-0: *.js\n"
22
+
23
+ #: admin/send-email.php:11 admin/settings.php:11 admin/subscribers.php:32
24
+ #: admin/your-subscriptions.php:13
25
+ msgid "Security error! Your request cannot be completed."
26
+ msgstr ""
27
+
28
+ #: admin/send-email.php:79
29
+ msgid "Your email was empty"
30
+ msgstr ""
31
+
32
+ #: admin/send-email.php:86
33
+ msgid "Check your settings and check with your hosting provider"
34
+ msgstr ""
35
+
36
+ #: admin/send-email.php:91
37
+ msgid "Preview message sent!"
38
+ msgstr ""
39
+
40
+ #: admin/send-email.php:93
41
+ msgid "Message sent!"
42
+ msgstr ""
43
+
44
+ #: admin/send-email.php:97
45
+ msgid "Message failed!"
46
+ msgstr ""
47
+
48
+ #: admin/send-email.php:104
49
+ msgid "Send an email to subscribers"
50
+ msgstr ""
51
+
52
+ #: admin/send-email.php:112
53
+ msgid "A message from"
54
+ msgstr ""
55
+
56
+ #: admin/send-email.php:117
57
+ msgid "Subject"
58
+ msgstr ""
59
+
60
+ #: admin/send-email.php:120
61
+ msgid "Add More Files"
62
+ msgstr ""
63
+
64
+ #: admin/send-email.php:122
65
+ msgid "Recipients:"
66
+ msgstr ""
67
+
68
+ #: admin/send-email.php:125
69
+ msgid "Preview"
70
+ msgstr ""
71
+
72
+ #: admin/send-email.php:125
73
+ msgid "Send"
74
+ msgstr ""
75
+
76
+ #: admin/settings.php:19
77
+ msgid "Options reset!"
78
+ msgstr ""
79
+
80
+ #: admin/settings.php:30
81
+ msgid "Preview message(s) sent to logged in user"
82
+ msgstr ""
83
+
84
+ #: admin/settings.php:35
85
+ msgid "Attempt made to resend the Digest Notification email"
86
+ msgstr ""
87
+
88
+ #: admin/settings.php:37
89
+ msgid ""
90
+ "The Digest Notification email contained no post information. No email was "
91
+ "sent"
92
+ msgstr ""
93
+
94
+ #: admin/settings.php:120
95
+ msgid "Options saved!"
96
+ msgstr ""
97
+
98
+ #: admin/settings.php:128
99
+ msgid "You must create a WordPress page for this plugin to work correctly."
100
+ msgstr ""
101
+
102
+ #: admin/settings.php:134
103
+ msgid "Your Settings may breach GDPR"
104
+ msgstr ""
105
+
106
+ #: admin/settings.php:150
107
+ msgid "Modify your template"
108
+ msgstr ""
109
+
110
+ #: admin/settings.php:152
111
+ msgid ""
112
+ "Your chosen email type (per-post or digest) does not support the following "
113
+ "keywords:"
114
+ msgstr ""
115
+
116
+ #: admin/settings.php:166
117
+ #, php-format
118
+ msgid ""
119
+ "You appear to be sending notifications from %1$s, which has a different "
120
+ "domain name than your blog server %2$s. This may result in failed emails."
121
+ msgstr ""
122
+
123
+ #: admin/settings.php:174 classes/class-s2-admin.php:22
124
+ #: classes/class-s2-admin.php:259
125
+ msgid "Settings"
126
+ msgstr ""
127
+
128
+ #: admin/settings.php:176 classes/class-s2-admin.php:116
129
+ msgid "Email Settings"
130
+ msgstr ""
131
+
132
+ #: admin/settings.php:177 classes/class-s2-admin.php:126
133
+ msgid "Templates"
134
+ msgstr ""
135
+
136
+ #: admin/settings.php:178 classes/class-s2-admin.php:136
137
+ msgid "Registered Users"
138
+ msgstr ""
139
+
140
+ #: admin/settings.php:179 classes/class-s2-admin.php:145
141
+ msgid "Appearance"
142
+ msgstr ""
143
+
144
+ #: admin/settings.php:180 classes/class-s2-admin.php:163
145
+ msgid "Miscellaneous"
146
+ msgstr ""
147
+
148
+ #: admin/settings.php:201
149
+ msgid ""
150
+ "Restrict the number of <strong>recipients per email</strong> to (0 for "
151
+ "unlimited)"
152
+ msgstr ""
153
+
154
+ #: admin/settings.php:203 classes/class-s2-admin.php:751
155
+ #: classes/class-s2-list-table-legacy.php:43 classes/class-s2-list-table.php:43
156
+ msgid "Edit"
157
+ msgstr ""
158
+
159
+ #: admin/settings.php:206 classes/class-s2-admin.php:765
160
+ msgid "Update"
161
+ msgstr ""
162
+
163
+ #: admin/settings.php:207 classes/class-s2-admin.php:766
164
+ msgid "Revert"
165
+ msgstr ""
166
+
167
+ #: admin/settings.php:209
168
+ msgid "Send Admins notifications for new"
169
+ msgstr ""
170
+
171
+ #: admin/settings.php:211
172
+ msgid "Subscriptions"
173
+ msgstr ""
174
+
175
+ #: admin/settings.php:213
176
+ msgid "Unsubscriptions"
177
+ msgstr ""
178
+
179
+ #: admin/settings.php:215
180
+ msgid "Both"
181
+ msgstr ""
182
+
183
+ #: admin/settings.php:217
184
+ msgid "Neither"
185
+ msgstr ""
186
+
187
+ #: admin/settings.php:219
188
+ msgid "Include theme CSS stylesheet in HTML notifications"
189
+ msgstr ""
190
+
191
+ #: admin/settings.php:221 admin/settings.php:227 admin/settings.php:241
192
+ #: admin/settings.php:246 admin/settings.php:252 admin/settings.php:382
193
+ #: admin/settings.php:388 admin/settings.php:403 admin/settings.php:411
194
+ #: admin/settings.php:427 admin/settings.php:434 admin/subscribers.php:328
195
+ #: classes/class-s2-forms.php:59 classes/class-s2-forms.php:100
196
+ msgid "Yes"
197
+ msgstr ""
198
+
199
+ #: admin/settings.php:223 admin/settings.php:229 admin/settings.php:243
200
+ #: admin/settings.php:248 admin/settings.php:254 admin/settings.php:379
201
+ #: admin/settings.php:384 admin/settings.php:390 admin/settings.php:405
202
+ #: admin/settings.php:413 admin/settings.php:423 admin/settings.php:429
203
+ #: admin/settings.php:436 admin/subscribers.php:330
204
+ #: classes/class-s2-forms.php:61 classes/class-s2-forms.php:104
205
+ msgid "No"
206
+ msgstr ""
207
+
208
+ #: admin/settings.php:225
209
+ msgid "Send Emails for Pages"
210
+ msgstr ""
211
+
212
+ #: admin/settings.php:233
213
+ msgid ""
214
+ "Subscribe2 will send email notifications for the following custom post types"
215
+ msgstr ""
216
+
217
+ #: admin/settings.php:239
218
+ msgid "Send Emails for Password Protected Posts"
219
+ msgstr ""
220
+
221
+ #: admin/settings.php:244
222
+ msgid "Send Emails for Private Posts"
223
+ msgstr ""
224
+
225
+ #: admin/settings.php:250
226
+ msgid "Include Sticky Posts at the top of all Digest Notifications"
227
+ msgstr ""
228
+
229
+ #: admin/settings.php:256
230
+ msgid "Send Email From"
231
+ msgstr ""
232
+
233
+ #: admin/settings.php:261
234
+ msgid "Send Emails"
235
+ msgstr ""
236
+
237
+ #: admin/settings.php:263
238
+ msgid "For digest notifications, date order for posts is"
239
+ msgstr ""
240
+
241
+ #: admin/settings.php:265
242
+ msgid "Descending"
243
+ msgstr ""
244
+
245
+ #: admin/settings.php:267
246
+ msgid "Ascending"
247
+ msgstr ""
248
+
249
+ #: admin/settings.php:269
250
+ msgid "Add Tracking Parameters to the Permalink"
251
+ msgstr ""
252
+
253
+ #: admin/settings.php:271
254
+ msgid ""
255
+ "eg. utm_source=subscribe2&amp;utm_medium=email&amp;"
256
+ "utm_campaign=postnotify&amp;utm_id={ID}&amp;utm_title={TITLE}"
257
+ msgstr ""
258
+
259
+ #: admin/settings.php:282
260
+ msgid "Notification email (must not be empty)"
261
+ msgstr ""
262
+
263
+ #: admin/settings.php:283 admin/settings.php:316 admin/settings.php:321
264
+ msgid "Subject Line"
265
+ msgstr ""
266
+
267
+ #: admin/settings.php:288
268
+ msgid "Send Email Preview"
269
+ msgstr ""
270
+
271
+ #: admin/settings.php:289
272
+ msgid "Message substitutions"
273
+ msgstr ""
274
+
275
+ #: admin/settings.php:291
276
+ msgid ""
277
+ "IF THE FOLLOWING KEYWORDS ARE ALSO IN YOUR POST THEY WILL BE SUBSTITUTED"
278
+ msgstr ""
279
+
280
+ #: admin/settings.php:294
281
+ msgid "the post's title<br />(<i>for per-post emails only</i>)"
282
+ msgstr ""
283
+
284
+ #: admin/settings.php:295
285
+ msgid "the post's unformatted title <br />(<i>for per-post emails only</i>)"
286
+ msgstr ""
287
+
288
+ #: admin/settings.php:296
289
+ msgid ""
290
+ "the excerpt or the entire post<br />(<i>based on the subscriber's "
291
+ "preferences</i>)"
292
+ msgstr ""
293
+
294
+ #: admin/settings.php:297
295
+ msgid ""
296
+ "the excerpt of the post and the time it was posted<br />(<i>for digest "
297
+ "emails only</i>)"
298
+ msgstr ""
299
+
300
+ #: admin/settings.php:298
301
+ msgid "a list of post titles<br />(<i>for digest emails only</i>)"
302
+ msgstr ""
303
+
304
+ #: admin/settings.php:299
305
+ msgid ""
306
+ "a list of post titles followed by links to the articles<br />(<i>for digest "
307
+ "emails only</i>)"
308
+ msgstr ""
309
+
310
+ #: admin/settings.php:300
311
+ msgid ""
312
+ "a reference style list of links at the end of the email with corresponding "
313
+ "numbers in the content<br />(<i>for the full content plain text per-post "
314
+ "email only</i>)"
315
+ msgstr ""
316
+
317
+ #: admin/settings.php:301
318
+ msgid "the post's permalink<br />(<i>for per-post emails only</i>)"
319
+ msgstr ""
320
+
321
+ #: admin/settings.php:302
322
+ msgid "the post's permalink after conversion by TinyURL"
323
+ msgstr ""
324
+
325
+ #: admin/settings.php:303
326
+ msgid "the post's unformatted permalink<br />(<i>for per-post emails only</i>)"
327
+ msgstr ""
328
+
329
+ #: admin/settings.php:304
330
+ msgid "the date the post was made<br />(<i>for per-post emails only</i>)"
331
+ msgstr ""
332
+
333
+ #: admin/settings.php:305
334
+ msgid "the time the post was made<br />(<i>for per-post emails only</i>)"
335
+ msgstr ""
336
+
337
+ #: admin/settings.php:306
338
+ msgid "the admin or post author's name"
339
+ msgstr ""
340
+
341
+ #: admin/settings.php:307
342
+ msgid "the admin or post author's email"
343
+ msgstr ""
344
+
345
+ #: admin/settings.php:308
346
+ msgid "the post author's name"
347
+ msgstr ""
348
+
349
+ #: admin/settings.php:309
350
+ msgid ""
351
+ "the generated link to confirm a request<br />(<i>only used in the "
352
+ "confirmation email template</i>)"
353
+ msgstr ""
354
+
355
+ #: admin/settings.php:310
356
+ msgid ""
357
+ "Action performed by LINK in confirmation email<br />(<i>only used in the "
358
+ "confirmation email template</i>)"
359
+ msgstr ""
360
+
361
+ #: admin/settings.php:311
362
+ msgid "the post's assigned categories"
363
+ msgstr ""
364
+
365
+ #: admin/settings.php:312
366
+ msgid "the post's assigned Tags"
367
+ msgstr ""
368
+
369
+ #: admin/settings.php:313
370
+ msgid ""
371
+ "the number of posts included in the digest email<br />(<i>for digest emails "
372
+ "only</i>)"
373
+ msgstr ""
374
+
375
+ #: admin/settings.php:315
376
+ msgid "Subscribe / Unsubscribe confirmation email"
377
+ msgstr ""
378
+
379
+ #: admin/settings.php:320
380
+ msgid "Reminder email to Unconfirmed Subscribers"
381
+ msgstr ""
382
+
383
+ #: admin/settings.php:336
384
+ msgid "Compulsory Categories"
385
+ msgstr ""
386
+
387
+ #: admin/settings.php:338
388
+ msgid ""
389
+ "Compulsory categories will be checked by default for Registered Subscribers"
390
+ msgstr ""
391
+
392
+ #: admin/settings.php:345
393
+ msgid "Excluded Categories"
394
+ msgstr ""
395
+
396
+ #: admin/settings.php:347
397
+ msgid ""
398
+ "Posts assigned to any Excluded Category do not generate notifications and "
399
+ "are not included in digest notifications"
400
+ msgstr ""
401
+
402
+ #: admin/settings.php:351
403
+ msgid "Allow registered users to subscribe to excluded categories?"
404
+ msgstr ""
405
+
406
+ #: admin/settings.php:359
407
+ msgid "Excluded Formats"
408
+ msgstr ""
409
+
410
+ #: admin/settings.php:361
411
+ msgid ""
412
+ "Posts assigned to any Excluded Format do not generate notifications and are "
413
+ "not included in digest notifications"
414
+ msgstr ""
415
+
416
+ #: admin/settings.php:369
417
+ msgid "Auto-Subscribe"
418
+ msgstr ""
419
+
420
+ #: admin/settings.php:371
421
+ msgid "Subscribe new users registering with your blog"
422
+ msgstr ""
423
+
424
+ #: admin/settings.php:374
425
+ msgid "Automatically"
426
+ msgstr ""
427
+
428
+ #: admin/settings.php:377
429
+ msgid "Display option on Registration Form"
430
+ msgstr ""
431
+
432
+ #: admin/settings.php:380
433
+ msgid "Auto-subscribe includes any excluded categories"
434
+ msgstr ""
435
+
436
+ #: admin/settings.php:386
437
+ msgid "Registration Form option is checked by default"
438
+ msgstr ""
439
+
440
+ #: admin/settings.php:392
441
+ msgid "Auto-subscribe users to receive email as"
442
+ msgstr ""
443
+
444
+ #: admin/settings.php:394 admin/subscribers.php:314
445
+ #: classes/class-s2-forms.php:48
446
+ msgid "HTML - Full"
447
+ msgstr ""
448
+
449
+ #: admin/settings.php:396 admin/subscribers.php:315
450
+ #: classes/class-s2-forms.php:50
451
+ msgid "HTML - Excerpt"
452
+ msgstr ""
453
+
454
+ #: admin/settings.php:398 admin/subscribers.php:316
455
+ #: classes/class-s2-forms.php:52
456
+ msgid "Plain Text - Full"
457
+ msgstr ""
458
+
459
+ #: admin/settings.php:400 admin/subscribers.php:317
460
+ #: classes/class-s2-forms.php:54
461
+ msgid "Plain Text - Excerpt"
462
+ msgstr ""
463
+
464
+ #: admin/settings.php:401
465
+ msgid "Registered Users have the option to auto-subscribe to new categories"
466
+ msgstr ""
467
+
468
+ #: admin/settings.php:407
469
+ msgid "New categories are immediately excluded"
470
+ msgstr ""
471
+
472
+ #: admin/settings.php:409
473
+ msgid ""
474
+ "Option for Registered Users to auto-subscribe to new categories is checked "
475
+ "by default"
476
+ msgstr ""
477
+
478
+ #: admin/settings.php:417
479
+ msgid "Display checkbox to allow subscriptions from the comment form"
480
+ msgstr ""
481
+
482
+ #: admin/settings.php:419
483
+ msgid "Before the Comment Submit button"
484
+ msgstr ""
485
+
486
+ #: admin/settings.php:421
487
+ msgid "After the Comment Submit button"
488
+ msgstr ""
489
+
490
+ #: admin/settings.php:425
491
+ msgid "Comment form checkbox is checked by default"
492
+ msgstr ""
493
+
494
+ #: admin/settings.php:432
495
+ msgid "Show one-click subscription on profile page"
496
+ msgstr ""
497
+
498
+ #: admin/settings.php:447
499
+ msgid "Set default Subscribe2 page as"
500
+ msgstr ""
501
+
502
+ #: admin/settings.php:449
503
+ msgid "Select a page"
504
+ msgstr ""
505
+
506
+ #: admin/settings.php:455
507
+ msgid "Show a link to your subscription page in \"meta\"?"
508
+ msgstr ""
509
+
510
+ #: admin/settings.php:459
511
+ msgid "Show the Subscribe2 button on the Write toolbar?"
512
+ msgstr ""
513
+
514
+ #: admin/settings.php:463
515
+ msgid "Enable popup style subscription form?"
516
+ msgstr ""
517
+
518
+ #: admin/settings.php:467
519
+ msgid "Enable Subscribe2 Widget?"
520
+ msgstr ""
521
+
522
+ #: admin/settings.php:471
523
+ msgid "Enable Subscribe2 Counter Widget?"
524
+ msgstr ""
525
+
526
+ #: admin/settings.php:475
527
+ msgid "Disable email notifications is checked by default on authoring pages?"
528
+ msgstr ""
529
+
530
+ #: admin/settings.php:479
531
+ msgid ""
532
+ "Use javascript to update IP address in Subscribe2 HTML form data? (useful if "
533
+ "caching is enabled)"
534
+ msgstr ""
535
+
536
+ #: admin/settings.php:487
537
+ msgid "Barred Domains"
538
+ msgstr ""
539
+
540
+ #: admin/settings.php:489
541
+ msgid ""
542
+ "Enter domains to bar for public subscriptions, wildcards (*) and exceptions "
543
+ "(!) are allowed"
544
+ msgstr ""
545
+
546
+ #: admin/settings.php:490
547
+ msgid ""
548
+ "Use a new line for each entry and omit the \"@\" symbol, for example !email."
549
+ "com, hotmail.com, yahoo.*"
550
+ msgstr ""
551
+
552
+ #: admin/settings.php:493
553
+ msgid "Links"
554
+ msgstr ""
555
+
556
+ #: admin/settings.php:494
557
+ msgid "Plugin Site"
558
+ msgstr ""
559
+
560
+ #: admin/settings.php:495
561
+ msgid "Plugin Forum"
562
+ msgstr ""
563
+
564
+ #: admin/settings.php:496
565
+ msgid "Plugin Blog"
566
+ msgstr ""
567
+
568
+ #: admin/settings.php:497
569
+ msgid "Make a donation via PayPal"
570
+ msgstr ""
571
+
572
+ #: admin/settings.php:503
573
+ msgid "Submit"
574
+ msgstr ""
575
+
576
+ #: admin/settings.php:507
577
+ msgid "Reset to Default Settings"
578
+ msgstr ""
579
+
580
+ #: admin/settings.php:508
581
+ msgid ""
582
+ "Use this to reset all options to their defaults. This <strong><em>will not</"
583
+ "em></strong> modify your list of subscribers."
584
+ msgstr ""
585
+
586
+ #: admin/settings.php:510
587
+ msgid "RESET"
588
+ msgstr ""
589
+
590
+ #: admin/subscribers.php:57
591
+ msgid "Address(es) subscribed!"
592
+ msgstr ""
593
+
594
+ #: admin/subscribers.php:64
595
+ msgid "Address(es) unsubscribed!"
596
+ msgstr ""
597
+
598
+ #: admin/subscribers.php:69
599
+ msgid ""
600
+ "Some emails were not processed, the following are already Registered "
601
+ "Subscribers"
602
+ msgstr ""
603
+
604
+ #: admin/subscribers.php:72
605
+ msgid ""
606
+ "Some emails were not processed, the following are already Public Subscribers"
607
+ msgstr ""
608
+
609
+ #: admin/subscribers.php:75
610
+ msgid "Some emails were not processed, the following were not in the database"
611
+ msgstr ""
612
+
613
+ #: admin/subscribers.php:78
614
+ msgid ""
615
+ "Some emails were not processed, the following were invalid email addresses"
616
+ msgstr ""
617
+
618
+ #: admin/subscribers.php:86
619
+ msgid "Reminder Email(s) Sent!"
620
+ msgstr ""
621
+
622
+ #: admin/subscribers.php:93
623
+ msgid "Registered Users Subscribed!"
624
+ msgstr ""
625
+
626
+ #: admin/subscribers.php:100
627
+ msgid "Registered Users Unsubscribed!"
628
+ msgstr ""
629
+
630
+ #: admin/subscribers.php:107
631
+ msgid "Format updated for Selected Registered Users!"
632
+ msgstr ""
633
+
634
+ #: admin/subscribers.php:114
635
+ msgid "Digest Subscription updated for Selected Registered Users!"
636
+ msgstr ""
637
+
638
+ #: admin/subscribers.php:199 classes/class-s2-admin.php:15
639
+ msgid "Subscribers"
640
+ msgstr ""
641
+
642
+ #: admin/subscribers.php:201 classes/class-s2-admin.php:69
643
+ #: classes/class-s2-admin.php:573
644
+ msgid "Public Subscribers"
645
+ msgstr ""
646
+
647
+ #: admin/subscribers.php:202 classes/class-s2-admin.php:76
648
+ #: classes/class-s2-admin.php:577
649
+ msgid "Registered Subscribers"
650
+ msgstr ""
651
+
652
+ #: admin/subscribers.php:217 admin/subscribers.php:240
653
+ msgid "Add/Remove Subscribers"
654
+ msgstr ""
655
+
656
+ #: admin/subscribers.php:218
657
+ msgid "Enter addresses, one per line or comma-separated"
658
+ msgstr ""
659
+
660
+ #: admin/subscribers.php:221 admin/subscribers.php:305
661
+ #: classes/class-s2-forms.php:195 classes/class-s2-frontend.php:84
662
+ msgid "Subscribe"
663
+ msgstr ""
664
+
665
+ #: admin/subscribers.php:222 admin/subscribers.php:306
666
+ #: classes/class-s2-forms.php:174 classes/class-s2-frontend.php:83
667
+ msgid "Unsubscribe"
668
+ msgstr ""
669
+
670
+ #: admin/subscribers.php:227 admin/subscribers.php:247
671
+ msgid "Current Subscribers"
672
+ msgstr ""
673
+
674
+ #: admin/subscribers.php:241
675
+ msgid "Add Registered User"
676
+ msgstr ""
677
+
678
+ #: admin/subscribers.php:256
679
+ msgid "Filter"
680
+ msgstr ""
681
+
682
+ #: admin/subscribers.php:260
683
+ msgid "Send Reminder Email"
684
+ msgstr ""
685
+
686
+ #: admin/subscribers.php:274
687
+ msgid "Save Emails to CSV File"
688
+ msgstr ""
689
+
690
+ #: admin/subscribers.php:281
691
+ msgid "Search"
692
+ msgstr ""
693
+
694
+ #: admin/subscribers.php:288
695
+ msgid "Bulk Management"
696
+ msgstr ""
697
+
698
+ #: admin/subscribers.php:302 admin/subscribers.php:324
699
+ msgid ""
700
+ "Preferences for Registered Users selected above can be changed using this "
701
+ "section."
702
+ msgstr ""
703
+
704
+ #: admin/subscribers.php:303
705
+ msgid "Consider User Privacy as changes cannot be undone"
706
+ msgstr ""
707
+
708
+ #: admin/subscribers.php:304
709
+ msgid "Action to perform"
710
+ msgstr ""
711
+
712
+ #: admin/subscribers.php:312
713
+ msgid "Bulk Update Categories"
714
+ msgstr ""
715
+
716
+ #: admin/subscribers.php:313
717
+ msgid "Send email as"
718
+ msgstr ""
719
+
720
+ #: admin/subscribers.php:318
721
+ msgid "Bulk Update Format"
722
+ msgstr ""
723
+
724
+ #: admin/subscribers.php:325
725
+ msgid "Consider User Privacy as changes cannot be undone."
726
+ msgstr ""
727
+
728
+ #: admin/subscribers.php:326
729
+ msgid "Subscribe Selected Users to receive a periodic digest notification"
730
+ msgstr ""
731
+
732
+ #: admin/subscribers.php:331
733
+ msgid "Bulk Update Digest Subscription"
734
+ msgstr ""
735
+
736
+ #: admin/your-subscriptions.php:26
737
+ msgid "Your Notification Settings"
738
+ msgstr ""
739
+
740
+ #: admin/your-subscriptions.php:28
741
+ msgid "Notification Settings for user:"
742
+ msgstr ""
743
+
744
+ #: admin/your-subscriptions.php:40
745
+ msgid "Update Preferences"
746
+ msgstr ""
747
+
748
+ #. Plugin Name of the plugin/theme
749
+ #. Author of the plugin/theme
750
+ #: classes/class-s2-admin.php:8 classes/class-s2-form-widget.php:24
751
+ msgid "Subscribe2"
752
+ msgstr ""
753
+
754
+ #: classes/class-s2-admin.php:10
755
+ msgid "Your Subscriptions"
756
+ msgstr ""
757
+
758
+ #: classes/class-s2-admin.php:29
759
+ msgid "Send Email"
760
+ msgstr ""
761
+
762
+ #: classes/class-s2-admin.php:42 classes/class-s2-admin.php:50
763
+ #: classes/class-s2-admin.php:62 classes/class-s2-admin.php:109
764
+ #: classes/class-s2-admin.php:176
765
+ msgid "Overview"
766
+ msgstr ""
767
+
768
+ #: classes/class-s2-admin.php:43
769
+ msgid ""
770
+ "From this page you can opt in or out of receiving a periodical digest style "
771
+ "email of blog posts."
772
+ msgstr ""
773
+
774
+ #: classes/class-s2-admin.php:51
775
+ msgid ""
776
+ "From this page you can control your subscription preferences. Choose the "
777
+ "email format you wish to receive, which categories you would like to receive "
778
+ "notification for and depending on the site settings which authors you would "
779
+ "like to read."
780
+ msgstr ""
781
+
782
+ #: classes/class-s2-admin.php:63
783
+ msgid "From this page you can manage your subscribers."
784
+ msgstr ""
785
+
786
+ #: classes/class-s2-admin.php:70
787
+ msgid ""
788
+ "Public Subscribers are subscribers who have used the plugin form and only "
789
+ "provided their email address."
790
+ msgstr ""
791
+
792
+ #: classes/class-s2-admin.php:70
793
+ msgid ""
794
+ "On this page public subscribers can be viewed, searched, deleted and also "
795
+ "toggled between Confirmed and Unconfirmed status."
796
+ msgstr ""
797
+
798
+ #: classes/class-s2-admin.php:77
799
+ msgid ""
800
+ "Registered Subscribers are subscribers who have registered in WordPress and "
801
+ "have a username and password."
802
+ msgstr ""
803
+
804
+ #: classes/class-s2-admin.php:78
805
+ msgid ""
806
+ "Registered Subscribers have greater personal control over their "
807
+ "subscription. They can change the format of the email and also select which "
808
+ "categories and authors they want to receive notifications about."
809
+ msgstr ""
810
+
811
+ #: classes/class-s2-admin.php:79
812
+ msgid ""
813
+ "On this page registered subscribers can be viewed and searched. User "
814
+ "accounts can be deleted from here with any posts created by those users "
815
+ "being assigned to the currently logged in user. Bulk changes can be applied "
816
+ "to all user settings changing their subscription email format and categories."
817
+ msgstr ""
818
+
819
+ #: classes/class-s2-admin.php:88
820
+ msgid "Number of subscribers per page: "
821
+ msgstr ""
822
+
823
+ #: classes/class-s2-admin.php:110
824
+ msgid "From this page you can adjust the Settings for Subscribe2."
825
+ msgstr ""
826
+
827
+ #: classes/class-s2-admin.php:117
828
+ msgid ""
829
+ "This section allows you to specify settings that apply to the emails "
830
+ "generated by the site."
831
+ msgstr ""
832
+
833
+ #: classes/class-s2-admin.php:118
834
+ msgid ""
835
+ "Emails can be sent to individual subscribers by setting the number of "
836
+ "recipients per email to 1. A setting greater than one will group recipients "
837
+ "together and make use of the BCC emails header. A setting of 0 sends a "
838
+ "single email with all subscribers in one large BCC group. A setting of 1 "
839
+ "looks less like spam email to filters but takes longer to process."
840
+ msgstr ""
841
+
842
+ #: classes/class-s2-admin.php:119
843
+ msgid ""
844
+ "This section is also where the sender of the email on this page is chosen. "
845
+ "You can choose Post Author or your Blogname but it is recommended to create "
846
+ "a user account with an email address that really exists and shares the same "
847
+ "domain name as your site (the bit after the @ should be the same as your "
848
+ "sites web address) and then use this account."
849
+ msgstr ""
850
+
851
+ #: classes/class-s2-admin.php:120
852
+ msgid ""
853
+ "This page also configures the frequency of emails. This can be at the time "
854
+ "new posts are made (per post) or periodically with an excerpt of each post "
855
+ "made (digest). Additionally the post types (pages, private, password "
856
+ "protected) can also be configured here."
857
+ msgstr ""
858
+
859
+ #: classes/class-s2-admin.php:127
860
+ msgid ""
861
+ "This section allows you to customise the content of your notification emails."
862
+ msgstr ""
863
+
864
+ #: classes/class-s2-admin.php:128
865
+ msgid ""
866
+ "There are special {KEYWORDS} that are used by Subscribe2 to place content "
867
+ "into the final email. The template also accepts regular text and HTML as "
868
+ "desired in the final emails."
869
+ msgstr ""
870
+
871
+ #: classes/class-s2-admin.php:129
872
+ msgid ""
873
+ "The {KEYWORDS} are listed on the right of the templates, note that some are "
874
+ "for per post emails only and some are for digest emails only. Make sure the "
875
+ "correct keywords are used based upon the Email Settings."
876
+ msgstr ""
877
+
878
+ #: classes/class-s2-admin.php:130
879
+ msgid ""
880
+ "The Notification Email template is used for sending notifications of new "
881
+ "posts. The Subscribe / Unsubscribe confirmation template is sent when a new "
882
+ "subscription or unsubscription request is made. The Reminder template is "
883
+ "used to send reminder emails; this is done automatically or can be done "
884
+ "manually."
885
+ msgstr ""
886
+
887
+ #: classes/class-s2-admin.php:137
888
+ msgid ""
889
+ "This section allows settings that apply to Registered Subscribers to be "
890
+ "configured."
891
+ msgstr ""
892
+
893
+ #: classes/class-s2-admin.php:138
894
+ msgid ""
895
+ "Categories can be made compulsory so emails are always sent for posts in "
896
+ "these categories. They can also be excludes so that emails are not "
897
+ "generated. Excluded categories take precedence over Compulsory categories."
898
+ msgstr ""
899
+
900
+ #: classes/class-s2-admin.php:139
901
+ msgid ""
902
+ "A set of default settings for new users can also be specified using the Auto "
903
+ "Subscribe section. Settings specified here will be applied to any newly "
904
+ "created user accounts while Subscribe2 is activated."
905
+ msgstr ""
906
+
907
+ #: classes/class-s2-admin.php:146
908
+ msgid ""
909
+ "This section allows you to enable several aspect of the plugin such as "
910
+ "Widgets and editor buttons."
911
+ msgstr ""
912
+
913
+ #: classes/class-s2-admin.php:147
914
+ msgid ""
915
+ "AJAX mode can be enabled that is intended to work with the shortcode link "
916
+ "parameter so that a dialog opens in the centre of the browser rather then "
917
+ "using the regular form."
918
+ msgstr ""
919
+
920
+ #: classes/class-s2-admin.php:148
921
+ msgid ""
922
+ "The email over ride check box can be set to be automatically checked for "
923
+ "every new post and page from here to, this may be useful if you will only "
924
+ "want to send very occasional notifications for specific posts. You can then "
925
+ "uncheck this box just before you publish your content."
926
+ msgstr ""
927
+
928
+ #: classes/class-s2-admin.php:154
929
+ msgid "ReCaptcha"
930
+ msgstr ""
931
+
932
+ #: classes/class-s2-admin.php:155
933
+ msgid "This section holds site and secret keys for using Google ReCaptcha."
934
+ msgstr ""
935
+
936
+ #: classes/class-s2-admin.php:156
937
+ msgid ""
938
+ "V2 ReCaptcha takes precedence over Invisible ReCaptcha. To use Invisible "
939
+ "ReCaptcha, leave the V2 ReCaptcha key fields empty."
940
+ msgstr ""
941
+
942
+ #: classes/class-s2-admin.php:157
943
+ msgid ""
944
+ "Both key files needs populating for V2 ReCaptcha or Invisible ReCaptcha, "
945
+ "failure to complete both fields will result in ReCaptcha not working."
946
+ msgstr ""
947
+
948
+ #: classes/class-s2-admin.php:164
949
+ msgid ""
950
+ "This section contains a place to bar specified domains from becoming Public "
951
+ "Subscribers and links to help and support pages."
952
+ msgstr ""
953
+
954
+ #: classes/class-s2-admin.php:165
955
+ msgid ""
956
+ "In the paid Subscribe2 HTML version there is also a place here to enter a "
957
+ "license code so that updates can be accessed automatically."
958
+ msgstr ""
959
+
960
+ #: classes/class-s2-admin.php:177
961
+ msgid ""
962
+ "From this page you can send emails to the recipients in the group selected "
963
+ "in the drop down."
964
+ msgstr ""
965
+
966
+ #: classes/class-s2-admin.php:178
967
+ msgid ""
968
+ "<strong>Preview</strong> will send a preview of the email to the currently "
969
+ "logged in user. <strong>Send</strong> will send the email to the recipient "
970
+ "list."
971
+ msgstr ""
972
+
973
+ #: classes/class-s2-admin.php:236
974
+ msgid ""
975
+ "You are about to delete a registered user account, any posts made by this "
976
+ "user will be assigned to you. Are you sure?"
977
+ msgstr ""
978
+
979
+ #: classes/class-s2-admin.php:237
980
+ msgid ""
981
+ "You are about to delete registered user accounts, any posts made by these "
982
+ "users will be assigned to you. Are you sure?"
983
+ msgstr ""
984
+
985
+ #: classes/class-s2-admin.php:238
986
+ msgid "You are about to delete a public subscriber. Are you sure?"
987
+ msgstr ""
988
+
989
+ #: classes/class-s2-admin.php:239
990
+ msgid "You are about to delete public subscribers. Are you sure?"
991
+ msgstr ""
992
+
993
+ #: classes/class-s2-admin.php:240
994
+ msgid ""
995
+ "You are about to make Bulk Management changes to all Registered Users. Are "
996
+ "you sure?"
997
+ msgstr ""
998
+
999
+ #: classes/class-s2-admin.php:241
1000
+ msgid ""
1001
+ "You are about to make Bulk Management changes to the selected Registered "
1002
+ "User. Are you sure?"
1003
+ msgstr ""
1004
+
1005
+ #: classes/class-s2-admin.php:242
1006
+ msgid ""
1007
+ "You are about to make Bulk Management changes to the selected Registered "
1008
+ "Users. Are you sure?"
1009
+ msgstr ""
1010
+
1011
+ #: classes/class-s2-admin.php:260
1012
+ msgid "Donate"
1013
+ msgstr ""
1014
+
1015
+ #: classes/class-s2-admin.php:367
1016
+ msgid "Subscribe2 Notification Override"
1017
+ msgstr ""
1018
+
1019
+ #: classes/class-s2-admin.php:386
1020
+ msgid ""
1021
+ "Check here to disable sending of an email notification for this post/page"
1022
+ msgstr ""
1023
+
1024
+ #: classes/class-s2-admin.php:490
1025
+ msgctxt "Comma Separated Column Header names for CSV Export"
1026
+ msgid "User Email,User Type,User Name,Confirm Date,IP"
1027
+ msgstr ""
1028
+
1029
+ #: classes/class-s2-admin.php:511
1030
+ msgid "Registered User"
1031
+ msgstr ""
1032
+
1033
+ #: classes/class-s2-admin.php:516
1034
+ msgid "Confirmed Public Subscriber"
1035
+ msgstr ""
1036
+
1037
+ #: classes/class-s2-admin.php:518
1038
+ msgid "Unconfirmed Public Subscriber"
1039
+ msgstr ""
1040
+
1041
+ #: classes/class-s2-admin.php:535 classes/class-s2-forms.php:306
1042
+ #: classes/class-s2-forms.php:366
1043
+ msgid "Select / Unselect All"
1044
+ msgstr ""
1045
+
1046
+ #: classes/class-s2-admin.php:572
1047
+ msgid "All Users and Subscribers"
1048
+ msgstr ""
1049
+
1050
+ #: classes/class-s2-admin.php:574
1051
+ msgid "Confirmed"
1052
+ msgstr ""
1053
+
1054
+ #: classes/class-s2-admin.php:575
1055
+ msgid "Unconfirmed"
1056
+ msgstr ""
1057
+
1058
+ #: classes/class-s2-admin.php:576
1059
+ msgid "All Registered Users"
1060
+ msgstr ""
1061
+
1062
+ #: classes/class-s2-admin.php:683
1063
+ msgid "Post Author"
1064
+ msgstr ""
1065
+
1066
+ #: classes/class-s2-admin.php:711
1067
+ msgid ""
1068
+ "The WordPress cron functions may be disabled on this server. Digest "
1069
+ "notifications may not work."
1070
+ msgstr ""
1071
+
1072
+ #: classes/class-s2-admin.php:720
1073
+ msgid "For each Post"
1074
+ msgstr ""
1075
+
1076
+ #: classes/class-s2-admin.php:742
1077
+ msgid "Current UTC time is"
1078
+ msgstr ""
1079
+
1080
+ #: classes/class-s2-admin.php:744
1081
+ msgid "Current blog time is"
1082
+ msgstr ""
1083
+
1084
+ #: classes/class-s2-admin.php:746
1085
+ msgid "Next email notification will be sent when your blog time is after"
1086
+ msgstr ""
1087
+
1088
+ #: classes/class-s2-admin.php:768
1089
+ msgid "Attempt to resend the last Digest Notification email"
1090
+ msgstr ""
1091
+
1092
+ #: classes/class-s2-admin.php:769
1093
+ msgid "Resend Digest"
1094
+ msgstr ""
1095
+
1096
+ #: classes/class-s2-admin.php:1045
1097
+ msgid "Email subscription"
1098
+ msgstr ""
1099
+
1100
+ #: classes/class-s2-admin.php:1047
1101
+ msgid "Subscribe / Unsubscribe"
1102
+ msgstr ""
1103
+
1104
+ #: classes/class-s2-admin.php:1048
1105
+ msgid "Receive notifications"
1106
+ msgstr ""
1107
+
1108
+ #: classes/class-s2-admin.php:1049
1109
+ msgid ""
1110
+ "Check if you want to receive email notification when new posts are published"
1111
+ msgstr ""
1112
+
1113
+ #: classes/class-s2-ajax.php:41
1114
+ msgid "Subscribe to this blog"
1115
+ msgstr ""
1116
+
1117
+ #: classes/class-s2-ajax.php:70
1118
+ msgid "There was an error validating your request. Please try again later."
1119
+ msgstr ""
1120
+
1121
+ #: classes/class-s2-ajax.php:76 classes/class-s2-ajax.php:106
1122
+ #: classes/class-s2-ajax.php:120 classes/class-s2-frontend.php:24
1123
+ msgid "A confirmation message is on its way!"
1124
+ msgstr ""
1125
+
1126
+ #: classes/class-s2-ajax.php:84 classes/class-s2-frontend.php:30
1127
+ msgid "Sorry, but that does not look like an email address to me."
1128
+ msgstr ""
1129
+
1130
+ #: classes/class-s2-ajax.php:86 classes/class-s2-frontend.php:32
1131
+ msgid ""
1132
+ "Sorry, email addresses at that domain are currently barred due to spam, "
1133
+ "please use an alternative email address."
1134
+ msgstr ""
1135
+
1136
+ #: classes/class-s2-ajax.php:92 classes/class-s2-frontend.php:193
1137
+ msgid "Slow down, you move too fast."
1138
+ msgstr ""
1139
+
1140
+ #: classes/class-s2-ajax.php:98 classes/class-s2-frontend.php:8
1141
+ #, php-format
1142
+ msgid "To manage your subscription options please <a href=\"%1$s\">login.</a>"
1143
+ msgstr ""
1144
+
1145
+ #: classes/class-s2-ajax.php:108 classes/class-s2-ajax.php:122
1146
+ #: classes/class-s2-frontend.php:34
1147
+ msgid ""
1148
+ "Sorry, there seems to be an error on the server. Please try again later."
1149
+ msgstr ""
1150
+
1151
+ #: classes/class-s2-ajax.php:112 classes/class-s2-frontend.php:26
1152
+ msgid "That email address is already subscribed."
1153
+ msgstr ""
1154
+
1155
+ #: classes/class-s2-ajax.php:116 classes/class-s2-frontend.php:28
1156
+ msgid "That email address is not subscribed."
1157
+ msgstr ""
1158
+
1159
+ #: classes/class-s2-core.php:552
1160
+ msgid "Plain Text Excerpt Preview"
1161
+ msgstr ""
1162
+
1163
+ #: classes/class-s2-core.php:554
1164
+ msgid "Plain Text Full Preview"
1165
+ msgstr ""
1166
+
1167
+ #: classes/class-s2-core.php:556
1168
+ msgid "HTML Excerpt Preview"
1169
+ msgstr ""
1170
+
1171
+ #: classes/class-s2-core.php:558
1172
+ msgid "HTML Full Preview"
1173
+ msgstr ""
1174
+
1175
+ #: classes/class-s2-core.php:1205
1176
+ msgid "Check here to Subscribe to email notifications for new posts"
1177
+ msgstr ""
1178
+
1179
+ #: classes/class-s2-core.php:1210
1180
+ msgid ""
1181
+ "By registering with this blog you are also agreeing to receive email "
1182
+ "notifications for new posts but you can unsubscribe at anytime"
1183
+ msgstr ""
1184
+
1185
+ #: classes/class-s2-core.php:1238
1186
+ msgid "Check here to Subscribe to notifications for new posts"
1187
+ msgstr ""
1188
+
1189
+ #: classes/class-s2-core.php:1357
1190
+ msgid "Weekly"
1191
+ msgstr ""
1192
+
1193
+ #: classes/class-s2-core.php:1570 classes/class-s2-core.php:1571
1194
+ msgid "Author"
1195
+ msgstr ""
1196
+
1197
+ #: classes/class-s2-core.php:1577
1198
+ msgid "Posted on"
1199
+ msgstr ""
1200
+
1201
+ #: classes/class-s2-core.php:1601 classes/class-s2-core.php:1602
1202
+ msgid "Posted in"
1203
+ msgstr ""
1204
+
1205
+ #: classes/class-s2-core.php:1613 classes/class-s2-core.php:1614
1206
+ msgid "Tagged as"
1207
+ msgstr ""
1208
+
1209
+ #: classes/class-s2-core.php:1692
1210
+ msgid "Digest Email"
1211
+ msgstr ""
1212
+
1213
+ #: classes/class-s2-core.php:1705
1214
+ msgid "Digest Preview"
1215
+ msgstr ""
1216
+
1217
+ #: classes/class-s2-counter-widget.php:9
1218
+ msgid "Subscriber Counter widget for Subscribe2"
1219
+ msgstr ""
1220
+
1221
+ #: classes/class-s2-counter-widget.php:17
1222
+ msgid "Subscribe2 Counter"
1223
+ msgstr ""
1224
+
1225
+ #: classes/class-s2-counter-widget.php:95
1226
+ msgid "Widget Title"
1227
+ msgstr ""
1228
+
1229
+ #: classes/class-s2-counter-widget.php:100
1230
+ msgid "Color Scheme"
1231
+ msgstr ""
1232
+
1233
+ #: classes/class-s2-counter-widget.php:102
1234
+ msgid "Body"
1235
+ msgstr ""
1236
+
1237
+ #: classes/class-s2-counter-widget.php:104
1238
+ msgid "Text"
1239
+ msgstr ""
1240
+
1241
+ #: classes/class-s2-counter-widget.php:109
1242
+ msgid "Width, Height and Font Size"
1243
+ msgstr ""
1244
+
1245
+ #: classes/class-s2-counter-widget.php:111
1246
+ msgid "Width"
1247
+ msgstr ""
1248
+
1249
+ #: classes/class-s2-counter-widget.php:113
1250
+ msgid "Height"
1251
+ msgstr ""
1252
+
1253
+ #: classes/class-s2-counter-widget.php:115
1254
+ msgid "Font"
1255
+ msgstr ""
1256
+
1257
+ #: classes/class-s2-form-widget.php:9
1258
+ msgid "Sidebar Widget for Subscribe2"
1259
+ msgstr ""
1260
+
1261
+ #: classes/class-s2-form-widget.php:17
1262
+ msgid "Subscribe2 Widget"
1263
+ msgstr ""
1264
+
1265
+ #: classes/class-s2-form-widget.php:38
1266
+ msgid "(Un)Subscribe to Posts"
1267
+ msgstr ""
1268
+
1269
+ #: classes/class-s2-form-widget.php:144
1270
+ msgid "Title"
1271
+ msgstr ""
1272
+
1273
+ #: classes/class-s2-form-widget.php:146
1274
+ msgid "Div class name"
1275
+ msgstr ""
1276
+
1277
+ #: classes/class-s2-form-widget.php:148
1278
+ msgid "Pre-Content"
1279
+ msgstr ""
1280
+
1281
+ #: classes/class-s2-form-widget.php:150
1282
+ msgid "Post-Content"
1283
+ msgstr ""
1284
+
1285
+ #: classes/class-s2-form-widget.php:152
1286
+ msgid "Text Box Size"
1287
+ msgstr ""
1288
+
1289
+ #: classes/class-s2-form-widget.php:154
1290
+ msgid "Display options"
1291
+ msgstr ""
1292
+
1293
+ #: classes/class-s2-form-widget.php:155
1294
+ msgid "Show complete form"
1295
+ msgstr ""
1296
+
1297
+ #: classes/class-s2-form-widget.php:156
1298
+ msgid "Hide Subscribe button"
1299
+ msgstr ""
1300
+
1301
+ #: classes/class-s2-form-widget.php:157
1302
+ msgid "Hide Unsubscribe button"
1303
+ msgstr ""
1304
+
1305
+ #: classes/class-s2-form-widget.php:159
1306
+ msgid "Show as link"
1307
+ msgstr ""
1308
+
1309
+ #: classes/class-s2-form-widget.php:162
1310
+ msgid "Post form content to page"
1311
+ msgstr ""
1312
+
1313
+ #: classes/class-s2-form-widget.php:164
1314
+ msgid "Use Subscribe2 Default"
1315
+ msgstr ""
1316
+
1317
+ #: classes/class-s2-form-widget.php:169
1318
+ msgid "Use Home Page"
1319
+ msgstr ""
1320
+
1321
+ #: classes/class-s2-form-widget.php:174
1322
+ msgid "Use Referring Page"
1323
+ msgstr ""
1324
+
1325
+ #: classes/class-s2-form-widget.php:177
1326
+ msgid "Disable JavaScript"
1327
+ msgstr ""
1328
+
1329
+ #: classes/class-s2-form-widget.php:180
1330
+ msgid "Disable Anti-spam measures"
1331
+ msgstr ""
1332
+
1333
+ #: classes/class-s2-form-widget.php:183
1334
+ msgid "Disable wrapping of form buttons"
1335
+ msgstr ""
1336
+
1337
+ #: classes/class-s2-forms.php:17 classes/class-s2-forms.php:21
1338
+ msgid "Permission error! Your request cannot be completed."
1339
+ msgstr ""
1340
+
1341
+ #: classes/class-s2-forms.php:46
1342
+ msgid "Receive email as"
1343
+ msgstr ""
1344
+
1345
+ #: classes/class-s2-forms.php:57
1346
+ msgid "Automatically subscribe me to newly created categories"
1347
+ msgstr ""
1348
+
1349
+ #: classes/class-s2-forms.php:67
1350
+ msgid "One Click Subscription / Unsubscription"
1351
+ msgstr ""
1352
+
1353
+ #: classes/class-s2-forms.php:68
1354
+ msgid "Subscribe to All"
1355
+ msgstr ""
1356
+
1357
+ #: classes/class-s2-forms.php:69
1358
+ msgid "Unsubscribe from All"
1359
+ msgstr ""
1360
+
1361
+ #: classes/class-s2-forms.php:79
1362
+ msgid "Unsubscribe me from this blog"
1363
+ msgstr ""
1364
+
1365
+ #: classes/class-s2-forms.php:83
1366
+ msgid "Subscribe to all categories"
1367
+ msgstr ""
1368
+
1369
+ #: classes/class-s2-forms.php:85
1370
+ msgid "Subscribed Categories on"
1371
+ msgstr ""
1372
+
1373
+ #: classes/class-s2-forms.php:87
1374
+ msgid "Subscribed Categories"
1375
+ msgstr ""
1376
+
1377
+ #: classes/class-s2-forms.php:94
1378
+ msgid "Receive periodic summaries of new posts?"
1379
+ msgstr ""
1380
+
1381
+ #: classes/class-s2-forms.php:110
1382
+ msgid "Do not send notifications for post made by these authors"
1383
+ msgstr ""
1384
+
1385
+ #: classes/class-s2-forms.php:163
1386
+ msgid "Subscribed Blogs"
1387
+ msgstr ""
1388
+
1389
+ #: classes/class-s2-forms.php:168 classes/class-s2-forms.php:189
1390
+ msgid "Viewing Settings Now"
1391
+ msgstr ""
1392
+
1393
+ #: classes/class-s2-forms.php:172 classes/class-s2-forms.php:193
1394
+ msgid "View Settings"
1395
+ msgstr ""
1396
+
1397
+ #: classes/class-s2-forms.php:184
1398
+ msgid "Subscribe to new blogs"
1399
+ msgstr ""
1400
+
1401
+ #: classes/class-s2-forms.php:285
1402
+ msgid "Subscription preferences updated."
1403
+ msgstr ""
1404
+
1405
+ #: classes/class-s2-frontend.php:12
1406
+ #, php-format
1407
+ msgid ""
1408
+ "You may manage your subscription options from your <a href=\"%1$s\">profile</"
1409
+ "a>"
1410
+ msgstr ""
1411
+
1412
+ #: classes/class-s2-frontend.php:20
1413
+ #, php-format
1414
+ msgid ""
1415
+ "<a href=\"%1$s\">Subscribe</a> to email notifications when this blog posts "
1416
+ "new content."
1417
+ msgstr ""
1418
+
1419
+ #: classes/class-s2-frontend.php:37
1420
+ msgid "No such email address is registered."
1421
+ msgstr ""
1422
+
1423
+ #: classes/class-s2-frontend.php:39
1424
+ msgid "You have successfully subscribed!"
1425
+ msgstr ""
1426
+
1427
+ #: classes/class-s2-frontend.php:41
1428
+ msgid "You have successfully unsubscribed."
1429
+ msgstr ""
1430
+
1431
+ #: classes/class-s2-frontend.php:43
1432
+ msgid "subscribe"
1433
+ msgstr ""
1434
+
1435
+ #: classes/class-s2-frontend.php:45
1436
+ msgid "unsubscribe"
1437
+ msgstr ""
1438
+
1439
+ #: classes/class-s2-frontend.php:124
1440
+ msgid "Enter email address..."
1441
+ msgstr ""
1442
+
1443
+ #: classes/class-s2-frontend.php:155 classes/class-s2-frontend.php:157
1444
+ msgid "Your email:"
1445
+ msgstr ""
1446
+
1447
+ #: classes/class-s2-frontend.php:301
1448
+ msgid "Subscription Confirmation"
1449
+ msgstr ""
1450
+
1451
+ #: classes/class-s2-frontend.php:303
1452
+ msgid "Unsubscription Confirmation"
1453
+ msgstr ""
1454
+
1455
+ #: classes/class-s2-frontend.php:376
1456
+ msgid "New Subscription"
1457
+ msgstr ""
1458
+
1459
+ #: classes/class-s2-frontend.php:377
1460
+ msgid "subscribed to email notifications!"
1461
+ msgstr ""
1462
+
1463
+ #: classes/class-s2-frontend.php:379
1464
+ msgid "New Unsubscription"
1465
+ msgstr ""
1466
+
1467
+ #: classes/class-s2-frontend.php:380
1468
+ msgid "unsubscribed from email notifications!"
1469
+ msgstr ""
1470
+
1471
+ #: classes/class-s2-frontend.php:409
1472
+ msgid "[Un]Subscribe to Posts"
1473
+ msgstr ""
1474
+
1475
+ #: classes/class-s2-list-table-legacy.php:75
1476
+ #: classes/class-s2-list-table-legacy.php:80 classes/class-s2-list-table.php:75
1477
+ #: classes/class-s2-list-table.php:80
1478
+ msgctxt "column name"
1479
+ msgid "Email"
1480
+ msgstr ""
1481
+
1482
+ #: classes/class-s2-list-table-legacy.php:81 classes/class-s2-list-table.php:81
1483
+ msgctxt "column name"
1484
+ msgid "Date"
1485
+ msgstr ""
1486
+
1487
+ #: classes/class-s2-list-table-legacy.php:131
1488
+ #: classes/class-s2-list-table.php:131
1489
+ msgid "Select All"
1490
+ msgstr ""
1491
+
1492
+ #: classes/class-s2-list-table-legacy.php:183
1493
+ #: classes/class-s2-list-table-legacy.php:188
1494
+ #: classes/class-s2-list-table.php:186 classes/class-s2-list-table.php:191
1495
+ msgid "Delete"
1496
+ msgstr ""
1497
+
1498
+ #: classes/class-s2-list-table-legacy.php:189
1499
+ #: classes/class-s2-list-table.php:192
1500
+ msgid "Toggle"
1501
+ msgstr ""
1502
+
1503
+ #: classes/class-s2-list-table-legacy.php:198
1504
+ #: classes/class-s2-list-table.php:201
1505
+ msgid "No users were selected."
1506
+ msgstr ""
1507
+
1508
+ #: classes/class-s2-list-table-legacy.php:211
1509
+ #: classes/class-s2-list-table.php:214
1510
+ msgid "Address(es) deleted!"
1511
+ msgstr ""
1512
+
1513
+ #: classes/class-s2-list-table-legacy.php:215
1514
+ #: classes/class-s2-list-table.php:218
1515
+ msgid "Delete failed! You cannot delete some or all of these users."
1516
+ msgstr ""
1517
+
1518
+ #: classes/class-s2-list-table-legacy.php:218
1519
+ #: classes/class-s2-list-table.php:221
1520
+ msgid ""
1521
+ "Registered user(s) deleted! Any posts made by these users were assigned to "
1522
+ "you."
1523
+ msgstr ""
1524
+
1525
+ #: classes/class-s2-list-table-legacy.php:242
1526
+ #: classes/class-s2-list-table.php:245
1527
+ msgid "Status changed!"
1528
+ msgstr ""
1529
+
1530
+ #: classes/class-s2-list-table-legacy.php:259
1531
+ #: classes/class-s2-list-table.php:266
1532
+ #, php-format
1533
+ msgid "%s item"
1534
+ msgid_plural "%s items"
1535
+ msgstr[0] ""
1536
+ msgstr[1] ""
1537
+
1538
+ #: classes/class-s2-list-table-legacy.php:307
1539
+ msgid "Go to the first page"
1540
+ msgstr ""
1541
+
1542
+ #: classes/class-s2-list-table-legacy.php:315
1543
+ msgid "Go to the previous page"
1544
+ msgstr ""
1545
+
1546
+ #: classes/class-s2-list-table-legacy.php:325
1547
+ msgid "Current page"
1548
+ msgstr ""
1549
+
1550
+ #: classes/class-s2-list-table-legacy.php:333
1551
+ #: classes/class-s2-list-table.php:357
1552
+ #, php-format
1553
+ msgctxt "paging"
1554
+ msgid "%1$s of %2$s"
1555
+ msgstr ""
1556
+
1557
+ #: classes/class-s2-list-table-legacy.php:338
1558
+ msgid "Go to the next page"
1559
+ msgstr ""
1560
+
1561
+ #: classes/class-s2-list-table-legacy.php:346
1562
+ msgid "Go to the last page"
1563
+ msgstr ""
1564
+
1565
+ #: classes/class-s2-list-table.php:327
1566
+ msgid "First page"
1567
+ msgstr ""
1568
+
1569
+ #: classes/class-s2-list-table.php:338
1570
+ msgid "Previous page"
1571
+ msgstr ""
1572
+
1573
+ #: classes/class-s2-list-table.php:345 classes/class-s2-list-table.php:349
1574
+ msgid "Current Page"
1575
+ msgstr ""
1576
+
1577
+ #: classes/class-s2-list-table.php:365
1578
+ msgid "Next page"
1579
+ msgstr ""
1580
+
1581
+ #: classes/class-s2-list-table.php:376
1582
+ msgid "Last page"
1583
+ msgstr ""
1584
+
1585
+ #: classes/mo-notice.php:60
1586
+ #, php-format
1587
+ msgid ""
1588
+ "Free optin form plugin that will %1$sincrease your email list subscribers"
1589
+ "%2$s and keep them engaged with %1$sautomated and schedule newsletters%2$s."
1590
+ msgstr ""
1591
+
1592
+ #: classes/mo-notice.php:69
1593
+ msgid "Install MailOptin Now for Free!"
1594
+ msgstr ""
1595
+
1596
+ #: classes/mo-notice.php:74
1597
+ msgid "Activate MailOptin Now!"
1598
+ msgstr ""
1599
+
1600
+ #: classes/mo-notice.php:83
1601
+ msgid "Dismiss this notice"
1602
+ msgstr ""
1603
+
1604
+ #: include/options.php:140
1605
+ msgid ""
1606
+ "{BLOGNAME} has posted a new item, '{TITLE}'\n"
1607
+ "\n"
1608
+ "{POST}\n"
1609
+ "\n"
1610
+ "You may view the latest post at\n"
1611
+ "{PERMALINK}\n"
1612
+ "\n"
1613
+ "You received this e-mail because you asked to be notified when new updates "
1614
+ "are posted.\n"
1615
+ "Best regards,\n"
1616
+ "{MYNAME}\n"
1617
+ "{EMAIL}"
1618
+ msgstr ""
1619
+
1620
+ #: include/options.php:148
1621
+ msgid ""
1622
+ "{BLOGNAME} has received a request to {ACTION} for this email address. To "
1623
+ "complete your request please click on the link below:\\n\\n{LINK}\\n\\nIf "
1624
+ "you did not request this, please feel free to disregard this notice!\\n"
1625
+ "\\nThank you,\\n{MYNAME}."
1626
+ msgstr ""
1627
+
1628
+ #: include/options.php:152
1629
+ msgid "Please confirm your request"
1630
+ msgstr ""
1631
+
1632
+ #: include/options.php:156
1633
+ msgid ""
1634
+ "This email address was subscribed for notifications at {BLOGNAME} "
1635
+ "({BLOGLINK}) but the subscription remains incomplete.\\n\\nIf you wish to "
1636
+ "complete your subscription please click on the link below:\\n\\n{LINK}\\n"
1637
+ "\\nIf you do not wish to complete your subscription please ignore this email "
1638
+ "and your address will be removed from our database.\\n\\nRegards,\\n{MYNAME}"
1639
+ msgstr ""
1640
+
1641
+ #: include/options.php:160
1642
+ msgid "Subscription Reminder"
1643
+ msgstr ""
1644
+
1645
+ #: subscribe2.php:36
1646
+ msgid "I'm just a plugin, please don't call me directly"
1647
+ msgstr ""
1648
+
1649
+ #: subscribe2.php:39
1650
+ #, php-format
1651
+ msgid ""
1652
+ "This version of Subscribe2 requires WordPress 3.3 or greater. Please update "
1653
+ "%1$s or use an older version of %2$s."
1654
+ msgstr ""
1655
+
1656
+ #: subscribe2.php:51
1657
+ msgid ""
1658
+ "Subscribe2 HTML cannot be activated as a network plugin. Please activate it "
1659
+ "on a site level"
1660
+ msgstr ""
1661
+
1662
+ #. Plugin URI of the plugin/theme
1663
+ #. Author URI of the plugin/theme
1664
+ msgid "https://subscribe2.wordpress.com/"
1665
+ msgstr ""
1666
+
1667
+ #. Description of the plugin/theme
1668
+ msgid "Notifies an email list when new entries are posted."
1669
+ msgstr ""
tinymce/css/content.css CHANGED
@@ -1,9 +1,12 @@
1
- .mceSubscribe2 {
2
- display:block;
3
- width:100%;
4
- height:12px;
5
- margin-top:15px;
6
- border:0;
7
- border-top:1px;
8
- background:url(../../include/s2-marker.png) center top no-repeat #fff;
9
- }
 
 
 
1
+ .mceSubscribe2
2
+ {
3
+ display: block;
4
+
5
+ width: 100%;
6
+ height: 12px;
7
+ margin-top: 15px;
8
+
9
+ border: 0;
10
+ border-top: 1px;
11
+ background: url(../../include/s2-marker.png) center top no-repeat #fff;
12
+ }
tinymce/css/content.min.css DELETED
@@ -1 +0,0 @@
1
- .mceSubscribe2{display:block;width:100%;height:12px;margin-top:15px;border:0;border-top:1px;background:url(../../include/s2-marker.png) center top no-repeat #fff;}
 
tinymce/editor-plugin3.js CHANGED
@@ -1,14 +1,15 @@
1
  /* global tinymce */
2
- (function () {
 
3
  tinymce.create( 'tinymce.plugins.Subscribe2Plugin', {
4
- init : function ( ed, url ) {
5
  var i = 0,
6
  pb = '<img src="' + url + '/../include/spacer.gif" class="mceSubscribe2 mceItemNoResize" />',
7
  cls = 'mceSubscribe2',
8
  shortcode = '[subscribe2]',
9
  pbreplaced = [],
10
  pbRE = new RegExp( /(\[|<!--)subscribe2.*?(\]|-->)/g ),
11
- replacer = function ( str ) {
12
  if ( -1 !== str.indexOf( 'class="mceSubscribe2' ) ) {
13
  str = pbreplaced[i];
14
  }
@@ -16,79 +17,79 @@
16
  };
17
 
18
  // Register commands
19
- ed.addCommand( 'mceSubscribe2', function () {
20
  ed.execCommand( 'mceInsertContent', 0, pb );
21
- });
22
 
23
  // Register buttons
24
  ed.addButton( 'subscribe2', {
25
- title : 'Insert Subscribe2 Token',
26
- image : url + '/../include/s2-button.png',
27
- cmd : cls
28
- });
29
 
30
  // load the CSS and enable it on the right class
31
- ed.onInit.add(function () {
32
- ed.dom.loadCSS( url + '/css/content.min.css' );
33
  if ( ed.theme.onResolveName ) {
34
- ed.theme.onResolveName.add(function ( th, o ) {
35
- if ( o.node.nodeName === 'IMG' && ed.dom.hasClass( o.node, cls ) ) {
36
  o.name = 'subscribe2';
37
  }
38
- });
39
  }
40
- });
41
 
42
  // allow selection of the image placeholder
43
- ed.onClick.add(function ( ed, e ) {
44
  e = e.target;
45
- if ( e.nodeName === 'IMG' && ed.dom.hasClass( e, cls ) ) {
46
  ed.selection.select( e );
47
  }
48
- });
49
 
50
  // re-enable the CSS when the node changes
51
- ed.onNodeChange.add(function ( ed, cm, n ) {
52
- cm.setActive( 'subscribe2', n.nodeName === 'IMG' && ed.dom.hasClass( n, cls ) );
53
- });
54
 
55
  // create an array of replaced shortcodes so we have additional parameters
56
  // then swap in the graphic
57
- ed.onBeforeSetContent.add(function ( ed, o ) {
58
  pbreplaced = o.content.match( pbRE );
59
  o.content = o.content.replace( pbRE, pb );
60
- });
61
 
62
  // swap back the array of shortcodes to preserve parameters
63
  // replace any other instances with the default shortcode
64
- ed.onPostProcess.add(function ( ed, o ) {
65
  if ( o.get ) {
66
  if ( null !== pbreplaced ) {
67
  for ( i = 0; i < pbreplaced.length; i++ ) {
68
  o.content = o.content.replace( /<img[^>]+>/, replacer );
69
  }
70
  }
71
- o.content = o.content.replace( /<img[^>]+>/g, function ( im ) {
72
  if ( -1 !== im.indexOf( 'class="mceSubscribe2' ) ) {
73
  im = shortcode;
74
  }
75
  return im;
76
- });
77
  }
78
- });
79
  },
80
 
81
- getInfo : function () {
82
  return {
83
- longname : 'Insert Subscribe2 Token',
84
- author : 'Matthew Robinson',
85
- authorurl : 'http://subscribe2.wordpress.com',
86
- infourl : 'http://subscribe2.wordpress.com',
87
- version : tinymce.majorVersion + '.' + tinymce.minorVersion
88
  };
89
  }
90
- });
91
 
92
  // Register plugin
93
  tinymce.PluginManager.add( 'subscribe2', tinymce.plugins.Subscribe2Plugin );
94
- })();
1
  /* global tinymce */
2
+
3
+ ( function() {
4
  tinymce.create( 'tinymce.plugins.Subscribe2Plugin', {
5
+ init: function( ed, url ) {
6
  var i = 0,
7
  pb = '<img src="' + url + '/../include/spacer.gif" class="mceSubscribe2 mceItemNoResize" />',
8
  cls = 'mceSubscribe2',
9
  shortcode = '[subscribe2]',
10
  pbreplaced = [],
11
  pbRE = new RegExp( /(\[|<!--)subscribe2.*?(\]|-->)/g ),
12
+ replacer = function( str ) {
13
  if ( -1 !== str.indexOf( 'class="mceSubscribe2' ) ) {
14
  str = pbreplaced[i];
15
  }
17
  };
18
 
19
  // Register commands
20
+ ed.addCommand( 'mceSubscribe2', function() {
21
  ed.execCommand( 'mceInsertContent', 0, pb );
22
+ } );
23
 
24
  // Register buttons
25
  ed.addButton( 'subscribe2', {
26
+ title: 'Insert Subscribe2 Token',
27
+ image: url + '/../include/s2-button.png',
28
+ cmd: cls
29
+ } );
30
 
31
  // load the CSS and enable it on the right class
32
+ ed.onInit.add( function() {
33
+ ed.dom.loadCSS( url + '/css/content.css' );
34
  if ( ed.theme.onResolveName ) {
35
+ ed.theme.onResolveName.add( function( th, o ) {
36
+ if ( 'IMG' === o.node.nodeName && ed.dom.hasClass( o.node, cls ) ) {
37
  o.name = 'subscribe2';
38
  }
39
+ } );
40
  }
41
+ } );
42
 
43
  // allow selection of the image placeholder
44
+ ed.onClick.add( function( ed, e ) {
45
  e = e.target;
46
+ if ( 'IMG' === e.nodeName && ed.dom.hasClass( e, cls ) ) {
47
  ed.selection.select( e );
48
  }
49
+ } );
50
 
51
  // re-enable the CSS when the node changes
52
+ ed.onNodeChange.add( function( ed, cm, n ) {
53
+ cm.setActive( 'subscribe2', 'IMG' === n.nodeName && ed.dom.hasClass( n, cls ) );
54
+ } );
55
 
56
  // create an array of replaced shortcodes so we have additional parameters
57
  // then swap in the graphic
58
+ ed.onBeforeSetContent.add( function( ed, o ) {
59
  pbreplaced = o.content.match( pbRE );
60
  o.content = o.content.replace( pbRE, pb );
61
+ } );
62
 
63
  // swap back the array of shortcodes to preserve parameters
64
  // replace any other instances with the default shortcode
65
+ ed.onPostProcess.add( function( ed, o ) {
66
  if ( o.get ) {
67
  if ( null !== pbreplaced ) {
68
  for ( i = 0; i < pbreplaced.length; i++ ) {
69
  o.content = o.content.replace( /<img[^>]+>/, replacer );
70
  }
71
  }
72
+ o.content = o.content.replace( /<img[^>]+>/g, function( im ) {
73
  if ( -1 !== im.indexOf( 'class="mceSubscribe2' ) ) {
74
  im = shortcode;
75
  }
76
  return im;
77
+ } );
78
  }
79
+ } );
80
  },
81
 
82
+ getInfo: function() {
83
  return {
84
+ longname: 'Insert Subscribe2 Token',
85
+ author: 'Matthew Robinson',
86
+ authorurl: 'http://subscribe2.wordpress.com',
87
+ infourl: 'http://subscribe2.wordpress.com',
88
+ version: tinymce.majorVersion + '.' + tinymce.minorVersion
89
  };
90
  }
91
+ } );
92
 
93
  // Register plugin
94
  tinymce.PluginManager.add( 'subscribe2', tinymce.plugins.Subscribe2Plugin );
95
+ } () );
tinymce/editor-plugin3.min.js CHANGED
@@ -1 +1 @@
1
- !function(){tinymce.create("tinymce.plugins.Subscribe2Plugin",{init:function(a,b){var c=0,d='<img src="'+b+'/../include/spacer.gif" class="mceSubscribe2 mceItemNoResize" />',e="mceSubscribe2",f="[subscribe2]",g=[],h=new RegExp(/(\[|<!--)subscribe2.*?(\]|-->)/g),i=function(a){return-1!==a.indexOf('class="mceSubscribe2')&&(a=g[c]),a};a.addCommand("mceSubscribe2",function(){a.execCommand("mceInsertContent",0,d)}),a.addButton("subscribe2",{title:"Insert Subscribe2 Token",image:b+"/../include/s2-button.png",cmd:e}),a.onInit.add(function(){a.dom.loadCSS(b+"/css/content.min.css"),a.theme.onResolveName&&a.theme.onResolveName.add(function(b,c){"IMG"===c.node.nodeName&&a.dom.hasClass(c.node,e)&&(c.name="subscribe2")})}),a.onClick.add(function(a,b){b=b.target,"IMG"===b.nodeName&&a.dom.hasClass(b,e)&&a.selection.select(b)}),a.onNodeChange.add(function(a,b,c){b.setActive("subscribe2","IMG"===c.nodeName&&a.dom.hasClass(c,e))}),a.onBeforeSetContent.add(function(a,b){g=b.content.match(h),b.content=b.content.replace(h,d)}),a.onPostProcess.add(function(a,b){if(b.get){if(null!==g)for(c=0;c<g.length;c++)b.content=b.content.replace(/<img[^>]+>/,i);b.content=b.content.replace(/<img[^>]+>/g,function(a){return-1!==a.indexOf('class="mceSubscribe2')&&(a=f),a})}})},getInfo:function(){return{longname:"Insert Subscribe2 Token",author:"Matthew Robinson",authorurl:"http://subscribe2.wordpress.com",infourl:"http://subscribe2.wordpress.com",version:tinymce.majorVersion+"."+tinymce.minorVersion}}}),tinymce.PluginManager.add("subscribe2",tinymce.plugins.Subscribe2Plugin)}();
1
+ tinymce.create("tinymce.plugins.Subscribe2Plugin",{init:function(e,n){var t=0,c='<img src="'+n+'/../include/spacer.gif" class="mceSubscribe2 mceItemNoResize" />',o="mceSubscribe2",s=[],i=new RegExp(/(\[|<!--)subscribe2.*?(\]|-->)/g),r=function(e){return-1!==e.indexOf('class="mceSubscribe2')&&(e=s[t]),e};e.addCommand("mceSubscribe2",function(){e.execCommand("mceInsertContent",0,c)}),e.addButton("subscribe2",{title:"Insert Subscribe2 Token",image:n+"/../include/s2-button.png",cmd:o}),e.onInit.add(function(){e.dom.loadCSS(n+"/css/content.css"),e.theme.onResolveName&&e.theme.onResolveName.add(function(n,t){"IMG"===t.node.nodeName&&e.dom.hasClass(t.node,o)&&(t.name="subscribe2")})}),e.onClick.add(function(e,n){"IMG"===(n=n.target).nodeName&&e.dom.hasClass(n,o)&&e.selection.select(n)}),e.onNodeChange.add(function(e,n,t){n.setActive("subscribe2","IMG"===t.nodeName&&e.dom.hasClass(t,o))}),e.onBeforeSetContent.add(function(e,n){s=n.content.match(i),n.content=n.content.replace(i,c)}),e.onPostProcess.add(function(e,n){if(n.get){if(null!==s)for(t=0;t<s.length;t++)n.content=n.content.replace(/<img[^>]+>/,r);n.content=n.content.replace(/<img[^>]+>/g,function(e){return-1!==e.indexOf('class="mceSubscribe2')&&(e="[subscribe2]"),e})}})},getInfo:function(){return{longname:"Insert Subscribe2 Token",author:"Matthew Robinson",authorurl:"http://subscribe2.wordpress.com",infourl:"http://subscribe2.wordpress.com",version:tinymce.majorVersion+"."+tinymce.minorVersion}}}),tinymce.PluginManager.add("subscribe2",tinymce.plugins.Subscribe2Plugin);
tinymce/editor-plugin4.js CHANGED
@@ -1,14 +1,15 @@
1
  /* global tinymce */
2
- (function () {
 
3
  tinymce.create( 'tinymce.plugins.Subscribe2Plugin', {
4
- init : function ( ed, url ) {
5
  var i = 0,
6
  pb = '<p><img src="' + url + '/../include/spacer.gif" class="mceSubscribe2 mceItemNoResize" /></p>',
7
  cls = 'mceSubscribe2',
8
  shortcode = '[subscribe2]',
9
  pbreplaced = [],
10
  pbRE = new RegExp( /(\[|<!--)subscribe2.*?(\]|-->)/g ),
11
- replacer = function ( str ) {
12
  if ( -1 !== str.indexOf( 'class="mceSubscribe2' ) ) {
13
  str = pbreplaced[i];
14
  }
@@ -16,67 +17,67 @@
16
  };
17
 
18
  // Register commands
19
- ed.addCommand( 'mceSubscribe2', function () {
20
  ed.execCommand( 'mceInsertContent', 0, pb );
21
- });
22
 
23
  // Register buttons
24
  ed.addButton( 'subscribe2', {
25
- title : 'Insert Subscribe2 Token',
26
- image : url + '/../include/s2-button.png',
27
- cmd : cls
28
- });
29
 
30
  // load the CSS and enable it on the right class
31
- ed.on('init', function () {
32
- ed.dom.loadCSS( url + '/css/content.min.css' );
33
 
34
  if ( ed.theme.onResolveName ) {
35
- ed.theme.onResolveName.add(function ( th, o ) {
36
- if ( o.node.nodeName === 'IMG' && ed.dom.hasClass( o.node, cls ) ) {
37
  o.name = 'subscribe2';
38
  }
39
- });
40
  }
41
- });
42
 
43
  // create an array of replaced shortcodes so we have additional parameters
44
  // then swap in the graphic
45
- ed.on('BeforeSetContent', function ( ed ) {
46
  pbreplaced = ed.content.match( pbRE );
47
  ed.content = ed.content.replace( pbRE, pb );
48
- });
49
 
50
  // swap back the array of shortcodes to preserve parameters
51
  // replace any other instances with the default shortcode
52
- ed.on('PostProcess', function ( ed ) {
53
  if ( ed.get ) {
54
  if ( null !== pbreplaced ) {
55
  for ( i = 0; i < pbreplaced.length; i++ ) {
56
  ed.content = ed.content.replace( /<img[^>]+>/, replacer );
57
  }
58
  }
59
- ed.content = ed.content.replace( /<img[^>]+>/g, function ( im ) {
60
  if ( -1 !== im.indexOf( 'class="mceSubscribe2' ) ) {
61
  im = shortcode;
62
  }
63
  return im;
64
- });
65
  }
66
- });
67
  },
68
 
69
- getInfo : function () {
70
  return {
71
- longname : 'Insert Subscribe2 Token',
72
- author : 'Matthew Robinson',
73
- authorurl : 'http://subscribe2.wordpress.com',
74
- infourl : 'http://subscribe2.wordpress.com',
75
- version : tinymce.majorVersion + '.' + tinymce.minorVersion
76
  };
77
  }
78
- });
79
 
80
  // Register plugin
81
  tinymce.PluginManager.add( 'subscribe2', tinymce.plugins.Subscribe2Plugin );
82
- })();
1
  /* global tinymce */
2
+
3
+ ( function() {
4
  tinymce.create( 'tinymce.plugins.Subscribe2Plugin', {
5
+ init: function( ed, url ) {
6
  var i = 0,
7
  pb = '<p><img src="' + url + '/../include/spacer.gif" class="mceSubscribe2 mceItemNoResize" /></p>',
8
  cls = 'mceSubscribe2',
9
  shortcode = '[subscribe2]',
10
  pbreplaced = [],
11
  pbRE = new RegExp( /(\[|<!--)subscribe2.*?(\]|-->)/g ),
12
+ replacer = function( str ) {
13
  if ( -1 !== str.indexOf( 'class="mceSubscribe2' ) ) {
14
  str = pbreplaced[i];
15
  }
17
  };
18
 
19
  // Register commands
20
+ ed.addCommand( 'mceSubscribe2', function() {
21
  ed.execCommand( 'mceInsertContent', 0, pb );
22
+ } );
23
 
24
  // Register buttons
25
  ed.addButton( 'subscribe2', {
26
+ title: 'Insert Subscribe2 Token',
27
+ image: url + '/../include/s2-button.png',
28
+ cmd: cls
29
+ } );
30
 
31
  // load the CSS and enable it on the right class
32
+ ed.on( 'init', function() {
33
+ ed.dom.loadCSS( url + '/css/content.css' );
34
 
35
  if ( ed.theme.onResolveName ) {
36
+ ed.theme.onResolveName.add( function( th, o ) {
37
+ if ( 'IMG' === o.node.nodeName && ed.dom.hasClass( o.node, cls ) ) {
38
  o.name = 'subscribe2';
39
  }
40
+ } );
41
  }
42
+ } );
43
 
44
  // create an array of replaced shortcodes so we have additional parameters
45
  // then swap in the graphic
46
+ ed.on( 'BeforeSetContent', function( ed ) {
47
  pbreplaced = ed.content.match( pbRE );
48
  ed.content = ed.content.replace( pbRE, pb );
49
+ } );
50
 
51
  // swap back the array of shortcodes to preserve parameters
52
  // replace any other instances with the default shortcode
53
+ ed.on( 'PostProcess', function( ed ) {
54
  if ( ed.get ) {
55
  if ( null !== pbreplaced ) {
56
  for ( i = 0; i < pbreplaced.length; i++ ) {
57
  ed.content = ed.content.replace( /<img[^>]+>/, replacer );
58
  }
59
  }
60
+ ed.content = ed.content.replace( /<img[^>]+>/g, function( im ) {
61
  if ( -1 !== im.indexOf( 'class="mceSubscribe2' ) ) {
62
  im = shortcode;
63
  }
64
  return im;
65
+ } );
66
  }
67
+ } );
68
  },
69
 
70
+ getInfo: function() {
71
  return {
72
+ longname: 'Insert Subscribe2 Token',
73
+ author: 'Matthew Robinson',
74
+ authorurl: 'http://subscribe2.wordpress.com',
75
+ infourl: 'http://subscribe2.wordpress.com',
76
+ version: tinymce.majorVersion + '.' + tinymce.minorVersion
77
  };
78
  }
79
+ } );
80
 
81
  // Register plugin
82
  tinymce.PluginManager.add( 'subscribe2', tinymce.plugins.Subscribe2Plugin );
83
+ }() );
tinymce/editor-plugin4.min.js CHANGED
@@ -1 +1 @@
1
- !function(){tinymce.create("tinymce.plugins.Subscribe2Plugin",{init:function(a,b){var c=0,d='<p><img src="'+b+'/../include/spacer.gif" class="mceSubscribe2 mceItemNoResize" /></p>',e="mceSubscribe2",f="[subscribe2]",g=[],h=new RegExp(/(\[|<!--)subscribe2.*?(\]|-->)/g),i=function(a){return-1!==a.indexOf('class="mceSubscribe2')&&(a=g[c]),a};a.addCommand("mceSubscribe2",function(){a.execCommand("mceInsertContent",0,d)}),a.addButton("subscribe2",{title:"Insert Subscribe2 Token",image:b+"/../include/s2-button.png",cmd:e}),a.on("init",function(){a.dom.loadCSS(b+"/css/content.min.css"),a.theme.onResolveName&&a.theme.onResolveName.add(function(b,c){"IMG"===c.node.nodeName&&a.dom.hasClass(c.node,e)&&(c.name="subscribe2")})}),a.on("BeforeSetContent",function(a){g=a.content.match(h),a.content=a.content.replace(h,d)}),a.on("PostProcess",function(a){if(a.get){if(null!==g)for(c=0;c<g.length;c++)a.content=a.content.replace(/<img[^>]+>/,i);a.content=a.content.replace(/<img[^>]+>/g,function(a){return-1!==a.indexOf('class="mceSubscribe2')&&(a=f),a})}})},getInfo:function(){return{longname:"Insert Subscribe2 Token",author:"Matthew Robinson",authorurl:"http://subscribe2.wordpress.com",infourl:"http://subscribe2.wordpress.com",version:tinymce.majorVersion+"."+tinymce.minorVersion}}}),tinymce.PluginManager.add("subscribe2",tinymce.plugins.Subscribe2Plugin)}();
1
+ tinymce.create("tinymce.plugins.Subscribe2Plugin",{init:function(e,n){var t=0,c='<p><img src="'+n+'/../include/spacer.gif" class="mceSubscribe2 mceItemNoResize" /></p>',i="mceSubscribe2",o=[],s=new RegExp(/(\[|<!--)subscribe2.*?(\]|-->)/g),r=function(e){return-1!==e.indexOf('class="mceSubscribe2')&&(e=o[t]),e};e.addCommand("mceSubscribe2",function(){e.execCommand("mceInsertContent",0,c)}),e.addButton("subscribe2",{title:"Insert Subscribe2 Token",image:n+"/../include/s2-button.png",cmd:i}),e.on("init",function(){e.dom.loadCSS(n+"/css/content.css"),e.theme.onResolveName&&e.theme.onResolveName.add(function(n,t){"IMG"===t.node.nodeName&&e.dom.hasClass(t.node,i)&&(t.name="subscribe2")})}),e.on("BeforeSetContent",function(e){o=e.content.match(s),e.content=e.content.replace(s,c)}),e.on("PostProcess",function(e){if(e.get){if(null!==o)for(t=0;t<o.length;t++)e.content=e.content.replace(/<img[^>]+>/,r);e.content=e.content.replace(/<img[^>]+>/g,function(e){return-1!==e.indexOf('class="mceSubscribe2')&&(e="[subscribe2]"),e})}})},getInfo:function(){return{longname:"Insert Subscribe2 Token",author:"Matthew Robinson",authorurl:"http://subscribe2.wordpress.com",infourl:"http://subscribe2.wordpress.com",version:tinymce.majorVersion+"."+tinymce.minorVersion}}}),tinymce.PluginManager.add("subscribe2",tinymce.plugins.Subscribe2Plugin);
uninstall.php CHANGED
@@ -30,8 +30,6 @@ if ( ! defined( 'ABSPATH' ) && ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
30
  }
31
  function s2_uninstall() {
32
  global $wpdb;
33
- // get name of subscribe2 table
34
- $public = $wpdb->prefix . 'subscribe2';
35
  // delete entry from wp_options table
36
  delete_option( 'subscribe2_options' );
37
  // delete legacy entry from wp-options table
@@ -49,6 +47,5 @@ function s2_uninstall() {
49
  $wpdb->query( "DELETE from $wpdb->postmeta WHERE meta_key = 's2mail'" );
50
 
51
  // drop the subscribe2 table
52
- $wpdb->query( "DROP TABLE IF EXISTS $public" );
53
  } // end s2_uninstall()
54
- ?>
30
  }
31
  function s2_uninstall() {
32
  global $wpdb;
 
 
33
  // delete entry from wp_options table
34
  delete_option( 'subscribe2_options' );
35
  // delete legacy entry from wp-options table
47
  $wpdb->query( "DELETE from $wpdb->postmeta WHERE meta_key = 's2mail'" );
48
 
49
  // drop the subscribe2 table
50
+ $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}subscribe2" );
51
  } // end s2_uninstall()