PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 8.1
Jetpack – WP Security, Backup, Speed, & Growth v8.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 in Jetpack – WP Security, Backup, Speed, & Growth 8.1, at modules/subscriptions.php

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