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