Subscribe2 - Version 10.28

Version Description

Download this release

Release Info

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

Code changes from version 10.27 to 10.28

ChangeLog.txt CHANGED
@@ -1,3 +1,9 @@
 
 
 
 
 
 
1
  = 10.27 =
2
 
3
  * Tightened checks for Coding Standards
1
+ = 10.28 =
2
+
3
+ * Fix warning message for when set_time_limit() is disabled in php.ini
4
+ * Remove unused variable to fix error message
5
+ * Fixes for strict in_array() checks
6
+
7
  = 10.27 =
8
 
9
  * Tightened checks for Coding Standards
ReadMe.txt CHANGED
@@ -65,6 +65,12 @@ This token will automatically be replaced by dynamic subscription information an
65
 
66
  == Changelog ==
67
 
 
 
 
 
 
 
68
  = 10.27 =
69
 
70
  * Tightened checks for Coding Standards
65
 
66
  == Changelog ==
67
 
68
+ = 10.28 =
69
+
70
+ * Fix warning message for when set_time_limit() is disabled in php.ini
71
+ * Remove unused variable to fix error message
72
+ * Fixes for strict in_array() checks
73
+
74
  = 10.27 =
75
 
76
  * Tightened checks for Coding Standards
admin/settings.php CHANGED
@@ -1,169 +1,169 @@
1
  <?php
2
  if ( ! function_exists( 'add_action' ) ) {
3
- exit();
4
  }
5
 
6
  global $wpdb, $wp_version, $current_tab;
7
 
8
  // was anything POSTed?
9
  if ( isset( $_POST['s2_admin'] ) ) {
10
- if ( false === wp_verify_nonce( $_REQUEST['_wpnonce'], 'subscribe2-options_subscribers' . S2VERSION ) ) {
11
- die( '<p>' . __( 'Security error! Your request cannot be completed.', 'subscribe2' ) . '</p>' );
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
- $preview_posts = get_posts( 'numberposts=1' );
25
- $preview_post = $preview_posts[0];
26
- $this->publish( $preview_post, $user_email );
27
- } else {
28
- do_action( 's2_digest_preview', $user_email );
29
- }
30
- echo '<div id="message" class="updated fade"><p><strong>' . __( 'Preview message(s) sent to logged in user', 'subscribe2' ) . '</strong></p></div>';
31
- } elseif ( isset( $_POST['resend'] ) ) {
32
- $stickies = get_option( 'sticky_posts' );
33
- if ( ! empty( $this->subscribe2_options['last_s2cron'] ) || ( 'yes' === $this->subscribe2_options['stickies'] && ! empty( $stickies ) ) ) {
34
- do_action( 's2_digest_resend', 'resend' );
35
- echo '<div id="message" class="updated fade"><p><strong>' . __( 'Attempt made to resend the Digest Notification email', 'subscribe2' ) . '</strong></p></div>';
36
- } else {
37
- echo '<div id="message" class="updated fade"><p><strong>' . __( 'The Digest Notification email contained no post information. No email was sent', 'subscribe2' ) . '</strong></p></div>';
38
- }
39
- } elseif ( isset( $_POST['submit'] ) ) {
40
- foreach ( $_POST as $key => $value ) {
41
- if ( in_array( $key, array( 'bcclimit', 's2page' ), true ) ) {
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' ), true ) ) {
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' ), true ) && ! empty( $_POST[ $key ] ) ) {
57
- // email subject and body templates
58
- $this->subscribe2_options[ $key ] = trim( $_POST[ $key ] );
59
- } elseif ( in_array( $key, array( 'compulsory', 'exclude', 'format' ), true ) ) {
60
- sort( $_POST[ $key ] );
61
- $newvalue = implode( ',', $_POST[ $key ] );
62
-
63
- if ( 'format' === $key ) {
64
- $this->subscribe2_options['exclude_formats'] = $newvalue;
65
- } else {
66
- $this->subscribe2_options[ $key ] = $newvalue;
67
- }
68
- } elseif ( 'registered_users_tab' === $key ) {
69
- $options = array( 'compulsory', 'exclude', 'format', 'reg_override' );
70
- foreach ( $options as $option ) {
71
- if ( ! isset( $_POST[ $option ] ) ) {
72
- if ( 'format' === $option ) {
73
- $this->subscribe2_options['exclude_formats'] = '';
74
- } else {
75
- $this->subscribe2_options[ $option ] = '';
76
- }
77
- }
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;
102
- while ( $timestamp < time() ) {
103
- // if we are trying to set the time in the past increment it forward
104
- // by the interval period until it is in the future
105
- $timestamp += $interval;
106
- }
107
- wp_schedule_event( $timestamp, $email_freq, 's2_digest_cron' );
108
- }
109
- }
110
- } else {
111
- if ( isset( $this->subscribe2_options[ $key ] ) ) {
112
- if ( 'sender' === $key && $this->subscribe2_options[ $key ] !== $_POST[ $key ] ) {
113
- $this->subscribe2_options['dismiss_sender_warning'] = '0';
114
- }
115
- $this->subscribe2_options[ $key ] = $_POST[ $key ];
116
- }
117
- }
118
- }
119
-
120
- echo '<div id="message" class="updated fade"><p><strong>' . __( 'Options saved!', 'subscribe2' ) . '</strong></p></div>';
121
- update_option( 'subscribe2_options', $this->subscribe2_options );
122
- }
123
  }
124
 
125
  // send error message if no WordPress page exists
126
  $page_id = $wpdb->get_var( "SELECT ID FROM `{$wpdb->prefix}posts` WHERE post_type='page' AND post_status='publish' LIMIT 1" );
127
  if ( empty( $page_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['autosub'] || 'yes' === $this->subscribe2_options['wpregdef'] || '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 {
141
- $disallowed_keywords = array( '{POSTTIME}', '{TABLE}', '{TABLELINKS}', '{COUNT}', '{LINK}', '{ACTION}' );
142
  }
143
  $disallowed = false;
144
  foreach ( $disallowed_keywords as $disallowed_keyword ) {
145
- if ( false !== strstr( $this->subscribe2_options['mailtext'], $disallowed_keyword ) ) {
146
- $disallowed[] = $disallowed_keyword;
147
- }
148
  }
149
 
150
  $template_link = '<a href="' . admin_url( 'admin.php?page=s2_settings&tab=templates' ) . '">' . __( 'Modify your template', 'subscribe2' ) . '</a>';
151
  if ( false !== $disallowed ) {
152
- $disallowed_keywords = __( 'Your chosen email type (per-post or digest) does not support the following keywords:', 'subscribe2' );
153
- echo '<div id="keyword_message" class="error"><p class="s2_error"><strong>' . $disallowed_keywords . '</strong><br />' . implode( $disallowed, ', ' ) . '<br />' . $template_link . '</p></div>';
154
  }
155
 
156
  // send error message if sender email address is off-domain
157
  if ( 'blogname' === $this->subscribe2_options['sender'] ) {
158
- $sender = get_bloginfo( 'admin_email' );
159
  } else {
160
- $user = $this->get_userdata( $this->subscribe2_options['sender'] );
161
- $sender = $user->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
 
169
  // detect or define which tab we are in
@@ -173,16 +173,16 @@ $current_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'email';
173
  echo '<div class="wrap">';
174
  echo '<h1>' . __( 'Settings', 'subscribe2' ) . '</h1>' . "\r\n";
175
  $s2tabs = 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 ( $s2tabs 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>';
188
 
@@ -194,324 +194,324 @@ 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':
198
- // settings for outgoing emails
199
- echo '<div class="s2_admin" id="s2_notification_settings">' . "\r\n";
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";
211
- echo __( 'Subscriptions', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
212
- echo '<label><input type="radio" name="admin_email" value="unsubs"' . checked( $this->subscribe2_options['admin_email'], 'unsubs', false ) . ' />' . "\r\n";
213
- echo __( 'Unsubscriptions', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
214
- echo '<label><input type="radio" name="admin_email" value="both"' . checked( $this->subscribe2_options['admin_email'], 'both', false ) . ' />' . "\r\n";
215
- echo __( 'Both', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
216
- echo '<label><input type="radio" name="admin_email" value="none"' . checked( $this->subscribe2_options['admin_email'], 'none', false ) . ' />' . "\r\n";
217
- echo __( 'Neither', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
218
-
219
- echo __( 'Include theme CSS stylesheet in HTML notifications', 'subscribe2' ) . ': ';
220
- echo '<label><input type="radio" name="stylesheet" value="yes"' . checked( $this->subscribe2_options['stylesheet'], 'yes', false ) . ' /> ';
221
- echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
222
- echo '<label><input type="radio" name="stylesheet" value="no"' . checked( $this->subscribe2_options['stylesheet'], 'no', false ) . ' /> ';
223
- echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
224
-
225
- echo __( 'Send Emails for Pages', 'subscribe2' ) . ': ';
226
- echo '<label><input type="radio" name="pages" value="yes"' . checked( $this->subscribe2_options['pages'], 'yes', false ) . ' /> ';
227
- echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
228
- echo '<label><input type="radio" name="pages" value="no"' . checked( $this->subscribe2_options['pages'], 'no', false ) . ' /> ';
229
- echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
230
- $s2_post_types = apply_filters( 's2_post_types', null );
231
- if ( ! empty( $s2_post_types ) ) {
232
- $types = '';
233
- echo __( 'Subscribe2 will send email notifications for the following custom post types', 'subscribe2' ) . ': <strong>';
234
- foreach ( $s2_post_types as $s2_post_type ) {
235
- ( '' === $types ) ? $types = ucwords( $s2_post_type ) : $types .= ', ' . ucwords( $s2_post_type );
236
- }
237
- echo $types . '</strong><br /><br />' . "\r\n";
238
- }
239
- echo __( 'Send Emails for Password Protected Posts', 'subscribe2' ) . ': ';
240
- echo '<label><input type="radio" name="password" value="yes"' . checked( $this->subscribe2_options['password'], 'yes', false ) . ' /> ';
241
- echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
242
- echo '<label><input type="radio" name="password" value="no"' . checked( $this->subscribe2_options['password'], 'no', false ) . ' /> ';
243
- echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
244
- echo __( 'Send Emails for Private Posts', 'subscribe2' ) . ': ';
245
- echo '<label><input type="radio" name="private" value="yes"' . checked( $this->subscribe2_options['private'], 'yes', false ) . ' /> ';
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 );
259
- echo '</label><br /><br />' . "\r\n";
260
- if ( function_exists( 'wp_schedule_event' ) ) {
261
- echo __( 'Send Emails', 'subscribe2' ) . ': <br /><br />' . "\r\n";
262
- $this->display_digest_choices();
263
- echo '<p>' . __( 'For digest notifications, date order for posts is', 'subscribe2' ) . ': ' . "\r\n";
264
- echo '<label><input type="radio" name="cron_order" value="desc"' . checked( $this->subscribe2_options['cron_order'], 'desc', false ) . ' /> ';
265
- echo __( 'Descending', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
266
- echo '<label><input type="radio" name="cron_order" value="asc"' . checked( $this->subscribe2_options['cron_order'], 'asc', false ) . ' /> ';
267
- echo __( 'Ascending', 'subscribe2' ) . '</label></p>' . "\r\n";
268
- }
269
- echo __( 'Add Tracking Parameters to the Permalink', 'subscribe2' ) . ': ';
270
- echo '<input type="text" name="tracking" value="' . stripslashes( $this->subscribe2_options['tracking'] ) . '" size="50" /> ';
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
278
- echo '<div class="s2_admin" id="s2_templates">' . "\r\n";
279
- echo '<p>' . "\r\n";
280
- echo '<table style="width: 100%; border-collapse: separate; border-spacing: 5px; *border-collapse: expression(\'separate\', cellSpacing = \'5px\');" class="editform">' . "\r\n";
281
- echo '<tr><td style="vertical-align: top; height: 350px; min-height: 350px;">';
282
- echo __( 'Notification email (must not be empty)', 'subscribe2' ) . ':<br />' . "\r\n";
283
- echo __( 'Subject Line', 'subscribe2' ) . ': ';
284
- echo '<input type="text" name="notification_subject" value="' . stripslashes( $this->subscribe2_options['notification_subject'] ) . '" size="45" />';
285
- echo '<br />' . "\r\n";
286
- echo '<textarea rows="9" cols="60" name="mailtext">' . stripslashes( $this->subscribe2_options['mailtext'] ) . '</textarea>' . "\r\n";
287
- echo '</td><td style="vertical-align: top;" rowspan="3">';
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";
295
- echo '<dt><b>{TITLETEXT}</b></dt><dd>' . __( "the post's unformatted title <br />(<i>for per-post emails only</i>)", 'subscribe2' ) . '</dd>' . "\r\n";
296
- echo '<dt><b>{POST}</b></dt><dd>' . __( "the excerpt or the entire post<br />(<i>based on the subscriber's preferences</i>)", 'subscribe2' ) . '</dd>' . "\r\n";
297
- echo '<dt><b>{POSTTIME}</b></dt><dd>' . __( 'the excerpt of the post and the time it was posted<br />(<i>for digest emails only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
298
- echo '<dt><b>{TABLE}</b></dt><dd>' . __( 'a list of post titles<br />(<i>for digest emails only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
299
- echo '<dt><b>{TABLELINKS}</b></dt><dd>' . __( 'a list of post titles followed by links to the articles<br />(<i>for digest emails only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
300
- echo '<dt><b>{REFERENCELINKS}</b></dt><dd>' . __( 'a reference style list of links at the end of the email with corresponding numbers in the content<br />(<i>for the full content plain text per-post email only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
301
- echo '<dt><b>{PERMALINK}</b></dt><dd>' . __( "the post's permalink<br />(<i>for per-post emails only</i>)", 'subscribe2' ) . '</dd>' . "\r\n";
302
- echo '<dt><b>{TINYLINK}</b></dt><dd>' . __( "the post's permalink after conversion by TinyURL", 'subscribe2' ) . '</dd>' . "\r\n";
303
- echo '<dt><b>{PERMAURL}</b></dt><dd>' . __( "the post's unformatted permalink<br />(<i>for per-post emails only</i>)", 'subscribe2' ) . '</dd>' . "\r\n";
304
- echo '<dt><b>{DATE}</b></dt><dd>' . __( 'the date the post was made<br />(<i>for per-post emails only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
305
- echo '<dt><b>{TIME}</b></dt><dd>' . __( 'the time the post was made<br />(<i>for per-post emails only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
306
- echo '<dt><b>{MYNAME}</b></dt><dd>' . __( "the admin or post author's name", 'subscribe2' ) . '</dd>' . "\r\n";
307
- echo '<dt><b>{EMAIL}</b></dt><dd>' . __( "the admin or post author's email", 'subscribe2' ) . ' </dd>' . "\r\n";
308
- echo '<dt><b>{AUTHORNAME}</b></dt><dd>' . __( "the post author's name", 'subscribe2' ) . '</dd>' . "\r\n";
309
- echo '<dt><b>{LINK}</b></dt><dd>' . __( 'the generated link to confirm a request<br />(<i>only used in the confirmation email template</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
310
- echo '<dt><b>{ACTION}</b></dt><dd>' . __( 'Action performed by LINK in confirmation email<br />(<i>only used in the confirmation email template</i>)', 'subscribe2' ) . "</dd>\r\n";
311
- echo '<dt><b>{CATS}</b></dt><dd>' . __( "the post's assigned categories", 'subscribe2' ) . "</dd>\r\n";
312
- echo '<dt><b>{TAGS}</b></dt><dd>' . __( "the post's assigned Tags", 'subscribe2' ) . "</dd>\r\n";
313
- echo '<dt><b>{COUNT}</b></dt><dd>' . __( 'the number of posts included in the digest email<br />(<i>for digest emails only</i>)', 'subscribe2' ) . "</dd>\r\n";
314
- echo '</dl></td></tr><tr><td style="vertical-align: top; height: 350px; min-height: 350px;">';
315
- echo __( 'Subscribe / Unsubscribe confirmation email', 'subscribe2' ) . ':<br />' . "\r\n";
316
- echo __( 'Subject Line', 'subscribe2' ) . ': ';
317
- echo '<input type="text" name="confirm_subject" value="' . stripslashes( $this->subscribe2_options['confirm_subject'] ) . '" size="45" /><br />' . "\r\n";
318
- echo '<textarea rows="9" cols="60" name="confirm_email">' . stripslashes( $this->subscribe2_options['confirm_email'] ) . '</textarea>' . "\r\n";
319
- echo '</td></tr><tr><td style="vertical-align: top; height: 350px; min-height: 350px;">';
320
- echo __( 'Reminder email to Unconfirmed Subscribers', 'subscribe2' ) . ':<br />' . "\r\n";
321
- echo __( 'Subject Line', 'subscribe2' ) . ': ';
322
- echo '<input type="text" name="remind_subject" value="' . stripslashes( $this->subscribe2_options['remind_subject'] ) . '" size="45" /><br />' . "\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";
335
- echo '<input type="hidden" name="registered_users_tab" value="options" />' . "\r\n";
336
- echo '<h3>' . __( 'Compulsory Categories', 'subscribe2' ) . '</h3>' . "\r\n";
337
- echo '<p>' . "\r\n";
338
- echo '<strong><em style="color: red">' . __( 'Compulsory categories will be checked by default for Registered Subscribers', 'subscribe2' ) . '</em></strong><br />' . "\r\n";
339
- echo '</p>';
340
- $s2_forms->display_category_form( explode( ',', $this->subscribe2_options['compulsory'] ), 1, array(), 'compulsory' );
341
- echo "</div>\r\n";
342
-
343
- // excluded categories
344
- echo '<div class="s2_admin" id="s2_excluded_categories">' . "\r\n";
345
- echo '<h3>' . __( 'Excluded Categories', 'subscribe2' ) . '</h3>' . "\r\n";
346
- echo '<p>';
347
- echo '<strong><em style="color: red">' . __( 'Posts assigned to any Excluded Category do not generate notifications and are not included in digest notifications', 'subscribe2' ) . '</em></strong><br />' . "\r\n";
348
- echo '</p>';
349
- $s2_forms->display_category_form( explode( ',', $this->subscribe2_options['exclude'] ), 1, array(), 'exclude' );
350
- echo '<p style="text-align: center;"><label><input type="checkbox" name="reg_override" value="1"' . checked( $this->subscribe2_options['reg_override'], '1', false ) . ' /> ';
351
- echo __( 'Allow registered users to subscribe to excluded categories?', 'subscribe2' ) . '</label></p>' . "\r\n";
352
- echo '</div>' . "\r\n";
353
-
354
- // excluded post formats
355
- $formats = get_theme_support( 'post-formats' );
356
- if ( false !== $formats ) {
357
- // excluded formats
358
- echo '<div class="s2_admin" id="s2_excluded_formats">' . "\r\n";
359
- echo '<h3>' . __( 'Excluded Formats', 'subscribe2' ) . '</h3>' . "\r\n";
360
- echo '<p>';
361
- echo '<strong><em style="color: red">' . __( 'Posts assigned to any Excluded Format do not generate notifications and are not included in digest notifications', 'subscribe2' ) . '</em></strong><br />' . "\r\n";
362
- echo '</p>';
363
- $this->display_format_form( $formats, explode( ',', $this->subscribe2_options['exclude_formats'] ) );
364
- echo '</div>' . "\r\n";
365
- }
366
-
367
- //Auto Subscription for new registrations
368
- echo '<div class="s2_admin" id="s2_autosubscribe_settings">' . "\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 ) . ' /> ';
379
- echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
380
- echo __( 'Auto-subscribe includes any excluded categories', 'subscribe2' ) . ':<br />' . "\r\n";
381
- echo '<label><input type="radio" name="newreg_override" value="yes"' . checked( $this->subscribe2_options['newreg_override'], 'yes', 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;';
395
- echo '<label><input type="radio" name="autoformat" value="html_excerpt"' . checked( $this->subscribe2_options['autoformat'], 'html_excerpt', false ) . ' /> ';
396
- echo __( 'HTML - Excerpt', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
397
- echo '<label><input type="radio" name="autoformat" value="post"' . checked( $this->subscribe2_options['autoformat'], 'post', false ) . ' /> ';
398
- echo __( 'Plain Text - Full', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
399
- echo '<label><input type="radio" name="autoformat" value="excerpt"' . checked( $this->subscribe2_options['autoformat'], 'excerpt', false ) . ' /> ';
400
- echo __( 'Plain Text - Excerpt', 'subscribe2' ) . '</label><br /><br />';
401
- echo __( 'Registered Users have the option to auto-subscribe to new categories', 'subscribe2' ) . ': <br />' . "\r\n";
402
- echo '<label><input type="radio" name="show_autosub" value="yes"' . checked( $this->subscribe2_options['show_autosub'], 'yes', false ) . ' /> ';
403
- echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
404
- echo '<label><input type="radio" name="show_autosub" value="no"' . checked( $this->subscribe2_options['show_autosub'], 'no', false ) . ' /> ';
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";
418
- echo '<label><input type="radio" name="comment_subs" value="before"' . checked( $this->subscribe2_options['comment_subs'], 'before', false ) . ' /> ';
419
- echo __( 'Before the Comment Submit button', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
420
- echo '<label><input type="radio" name="comment_subs" value="after"' . checked( $this->subscribe2_options['comment_subs'], 'after', false ) . ' /> ';
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 ) . ' /> ';
434
- echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
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
447
- echo __( 'Set default Subscribe2 page as', 'subscribe2' ) . ': ';
448
- echo '<select name="s2page">' . "\r\n";
449
- echo '<option value="0">' . __( 'Select a page', 'subscribe2' ) . '</option>' . "\r\n";
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";
456
-
457
- // show QuickTag button
458
- echo '<label><input type="checkbox" name="show_button" value="1"' . checked( $this->subscribe2_options['show_button'], '1', false ) . ' /> ';
459
- echo __( 'Show the Subscribe2 button on the Write toolbar?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
460
-
461
- // enable popup style form
462
- echo '<label><input type="checkbox" name="ajax" value="1"' . checked( $this->subscribe2_options['ajax'], '1', false ) . ' /> ';
463
- echo __( 'Enable popup style subscription form?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
464
-
465
- // show Widget
466
- echo '<label><input type="checkbox" name="widget" value="1"' . checked( $this->subscribe2_options['widget'], '1', false ) . ' /> ';
467
- echo __( 'Enable Subscribe2 Widget?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
468
-
469
- // show Counter Widget
470
- echo '<label><input type="checkbox" name="counterwidget" value="1"' . checked( $this->subscribe2_options['counterwidget'], '1', false ) . ' /> ';
471
- echo __( 'Enable Subscribe2 Counter Widget?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
472
-
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
503
  echo '<p class="submit" style="text-align: center"><input type="submit" class="button-primary" name="submit" value="' . __( 'Submit', 'subscribe2' ) . '" /></p>';
504
 
505
  if ( 'misc' === $current_tab ) {
506
- // reset
507
- echo '<h3>' . __( 'Reset to Default Settings', 'subscribe2' ) . '</h3>' . "\r\n";
508
- echo '<p>' . __( 'Use this to reset all options to their defaults. This <strong><em>will not</em></strong> modify your list of subscribers.', 'subscribe2' ) . '</p>' . "\r\n";
509
- echo '<p class="submit" style="text-align: center">';
510
- echo '<input type="submit" id="deletepost" name="reset" value="' . __( 'RESET', 'subscribe2' ) .
511
- '" /></p>';
512
  }
513
  echo '</form></div>' . "\r\n";
514
 
515
  require ABSPATH . 'wp-admin/admin-footer.php';
516
  // just to be sure
517
- die;
1
  <?php
2
  if ( ! function_exists( 'add_action' ) ) {
3
+ exit();
4
  }
5
 
6
  global $wpdb, $wp_version, $current_tab;
7
 
8
  // was anything POSTed?
9
  if ( isset( $_POST['s2_admin'] ) ) {
10
+ if ( false === wp_verify_nonce( $_REQUEST['_wpnonce'], 'subscribe2-options_subscribers' . S2VERSION ) ) {
11
+ die( '<p>' . __( 'Security error! Your request cannot be completed.', 'subscribe2' ) . '</p>' );
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
+ $preview_posts = get_posts( 'numberposts=1' );
25
+ $preview_post = $preview_posts[0];
26
+ $this->publish( $preview_post, $user_email );
27
+ } else {
28
+ do_action( 's2_digest_preview', $user_email );
29
+ }
30
+ echo '<div id="message" class="updated fade"><p><strong>' . __( 'Preview message(s) sent to logged in user', 'subscribe2' ) . '</strong></p></div>';
31
+ } elseif ( isset( $_POST['resend'] ) ) {
32
+ $stickies = get_option( 'sticky_posts' );
33
+ if ( ! empty( $this->subscribe2_options['last_s2cron'] ) || ( 'yes' === $this->subscribe2_options['stickies'] && ! empty( $stickies ) ) ) {
34
+ do_action( 's2_digest_resend', 'resend' );
35
+ echo '<div id="message" class="updated fade"><p><strong>' . __( 'Attempt made to resend the Digest Notification email', 'subscribe2' ) . '</strong></p></div>';
36
+ } else {
37
+ echo '<div id="message" class="updated fade"><p><strong>' . __( 'The Digest Notification email contained no post information. No email was sent', 'subscribe2' ) . '</strong></p></div>';
38
+ }
39
+ } elseif ( isset( $_POST['submit'] ) ) {
40
+ foreach ( $_POST as $key => $value ) {
41
+ if ( in_array( $key, array( 'bcclimit', 's2page' ), true ) ) {
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' ), true ) ) {
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' ), true ) && ! empty( $_POST[ $key ] ) ) {
57
+ // email subject and body templates
58
+ $this->subscribe2_options[ $key ] = trim( $_POST[ $key ] );
59
+ } elseif ( in_array( $key, array( 'compulsory', 'exclude', 'format' ), true ) ) {
60
+ sort( $_POST[ $key ] );
61
+ $newvalue = implode( ',', $_POST[ $key ] );
62
+
63
+ if ( 'format' === $key ) {
64
+ $this->subscribe2_options['exclude_formats'] = $newvalue;
65
+ } else {
66
+ $this->subscribe2_options[ $key ] = $newvalue;
67
+ }
68
+ } elseif ( 'registered_users_tab' === $key ) {
69
+ $options = array( 'compulsory', 'exclude', 'format', 'reg_override' );
70
+ foreach ( $options as $option ) {
71
+ if ( ! isset( $_POST[ $option ] ) ) {
72
+ if ( 'format' === $option ) {
73
+ $this->subscribe2_options['exclude_formats'] = '';
74
+ } else {
75
+ $this->subscribe2_options[ $option ] = '';
76
+ }
77
+ }
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;
102
+ while ( $timestamp < time() ) {
103
+ // if we are trying to set the time in the past increment it forward
104
+ // by the interval period until it is in the future
105
+ $timestamp += $interval;
106
+ }
107
+ wp_schedule_event( $timestamp, $email_freq, 's2_digest_cron' );
108
+ }
109
+ }
110
+ } else {
111
+ if ( isset( $this->subscribe2_options[ $key ] ) ) {
112
+ if ( 'sender' === $key && $this->subscribe2_options[ $key ] !== $_POST[ $key ] ) {
113
+ $this->subscribe2_options['dismiss_sender_warning'] = '0';
114
+ }
115
+ $this->subscribe2_options[ $key ] = $_POST[ $key ];
116
+ }
117
+ }
118
+ }
119
+
120
+ echo '<div id="message" class="updated fade"><p><strong>' . __( 'Options saved!', 'subscribe2' ) . '</strong></p></div>';
121
+ update_option( 'subscribe2_options', $this->subscribe2_options );
122
+ }
123
  }
124
 
125
  // send error message if no WordPress page exists
126
  $page_id = $wpdb->get_var( "SELECT ID FROM `{$wpdb->prefix}posts` WHERE post_type='page' AND post_status='publish' LIMIT 1" );
127
  if ( empty( $page_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['autosub'] || 'yes' === $this->subscribe2_options['wpregdef'] || '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 {
141
+ $disallowed_keywords = array( '{POSTTIME}', '{TABLE}', '{TABLELINKS}', '{COUNT}', '{LINK}', '{ACTION}' );
142
  }
143
  $disallowed = false;
144
  foreach ( $disallowed_keywords as $disallowed_keyword ) {
145
+ if ( false !== strstr( $this->subscribe2_options['mailtext'], $disallowed_keyword ) ) {
146
+ $disallowed[] = $disallowed_keyword;
147
+ }
148
  }
149
 
150
  $template_link = '<a href="' . admin_url( 'admin.php?page=s2_settings&tab=templates' ) . '">' . __( 'Modify your template', 'subscribe2' ) . '</a>';
151
  if ( false !== $disallowed ) {
152
+ $disallowed_keywords = __( 'Your chosen email type (per-post or digest) does not support the following keywords:', 'subscribe2' );
153
+ echo '<div id="keyword_message" class="error"><p class="s2_error"><strong>' . $disallowed_keywords . '</strong><br />' . implode( $disallowed, ', ' ) . '<br />' . $template_link . '</p></div>';
154
  }
155
 
156
  // send error message if sender email address is off-domain
157
  if ( 'blogname' === $this->subscribe2_options['sender'] ) {
158
+ $sender = get_bloginfo( 'admin_email' );
159
  } else {
160
+ $user = $this->get_userdata( $this->subscribe2_options['sender'] );
161
+ $sender = $user->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
 
169
  // detect or define which tab we are in
173
  echo '<div class="wrap">';
174
  echo '<h1>' . __( 'Settings', 'subscribe2' ) . '</h1>' . "\r\n";
175
  $s2tabs = 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 ( $s2tabs 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>';
188
 
194
  echo '<input type="hidden" id="jsbcclimit" value="' . $this->subscribe2_options['bcclimit'] . '" />';
195
 
196
  switch ( $current_tab ) {
197
+ case 'email':
198
+ // settings for outgoing emails
199
+ echo '<div class="s2_admin" id="s2_notification_settings">' . "\r\n";
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";
211
+ echo __( 'Subscriptions', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
212
+ echo '<label><input type="radio" name="admin_email" value="unsubs"' . checked( $this->subscribe2_options['admin_email'], 'unsubs', false ) . ' />' . "\r\n";
213
+ echo __( 'Unsubscriptions', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
214
+ echo '<label><input type="radio" name="admin_email" value="both"' . checked( $this->subscribe2_options['admin_email'], 'both', false ) . ' />' . "\r\n";
215
+ echo __( 'Both', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
216
+ echo '<label><input type="radio" name="admin_email" value="none"' . checked( $this->subscribe2_options['admin_email'], 'none', false ) . ' />' . "\r\n";
217
+ echo __( 'Neither', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
218
+
219
+ echo __( 'Include theme CSS stylesheet in HTML notifications', 'subscribe2' ) . ': ';
220
+ echo '<label><input type="radio" name="stylesheet" value="yes"' . checked( $this->subscribe2_options['stylesheet'], 'yes', false ) . ' /> ';
221
+ echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
222
+ echo '<label><input type="radio" name="stylesheet" value="no"' . checked( $this->subscribe2_options['stylesheet'], 'no', false ) . ' /> ';
223
+ echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
224
+
225
+ echo __( 'Send Emails for Pages', 'subscribe2' ) . ': ';
226
+ echo '<label><input type="radio" name="pages" value="yes"' . checked( $this->subscribe2_options['pages'], 'yes', false ) . ' /> ';
227
+ echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
228
+ echo '<label><input type="radio" name="pages" value="no"' . checked( $this->subscribe2_options['pages'], 'no', false ) . ' /> ';
229
+ echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
230
+ $s2_post_types = apply_filters( 's2_post_types', null );
231
+ if ( ! empty( $s2_post_types ) ) {
232
+ $types = '';
233
+ echo __( 'Subscribe2 will send email notifications for the following custom post types', 'subscribe2' ) . ': <strong>';
234
+ foreach ( $s2_post_types as $s2_post_type ) {
235
+ ( '' === $types ) ? $types = ucwords( $s2_post_type ) : $types .= ', ' . ucwords( $s2_post_type );
236
+ }
237
+ echo $types . '</strong><br /><br />' . "\r\n";
238
+ }
239
+ echo __( 'Send Emails for Password Protected Posts', 'subscribe2' ) . ': ';
240
+ echo '<label><input type="radio" name="password" value="yes"' . checked( $this->subscribe2_options['password'], 'yes', false ) . ' /> ';
241
+ echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
242
+ echo '<label><input type="radio" name="password" value="no"' . checked( $this->subscribe2_options['password'], 'no', false ) . ' /> ';
243
+ echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
244
+ echo __( 'Send Emails for Private Posts', 'subscribe2' ) . ': ';
245
+ echo '<label><input type="radio" name="private" value="yes"' . checked( $this->subscribe2_options['private'], 'yes', false ) . ' /> ';
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 );
259
+ echo '</label><br /><br />' . "\r\n";
260
+ if ( function_exists( 'wp_schedule_event' ) ) {
261
+ echo __( 'Send Emails', 'subscribe2' ) . ': <br /><br />' . "\r\n";
262
+ $this->display_digest_choices();
263
+ echo '<p>' . __( 'For digest notifications, date order for posts is', 'subscribe2' ) . ': ' . "\r\n";
264
+ echo '<label><input type="radio" name="cron_order" value="desc"' . checked( $this->subscribe2_options['cron_order'], 'desc', false ) . ' /> ';
265
+ echo __( 'Descending', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
266
+ echo '<label><input type="radio" name="cron_order" value="asc"' . checked( $this->subscribe2_options['cron_order'], 'asc', false ) . ' /> ';
267
+ echo __( 'Ascending', 'subscribe2' ) . '</label></p>' . "\r\n";
268
+ }
269
+ echo __( 'Add Tracking Parameters to the Permalink', 'subscribe2' ) . ': ';
270
+ echo '<input type="text" name="tracking" value="' . stripslashes( $this->subscribe2_options['tracking'] ) . '" size="50" /> ';
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
278
+ echo '<div class="s2_admin" id="s2_templates">' . "\r\n";
279
+ echo '<p>' . "\r\n";
280
+ echo '<table style="width: 100%; border-collapse: separate; border-spacing: 5px; *border-collapse: expression(\'separate\', cellSpacing = \'5px\');" class="editform">' . "\r\n";
281
+ echo '<tr><td style="vertical-align: top; height: 350px; min-height: 350px;">';
282
+ echo __( 'Notification email (must not be empty)', 'subscribe2' ) . ':<br />' . "\r\n";
283
+ echo __( 'Subject Line', 'subscribe2' ) . ': ';
284
+ echo '<input type="text" name="notification_subject" value="' . stripslashes( $this->subscribe2_options['notification_subject'] ) . '" size="45" />';
285
+ echo '<br />' . "\r\n";
286
+ echo '<textarea rows="9" cols="60" name="mailtext" style="width:95%;">' . stripslashes( $this->subscribe2_options['mailtext'] ) . '</textarea>' . "\r\n";
287
+ echo '</td><td style="vertical-align: top;" rowspan="3">';
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";
295
+ echo '<dt><b>{TITLETEXT}</b></dt><dd>' . __( "the post's unformatted title <br />(<i>for per-post emails only</i>)", 'subscribe2' ) . '</dd>' . "\r\n";
296
+ echo '<dt><b>{POST}</b></dt><dd>' . __( "the excerpt or the entire post<br />(<i>based on the subscriber's preferences</i>)", 'subscribe2' ) . '</dd>' . "\r\n";
297
+ echo '<dt><b>{POSTTIME}</b></dt><dd>' . __( 'the excerpt of the post and the time it was posted<br />(<i>for digest emails only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
298
+ echo '<dt><b>{TABLE}</b></dt><dd>' . __( 'a list of post titles<br />(<i>for digest emails only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
299
+ echo '<dt><b>{TABLELINKS}</b></dt><dd>' . __( 'a list of post titles followed by links to the articles<br />(<i>for digest emails only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
300
+ echo '<dt><b>{REFERENCELINKS}</b></dt><dd>' . __( 'a reference style list of links at the end of the email with corresponding numbers in the content<br />(<i>for the full content plain text per-post email only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
301
+ echo '<dt><b>{PERMALINK}</b></dt><dd>' . __( "the post's permalink<br />(<i>for per-post emails only</i>)", 'subscribe2' ) . '</dd>' . "\r\n";
302
+ echo '<dt><b>{TINYLINK}</b></dt><dd>' . __( "the post's permalink after conversion by TinyURL", 'subscribe2' ) . '</dd>' . "\r\n";
303
+ echo '<dt><b>{PERMAURL}</b></dt><dd>' . __( "the post's unformatted permalink<br />(<i>for per-post emails only</i>)", 'subscribe2' ) . '</dd>' . "\r\n";
304
+ echo '<dt><b>{DATE}</b></dt><dd>' . __( 'the date the post was made<br />(<i>for per-post emails only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
305
+ echo '<dt><b>{TIME}</b></dt><dd>' . __( 'the time the post was made<br />(<i>for per-post emails only</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
306
+ echo '<dt><b>{MYNAME}</b></dt><dd>' . __( "the admin or post author's name", 'subscribe2' ) . '</dd>' . "\r\n";
307
+ echo '<dt><b>{EMAIL}</b></dt><dd>' . __( "the admin or post author's email", 'subscribe2' ) . ' </dd>' . "\r\n";
308
+ echo '<dt><b>{AUTHORNAME}</b></dt><dd>' . __( "the post author's name", 'subscribe2' ) . '</dd>' . "\r\n";
309
+ echo '<dt><b>{LINK}</b></dt><dd>' . __( 'the generated link to confirm a request<br />(<i>only used in the confirmation email template</i>)', 'subscribe2' ) . '</dd>' . "\r\n";
310
+ echo '<dt><b>{ACTION}</b></dt><dd>' . __( 'Action performed by LINK in confirmation email<br />(<i>only used in the confirmation email template</i>)', 'subscribe2' ) . "</dd>\r\n";
311
+ echo '<dt><b>{CATS}</b></dt><dd>' . __( "the post's assigned categories", 'subscribe2' ) . "</dd>\r\n";
312
+ echo '<dt><b>{TAGS}</b></dt><dd>' . __( "the post's assigned Tags", 'subscribe2' ) . "</dd>\r\n";
313
+ echo '<dt><b>{COUNT}</b></dt><dd>' . __( 'the number of posts included in the digest email<br />(<i>for digest emails only</i>)', 'subscribe2' ) . "</dd>\r\n";
314
+ echo '</dl></td></tr><tr><td style="vertical-align: top; height: 350px; min-height: 350px;">';
315
+ echo __( 'Subscribe / Unsubscribe confirmation email', 'subscribe2' ) . ':<br />' . "\r\n";
316
+ echo __( 'Subject Line', 'subscribe2' ) . ': ';
317
+ echo '<input type="text" name="confirm_subject" value="' . stripslashes( $this->subscribe2_options['confirm_subject'] ) . '" size="45" /><br />' . "\r\n";
318
+ echo '<textarea rows="9" cols="60" name="confirm_email" style="width:95%;">' . stripslashes( $this->subscribe2_options['confirm_email'] ) . '</textarea>' . "\r\n";
319
+ echo '</td></tr><tr><td style="vertical-align: top; height: 350px; min-height: 350px;">';
320
+ echo __( 'Reminder email to Unconfirmed Subscribers', 'subscribe2' ) . ':<br />' . "\r\n";
321
+ echo __( 'Subject Line', 'subscribe2' ) . ': ';
322
+ echo '<input type="text" name="remind_subject" value="' . stripslashes( $this->subscribe2_options['remind_subject'] ) . '" size="45" /><br />' . "\r\n";
323
+ echo '<textarea rows="9" cols="60" name="remind_email" style="width:95%;">' . 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";
335
+ echo '<input type="hidden" name="registered_users_tab" value="options" />' . "\r\n";
336
+ echo '<h3>' . __( 'Compulsory Categories', 'subscribe2' ) . '</h3>' . "\r\n";
337
+ echo '<p>' . "\r\n";
338
+ echo '<strong><em style="color: red">' . __( 'Compulsory categories will be checked by default for Registered Subscribers', 'subscribe2' ) . '</em></strong><br />' . "\r\n";
339
+ echo '</p>';
340
+ $s2_forms->display_category_form( explode( ',', $this->subscribe2_options['compulsory'] ), 1, array(), 'compulsory' );
341
+ echo "</div>\r\n";
342
+
343
+ // excluded categories
344
+ echo '<div class="s2_admin" id="s2_excluded_categories">' . "\r\n";
345
+ echo '<h3>' . __( 'Excluded Categories', 'subscribe2' ) . '</h3>' . "\r\n";
346
+ echo '<p>';
347
+ echo '<strong><em style="color: red">' . __( 'Posts assigned to any Excluded Category do not generate notifications and are not included in digest notifications', 'subscribe2' ) . '</em></strong><br />' . "\r\n";
348
+ echo '</p>';
349
+ $s2_forms->display_category_form( explode( ',', $this->subscribe2_options['exclude'] ), 1, array(), 'exclude' );
350
+ echo '<p style="text-align: center;"><label><input type="checkbox" name="reg_override" value="1"' . checked( $this->subscribe2_options['reg_override'], '1', false ) . ' /> ';
351
+ echo __( 'Allow registered users to subscribe to excluded categories?', 'subscribe2' ) . '</label></p>' . "\r\n";
352
+ echo '</div>' . "\r\n";
353
+
354
+ // excluded post formats
355
+ $formats = get_theme_support( 'post-formats' );
356
+ if ( false !== $formats ) {
357
+ // excluded formats
358
+ echo '<div class="s2_admin" id="s2_excluded_formats">' . "\r\n";
359
+ echo '<h3>' . __( 'Excluded Formats', 'subscribe2' ) . '</h3>' . "\r\n";
360
+ echo '<p>';
361
+ echo '<strong><em style="color: red">' . __( 'Posts assigned to any Excluded Format do not generate notifications and are not included in digest notifications', 'subscribe2' ) . '</em></strong><br />' . "\r\n";
362
+ echo '</p>';
363
+ $this->display_format_form( $formats, explode( ',', $this->subscribe2_options['exclude_formats'] ) );
364
+ echo '</div>' . "\r\n";
365
+ }
366
+
367
+ //Auto Subscription for new registrations
368
+ echo '<div class="s2_admin" id="s2_autosubscribe_settings">' . "\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 ) . ' /> ';
379
+ echo __( 'No', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
380
+ echo __( 'Auto-subscribe includes any excluded categories', 'subscribe2' ) . ':<br />' . "\r\n";
381
+ echo '<label><input type="radio" name="newreg_override" value="yes"' . checked( $this->subscribe2_options['newreg_override'], 'yes', 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;';
395
+ echo '<label><input type="radio" name="autoformat" value="html_excerpt"' . checked( $this->subscribe2_options['autoformat'], 'html_excerpt', false ) . ' /> ';
396
+ echo __( 'HTML - Excerpt', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
397
+ echo '<label><input type="radio" name="autoformat" value="post"' . checked( $this->subscribe2_options['autoformat'], 'post', false ) . ' /> ';
398
+ echo __( 'Plain Text - Full', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
399
+ echo '<label><input type="radio" name="autoformat" value="excerpt"' . checked( $this->subscribe2_options['autoformat'], 'excerpt', false ) . ' /> ';
400
+ echo __( 'Plain Text - Excerpt', 'subscribe2' ) . '</label><br /><br />';
401
+ echo __( 'Registered Users have the option to auto-subscribe to new categories', 'subscribe2' ) . ': <br />' . "\r\n";
402
+ echo '<label><input type="radio" name="show_autosub" value="yes"' . checked( $this->subscribe2_options['show_autosub'], 'yes', false ) . ' /> ';
403
+ echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
404
+ echo '<label><input type="radio" name="show_autosub" value="no"' . checked( $this->subscribe2_options['show_autosub'], 'no', false ) . ' /> ';
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";
418
+ echo '<label><input type="radio" name="comment_subs" value="before"' . checked( $this->subscribe2_options['comment_subs'], 'before', false ) . ' /> ';
419
+ echo __( 'Before the Comment Submit button', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
420
+ echo '<label><input type="radio" name="comment_subs" value="after"' . checked( $this->subscribe2_options['comment_subs'], 'after', false ) . ' /> ';
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 ) . ' /> ';
434
+ echo __( 'Yes', 'subscribe2' ) . '</label>&nbsp;&nbsp;';
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
447
+ echo __( 'Set default Subscribe2 page as', 'subscribe2' ) . ': ';
448
+ echo '<select name="s2page">' . "\r\n";
449
+ echo '<option value="0">' . __( 'Select a page', 'subscribe2' ) . '</option>' . "\r\n";
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";
456
+
457
+ // show QuickTag button
458
+ echo '<label><input type="checkbox" name="show_button" value="1"' . checked( $this->subscribe2_options['show_button'], '1', false ) . ' /> ';
459
+ echo __( 'Show the Subscribe2 button on the Write toolbar?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
460
+
461
+ // enable popup style form
462
+ echo '<label><input type="checkbox" name="ajax" value="1"' . checked( $this->subscribe2_options['ajax'], '1', false ) . ' /> ';
463
+ echo __( 'Enable popup style subscription form?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
464
+
465
+ // show Widget
466
+ echo '<label><input type="checkbox" name="widget" value="1"' . checked( $this->subscribe2_options['widget'], '1', false ) . ' /> ';
467
+ echo __( 'Enable Subscribe2 Widget?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
468
+
469
+ // show Counter Widget
470
+ echo '<label><input type="checkbox" name="counterwidget" value="1"' . checked( $this->subscribe2_options['counterwidget'], '1', false ) . ' /> ';
471
+ echo __( 'Enable Subscribe2 Counter Widget?', 'subscribe2' ) . '</label><br /><br />' . "\r\n";
472
+
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
503
  echo '<p class="submit" style="text-align: center"><input type="submit" class="button-primary" name="submit" value="' . __( 'Submit', 'subscribe2' ) . '" /></p>';
504
 
505
  if ( 'misc' === $current_tab ) {
506
+ // reset
507
+ echo '<h3>' . __( 'Reset to Default Settings', 'subscribe2' ) . '</h3>' . "\r\n";
508
+ echo '<p>' . __( 'Use this to reset all options to their defaults. This <strong><em>will not</em></strong> modify your list of subscribers.', 'subscribe2' ) . '</p>' . "\r\n";
509
+ echo '<p class="submit" style="text-align: center">';
510
+ echo '<input type="submit" id="deletepost" name="reset" value="' . __( 'RESET', 'subscribe2' ) .
511
+ '" /></p>';
512
  }
513
  echo '</form></div>' . "\r\n";
514
 
515
  require ABSPATH . 'wp-admin/admin-footer.php';
516
  // just to be sure
517
+ die;
classes/class-s2-admin.php CHANGED
@@ -1,1117 +1,1155 @@
1
  <?php
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' );
11
- add_action( "admin_print_scripts-$s2user", array( &$this, 'checkbox_form_js' ) );
12
- add_action( "admin_print_styles-$s2user", array( &$this, 'user_admin_css' ) );
13
- add_action( 'load-' . $s2user, array( &$this, 'user_help' ) );
14
-
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' ) );
24
- add_action( "admin_print_scripts-$s2settings", array( &$this, 'option_form_js' ) );
25
- add_action( "admin_print_scripts-$s2settings", array( &$this, 'dismiss_js' ) );
26
- add_filter( 'plugin_row_meta', array( &$this, 'plugin_links' ), 10, 2 );
27
- add_action( 'load-' . $s2settings, array( &$this, 'settings_help' ) );
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', true );
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', true );
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.12.1/themes/smoothness/jquery-ui.css', array(), '1.12.1' );
209
- wp_register_script( 's2_date_time', S2URL . 'include/s2-date-time' . $this->script_debug . '.js', array( 'jquery-ui-datepicker' ), '1.1', true );
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', true );
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' ), true ) && ! 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' ) );
309
- add_filter( 'mce_buttons', array( &$this, 'mce_button' ) );
310
- } else {
311
- wp_enqueue_script( 'subscribe2_button', S2URL . 'include/s2-button' . $this->script_debug . '.js', array( 'quicktags' ), '2.0', true );
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 {
322
- $path = S2URL . 'tinymce/editor-plugin4' . $this->script_debug . '.js';
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', true );
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
- add_meta_box(
377
- 'subscribe2-preview',
378
- __( 'Subscribe2 Preview', 'subscribe2' ),
379
- array( &$this, 's2_preview_meta' ),
380
- $s2_post_type,
381
- 'side',
382
- 'default',
383
- array(
384
- '__block_editor_compatible_meta_box' => false,
385
- )
386
- );
387
- }
388
- }
389
-
390
- /**
391
- * Meta override box code
392
- */
393
- public function s2_override_meta() {
394
- global $post_ID;
395
- $s2mail = get_post_meta( $post_ID, '_s2mail', true );
396
- echo '<input type="hidden" name="s2meta_nonce" id="s2meta_nonce" value="' . wp_create_nonce( wp_hash( plugin_basename( __FILE__ ) ) ) . '" />';
397
- echo __( 'Check here to disable sending of an email notification for this post/page', 'subscribe2' );
398
- echo '&nbsp;&nbsp;<input type="checkbox" name="s2_meta_field" value="no"';
399
- if ( 'no' === $s2mail || ( '1' === $this->subscribe2_options['s2meta_default'] && '' === $s2mail ) ) {
400
- echo ' checked="checked"';
401
- }
402
- echo ' />';
403
- }
404
-
405
- /**
406
- * Meta override box form handler
407
- */
408
- public function s2_meta_handler( $post_id ) {
409
- if ( ! isset( $_POST['s2meta_nonce'] ) || ! wp_verify_nonce( $_POST['s2meta_nonce'], wp_hash( plugin_basename( __FILE__ ) ) ) ) {
410
- return $post_id;
411
- }
412
-
413
- if ( 'page' === $_POST['post_type'] ) {
414
- if ( ! current_user_can( 'edit_page', $post_id ) ) {
415
- return $post_id;
416
- }
417
- } else {
418
- if ( ! current_user_can( 'edit_post', $post_id ) ) {
419
- return $post_id;
420
- }
421
- }
422
-
423
- if ( isset( $_POST['s2_meta_field'] ) && 'no' === $_POST['s2_meta_field'] ) {
424
- update_post_meta( $post_id, '_s2mail', $_POST['s2_meta_field'] );
425
- } else {
426
- update_post_meta( $post_id, '_s2mail', 'yes' );
427
- }
428
- }
429
-
430
- /**
431
- * Meta preview box code
432
- */
433
- public function s2_preview_meta() {
434
- echo '<p>' . __( 'Send preview email of this post to currently logged in user:', 'subscribe2' ) . '</p>' . "\r\n";
435
- echo '<input class="button" name="s2_preview" type="submit" value="' . __( 'Send Preview', 'subscribe2' ) . '" />' . "\r\n";
436
- }
437
-
438
- /**
439
- * Meta preview box handler
440
- */
441
- public function s2_preview_handler() {
442
- if ( isset( $_POST['s2_preview'] ) ) {
443
- global $post, $current_user;
444
- $this->publish( $post, $current_user->user_email );
445
- }
446
- }
447
-
448
- /* ===== WordPress menu helper functions ===== */
449
- /**
450
- * Collects the signup date for all public subscribers
451
- */
452
- public function signup_date( $email = '' ) {
453
- if ( '' === $email ) {
454
- return false;
455
- }
456
-
457
- global $wpdb;
458
- if ( ! empty( $this->signup_dates ) ) {
459
- return $this->signup_dates[ $email ];
460
- } else {
461
- $results = $wpdb->get_results( "SELECT email, date FROM $wpdb->subscribe2", ARRAY_N );
462
- foreach ( $results as $result ) {
463
- $this->signup_dates[ $result[0] ] = $result[1];
464
- }
465
- return $this->signup_dates[ $email ];
466
- }
467
- }
468
-
469
- /**
470
- * Collects the signup time for all public subscribers
471
- */
472
- public function signup_time( $email = '' ) {
473
- if ( '' === $email ) {
474
- return false;
475
- }
476
-
477
- global $wpdb;
478
- if ( ! empty( $this->signup_times ) ) {
479
- return $this->signup_times[ $email ];
480
- } else {
481
- $results = $wpdb->get_results( "SELECT email, time FROM $wpdb->subscribe2", ARRAY_N );
482
- foreach ( $results as $result ) {
483
- $this->signup_times[ $result[0] ] = $result[1];
484
- }
485
- return $this->signup_times[ $email ];
486
- }
487
- }
488
-
489
- /**
490
- * Collects the ip address for all public subscribers
491
- */
492
- public function signup_ip( $email = '' ) {
493
- if ( '' === $email ) {
494
- return false;
495
- }
496
-
497
- global $wpdb;
498
- if ( ! empty( $this->signup_ips ) ) {
499
- return $this->signup_ips[ $email ];
500
- } else {
501
- $results = $wpdb->get_results( "SELECT email, ip FROM $wpdb->subscribe2", ARRAY_N );
502
- foreach ( $results as $result ) {
503
- $this->signup_ips[ $result[0] ] = $result[1];
504
- }
505
- return $this->signup_ips[ $email ];
506
- }
507
- }
508
-
509
- /**
510
- * Export subscriber emails and other details to CSV
511
- */
512
- public function prepare_export( $subscribers ) {
513
- if ( empty( $subscribers ) ) {
514
- return;
515
- }
516
- $subscribers = explode( ",\r\n", $subscribers );
517
- natcasesort( $subscribers );
518
-
519
- $exportcsv = _x( 'User Email,User Type,User Name,Confirm Date,IP', 'Comma Separated Column Header names for CSV Export', 'subscribe2' );
520
- $all_cats = $this->all_cats( false, 'ID' );
521
-
522
- foreach ( $all_cats as $cat ) {
523
- $exportcsv .= ',' . html_entity_decode( $cat->cat_name, ENT_QUOTES );
524
- $cat_ids[] = $cat->term_id;
525
- }
526
- $exportcsv .= "\r\n";
527
-
528
- foreach ( $subscribers as $subscriber ) {
529
- if ( $this->is_registered( $subscriber ) ) {
530
- $user_id = $this->get_user_id( $subscriber );
531
- $user_info = get_userdata( $user_id );
532
-
533
- $cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
534
- $subscribed_cats = '';
535
- foreach ( $cat_ids as $cat ) {
536
- ( in_array( $cat, $cats, true ) ) ? $subscribed_cats .= ',Yes' : $subscribed_cats .= ',No';
537
- }
538
-
539
- $exportcsv .= $subscriber . ',';
540
- $exportcsv .= __( 'Registered User', 'subscribe2' );
541
- $exportcsv .= ',' . $user_info->display_name;
542
- $exportcsv .= ',,' . $subscribed_cats . "\r\n";
543
- } else {
544
- if ( '1' === $this->is_public( $subscriber ) ) {
545
- $exportcsv .= $subscriber . ',' . __( 'Confirmed Public Subscriber', 'subscribe2' ) . ',,' . $this->signup_date( $subscriber ) . ',' . $this->signup_ip( $subscriber ) . "\r\n";
546
- } elseif ( '0' === $this->is_public( $subscriber ) ) {
547
- $exportcsv .= $subscriber . ',' . __( 'Unconfirmed Public Subscriber', 'subscribe2' ) . ',,' . $this->signup_date( $subscriber ) . ',' . $this->signup_ip( $subscriber ) . "\r\n";
548
- }
549
- }
550
- }
551
-
552
- return $exportcsv;
553
- }
554
-
555
- /**
556
- * Display a table of post formats supported by the currently active theme
557
- */
558
- public function display_format_form( $formats, $selected = array() ) {
559
- $half = ( count( $formats[0] ) / 2 );
560
- $i = 0;
561
- $j = 0;
562
- echo '<table style="width: 100%; border-collapse: separate; border-spacing: 2px; *border-collapse: expression(\'separate\', cellSpacing = \'2px\');" class="editform">' . "\r\n";
563
- echo '<tr><td style="text-align: left;" colspan="2">' . "\r\n";
564
- echo '<label><input type="checkbox" name="checkall" value="checkall_format" /> ' . __( 'Select / Unselect All', 'subscribe2' ) . '</label>' . "\r\n";
565
- echo '</td></tr>' . "\r\n";
566
- echo '<tr style="vertical-align: top;"><td style="width: 50%; text-align: left">' . "\r\n";
567
- foreach ( $formats[0] as $format ) {
568
- if ( $i >= $half && 0 === $j ) {
569
- echo '</td><td style="width: 50%; text-align: left">' . "\r\n";
570
- $j++;
571
- }
572
-
573
- if ( 0 === $j ) {
574
- echo '<label><input class="checkall_format" type="checkbox" name="format[]" value="' . $format . '"';
575
- if ( in_array( $format, $selected, true ) ) {
576
- echo ' checked="checked"';
577
- }
578
- echo ' /> ' . ucwords( $format ) . '</label><br />' . "\r\n";
579
- } else {
580
- echo '<label><input class="checkall_format" type="checkbox" name="format[]" value="' . $format . '"';
581
- if ( in_array( $format, $selected, true ) ) {
582
- echo ' checked="checked"';
583
- }
584
- echo ' /> ' . ucwords( $format ) . '</label><br />' . "\r\n";
585
- }
586
- $i++;
587
- }
588
- echo '</td></tr>' . "\r\n";
589
- echo '</table>' . "\r\n";
590
- }
591
-
592
- /**
593
- * Display a drop-down form to select subscribers
594
- * $selected is the option to select
595
- * $submit is the text to use on the Submit button
596
- */
597
- public function display_subscriber_dropdown( $selected = 'registered', $submit = '', $exclude = array() ) {
598
- global $wpdb;
599
-
600
- $who = array(
601
- 'all' => __( 'All Users and Subscribers', 'subscribe2' ),
602
- 'public' => __( 'Public Subscribers', 'subscribe2' ),
603
- 'confirmed' => ' &nbsp;&nbsp;' . __( 'Confirmed', 'subscribe2' ),
604
- 'unconfirmed' => ' &nbsp;&nbsp;' . __( 'Unconfirmed', 'subscribe2' ),
605
- 'all_users' => __( 'All Registered Users', 'subscribe2' ),
606
- 'registered' => __( 'Registered Subscribers', 'subscribe2' ),
607
- );
608
-
609
- $all_cats = $this->all_cats( false );
610
-
611
- // count the number of subscribers
612
- $count['confirmed'] = $wpdb->get_var( "SELECT COUNT(id) FROM $wpdb->subscribe2 WHERE active='1'" );
613
- $count['unconfirmed'] = $wpdb->get_var( "SELECT COUNT(id) FROM $wpdb->subscribe2 WHERE active='0'" );
614
- if ( in_array( 'unconfirmed', $exclude, true ) ) {
615
- $count['public'] = $count['confirmed'];
616
- } elseif ( in_array( 'confirmed', $exclude, true ) ) {
617
- $count['public'] = $count['unconfirmed'];
618
- } else {
619
- $count['public'] = ( $count['confirmed'] + $count['unconfirmed'] );
620
- }
621
- if ( $this->s2_mu ) {
622
- $count['all_users'] = $wpdb->get_var( "SELECT COUNT(meta_key) FROM $wpdb->usermeta WHERE meta_key='" . $wpdb->prefix . "capabilities'" );
623
- } else {
624
- $count['all_users'] = $wpdb->get_var( "SELECT COUNT(ID) FROM $wpdb->users" );
625
- }
626
- if ( $this->s2_mu ) {
627
- $count['registered'] = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(b.meta_key) FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b ON a.user_id = b.user_id WHERE a.meta_key='" . $wpdb->prefix . "capabilities' AND b.meta_key=%s AND b.meta_value <> ''", $this->get_usermeta_keyname( 's2_subscribed' ) ) );
628
- } else {
629
- $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' ) ) );
630
- }
631
- $count['all'] = ( $count['confirmed'] + $count['unconfirmed'] + $count['all_users'] );
632
- // get subscribers to individual categories but only if we are using per-post notifications
633
- if ( 'never' === $this->subscribe2_options['email_freq'] ) {
634
- $compulsory = explode( ',', $this->subscribe2_options['compulsory'] );
635
- if ( $this->s2_mu ) {
636
- foreach ( $all_cats as $cat ) {
637
- if ( in_array( $cat->term_id, $compulsory, true ) ) {
638
- $count[ $cat->name ] = $count['all_users'];
639
- } else {
640
- $count[ $cat->name ] = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(a.meta_key) FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b ON a.user_id = b.user_id WHERE a.meta_key='" . $wpdb->prefix . "capabilities' AND b.meta_key=%s", $this->get_usermeta_keyname( 's2_cat' ) . $cat->term_id ) );
641
- }
642
- }
643
- } else {
644
- foreach ( $all_cats as $cat ) {
645
- if ( in_array( $cat->term_id, $compulsory, true ) ) {
646
- $count[ $cat->name ] = $count['all_users'];
647
- } else {
648
- $count[ $cat->name ] = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(meta_value) FROM $wpdb->usermeta WHERE meta_key=%s", $this->get_usermeta_keyname( 's2_cat' ) . $cat->term_id ) );
649
- }
650
- }
651
- }
652
- }
653
-
654
- echo '<select name="what">' . "\r\n";
655
- foreach ( $who as $whom => $display ) {
656
- if ( in_array( $whom, $exclude, true ) ) {
657
- continue;
658
- }
659
-
660
- echo '<option value="' . $whom . '"';
661
- if ( $whom === $selected ) {
662
- echo ' selected="selected" ';
663
- }
664
- echo '>' . $display . ' (' . ( $count[ $whom ] ) . ')</option>' . "\r\n";
665
- }
666
-
667
- if ( $count['registered'] > 0 && 'never' === $this->subscribe2_options['email_freq'] ) {
668
- foreach ( $all_cats as $cat ) {
669
- if ( in_array( $cat->term_id, $exclude, true ) ) {
670
- continue;
671
- }
672
- echo '<option value="' . $cat->term_id . '"';
673
- if ( $cat->term_id === $selected ) {
674
- echo ' selected="selected" ';
675
- }
676
- echo '> &nbsp;&nbsp;' . $cat->name . '&nbsp;(' . $count[ $cat->name ] . ') </option>' . "\r\n";
677
- }
678
- }
679
- echo '</select>';
680
- if ( false !== $submit ) {
681
- echo '&nbsp;<input type="submit" class="button-secondary" value="' . $submit . '" />' . "\r\n";
682
- }
683
- }
684
-
685
- /**
686
- * Display a drop down list of administrator level users and
687
- * optionally include a choice for Post Author
688
- */
689
- public function admin_dropdown( $inc_author = false ) {
690
- global $wpdb;
691
-
692
- $args = array(
693
- 'fields' => array(
694
- 'ID',
695
- 'display_name',
696
- ),
697
- 'role' => 'administrator',
698
- );
699
-
700
- $wp_user_query = get_users( $args );
701
- if ( ! empty( $wp_user_query ) ) {
702
- foreach ( $wp_user_query as $user ) {
703
- $admins[] = $user;
704
- }
705
- } else {
706
- $admins = array();
707
- }
708
-
709
- if ( $inc_author ) {
710
- $author[] = (object) array(
711
- 'ID' => 'author',
712
- 'display_name' => __( 'Post Author', 'subscribe2' ),
713
- );
714
- $author[] = (object) array(
715
- 'ID' => 'blogname',
716
- 'display_name' => html_entity_decode( get_option( 'blogname' ), ENT_QUOTES ),
717
- );
718
- $admins = array_merge( $author, $admins );
719
- }
720
-
721
- echo '<select name="sender">' . "\r\n";
722
- foreach ( $admins as $admin ) {
723
- echo '<option value="' . $admin->ID . '"';
724
- if ( $admin->ID === $this->subscribe2_options['sender'] ) {
725
- echo ' selected="selected"';
726
- }
727
- echo '>' . $admin->display_name . '</option>' . "\r\n";
728
- }
729
- echo '</select>' . "\r\n";
730
- }
731
-
732
- /**
733
- * Display a dropdown of choices for digest email frequency
734
- * and give user details of timings when event is scheduled
735
- */
736
- public function display_digest_choices() {
737
- global $wpdb;
738
- $cron_file = ABSPATH . 'wp-cron.php';
739
- if ( ! is_readable( $cron_file ) ) {
740
- 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";
741
- }
742
- $scheduled_time = wp_next_scheduled( 's2_digest_cron' );
743
- $offset = get_option( 'gmt_offset' ) * 60 * 60;
744
- $schedule = (array) wp_get_schedules();
745
- $schedule = array_merge(
746
- array(
747
- 'never' => array(
748
- 'interval' => 0,
749
- 'display' => __( 'For each Post', 'subscribe2' ),
750
- ),
751
- ),
752
- $schedule
753
- );
754
-
755
- $sort = array();
756
- foreach ( (array) $schedule as $key => $value ) {
757
- $sort[ $key ] = $value['interval'];
758
- }
759
- asort( $sort );
760
- $schedule_sorted = array();
761
- foreach ( $sort as $key => $value ) {
762
- $schedule_sorted[ $key ] = $schedule[ $key ];
763
- }
764
- foreach ( $schedule_sorted as $key => $value ) {
765
- echo '<label><input type="radio" name="email_freq" value="' . $key . '"' . checked( $this->subscribe2_options['email_freq'], $key, false ) . ' />';
766
- echo ' ' . $value['display'] . '</label><br />' . "\r\n";
767
- }
768
- if ( $scheduled_time ) {
769
- $date_format = get_option( 'date_format' );
770
- $time_format = get_option( 'time_format' );
771
- echo '<p>' . __( 'Current UTC time is', 'subscribe2' ) . ': ' . "\r\n";
772
- echo '<strong>' . date_i18n( $date_format . ' @ ' . $time_format, false, 'gmt' ) . '</strong></p>' . "\r\n";
773
- echo '<p>' . __( 'Current blog time is', 'subscribe2' ) . ': ' . "\r\n";
774
- echo '<strong>' . date_i18n( $date_format . ' @ ' . $time_format ) . '</strong></p>' . "\r\n";
775
- echo '<p>' . __( 'Next email notification will be sent when your blog time is after', 'subscribe2' ) . ': ' . "\r\n";
776
- echo '<input type="hidden" id="jscrondate" value="' . date_i18n( $date_format, $scheduled_time + $offset ) . '" />';
777
- echo '<input type="hidden" id="jscrontime" value="' . date_i18n( $time_format, $scheduled_time + $offset ) . '" />';
778
- echo '<span id="s2cron_1"><span id="s2crondate" style="background-color: #FFFBCC">' . date_i18n( $date_format, $scheduled_time + $offset ) . '</span>';
779
- echo ' @ <span id="s2crontime" style="background-color: #FFFBCC">' . date_i18n( $time_format, $scheduled_time + $offset ) . '</span> ';
780
- echo '<a href="#" onclick="s2Show(\'cron\'); return false;">' . __( 'Edit', 'subscribe2' ) . '</a></span>' . "\r\n";
781
- echo '<span id="s2cron_2">' . "\r\n";
782
- echo '<input id="s2datepicker" name="crondate" value="' . date_i18n( $date_format, $scheduled_time + $offset ) . '">' . "\r\n";
783
- $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' );
784
- $current_hour = intval( date_i18n( 'G', $scheduled_time + $offset ) );
785
- echo '<select name="crontime">' . "\r\n";
786
- foreach ( $hours as $key => $value ) {
787
- echo '<option value="' . $key . '"';
788
- if ( ! empty( $scheduled_time ) && $key === $current_hour ) {
789
- echo ' selected="selected"';
790
- }
791
- echo '>' . $value . '</option>' . "\r\n";
792
- }
793
- echo '</select>' . "\r\n";
794
- echo '<a href="#" onclick="s2CronUpdate(\'cron\'); return false;">' . __( 'Update', 'subscribe2' ) . '</a>' . "\r\n";
795
- echo '<a href="#" onclick="s2CronRevert(\'cron\'); return false;">' . __( 'Revert', 'subscribe2' ) . '</a></span>' . "\r\n";
796
- if ( ! empty( $this->subscribe2_options['last_s2cron'] ) ) {
797
- echo '<p>' . __( 'Attempt to resend the last Digest Notification email', 'subscribe2' ) . ': ';
798
- echo '<input type="submit" class="button-secondary" name="resend" value="' . __( 'Resend Digest', 'subscribe2' ) . '" /></p>' . "\r\n";
799
- }
800
- } else {
801
- echo '<br />';
802
- }
803
- }
804
-
805
- /**
806
- * Create and display a dropdown list of pages
807
- */
808
- public function pages_dropdown( $s2page ) {
809
- $pages = get_pages();
810
- if ( empty( $pages ) ) {
811
- return;
812
- }
813
-
814
- $option = '';
815
- foreach ( $pages as $page ) {
816
- $option .= '<option value="' . $page->ID . '"';
817
- if ( $page->ID === $s2page ) {
818
- $option .= ' selected="selected"';
819
- }
820
- $option .= '>';
821
- $parents = array_reverse( get_ancestors( $page->ID, 'page' ) );
822
- if ( $parents ) {
823
- foreach ( $parents as $parent ) {
824
- $option .= get_the_title( $parent ) . ' &raquo; ';
825
- }
826
- }
827
- $option .= $page->post_title . '</option>' . "\r\n";
828
- }
829
-
830
- echo $option;
831
- }
832
-
833
- /**
834
- * Subscribe all registered users to category selected on Admin Manage Page
835
- */
836
- public function subscribe_registered_users( $emails = '', $cats = array() ) {
837
- if ( '' === $emails || '' === $cats ) {
838
- return false;
839
- }
840
- global $wpdb;
841
-
842
- $useremails = explode( ",\r\n", $emails );
843
- $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
844
-
845
- $user_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // phpcs:ignore WordPress.DB.PreparedSQL
846
-
847
- foreach ( $user_ids as $user_id ) {
848
- $old_cats = get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true );
849
- if ( ! empty( $old_cats ) ) {
850
- $old_cats = explode( ',', $old_cats );
851
- $newcats = array_unique( array_merge( $cats, $old_cats ) );
852
- } else {
853
- $newcats = $cats;
854
- }
855
- if ( ! empty( $newcats ) && $newcats !== $old_cats ) {
856
- // add subscription to these cat IDs
857
- foreach ( $newcats as $id ) {
858
- update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id, $id );
859
- }
860
- update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
861
- }
862
- unset( $newcats );
863
- }
864
- }
865
-
866
- /**
867
- * Unsubscribe all registered users to category selected on Admin Manage Page
868
- */
869
- public function unsubscribe_registered_users( $emails = '', $cats = array() ) {
870
- if ( '' === $emails || '' === $cats ) {
871
- return false;
872
- }
873
- global $wpdb;
874
-
875
- $useremails = explode( ",\r\n", $emails );
876
- $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
877
-
878
- $user_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // phpcs:ignore WordPress.DB.PreparedSQL
879
-
880
- foreach ( $user_ids as $user_id ) {
881
- $old_cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
882
- $remain = array_diff( $old_cats, $cats );
883
- if ( ! empty( $remain ) && $remain !== $old_cats ) {
884
- // remove subscription to these cat IDs and update s2_subscribed
885
- foreach ( $cats as $id ) {
886
- delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id );
887
- }
888
- update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $remain ) );
889
- } else {
890
- // remove subscription to these cat IDs and update s2_subscribed to ''
891
- foreach ( $cats as $id ) {
892
- delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id );
893
- }
894
- delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ) );
895
- }
896
- unset( $remain );
897
- }
898
- }
899
-
900
- /**
901
- * Handles bulk changes to email format for Registered Subscribers
902
- */
903
- public function format_change( $emails, $format ) {
904
- if ( empty( $format ) ) {
905
- return;
906
- }
907
-
908
- global $wpdb;
909
- $useremails = explode( ",\r\n", $emails );
910
- $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
911
- $ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // phpcs:ignore WordPress.DB.PreparedSQL
912
- $ids = implode( ',', array_map( array( $this, 'prepare_in_data' ), $ids ) );
913
- $sql = "UPDATE $wpdb->usermeta SET meta_value='{$format}' WHERE meta_key='" . $this->get_usermeta_keyname( 's2_format' ) . "' AND user_id IN ($ids)";
914
- $wpdb->query( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL
915
- }
916
-
917
- /**
918
- * Handles bulk update to digest preferences
919
- */
920
- public function digest_change( $emails, $digest ) {
921
- if ( empty( $digest ) ) {
922
- return;
923
- }
924
-
925
- global $wpdb;
926
- $useremails = explode( ",\r\n", $emails );
927
- $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
928
-
929
- $user_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // phpcs:ignore WordPress.DB.PreparedSQL
930
-
931
- if ( 'digest' === $digest ) {
932
- $exclude = explode( ',', $this->subscribe2_options['exclude'] );
933
- if ( ! empty( $exclude ) ) {
934
- $all_cats = $this->all_cats( true, 'ID' );
935
- } else {
936
- $all_cats = $this->all_cats( false, 'ID' );
937
- }
938
-
939
- $cats_string = '';
940
- foreach ( $all_cats as $cat ) {
941
- ( '' === $cats_string ) ? $cats_string = "$cat->term_id" : $cats_string .= ",$cat->term_id";
942
- }
943
-
944
- foreach ( $user_ids as $user_id ) {
945
- foreach ( $all_cats as $cat ) {
946
- update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $cat->term_id, $cat->term_id );
947
- }
948
- update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), $cats_string );
949
- }
950
- } elseif ( '-1' === $digest ) {
951
- foreach ( $user_ids as $user_id ) {
952
- $cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
953
- foreach ( $cats as $id ) {
954
- delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id );
955
- }
956
- delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ) );
957
- }
958
- }
959
- }
960
-
961
- /* ===== functions to handle addition and removal of WordPress categories ===== */
962
- /**
963
- * Autosubscribe registered users to newly created categories
964
- * if registered user has selected this option
965
- */
966
- public function new_category( $new_category = '' ) {
967
- if ( 'no' === $this->subscribe2_options['show_autosub'] ) {
968
- return;
969
- }
970
-
971
- global $wpdb;
972
- if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
973
- // if we are doing digests add new categories to users who are currently opted in
974
- $user_ids = $wpdb->get_col(
975
- $wpdb->prepare(
976
- "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key=%s AND meta_value<>''",
977
- $this->get_usermeta_keyname( 's2_subscribed' )
978
- )
979
- );
980
- foreach ( $user_ids as $user_id ) {
981
- $old_cats = get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true );
982
- $old_cats = explode( ',', $old_cats );
983
- $newcats = array_merge( $old_cats, (array) $new_category );
984
- update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $new_category, $new_category );
985
- update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
986
- }
987
- return;
988
- }
989
-
990
- if ( 'yes' === $this->subscribe2_options['show_autosub'] ) {
991
- if ( $this->s2_mu ) {
992
- $user_ids = $wpdb->get_col(
993
- $wpdb->prepare(
994
- "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",
995
- $this->get_usermeta_keyname( 's2_autosub' ),
996
- $this->get_usermeta_keyname( 's2_subscribed' )
997
- )
998
- );
999
- } else {
1000
- $user_ids = $wpdb->get_col(
1001
- $wpdb->prepare(
1002
- "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE $wpdb->usermeta.meta_key=%s AND $wpdb->usermeta.meta_value='yes'",
1003
- $this->get_usermeta_keyname( 's2_autosub' )
1004
- )
1005
- );
1006
- }
1007
- if ( '' === $user_ids ) {
1008
- return;
1009
- }
1010
-
1011
- foreach ( $user_ids as $user_id ) {
1012
- $old_cats = get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true );
1013
- if ( empty( $old_cats ) ) {
1014
- $newcats = (array) $new_category;
1015
- } else {
1016
- $old_cats = explode( ',', $old_cats );
1017
- $newcats = array_merge( $old_cats, (array) $new_category );
1018
- }
1019
- // add subscription to these cat IDs
1020
- update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $new_category, $new_category );
1021
- update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
1022
- }
1023
- } elseif ( 'exclude' === $this->subscribe2_options['show_autosub'] ) {
1024
- $excluded_cats = explode( ',', $this->subscribe2_options['exclude'] );
1025
- $excluded_cats[] = $new_category;
1026
- $this->subscribe2_options['exclude'] = implode( ',', $excluded_cats );
1027
- update_option( 'subscribe2_options', $this->subscribe2_options );
1028
- }
1029
- }
1030
-
1031
- /**
1032
- * Automatically delete subscriptions to a category when it is deleted
1033
- */
1034
- public function delete_category( $deleted_category = '' ) {
1035
- global $wpdb;
1036
-
1037
- if ( $this->s2_mu ) {
1038
- $user_ids = $wpdb->get_col(
1039
- $wpdb->prepare(
1040
- "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",
1041
- $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category,
1042
- $this->get_usermeta_keyname( 's2_subscribed' )
1043
- )
1044
- );
1045
- } else {
1046
- $user_ids = $wpdb->get_col(
1047
- $wpdb->prepare(
1048
- "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key=%s",
1049
- $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category
1050
- )
1051
- );
1052
- }
1053
- if ( '' === $user_ids ) {
1054
- return;
1055
- }
1056
-
1057
- foreach ( $user_ids as $user_id ) {
1058
- $old_cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
1059
- if ( ! is_array( $old_cats ) ) {
1060
- $old_cats = array( $old_cats );
1061
- }
1062
- // add subscription to these cat IDs
1063
- delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category );
1064
- $remain = array_diff( $old_cats, (array) $deleted_category );
1065
- update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $remain ) );
1066
- }
1067
- }
1068
-
1069
- /* ===== functions to show & handle one-click subscription ===== */
1070
- /**
1071
- * Show form for one-click subscription on user profile page
1072
- */
1073
- public function one_click_profile_form( $user ) {
1074
- echo '<h3>' . __( 'Email subscription', 'subscribe2' ) . '</h3>' . "\r\n";
1075
- echo '<table class="form-table">' . "\r\n";
1076
- echo '<tr><th scope="row">' . __( 'Subscribe / Unsubscribe', 'subscribe2' ) . '</th>' . "\r\n";
1077
- 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";
1078
- echo '<span class="description">' . __( 'Check if you want to receive email notification when new posts are published', 'subscribe2' ) . '</span>' . "\r\n";
1079
- echo '</td></tr></table>' . "\r\n";
1080
- }
1081
-
1082
- /**
1083
- * Handle submission from profile one-click subscription
1084
- */
1085
- public function one_click_profile_form_save( $user_id ) {
1086
- if ( ! current_user_can( 'edit_user', $user_id ) ) {
1087
- return false;
1088
- }
1089
-
1090
- if ( isset( $_POST['sub2-one-click-subscribe'] ) && 1 === $_POST['sub2-one-click-subscribe'] ) {
1091
- // Subscribe
1092
- $this->one_click_handler( $user_id, 'subscribe' );
1093
- } else {
1094
- // Unsubscribe
1095
- $this->one_click_handler( $user_id, 'unsubscribe' );
1096
- }
1097
- }
1098
-
1099
- /**
1100
- * Core function to hook the digest email preview to the action on the Settings page
1101
- */
1102
- public function digest_preview( $user_email = '' ) {
1103
- if ( false === $this->validate_email( $user_email ) ) {
1104
- return;
1105
- }
1106
- $this->subscribe2_cron( $user_email );
1107
- }
1108
-
1109
- /**
1110
- * Core function to hook the resent digest email to the action on the Settings page
1111
- */
1112
- public function digest_resend( $resend ) {
1113
- if ( 'resend' === $resend ) {
1114
- $this->subscribe2_cron( '', 'resend' );
1115
- }
1116
- }
1117
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
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' );
11
+ add_action( "admin_print_scripts-$s2user", array( &$this, 'checkbox_form_js' ) );
12
+ add_action( "admin_print_styles-$s2user", array( &$this, 'user_admin_css' ) );
13
+ add_action( 'load-' . $s2user, array( &$this, 'user_help' ) );
14
+
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' ) );
24
+ add_action( "admin_print_scripts-$s2settings", array( &$this, 'option_form_js' ) );
25
+ add_action( "admin_print_scripts-$s2settings", array( &$this, 'dismiss_js' ) );
26
+ add_filter( 'plugin_row_meta', array( &$this, 'plugin_links' ), 10, 2 );
27
+ add_action( 'load-' . $s2settings, array( &$this, 'settings_help' ) );
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', true );
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', true );
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.12.1/themes/smoothness/jquery-ui.css', array(), '1.12.1' );
209
+ wp_register_script( 's2_date_time', S2URL . 'include/s2-date-time' . $this->script_debug . '.js', array( 'jquery-ui-datepicker' ), '1.1', true );
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', true );
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' ), true ) && ! 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' ) );
309
+ add_filter( 'mce_buttons', array( &$this, 'mce_button' ) );
310
+ } else {
311
+ wp_enqueue_script( 'subscribe2_button', S2URL . 'include/s2-button' . $this->script_debug . '.js', array( 'quicktags' ), '2.0', true );
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 {
322
+ $path = S2URL . 'tinymce/editor-plugin4' . $this->script_debug . '.js';
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', true );
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
+ '__back_compat_meta_box' => true,
375
+ )
376
+ );
377
+ add_meta_box(
378
+ 'subscribe2-preview',
379
+ __( 'Subscribe2 Preview', 'subscribe2' ),
380
+ array( &$this, 's2_preview_meta' ),
381
+ $s2_post_type,
382
+ 'side',
383
+ 'default',
384
+ array(
385
+ '__block_editor_compatible_meta_box' => false,
386
+ '__back_compat_meta_box' => true,
387
+ )
388
+ );
389
+ add_meta_box(
390
+ 'subscribe2-resend',
391
+ __( 'Subscribe2 Resend', 'subscribe2' ),
392
+ array( &$this, 's2_resend_meta' ),
393
+ $s2_post_type,
394
+ 'side',
395
+ 'default',
396
+ array(
397
+ '__block_editor_compatible_meta_box' => false,
398
+ '__back_compat_meta_box' => true,
399
+ )
400
+ );
401
+ }
402
+ }
403
+
404
+ /**
405
+ * Meta override box code
406
+ */
407
+ public function s2_override_meta() {
408
+ global $post_ID;
409
+ $s2mail = get_post_meta( $post_ID, '_s2mail', true );
410
+ echo '<input type="hidden" name="s2meta_nonce" id="s2meta_nonce" value="' . wp_create_nonce( wp_hash( plugin_basename( __FILE__ ) ) ) . '" />';
411
+ echo __( 'Check here to disable sending of an email notification for this post/page', 'subscribe2' );
412
+ echo '&nbsp;&nbsp;<input type="checkbox" name="s2_meta_field" value="no"';
413
+ if ( 'no' === $s2mail || ( '1' === $this->subscribe2_options['s2meta_default'] && '' === $s2mail ) ) {
414
+ echo ' checked="checked"';
415
+ }
416
+ echo ' />';
417
+ }
418
+
419
+ /**
420
+ * Meta override box form handler
421
+ */
422
+ public function s2_meta_handler( $post_id ) {
423
+ if ( ! isset( $_POST['s2meta_nonce'] ) || ! wp_verify_nonce( $_POST['s2meta_nonce'], wp_hash( plugin_basename( __FILE__ ) ) ) ) {
424
+ return $post_id;
425
+ }
426
+
427
+ if ( 'page' === $_POST['post_type'] ) {
428
+ if ( ! current_user_can( 'edit_page', $post_id ) ) {
429
+ return $post_id;
430
+ }
431
+ } else {
432
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
433
+ return $post_id;
434
+ }
435
+ }
436
+
437
+ if ( isset( $_POST['s2_meta_field'] ) && 'no' === $_POST['s2_meta_field'] ) {
438
+ update_post_meta( $post_id, '_s2mail', $_POST['s2_meta_field'] );
439
+ } else {
440
+ update_post_meta( $post_id, '_s2mail', 'yes' );
441
+ }
442
+ }
443
+
444
+ /**
445
+ * Meta preview box code
446
+ */
447
+ public function s2_preview_meta() {
448
+ echo '<p>' . __( 'Send preview email of this post to currently logged in user:', 'subscribe2' ) . '</p>' . "\r\n";
449
+ echo '<input class="button" name="s2_preview" type="submit" value="' . __( 'Send Preview', 'subscribe2' ) . '" />' . "\r\n";
450
+ }
451
+
452
+ /**
453
+ * Meta preview box handler
454
+ */
455
+ public function s2_preview_handler() {
456
+ if ( isset( $_POST['s2_preview'] ) ) {
457
+ global $post, $current_user;
458
+ $this->publish( $post, $current_user->user_email );
459
+ }
460
+ }
461
+
462
+ /**
463
+ * Meta resend box code
464
+ */
465
+ public function s2_resend_meta() {
466
+ global $post;
467
+ if ( 'publish' === $post->post_status || ( 'private' === $post->post_status && 'yes' === $this->subscribe2_options['private'] ) ) {
468
+ echo '<p>' . __( 'Resend the notification email of this post to current subscribers:', 'subscribe2' ) . '</p>' . "\r\n";
469
+ echo '<input class="button" name="s2_resend" type="submit" value="' . __( 'Resend Notification', 'subscribe2' ) . '" />' . "\r\n";
470
+ } else {
471
+ echo '<p>' . __( 'This post has not been published yet or is a private post and Subscribe2 HTML is not configured to send notifications for priavte posts. Resending is not currently possible.', 'subscribe2' ) . '</p>' . "\r\n";
472
+ }
473
+ }
474
+
475
+ /**
476
+ * Meta resend box handler
477
+ */
478
+ public function s2_resend_handler() {
479
+ if ( isset( $_POST['s2_resend'] ) ) {
480
+ global $post;
481
+ $this->publish( $post );
482
+ }
483
+ }
484
+
485
+ /* ===== WordPress menu helper functions ===== */
486
+ /**
487
+ * Collects the signup date for all public subscribers
488
+ */
489
+ public function signup_date( $email = '' ) {
490
+ if ( '' === $email ) {
491
+ return false;
492
+ }
493
+
494
+ global $wpdb;
495
+ if ( ! empty( $this->signup_dates ) ) {
496
+ return $this->signup_dates[ $email ];
497
+ } else {
498
+ $results = $wpdb->get_results( "SELECT email, date FROM $wpdb->subscribe2", ARRAY_N );
499
+ foreach ( $results as $result ) {
500
+ $this->signup_dates[ $result[0] ] = $result[1];
501
+ }
502
+ return $this->signup_dates[ $email ];
503
+ }
504
+ }
505
+
506
+ /**
507
+ * Collects the signup time for all public subscribers
508
+ */
509
+ public function signup_time( $email = '' ) {
510
+ if ( '' === $email ) {
511
+ return false;
512
+ }
513
+
514
+ global $wpdb;
515
+ if ( ! empty( $this->signup_times ) ) {
516
+ return $this->signup_times[ $email ];
517
+ } else {
518
+ $results = $wpdb->get_results( "SELECT email, time FROM $wpdb->subscribe2", ARRAY_N );
519
+ foreach ( $results as $result ) {
520
+ $this->signup_times[ $result[0] ] = $result[1];
521
+ }
522
+ return $this->signup_times[ $email ];
523
+ }
524
+ }
525
+
526
+ /**
527
+ * Collects the ip address for all public subscribers
528
+ */
529
+ public function signup_ip( $email = '' ) {
530
+ if ( '' === $email ) {
531
+ return false;
532
+ }
533
+
534
+ global $wpdb;
535
+ if ( ! empty( $this->signup_ips ) ) {
536
+ return $this->signup_ips[ $email ];
537
+ } else {
538
+ $results = $wpdb->get_results( "SELECT email, ip FROM $wpdb->subscribe2", ARRAY_N );
539
+ foreach ( $results as $result ) {
540
+ $this->signup_ips[ $result[0] ] = $result[1];
541
+ }
542
+ return $this->signup_ips[ $email ];
543
+ }
544
+ }
545
+
546
+ /**
547
+ * Export subscriber emails and other details to CSV
548
+ */
549
+ public function prepare_export( $subscribers ) {
550
+ if ( empty( $subscribers ) ) {
551
+ return;
552
+ }
553
+ $subscribers = explode( ",\r\n", $subscribers );
554
+ natcasesort( $subscribers );
555
+
556
+ $exportcsv = _x( 'User Email,User Type,User Name,Confirm Date,IP', 'Comma Separated Column Header names for CSV Export', 'subscribe2' );
557
+ $all_cats = $this->all_cats( false, 'ID' );
558
+
559
+ foreach ( $all_cats as $cat ) {
560
+ $exportcsv .= ',' . html_entity_decode( $cat->cat_name, ENT_QUOTES );
561
+ $cat_ids[] = $cat->term_id;
562
+ }
563
+ $exportcsv .= "\r\n";
564
+
565
+ foreach ( $subscribers as $subscriber ) {
566
+ if ( $this->is_registered( $subscriber ) ) {
567
+ $user_id = $this->get_user_id( $subscriber );
568
+ $user_info = get_userdata( $user_id );
569
+
570
+ $cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
571
+ $subscribed_cats = '';
572
+ foreach ( $cat_ids as $cat ) {
573
+ ( in_array( (string) $cat, $cats, true ) ) ? $subscribed_cats .= ',Yes' : $subscribed_cats .= ',No';
574
+ }
575
+
576
+ $exportcsv .= $subscriber . ',';
577
+ $exportcsv .= __( 'Registered User', 'subscribe2' );
578
+ $exportcsv .= ',' . $user_info->display_name;
579
+ $exportcsv .= ',,' . $subscribed_cats . "\r\n";
580
+ } else {
581
+ if ( '1' === $this->is_public( $subscriber ) ) {
582
+ $exportcsv .= $subscriber . ',' . __( 'Confirmed Public Subscriber', 'subscribe2' ) . ',,' . $this->signup_date( $subscriber ) . ',' . $this->signup_ip( $subscriber ) . "\r\n";
583
+ } elseif ( '0' === $this->is_public( $subscriber ) ) {
584
+ $exportcsv .= $subscriber . ',' . __( 'Unconfirmed Public Subscriber', 'subscribe2' ) . ',,' . $this->signup_date( $subscriber ) . ',' . $this->signup_ip( $subscriber ) . "\r\n";
585
+ }
586
+ }
587
+ }
588
+
589
+ return $exportcsv;
590
+ }
591
+
592
+ /**
593
+ * Display a table of post formats supported by the currently active theme
594
+ */
595
+ public function display_format_form( $formats, $selected = array() ) {
596
+ $half = ( count( $formats[0] ) / 2 );
597
+ $i = 0;
598
+ $j = 0;
599
+ echo '<table style="width: 100%; border-collapse: separate; border-spacing: 2px; *border-collapse: expression(\'separate\', cellSpacing = \'2px\');" class="editform">' . "\r\n";
600
+ echo '<tr><td style="text-align: left;" colspan="2">' . "\r\n";
601
+ echo '<label><input type="checkbox" name="checkall" value="checkall_format" /> ' . __( 'Select / Unselect All', 'subscribe2' ) . '</label>' . "\r\n";
602
+ echo '</td></tr>' . "\r\n";
603
+ echo '<tr style="vertical-align: top;"><td style="width: 50%; text-align: left">' . "\r\n";
604
+ foreach ( $formats[0] as $format ) {
605
+ if ( $i >= $half && 0 === $j ) {
606
+ echo '</td><td style="width: 50%; text-align: left">' . "\r\n";
607
+ $j++;
608
+ }
609
+
610
+ if ( 0 === $j ) {
611
+ echo '<label><input class="checkall_format" type="checkbox" name="format[]" value="' . $format . '"';
612
+ if ( in_array( $format, $selected, true ) ) {
613
+ echo ' checked="checked"';
614
+ }
615
+ echo ' /> ' . ucwords( $format ) . '</label><br />' . "\r\n";
616
+ } else {
617
+ echo '<label><input class="checkall_format" type="checkbox" name="format[]" value="' . $format . '"';
618
+ if ( in_array( $format, $selected, true ) ) {
619
+ echo ' checked="checked"';
620
+ }
621
+ echo ' /> ' . ucwords( $format ) . '</label><br />' . "\r\n";
622
+ }
623
+ $i++;
624
+ }
625
+ echo '</td></tr>' . "\r\n";
626
+ echo '</table>' . "\r\n";
627
+ }
628
+
629
+ /**
630
+ * Display a drop-down form to select subscribers
631
+ * $selected is the option to select
632
+ * $submit is the text to use on the Submit button
633
+ */
634
+ public function display_subscriber_dropdown( $selected = 'registered', $submit = '', $exclude = array() ) {
635
+ global $wpdb, $current_tab;
636
+
637
+ $who = array(
638
+ 'all' => __( 'All Users and Subscribers', 'subscribe2' ),
639
+ 'public' => __( 'Public Subscribers', 'subscribe2' ),
640
+ 'confirmed' => ' &nbsp;&nbsp;' . __( 'Confirmed', 'subscribe2' ),
641
+ 'unconfirmed' => ' &nbsp;&nbsp;' . __( 'Unconfirmed', 'subscribe2' ),
642
+ 'all_users' => __( 'All Registered Users', 'subscribe2' ),
643
+ 'registered' => __( 'Registered Subscribers', 'subscribe2' ),
644
+ );
645
+
646
+ $all_cats = $this->all_cats( false );
647
+
648
+ // count the number of subscribers
649
+ $count['confirmed'] = $wpdb->get_var( "SELECT COUNT(id) FROM $wpdb->subscribe2 WHERE active='1'" );
650
+ $count['unconfirmed'] = $wpdb->get_var( "SELECT COUNT(id) FROM $wpdb->subscribe2 WHERE active='0'" );
651
+ if ( in_array( 'unconfirmed', $exclude, true ) ) {
652
+ $count['public'] = $count['confirmed'];
653
+ } elseif ( in_array( 'confirmed', $exclude, true ) ) {
654
+ $count['public'] = $count['unconfirmed'];
655
+ } else {
656
+ $count['public'] = ( $count['confirmed'] + $count['unconfirmed'] );
657
+ }
658
+ if ( $this->s2_mu ) {
659
+ $count['all_users'] = $wpdb->get_var( "SELECT COUNT(meta_key) FROM $wpdb->usermeta WHERE meta_key='" . $wpdb->prefix . "capabilities'" );
660
+ } else {
661
+ $count['all_users'] = $wpdb->get_var( "SELECT COUNT(ID) FROM $wpdb->users" );
662
+ }
663
+ if ( $this->s2_mu ) {
664
+ $count['registered'] = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(b.meta_key) FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b ON a.user_id = b.user_id WHERE a.meta_key='" . $wpdb->prefix . "capabilities' AND b.meta_key=%s AND b.meta_value <> ''", $this->get_usermeta_keyname( 's2_subscribed' ) ) );
665
+ } else {
666
+ $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' ) ) );
667
+ }
668
+ $count['all'] = ( $count['confirmed'] + $count['unconfirmed'] + $count['all_users'] );
669
+ // get subscribers to individual categories but only if we are using per-post notifications
670
+ if ( 'never' === $this->subscribe2_options['email_freq'] ) {
671
+ $compulsory = explode( ',', $this->subscribe2_options['compulsory'] );
672
+ if ( $this->s2_mu ) {
673
+ foreach ( $all_cats as $cat ) {
674
+ if ( in_array( (string) $cat->term_id, $compulsory, true ) ) {
675
+ $count[ $cat->name ] = $count['all_users'];
676
+ } else {
677
+ $count[ $cat->name ] = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(a.meta_key) FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b ON a.user_id = b.user_id WHERE a.meta_key='" . $wpdb->prefix . "capabilities' AND b.meta_key=%s", $this->get_usermeta_keyname( 's2_cat' ) . $cat->term_id ) );
678
+ }
679
+ }
680
+ } else {
681
+ foreach ( $all_cats as $cat ) {
682
+ if ( in_array( (string) $cat->term_id, $compulsory, true ) ) {
683
+ $count[ $cat->name ] = $count['all_users'];
684
+ } else {
685
+ $count[ $cat->name ] = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(meta_value) FROM $wpdb->usermeta WHERE meta_key=%s", $this->get_usermeta_keyname( 's2_cat' ) . $cat->term_id ) );
686
+ }
687
+ }
688
+ }
689
+ }
690
+
691
+ echo '<select name="what">' . "\r\n";
692
+ foreach ( $who as $whom => $display ) {
693
+ if ( in_array( $whom, $exclude, true ) ) {
694
+ continue;
695
+ }
696
+
697
+ echo '<option value="' . $whom . '"';
698
+ if ( $whom === $selected ) {
699
+ echo ' selected="selected" ';
700
+ }
701
+ echo '>' . $display . ' (' . ( $count[ $whom ] ) . ')</option>' . "\r\n";
702
+ }
703
+
704
+ if ( 'public' !== $current_tab && $count['registered'] > 0 && 'never' === $this->subscribe2_options['email_freq'] ) {
705
+ foreach ( $all_cats as $cat ) {
706
+ if ( in_array( (string) $cat->term_id, $exclude, true ) ) {
707
+ continue;
708
+ }
709
+ echo '<option value="' . $cat->term_id . '"';
710
+ if ( $cat->term_id === $selected ) {
711
+ echo ' selected="selected" ';
712
+ }
713
+ echo '> &nbsp;&nbsp;' . $cat->name . '&nbsp;(' . $count[ $cat->name ] . ') </option>' . "\r\n";
714
+ }
715
+ }
716
+
717
+ echo '</select>';
718
+ if ( false !== $submit ) {
719
+ echo '&nbsp;<input type="submit" class="button-secondary" value="' . $submit . '" />' . "\r\n";
720
+ }
721
+ }
722
+
723
+ /**
724
+ * Display a drop down list of administrator level users and
725
+ * optionally include a choice for Post Author
726
+ */
727
+ public function admin_dropdown( $inc_author = false ) {
728
+ global $wpdb;
729
+
730
+ $args = array(
731
+ 'fields' => array(
732
+ 'ID',
733
+ 'display_name',
734
+ ),
735
+ 'role' => 'administrator',
736
+ );
737
+
738
+ $wp_user_query = get_users( $args );
739
+ if ( ! empty( $wp_user_query ) ) {
740
+ foreach ( $wp_user_query as $user ) {
741
+ $admins[] = $user;
742
+ }
743
+ } else {
744
+ $admins = array();
745
+ }
746
+
747
+ if ( $inc_author ) {
748
+ $author[] = (object) array(
749
+ 'ID' => 'author',
750
+ 'display_name' => __( 'Post Author', 'subscribe2' ),
751
+ );
752
+ $author[] = (object) array(
753
+ 'ID' => 'blogname',
754
+ 'display_name' => html_entity_decode( get_option( 'blogname' ), ENT_QUOTES ),
755
+ );
756
+ $admins = array_merge( $author, $admins );
757
+ }
758
+
759
+ echo '<select name="sender">' . "\r\n";
760
+ foreach ( $admins as $admin ) {
761
+ echo '<option value="' . $admin->ID . '"';
762
+ if ( $admin->ID === $this->subscribe2_options['sender'] ) {
763
+ echo ' selected="selected"';
764
+ }
765
+ echo '>' . $admin->display_name . '</option>' . "\r\n";
766
+ }
767
+ echo '</select>' . "\r\n";
768
+ }
769
+
770
+ /**
771
+ * Display a dropdown of choices for digest email frequency
772
+ * and give user details of timings when event is scheduled
773
+ */
774
+ public function display_digest_choices() {
775
+ global $wpdb;
776
+ $cron_file = ABSPATH . 'wp-cron.php';
777
+ if ( ! is_readable( $cron_file ) ) {
778
+ 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";
779
+ }
780
+ $scheduled_time = wp_next_scheduled( 's2_digest_cron' );
781
+ $offset = get_option( 'gmt_offset' ) * 60 * 60;
782
+ $schedule = (array) wp_get_schedules();
783
+ $schedule = array_merge(
784
+ array(
785
+ 'never' => array(
786
+ 'interval' => 0,
787
+ 'display' => __( 'For each Post', 'subscribe2' ),
788
+ ),
789
+ ),
790
+ $schedule
791
+ );
792
+
793
+ $sort = array();
794
+ foreach ( (array) $schedule as $key => $value ) {
795
+ $sort[ $key ] = $value['interval'];
796
+ }
797
+ asort( $sort );
798
+ $schedule_sorted = array();
799
+ foreach ( $sort as $key => $value ) {
800
+ $schedule_sorted[ $key ] = $schedule[ $key ];
801
+ }
802
+ foreach ( $schedule_sorted as $key => $value ) {
803
+ echo '<label><input type="radio" name="email_freq" value="' . $key . '"' . checked( $this->subscribe2_options['email_freq'], $key, false ) . ' />';
804
+ echo ' ' . $value['display'] . '</label><br />' . "\r\n";
805
+ }
806
+ if ( $scheduled_time ) {
807
+ $date_format = get_option( 'date_format' );
808
+ $time_format = get_option( 'time_format' );
809
+ echo '<p>' . __( 'Current UTC time is', 'subscribe2' ) . ': ' . "\r\n";
810
+ echo '<strong>' . date_i18n( $date_format . ' @ ' . $time_format, false, 'gmt' ) . '</strong></p>' . "\r\n";
811
+ echo '<p>' . __( 'Current blog time is', 'subscribe2' ) . ': ' . "\r\n";
812
+ echo '<strong>' . date_i18n( $date_format . ' @ ' . $time_format ) . '</strong></p>' . "\r\n";
813
+ echo '<p>' . __( 'Next email notification will be sent when your blog time is after', 'subscribe2' ) . ': ' . "\r\n";
814
+ echo '<input type="hidden" id="jscrondate" value="' . date_i18n( $date_format, $scheduled_time + $offset ) . '" />';
815
+ echo '<input type="hidden" id="jscrontime" value="' . date_i18n( $time_format, $scheduled_time + $offset ) . '" />';
816
+ echo '<span id="s2cron_1"><span id="s2crondate" style="background-color: #FFFBCC">' . date_i18n( $date_format, $scheduled_time + $offset ) . '</span>';
817
+ echo ' @ <span id="s2crontime" style="background-color: #FFFBCC">' . date_i18n( $time_format, $scheduled_time + $offset ) . '</span> ';
818
+ echo '<a href="#" onclick="s2Show(\'cron\'); return false;">' . __( 'Edit', 'subscribe2' ) . '</a></span>' . "\r\n";
819
+ echo '<span id="s2cron_2">' . "\r\n";
820
+ echo '<input id="s2datepicker" name="crondate" value="' . date_i18n( $date_format, $scheduled_time + $offset ) . '">' . "\r\n";
821
+ $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' );
822
+ $current_hour = intval( date_i18n( 'G', $scheduled_time + $offset ) );
823
+ echo '<select name="crontime">' . "\r\n";
824
+ foreach ( $hours as $key => $value ) {
825
+ echo '<option value="' . $key . '"';
826
+ if ( ! empty( $scheduled_time ) && $key === $current_hour ) {
827
+ echo ' selected="selected"';
828
+ }
829
+ echo '>' . $value . '</option>' . "\r\n";
830
+ }
831
+ echo '</select>' . "\r\n";
832
+ echo '<a href="#" onclick="s2CronUpdate(\'cron\'); return false;">' . __( 'Update', 'subscribe2' ) . '</a>' . "\r\n";
833
+ echo '<a href="#" onclick="s2CronRevert(\'cron\'); return false;">' . __( 'Revert', 'subscribe2' ) . '</a></span>' . "\r\n";
834
+ if ( ! empty( $this->subscribe2_options['last_s2cron'] ) ) {
835
+ echo '<p>' . __( 'Attempt to resend the last Digest Notification email', 'subscribe2' ) . ': ';
836
+ echo '<input type="submit" class="button-secondary" name="resend" value="' . __( 'Resend Digest', 'subscribe2' ) . '" /></p>' . "\r\n";
837
+ }
838
+ } else {
839
+ echo '<br />';
840
+ }
841
+ }
842
+
843
+ /**
844
+ * Create and display a dropdown list of pages
845
+ */
846
+ public function pages_dropdown( $s2page ) {
847
+ $pages = get_pages();
848
+ if ( empty( $pages ) ) {
849
+ return;
850
+ }
851
+
852
+ $option = '';
853
+ foreach ( $pages as $page ) {
854
+ $option .= '<option value="' . $page->ID . '"';
855
+ if ( $page->ID === $s2page ) {
856
+ $option .= ' selected="selected"';
857
+ }
858
+ $option .= '>';
859
+ $parents = array_reverse( get_ancestors( $page->ID, 'page' ) );
860
+ if ( $parents ) {
861
+ foreach ( $parents as $parent ) {
862
+ $option .= get_the_title( $parent ) . ' &raquo; ';
863
+ }
864
+ }
865
+ $option .= $page->post_title . '</option>' . "\r\n";
866
+ }
867
+
868
+ echo $option;
869
+ }
870
+
871
+ /**
872
+ * Subscribe all registered users to category selected on Admin Manage Page
873
+ */
874
+ public function subscribe_registered_users( $emails = '', $cats = array() ) {
875
+ if ( '' === $emails || '' === $cats ) {
876
+ return false;
877
+ }
878
+ global $wpdb;
879
+
880
+ $useremails = explode( ",\r\n", $emails );
881
+ $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
882
+
883
+ $user_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // phpcs:ignore WordPress.DB.PreparedSQL
884
+
885
+ foreach ( $user_ids as $user_id ) {
886
+ $old_cats = get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true );
887
+ if ( ! empty( $old_cats ) ) {
888
+ $old_cats = explode( ',', $old_cats );
889
+ $newcats = array_unique( array_merge( $cats, $old_cats ) );
890
+ } else {
891
+ $newcats = $cats;
892
+ }
893
+ if ( ! empty( $newcats ) && $newcats !== $old_cats ) {
894
+ // add subscription to these cat IDs
895
+ foreach ( $newcats as $id ) {
896
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id, $id );
897
+ }
898
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
899
+ }
900
+ unset( $newcats );
901
+ }
902
+ }
903
+
904
+ /**
905
+ * Unsubscribe all registered users to category selected on Admin Manage Page
906
+ */
907
+ public function unsubscribe_registered_users( $emails = '', $cats = array() ) {
908
+ if ( '' === $emails || '' === $cats ) {
909
+ return false;
910
+ }
911
+ global $wpdb;
912
+
913
+ $useremails = explode( ",\r\n", $emails );
914
+ $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
915
+
916
+ $user_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // phpcs:ignore WordPress.DB.PreparedSQL
917
+
918
+ foreach ( $user_ids as $user_id ) {
919
+ $old_cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
920
+ $remain = array_diff( $old_cats, $cats );
921
+ if ( ! empty( $remain ) && $remain !== $old_cats ) {
922
+ // remove subscription to these cat IDs and update s2_subscribed
923
+ foreach ( $cats as $id ) {
924
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id );
925
+ }
926
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $remain ) );
927
+ } else {
928
+ // remove subscription to these cat IDs and update s2_subscribed to ''
929
+ foreach ( $cats as $id ) {
930
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id );
931
+ }
932
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ) );
933
+ }
934
+ unset( $remain );
935
+ }
936
+ }
937
+
938
+ /**
939
+ * Handles bulk changes to email format for Registered Subscribers
940
+ */
941
+ public function format_change( $emails, $format ) {
942
+ if ( empty( $format ) ) {
943
+ return;
944
+ }
945
+
946
+ global $wpdb;
947
+ $useremails = explode( ",\r\n", $emails );
948
+ $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
949
+ $ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // phpcs:ignore WordPress.DB.PreparedSQL
950
+ $ids = implode( ',', array_map( array( $this, 'prepare_in_data' ), $ids ) );
951
+ $sql = "UPDATE $wpdb->usermeta SET meta_value='{$format}' WHERE meta_key='" . $this->get_usermeta_keyname( 's2_format' ) . "' AND user_id IN ($ids)";
952
+ $wpdb->query( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL
953
+ }
954
+
955
+ /**
956
+ * Handles bulk update to digest preferences
957
+ */
958
+ public function digest_change( $emails, $digest ) {
959
+ if ( empty( $digest ) ) {
960
+ return;
961
+ }
962
+
963
+ global $wpdb;
964
+ $useremails = explode( ",\r\n", $emails );
965
+ $useremails = implode( ', ', array_map( array( $this, 'prepare_in_data' ), $useremails ) );
966
+
967
+ $user_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)" ); // phpcs:ignore WordPress.DB.PreparedSQL
968
+
969
+ if ( 'digest' === $digest ) {
970
+ $exclude = explode( ',', $this->subscribe2_options['exclude'] );
971
+ if ( ! empty( $exclude ) ) {
972
+ $all_cats = $this->all_cats( true, 'ID' );
973
+ } else {
974
+ $all_cats = $this->all_cats( false, 'ID' );
975
+ }
976
+
977
+ $cats_string = '';
978
+ foreach ( $all_cats as $cat ) {
979
+ ( '' === $cats_string ) ? $cats_string = "$cat->term_id" : $cats_string .= ",$cat->term_id";
980
+ }
981
+
982
+ foreach ( $user_ids as $user_id ) {
983
+ foreach ( $all_cats as $cat ) {
984
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $cat->term_id, $cat->term_id );
985
+ }
986
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), $cats_string );
987
+ }
988
+ } elseif ( '-1' === $digest ) {
989
+ foreach ( $user_ids as $user_id ) {
990
+ $cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
991
+ foreach ( $cats as $id ) {
992
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $id );
993
+ }
994
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ) );
995
+ }
996
+ }
997
+ }
998
+
999
+ /* ===== functions to handle addition and removal of WordPress categories ===== */
1000
+ /**
1001
+ * Autosubscribe registered users to newly created categories
1002
+ * if registered user has selected this option
1003
+ */
1004
+ public function new_category( $new_category = '' ) {
1005
+ if ( 'no' === $this->subscribe2_options['show_autosub'] ) {
1006
+ return;
1007
+ }
1008
+
1009
+ global $wpdb;
1010
+ if ( 'never' !== $this->subscribe2_options['email_freq'] ) {
1011
+ // if we are doing digests add new categories to users who are currently opted in
1012
+ $user_ids = $wpdb->get_col(
1013
+ $wpdb->prepare(
1014
+ "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key=%s AND meta_value<>''",
1015
+ $this->get_usermeta_keyname( 's2_subscribed' )
1016
+ )
1017
+ );
1018
+ foreach ( $user_ids as $user_id ) {
1019
+ $old_cats = get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true );
1020
+ $old_cats = explode( ',', $old_cats );
1021
+ $newcats = array_merge( $old_cats, (array) $new_category );
1022
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $new_category, $new_category );
1023
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
1024
+ }
1025
+ return;
1026
+ }
1027
+
1028
+ if ( 'yes' === $this->subscribe2_options['show_autosub'] ) {
1029
+ if ( $this->s2_mu ) {
1030
+ $user_ids = $wpdb->get_col(
1031
+ $wpdb->prepare(
1032
+ "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",
1033
+ $this->get_usermeta_keyname( 's2_autosub' ),
1034
+ $this->get_usermeta_keyname( 's2_subscribed' )
1035
+ )
1036
+ );
1037
+ } else {
1038
+ $user_ids = $wpdb->get_col(
1039
+ $wpdb->prepare(
1040
+ "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE $wpdb->usermeta.meta_key=%s AND $wpdb->usermeta.meta_value='yes'",
1041
+ $this->get_usermeta_keyname( 's2_autosub' )
1042
+ )
1043
+ );
1044
+ }
1045
+ if ( '' === $user_ids ) {
1046
+ return;
1047
+ }
1048
+
1049
+ foreach ( $user_ids as $user_id ) {
1050
+ $old_cats = get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true );
1051
+ if ( empty( $old_cats ) ) {
1052
+ $newcats = (array) $new_category;
1053
+ } else {
1054
+ $old_cats = explode( ',', $old_cats );
1055
+ $newcats = array_merge( $old_cats, (array) $new_category );
1056
+ }
1057
+ // add subscription to these cat IDs
1058
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $new_category, $new_category );
1059
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $newcats ) );
1060
+ }
1061
+ } elseif ( 'exclude' === $this->subscribe2_options['show_autosub'] ) {
1062
+ $excluded_cats = explode( ',', $this->subscribe2_options['exclude'] );
1063
+ $excluded_cats[] = $new_category;
1064
+ $this->subscribe2_options['exclude'] = implode( ',', $excluded_cats );
1065
+ update_option( 'subscribe2_options', $this->subscribe2_options );
1066
+ }
1067
+ }
1068
+
1069
+ /**
1070
+ * Automatically delete subscriptions to a category when it is deleted
1071
+ */
1072
+ public function delete_category( $deleted_category = '' ) {
1073
+ global $wpdb;
1074
+
1075
+ if ( $this->s2_mu ) {
1076
+ $user_ids = $wpdb->get_col(
1077
+ $wpdb->prepare(
1078
+ "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",
1079
+ $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category,
1080
+ $this->get_usermeta_keyname( 's2_subscribed' )
1081
+ )
1082
+ );
1083
+ } else {
1084
+ $user_ids = $wpdb->get_col(
1085
+ $wpdb->prepare(
1086
+ "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key=%s",
1087
+ $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category
1088
+ )
1089
+ );
1090
+ }
1091
+ if ( '' === $user_ids ) {
1092
+ return;
1093
+ }
1094
+
1095
+ foreach ( $user_ids as $user_id ) {
1096
+ $old_cats = explode( ',', get_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), true ) );
1097
+ if ( ! is_array( $old_cats ) ) {
1098
+ $old_cats = array( $old_cats );
1099
+ }
1100
+ // add subscription to these cat IDs
1101
+ delete_user_meta( $user_id, $this->get_usermeta_keyname( 's2_cat' ) . $deleted_category );
1102
+ $remain = array_diff( $old_cats, (array) $deleted_category );
1103
+ update_user_meta( $user_id, $this->get_usermeta_keyname( 's2_subscribed' ), implode( ',', $remain ) );
1104
+ }
1105
+ }
1106
+
1107
+ /* ===== functions to show & handle one-click subscription ===== */
1108
+ /**
1109
+ * Show form for one-click subscription on user profile page
1110
+ */
1111
+ public function one_click_profile_form( $user ) {
1112
+ echo '<h3>' . __( 'Email subscription', 'subscribe2' ) . '</h3>' . "\r\n";
1113
+ echo '<table class="form-table">' . "\r\n";
1114
+ echo '<tr><th scope="row">' . __( 'Subscribe / Unsubscribe', 'subscribe2' ) . '</th>' . "\r\n";
1115
+ 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";
1116
+ echo '<span class="description">' . __( 'Check if you want to receive email notification when new posts are published', 'subscribe2' ) . '</span>' . "\r\n";
1117
+ echo '</td></tr></table>' . "\r\n";
1118
+ }
1119
+
1120
+ /**
1121
+ * Handle submission from profile one-click subscription
1122
+ */
1123
+ public function one_click_profile_form_save( $user_id ) {
1124
+ if ( ! current_user_can( 'edit_user', $user_id ) ) {
1125
+ return false;
1126
+ }
1127
+
1128
+ if ( isset( $_POST['sub2-one-click-subscribe'] ) && 1 === $_POST['sub2-one-click-subscribe'] ) {
1129
+ // Subscribe
1130
+ $this->one_click_handler( $user_id, 'subscribe' );
1131
+ } else {
1132
+ // Unsubscribe
1133
+ $this->one_click_handler( $user_id, 'unsubscribe' );
1134
+ }
1135
+ }
1136
+
1137
+ /**
1138
+ * Core function to hook the digest email preview to the action on the Settings page
1139
+ */
1140
+ public function digest_preview( $user_email = '' ) {
1141
+ if ( false === $this->validate_email( $user_email ) ) {
1142
+ return;
1143
+ }
1144
+ $this->subscribe2_cron( $user_email );
1145
+ }
1146
+
1147
+ /**
1148
+ * Core function to hook the resent digest email to the action on the Settings page
1149
+ */
1150
+ public function digest_resend( $resend ) {
1151
+ if ( 'resend' === $resend ) {
1152
+ $this->subscribe2_cron( '', 'resend' );
1153
+ }
1154
+ }
1155
+ }
classes/class-s2-block-editor.php CHANGED
@@ -1,137 +1,216 @@
1
  <?php
2
  class S2_Block_Editor {
3
- /**
4
- * Constructor
5
- */
6
- public function __construct() {
7
- // maybe use dev scripts
8
- $this->script_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
9
-
10
- add_action( 'init', array( &$this, 'register_s2_meta' ) );
11
- add_action( 'rest_api_init', array( $this, 'register_preview_endpoint' ) );
12
-
13
- if ( is_admin() ) {
14
- add_action( 'admin_enqueue_scripts', array( &$this, 'gutenberg_block_editor_assets' ), 6 );
15
- add_action( 'admin_enqueue_scripts', array( &$this, 'gutenberg_i18n' ), 6 );
16
- }
17
- }
18
-
19
- /**
20
- * Register _s2mail meta data for Block Editor
21
- */
22
- public function register_s2_meta() {
23
- register_meta(
24
- 'post',
25
- '_s2mail',
26
- array(
27
- 'show_in_rest' => true,
28
- 'single' => true,
29
- 'type' => 'string',
30
- 'auth_callback' => function() {
31
- return current_user_can( 'edit_posts' );
32
- },
33
- )
34
- );
35
- }
36
-
37
- /**
38
- * Register REST endpointsfor preview email
39
- */
40
- public function register_preview_endpoint() {
41
- register_rest_route(
42
- 's2/v1',
43
- '/preview/(?P<id>[0-9]+)',
44
- array(
45
- 'methods' => WP_REST_Server::READABLE,
46
- 'callback' => array( $this, 'preview' ),
47
- 'args' => array(
48
- 'id' => array(
49
- 'validate_callback' => function( $param ) {
50
- return preg_match( '/\\d/', $param ) > 0;
51
- },
52
- ),
53
- ),
54
- 'permission_callback' => function () {
55
- return current_user_can( 'edit_posts' );
56
- },
57
- )
58
- );
59
- }
60
-
61
- /**
62
- * Function to trigger Preview email on REST API request
63
- */
64
- public function preview( $data ) {
65
- global $mysubscribe2;
66
- $post = get_post( intval( $data['id'] ) );
67
-
68
- $current_user = wp_get_current_user();
69
- if ( 0 === $current_user->ID ) {
70
- return false;
71
- }
72
- $mysubscribe2->publish( $post, $current_user->user_email );
73
- return true;
74
- }
75
-
76
- /**
77
- * Enqueue Block Editor assets
78
- */
79
- public function gutenberg_block_editor_assets() {
80
- global $pagenow;
81
- if ( ! in_array( $pagenow, array( 'post-new.php', 'post.php', 'page-new.php', 'page.php' ), true ) ) {
82
- return;
83
- }
84
-
85
- wp_enqueue_script(
86
- 'subscribe2-shortcode',
87
- S2URL . 'gutenberg/shortcode' . $this->script_debug . '.js',
88
- array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-components', 'wp-editor' ),
89
- '1.1',
90
- true
91
- );
92
-
93
- register_block_type(
94
- 'subscribe2-html/shortcode',
95
- array(
96
- 'editor_script' => 'subscribe2-shortcode',
97
- )
98
- );
99
-
100
- wp_enqueue_script(
101
- 'subscribe2-sidebar',
102
- S2URL . 'gutenberg/sidebar' . $this->script_debug . '.js',
103
- array( 'wp-plugins', 'wp-element', 'wp-i18n', 'wp-edit-post', 'wp-components', 'wp-data', 'wp-compose', 'wp-api-fetch' ),
104
- '1.0',
105
- true
106
- );
107
- }
108
-
109
- /**
110
- * Handle translation of Block Editor assets
111
- */
112
- public function gutenberg_i18n() {
113
- global $pagenow;
114
- if ( ! in_array( $pagenow, array( 'post-new.php', 'post.php', 'page-new.php', 'page.php' ), true ) ) {
115
- return;
116
- }
117
-
118
- $translations = get_translations_for_domain( 'subscribe2' );
119
-
120
- $locale_data = array(
121
- '' => array(
122
- 'domain' => 'subscribe2',
123
- 'lang' => get_user_locale(),
124
- 'plural_forms' => 'nplurals=2; plural=n != 1;',
125
- ),
126
- );
127
-
128
- foreach ( $translations->entries as $msgid => $entry ) {
129
- $locale_data[ $msgid ] = $entry->translations;
130
- }
131
-
132
- wp_add_inline_script(
133
- 'wp-i18n',
134
- 'wp.i18n.setLocaleData( ' . wp_json_encode( $locale_data ) . ', "subscribe2" );'
135
- );
136
- }
137
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
  class S2_Block_Editor {
3
+ /**
4
+ * Constructor
5
+ */
6
+ public function __construct() {
7
+ // maybe use dev scripts
8
+ $this->script_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
9
+
10
+ add_action( 'init', array( &$this, 'register_s2_meta' ) );
11
+ add_action( 'rest_api_init', array( $this, 'register_preview_endpoint' ) );
12
+ add_action( 'rest_api_init', array( $this, 'register_resend_endpoint' ) );
13
+ add_action( 'rest_api_init', array( $this, 'register_settings_endpoint' ) );
14
+
15
+ if ( is_admin() ) {
16
+ add_action( 'admin_enqueue_scripts', array( &$this, 'gutenberg_block_editor_assets' ), 6 );
17
+ add_action( 'admin_enqueue_scripts', array( &$this, 'gutenberg_i18n' ), 6 );
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Register _s2mail meta data for Block Editor
23
+ */
24
+ public function register_s2_meta() {
25
+ register_meta(
26
+ 'post',
27
+ '_s2mail',
28
+ array(
29
+ 'show_in_rest' => true,
30
+ 'single' => true,
31
+ 'type' => 'string',
32
+ 'auth_callback' => function() {
33
+ return current_user_can( 'edit_posts' );
34
+ },
35
+ )
36
+ );
37
+ }
38
+
39
+ /**
40
+ * Register REST endpoints for preview email
41
+ */
42
+ public function register_preview_endpoint() {
43
+ register_rest_route(
44
+ 's2/v1',
45
+ '/preview/(?P<id>[0-9]+)',
46
+ array(
47
+ 'methods' => WP_REST_Server::READABLE,
48
+ 'callback' => array( $this, 'preview' ),
49
+ 'args' => array(
50
+ 'id' => array(
51
+ 'validate_callback' => function( $param ) {
52
+ return is_numeric( $param );
53
+ },
54
+ ),
55
+ ),
56
+ 'permission_callback' => function () {
57
+ return current_user_can( 'edit_posts' );
58
+ },
59
+ )
60
+ );
61
+ }
62
+
63
+ /**
64
+ * Register REST endpoints for resending emails
65
+ */
66
+ public function register_resend_endpoint() {
67
+ register_rest_route(
68
+ 's2/v1',
69
+ '/resend/(?P<id>[0-9]+)',
70
+ array(
71
+ 'methods' => WP_REST_Server::READABLE,
72
+ 'callback' => array( $this, 'resend' ),
73
+ 'args' => array(
74
+ 'id' => array(
75
+ 'validate_callback' => function( $param ) {
76
+ return is_numeric( $param );
77
+ },
78
+ ),
79
+ ),
80
+ 'permission_callback' => function () {
81
+ return current_user_can( 'edit_posts' );
82
+ },
83
+ )
84
+ );
85
+ }
86
+
87
+ /**
88
+ * Register REST endpoints for surfacing settings
89
+ */
90
+ public function register_settings_endpoint() {
91
+ register_rest_route(
92
+ 's2/v1',
93
+ '/settings/(?P<setting>[a-z0-9_]+)',
94
+ array(
95
+ 'methods' => WP_REST_Server::READABLE,
96
+ 'callback' => array( $this, 'setting' ),
97
+ 'args' => array(
98
+ 'id' => array(
99
+ 'validate_callback' => function( $param ) {
100
+ return preg_match( '/^[a-z0-9_]+$/', $param ) > 0;
101
+ },
102
+ ),
103
+ ),
104
+ 'permission_callback' => function () {
105
+ return current_user_can( 'edit_posts' );
106
+ },
107
+ )
108
+ );
109
+ }
110
+
111
+ /**
112
+ * Function to trigger Preview email on REST API request
113
+ */
114
+ public function preview( $data ) {
115
+ global $mysubscribe2;
116
+ $post = get_post( intval( $data['id'] ) );
117
+
118
+ $current_user = wp_get_current_user();
119
+ if ( 0 === $current_user->ID ) {
120
+ return false;
121
+ }
122
+
123
+ $mysubscribe2->publish( $post, $current_user->user_email );
124
+ return true;
125
+ }
126
+
127
+ /**
128
+ * Function to trigger resending of email on REST API request
129
+ */
130
+ public function resend( $data ) {
131
+ global $mysubscribe2;
132
+ $post = get_post( intval( $data['id'] ) );
133
+
134
+ $current_user = wp_get_current_user();
135
+ if ( 0 === $current_user->ID ) {
136
+ return false;
137
+ }
138
+
139
+ $mysubscribe2->publish( $post );
140
+ return true;
141
+ }
142
+
143
+ /**
144
+ * Function to return value for passed setting
145
+ */
146
+ public function setting( $data ) {
147
+ global $mysubscribe2;
148
+ if ( array_key_exists( $data['setting'], $mysubscribe2->subscribe2_options ) ) {
149
+ return $mysubscribe2->subscribe2_options[ $data['setting'] ];
150
+ }
151
+
152
+ return false;
153
+ }
154
+
155
+ /**
156
+ * Enqueue Block Editor assets
157
+ */
158
+ public function gutenberg_block_editor_assets() {
159
+ global $pagenow;
160
+ if ( ! in_array( $pagenow, array( 'post-new.php', 'post.php', 'page-new.php', 'page.php' ), true ) ) {
161
+ return;
162
+ }
163
+
164
+ wp_enqueue_script(
165
+ 'subscribe2-shortcode',
166
+ S2URL . 'gutenberg/shortcode' . $this->script_debug . '.js',
167
+ array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-components', 'wp-editor' ),
168
+ '1.1',
169
+ true
170
+ );
171
+
172
+ register_block_type(
173
+ 'subscribe2-html/shortcode',
174
+ array(
175
+ 'editor_script' => 'subscribe2-shortcode',
176
+ )
177
+ );
178
+
179
+ wp_enqueue_script(
180
+ 'subscribe2-sidebar',
181
+ S2URL . 'gutenberg/sidebar' . $this->script_debug . '.js',
182
+ array( 'wp-plugins', 'wp-element', 'wp-i18n', 'wp-edit-post', 'wp-components', 'wp-data', 'wp-compose', 'wp-api-fetch' ),
183
+ '1.1',
184
+ true
185
+ );
186
+ }
187
+
188
+ /**
189
+ * Handle translation of Block Editor assets
190
+ */
191
+ public function gutenberg_i18n() {
192
+ global $pagenow;
193
+ if ( ! in_array( $pagenow, array( 'post-new.php', 'post.php', 'page-new.php', 'page.php' ), true ) ) {
194
+ return;
195
+ }
196
+
197
+ $translations = get_translations_for_domain( 'subscribe2' );
198
+
199
+ $locale_data = array(
200
+ '' => array(
201
+ 'domain' => 'subscribe2',
202
+ 'lang' => get_user_locale(),
203
+ 'plural_forms' => 'nplurals=2; plural=n != 1;',
204
+ ),
205
+ );
206
+
207
+ foreach ( $translations->entries as $msgid => $entry ) {
208
+ $locale_data[ $msgid ] = $entry->translations;
209
+ }
210
+
211
+ wp_add_inline_script(
212
+ 'wp-i18n',
213
+ 'wp.i18n.setLocaleData( ' . wp_json_encode( $locale_data ) . ', "subscribe2" );'
214
+ );
215
+ }
216
+ }
classes/class-s2-core.php CHANGED
@@ -1919,6 +1919,7 @@ class S2_Core {
1919
  add_action( 'admin_menu', array( &$this, 's2_meta_init' ) );
1920
  add_action( 'save_post', array( &$this, 's2_meta_handler' ) );
1921
  add_action( 'save_post', array( &$this, 's2_preview_handler' ) );
 
1922
  add_action( 'create_category', array( &$this, 'new_category' ) );
1923
  add_action( 'delete_category', array( &$this, 'delete_category' ) );
1924
 
1919
  add_action( 'admin_menu', array( &$this, 's2_meta_init' ) );
1920
  add_action( 'save_post', array( &$this, 's2_meta_handler' ) );
1921
  add_action( 'save_post', array( &$this, 's2_preview_handler' ) );
1922
+ add_action( 'save_post', array( &$this, 's2_resend_handler' ) );
1923
  add_action( 'create_category', array( &$this, 'new_category' ) );
1924
  add_action( 'delete_category', array( &$this, 'delete_category' ) );
1925
 
classes/class-s2-frontend.php CHANGED
@@ -1,533 +1,528 @@
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;
15
- $user_ID = get_current_user_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
- }
23
-
24
- $this->confirmation_sent = '<p class="s2_message">' . __( 'A confirmation message is on its way!', 'subscribe2' ) . '</p>';
25
-
26
- $this->already_subscribed = '<p class="s2_error">' . __( 'That email address is already subscribed.', 'subscribe2' ) . '</p>';
27
-
28
- $this->not_subscribed = '<p class="s2_error">' . __( 'That email address is not subscribed.', 'subscribe2' ) . '</p>';
29
-
30
- $this->not_an_email = '<p class="s2_error">' . __( 'Sorry, but that does not look like an email address to me.', 'subscribe2' ) . '</p>';
31
-
32
- $this->barred_domain = '<p class="s2_error">' . __( 'Sorry, email addresses at that domain are currently barred due to spam, please use an alternative email address.', 'subscribe2' ) . '</p>';
33
-
34
- $this->error = '<p class="s2_error">' . __( 'Sorry, there seems to be an error on the server. Please try again later.', 'subscribe2' ) . '</p>';
35
-
36
- // confirmation messages
37
- $this->no_such_email = '<p class="s2_error">' . __( 'No such email address is registered.', 'subscribe2' ) . '</p>';
38
-
39
- $this->added = '<p class="s2_message">' . __( 'You have successfully subscribed!', 'subscribe2' ) . '</p>';
40
-
41
- $this->deleted = '<p class="s2_message">' . __( 'You have successfully unsubscribed.', 'subscribe2' ) . '</p>';
42
-
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() ) {
69
- $id = '';
70
- foreach ( $args as $arg_name => $arg_value ) {
71
- if ( ! empty( $arg_value ) && 'link' !== $arg_name && 'id' !== $arg_name ) {
72
- if ( 'nojs' === $arg_name ) {
73
- $arg_value = 'true';
74
- }
75
- ( '' === $id ) ? $id .= $arg_name . '-' . $arg_value : $id .= ':' . $arg_name . '-' . $arg_value;
76
- }
77
- }
78
- $this->s2form = '<a href="#" class="s2popup" id="' . esc_attr( $id ) . '">' . esc_html( $args['link'] ) . '</a>' . "\r\n";
79
- return $this->s2form;
80
- }
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'] );
88
- if ( 'subscribe' === $hide ) {
89
- $this->input_form_action = '<input type="submit" name="unsubscribe" value="' . esc_attr( $unsubscribe_button_value ) . '" />';
90
- } elseif ( 'unsubscribe' === $hide ) {
91
- $this->input_form_action = '<input type="submit" name="subscribe" value="' . esc_attr( $subscribe_button_value ) . '" />';
92
- } else {
93
- // both form input actions
94
- $this->input_form_action = '<input type="submit" name="subscribe" value="' . esc_attr( $subscribe_button_value ) . '" />&nbsp;<input type="submit" name="unsubscribe" value="' . esc_attr( $unsubscribe_button_value ) . '" />';
95
- }
96
-
97
- // if ID is provided, get permalink
98
- $action = '';
99
- if ( is_numeric( $args['id'] ) ) {
100
- $action = ' action="' . get_permalink( $args['id'] ) . '"';
101
- } elseif ( 'home' === $args['id'] ) {
102
- $action = ' action="' . get_site_url() . '"';
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 = '';
110
- }
111
- } elseif ( $this->subscribe2_options['s2page'] > 0 ) {
112
- $action = ' action="' . get_permalink( $this->subscribe2_options['s2page'] ) . '"';
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 {
124
- $value = __( 'Enter email address...', 'subscribe2' );
125
- }
126
-
127
- // if wrap is true add paragraph html tags
128
- $wrap_text = '';
129
- if ( 'true' === strtolower( $args['wrap'] ) ) {
130
- $wrap_text = '</p><p>';
131
- }
132
-
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://" />';
140
- $antispam_text .= '</span>';
141
- }
142
-
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'] ) ) {
172
- // anti spam sign up measure
173
- if ( ( isset( $_POST['firstname'] ) && '' !== $_POST['firstname'] ) || ( isset( $_POST['lastname'] ) && '' !== $_POST['lastname'] ) || ( isset( $_POST['uri'] ) && 'http://' !== $_POST['uri'] ) ) {
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;
187
- } else {
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, true ) ) {
193
- return __( 'Slow down, you move too fast.', 'subscribe2' );
194
- }
195
- }
196
- // does the supplied email belong to a registered user?
197
- $check = $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM $wpdb->users WHERE user_email = %s", $this->email ) );
198
- if ( null !== $check ) {
199
- // this is a registered email
200
- $this->s2form = $this->please_log_in;
201
- } else {
202
- // this is not a registered email
203
- // what should we do?
204
- if ( isset( $_POST['subscribe'] ) ) {
205
- // someone is trying to subscribe
206
- // lets see if they've tried to subscribe previously
207
- if ( '1' !== $this->is_public( $this->email ) ) {
208
- // the user is unknown or inactive
209
- $this->add( $this->email );
210
- $status = $this->send_confirm( 'add' );
211
- // set a variable to denote that we've already run, and shouldn't run again
212
- $this->filtered = 1;
213
- if ( $status ) {
214
- $this->s2form = $this->confirmation_sent;
215
- } else {
216
- $this->s2form = $this->error;
217
- }
218
- } else {
219
- // they're already subscribed
220
- $this->s2form = $this->already_subscribed;
221
- }
222
- $this->action = 'subscribe';
223
- } elseif ( isset( $_POST['unsubscribe'] ) ) {
224
- // is this email a subscriber?
225
- if ( false === $this->is_public( $this->email ) ) {
226
- $this->s2form = $this->s2form . $this->not_subscribed;
227
- } else {
228
- $status = $this->send_confirm( 'del' );
229
- // set a variable to denote that we've already run, and shouldn't run again
230
- $this->filtered = 1;
231
- if ( $status ) {
232
- $this->s2form = $this->confirmation_sent;
233
- } else {
234
- $this->s2form = $this->error;
235
- }
236
- }
237
- $this->action = 'unsubscribe';
238
- }
239
- }
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
-
269
- // brute force Simple Facebook Connect to bypass compatiblity issues
270
- $priority = has_filter( 'wp_head', 'sfc_base_meta' );
271
- if ( false !== $priority ) {
272
- remove_action( 'wp_head', 'sfc_base_meta', $priority );
273
- }
274
-
275
- if ( 0 !== $this->subscribe2_options['s2page'] ) {
276
- return array(
277
- 'page_id' => $this->subscribe2_options['s2page'],
278
- );
279
- } else {
280
- $id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_type='page' AND post_status='publish' LIMIT 1" );
281
- if ( $id ) {
282
- return array(
283
- 'page_id' => $id,
284
- );
285
- } else {
286
- return array(
287
- 'showposts' => 1,
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' );
302
- } else {
303
- return __( 'Unsubscription Confirmation', 'subscribe2' );
304
- }
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 ) {
317
- return $this->message;
318
- } elseif ( 1 === $this->filtered ) {
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 ) {
329
- return $this->no_such_email;
330
- }
331
- } else {
332
- return $this->no_such_email;
333
- }
334
-
335
- // get current status of email so messages are only sent once per emailed link
336
- $current = $this->is_public( $this->email );
337
-
338
- if ( '1' === $action ) {
339
- // make this subscription active
340
- $this->message = apply_filters( 's2_subscribe_confirmed', $this->added );
341
- if ( '1' !== $this->is_public( $this->email ) ) {
342
- $this->ip = esc_html( $this->get_remote_ip() );
343
- $this->toggle( $this->email );
344
- if ( 'subs' === $this->subscribe2_options['admin_email'] || 'both' === $this->subscribe2_options['admin_email'] ) {
345
- $this->admin_email( 'subscribe' );
346
- }
347
- }
348
- $this->filtered = 1;
349
- } elseif ( '0' === $action ) {
350
- // remove this public subscriber
351
- $this->message = apply_filters( 's2_unsubscribe_confirmed', $this->deleted );
352
- if ( '0' !== $this->is_public( $this->email ) ) {
353
- $this->delete( $this->email );
354
- if ( 'unsubs' === $this->subscribe2_options['admin_email'] || 'both' === $this->subscribe2_options['admin_email'] ) {
355
- $this->admin_email( 'unsubscribe' );
356
- }
357
- }
358
- $this->filtered = 1;
359
- }
360
-
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' ), true ) ) {
371
- return false;
372
- }
373
-
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 ) {
431
- continue;
432
- }
433
- for ( $i = 0; $i < $count; $i++ ) {
434
- if ( '*' === $url[ $i ] ) {
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 ) ) {
471
- return true;
472
- }
473
- } else {
474
- // direct domain string comparison
475
- $barred_domain = '@' . $barred_domain;
476
- if ( strtolower( $domain ) === strtolower( trim( $barred_domain ) ) ) {
477
- return true;
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
492
- $address_headers = array(
493
- 'HTTP_CLIENT_IP',
494
- 'HTTP_X_FORWARDED_FOR',
495
- 'HTTP_X_FORWARDED',
496
- 'HTTP_X_CLUSTER_CLIENT_IP',
497
- 'HTTP_FORWARDED_FOR',
498
- 'HTTP_FORWARDED',
499
- 'REMOTE_ADDR',
500
- );
501
-
502
- foreach ( $address_headers as $header ) {
503
- if ( array_key_exists( $header, $_SERVER ) ) {
504
- // HTTP_X_FORWARDED_FOR can contain a chain of comma-separated
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"; // phpcs:ignore WordPress.WP.EnqueuedResources
529
- }
530
-
531
- /* ===== define some variables ===== */
532
- public $profile = '';
533
- }
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;
15
+ $user_ID = get_current_user_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
+ }
23
+
24
+ $this->confirmation_sent = '<p class="s2_message">' . __( 'A confirmation message is on its way!', 'subscribe2' ) . '</p>';
25
+
26
+ $this->already_subscribed = '<p class="s2_error">' . __( 'That email address is already subscribed.', 'subscribe2' ) . '</p>';
27
+
28
+ $this->not_subscribed = '<p class="s2_error">' . __( 'That email address is not subscribed.', 'subscribe2' ) . '</p>';
29
+
30
+ $this->not_an_email = '<p class="s2_error">' . __( 'Sorry, but that does not look like an email address to me.', 'subscribe2' ) . '</p>';
31
+
32
+ $this->barred_domain = '<p class="s2_error">' . __( 'Sorry, email addresses at that domain are currently barred due to spam, please use an alternative email address.', 'subscribe2' ) . '</p>';
33
+
34
+ $this->error = '<p class="s2_error">' . __( 'Sorry, there seems to be an error on the server. Please try again later.', 'subscribe2' ) . '</p>';
35
+
36
+ // confirmation messages
37
+ $this->no_such_email = '<p class="s2_error">' . __( 'No such email address is registered.', 'subscribe2' ) . '</p>';
38
+
39
+ $this->added = '<p class="s2_message">' . __( 'You have successfully subscribed!', 'subscribe2' ) . '</p>';
40
+
41
+ $this->deleted = '<p class="s2_message">' . __( 'You have successfully unsubscribed.', 'subscribe2' ) . '</p>';
42
+
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() ) {
69
+ $id = '';
70
+ foreach ( $args as $arg_name => $arg_value ) {
71
+ if ( ! empty( $arg_value ) && 'link' !== $arg_name && 'id' !== $arg_name ) {
72
+ if ( 'nojs' === $arg_name ) {
73
+ $arg_value = 'true';
74
+ }
75
+ ( '' === $id ) ? $id .= $arg_name . '-' . $arg_value : $id .= ':' . $arg_name . '-' . $arg_value;
76
+ }
77
+ }
78
+ $this->s2form = '<a href="#" class="s2popup" id="' . esc_attr( $id ) . '">' . esc_html( $args['link'] ) . '</a>' . "\r\n";
79
+ return $this->s2form;
80
+ }
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'] );
88
+ if ( 'subscribe' === $hide ) {
89
+ $this->input_form_action = '<input type="submit" name="unsubscribe" value="' . esc_attr( $unsubscribe_button_value ) . '" />';
90
+ } elseif ( 'unsubscribe' === $hide ) {
91
+ $this->input_form_action = '<input type="submit" name="subscribe" value="' . esc_attr( $subscribe_button_value ) . '" />';
92
+ } else {
93
+ // both form input actions
94
+ $this->input_form_action = '<input type="submit" name="subscribe" value="' . esc_attr( $subscribe_button_value ) . '" />&nbsp;<input type="submit" name="unsubscribe" value="' . esc_attr( $unsubscribe_button_value ) . '" />';
95
+ }
96
+
97
+ // if ID is provided, get permalink
98
+ $action = '';
99
+ if ( is_numeric( $args['id'] ) ) {
100
+ $action = ' action="' . get_permalink( $args['id'] ) . '"';
101
+ } elseif ( 'home' === $args['id'] ) {
102
+ $action = ' action="' . get_site_url() . '"';
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 = '';
110
+ }
111
+ } elseif ( $this->subscribe2_options['s2page'] > 0 ) {
112
+ $action = ' action="' . get_permalink( $this->subscribe2_options['s2page'] ) . '"';
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 {
124
+ $value = __( 'Enter email address...', 'subscribe2' );
125
+ }
126
+
127
+ // if wrap is true add paragraph html tags
128
+ $wrap_text = '';
129
+ if ( 'true' === strtolower( $args['wrap'] ) ) {
130
+ $wrap_text = '</p><p>';
131
+ }
132
+
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://" />';
140
+ $antispam_text .= '</span>';
141
+ }
142
+
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
+ return $this->profile;
164
+ }
165
+
166
+ if ( isset( $_POST['subscribe'] ) || isset( $_POST['unsubscribe'] ) ) {
167
+ // anti spam sign up measure
168
+ if ( ( isset( $_POST['firstname'] ) && '' !== $_POST['firstname'] ) || ( isset( $_POST['lastname'] ) && '' !== $_POST['lastname'] ) || ( isset( $_POST['uri'] ) && 'http://' !== $_POST['uri'] ) ) {
169
+ // looks like some invisible-to-user fields were changed; falsely report success
170
+ return $this->confirmation_sent;
171
+ }
172
+ $validation = apply_filters( 's2_form_submission', true );
173
+ if ( true !== $validation ) {
174
+ return apply_filters( 's2_form_failed_validation', $this->s2form );
175
+ }
176
+ global $wpdb;
177
+ $this->email = $this->sanitize_email( $_POST['email'] );
178
+ if ( false === $this->validate_email( $this->email ) ) {
179
+ $this->s2form = $this->s2form . $this->not_an_email;
180
+ } elseif ( $this->is_barred( $this->email ) ) {
181
+ $this->s2form = $this->s2form . $this->barred_domain;
182
+ } else {
183
+ $this->ip = $_POST['ip'];
184
+ if ( is_int( $this->lockout ) && $this->lockout > 0 ) {
185
+ $date = date( 'H:i:s.u', $this->lockout );
186
+ $ips = $wpdb->get_col( $wpdb->prepare( "SELECT ip FROM $wpdb->subscribe2 WHERE date = CURDATE() AND time > SUBTIME(CURTIME(), %s)", $date ) );
187
+ if ( in_array( $this->ip, $ips, true ) ) {
188
+ return __( 'Slow down, you move too fast.', 'subscribe2' );
189
+ }
190
+ }
191
+ // does the supplied email belong to a registered user?
192
+ $check = $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM $wpdb->users WHERE user_email = %s", $this->email ) );
193
+ if ( null !== $check ) {
194
+ // this is a registered email
195
+ $this->s2form = $this->please_log_in;
196
+ } else {
197
+ // this is not a registered email
198
+ // what should we do?
199
+ if ( isset( $_POST['subscribe'] ) ) {
200
+ // someone is trying to subscribe
201
+ // lets see if they've tried to subscribe previously
202
+ if ( '1' !== $this->is_public( $this->email ) ) {
203
+ // the user is unknown or inactive
204
+ $this->add( $this->email );
205
+ $status = $this->send_confirm( 'add' );
206
+ // set a variable to denote that we've already run, and shouldn't run again
207
+ $this->filtered = 1;
208
+ if ( $status ) {
209
+ $this->s2form = $this->confirmation_sent;
210
+ } else {
211
+ $this->s2form = $this->error;
212
+ }
213
+ } else {
214
+ // they're already subscribed
215
+ $this->s2form = $this->already_subscribed;
216
+ }
217
+ $this->action = 'subscribe';
218
+ } elseif ( isset( $_POST['unsubscribe'] ) ) {
219
+ // is this email a subscriber?
220
+ if ( false === $this->is_public( $this->email ) ) {
221
+ $this->s2form = $this->s2form . $this->not_subscribed;
222
+ } else {
223
+ $status = $this->send_confirm( 'del' );
224
+ // set a variable to denote that we've already run, and shouldn't run again
225
+ $this->filtered = 1;
226
+ if ( $status ) {
227
+ $this->s2form = $this->confirmation_sent;
228
+ } else {
229
+ $this->s2form = $this->error;
230
+ }
231
+ }
232
+ $this->action = 'unsubscribe';
233
+ }
234
+ }
235
+ }
236
+ }
237
+ return $this->s2form;
238
+ }
239
+
240
+ /**
241
+ * Display form when deprecated <!--subscribe2--> is used
242
+ */
243
+ public function filter( $content = '' ) {
244
+ if ( '' === $content || ! strstr( $content, '<!--subscribe2-->' ) ) {
245
+ return $content;
246
+ }
247
+
248
+ return preg_replace( '/(<p>)?(\n)*<!--subscribe2-->(\n)*(<\/p>)?/', do_shortcode( '[subscribe2]' ), $content );
249
+ }
250
+
251
+ /**
252
+ * Overrides the default query when handling a (un)subscription confirmation
253
+ * This is basically a trick: if the s2 variable is in the query string, just grab the first
254
+ * static page and override it's contents later with title_filter()
255
+ */
256
+ public function query_filter() {
257
+ // don't interfere if we've already done our thing
258
+ if ( 1 === $this->filtered ) {
259
+ return;
260
+ }
261
+
262
+ global $wpdb;
263
+
264
+ // brute force Simple Facebook Connect to bypass compatiblity issues
265
+ $priority = has_filter( 'wp_head', 'sfc_base_meta' );
266
+ if ( false !== $priority ) {
267
+ remove_action( 'wp_head', 'sfc_base_meta', $priority );
268
+ }
269
+
270
+ if ( 0 !== $this->subscribe2_options['s2page'] ) {
271
+ return array(
272
+ 'page_id' => $this->subscribe2_options['s2page'],
273
+ );
274
+ } else {
275
+ $id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_type='page' AND post_status='publish' LIMIT 1" );
276
+ if ( $id ) {
277
+ return array(
278
+ 'page_id' => $id,
279
+ );
280
+ } else {
281
+ return array(
282
+ 'showposts' => 1,
283
+ );
284
+ }
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Overrides the page title
290
+ */
291
+ public function title_filter( $title ) {
292
+ if ( in_the_loop() ) {
293
+ $code = $_GET['s2'];
294
+ $action = intval( substr( $code, 0, 1 ) );
295
+ if ( 1 === $action ) {
296
+ return __( 'Subscription Confirmation', 'subscribe2' );
297
+ } else {
298
+ return __( 'Unsubscription Confirmation', 'subscribe2' );
299
+ }
300
+ } else {
301
+ return $title;
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Confirm request from the link emailed to the user and email the admin
307
+ */
308
+ public function confirm( $content = '' ) {
309
+ global $wpdb;
310
+
311
+ if ( 1 === $this->filtered && '' !== $this->message ) {
312
+ return $this->message;
313
+ } elseif ( 1 === $this->filtered ) {
314
+ return $content;
315
+ }
316
+
317
+ $code = $_GET['s2'];
318
+ $action = substr( $code, 0, 1 );
319
+ $hash = substr( $code, 1, 32 );
320
+ $id = intval( substr( $code, 33 ) );
321
+ if ( $id ) {
322
+ $this->email = $this->sanitize_email( $this->get_email( $id ) );
323
+ if ( ! $this->email || wp_hash( $this->email ) !== $hash ) {
324
+ return $this->no_such_email;
325
+ }
326
+ } else {
327
+ return $this->no_such_email;
328
+ }
329
+
330
+ // get current status of email so messages are only sent once per emailed link
331
+ $current = $this->is_public( $this->email );
332
+
333
+ if ( '1' === $action ) {
334
+ // make this subscription active
335
+ $this->message = apply_filters( 's2_subscribe_confirmed', $this->added );
336
+ if ( '1' !== $this->is_public( $this->email ) ) {
337
+ $this->ip = esc_html( $this->get_remote_ip() );
338
+ $this->toggle( $this->email );
339
+ if ( 'subs' === $this->subscribe2_options['admin_email'] || 'both' === $this->subscribe2_options['admin_email'] ) {
340
+ $this->admin_email( 'subscribe' );
341
+ }
342
+ }
343
+ $this->filtered = 1;
344
+ } elseif ( '0' === $action ) {
345
+ // remove this public subscriber
346
+ $this->message = apply_filters( 's2_unsubscribe_confirmed', $this->deleted );
347
+ if ( '0' !== $this->is_public( $this->email ) ) {
348
+ $this->delete( $this->email );
349
+ if ( 'unsubs' === $this->subscribe2_options['admin_email'] || 'both' === $this->subscribe2_options['admin_email'] ) {
350
+ $this->admin_email( 'unsubscribe' );
351
+ }
352
+ }
353
+ $this->filtered = 1;
354
+ }
355
+
356
+ if ( '' !== $this->message ) {
357
+ return $this->message;
358
+ }
359
+ }
360
+
361
+ /**
362
+ * Prepare and send emails to admins on new subscriptions and unsubsriptions
363
+ */
364
+ public function admin_email( $action ) {
365
+ if ( ! in_array( $action, array( 'subscribe', 'unsubscribe' ), true ) ) {
366
+ return false;
367
+ }
368
+
369
+ ( '' === get_option( 'blogname' ) ) ? $subject = '' : $subject = '[' . stripslashes( html_entity_decode( get_option( 'blogname' ), ENT_QUOTES ) ) . '] ';
370
+ if ( 'subscribe' === $action ) {
371
+ $subject .= __( 'New Subscription', 'subscribe2' );
372
+ $message = $this->email . ' ' . __( 'subscribed to email notifications!', 'subscribe2' );
373
+ } elseif ( 'unsubscribe' === $action ) {
374
+ $subject .= __( 'New Unsubscription', 'subscribe2' );
375
+ $message = $this->email . ' ' . __( 'unsubscribed from email notifications!', 'subscribe2' );
376
+ }
377
+
378
+ $subject = html_entity_decode( $subject, ENT_QUOTES );
379
+ $role = array(
380
+ 'fields' => array(
381
+ 'user_email',
382
+ ),
383
+ 'role' => 'administrator',
384
+ );
385
+
386
+ $wp_user_query = get_users( $role );
387
+ foreach ( $wp_user_query as $user ) {
388
+ $recipients[] = $user->user_email;
389
+ }
390
+
391
+ $recipients = apply_filters( 's2_admin_email', $recipients, $action );
392
+ $headers = $this->headers();
393
+ // send individual emails so we don't reveal admin emails to each other
394
+ foreach ( $recipients as $recipient ) {
395
+ $status = wp_mail( $recipient, $subject, $message, $headers );
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Add hook for Minimeta Widget plugin
401
+ */
402
+ public function add_minimeta() {
403
+ if ( 0 !== $this->subscribe2_options['s2page'] ) {
404
+ echo '<li><a href="' . get_permalink( $this->subscribe2_options['s2page'] ) . '">' . __( '[Un]Subscribe to Posts', 'subscribe2' ) . '</a></li>' . "\r\n";
405
+ }
406
+ }
407
+
408
+ /**
409
+ * Check email is not from a barred domain
410
+ */
411
+ public function is_barred( $email = '' ) {
412
+ if ( '' === $email ) {
413
+ return false;
414
+ }
415
+
416
+ list( $user, $domain ) = explode( '@', $email, 2 );
417
+
418
+ $domain = '@' . $domain;
419
+
420
+ foreach ( preg_split( '/[\s,]+/', $this->subscribe2_options['barred'] ) as $barred_domain ) {
421
+ if ( false !== strpos( $barred_domain, '!' ) ) {
422
+ $url = explode( '.', str_replace( '!', '', $barred_domain ) );
423
+ $count = count( $url );
424
+ // make sure our exploded domain has at least 2 components e.g. yahoo.*
425
+ if ( $count < 2 ) {
426
+ continue;
427
+ }
428
+ for ( $i = 0; $i < $count; $i++ ) {
429
+ if ( '*' === $url[ $i ] ) {
430
+ unset( $url[ $i ] );
431
+ }
432
+ }
433
+
434
+ $new_barred_domain = '@' . strtolower( trim( implode( '.', $url ) ) );
435
+
436
+ if ( false !== strpos( $barred_domain, '*' ) ) {
437
+ $new_barred_subdomain = '.' . strtolower( trim( implode( '.', $url ) ) );
438
+ if ( false !== stripos( $domain, $new_barred_domain ) || false !== stripos( $domain, $new_barred_subdomain ) ) {
439
+ return false;
440
+ }
441
+ } else {
442
+ if ( false !== stripos( $domain, $new_barred_domain ) ) {
443
+ return false;
444
+ }
445
+ }
446
+ }
447
+
448
+ if ( false === strpos( $barred_domain, '!' ) && false !== strpos( $barred_domain, '*' ) ) {
449
+ // wildcard and explictly allowed checking
450
+ $url = explode( '.', str_replace( '!', '', $barred_domain ) );
451
+ $count = count( $url );
452
+ // make sure our exploded domain has at least 2 components e.g. yahoo.*
453
+ if ( $count < 2 ) {
454
+ continue;
455
+ }
456
+ for ( $i = 0; $i < $count; $i++ ) {
457
+ if ( '*' === $url[ $i ] ) {
458
+ unset( $url[ $i ] );
459
+ }
460
+ }
461
+
462
+ $new_barred_domain = '@' . strtolower( trim( implode( '.', $url ) ) );
463
+ $new_barred_subdomain = '.' . strtolower( trim( implode( '.', $url ) ) );
464
+
465
+ if ( false !== stripos( $domain, $new_barred_domain ) || false !== stripos( $domain, $new_barred_subdomain ) ) {
466
+ return true;
467
+ }
468
+ } else {
469
+ // direct domain string comparison
470
+ $barred_domain = '@' . $barred_domain;
471
+ if ( strtolower( $domain ) === strtolower( trim( $barred_domain ) ) ) {
472
+ return true;
473
+ }
474
+ }
475
+ }
476
+
477
+ return false;
478
+ }
479
+
480
+ /**
481
+ * Collect and return the IP address of the remote client machine
482
+ */
483
+ public function get_remote_ip() {
484
+ $remote_ip = false;
485
+
486
+ // In order of preference, with the best ones for this purpose first
487
+ $address_headers = array(
488
+ 'HTTP_CLIENT_IP',
489
+ 'HTTP_X_FORWARDED_FOR',
490
+ 'HTTP_X_FORWARDED',
491
+ 'HTTP_X_CLUSTER_CLIENT_IP',
492
+ 'HTTP_FORWARDED_FOR',
493
+ 'HTTP_FORWARDED',
494
+ 'REMOTE_ADDR',
495
+ );
496
+
497
+ foreach ( $address_headers as $header ) {
498
+ if ( array_key_exists( $header, $_SERVER ) ) {
499
+ // HTTP_X_FORWARDED_FOR can contain a chain of comma-separated
500
+ // addresses. The first one is the original client. It can't be
501
+ // trusted for authenticity, but we don't need to for this purpose.
502
+ $address_chain = explode( ',', $_SERVER[ $header ] );
503
+ $remote_ip = trim( $address_chain[0] );
504
+ break;
505
+ }
506
+ }
507
+
508
+ return $remote_ip;
509
+ }
510
+
511
+ /**
512
+ * Enqueue javascript ip updater code
513
+ */
514
+ public function js_ip_script() {
515
+ wp_register_script( 's2_ip_updater', S2URL . 'include/s2-ip-updater' . $this->script_debug . '.js', array(), '1.1', true );
516
+ wp_enqueue_script( 's2_ip_updater' );
517
+ }
518
+
519
+ /**
520
+ * Add ip updater library to footer
521
+ */
522
+ public function js_ip_library_script() {
523
+ echo '<script async="async" src="https://api.ipify.org?format=jsonp&callback=getip"></script>' . "\r\n"; // phpcs:ignore WordPress.WP.EnqueuedResources
524
+ }
525
+
526
+ /* ===== define some variables ===== */
527
+ public $profile = '';
528
+ }
 
 
 
 
 
gutenberg/gutenberg-translations.php CHANGED
@@ -2,27 +2,31 @@
2
  /* THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY. */
3
  /* THIS FILE EXPOSES STRINGS FROM JAVASCRIPT FILES FOR TRANSLATION */
4
  $generated_i18n_strings = array(
5
- __( 'Subscribe2 HTML', 'subscribe2' ),
6
- __( 'email', 'subscribe2' ),
7
- __( 'notification', 'subscribe2' ),
8
- __( 'Subscribe2 Shortcode Parameters', 'subscribe2' ),
9
- __( 'Button Display Options', 'subscribe2' ),
10
- __( 'Show Both Buttons', 'subscribe2' ),
11
- __( 'Hide Subscribe Button', 'subscribe2' ),
12
- __( 'Hide Unsubscribe Button', 'subscribe2' ),
13
- __( 'Page ID', 'subscribe2' ),
14
- __( 'Disable Javascript', 'subscribe2' ),
15
- __( 'Disable Simple Anti-Spam Measures', 'subscribe2' ),
16
- __( 'Textbox size', 'subscribe2' ),
17
- __( 'Disable wrapping of form buttons', 'subscribe2' ),
18
- __( 'Link Text', 'subscribe2' ),
19
- __( 'Subscribe2 HTML Shortcode', 'subscribe2' ),
20
- __( 'Check here to disable sending of an email notification for this post/page', 'subscribe2' ),
21
- __( 'Attempt made to send email preview', 'subscribe2' ),
22
- __( 'Subscribe2 Sidebar', 'subscribe2' ),
23
- __( 'Subscribe2 Sidebar', 'subscribe2' ),
24
- __( 'Subscribe2 Override', 'subscribe2' ),
25
- __( 'Subscribe2 Preview', 'subscribe2' ),
26
- __( 'Send preview email of this post to currently logged in user:', 'subscribe2' ),
27
- __( 'Send Preview', 'subscribe2' ),
28
- );
 
 
 
 
2
  /* THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY. */
3
  /* THIS FILE EXPOSES STRINGS FROM JAVASCRIPT FILES FOR TRANSLATION */
4
  $generated_i18n_strings = array(
5
+ __( 'Subscribe2 HTML', 'subscribe2' ),
6
+ __( 'email', 'subscribe2' ),
7
+ __( 'notification', 'subscribe2' ),
8
+ __( 'Subscribe2 Shortcode Parameters', 'subscribe2' ),
9
+ __( 'Button Display Options', 'subscribe2' ),
10
+ __( 'Show Both Buttons', 'subscribe2' ),
11
+ __( 'Hide Subscribe Button', 'subscribe2' ),
12
+ __( 'Hide Unsubscribe Button', 'subscribe2' ),
13
+ __( 'Page ID', 'subscribe2' ),
14
+ __( 'Disable Javascript', 'subscribe2' ),
15
+ __( 'Disable Simple Anti-Spam Measures', 'subscribe2' ),
16
+ __( 'Textbox size', 'subscribe2' ),
17
+ __( 'Disable wrapping of form buttons', 'subscribe2' ),
18
+ __( 'Link Text', 'subscribe2' ),
19
+ __( 'Subscribe2 HTML Shortcode', 'subscribe2' ),
20
+ __( 'Check here to disable sending of an email notification for this post/page', 'subscribe2' ),
21
+ __( 'Subscribe2 Resend', 'subscribe2' ),
22
+ __( 'Resend the notification email of this post to current subscribers:', 'subscribe2' ),
23
+ __( 'Resend Notification', 'subscribe2' ),
24
+ __( 'Attempt made to send email preview', 'subscribe2' ),
25
+ __( 'Attempt made to resend email notification', 'subscribe2' ),
26
+ __( 'Subscribe2 Sidebar', 'subscribe2' ),
27
+ __( 'Subscribe2 Sidebar', 'subscribe2' ),
28
+ __( 'Subscribe2 Override', 'subscribe2' ),
29
+ __( 'Subscribe2 Preview', 'subscribe2' ),
30
+ __( 'Send preview email of this post to currently logged in user:', 'subscribe2' ),
31
+ __( 'Send Preview', 'subscribe2' ),
32
+ );
gutenberg/shortcode.js CHANGED
@@ -4,398 +4,398 @@
4
  // Version 1.1 - eslinted and fixed bug in transformation of wrap attribute
5
 
6
  ( function( blocks, i18n, element, components, editor ) {
7
- var el = element.createElement,
8
- TextControl = components.TextControl,
9
- CheckboxControl = components.CheckboxControl,
10
- RadioControl = components.RadioControl;
11
 
12
- function s2shortcode( props, control, newVal ) {
13
- var attributes = props.attributes || '';
14
- var hide = '',
15
- id = '',
16
- nojs = '',
17
- antispam = '',
18
- size = '',
19
- wrap = '',
20
- link = '';
21
 
22
- // First we define the shortcode parameters from known Control values
23
- if ( 'subscribe' === attributes.hide ) {
24
- hide = ' hide="subscribe"';
25
- } else if ( 'unsubscribe' === attributes.hide ) {
26
- hide = ' hide="unsubscribe"';
27
- }
28
- if ( '' !== attributes.id && undefined !== attributes.id ) {
29
- id = ' id="' + attributes.id + '"';
30
- }
31
- if ( true === attributes.nojs ) {
32
- nojs = ' nojs="true"';
33
- }
34
- if ( true === attributes.antispam ) {
35
- antispam = ' antispam="true"';
36
- }
37
- if ( '' !== attributes.size && undefined !== attributes.size && '20' !== attributes.size ) {
38
- size = ' size="' + attributes.size + '"';
39
- }
40
- if ( true === attributes.wrap ) {
41
- wrap = ' wrap="false"';
42
- }
43
- if ( '' !== attributes.link && undefined !== attributes.link ) {
44
- link = ' link="' + attributes.link + '"';
45
- }
46
 
47
- // Second we amend parameter values based on recent input as values are asynchronous
48
- switch ( control ) {
49
- case 'hide':
50
- if ( 'none' === newVal ) {
51
- hide = '';
52
- } else if ( 'subscribe' === newVal ) {
53
- hide = ' hide="subscribe"';
54
- } else if ( 'unsubscribe' === newVal ) {
55
- hide = ' hide="unsubscribe"';
56
- }
57
- break;
58
- case 'id':
59
- if ( '' === newVal ) {
60
- id = '';
61
- } else {
62
- id = ' id="' + newVal + '"';
63
- }
64
- break;
65
- case 'nojs':
66
- if ( true === newVal ) {
67
- nojs = ' nojs="true"';
68
- } else if ( false === newVal ) {
69
- nojs = '';
70
- }
71
- break;
72
- case 'antispam':
73
- if ( true === newVal ) {
74
- antispam = ' antispam="true"';
75
- } else if ( false === newVal ) {
76
- antispam = '';
77
- }
78
- break;
79
- case 'size':
80
- if ( '20' === newVal ) {
81
- size = '';
82
- } else {
83
- size = ' size="' + newVal + '"';
84
- }
85
- break;
86
- case 'wrap':
87
- if ( true === newVal ) {
88
- wrap = ' wrap="false"';
89
- } else if ( false === newVal ) {
90
- wrap = '';
91
- }
92
- break;
93
- case 'link':
94
- if ( '' === newVal ) {
95
- link = '';
96
- } else {
97
- link = ' link="' + newVal + '"';
98
- }
99
- break;
100
- default:
101
- break;
102
- }
103
 
104
- // Now we construct and return our shortcode
105
- props.attributes.shortcode = '[subscribe2' + hide + id + nojs + antispam + size + wrap + link + ']';
106
- return props.attributes.shortcode;
107
- }
108
 
109
- blocks.registerBlockType(
110
- 'subscribe2-html/shortcode',
111
- {
112
- title: i18n.__( 'Subscribe2 HTML', 'subscribe2' ),
113
- icon: 'email',
114
- category: 'widgets',
115
- keywords: [
116
- i18n.__( 'email', 'subscribe2' ),
117
- i18n.__( 'notification', 'subscribe2' )
118
- ],
119
- supports: {
120
- customClassName: false,
121
- className: false,
122
- multiple: false,
123
- html: false
124
- },
125
- attributes: {
126
- shortcode: {
127
- type: 'text',
128
- selector: 'p'
129
- },
130
- hide: {
131
- type: 'string'
132
- },
133
- id: {
134
- type: 'string'
135
- },
136
- nojs: {
137
- type: 'boolean'
138
- },
139
- antispam: {
140
- type: 'boolean'
141
- },
142
- size: {
143
- type: 'number'
144
- },
145
- wrap: {
146
- type: 'boolean'
147
- },
148
- link: {
149
- type: 'string'
150
- }
151
- },
152
- transforms: {
153
- to: [
154
- {
155
- type: 'block',
156
- blocks: [ 'core/shortcode' ],
157
- transform: function( content ) {
158
- if ( undefined === content.shortcode || '' === content.shortcode ) {
159
- content.shortcode = '[subscribe2]';
160
- }
161
- return blocks.createBlock( 'core/shortcode', { text: content.shortcode } );
162
- }
163
- }
164
- ],
165
- from: [
166
- {
167
- type: 'block',
168
- blocks: [ 'core/shortcode' ],
169
- transform: function( content ) {
170
- var shortcode, params, param, hide, id, nojs, antispam, size, wrap, link, i, l;
171
- if ( 'subscribe2' === content.text.substr( 1, 10 ) ) {
172
- shortcode = content.text;
173
- params = content.text.replace( /^\[subscribe2|\]$/g, '' ).replace( /^\s+|\s+$/g, '' ).split( /['"]\s/g );
174
- l = params.length;
175
 
176
- for ( i = 0; i < l; i++ ) {
177
- param = params[i].split( '=' );
178
- if ( 'hide' === param[0] ) {
179
- hide = param[1].replace( /['"]+/g, '' );
180
- }
181
- if ( 'id' === param[0] ) {
182
- id = param[1].replace( /['"]+/g, '' );
183
- }
184
- if ( 'nojs' === param[0] ) {
185
- nojs = 'true' === param[1].replace( /['"]+/g, '' );
186
- }
187
- if ( 'antispam' === param[0] ) {
188
- antispam = 'true' === param[1].replace( /['"]+/g, '' );
189
- }
190
- if ( 'size' === param[0] ) {
191
- size = param[1].replace( /['"]+/g, '' );
192
- }
193
- if ( 'wrap' === param[0] ) {
194
- wrap = 'false' === param[1].replace( /['"]+/g, '' );
195
- }
196
- if ( 'link' === param[0] ) {
197
- link = param[1].replace( /^['"]|['"]$/g, '' );
198
- }
199
- }
200
 
201
- return blocks.createBlock(
202
- 'subscribe2-html/shortcode',
203
- {
204
- shortcode: shortcode,
205
- hide: hide,
206
- id: id,
207
- nojs: nojs,
208
- antispam: antispam,
209
- size: size,
210
- wrap: wrap,
211
- link: link
212
- }
213
- );
214
- }
215
- }
216
- },
217
- {
218
- type: 'shortcode',
219
- tag: 'subscribe2',
220
- attributes: {
221
- shortcode: {
222
- type: 'string',
223
- selector: 'p'
224
- },
225
- hide: {
226
- type: 'string',
227
- shortcode: function( content ) {
228
- return content.named.hide || 'none';
229
- }
230
- },
231
- id: {
232
- type: 'string',
233
- shortcode: function( content ) {
234
- return content.named.id || '';
235
- }
236
- },
237
- nojs: {
238
- type: 'boolean',
239
- shortcode: function( content ) {
240
- return content.named.nojs || false;
241
- }
242
- },
243
- antispam: {
244
- type: 'boolean',
245
- shortcode: function( content ) {
246
- return content.named.antispam || false;
247
- }
248
- },
249
- size: {
250
- type: 'number',
251
- shortcode: function( content ) {
252
- return content.named.size || '20';
253
- }
254
- },
255
- wrap: {
256
- type: 'boolean',
257
- shortcode: function( content ) {
258
- return content.named.wrap || false;
259
- }
260
- },
261
- link: {
262
- type: 'string',
263
- shortcode: function( content ) {
264
- return content.named.link || '';
265
- }
266
- }
267
- }
268
- }
269
- ]
270
- },
271
- edit: function( props ) {
272
- var hide = props.attributes.hide || 'none',
273
- id = props.attributes.id || '',
274
- nojs = props.attributes.nojs || false,
275
- antispam = props.attributes.antispam || false,
276
- size = props.attributes.size || '20',
277
- wrap = props.attributes.wrap || false,
278
- link = props.attributes.link || '',
279
- isSelected = props.isSelected;
280
 
281
- function onChangeHide( newHide ) {
282
- props.attributes.shortcode = s2shortcode( props, 'hide', newHide );
283
- props.setAttributes( { hide: newHide } );
284
- }
285
- function onChangeId( newId ) {
286
- props.attributes.shortcode = s2shortcode( props, 'id', newId );
287
- props.setAttributes( { id: newId } );
288
- }
289
- function onChangeNojs( newNojs ) {
290
- props.attributes.shortcode = s2shortcode( props, 'nojs', newNojs );
291
- props.setAttributes( { nojs: newNojs } );
292
- }
293
- function onChangeAntispam( newAntispam ) {
294
- props.attributes.shortcode = s2shortcode( props, 'antispam', newAntispam );
295
- props.setAttributes( { antispam: newAntispam } );
296
- }
297
- function onChangeSize( newSize ) {
298
- props.attributes.shortcode = s2shortcode( props, 'size', newSize );
299
- props.setAttributes( { size: newSize } );
300
- }
301
- function onChangeWrap( newWrap ) {
302
- props.attributes.shortcode = s2shortcode( props, 'wrap', newWrap );
303
- props.setAttributes( { wrap: newWrap } );
304
- }
305
- function onChangeLink( newLink ) {
306
- props.attributes.shortcode = s2shortcode( props, 'link', newLink );
307
- props.setAttributes( { link: newLink } );
308
- }
309
 
310
- return [
311
- isSelected && el(
312
- editor.InspectorControls,
313
- { key: 'subscribe2-html/inspector' },
314
- el( 'h3', {}, i18n.__( 'Subscribe2 Shortcode Parameters', 'subscribe2' ) ),
315
- el(
316
- RadioControl,
317
- {
318
- label: i18n.__( 'Button Display Options', 'subscribe2' ),
319
- selected: hide,
320
- onChange: onChangeHide,
321
- options: [
322
- { value: 'none', label: i18n.__( 'Show Both Buttons', 'subscribe2' ) },
323
- { value: 'subscribe', label: i18n.__( 'Hide Subscribe Button', 'subscribe2' ) },
324
- { value: 'unsubscribe', label: i18n.__( 'Hide Unsubscribe Button', 'subscribe2' ) }
325
- ]
326
- }
327
- ),
328
- el(
329
- TextControl,
330
- {
331
- type: 'number',
332
- label: i18n.__( 'Page ID', 'subscribe2' ),
333
- value: id,
334
- onChange: onChangeId
335
- }
336
- ),
337
- el(
338
- CheckboxControl,
339
- {
340
- label: i18n.__( 'Disable Javascript', 'subscribe2' ),
341
- checked: nojs,
342
- onChange: onChangeNojs
343
- }
344
- ),
345
- el(
346
- CheckboxControl,
347
- {
348
- label: i18n.__( 'Disable Simple Anti-Spam Measures', 'subscribe2' ),
349
- checked: antispam,
350
- onChange: onChangeAntispam
351
- }
352
- ),
353
- el(
354
- TextControl,
355
- {
356
- type: 'number',
357
- label: i18n.__( 'Textbox size', 'subscribe2' ),
358
- value: size,
359
- onChange: onChangeSize
360
- }
361
- ),
362
- el(
363
- CheckboxControl,
364
- {
365
- label: i18n.__( 'Disable wrapping of form buttons', 'subscribe2' ),
366
- checked: wrap,
367
- onChange: onChangeWrap
368
- }
369
- ),
370
- el(
371
- TextControl,
372
- {
373
- type: 'string',
374
- label: i18n.__( 'Link Text', 'subscribe2' ),
375
- value: link,
376
- onChange: onChangeLink
377
- }
378
- )
379
- ),
380
- el(
381
- 'div',
382
- {
383
- key: 'subscribe2-html/block',
384
- style: { backgroundColor: '#ff0', color: '#000', padding: '2px', 'textAlign': 'center' }
385
- },
386
- i18n.__( 'Subscribe2 HTML Shortcode', 'subscribe2' )
387
- )
388
- ];
389
- },
390
- save: function( props ) {
391
- return el( element.RawHTML, null, '<p>' + props.attributes.shortcode + '</p>' );
392
- }
393
- }
394
- );
395
  } (
396
- window.wp.blocks,
397
- window.wp.i18n,
398
- window.wp.element,
399
- window.wp.components,
400
- window.wp.editor
401
- ) );
4
  // Version 1.1 - eslinted and fixed bug in transformation of wrap attribute
5
 
6
  ( function( blocks, i18n, element, components, editor ) {
7
+ var el = element.createElement,
8
+ TextControl = components.TextControl,
9
+ CheckboxControl = components.CheckboxControl,
10
+ RadioControl = components.RadioControl;
11
 
12
+ function s2shortcode( props, control, newVal ) {
13
+ var attributes = props.attributes || '';
14
+ var hide = '',
15
+ id = '',
16
+ nojs = '',
17
+ antispam = '',
18
+ size = '',
19
+ wrap = '',
20
+ link = '';
21
 
22
+ // First we define the shortcode parameters from known Control values
23
+ if ( 'subscribe' === attributes.hide ) {
24
+ hide = ' hide="subscribe"';
25
+ } else if ( 'unsubscribe' === attributes.hide ) {
26
+ hide = ' hide="unsubscribe"';
27
+ }
28
+ if ( '' !== attributes.id && undefined !== attributes.id ) {
29
+ id = ' id="' + attributes.id + '"';
30
+ }
31
+ if ( true === attributes.nojs ) {
32
+ nojs = ' nojs="true"';
33
+ }
34
+ if ( true === attributes.antispam ) {
35
+ antispam = ' antispam="true"';
36
+ }
37
+ if ( '' !== attributes.size && undefined !== attributes.size && '20' !== attributes.size ) {
38
+ size = ' size="' + attributes.size + '"';
39
+ }
40
+ if ( true === attributes.wrap ) {
41
+ wrap = ' wrap="false"';
42
+ }
43
+ if ( '' !== attributes.link && undefined !== attributes.link ) {
44
+ link = ' link="' + attributes.link + '"';
45
+ }
46
 
47
+ // Second we amend parameter values based on recent input as values are asynchronous
48
+ switch ( control ) {
49
+ case 'hide':
50
+ if ( 'none' === newVal ) {
51
+ hide = '';
52
+ } else if ( 'subscribe' === newVal ) {
53
+ hide = ' hide="subscribe"';
54
+ } else if ( 'unsubscribe' === newVal ) {
55
+ hide = ' hide="unsubscribe"';
56
+ }
57
+ break;
58
+ case 'id':
59
+ if ( '' === newVal ) {
60
+ id = '';
61
+ } else {
62
+ id = ' id="' + newVal + '"';
63
+ }
64
+ break;
65
+ case 'nojs':
66
+ if ( true === newVal ) {
67
+ nojs = ' nojs="true"';
68
+ } else if ( false === newVal ) {
69
+ nojs = '';
70
+ }
71
+ break;
72
+ case 'antispam':
73
+ if ( true === newVal ) {
74
+ antispam = ' antispam="true"';
75
+ } else if ( false === newVal ) {
76
+ antispam = '';
77
+ }
78
+ break;
79
+ case 'size':
80
+ if ( '20' === newVal ) {
81
+ size = '';
82
+ } else {
83
+ size = ' size="' + newVal + '"';
84
+ }
85
+ break;
86
+ case 'wrap':
87
+ if ( true === newVal ) {
88
+ wrap = ' wrap="false"';
89
+ } else if ( false === newVal ) {
90
+ wrap = '';
91
+ }
92
+ break;
93
+ case 'link':
94
+ if ( '' === newVal ) {
95
+ link = '';
96
+ } else {
97
+ link = ' link="' + newVal + '"';
98
+ }
99
+ break;
100
+ default:
101
+ break;
102
+ }
103
 
104
+ // Now we construct and return our shortcode
105
+ props.attributes.shortcode = '[subscribe2' + hide + id + nojs + antispam + size + wrap + link + ']';
106
+ return props.attributes.shortcode;
107
+ }
108
 
109
+ blocks.registerBlockType(
110
+ 'subscribe2-html/shortcode',
111
+ {
112
+ title: i18n.__( 'Subscribe2 HTML', 'subscribe2' ),
113
+ icon: 'email',
114
+ category: 'widgets',
115
+ keywords: [
116
+ i18n.__( 'email', 'subscribe2' ),
117
+ i18n.__( 'notification', 'subscribe2' )
118
+ ],
119
+ supports: {
120
+ customClassName: false,
121
+ className: false,
122
+ multiple: false,
123
+ html: false
124
+ },
125
+ attributes: {
126
+ shortcode: {
127
+ type: 'text',
128
+ selector: 'p'
129
+ },
130
+ hide: {
131
+ type: 'string'
132
+ },
133
+ id: {
134
+ type: 'string'
135
+ },
136
+ nojs: {
137
+ type: 'boolean'
138
+ },
139
+ antispam: {
140
+ type: 'boolean'
141
+ },
142
+ size: {
143
+ type: 'number'
144
+ },
145
+ wrap: {
146
+ type: 'boolean'
147
+ },
148
+ link: {
149
+ type: 'string'
150
+ }
151
+ },
152
+ transforms: {
153
+ to: [
154
+ {
155
+ type: 'block',
156
+ blocks: [ 'core/shortcode' ],
157
+ transform: function( content ) {
158
+ if ( undefined === content.shortcode || '' === content.shortcode ) {
159
+ content.shortcode = '[subscribe2]';
160
+ }
161
+ return blocks.createBlock( 'core/shortcode', { text: content.shortcode } );
162
+ }
163
+ }
164
+ ],
165
+ from: [
166
+ {
167
+ type: 'block',
168
+ blocks: [ 'core/shortcode' ],
169
+ transform: function( content ) {
170
+ var shortcode, params, param, hide, id, nojs, antispam, size, wrap, link, i, l;
171
+ if ( 'subscribe2' === content.text.substr( 1, 10 ) ) {
172
+ shortcode = content.text;
173
+ params = content.text.replace( /^\[subscribe2|\]$/g, '' ).replace( /^\s+|\s+$/g, '' ).split( /['"]\s/g );
174
+ l = params.length;
175
 
176
+ for ( i = 0; i < l; i++ ) {
177
+ param = params[i].split( '=' );
178
+ if ( 'hide' === param[0] ) {
179
+ hide = param[1].replace( /['"]+/g, '' );
180
+ }
181
+ if ( 'id' === param[0] ) {
182
+ id = param[1].replace( /['"]+/g, '' );
183
+ }
184
+ if ( 'nojs' === param[0] ) {
185
+ nojs = 'true' === param[1].replace( /['"]+/g, '' );
186
+ }
187
+ if ( 'antispam' === param[0] ) {
188
+ antispam = 'true' === param[1].replace( /['"]+/g, '' );
189
+ }
190
+ if ( 'size' === param[0] ) {
191
+ size = param[1].replace( /['"]+/g, '' );
192
+ }
193
+ if ( 'wrap' === param[0] ) {
194
+ wrap = 'false' === param[1].replace( /['"]+/g, '' );
195
+ }
196
+ if ( 'link' === param[0] ) {
197
+ link = param[1].replace( /^['"]|['"]$/g, '' );
198
+ }
199
+ }
200
 
201
+ return blocks.createBlock(
202
+ 'subscribe2-html/shortcode',
203
+ {
204
+ shortcode: shortcode,
205
+ hide: hide,
206
+ id: id,
207
+ nojs: nojs,
208
+ antispam: antispam,
209
+ size: size,
210
+ wrap: wrap,
211
+ link: link
212
+ }
213
+ );
214
+ }
215
+ }
216
+ },
217
+ {
218
+ type: 'shortcode',
219
+ tag: 'subscribe2',
220
+ attributes: {
221
+ shortcode: {
222
+ type: 'string',
223
+ selector: 'p'
224
+ },
225
+ hide: {
226
+ type: 'string',
227
+ shortcode: function( content ) {
228
+ return content.named.hide || 'none';
229
+ }
230
+ },
231
+ id: {
232
+ type: 'string',
233
+ shortcode: function( content ) {
234
+ return content.named.id || '';
235
+ }
236
+ },
237
+ nojs: {
238
+ type: 'boolean',
239
+ shortcode: function( content ) {
240
+ return content.named.nojs || false;
241
+ }
242
+ },
243
+ antispam: {
244
+ type: 'boolean',
245
+ shortcode: function( content ) {
246
+ return content.named.antispam || false;
247
+ }
248
+ },
249
+ size: {
250
+ type: 'number',
251
+ shortcode: function( content ) {
252
+ return content.named.size || '20';
253
+ }
254
+ },
255
+ wrap: {
256
+ type: 'boolean',
257
+ shortcode: function( content ) {
258
+ return content.named.wrap || false;
259
+ }
260
+ },
261
+ link: {
262
+ type: 'string',
263
+ shortcode: function( content ) {
264
+ return content.named.link || '';
265
+ }
266
+ }
267
+ }
268
+ }
269
+ ]
270
+ },
271
+ edit: function( props ) {
272
+ var hide = props.attributes.hide || 'none',
273
+ id = props.attributes.id || '',
274
+ nojs = props.attributes.nojs || false,
275
+ antispam = props.attributes.antispam || false,
276
+ size = props.attributes.size || '20',
277
+ wrap = props.attributes.wrap || false,
278
+ link = props.attributes.link || '',
279
+ isSelected = props.isSelected;
280
 
281
+ function onChangeHide( newHide ) {
282
+ props.attributes.shortcode = s2shortcode( props, 'hide', newHide );
283
+ props.setAttributes( { hide: newHide } );
284
+ }
285
+ function onChangeId( newId ) {
286
+ props.attributes.shortcode = s2shortcode( props, 'id', newId );
287
+ props.setAttributes( { id: newId } );
288
+ }
289
+ function onChangeNojs( newNojs ) {
290
+ props.attributes.shortcode = s2shortcode( props, 'nojs', newNojs );
291
+ props.setAttributes( { nojs: newNojs } );
292
+ }
293
+ function onChangeAntispam( newAntispam ) {
294
+ props.attributes.shortcode = s2shortcode( props, 'antispam', newAntispam );
295
+ props.setAttributes( { antispam: newAntispam } );
296
+ }
297
+ function onChangeSize( newSize ) {
298
+ props.attributes.shortcode = s2shortcode( props, 'size', newSize );
299
+ props.setAttributes( { size: newSize } );
300
+ }
301
+ function onChangeWrap( newWrap ) {
302
+ props.attributes.shortcode = s2shortcode( props, 'wrap', newWrap );
303
+ props.setAttributes( { wrap: newWrap } );
304
+ }
305
+ function onChangeLink( newLink ) {
306
+ props.attributes.shortcode = s2shortcode( props, 'link', newLink );
307
+ props.setAttributes( { link: newLink } );
308
+ }
309
 
310
+ return [
311
+ isSelected && el(
312
+ editor.InspectorControls,
313
+ { key: 'subscribe2-html/inspector' },
314
+ el( 'h3', {}, i18n.__( 'Subscribe2 Shortcode Parameters', 'subscribe2' ) ),
315
+ el(
316
+ RadioControl,
317
+ {
318
+ label: i18n.__( 'Button Display Options', 'subscribe2' ),
319
+ selected: hide,
320
+ onChange: onChangeHide,
321
+ options: [
322
+ { value: 'none', label: i18n.__( 'Show Both Buttons', 'subscribe2' ) },
323
+ { value: 'subscribe', label: i18n.__( 'Hide Subscribe Button', 'subscribe2' ) },
324
+ { value: 'unsubscribe', label: i18n.__( 'Hide Unsubscribe Button', 'subscribe2' ) }
325
+ ]
326
+ }
327
+ ),
328
+ el(
329
+ TextControl,
330
+ {
331
+ type: 'number',
332
+ label: i18n.__( 'Page ID', 'subscribe2' ),
333
+ value: id,
334
+ onChange: onChangeId
335
+ }
336
+ ),
337
+ el(
338
+ CheckboxControl,
339
+ {
340
+ label: i18n.__( 'Disable Javascript', 'subscribe2' ),
341
+ checked: nojs,
342
+ onChange: onChangeNojs
343
+ }
344
+ ),
345
+ el(
346
+ CheckboxControl,
347
+ {
348
+ label: i18n.__( 'Disable Simple Anti-Spam Measures', 'subscribe2' ),
349
+ checked: antispam,
350
+ onChange: onChangeAntispam
351
+ }
352
+ ),
353
+ el(
354
+ TextControl,
355
+ {
356
+ type: 'number',
357
+ label: i18n.__( 'Textbox size', 'subscribe2' ),
358
+ value: size,
359
+ onChange: onChangeSize
360
+ }
361
+ ),
362
+ el(
363
+ CheckboxControl,
364
+ {
365
+ label: i18n.__( 'Disable wrapping of form buttons', 'subscribe2' ),
366
+ checked: wrap,
367
+ onChange: onChangeWrap
368
+ }
369
+ ),
370
+ el(
371
+ TextControl,
372
+ {
373
+ type: 'string',
374
+ label: i18n.__( 'Link Text', 'subscribe2' ),
375
+ value: link,
376
+ onChange: onChangeLink
377
+ }
378
+ )
379
+ ),
380
+ el(
381
+ 'div',
382
+ {
383
+ key: 'subscribe2-html/block',
384
+ style: { backgroundColor: '#ff0', color: '#000', padding: '2px', 'textAlign': 'center' }
385
+ },
386
+ i18n.__( 'Subscribe2 HTML Shortcode', 'subscribe2' )
387
+ )
388
+ ];
389
+ },
390
+ save: function( props ) {
391
+ return el( element.RawHTML, null, '<p>' + props.attributes.shortcode + '</p>' );
392
+ }
393
+ }
394
+ );
395
  } (
396
+ window.wp.blocks,
397
+ window.wp.i18n,
398
+ window.wp.element,
399
+ window.wp.components,
400
+ window.wp.editor
401
+ ) );
gutenberg/sidebar.js CHANGED
@@ -1,149 +1,205 @@
1
  // Version 1.0 - Initial version
 
 
 
 
 
 
 
 
 
2
 
3
  ( function( plugins, element, i18n, editPost, components, data, compose, apiFetch ) {
4
- var registerPlugin = plugins.registerPlugin,
5
- el = element.createElement,
6
- __ = i18n.__,
7
- Fragment = element.Fragment,
8
- PluginSidebar = editPost.PluginSidebar,
9
- PluginSidebarMoreMenuItem = editPost.PluginSidebarMoreMenuItem,
10
- PanelBody = components.PanelBody,
11
- PanelRow = components.PanelRow,
12
- CheckboxControl = components.CheckboxControl,
13
- Button = components.Button,
14
- select = data.select,
15
- dispatch = data.dispatch,
16
- withSelect = data.withSelect,
17
- withDispatch = data.withDispatch,
18
- Compose = compose.compose;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
- var CheckboxControlMeta = Compose(
21
- withSelect(
22
- function( select, props ) {
23
- var s2mail = select( 'core/editor' ).getEditedPostAttribute( 'meta' )[ props.fieldName ];
24
- return {
25
- metaChecked: ( 'no' === s2mail ? true : false )
26
- };
27
- }
28
- ),
29
- withDispatch(
30
- function( dispatch, props ) {
31
- return {
32
- setMetaChecked: function( value ) {
33
- var s2mail = ( true === value ? 'no' : 'yes' );
34
- dispatch( 'core/editor' ).editPost( { meta: { [props.fieldName]: s2mail } } );
35
- dispatch( 'core/editor' ).savePost();
36
- }
37
- };
38
- }
39
- )
40
- )(
41
- function( props ) {
42
- return el(
43
- CheckboxControl,
44
- {
45
- label: __( 'Check here to disable sending of an email notification for this post/page', 'subscribe2' ),
46
- checked: props.metaChecked,
47
- onChange: function( content ) {
48
- props.setMetaChecked( content );
49
- }
50
- }
51
- );
52
- }
53
- );
54
 
55
- var buttonClick = function() {
56
- var postid = select( 'core/editor' ).getCurrentPostId();
57
- dispatch( 'core/editor' ).savePost();
58
- apiFetch( { path: '/s2/v1/preview/' + postid } );
59
- dispatch( 'core/notices' ).createInfoNotice( __( 'Attempt made to send email preview', 'subscribe2' ) );
60
- };
61
 
62
- var s2sidebar = function() {
63
- return el(
64
- Fragment,
65
- {},
66
- el(
67
- PluginSidebarMoreMenuItem,
68
- {
69
- target: 's2-sidebar',
70
- icon: 'email'
71
- },
72
- __( 'Subscribe2 Sidebar', 'subscribe2' )
73
- ),
74
- el(
75
- PluginSidebar,
76
- {
77
- name: 's2-sidebar',
78
- title: __( 'Subscribe2 Sidebar', 'subscribe2' ),
79
- icon: 'email',
80
- isPinned: true,
81
- isPinnable: true,
82
- togglePin: true,
83
- togglesidebar: false
84
- },
85
- el(
86
- PanelBody,
87
- {
88
- title: __( 'Subscribe2 Override', 'subscribe2' ),
89
- initialOpen: true
90
- },
91
- el(
92
- PanelRow,
93
- {},
94
- el(
95
- CheckboxControlMeta,
96
- {
97
- fieldName: '_s2mail'
98
- }
99
- )
100
- )
101
- ),
102
- el(
103
- PanelBody,
104
- {
105
- title: __( 'Subscribe2 Preview', 'subscribe2' ),
106
- initialOpen: true
107
- },
108
- el(
109
- PanelRow,
110
- {},
111
- el(
112
- 'div',
113
- null,
114
- __( 'Send preview email of this post to currently logged in user:', 'subscribe2' )
115
- )
116
- ),
117
- el(
118
- PanelRow,
119
- {},
120
- el(
121
- Button,
122
- {
123
- isDefault: true,
124
- onClick: buttonClick
125
- },
126
- __( 'Send Preview', 'subscribe2' )
127
- )
128
- )
129
- )
130
- )
131
- );
132
- };
 
133
 
134
- registerPlugin(
135
- 'subscribe2-sidebar',
136
- {
137
- render: s2sidebar
138
- }
139
- );
140
  } (
141
- wp.plugins,
142
- wp.element,
143
- wp.i18n,
144
- wp.editPost,
145
- wp.components,
146
- wp.data,
147
- wp.compose,
148
- wp.apiFetch
149
- ) );
1
  // Version 1.0 - Initial version
2
+ // Version 1.1 - Add Resend functionality
3
+
4
+ var privSetting = '';
5
+
6
+ wp.apiFetch( { path: '/s2/v1/settings/private' } ).then(
7
+ function ( setting ) {
8
+ privSetting = setting;
9
+ }
10
+ );
11
 
12
  ( function( plugins, element, i18n, editPost, components, data, compose, apiFetch ) {
13
+ var registerPlugin = plugins.registerPlugin,
14
+ el = element.createElement,
15
+ __ = i18n.__,
16
+ Fragment = element.Fragment,
17
+ PluginSidebar = editPost.PluginSidebar,
18
+ PluginSidebarMoreMenuItem = editPost.PluginSidebarMoreMenuItem,
19
+ PanelBody = components.PanelBody,
20
+ PanelRow = components.PanelRow,
21
+ CheckboxControl = components.CheckboxControl,
22
+ Button = components.Button,
23
+ select = data.select,
24
+ dispatch = data.dispatch,
25
+ withSelect = data.withSelect,
26
+ withDispatch = data.withDispatch,
27
+ Compose = compose.compose;
28
+
29
+ var CheckboxControlMeta = Compose(
30
+ withSelect(
31
+ function( select, props ) {
32
+ var s2mail = select( 'core/editor' ).getEditedPostAttribute( 'meta' )[ props.fieldName ];
33
+ return {
34
+ metaChecked: ( 'no' === s2mail ? true : false )
35
+ };
36
+ }
37
+ ),
38
+ withDispatch(
39
+ function( dispatch, props ) {
40
+ return {
41
+ setMetaChecked: function( value ) {
42
+ var s2mail = ( true === value ? 'no' : 'yes' );
43
+ dispatch( 'core/editor' ).editPost( { meta: { [ props.fieldName ]: s2mail } } );
44
+ dispatch( 'core/editor' ).savePost();
45
+ }
46
+ };
47
+ }
48
+ )
49
+ )(
50
+ function( props ) {
51
+ return el(
52
+ CheckboxControl,
53
+ {
54
+ label: __( 'Check here to disable sending of an email notification for this post/page', 'subscribe2' ),
55
+ checked: props.metaChecked,
56
+ onChange: function( content ) {
57
+ props.setMetaChecked( content );
58
+ }
59
+ }
60
+ );
61
+ }
62
+ );
63
+
64
+ var maybeRenderResend = function( privSetting ) {
65
+ if ( 'publish' === select( 'core/editor' ).getEditedPostAttribute( 'status' ) ) {
66
+ return renderResendPanel();
67
+ } else if ( 'private' === select( 'core/editor' ).getEditedPostAttribute( 'status' ) && 'yes' === privSetting ) {
68
+ return renderResendPanel();
69
+ }
70
+ };
71
+
72
+ var renderResendPanel = function() {
73
+ return el(
74
+ PanelBody,
75
+ {
76
+ title: __( 'Subscribe2 Resend', 'subscribe2' ),
77
+ initialOpen: false
78
+ },
79
+ el(
80
+ PanelRow,
81
+ {},
82
+ el(
83
+ 'div',
84
+ null,
85
+ __( 'Resend the notification email of this post to current subscribers:', 'subscribe2' )
86
+ )
87
+ ),
88
+ el(
89
+ PanelRow,
90
+ {},
91
+ el(
92
+ Button,
93
+ {
94
+ isDefault: true,
95
+ onClick: resendClick
96
+ },
97
+ __( 'Resend Notification', 'subscribe2' )
98
+ )
99
+ )
100
+ );
101
+ };
102
 
103
+ var previewClick = function() {
104
+ var postid = select( 'core/editor' ).getCurrentPostId();
105
+ dispatch( 'core/editor' ).savePost();
106
+ apiFetch( { path: '/s2/v1/preview/' + postid } );
107
+ dispatch( 'core/notices' ).createInfoNotice( __( 'Attempt made to send email preview', 'subscribe2' ) );
108
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
+ var resendClick = function() {
111
+ var postid = select( 'core/editor' ).getCurrentPostId();
112
+ dispatch( 'core/editor' ).savePost();
113
+ apiFetch( { path: '/s2/v1/resend/' + postid } );
114
+ dispatch( 'core/notices' ).createInfoNotice( __( 'Attempt made to resend email notification', 'subscribe2' ) );
115
+ };
116
 
117
+ var s2sidebar = function() {
118
+ return el(
119
+ Fragment,
120
+ {},
121
+ el(
122
+ PluginSidebarMoreMenuItem,
123
+ {
124
+ target: 's2-sidebar',
125
+ icon: 'email'
126
+ },
127
+ __( 'Subscribe2 Sidebar', 'subscribe2' )
128
+ ),
129
+ el(
130
+ PluginSidebar,
131
+ {
132
+ name: 's2-sidebar',
133
+ title: __( 'Subscribe2 Sidebar', 'subscribe2' ),
134
+ icon: 'email',
135
+ isPinned: true,
136
+ isPinnable: true,
137
+ togglePin: true,
138
+ togglesidebar: false
139
+ },
140
+ el(
141
+ PanelBody,
142
+ {
143
+ title: __( 'Subscribe2 Override', 'subscribe2' ),
144
+ initialOpen: true
145
+ },
146
+ el(
147
+ PanelRow,
148
+ {},
149
+ el(
150
+ CheckboxControlMeta,
151
+ {
152
+ fieldName: '_s2mail'
153
+ }
154
+ )
155
+ )
156
+ ),
157
+ el(
158
+ PanelBody,
159
+ {
160
+ title: __( 'Subscribe2 Preview', 'subscribe2' ),
161
+ initialOpen: false
162
+ },
163
+ el(
164
+ PanelRow,
165
+ {},
166
+ el(
167
+ 'div',
168
+ null,
169
+ __( 'Send preview email of this post to currently logged in user:', 'subscribe2' )
170
+ )
171
+ ),
172
+ el(
173
+ PanelRow,
174
+ {},
175
+ el(
176
+ Button,
177
+ {
178
+ isDefault: true,
179
+ onClick: previewClick
180
+ },
181
+ __( 'Send Preview', 'subscribe2' )
182
+ )
183
+ )
184
+ ),
185
+ maybeRenderResend( privSetting )
186
+ )
187
+ );
188
+ };
189
 
190
+ registerPlugin(
191
+ 'subscribe2-sidebar',
192
+ {
193
+ render: s2sidebar
194
+ }
195
+ );
196
  } (
197
+ wp.plugins,
198
+ wp.element,
199
+ wp.i18n,
200
+ wp.editPost,
201
+ wp.components,
202
+ wp.data,
203
+ wp.compose,
204
+ wp.apiFetch
205
+ ) );
gutenberg/sidebar.min.js CHANGED
@@ -1 +1 @@
1
- !function(e,i,t,r,n,s,o,a){var c=e.registerPlugin,d=i.createElement,b=t.__,l=i.Fragment,u=r.PluginSidebar,p=r.PluginSidebarMoreMenuItem,m=n.PanelBody,g=n.PanelRow,f=n.CheckboxControl,h=n.Button,w=s.select,P=s.dispatch,v=s.withSelect,S=s.withDispatch,C=(0,o.compose)(v(function(e,i){return{metaChecked:"no"===e("core/editor").getEditedPostAttribute("meta")[i.fieldName]}}),S(function(e,i){return{setMetaChecked:function(t){var r=!0===t?"no":"yes";e("core/editor").editPost({meta:{[i.fieldName]:r}}),e("core/editor").savePost()}}}))(function(e){return d(f,{label:b("Check here to disable sending of an email notification for this post/page","subscribe2"),checked:e.metaChecked,onChange:function(i){e.setMetaChecked(i)}})}),k=function(){var e=w("core/editor").getCurrentPostId();P("core/editor").savePost(),a({path:"/s2/v1/preview/"+e}),P("core/notices").createInfoNotice(b("Attempt made to send email preview","subscribe2"))};c("subscribe2-sidebar",{render:function(){return d(l,{},d(p,{target:"s2-sidebar",icon:"email"},b("Subscribe2 Sidebar","subscribe2")),d(u,{name:"s2-sidebar",title:b("Subscribe2 Sidebar","subscribe2"),icon:"email",isPinned:!0,isPinnable:!0,togglePin:!0,togglesidebar:!1},d(m,{title:b("Subscribe2 Override","subscribe2"),initialOpen:!0},d(g,{},d(C,{fieldName:"_s2mail"}))),d(m,{title:b("Subscribe2 Preview","subscribe2"),initialOpen:!0},d(g,{},d("div",null,b("Send preview email of this post to currently logged in user:","subscribe2"))),d(g,{},d(h,{isDefault:!0,onClick:k},b("Send Preview","subscribe2"))))))}})}(wp.plugins,wp.element,wp.i18n,wp.editPost,wp.components,wp.data,wp.compose,wp.apiFetch);
1
+ var privSetting="";wp.apiFetch({path:"/s2/v1/settings/private"}).then(function(e){privSetting=e}),function(e,t,i,r,n,s,o,c){var a=e.registerPlugin,u=t.createElement,d=i.__,b=t.Fragment,l=r.PluginSidebar,p=r.PluginSidebarMoreMenuItem,f=n.PanelBody,m=n.PanelRow,g=n.CheckboxControl,v=n.Button,h=s.select,P=s.dispatch,w=s.withSelect,S=s.withDispatch,C=(0,o.compose)(w(function(e,t){return{metaChecked:"no"===e("core/editor").getEditedPostAttribute("meta")[t.fieldName]}}),S(function(e,t){return{setMetaChecked:function(i){var r=!0===i?"no":"yes";e("core/editor").editPost({meta:{[t.fieldName]:r}}),e("core/editor").savePost()}}}))(function(e){return u(g,{label:d("Check here to disable sending of an email notification for this post/page","subscribe2"),checked:e.metaChecked,onChange:function(t){e.setMetaChecked(t)}})}),k=function(){return u(f,{title:d("Subscribe2 Resend","subscribe2"),initialOpen:!1},u(m,{},u("div",null,d("Resend the notification email of this post to current subscribers:","subscribe2"))),u(m,{},u(v,{isDefault:!0,onClick:A},d("Resend Notification","subscribe2"))))},N=function(){var e=h("core/editor").getCurrentPostId();P("core/editor").savePost(),c({path:"/s2/v1/preview/"+e}),P("core/notices").createInfoNotice(d("Attempt made to send email preview","subscribe2"))},A=function(){var e=h("core/editor").getCurrentPostId();P("core/editor").savePost(),c({path:"/s2/v1/resend/"+e}),P("core/notices").createInfoNotice(d("Attempt made to resend email notification","subscribe2"))};a("subscribe2-sidebar",{render:function(){return u(b,{},u(p,{target:"s2-sidebar",icon:"email"},d("Subscribe2 Sidebar","subscribe2")),u(l,{name:"s2-sidebar",title:d("Subscribe2 Sidebar","subscribe2"),icon:"email",isPinned:!0,isPinnable:!0,togglePin:!0,togglesidebar:!1},u(f,{title:d("Subscribe2 Override","subscribe2"),initialOpen:!0},u(m,{},u(C,{fieldName:"_s2mail"}))),u(f,{title:d("Subscribe2 Preview","subscribe2"),initialOpen:!1},u(m,{},u("div",null,d("Send preview email of this post to currently logged in user:","subscribe2"))),u(m,{},u(v,{isDefault:!0,onClick:N},d("Send Preview","subscribe2")))),function(e){return"publish"===h("core/editor").getEditedPostAttribute("status")?k():"private"===h("core/editor").getEditedPostAttribute("status")&&"yes"===e?k():void 0}(privSetting)))}})}(wp.plugins,wp.element,wp.i18n,wp.editPost,wp.components,wp.data,wp.compose,wp.apiFetch);
subscribe2.php CHANGED
@@ -3,7 +3,7 @@
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.27
7
  Author: Subscribe2
8
  Author URI: https://subscribe2.wordpress.com/
9
  Licence: GPLv3
@@ -54,7 +54,7 @@ if ( is_plugin_active_for_network( plugin_basename( __FILE__ ) ) ) {
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.27' );
58
  define( 'S2PATH', trailingslashit( dirname( __FILE__ ) ) );
59
  define( 'S2DIR', trailingslashit( dirname( plugin_basename( __FILE__ ) ) ) );
60
  define( 'S2URL', plugin_dir_url( dirname( __FILE__ ) ) . S2DIR );
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.28
7
  Author: Subscribe2
8
  Author URI: https://subscribe2.wordpress.com/
9
  Licence: GPLv3
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.28' );
58
  define( 'S2PATH', trailingslashit( dirname( __FILE__ ) ) );
59
  define( 'S2DIR', trailingslashit( dirname( plugin_basename( __FILE__ ) ) ) );
60
  define( 'S2URL', plugin_dir_url( dirname( __FILE__ ) ) . S2DIR );
subscribe2.pot CHANGED
@@ -2,7 +2,7 @@
2
  # This file is distributed under the same license as the Subscribe2 package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Subscribe2 10.27\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/subscribe2\n"
7
  "POT-Creation-Date: 2019-02-24 11:49:50+00:00\n"
8
  "MIME-Version: 1.0\n"
2
  # This file is distributed under the same license as the Subscribe2 package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Subscribe2 10.28\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/subscribe2\n"
7
  "POT-Creation-Date: 2019-02-24 11:49:50+00:00\n"
8
  "MIME-Version: 1.0\n"