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