PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 6.9
Jetpack – WP Security, Backup, Speed, & Growth v6.9
16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
← All changes | modules/subscriptions.php +229 -501 14.4.26.9 View file →
@@ -1,40 +1,31 @@
1 -<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName)
1 +<?php
2 2 /**
3 - * Module Name: Newsletter
4 - * Module Description: Let visitors subscribe to new posts and comments via email
3 + * Module Name: Subscriptions
4 + * Module Description: Allow users to subscribe to your posts and comments and receive notifications via email
5 + * Jumpstart Description: Give visitors two easy subscription options — while commenting, or via a separate email subscription widget you can display.
5 6 * Sort Order: 9
6 7 * Recommendation Order: 8
7 8 * First Introduced: 1.2
8 9 * Requires Connection: Yes
9 - * Requires User Connection: Yes
10 - * Auto Activate: No
10 + * Auto Activate: Yes
11 11 * Module Tags: Social
12 - * Feature: Engagement
13 - * Additional Search Queries: subscriptions, subscription, email, follow, followers, subscribers, signup, newsletter, creator
12 + * Feature: Engagement, Jumpstart
13 + * Additional Search Queries: subscriptions, subscription, email, follow, followers, subscribers, signup
14 14 */
15 15
16 -// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
17 -
18 -use Automattic\Jetpack\Admin_UI\Admin_Menu;
19 -use Automattic\Jetpack\Connection\Manager as Connection_Manager;
20 -use Automattic\Jetpack\Connection\XMLRPC_Async_Call;
21 -use Automattic\Jetpack\Redirect;
22 -use Automattic\Jetpack\Status;
23 -use Automattic\Jetpack\Status\Host;
24 -
25 16 add_action( 'jetpack_modules_loaded', 'jetpack_subscriptions_load' );
26 17
27 -// Loads the User Content Link Redirection feature.
28 -require_once __DIR__ . '/subscriptions/jetpack-user-content-link-redirection.php';
29 -
30 -/**
31 - * Loads the Subscriptions module.
32 - */
33 18 function jetpack_subscriptions_load() {
34 19 Jetpack::enable_module_configurable( __FILE__ );
20 + Jetpack::module_configuration_load( __FILE__, 'jetpack_subscriptions_configuration_load' );
35 21 }
36 22
23 +function jetpack_subscriptions_configuration_load() {
24 + wp_safe_redirect( admin_url( 'options-discussion.php#jetpack-subscriptions-settings' ) );
25 + exit;
26 +}
27 +
37 28 /**
38 29 * Cherry picks keys from `$_SERVER` array.
39 30 *
40 31 * @since 6.0.0
@@ -44,13 +35,13 @@
44 35 function jetpack_subscriptions_cherry_pick_server_data() {
45 36 $data = array();
46 37
47 38 foreach ( $_SERVER as $key => $value ) {
48 - if ( ! is_string( $value ) || str_starts_with( $key, 'HTTP_COOKIE' ) ) {
39 + if ( ! is_string( $value ) || 0 === strpos( $key, 'HTTP_COOKIE' ) ) {
49 40 continue;
50 41 }
51 42
52 - if ( str_starts_with( $key, 'HTTP_' ) || in_array( $key, array( 'REMOTE_ADDR', 'REQUEST_URI', 'DOCUMENT_URI' ), true ) ) {
43 + if ( 0 === strpos( $key, 'HTTP_' ) || in_array( $key, array( 'REMOTE_ADDR', 'REQUEST_URI', 'DOCUMENT_URI' ), true ) ) {
53 44 $data[ $key ] = $value;
54 45 }
55 46 }
56 47
@@ -56,49 +47,32 @@
56 47
57 48 return $data;
58 49 }
59 50
60 -/**
61 - * Main class file for the Subscriptions module.
62 - */
63 51 class Jetpack_Subscriptions {
64 - /**
65 - * Whether Jetpack has been instantiated or not.
66 - *
67 - * @var bool
68 - */
69 52 public $jetpack = false;
70 53
71 - /**
72 - * Hash of the siteurl option.
73 - *
74 - * @var string
75 - */
76 54 public static $hash;
77 55
78 56 /**
79 57 * Singleton
80 - *
81 58 * @static
82 59 */
83 - public static function init() {
60 + static function init() {
84 61 static $instance = false;
85 62
86 - if ( ! $instance ) {
87 - $instance = new Jetpack_Subscriptions();
63 + if ( !$instance ) {
64 + $instance = new Jetpack_Subscriptions;
88 65 }
89 66
90 67 return $instance;
91 68 }
92 69
93 - /**
94 - * Jetpack_Subscriptions constructor.
95 - */
96 - public function __construct() {
70 + function __construct() {
97 71 $this->jetpack = Jetpack::init();
98 72
99 73 // Don't use COOKIEHASH as it could be shared across installs && is non-unique in multisite.
100 - // @see: https://twitter.com/nacin/status/378246957451333632 .
74 + // @see: https://twitter.com/nacin/status/378246957451333632
101 75 self::$hash = md5( get_option( 'siteurl' ) );
102 76
103 77 add_filter( 'jetpack_xmlrpc_methods', array( $this, 'xmlrpc_methods' ) );
104 78
@@ -103,23 +77,22 @@
103 77 add_filter( 'jetpack_xmlrpc_methods', array( $this, 'xmlrpc_methods' ) );
104 78
105 79 // @todo remove sync from subscriptions and move elsewhere...
106 80
107 - // Add Configuration Page.
81 + // Add Configuration Page
108 82 add_action( 'admin_init', array( $this, 'configure' ) );
109 83
110 - // Catch subscription widget submits.
111 - if ( isset( $_REQUEST['jetpack_subscriptions_widget'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce checked in widget_submit() for logged in users.
84 + // Catch subscription widget submits
85 + if ( isset( $_REQUEST['jetpack_subscriptions_widget'] ) )
112 86 add_action( 'template_redirect', array( $this, 'widget_submit' ) );
113 - }
114 87
115 - // Set up the comment subscription checkboxes.
116 - add_filter( 'comment_form_submit_field', array( $this, 'comment_subscribe_init' ), 10, 2 );
88 + // Set up the comment subscription checkboxes
89 + add_action( 'comment_form_after_fields', array( $this, 'comment_subscribe_init' ) );
117 90
118 91 // Catch comment posts and check for subscriptions.
119 92 add_action( 'comment_post', array( $this, 'comment_subscribe_submit' ), 50, 2 );
120 93
121 - // Adds post meta checkbox in the post submit metabox.
94 + // Adds post meta checkbox in the post submit metabox
122 95 add_action( 'post_submitbox_misc_actions', array( $this, 'subscription_post_page_metabox' ) );
123 96
124 97 add_action( 'transition_post_status', array( $this, 'maybe_send_subscription_email' ), 10, 3 );
125 98
@@ -125,29 +98,8 @@
125 98
126 99 add_filter( 'jetpack_published_post_flags', array( $this, 'set_post_flags' ), 10, 2 );
127 100
128 101 add_filter( 'post_updated_messages', array( $this, 'update_published_message' ), 18, 1 );
129 -
130 - // Set "social_notifications_subscribe" option during the first-time activation.
131 - add_action( 'jetpack_activate_module_subscriptions', array( $this, 'set_social_notifications_subscribe' ) );
132 -
133 - // Hide subscription messaging in Publish panel for posts that were published in the past
134 - add_action( 'init', array( $this, 'register_post_meta' ), 20 );
135 - add_action( 'transition_post_status', array( $this, 'maybe_set_first_published_status' ), 10, 3 );
136 -
137 - // Add Subscribers menu to Jetpack navigation.
138 - add_action( 'jetpack_admin_menu', array( $this, 'add_subscribers_menu' ) );
139 -
140 - // Customize the configuration URL to lead to the Subscriptions settings.
141 - add_filter(
142 - 'jetpack_module_configuration_url_subscriptions',
143 - function () {
144 - return Jetpack::admin_url( array( 'page' => 'jetpack#/newsletter' ) );
145 - }
146 - );
147 -
148 - // Track categories created through the category editor page
149 - add_action( 'wp_ajax_add-tag', array( $this, 'track_newsletter_category_creation' ), 1 );
150 102 }
151 103
152 104 /**
153 105 * Jetpack_Subscriptions::xmlrpc_methods()
@@ -152,12 +104,11 @@
152 104 /**
153 105 * Jetpack_Subscriptions::xmlrpc_methods()
154 106 *
155 107 * Register subscriptions methods with the Jetpack XML-RPC server.
156 - *
157 - * @param array $methods Methods being registered.
108 + * @param array $methods
158 109 */
159 - public function xmlrpc_methods( $methods ) {
110 + function xmlrpc_methods( $methods ) {
160 111 return array_merge(
161 112 $methods,
162 113 array(
163 114 'jetpack.subscriptions.subscribe' => array( $this, 'subscribe' ),
@@ -164,13 +115,13 @@
164 115 )
165 116 );
166 117 }
167 118
168 - /**
119 + /*
169 120 * Disable Subscribe on Single Post
170 121 * Register post meta
171 122 */
172 - public function subscription_post_page_metabox() {
123 + function subscription_post_page_metabox() {
173 124 if (
174 125 /**
175 126 * Filter whether or not to show the per-post subscription option.
176 127 *
@@ -179,9 +130,10 @@
179 130 * @since 3.7.0
180 131 *
181 132 * @param bool true = show checkbox option on all new posts | false = hide the option.
182 133 */
183 - ! apply_filters( 'jetpack_allow_per_post_subscriptions', false ) ) {
134 + ! apply_filters( 'jetpack_allow_per_post_subscriptions', false ) )
135 + {
184 136 return;
185 137 }
186 138
187 139 if ( has_filter( 'jetpack_subscriptions_exclude_these_categories' ) || has_filter( 'jetpack_subscriptions_include_only_these_categories' ) ) {
@@ -190,19 +142,18 @@
190 142
191 143 global $post;
192 144 $disable_subscribe_value = get_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', true );
193 145 // only show checkbox if post hasn't been published and is a 'post' post type.
194 - if ( get_post_status( $post->ID ) !== 'publish' && get_post_type( $post->ID ) === 'post' ) :
195 - // Nonce it.
146 + if ( get_post_status( $post->ID ) !== 'publish' && get_post_type( $post->ID ) == 'post' ) :
147 + // Nonce it
196 148 wp_nonce_field( 'disable_subscribe', 'disable_subscribe_nonce' );
197 149 ?>
198 150 <div class="misc-pub-section">
199 - <label for="_jetpack_dont_email_post_to_subs"><?php esc_html_e( 'Jetpack Subscriptions:', 'jetpack' ); ?></label><br>
151 + <label for="_jetpack_dont_email_post_to_subs"><?php _e( 'Jetpack Subscriptions:', 'jetpack' ); ?></label><br>
200 152 <input type="checkbox" name="_jetpack_dont_email_post_to_subs" id="jetpack-per-post-subscribe" value="1" <?php checked( $disable_subscribe_value, 1, true ); ?> />
201 - <?php esc_html_e( 'Don&#8217;t send this to subscribers', 'jetpack' ); ?>
153 + <?php _e( 'Don&#8217;t send this to subscribers', 'jetpack' ); ?>
202 154 </div>
203 - <?php
204 - endif;
155 + <?php endif;
205 156 }
206 157
207 158 /**
208 159 * Checks whether or not the post should be emailed to subscribers
@@ -213,38 +164,32 @@
213 164 * - Existence of the per-post checkbox option
214 165 *
215 166 * Only one of these can be used at any given time.
216 167 *
217 - * @param string $new_status Tthe "new" post status of the transition when saved.
218 - * @param string $old_status The "old" post status of the transition when saved.
219 - * @param object $post obj The post object.
168 + * @param $new_status string - the "new" post status of the transition when saved
169 + * @param $old_status string - the "old" post status of the transition when saved
170 + * @param $post obj - The post object
220 171 */
221 - public function maybe_send_subscription_email( $new_status, $old_status, $post ) {
172 + function maybe_send_subscription_email( $new_status, $old_status, $post ) {
222 173
223 174 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
224 175 return;
225 176 }
226 177
227 - // Make sure that the checkbox is preseved.
228 - if ( ! empty( $_POST['disable_subscribe_nonce'] ) && wp_verify_nonce( $_POST['disable_subscribe_nonce'], 'disable_subscribe' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- WP Core doesn't unslash or sanitize nonces either.
178 + // Make sure that the checkbox is preseved
179 + if ( ! empty( $_POST['disable_subscribe_nonce'] ) && wp_verify_nonce( $_POST['disable_subscribe_nonce'], 'disable_subscribe' ) ) {
229 180 $set_checkbox = isset( $_POST['_jetpack_dont_email_post_to_subs'] ) ? 1 : 0;
230 181 update_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', $set_checkbox );
231 182 }
232 183 }
233 184
234 - /**
235 - * Message used when publishing a post.
236 - *
237 - * @param array $messages Message array for a post.
238 - */
239 - public function update_published_message( $messages ) {
185 + function update_published_message( $messages ) {
240 186 global $post;
241 187 if ( ! $this->should_email_post_to_subscribers( $post ) ) {
242 188 return $messages;
243 189 }
244 190
245 - $view_post_link_html = sprintf(
246 - ' <a href="%1$s">%2$s</a>',
191 + $view_post_link_html = sprintf( ' <a href="%1$s">%2$s</a>',
247 192 esc_url( get_permalink( $post ) ),
248 193 __( 'View post', 'jetpack' )
249 194 );
250 195
@@ -250,17 +195,12 @@
250 195
251 196 $messages['post'][6] = sprintf(
252 197 /* translators: Message shown after a post is published */
253 198 esc_html__( 'Post published and sending emails to subscribers.', 'jetpack' )
254 - ) . $view_post_link_html;
199 + ) . $view_post_link_html;
255 200 return $messages;
256 201 }
257 202
258 - /**
259 - * Determine if a post should notifiy subscribers via email.
260 - *
261 - * @param object $post The post.
262 - */
263 203 public function should_email_post_to_subscribers( $post ) {
264 204 $should_email = true;
265 205 if ( get_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', true ) ) {
266 206 return false;
@@ -265,18 +205,13 @@
265 205 if ( get_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', true ) ) {
266 206 return false;
267 207 }
268 208
269 - // Only posts are currently supported.
270 - if ( 'post' !== $post->post_type ) {
209 + // Only posts are currently supported
210 + if ( $post->post_type !== 'post' ) {
271 211 return false;
272 212 }
273 213
274 - // Private posts are not sent to subscribers.
275 - if ( 'private' === $post->post_status ) {
276 - return false;
277 - }
278 -
279 214 /**
280 215 * Array of categories that will never trigger subscription emails.
281 216 *
282 217 * Will not send subscription emails from any post from within these categories.
@@ -288,9 +223,9 @@
288 223 * @param array $args Array of category slugs or ID's.
289 224 */
290 225 $excluded_categories = apply_filters( 'jetpack_subscriptions_exclude_these_categories', array() );
291 226
292 - // Never email posts from these categories.
227 + // Never email posts from these categories
293 228 if ( ! empty( $excluded_categories ) && in_category( $excluded_categories, $post->ID ) ) {
294 229 $should_email = false;
295 230 }
296 231
@@ -306,9 +241,9 @@
306 241 * @param array $args Array of category slugs or ID's.
307 242 */
308 243 $only_these_categories = apply_filters( 'jetpack_subscriptions_exclude_all_categories_except', array() );
309 244
310 - // Only emails posts from these categories.
245 + // Only emails posts from these categories
311 246 if ( ! empty( $only_these_categories ) && ! in_category( $only_these_categories, $post->ID ) ) {
312 247 $should_email = false;
313 248 }
314 249
@@ -314,15 +249,9 @@
314 249
315 250 return $should_email;
316 251 }
317 252
318 - /**
319 - * Retrieve which flags should be added to a particular post.
320 - *
321 - * @param array $flags Flags to be added.
322 - * @param object $post A post object.
323 - */
324 - public function set_post_flags( $flags, $post ) {
253 + function set_post_flags( $flags, $post ) {
325 254 $flags['send_subscription'] = $this->should_email_post_to_subscribers( $post );
326 255 return $flags;
327 256 }
328 257
@@ -330,10 +259,10 @@
330 259 * Jetpack_Subscriptions::configure()
331 260 *
332 261 * Jetpack Subscriptions configuration screen.
333 262 */
334 - public function configure() {
335 - // Create the section.
263 + function configure() {
264 + // Create the section
336 265 add_settings_section(
337 266 'jetpack_subscriptions',
338 267 __( 'Jetpack Subscriptions Settings', 'jetpack' ),
339 268 array( $this, 'subscriptions_settings_section' ),
@@ -339,9 +268,9 @@
339 268 array( $this, 'subscriptions_settings_section' ),
340 269 'discussion'
341 270 );
342 271
343 - /** Subscribe to Posts */
272 + /** Subscribe to Posts ***************************************************/
344 273
345 274 add_settings_field(
346 275 'jetpack_subscriptions_post_subscribe',
347 276 __( 'Follow Blog', 'jetpack' ),
@@ -354,9 +283,9 @@
354 283 'discussion',
355 284 'stb_enabled'
356 285 );
357 286
358 - /** Subscribe to Comments */
287 + /** Subscribe to Comments ******************************************************/
359 288
360 289 add_settings_field(
361 290 'jetpack_subscriptions_comment_subscribe',
362 291 __( 'Follow Comments', 'jetpack' ),
@@ -369,180 +298,155 @@
369 298 'discussion',
370 299 'stc_enabled'
371 300 );
372 301
373 - /** Email me whenever: Someone subscribes to my blog */
374 - /* @since 8.1 */
302 + /** Subscription Messaging Options ******************************************************/
375 303
304 + register_setting(
305 + 'reading',
306 + 'subscription_options',
307 + array( $this, 'validate_settings' )
308 + );
309 +
376 310 add_settings_section(
377 - 'notifications_section',
378 - __( 'Someone subscribes to my blog', 'jetpack' ),
379 - array( $this, 'social_notifications_subscribe_section' ),
380 - 'discussion'
311 + 'email_settings',
312 + __( 'Follower Settings', 'jetpack' ),
313 + array( $this, 'reading_section' ),
314 + 'reading'
381 315 );
382 316
383 317 add_settings_field(
384 - 'jetpack_subscriptions_social_notifications_subscribe',
385 - __( 'Email me whenever', 'jetpack' ),
386 - array( $this, 'social_notifications_subscribe_field' ),
387 - 'discussion',
388 - 'notifications_section'
318 + 'invitation',
319 + __( 'Blog follow email text', 'jetpack' ),
320 + array( $this, 'setting_invitation' ),
321 + 'reading',
322 + 'email_settings'
389 323 );
390 324
391 - register_setting(
392 - 'discussion',
393 - 'social_notifications_subscribe',
394 - array( $this, 'social_notifications_subscribe_validate' )
325 + add_settings_field(
326 + 'comment-follow',
327 + __( 'Comment follow email text', 'jetpack' ),
328 + array( $this, 'setting_comment_follow' ),
329 + 'reading',
330 + 'email_settings'
395 331 );
396 332 }
397 333
398 334 /**
399 - * Discussions setting section blurb.
335 + * Discussions setting section blurb
336 + *
400 337 */
401 - public function subscriptions_settings_section() {
402 - ?>
403 - <p id="jetpack-subscriptions-settings"><?php esc_html_e( 'Change whether your visitors can subscribe to your posts or comments or both.', 'jetpack' ); ?></p>
338 + function subscriptions_settings_section() {
339 + ?>
340 + <p id="jetpack-subscriptions-settings"><?php _e( 'Change whether your visitors can subscribe to your posts or comments or both.', 'jetpack' ); ?></p>
404 341
405 - <?php
342 + <?php
406 343 }
407 344
408 345 /**
409 - * Post Subscriptions Toggle.
346 + * Post Subscriptions Toggle
347 + *
410 348 */
411 - public function subscription_post_subscribe_setting() {
349 + function subscription_post_subscribe_setting() {
412 350
413 - $stb_enabled = get_option( 'stb_enabled', 1 );
414 - ?>
351 + $stb_enabled = get_option( 'stb_enabled', 1 ); ?>
415 352
416 353 <p class="description">
417 354 <input type="checkbox" name="stb_enabled" id="jetpack-post-subscribe" value="1" <?php checked( $stb_enabled, 1 ); ?> />
418 - <?php
419 - echo wp_kses(
420 - __(
421 - "Show a <em>'follow blog'</em> option in the comment form",
422 - 'jetpack'
423 - ),
424 - array( 'em' => array() )
425 - );
426 - ?>
355 + <?php _e( "Show a <em>'follow blog'</em> option in the comment form", 'jetpack' ); ?>
427 356 </p>
428 - <?php
357 + <?php
429 358 }
430 359
431 360 /**
432 - * Comments Subscriptions Toggle.
361 + * Comments Subscriptions Toggle
362 + *
433 363 */
434 - public function subscription_comment_subscribe_setting() {
364 + function subscription_comment_subscribe_setting() {
435 365
436 - $stc_enabled = get_option( 'stc_enabled', 1 );
437 - ?>
366 + $stc_enabled = get_option( 'stc_enabled', 1 ); ?>
438 367
439 368 <p class="description">
440 369 <input type="checkbox" name="stc_enabled" id="jetpack-comment-subscribe" value="1" <?php checked( $stc_enabled, 1 ); ?> />
441 - <?php
442 - echo wp_kses(
443 - __(
444 - "Show a <em>'follow comments'</em> option in the comment form",
445 - 'jetpack'
446 - ),
447 - array( 'em' => array() )
448 - );
449 - ?>
370 + <?php _e( "Show a <em>'follow comments'</em> option in the comment form", 'jetpack' ); ?>
450 371 </p>
451 372
452 - <?php
373 + <?php
453 374 }
454 375
455 - /**
456 - * Someone subscribes to my blog section
457 - *
458 - * @since 8.1
459 - */
460 - public function social_notifications_subscribe_section() {
461 - // Atypical usage here. We emit jquery to move subscribe notification checkbox to be with the rest of the email notification settings.
462 - ?>
463 - <script type="text/javascript">
464 - jQuery( function( $ ) {
465 - var table = $( '#social_notifications_subscribe' ).parents( 'table:first' ),
466 - header = table.prevAll( 'h2:first' ),
467 - newParent = $( '#moderation_notify' ).parent( 'label' ).parent();
376 + function validate_settings( $settings ) {
377 + global $allowedposttags;
468 378
469 - if ( ! table.length || ! header.length || ! newParent.length ) {
470 - return;
471 - }
379 + $default = $this->get_default_settings();
472 380
473 - newParent.append( '<br/>' ).append( table.end().parent( 'label' ).siblings().andSelf() );
474 - header.remove();
475 - table.remove();
476 - } );
477 - </script>
478 - <?php
381 + // Blog Follow
382 + $settings['invitation'] = trim( wp_kses( $settings['invitation'], $allowedposttags ) );
383 + if ( empty( $settings['invitation'] ) )
384 + $settings['invitation'] = $default['invitation'];
385 +
386 + // Comments Follow (single post)
387 + $settings['comment_follow'] = trim( wp_kses( $settings['comment_follow'], $allowedposttags ) );
388 + if ( empty( $settings['comment_follow'] ) )
389 + $settings['comment_follow'] = $default['comment_follow'];
390 +
391 + return $settings;
479 392 }
480 393
481 - /**
482 - * Someone subscribes to my blog Toggle
483 - *
484 - * @since 8.1
485 - */
486 - public function social_notifications_subscribe_field() {
487 - $checked = (int) ( 'on' === get_option( 'social_notifications_subscribe', 'on' ) );
488 - ?>
394 + public function reading_section() {
395 + echo '<p id="follower-settings">';
396 + _e( 'These settings change emails sent from your blog to followers.', 'jetpack' );
397 + echo '</p>';
398 + }
489 399
490 - <label>
491 - <input type="checkbox" name="social_notifications_subscribe" id="social_notifications_subscribe" value="1" <?php checked( $checked ); ?> />
492 - <?php
493 - /* translators: this is a label for a setting that starts with "Email me whenever" */
494 - esc_html_e( 'Someone subscribes to my blog', 'jetpack' );
495 - ?>
496 - </label>
497 - <?php
400 + public function setting_invitation() {
401 + $settings = $this->get_settings();
402 + echo '<textarea name="subscription_options[invitation]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['invitation'] ) . '</textarea>';
403 + echo '<p><span class="description">'.__( 'Introduction text sent when someone follows your blog. (Site and confirmation details will be automatically added for you.)', 'jetpack' ).'</span></p>';
498 404 }
499 405
500 - /**
501 - * Validate "Someone subscribes to my blog" option
502 - *
503 - * @since 8.1
504 - *
505 - * @param String $input the input string to be validated.
506 - * @return string on|off
507 - */
508 - public function social_notifications_subscribe_validate( $input ) {
509 - // If it's not set (was unchecked during form submission) or was set to off (during option update), return 'off'.
510 - if ( ! $input || 'off' === $input ) {
511 - return 'off';
512 - }
406 + public function setting_comment_follow() {
407 + $settings = $this->get_settings();
408 + echo '<textarea name="subscription_options[comment_follow]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['comment_follow'] ) . '</textarea>';
409 + echo '<p><span class="description">'.__( 'Introduction text sent when someone follows a post on your blog. (Site and confirmation details will be automatically added for you.)', 'jetpack' ).'</span></p>';
410 + }
513 411
514 - // Otherwise we return 'on'.
515 - return 'on';
412 + function get_default_settings() {
413 + return array(
414 + 'invitation' => __( "Howdy.\n\nYou recently followed this blog's posts. This means you will receive each new post by email.\n\nTo activate, click confirm below. If you believe this is an error, ignore this message and we'll never bother you again.", 'jetpack' ),
415 + 'comment_follow' => __( "Howdy.\n\nYou recently followed one of my posts. This means you will receive an email when new comments are posted.\n\nTo activate, click confirm below. If you believe this is an error, ignore this message and we'll never bother you again.", 'jetpack' )
416 + );
516 417 }
517 418
419 + function get_settings() {
420 + return wp_parse_args( (array) get_option( 'subscription_options', array() ), $this->get_default_settings() );
421 + }
422 +
518 423 /**
519 424 * Jetpack_Subscriptions::subscribe()
520 425 *
521 426 * Send a synchronous XML-RPC subscribe to blog posts or subscribe to post comments request.
522 427 *
523 - * @param string $email being subscribed.
524 - * @param array $post_ids (optional) defaults to 0 for blog posts only: array of post IDs to subscribe to blog's posts.
428 + * @param string $email
429 + * @param array $post_ids (optional) defaults to 0 for blog posts only: array of post IDs to subscribe to blog's posts
525 430 * @param bool $async (optional) Should the subscription be performed asynchronously? Defaults to true.
526 - * @param array $extra_data Additional data passed to the `jetpack.subscribeToSite` call.
527 431 *
528 - * @return true|WP_Error true on success
529 - * invalid_email : not a valid email address
530 - * invalid_post_id : not a valid post ID
531 - * unknown_post_id : unknown post
532 - * not_subscribed : strange error. Jetpack servers at WordPress.com could subscribe the email.
533 - * disabled : Site owner has disabled subscriptions.
534 - * active : Already subscribed.
535 - * pending : Tried to subscribe before but the confirmation link is never clicked. No confirmation email is sent.
536 - * unknown : strange error. Jetpack servers at WordPress.com returned something malformed.
537 - * unknown_status : strange error. Jetpack servers at WordPress.com returned something I didn't understand.
432 + * @return true|Jetpack_Error true on success
433 + * invalid_email : not a valid email address
434 + * invalid_post_id : not a valid post ID
435 + * unknown_post_id : unknown post
436 + * not_subscribed : strange error. Jetpack servers at WordPress.com could subscribe the email.
437 + * disabled : Site owner has disabled subscriptions.
438 + * active : Already subscribed.
439 + * unknown : strange error. Jetpack servers at WordPress.com returned something malformed.
440 + * unknown_status : strange error. Jetpack servers at WordPress.com returned something I didn't understand.
538 441 */
539 - public function subscribe( $email, $post_ids = 0, $async = true, $extra_data = array() ) {
540 - if ( ! is_email( $email ) ) {
541 - return new WP_Error( 'invalid_email' );
442 + function subscribe( $email, $post_ids = 0, $async = true, $extra_data = array() ) {
443 + if ( !is_email( $email ) ) {
444 + return new Jetpack_Error( 'invalid_email' );
542 445 }
543 446
544 - if ( ! $async ) {
447 + if ( !$async ) {
448 + Jetpack::load_xml_rpc_client();
545 449 $xml = new Jetpack_IXR_ClientMulticall();
546 450 }
547 451
548 452 foreach ( (array) $post_ids as $post_id ) {
@@ -547,17 +451,17 @@
547 451
548 452 foreach ( (array) $post_ids as $post_id ) {
549 453 $post_id = (int) $post_id;
550 454 if ( $post_id < 0 ) {
551 - return new WP_Error( 'invalid_post_id' );
552 - } elseif ( $post_id && ! get_post( $post_id ) ) {
553 - return new WP_Error( 'unknown_post_id' );
455 + return new Jetpack_Error( 'invalid_post_id' );
456 + } else if ( $post_id && !$post = get_post( $post_id ) ) {
457 + return new Jetpack_Error( 'unknown_post_id' );
554 458 }
555 459
556 460 if ( $async ) {
557 - XMLRPC_Async_Call::add_call( 'jetpack.subscribeToSite', 0, $email, $post_id, serialize( $extra_data ) ); //phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
461 + Jetpack::xmlrpc_async_call( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) );
558 462 } else {
559 - $xml->addCall( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) ); //phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
463 + $xml->addCall( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) );
560 464 }
561 465 }
562 466
563 467 if ( $async ) {
@@ -563,9 +467,9 @@
563 467 if ( $async ) {
564 468 return;
565 469 }
566 470
567 - // Call.
471 + // Call
568 472 $xml->query();
569 473
570 474 if ( $xml->isError() ) {
571 475 return $xml->get_jetpack_error();
@@ -579,32 +483,29 @@
579 483 $r[] = $xml->get_jetpack_error( $response['faultCode'], $response['faultString'] );
580 484 continue;
581 485 }
582 486
583 - if ( ! is_array( $response[0] ) || empty( $response[0]['status'] ) ) {
584 - $r[] = new WP_Error( 'unknown' );
487 + if ( !is_array( $response[0] ) || empty( $response[0]['status'] ) ) {
488 + $r[] = new Jetpack_Error( 'unknown' );
585 489 continue;
586 490 }
587 491
588 492 switch ( $response[0]['status'] ) {
589 - case 'error':
590 - $r[] = new WP_Error( 'not_subscribed' );
591 - continue 2;
592 - case 'disabled':
593 - $r[] = new WP_Error( 'disabled' );
594 - continue 2;
595 - case 'active':
596 - $r[] = new WP_Error( 'active' );
597 - continue 2;
598 - case 'confirming':
599 - $r[] = true;
600 - continue 2;
601 - case 'pending':
602 - $r[] = new WP_Error( 'pending' );
603 - continue 2;
604 - default:
605 - $r[] = new WP_Error( 'unknown_status', (string) $response[0]['status'] );
606 - continue 2;
493 + case 'error' :
494 + $r[] = new Jetpack_Error( 'not_subscribed' );
495 + continue 2;
496 + case 'disabled' :
497 + $r[] = new Jetpack_Error( 'disabled' );
498 + continue 2;
499 + case 'active' :
500 + $r[] = new Jetpack_Error( 'active' );
501 + continue 2;
502 + case 'pending' :
503 + $r[] = true;
504 + continue 2;
505 + default :
506 + $r[] = new Jetpack_Error( 'unknown_status', (string) $response[0]['status'] );
507 + continue 2;
607 508 }
608 509 }
609 510
610 511 return $r;
@@ -614,36 +515,35 @@
614 515 * Jetpack_Subscriptions::widget_submit()
615 516 *
616 517 * When a user submits their email via the blog subscription widget, check the details and call the subsribe() method.
617 518 */
618 - public function widget_submit() {
519 + function widget_submit() {
619 520 // Check the nonce.
620 - if ( ! wp_verify_nonce( isset( $_REQUEST['_wpnonce'] ) ? sanitize_key( $_REQUEST['_wpnonce'] ) : '', 'blogsub_subscribe_' . \Jetpack_Options::get_option( 'id' ) ) ) {
621 - return false;
521 + if ( is_user_logged_in() ) {
522 + check_admin_referer( 'blogsub_subscribe_' . get_current_blog_id() );
622 523 }
623 524
624 - if ( empty( $_REQUEST['email'] ) || ! is_string( $_REQUEST['email'] ) ) {
525 + if ( empty( $_REQUEST['email'] ) )
625 526 return false;
626 - }
627 527
628 528 $redirect_fragment = false;
629 529 if ( isset( $_REQUEST['redirect_fragment'] ) ) {
630 - $redirect_fragment = preg_replace( '/[^a-z0-9_-]/i', '', $_REQUEST['redirect_fragment'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- This is manually unslashing and sanitizing.
530 + $redirect_fragment = preg_replace( '/[^a-z0-9_-]/i', '', $_REQUEST['redirect_fragment'] );
631 531 }
632 - if ( ! $redirect_fragment || ! is_string( $redirect_fragment ) ) {
532 + if ( !$redirect_fragment ) {
633 533 $redirect_fragment = 'subscribe-blog';
634 534 }
635 535
636 - $subscribe = self::subscribe(
637 - isset( $_REQUEST['email'] ) ? wp_unslash( $_REQUEST['email'] ) : null, // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated inside self::subscribe().
638 - 0,
639 - false,
640 - array(
641 - 'source' => 'widget',
642 - 'widget-in-use' => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
643 - 'comment_status' => '',
644 - 'server_data' => jetpack_subscriptions_cherry_pick_server_data(),
645 - )
536 + $subscribe = Jetpack_Subscriptions::subscribe(
537 + $_REQUEST['email'],
538 + 0,
539 + false,
540 + array(
541 + 'source' => 'widget',
542 + 'widget-in-use' => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
543 + 'comment_status' => '',
544 + 'server_data' => jetpack_subscriptions_cherry_pick_server_data(),
545 + )
646 546 );
647 547
648 548 if ( is_wp_error( $subscribe ) ) {
649 549 $error = $subscribe->get_error_code();
@@ -667,16 +567,11 @@
667 567 case 'blocked_email':
668 568 $result = 'opted_out';
669 569 break;
670 570 case 'active':
571 + case 'pending':
671 572 $result = 'already';
672 573 break;
673 - case 'flooded_email':
674 - $result = 'many_pending_subs';
675 - break;
676 - case 'pending':
677 - $result = 'pending';
678 - break;
679 574 default:
680 575 $result = 'error';
681 576 break;
682 577 }
@@ -694,9 +589,9 @@
694 589 */
695 590 do_action( 'jetpack_subscriptions_form_submission', $result );
696 591
697 592 wp_safe_redirect( "$redirect#$redirect_fragment" );
698 - exit( 0 );
593 + exit;
699 594 }
700 595
701 596 /**
702 597 * Jetpack_Subscriptions::comment_subscribe_init()
@@ -701,19 +596,12 @@
701 596 /**
702 597 * Jetpack_Subscriptions::comment_subscribe_init()
703 598 *
704 599 * Set up and add the comment subscription checkbox to the comment form.
705 - *
706 - * @param string $submit_button HTML markup for the submit field.
707 600 */
708 - public function comment_subscribe_init( $submit_button ) {
601 + function comment_subscribe_init() {
709 602 global $post;
710 603
711 - // Subscriptions are only available for posts so far.
712 - if ( ! $post || 'post' !== $post->post_type ) {
713 - return $submit_button;
714 - }
715 -
716 604 $comments_checked = '';
717 605 $blog_checked = '';
718 606
719 607 // Check for a comment / blog submission and set a cookie to retain the setting and check the boxes.
@@ -724,20 +612,20 @@
724 612 if ( isset( $_COOKIE[ 'jetpack_blog_subscribe_' . self::$hash ] ) ) {
725 613 $blog_checked = ' checked="checked"';
726 614 }
727 615
728 - // Some themes call this function, don't show the checkbox again.
616 + // Some themes call this function, don't show the checkbox again
729 617 remove_action( 'comment_form', 'subscription_comment_form' );
730 618
731 - // Check if Mark Jaquith's Subscribe to Comments plugin is active - if so, suppress Jetpack checkbox.
619 + // Check if Mark Jaquith's Subscribe to Comments plugin is active - if so, suppress Jetpack checkbox
732 620
733 621 $str = '';
734 622
735 - if ( false === has_filter( 'comment_form', 'show_subscription_checkbox' ) && 1 === (int) get_option( 'stc_enabled', 1 ) && empty( $post->post_password ) && 'post' === get_post_type() ) {
736 - // Subscribe to comments checkbox.
737 - $str .= '<p class="comment-subscription-form"><input type="checkbox" name="subscribe_comments" id="subscribe_comments" value="subscribe" style="width: auto; -moz-appearance: checkbox; -webkit-appearance: checkbox;"' . $comments_checked . ' /> ';
623 + if ( FALSE === has_filter( 'comment_form', 'show_subscription_checkbox' ) && 1 == get_option( 'stc_enabled', 1 ) && empty( $post->post_password ) && 'post' == get_post_type() ) {
624 + // Subscribe to comments checkbox
625 + $str .= '<p class="comment-subscription-form"><input type="checkbox" name="subscribe_comments" id="subscribe_comments" value="subscribe" style="width: auto; -moz-appearance: checkbox; -webkit-appearance: checkbox;"' . $comments_checked . ' /> ';
738 626 $comment_sub_text = __( 'Notify me of follow-up comments by email.', 'jetpack' );
739 - $str .= '<label class="subscribe-label" id="subscribe-label" for="subscribe_comments">' . esc_html(
627 + $str .= '<label class="subscribe-label" id="subscribe-label" for="subscribe_comments">' . esc_html(
740 628 /**
741 629 * Filter the Subscribe to comments text appearing below the comment form.
742 630 *
743 631 * @module subscriptions
@@ -750,13 +638,13 @@
750 638 ) . '</label>';
751 639 $str .= '</p>';
752 640 }
753 641
754 - if ( 1 === (int) get_option( 'stb_enabled', 1 ) ) {
755 - // Subscribe to blog checkbox.
756 - $str .= '<p class="comment-subscription-form"><input type="checkbox" name="subscribe_blog" id="subscribe_blog" value="subscribe" style="width: auto; -moz-appearance: checkbox; -webkit-appearance: checkbox;"' . $blog_checked . ' /> ';
642 + if ( 1 == get_option( 'stb_enabled', 1 ) ) {
643 + // Subscribe to blog checkbox
644 + $str .= '<p class="comment-subscription-form"><input type="checkbox" name="subscribe_blog" id="subscribe_blog" value="subscribe" style="width: auto; -moz-appearance: checkbox; -webkit-appearance: checkbox;"' . $blog_checked . ' /> ';
757 645 $blog_sub_text = __( 'Notify me of new posts by email.', 'jetpack' );
758 - $str .= '<label class="subscribe-label" id="subscribe-blog-label" for="subscribe_blog">' . esc_html(
646 + $str .= '<label class="subscribe-label" id="subscribe-blog-label" for="subscribe_blog">' . esc_html(
759 647 /**
760 648 * Filter the Subscribe to blog text appearing below the comment form.
761 649 *
762 650 * @module subscriptions
@@ -778,11 +666,9 @@
778 666 * @since 1.2.0
779 667 *
780 668 * @param string $str Comment Subscription form HTML output.
781 669 */
782 - $str = apply_filters( 'jetpack_comment_subscription_form', $str );
783 -
784 - return $str . $submit_button;
670 + echo apply_filters( 'jetpack_comment_subscription_form', $str );
785 671 }
786 672
787 673 /**
788 674 * Jetpack_Subscriptions::comment_subscribe_init()
@@ -787,49 +673,40 @@
787 673 /**
788 674 * Jetpack_Subscriptions::comment_subscribe_init()
789 675 *
790 676 * When a user checks the comment subscribe box and submits a comment, subscribe them to the comment thread.
791 - *
792 - * @param int|string $comment_id Comment thread being subscribed to.
793 - * @param string $approved Comment status.
794 677 */
795 - public function comment_subscribe_submit( $comment_id, $approved ) {
678 + function comment_subscribe_submit( $comment_id, $approved ) {
796 679 if ( 'spam' === $approved ) {
797 680 return;
798 681 }
799 682
800 683 $comment = get_comment( $comment_id );
801 - if ( ! $comment ) {
802 - return;
803 - }
804 684
805 - // Set cookies for this post/comment.
806 - $this->set_cookies( isset( $_REQUEST['subscribe_comments'] ), $comment->comment_post_ID, isset( $_REQUEST['subscribe_blog'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
685 + // Set cookies for this post/comment
686 + $this->set_cookies( isset( $_REQUEST['subscribe_comments'] ), $comment->comment_post_ID, isset( $_REQUEST['subscribe_blog'] ) );
807 687
808 - if ( ! isset( $_REQUEST['subscribe_comments'] ) && ! isset( $_REQUEST['subscribe_blog'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
688 + if ( !isset( $_REQUEST['subscribe_comments'] ) && !isset( $_REQUEST['subscribe_blog'] ) )
809 689 return;
810 - }
811 690
812 691 $post_ids = array();
813 692
814 - if ( isset( $_REQUEST['subscribe_comments'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
693 + if ( isset( $_REQUEST['subscribe_comments'] ) )
815 694 $post_ids[] = $comment->comment_post_ID;
816 - }
817 695
818 - if ( isset( $_REQUEST['subscribe_blog'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
696 + if ( isset( $_REQUEST['subscribe_blog'] ) )
819 697 $post_ids[] = 0;
820 - }
821 698
822 - $result = self::subscribe(
823 - $comment->comment_author_email,
824 - $post_ids,
825 - true,
826 - array(
827 - 'source' => 'comment-form',
828 - 'widget-in-use' => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
829 - 'comment_status' => $approved,
830 - 'server_data' => jetpack_subscriptions_cherry_pick_server_data(),
831 - )
699 + $result = Jetpack_Subscriptions::subscribe(
700 + $comment->comment_author_email,
701 + $post_ids,
702 + true,
703 + array(
704 + 'source' => 'comment-form',
705 + 'widget-in-use' => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
706 + 'comment_status' => $approved,
707 + 'server_data' => jetpack_subscriptions_cherry_pick_server_data(),
708 + )
832 709 );
833 710
834 711 /**
835 712 * Fires on each comment subscription form submission.
@@ -838,9 +715,9 @@
838 715 *
839 716 * @since 5.5.0
840 717 *
841 718 * @param NULL|WP_Error $result Result of form submission: NULL on success, WP_Error otherwise.
842 - * @param array $post_ids An array of post IDs that the user subscribed to, 0 means blog subscription.
719 + * @param Array $post_ids An array of post IDs that the user subscribed to, 0 means blog subscription.
843 720 */
844 721 do_action( 'jetpack_subscriptions_comment_form_submission', $result, $post_ids );
845 722 }
846 723
@@ -849,16 +726,16 @@
849 726 *
850 727 * Set a cookie to save state on the comment and post subscription checkboxes.
851 728 *
852 729 * @param bool $subscribe_to_post Whether the user chose to subscribe to subsequent comments on this post.
853 - * @param int $post_id If $subscribe_to_post is true, the post ID they've subscribed to.
730 + * @param int $post_id If $subscribe_to_post is true, the post ID they've subscribed to.
854 731 * @param bool $subscribe_to_blog Whether the user chose to subscribe to all new posts on the blog.
855 732 */
856 - public function set_cookies( $subscribe_to_post = false, $post_id = null, $subscribe_to_blog = false ) {
857 - $post_id = (int) $post_id;
733 + function set_cookies( $subscribe_to_post = false, $post_id = null, $subscribe_to_blog = false ) {
734 + $post_id = intval( $post_id );
858 735
859 736 /** This filter is already documented in core/wp-includes/comment-functions.php */
860 - $cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
737 + $cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
861 738
862 739 /**
863 740 * Filter the Jetpack Comment cookie path.
864 741 *
@@ -867,9 +744,9 @@
867 744 * @since 2.5.0
868 745 *
869 746 * @param string COOKIEPATH Cookie path.
870 747 */
871 - $cookie_path = apply_filters( 'jetpack_comment_cookie_path', COOKIEPATH );
748 + $cookie_path = apply_filters( 'jetpack_comment_cookie_path', COOKIEPATH );
872 749
873 750 /**
874 751 * Filter the Jetpack Comment cookie domain.
875 752 *
@@ -878,173 +755,24 @@
878 755 * @since 2.5.0
879 756 *
880 757 * @param string COOKIE_DOMAIN Cookie domain.
881 758 */
882 - $cookie_domain = apply_filters( 'jetpack_comment_cookie_domain', COOKIE_DOMAIN );
759 + $cookie_domain = apply_filters( 'jetpack_comment_cookie_domain', COOKIE_DOMAIN );
883 760
884 761 if ( $subscribe_to_post && $post_id >= 0 ) {
885 - setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain, is_ssl(), true );
762 + setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain );
886 763 } else {
887 - setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, '', time() - 3600, $cookie_path, $cookie_domain, is_ssl(), true );
764 + setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, '', time() - 3600, $cookie_path, $cookie_domain );
888 765 }
889 766
890 767 if ( $subscribe_to_blog ) {
891 - setcookie( 'jetpack_blog_subscribe_' . self::$hash, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain, is_ssl(), true );
768 + setcookie( 'jetpack_blog_subscribe_' . self::$hash, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain );
892 769 } else {
893 - setcookie( 'jetpack_blog_subscribe_' . self::$hash, '', time() - 3600, $cookie_path, $cookie_domain, is_ssl(), true );
770 + setcookie( 'jetpack_blog_subscribe_' . self::$hash, '', time() - 3600, $cookie_path, $cookie_domain );
894 771 }
895 772 }
896 773
897 - /**
898 - * Set the social_notifications_subscribe option to `off` when the Subscriptions module is activated in the first time.
899 - *
900 - * @since 8.1
901 - *
902 - * @return void
903 - */
904 - public function set_social_notifications_subscribe() {
905 - if ( false === get_option( 'social_notifications_subscribe' ) ) {
906 - add_option( 'social_notifications_subscribe', 'off' );
907 - }
908 - }
909 -
910 - /**
911 - * Save a flag when a post was ever published.
912 - *
913 - * It saves the post meta when the post was published and becomes a draft.
914 - * Then this meta is used to hide subscription messaging in Publish panel.
915 - *
916 - * @param string $new_status Tthe "new" post status of the transition when saved.
917 - * @param string $old_status The "old" post status of the transition when saved.
918 - * @param object $post obj The post object.
919 - */
920 - public function maybe_set_first_published_status( $new_status, $old_status, $post ) {
921 - $was_post_ever_published = get_post_meta( $post->ID, '_jetpack_post_was_ever_published', true );
922 - if ( ! $was_post_ever_published && 'publish' === $old_status && 'draft' === $new_status ) {
923 - update_post_meta( $post->ID, '_jetpack_post_was_ever_published', true );
924 - }
925 - }
926 -
927 - /**
928 - * Checks if the current user can publish posts.
929 - *
930 - * @return bool
931 - */
932 - public function first_published_status_meta_auth_callback() {
933 - /**
934 - * Filter the capability to view if a post was ever published in the Subscription Module.
935 - *
936 - * @module subscriptions
937 - *
938 - * @since 13.4
939 - *
940 - * @param string $capability User capability needed to view if a post was ever published. Default to publish_posts.
941 - */
942 - $capability = apply_filters( 'jetpack_subscriptions_post_was_ever_published_capability', 'publish_posts' );
943 - if ( current_user_can( $capability ) ) {
944 - return true;
945 - }
946 - return false;
947 - }
948 -
949 - /**
950 - * Registers the 'post_was_ever_published' post meta for use in the REST API.
951 - */
952 - public function register_post_meta() {
953 - $jetpack_post_was_ever_published = array(
954 - 'type' => 'boolean',
955 - 'description' => __( 'Whether the post was ever published.', 'jetpack' ),
956 - 'single' => true,
957 - 'default' => false,
958 - 'show_in_rest' => array(
959 - 'name' => 'jetpack_post_was_ever_published',
960 - ),
961 - 'auth_callback' => array( $this, 'first_published_status_meta_auth_callback' ),
962 - );
963 -
964 - register_meta( 'post', '_jetpack_post_was_ever_published', $jetpack_post_was_ever_published );
965 - }
966 -
967 - /**
968 - * Create a Subscribers menu displayed on self-hosted sites.
969 - *
970 - * - It is not displayed on WordPress.com sites.
971 - * - It directs you to Calypso to the existing Subscribers page.
972 - *
973 - * @return void
974 - */
975 - public function add_subscribers_menu() {
976 - /*
977 - * Do not display any menu on WoA and WordPress.com Simple sites (unless Classic wp-admin is enabled).
978 - * They already get a menu item under Users via nav-unification.
979 - */
980 - if ( ( new Host() )->is_wpcom_platform() && get_option( 'wpcom_admin_interface' ) !== 'wp-admin' ) {
981 - return;
982 - }
983 -
984 - $status = new Status();
985 -
986 - /*
987 - * Do not display if we're in Offline mode,
988 - * or if the user is not connected.
989 - */
990 - if (
991 - $status->is_offline_mode()
992 - || ! ( new Connection_Manager( 'jetpack' ) )->is_user_connected()
993 - ) {
994 - return;
995 - }
996 -
997 - $blog_id = Connection_Manager::get_site_id( true );
998 -
999 - $link = Redirect::get_url(
1000 - 'jetpack-menu-jetpack-manage-subscribers',
1001 - array( 'site' => $blog_id ? $blog_id : $status->get_site_suffix() )
1002 - );
1003 -
1004 - Admin_Menu::add_menu(
1005 - __( 'Subscribers', 'jetpack' ),
1006 - __( 'Subscribers', 'jetpack' ) . ' <span class="dashicons dashicons-external"></span>',
1007 - 'manage_options',
1008 - esc_url( $link ),
1009 - null,
1010 - 11
1011 - );
1012 - }
1013 -
1014 - /**
1015 - * Record tracks event if categories is created when user enters
1016 - * the edit category page through the newsletter settings page.
1017 - *
1018 - * @return void
1019 - */
1020 - public function track_newsletter_category_creation() {
1021 -
1022 - // phpcs:disable WordPress.Security.NonceVerification.Missing
1023 - if ( empty( $_POST['_wp_http_referer'] ) ) {
1024 - return;
1025 - }
1026 -
1027 - if ( strpos( sanitize_url( wp_unslash( $_POST['_wp_http_referer'] ) ), 'referer=newsletter-categories' ) > -1 ) {
1028 -
1029 - $parent = filter_var( empty( $_POST['parent'] ) ? 0 : wp_unslash( $_POST['parent'] ), FILTER_SANITIZE_NUMBER_INT );
1030 -
1031 - $is_child_category = $parent > 0;
1032 -
1033 - $tracking = new Automattic\Jetpack\Tracking();
1034 - $tracking->tracks_record_event(
1035 - wp_get_current_user(),
1036 - 'jetpack_newsletter_add_category',
1037 - array(
1038 - 'is_child_category' => $is_child_category,
1039 - )
1040 - );
1041 - }
1042 - }
1043 774 }
1044 775
1045 776 Jetpack_Subscriptions::init();
1046 777
1047 -require __DIR__ . '/subscriptions/views.php';
1048 -require __DIR__ . '/subscriptions/subscribe-modal/class-jetpack-subscribe-modal.php';
1049 -require __DIR__ . '/subscriptions/subscribe-overlay/class-jetpack-subscribe-overlay.php';
1050 -require __DIR__ . '/subscriptions/subscribe-floating-button/class-jetpack-subscribe-floating-button.php';
778 +include dirname( __FILE__ ) . '/subscriptions/views.php';