PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 8.8.1
Jetpack – WP Security, Backup, Speed, & Growth v8.8.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
jetpack / modules / subscriptions.php
subscriptions.php
893 lines 27.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Module Name: Subscriptions
4 * Module Description: Let visitors subscribe to new posts and comments via email
5 * Sort Order: 9
6 * Recommendation Order: 8
7 * First Introduced: 1.2
8 * Requires Connection: Yes
9 * Auto Activate: No
10 * Module Tags: Social
11 * Feature: Engagement
12 * Additional Search Queries: subscriptions, subscription, email, follow, followers, subscribers, signup
13 */
14
15 add_action( 'jetpack_modules_loaded', 'jetpack_subscriptions_load' );
16
17 function jetpack_subscriptions_load() {
18 Jetpack::enable_module_configurable( __FILE__ );
19 }
20
21 /**
22 * Cherry picks keys from `$_SERVER` array.
23 *
24 * @since 6.0.0
25 *
26 * @return array An array of server data.
27 */
28 function jetpack_subscriptions_cherry_pick_server_data() {
29 $data = array();
30
31 foreach ( $_SERVER as $key => $value ) {
32 if ( ! is_string( $value ) || 0 === strpos( $key, 'HTTP_COOKIE' ) ) {
33 continue;
34 }
35
36 if ( 0 === strpos( $key, 'HTTP_' ) || in_array( $key, array( 'REMOTE_ADDR', 'REQUEST_URI', 'DOCUMENT_URI' ), true ) ) {
37 $data[ $key ] = $value;
38 }
39 }
40
41 return $data;
42 }
43
44 class Jetpack_Subscriptions {
45 public $jetpack = false;
46
47 public static $hash;
48
49 /**
50 * Singleton
51 * @static
52 */
53 static function init() {
54 static $instance = false;
55
56 if ( !$instance ) {
57 $instance = new Jetpack_Subscriptions;
58 }
59
60 return $instance;
61 }
62
63 function __construct() {
64 $this->jetpack = Jetpack::init();
65
66 // Don't use COOKIEHASH as it could be shared across installs && is non-unique in multisite.
67 // @see: https://twitter.com/nacin/status/378246957451333632
68 self::$hash = md5( get_option( 'siteurl' ) );
69
70 add_filter( 'jetpack_xmlrpc_methods', array( $this, 'xmlrpc_methods' ) );
71
72 // @todo remove sync from subscriptions and move elsewhere...
73
74 // Add Configuration Page
75 add_action( 'admin_init', array( $this, 'configure' ) );
76
77 // Catch subscription widget submits
78 if ( isset( $_REQUEST['jetpack_subscriptions_widget'] ) )
79 add_action( 'template_redirect', array( $this, 'widget_submit' ) );
80
81 // Set up the comment subscription checkboxes
82 add_filter( 'comment_form_submit_field', array( $this, 'comment_subscribe_init' ), 10, 2 );
83
84 // Catch comment posts and check for subscriptions.
85 add_action( 'comment_post', array( $this, 'comment_subscribe_submit' ), 50, 2 );
86
87 // Adds post meta checkbox in the post submit metabox
88 add_action( 'post_submitbox_misc_actions', array( $this, 'subscription_post_page_metabox' ) );
89
90 add_action( 'transition_post_status', array( $this, 'maybe_send_subscription_email' ), 10, 3 );
91
92 add_filter( 'jetpack_published_post_flags', array( $this, 'set_post_flags' ), 10, 2 );
93
94 add_filter( 'post_updated_messages', array( $this, 'update_published_message' ), 18, 1 );
95
96 // Set "social_notifications_subscribe" option during the first-time activation.
97 add_action( 'jetpack_activate_module_subscriptions', array( $this, 'set_social_notifications_subscribe' ) );
98 }
99
100 /**
101 * Jetpack_Subscriptions::xmlrpc_methods()
102 *
103 * Register subscriptions methods with the Jetpack XML-RPC server.
104 * @param array $methods
105 */
106 function xmlrpc_methods( $methods ) {
107 return array_merge(
108 $methods,
109 array(
110 'jetpack.subscriptions.subscribe' => array( $this, 'subscribe' ),
111 )
112 );
113 }
114
115 /*
116 * Disable Subscribe on Single Post
117 * Register post meta
118 */
119 function subscription_post_page_metabox() {
120 if (
121 /**
122 * Filter whether or not to show the per-post subscription option.
123 *
124 * @module subscriptions
125 *
126 * @since 3.7.0
127 *
128 * @param bool true = show checkbox option on all new posts | false = hide the option.
129 */
130 ! apply_filters( 'jetpack_allow_per_post_subscriptions', false ) )
131 {
132 return;
133 }
134
135 if ( has_filter( 'jetpack_subscriptions_exclude_these_categories' ) || has_filter( 'jetpack_subscriptions_include_only_these_categories' ) ) {
136 return;
137 }
138
139 global $post;
140 $disable_subscribe_value = get_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', true );
141 // only show checkbox if post hasn't been published and is a 'post' post type.
142 if ( get_post_status( $post->ID ) !== 'publish' && get_post_type( $post->ID ) == 'post' ) :
143 // Nonce it
144 wp_nonce_field( 'disable_subscribe', 'disable_subscribe_nonce' );
145 ?>
146 <div class="misc-pub-section">
147 <label for="_jetpack_dont_email_post_to_subs"><?php _e( 'Jetpack Subscriptions:', 'jetpack' ); ?></label><br>
148 <input type="checkbox" name="_jetpack_dont_email_post_to_subs" id="jetpack-per-post-subscribe" value="1" <?php checked( $disable_subscribe_value, 1, true ); ?> />
149 <?php _e( 'Don&#8217;t send this to subscribers', 'jetpack' ); ?>
150 </div>
151 <?php endif;
152 }
153
154 /**
155 * Checks whether or not the post should be emailed to subscribers
156 *
157 * It checks for the following things in order:
158 * - Usage of filter jetpack_subscriptions_exclude_these_categories
159 * - Usage of filter jetpack_subscriptions_include_only_these_categories
160 * - Existence of the per-post checkbox option
161 *
162 * Only one of these can be used at any given time.
163 *
164 * @param $new_status string - the "new" post status of the transition when saved
165 * @param $old_status string - the "old" post status of the transition when saved
166 * @param $post obj - The post object
167 */
168 function maybe_send_subscription_email( $new_status, $old_status, $post ) {
169
170 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
171 return;
172 }
173
174 // Make sure that the checkbox is preseved
175 if ( ! empty( $_POST['disable_subscribe_nonce'] ) && wp_verify_nonce( $_POST['disable_subscribe_nonce'], 'disable_subscribe' ) ) {
176 $set_checkbox = isset( $_POST['_jetpack_dont_email_post_to_subs'] ) ? 1 : 0;
177 update_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', $set_checkbox );
178 }
179 }
180
181 function update_published_message( $messages ) {
182 global $post;
183 if ( ! $this->should_email_post_to_subscribers( $post ) ) {
184 return $messages;
185 }
186
187 $view_post_link_html = sprintf( ' <a href="%1$s">%2$s</a>',
188 esc_url( get_permalink( $post ) ),
189 __( 'View post', 'jetpack' )
190 );
191
192 $messages['post'][6] = sprintf(
193 /* translators: Message shown after a post is published */
194 esc_html__( 'Post published and sending emails to subscribers.', 'jetpack' )
195 ) . $view_post_link_html;
196 return $messages;
197 }
198
199 public function should_email_post_to_subscribers( $post ) {
200 $should_email = true;
201 if ( get_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', true ) ) {
202 return false;
203 }
204
205 // Only posts are currently supported
206 if ( $post->post_type !== 'post' ) {
207 return false;
208 }
209
210 // Private posts are not sent to subscribers.
211 if ( 'private' === $post->post_status ) {
212 return false;
213 }
214
215 /**
216 * Array of categories that will never trigger subscription emails.
217 *
218 * Will not send subscription emails from any post from within these categories.
219 *
220 * @module subscriptions
221 *
222 * @since 3.7.0
223 *
224 * @param array $args Array of category slugs or ID's.
225 */
226 $excluded_categories = apply_filters( 'jetpack_subscriptions_exclude_these_categories', array() );
227
228 // Never email posts from these categories
229 if ( ! empty( $excluded_categories ) && in_category( $excluded_categories, $post->ID ) ) {
230 $should_email = false;
231 }
232
233 /**
234 * ONLY send subscription emails for these categories
235 *
236 * Will ONLY send subscription emails to these categories.
237 *
238 * @module subscriptions
239 *
240 * @since 3.7.0
241 *
242 * @param array $args Array of category slugs or ID's.
243 */
244 $only_these_categories = apply_filters( 'jetpack_subscriptions_exclude_all_categories_except', array() );
245
246 // Only emails posts from these categories
247 if ( ! empty( $only_these_categories ) && ! in_category( $only_these_categories, $post->ID ) ) {
248 $should_email = false;
249 }
250
251 return $should_email;
252 }
253
254 function set_post_flags( $flags, $post ) {
255 $flags['send_subscription'] = $this->should_email_post_to_subscribers( $post );
256 return $flags;
257 }
258
259 /**
260 * Jetpack_Subscriptions::configure()
261 *
262 * Jetpack Subscriptions configuration screen.
263 */
264 function configure() {
265 // Create the section
266 add_settings_section(
267 'jetpack_subscriptions',
268 __( 'Jetpack Subscriptions Settings', 'jetpack' ),
269 array( $this, 'subscriptions_settings_section' ),
270 'discussion'
271 );
272
273 /** Subscribe to Posts ***************************************************/
274
275 add_settings_field(
276 'jetpack_subscriptions_post_subscribe',
277 __( 'Follow Blog', 'jetpack' ),
278 array( $this, 'subscription_post_subscribe_setting' ),
279 'discussion',
280 'jetpack_subscriptions'
281 );
282
283 register_setting(
284 'discussion',
285 'stb_enabled'
286 );
287
288 /** Subscribe to Comments ******************************************************/
289
290 add_settings_field(
291 'jetpack_subscriptions_comment_subscribe',
292 __( 'Follow Comments', 'jetpack' ),
293 array( $this, 'subscription_comment_subscribe_setting' ),
294 'discussion',
295 'jetpack_subscriptions'
296 );
297
298 register_setting(
299 'discussion',
300 'stc_enabled'
301 );
302
303 /** Email me whenever: Someone follows my blog ***************************************************/
304 /* @since 8.1 */
305
306 add_settings_section(
307 'notifications_section',
308 __( 'Someone follows my blog', 'jetpack' ),
309 array( $this, 'social_notifications_subscribe_section' ),
310 'discussion'
311 );
312
313 add_settings_field(
314 'jetpack_subscriptions_social_notifications_subscribe',
315 __( 'Email me whenever', 'jetpack' ),
316 array( $this, 'social_notifications_subscribe_field' ),
317 'discussion',
318 'notifications_section'
319 );
320
321 register_setting(
322 'discussion',
323 'social_notifications_subscribe',
324 array( $this, 'social_notifications_subscribe_validate' )
325 );
326
327 /** Subscription Messaging Options ******************************************************/
328
329 register_setting(
330 'reading',
331 'subscription_options',
332 array( $this, 'validate_settings' )
333 );
334
335 add_settings_section(
336 'email_settings',
337 __( 'Follower Settings', 'jetpack' ),
338 array( $this, 'reading_section' ),
339 'reading'
340 );
341
342 add_settings_field(
343 'invitation',
344 __( 'Blog follow email text', 'jetpack' ),
345 array( $this, 'setting_invitation' ),
346 'reading',
347 'email_settings'
348 );
349
350 add_settings_field(
351 'comment-follow',
352 __( 'Comment follow email text', 'jetpack' ),
353 array( $this, 'setting_comment_follow' ),
354 'reading',
355 'email_settings'
356 );
357 }
358
359 /**
360 * Discussions setting section blurb
361 *
362 */
363 function subscriptions_settings_section() {
364 ?>
365 <p id="jetpack-subscriptions-settings"><?php _e( 'Change whether your visitors can subscribe to your posts or comments or both.', 'jetpack' ); ?></p>
366
367 <?php
368 }
369
370 /**
371 * Post Subscriptions Toggle
372 *
373 */
374 function subscription_post_subscribe_setting() {
375
376 $stb_enabled = get_option( 'stb_enabled', 1 ); ?>
377
378 <p class="description">
379 <input type="checkbox" name="stb_enabled" id="jetpack-post-subscribe" value="1" <?php checked( $stb_enabled, 1 ); ?> />
380 <?php _e( "Show a <em>'follow blog'</em> option in the comment form", 'jetpack' ); ?>
381 </p>
382 <?php
383 }
384
385 /**
386 * Comments Subscriptions Toggle
387 *
388 */
389 function subscription_comment_subscribe_setting() {
390
391 $stc_enabled = get_option( 'stc_enabled', 1 ); ?>
392
393 <p class="description">
394 <input type="checkbox" name="stc_enabled" id="jetpack-comment-subscribe" value="1" <?php checked( $stc_enabled, 1 ); ?> />
395 <?php _e( "Show a <em>'follow comments'</em> option in the comment form", 'jetpack' ); ?>
396 </p>
397
398 <?php
399 }
400
401 /**
402 * Someone follows my blog section
403 *
404 * @since 8.1
405 */
406 public function social_notifications_subscribe_section() {
407 // Atypical usage here. We emit jquery to move subscribe notification checkbox to be with the rest of the email notification settings
408 ?>
409 <script type="text/javascript">
410 jQuery( function( $ ) {
411 var table = $( '#social_notifications_subscribe' ).parents( 'table:first' ),
412 header = table.prevAll( 'h2:first' ),
413 newParent = $( '#moderation_notify' ).parent( 'label' ).parent();
414
415 if ( ! table.length || ! header.length || ! newParent.length ) {
416 return;
417 }
418
419 newParent.append( '<br/>' ).append( table.end().parent( 'label' ).siblings().andSelf() );
420 header.remove();
421 table.remove();
422 } );
423 </script>
424 <?php
425 }
426
427 /**
428 * Someone follows my blog Toggle
429 *
430 * @since 8.1
431 */
432 public function social_notifications_subscribe_field() {
433 $checked = intval( 'on' === get_option( 'social_notifications_subscribe', 'on' ) );
434 ?>
435
436 <label>
437 <input type="checkbox" name="social_notifications_subscribe" id="social_notifications_subscribe" value="1" <?php checked( $checked ); ?> />
438 <?php
439 /* translators: this is a label for a setting that starts with "Email me whenever" */
440 esc_html_e( 'Someone follows my blog', 'jetpack' );
441 ?>
442 </label>
443 <?php
444 }
445
446 /**
447 * Validate "Someone follows my blog" option
448 *
449 * @since 8.1
450 *
451 * @param String $input the input string to be validated.
452 * @return string on|off
453 */
454 public function social_notifications_subscribe_validate( $input ) {
455 // If it's not set (was unchecked during form submission) or was set to off (during option update), return 'off'.
456 if ( ! $input || 'off' === $input ) {
457 return 'off';
458 }
459
460 // Otherwise we return 'on'.
461 return 'on';
462 }
463
464 function validate_settings( $settings ) {
465 global $allowedposttags;
466
467 $default = $this->get_default_settings();
468
469 // Blog Follow
470 $settings['invitation'] = trim( wp_kses( $settings['invitation'], $allowedposttags ) );
471 if ( empty( $settings['invitation'] ) )
472 $settings['invitation'] = $default['invitation'];
473
474 // Comments Follow (single post)
475 $settings['comment_follow'] = trim( wp_kses( $settings['comment_follow'], $allowedposttags ) );
476 if ( empty( $settings['comment_follow'] ) )
477 $settings['comment_follow'] = $default['comment_follow'];
478
479 return $settings;
480 }
481
482 public function reading_section() {
483 echo '<p id="follower-settings">';
484 _e( 'These settings change emails sent from your blog to followers.', 'jetpack' );
485 echo '</p>';
486 }
487
488 public function setting_invitation() {
489 $settings = $this->get_settings();
490 echo '<textarea name="subscription_options[invitation]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['invitation'] ) . '</textarea>';
491 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>';
492 }
493
494 public function setting_comment_follow() {
495 $settings = $this->get_settings();
496 echo '<textarea name="subscription_options[comment_follow]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['comment_follow'] ) . '</textarea>';
497 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>';
498 }
499
500 function get_default_settings() {
501 return array(
502 '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' ),
503 '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' )
504 );
505 }
506
507 function get_settings() {
508 return wp_parse_args( (array) get_option( 'subscription_options', array() ), $this->get_default_settings() );
509 }
510
511 /**
512 * Jetpack_Subscriptions::subscribe()
513 *
514 * Send a synchronous XML-RPC subscribe to blog posts or subscribe to post comments request.
515 *
516 * @param string $email
517 * @param array $post_ids (optional) defaults to 0 for blog posts only: array of post IDs to subscribe to blog's posts
518 * @param bool $async (optional) Should the subscription be performed asynchronously? Defaults to true.
519 *
520 * @return true|WP_Error true on success
521 * invalid_email : not a valid email address
522 * invalid_post_id : not a valid post ID
523 * unknown_post_id : unknown post
524 * not_subscribed : strange error. Jetpack servers at WordPress.com could subscribe the email.
525 * disabled : Site owner has disabled subscriptions.
526 * active : Already subscribed.
527 * pending : Tried to subscribe before but the confirmation link is never clicked. No confirmation email is sent.
528 * unknown : strange error. Jetpack servers at WordPress.com returned something malformed.
529 * unknown_status : strange error. Jetpack servers at WordPress.com returned something I didn't understand.
530 */
531 function subscribe( $email, $post_ids = 0, $async = true, $extra_data = array() ) {
532 if ( !is_email( $email ) ) {
533 return new WP_Error( 'invalid_email' );
534 }
535
536 if ( !$async ) {
537 $xml = new Jetpack_IXR_ClientMulticall();
538 }
539
540 foreach ( (array) $post_ids as $post_id ) {
541 $post_id = (int) $post_id;
542 if ( $post_id < 0 ) {
543 return new WP_Error( 'invalid_post_id' );
544 } else if ( $post_id && !$post = get_post( $post_id ) ) {
545 return new WP_Error( 'unknown_post_id' );
546 }
547
548 if ( $async ) {
549 Jetpack::xmlrpc_async_call( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) );
550 } else {
551 $xml->addCall( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) );
552 }
553 }
554
555 if ( $async ) {
556 return;
557 }
558
559 // Call
560 $xml->query();
561
562 if ( $xml->isError() ) {
563 return $xml->get_jetpack_error();
564 }
565
566 $responses = $xml->getResponse();
567
568 $r = array();
569 foreach ( (array) $responses as $response ) {
570 if ( isset( $response['faultCode'] ) || isset( $response['faultString'] ) ) {
571 $r[] = $xml->get_jetpack_error( $response['faultCode'], $response['faultString'] );
572 continue;
573 }
574
575 if ( !is_array( $response[0] ) || empty( $response[0]['status'] ) ) {
576 $r[] = new WP_Error( 'unknown' );
577 continue;
578 }
579
580 switch ( $response[0]['status'] ) {
581 case 'error':
582 $r[] = new WP_Error( 'not_subscribed' );
583 continue 2;
584 case 'disabled':
585 $r[] = new WP_Error( 'disabled' );
586 continue 2;
587 case 'active':
588 $r[] = new WP_Error( 'active' );
589 continue 2;
590 case 'confirming':
591 $r[] = true;
592 continue 2;
593 case 'pending':
594 $r[] = new WP_Error( 'pending' );
595 continue 2;
596 default:
597 $r[] = new WP_Error( 'unknown_status', (string) $response[0]['status'] );
598 continue 2;
599 }
600 }
601
602 return $r;
603 }
604
605 /**
606 * Jetpack_Subscriptions::widget_submit()
607 *
608 * When a user submits their email via the blog subscription widget, check the details and call the subsribe() method.
609 */
610 function widget_submit() {
611 // Check the nonce.
612 if ( is_user_logged_in() ) {
613 check_admin_referer( 'blogsub_subscribe_' . get_current_blog_id() );
614 }
615
616 if ( empty( $_REQUEST['email'] ) || ! is_string( $_REQUEST['email'] ) )
617 return false;
618
619 $redirect_fragment = false;
620 if ( isset( $_REQUEST['redirect_fragment'] ) ) {
621 $redirect_fragment = preg_replace( '/[^a-z0-9_-]/i', '', $_REQUEST['redirect_fragment'] );
622 }
623 if ( !$redirect_fragment || ! is_string( $redirect_fragment ) ) {
624 $redirect_fragment = 'subscribe-blog';
625 }
626
627 $subscribe = Jetpack_Subscriptions::subscribe(
628 $_REQUEST['email'],
629 0,
630 false,
631 array(
632 'source' => 'widget',
633 'widget-in-use' => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
634 'comment_status' => '',
635 'server_data' => jetpack_subscriptions_cherry_pick_server_data(),
636 )
637 );
638
639 if ( is_wp_error( $subscribe ) ) {
640 $error = $subscribe->get_error_code();
641 } else {
642 $error = false;
643 foreach ( $subscribe as $response ) {
644 if ( is_wp_error( $response ) ) {
645 $error = $response->get_error_code();
646 break;
647 }
648 }
649 }
650
651 switch ( $error ) {
652 case false:
653 $result = 'success';
654 break;
655 case 'invalid_email':
656 $result = $error;
657 break;
658 case 'blocked_email':
659 $result = 'opted_out';
660 break;
661 case 'active':
662 $result = 'already';
663 break;
664 case 'flooded_email':
665 $result = 'many_pending_subs';
666 break;
667 case 'pending':
668 $result = 'pending';
669 break;
670 default:
671 $result = 'error';
672 break;
673 }
674
675 $redirect = add_query_arg( 'subscribe', $result );
676
677 /**
678 * Fires on each subscription form submission.
679 *
680 * @module subscriptions
681 *
682 * @since 3.7.0
683 *
684 * @param string $result Result of form submission: success, invalid_email, already, error.
685 */
686 do_action( 'jetpack_subscriptions_form_submission', $result );
687
688 wp_safe_redirect( "$redirect#$redirect_fragment" );
689 exit;
690 }
691
692 /**
693 * Jetpack_Subscriptions::comment_subscribe_init()
694 *
695 * Set up and add the comment subscription checkbox to the comment form.
696 *
697 * @param string $submit_button HTML markup for the submit field.
698 * @param array $args Arguments passed to `comment_form()`.
699 */
700 function comment_subscribe_init( $submit_button, $args ) {
701 global $post;
702
703 $comments_checked = '';
704 $blog_checked = '';
705
706 // Check for a comment / blog submission and set a cookie to retain the setting and check the boxes.
707 if ( isset( $_COOKIE[ 'jetpack_comments_subscribe_' . self::$hash . '_' . $post->ID ] ) ) {
708 $comments_checked = ' checked="checked"';
709 }
710
711 if ( isset( $_COOKIE[ 'jetpack_blog_subscribe_' . self::$hash ] ) ) {
712 $blog_checked = ' checked="checked"';
713 }
714
715 // Some themes call this function, don't show the checkbox again
716 remove_action( 'comment_form', 'subscription_comment_form' );
717
718 // Check if Mark Jaquith's Subscribe to Comments plugin is active - if so, suppress Jetpack checkbox
719
720 $str = '';
721
722 if ( FALSE === has_filter( 'comment_form', 'show_subscription_checkbox' ) && 1 == get_option( 'stc_enabled', 1 ) && empty( $post->post_password ) && 'post' == get_post_type() ) {
723 // Subscribe to comments checkbox
724 $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 . ' /> ';
725 $comment_sub_text = __( 'Notify me of follow-up comments by email.', 'jetpack' );
726 $str .= '<label class="subscribe-label" id="subscribe-label" for="subscribe_comments">' . esc_html(
727 /**
728 * Filter the Subscribe to comments text appearing below the comment form.
729 *
730 * @module subscriptions
731 *
732 * @since 3.4.0
733 *
734 * @param string $comment_sub_text Subscribe to comments text.
735 */
736 apply_filters( 'jetpack_subscribe_comment_label', $comment_sub_text )
737 ) . '</label>';
738 $str .= '</p>';
739 }
740
741 if ( 1 == get_option( 'stb_enabled', 1 ) ) {
742 // Subscribe to blog checkbox
743 $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 . ' /> ';
744 $blog_sub_text = __( 'Notify me of new posts by email.', 'jetpack' );
745 $str .= '<label class="subscribe-label" id="subscribe-blog-label" for="subscribe_blog">' . esc_html(
746 /**
747 * Filter the Subscribe to blog text appearing below the comment form.
748 *
749 * @module subscriptions
750 *
751 * @since 3.4.0
752 *
753 * @param string $comment_sub_text Subscribe to blog text.
754 */
755 apply_filters( 'jetpack_subscribe_blog_label', $blog_sub_text )
756 ) . '</label>';
757 $str .= '</p>';
758 }
759
760 /**
761 * Filter the output of the subscription options appearing below the comment form.
762 *
763 * @module subscriptions
764 *
765 * @since 1.2.0
766 *
767 * @param string $str Comment Subscription form HTML output.
768 */
769 $str = apply_filters( 'jetpack_comment_subscription_form', $str );
770
771 return $str . $submit_button;
772 }
773
774 /**
775 * Jetpack_Subscriptions::comment_subscribe_init()
776 *
777 * When a user checks the comment subscribe box and submits a comment, subscribe them to the comment thread.
778 */
779 function comment_subscribe_submit( $comment_id, $approved ) {
780 if ( 'spam' === $approved ) {
781 return;
782 }
783
784 $comment = get_comment( $comment_id );
785
786 // Set cookies for this post/comment
787 $this->set_cookies( isset( $_REQUEST['subscribe_comments'] ), $comment->comment_post_ID, isset( $_REQUEST['subscribe_blog'] ) );
788
789 if ( !isset( $_REQUEST['subscribe_comments'] ) && !isset( $_REQUEST['subscribe_blog'] ) )
790 return;
791
792 $post_ids = array();
793
794 if ( isset( $_REQUEST['subscribe_comments'] ) )
795 $post_ids[] = $comment->comment_post_ID;
796
797 if ( isset( $_REQUEST['subscribe_blog'] ) )
798 $post_ids[] = 0;
799
800 $result = Jetpack_Subscriptions::subscribe(
801 $comment->comment_author_email,
802 $post_ids,
803 true,
804 array(
805 'source' => 'comment-form',
806 'widget-in-use' => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
807 'comment_status' => $approved,
808 'server_data' => jetpack_subscriptions_cherry_pick_server_data(),
809 )
810 );
811
812 /**
813 * Fires on each comment subscription form submission.
814 *
815 * @module subscriptions
816 *
817 * @since 5.5.0
818 *
819 * @param NULL|WP_Error $result Result of form submission: NULL on success, WP_Error otherwise.
820 * @param array $post_ids An array of post IDs that the user subscribed to, 0 means blog subscription.
821 */
822 do_action( 'jetpack_subscriptions_comment_form_submission', $result, $post_ids );
823 }
824
825 /**
826 * Jetpack_Subscriptions::set_cookies()
827 *
828 * Set a cookie to save state on the comment and post subscription checkboxes.
829 *
830 * @param bool $subscribe_to_post Whether the user chose to subscribe to subsequent comments on this post.
831 * @param int $post_id If $subscribe_to_post is true, the post ID they've subscribed to.
832 * @param bool $subscribe_to_blog Whether the user chose to subscribe to all new posts on the blog.
833 */
834 function set_cookies( $subscribe_to_post = false, $post_id = null, $subscribe_to_blog = false ) {
835 $post_id = intval( $post_id );
836
837 /** This filter is already documented in core/wp-includes/comment-functions.php */
838 $cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
839
840 /**
841 * Filter the Jetpack Comment cookie path.
842 *
843 * @module subscriptions
844 *
845 * @since 2.5.0
846 *
847 * @param string COOKIEPATH Cookie path.
848 */
849 $cookie_path = apply_filters( 'jetpack_comment_cookie_path', COOKIEPATH );
850
851 /**
852 * Filter the Jetpack Comment cookie domain.
853 *
854 * @module subscriptions
855 *
856 * @since 2.5.0
857 *
858 * @param string COOKIE_DOMAIN Cookie domain.
859 */
860 $cookie_domain = apply_filters( 'jetpack_comment_cookie_domain', COOKIE_DOMAIN );
861
862 if ( $subscribe_to_post && $post_id >= 0 ) {
863 setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain );
864 } else {
865 setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, '', time() - 3600, $cookie_path, $cookie_domain );
866 }
867
868 if ( $subscribe_to_blog ) {
869 setcookie( 'jetpack_blog_subscribe_' . self::$hash, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain );
870 } else {
871 setcookie( 'jetpack_blog_subscribe_' . self::$hash, '', time() - 3600, $cookie_path, $cookie_domain );
872 }
873 }
874
875 /**
876 * Set the social_notifications_subscribe option to `off` when the Subscriptions module is activated in the first time.
877 *
878 * @since 8.1
879 *
880 * @return null
881 */
882 function set_social_notifications_subscribe() {
883 if ( false === get_option( 'social_notifications_subscribe' ) ) {
884 add_option( 'social_notifications_subscribe', 'off' );
885 }
886 }
887
888 }
889
890 Jetpack_Subscriptions::init();
891
892 include dirname( __FILE__ ) . '/subscriptions/views.php';
893