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

840 lines 29.7 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: 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.
6 * Sort Order: 9
7 * Recommendation Order: 8
8 * First Introduced: 1.2
9 * Requires Connection: Yes
10 * Auto Activate: Yes
11 * Module Tags: Social
12 * Feature: Jumpstart
13 */
14
15 add_action( 'jetpack_modules_loaded', 'jetpack_subscriptions_load' );
16
17 Jetpack_Sync::sync_options(
18 __FILE__,
19 'home',
20 'blogname',
21 'siteurl',
22 'page_on_front',
23 'permalink_structure',
24 'category_base',
25 'rss_use_excerpt',
26 'subscription_options',
27 'stb_enabled',
28 'stc_enabled',
29 'tag_base'
30 );
31
32 Jetpack_Sync::sync_posts( __FILE__ );
33 Jetpack_Sync::sync_comments( __FILE__ );
34
35 function jetpack_subscriptions_load() {
36 Jetpack::enable_module_configurable( __FILE__ );
37 Jetpack::module_configuration_load( __FILE__, 'jetpack_subscriptions_configuration_load' );
38 }
39
40 function jetpack_subscriptions_configuration_load() {
41 wp_safe_redirect( admin_url( 'options-discussion.php#jetpack-subscriptions-settings' ) );
42 exit;
43 }
44
45 class Jetpack_Subscriptions {
46 var $jetpack = false;
47
48 public static $hash;
49
50 /**
51 * Singleton
52 * @static
53 */
54 static function init() {
55 static $instance = false;
56
57 if ( !$instance ) {
58 $instance = new Jetpack_Subscriptions;
59 }
60
61 return $instance;
62 }
63
64 function __construct() {
65 $this->jetpack = Jetpack::init();
66
67 // Don't use COOKIEHASH as it could be shared across installs && is non-unique in multisite.
68 // @see: https://twitter.com/nacin/status/378246957451333632
69 self::$hash = md5( get_option( 'siteurl' ) );
70
71 add_filter( 'jetpack_xmlrpc_methods', array( $this, 'xmlrpc_methods' ) );
72
73 // @todo remove sync from subscriptions and move elsewhere...
74
75 // Add Configuration Page
76 add_action( 'admin_init', array( $this, 'configure' ) );
77
78 // Set up the subscription widget.
79 add_action( 'widgets_init', array( $this, 'widget_init' ) );
80
81 // Catch subscription widget submits
82 if ( isset( $_REQUEST['jetpack_subscriptions_widget'] ) )
83 add_action( 'template_redirect', array( $this, 'widget_submit' ) );
84
85 // Set up the comment subscription checkboxes
86 add_action( 'comment_form', array( $this, 'comment_subscribe_init' ) );
87
88 // Catch comment posts and check for subscriptions.
89 add_action( 'comment_post', array( $this, 'comment_subscribe_submit' ), 50, 2 );
90 }
91
92 function post_is_public( $the_post ) {
93 if ( !$post = get_post( $the_post ) ) {
94 return false;
95 }
96
97 if ( 'publish' === $post->post_status && strlen( (string) $post->post_password ) < 1 ) {
98 return apply_filters( 'jetpack_is_post_mailable', true );
99 }
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 * Jetpack_Subscriptions::configure()
119 *
120 * Jetpack Subscriptions configuration screen.
121 */
122 function configure() {
123 // Create the section
124 add_settings_section(
125 'jetpack_subscriptions',
126 __( 'Jetpack Subscriptions Settings', 'jetpack' ),
127 array( $this, 'subscriptions_settings_section' ),
128 'discussion'
129 );
130
131 /** Subscribe to Posts ***************************************************/
132
133 add_settings_field(
134 'jetpack_subscriptions_post_subscribe',
135 __( 'Follow Blog', 'jetpack' ),
136 array( $this, 'subscription_post_subscribe_setting' ),
137 'discussion',
138 'jetpack_subscriptions'
139 );
140
141 register_setting(
142 'discussion',
143 'stb_enabled'
144 );
145
146 /** Subscribe to Comments ******************************************************/
147
148 add_settings_field(
149 'jetpack_subscriptions_comment_subscribe',
150 __( 'Follow Comments', 'jetpack' ),
151 array( $this, 'subscription_comment_subscribe_setting' ),
152 'discussion',
153 'jetpack_subscriptions'
154 );
155
156 register_setting(
157 'discussion',
158 'stc_enabled'
159 );
160
161 /** Subscription Messaging Options ******************************************************/
162
163 register_setting(
164 'reading',
165 'subscription_options',
166 array( $this, 'validate_settings' )
167 );
168
169 add_settings_section(
170 'email_settings',
171 __( 'Follower Settings', 'jetpack' ),
172 array( $this, 'reading_section' ),
173 'reading'
174 );
175
176 add_settings_field(
177 'invitation',
178 __( 'Blog follow email text', 'jetpack' ),
179 array( $this, 'setting_invitation' ),
180 'reading',
181 'email_settings'
182 );
183
184 add_settings_field(
185 'comment-follow',
186 __( 'Comment follow email text', 'jetpack' ),
187 array( $this, 'setting_comment_follow' ),
188 'reading',
189 'email_settings'
190 );
191 }
192
193 /**
194 * Discussions setting section blurb
195 *
196 */
197 function subscriptions_settings_section() {
198 ?>
199
200 <p id="jetpack-subscriptions-settings"><?php _e( 'Change whether your visitors can subscribe to your posts or comments or both.', 'jetpack' ); ?></p>
201
202 <?php
203 }
204
205 /**
206 * Post Subscriptions Toggle
207 *
208 */
209 function subscription_post_subscribe_setting() {
210
211 $stb_enabled = get_option( 'stb_enabled', 1 ); ?>
212
213 <p class="description">
214 <input type="checkbox" name="stb_enabled" id="jetpack-post-subscribe" value="1" <?php checked( $stb_enabled, 1 ); ?> />
215 <?php _e( "Show a <em>'follow blog'</em> option in the comment form", 'jetpack' ); ?>
216 </p>
217 <?php
218 }
219
220 /**
221 * Comments Subscriptions Toggle
222 *
223 */
224 function subscription_comment_subscribe_setting() {
225
226 $stc_enabled = get_option( 'stc_enabled', 1 ); ?>
227
228 <p class="description">
229 <input type="checkbox" name="stc_enabled" id="jetpack-comment-subscribe" value="1" <?php checked( $stc_enabled, 1 ); ?> />
230 <?php _e( "Show a <em>'follow comments'</em> option in the comment form", 'jetpack' ); ?>
231 </p>
232
233 <?php
234 }
235
236 function validate_settings( $settings ) {
237 global $allowedposttags;
238
239 $default = $this->get_default_settings();
240
241 // Blog Follow
242 $settings['invitation'] = trim( wp_kses( $settings['invitation'], $allowedposttags ) );
243 if ( empty( $settings['invitation'] ) )
244 $settings['invitation'] = $default['invitation'];
245
246 // Comments Follow (single post)
247 $settings['comment_follow'] = trim( wp_kses( $settings['comment_follow'], $allowedposttags ) );
248 if ( empty( $settings['comment_follow'] ) )
249 $settings['comment_follow'] = $default['comment_follow'];
250
251 return $settings;
252 }
253
254 public function reading_section() {
255 echo '<p id="follower-settings">';
256 _e( 'These settings change emails sent from your blog to followers.', 'jetpack' );
257 echo '</p>';
258 }
259
260 public function setting_invitation() {
261 $settings = $this->get_settings();
262 echo '<textarea name="subscription_options[invitation]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['invitation'] ) . '</textarea>';
263 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>';
264 }
265
266 public function setting_comment_follow() {
267 $settings = $this->get_settings();
268 echo '<textarea name="subscription_options[comment_follow]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['comment_follow'] ) . '</textarea>';
269 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>';
270 }
271
272 function get_default_settings() {
273 return array(
274 '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' ),
275 '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' )
276 );
277 }
278
279 function get_settings() {
280 return wp_parse_args( (array) get_option( 'subscription_options', array() ), $this->get_default_settings() );
281 }
282
283 /**
284 * Jetpack_Subscriptions::subscribe()
285 *
286 * Send a synchronous XML-RPC subscribe to blog posts or subscribe to post comments request.
287 *
288 * @param string $email
289 * @param array $post_ids (optional) defaults to 0 for blog posts only: array of post IDs to subscribe to blog's posts
290 * @param bool $async (optional) Should the subscription be performed asynchronously? Defaults to true.
291 *
292 * @return true|Jetpack_Error true on success
293 * invalid_email : not a valid email address
294 * invalid_post_id : not a valid post ID
295 * unknown_post_id : unknown post
296 * not_subscribed : strange error. Jetpack servers at WordPress.com could subscribe the email.
297 * disabled : Site owner has disabled subscriptions.
298 * active : Already subscribed.
299 * unknown : strange error. Jetpack servers at WordPress.com returned something malformed.
300 * unknown_status : strange error. Jetpack servers at WordPress.com returned something I didn't understand.
301 */
302 function subscribe( $email, $post_ids = 0, $async = true, $extra_data = array() ) {
303 if ( !is_email( $email ) ) {
304 return new Jetpack_Error( 'invalid_email' );
305 }
306
307 if ( !$async ) {
308 Jetpack::load_xml_rpc_client();
309 $xml = new Jetpack_IXR_ClientMulticall();
310 }
311
312 foreach ( (array) $post_ids as $post_id ) {
313 $post_id = (int) $post_id;
314 if ( $post_id < 0 ) {
315 return new Jetpack_Error( 'invalid_post_id' );
316 } else if ( $post_id && !$post = get_post( $post_id ) ) {
317 return new Jetpack_Error( 'unknown_post_id' );
318 }
319
320 if ( $async ) {
321 Jetpack::xmlrpc_async_call( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) );
322 } else {
323 $xml->addCall( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) );
324 }
325 }
326
327 if ( $async ) {
328 return;
329 }
330
331 // Call
332 $xml->query();
333
334 if ( $xml->isError() ) {
335 return $xml->get_jetpack_error();
336 }
337
338 $responses = $xml->getResponse();
339
340 $r = array();
341 foreach ( (array) $responses as $response ) {
342 if ( isset( $response['faultCode'] ) || isset( $response['faultString'] ) ) {
343 $r[] = $xml->get_jetpack_error( $response['faultCode'], $response['faultString'] );
344 continue;
345 }
346
347 if ( !is_array( $response[0] ) || empty( $response[0]['status'] ) ) {
348 $r[] = new Jetpack_Error( 'unknown' );
349 continue;
350 }
351
352 switch ( $response[0]['status'] ) {
353 case 'error' :
354 $r[] = new Jetpack_Error( 'not_subscribed' );
355 continue 2;
356 case 'disabled' :
357 $r[] = new Jetpack_Error( 'disabled' );
358 continue 2;
359 case 'active' :
360 $r[] = new Jetpack_Error( 'active' );
361 continue 2;
362 case 'pending' :
363 $r[] = true;
364 continue 2;
365 default :
366 $r[] = new Jetpack_Error( 'unknown_status', (string) $response[0]['status'] );
367 continue 2;
368 }
369 }
370
371 return $r;
372 }
373
374 /**
375 * Jetpack_Subscriptions::widget_init()
376 *
377 * Initialize and register the Jetpack Subscriptions widget.
378 */
379 function widget_init() {
380 register_widget( 'Jetpack_Subscriptions_Widget' );
381 }
382
383 /**
384 * Jetpack_Subscriptions::widget_submit()
385 *
386 * When a user submits their email via the blog subscription widget, check the details and call the subsribe() method.
387 */
388 function widget_submit() {
389 // Check the nonce.
390 if ( is_user_logged_in() ) {
391 check_admin_referer( 'blogsub_subscribe_' . get_current_blog_id() );
392 }
393
394 if ( empty( $_REQUEST['email'] ) )
395 return false;
396
397 $redirect_fragment = false;
398 if ( isset( $_REQUEST['redirect_fragment'] ) ) {
399 $redirect_fragment = preg_replace( '/[^a-z0-9_-]/i', '', $_REQUEST['redirect_fragment'] );
400 }
401 if ( !$redirect_fragment ) {
402 $redirect_fragment = 'subscribe-blog';
403 }
404
405 $subscribe = Jetpack_Subscriptions::subscribe(
406 $_REQUEST['email'],
407 0,
408 false,
409 array(
410 'source' => 'widget',
411 'widget-in-use' => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
412 'comment_status' => '',
413 'server_data' => $_SERVER,
414 )
415 );
416
417 if ( is_wp_error( $subscribe ) ) {
418 $error = $subscribe->get_error_code();
419 } else {
420 $error = false;
421 foreach ( $subscribe as $response ) {
422 if ( is_wp_error( $response ) ) {
423 $error = $response->get_error_code();
424 break;
425 }
426 }
427 }
428
429 if ( $error ) {
430 switch ( $error ) {
431 case 'invalid_email':
432 $redirect = add_query_arg( 'subscribe', 'invalid_email' );
433 break;
434 case 'active': case 'pending':
435 $redirect = add_query_arg( 'subscribe', 'already' );
436 break;
437 default:
438 $redirect = add_query_arg( 'subscribe', 'error' );
439 break;
440 }
441 } else {
442 $redirect = add_query_arg( 'subscribe', 'success' );
443 }
444
445 wp_safe_redirect( "$redirect#$redirect_fragment" );
446 exit;
447 }
448
449 /**
450 * Jetpack_Subscriptions::comment_subscribe_init()
451 *
452 * Set up and add the comment subscription checkbox to the comment form.
453 */
454 function comment_subscribe_init() {
455 global $post;
456
457 $comments_checked = '';
458 $blog_checked = '';
459
460 // Check for a comment / blog submission and set a cookie to retain the setting and check the boxes.
461 if ( isset( $_COOKIE[ 'jetpack_comments_subscribe_' . self::$hash ] ) && $_COOKIE[ 'jetpack_comments_subscribe_' . self::$hash ] == $post->ID )
462 $comments_checked = ' checked="checked"';
463
464 if ( isset( $_COOKIE[ 'jetpack_blog_subscribe_' . self::$hash ] ) )
465 $blog_checked = ' checked="checked"';
466
467 // Some themes call this function, don't show the checkbox again
468 remove_action( 'comment_form', 'subscription_comment_form' );
469
470 // Check if Mark Jaquith's Subscribe to Comments plugin is active - if so, suppress Jetpack checkbox
471
472 $str = '';
473
474 if ( FALSE === has_filter( 'comment_form', 'show_subscription_checkbox' ) && 1 == get_option( 'stc_enabled', 1 ) && empty( $post->post_password ) ) {
475 // Subscribe to comments checkbox
476 $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 . ' /> ';
477 $comment_sub_text = __( 'Notify me of follow-up comments by email.', 'jetpack' );
478 $str .= '<label class="subscribe-label" id="subscribe-label" for="subscribe_comments">' . esc_html( apply_filters( 'jetpack_subscribe_comment_label', $comment_sub_text ) ) . '</label>';
479 $str .= '</p>';
480 }
481
482 if ( 1 == get_option( 'stb_enabled', 1 ) ) {
483 // Subscribe to blog checkbox
484 $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 . ' /> ';
485 $blog_sub_text = __( 'Notify me of new posts by email.', 'jetpack' );
486 $str .= '<label class="subscribe-label" id="subscribe-blog-label" for="subscribe_blog">' . esc_html( apply_filters( 'jetpack_subscribe_blog_label', $blog_sub_text ) ) . '</label>';
487 $str .= '</p>';
488 }
489
490 echo apply_filters( 'jetpack_comment_subscription_form', $str );
491 }
492
493 /**
494 * Jetpack_Subscriptions::comment_subscribe_init()
495 *
496 * When a user checks the comment subscribe box and submits a comment, subscribe them to the comment thread.
497 */
498 function comment_subscribe_submit( $comment_id, $approved ) {
499 if ( 'spam' === $approved ) {
500 return;
501 }
502
503 // Set cookies for this post/comment
504 $this->set_cookies( isset( $_REQUEST['subscribe_comments'] ), isset( $_REQUEST['subscribe_blog'] ) );
505
506 if ( !isset( $_REQUEST['subscribe_comments'] ) && !isset( $_REQUEST['subscribe_blog'] ) )
507 return;
508
509 $comment = get_comment( $comment_id );
510 $post_ids = array();
511
512 if ( isset( $_REQUEST['subscribe_comments'] ) )
513 $post_ids[] = $comment->comment_post_ID;
514
515 if ( isset( $_REQUEST['subscribe_blog'] ) )
516 $post_ids[] = 0;
517
518 Jetpack_Subscriptions::subscribe(
519 $comment->comment_author_email,
520 $post_ids,
521 true,
522 array(
523 'source' => 'comment-form',
524 'widget-in-use' => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
525 'comment_status' => $approved,
526 'server_data' => $_SERVER,
527 )
528 );
529 }
530
531 /**
532 * Jetpack_Subscriptions::set_cookies()
533 *
534 * Set a cookie to save state on the comment and post subscription checkboxes.
535 */
536 function set_cookies( $comments = true, $posts = true ) {
537 global $post;
538
539 $cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
540 $cookie_path = apply_filters( 'jetpack_comment_cookie_path', COOKIEPATH );
541 $cookie_domain = apply_filters( 'jetpack_comment_cookie_domain', COOKIE_DOMAIN );
542
543 if ( $comments )
544 setcookie( 'jetpack_comments_subscribe_' . self::$hash, $post->ID, time() + $cookie_lifetime, $cookie_path, $cookie_domain );
545 else
546 setcookie( 'jetpack_comments_subscribe_' . self::$hash, '', time() - 3600, $cookie_path, $cookie_domain );
547
548 if ( $posts )
549 setcookie( 'jetpack_blog_subscribe_' . self::$hash, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain );
550 else
551 setcookie( 'jetpack_blog_subscribe_' . self::$hash, '', time() - 3600, $cookie_path, $cookie_domain );
552 }
553 }
554
555 Jetpack_Subscriptions::init();
556
557
558 /***
559 * Blog Subscription Widget
560 */
561
562 class Jetpack_Subscriptions_Widget extends WP_Widget {
563 function __construct() {
564 $widget_ops = array( 'classname' => 'jetpack_subscription_widget', 'description' => __( 'Add an email signup form to allow people to subscribe to your blog.', 'jetpack' ) );
565 $control_ops = array( 'width' => 300 );
566
567 parent::__construct( 'blog_subscription', __( 'Blog Subscriptions (Jetpack)', 'jetpack' ), $widget_ops, $control_ops );
568 }
569
570 function widget( $args, $instance ) {
571 if ( ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM )
572 && false === apply_filters( 'jetpack_auto_fill_logged_in_user', false )
573 ) {
574 $subscribe_email = '';
575 } else {
576 global $current_user;
577 if ( ! empty( $current_user->user_email ) ) {
578 $subscribe_email = esc_attr( $current_user->user_email );
579 } else {
580 $subscribe_email = '';
581 }
582 }
583
584
585
586 $source = 'widget';
587 $instance = wp_parse_args( (array) $instance, $this->defaults() );
588 $subscribe_text = isset( $instance['subscribe_text'] ) ? stripslashes( $instance['subscribe_text'] ) : '';
589 $subscribe_placeholder = isset( $instance['subscribe_placeholder'] ) ? stripslashes( $instance['subscribe_placeholder'] ) : '';
590 $subscribe_button = isset( $instance['subscribe_button'] ) ? stripslashes( $instance['subscribe_button'] ) : '';
591 $success_message = isset( $instance['success_message'] ) ? stripslashes( $instance['success_message'] ) : '';
592 $widget_id = esc_attr( !empty( $args['widget_id'] ) ? esc_attr( $args['widget_id'] ) : mt_rand( 450, 550 ) );
593
594 $show_subscribers_total = (bool) $instance['show_subscribers_total'];
595 $subscribers_total = $this->fetch_subscriber_count(); // Only used for the shortcode [total-subscribers]
596
597 // Give the input element a unique ID
598 $subscribe_field_id = apply_filters( 'subscribe_field_id', 'subscribe-field', $widget_id );
599
600 // Enqueue the form's CSS
601 wp_register_style( 'jetpack-subscriptions', plugins_url( 'subscriptions/subscriptions.css', __FILE__ ) );
602 wp_enqueue_style( 'jetpack-subscriptions' );
603
604 // Display the subscription form
605 echo $args['before_widget'];
606
607 // Only show the title if there actually is a title
608 if( ! empty( $instance['title'] ) ) {
609 echo $args['before_title'] . esc_attr( $instance['title'] ) . $args['after_title'] . "\n";
610 }
611
612 $referer = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
613
614 // Display any errors
615 if ( isset( $_GET['subscribe'] ) ) :
616 switch ( $_GET['subscribe'] ) :
617 case 'invalid_email' : ?>
618 <p class="error"><?php esc_html_e( 'The email you entered was invalid. Please check and try again.', 'jetpack' ); ?></p>
619 <?php break;
620 case 'already' : ?>
621 <p class="error"><?php esc_html_e( 'You have already subscribed to this site. Please check your inbox.', 'jetpack' ); ?></p>
622 <?php break;
623 case 'success' : ?>
624 <div class="success"><?php echo wpautop( str_replace( '[total-subscribers]', number_format_i18n( $subscribers_total['value'] ), $success_message ) ); ?></div>
625 <?php break;
626 default : ?>
627 <p class="error"><?php esc_html_e( 'There was an error when subscribing. Please try again.', 'jetpack' ); ?></p>
628 <?php break;
629 endswitch;
630 endif;
631
632 // Display a subscribe form
633 if ( isset( $_GET['subscribe'] ) && 'success' == $_GET['subscribe'] ) { ?>
634 <?php
635 } else { ?>
636 <form action="#" method="post" accept-charset="utf-8" id="subscribe-blog-<?php echo $widget_id; ?>">
637 <?php
638 if ( ! isset ( $_GET['subscribe'] ) || 'success' != $_GET['subscribe'] ) {
639 ?><div id="subscribe-text"><?php echo wpautop( str_replace( '[total-subscribers]', number_format_i18n( $subscribers_total['value'] ), $subscribe_text ) ); ?></div><?php
640 }
641
642 if ( $show_subscribers_total && 0 < $subscribers_total['value'] ) {
643 echo wpautop( sprintf( _n( 'Join %s other subscriber', 'Join %s other subscribers', $subscribers_total['value'], 'jetpack' ), number_format_i18n( $subscribers_total['value'] ) ) );
644 }
645 if ( ! isset ( $_GET['subscribe'] ) || 'success' != $_GET['subscribe'] ) { ?>
646 <p id="subscribe-email">
647 <label id="jetpack-subscribe-label" for="<?php echo esc_attr( $subscribe_field_id ); ?>">
648 <?php echo !empty( $subscribe_placeholder ) ? esc_html( $subscribe_placeholder ) : esc_html__( 'Email Address:', 'jetpack' ); ?>
649 </label>
650 <input type="email" name="email" required="required" class="required" value="<?php echo esc_attr( $subscribe_email ); ?>" id="<?php echo esc_attr( $subscribe_field_id ) . '-' . esc_attr( $widget_id ); ?>" placeholder="<?php echo esc_attr( $subscribe_placeholder ); ?>" />
651 </p>
652
653 <p id="subscribe-submit">
654 <input type="hidden" name="action" value="subscribe" />
655 <input type="hidden" name="source" value="<?php echo esc_url( $referer ); ?>" />
656 <input type="hidden" name="sub-type" value="<?php echo esc_attr( $source ); ?>" />
657 <input type="hidden" name="redirect_fragment" value="<?php echo $widget_id; ?>" />
658 <?php
659 if ( is_user_logged_in() ) {
660 wp_nonce_field( 'blogsub_subscribe_'. get_current_blog_id(), '_wpnonce', false );
661 }
662 ?>
663 <input type="submit" value="<?php echo esc_attr( $subscribe_button ); ?>" name="jetpack_subscriptions_widget" />
664 </p>
665 <?php }?>
666 </form>
667
668 <script>
669 /*
670 Custom functionality for safari and IE
671 */
672 (function( d ) {
673 // Creates placeholders for IE
674 if ( ( 'placeholder' in d.createElement( 'input' ) ) ) {
675 var label = d.getElementById( 'jetpack-subscribe-label' );
676 label.style.clip = 'rect(1px, 1px, 1px, 1px)';
677 label.style.position = 'absolute';
678 label.style.height = '1px';
679 label.style.width = '1px';
680 label.style.overflow = 'hidden';
681 }
682
683 // Make sure the email value is filled in before allowing submit
684 var form = d.getElementById('subscribe-blog-<?php echo $widget_id; ?>'),
685 input = d.getElementById('<?php echo esc_attr( $subscribe_field_id ) . '-' . esc_attr( $widget_id ); ?>'),
686 handler = function( event ) {
687 if ( '' === input.value ) {
688 input.focus();
689
690 if ( event.preventDefault ){
691 event.preventDefault();
692 }
693
694 return false;
695 }
696 };
697
698 if ( window.addEventListener ) {
699 form.addEventListener( 'submit', handler, false );
700 } else {
701 form.attachEvent( 'onsubmit', handler );
702 }
703 })( document );
704 </script>
705 <?php } ?>
706 <?php
707
708 echo "\n" . $args['after_widget'];
709 }
710
711 function increment_subscriber_count( $current_subs_array = array() ) {
712 $current_subs_array['value']++;
713
714 set_transient( 'wpcom_subscribers_total', $current_subs_array, 3600 ); // try to cache the result for at least 1 hour
715
716 return $current_subs_array;
717 }
718
719 function fetch_subscriber_count() {
720 $subs_count = get_transient( 'wpcom_subscribers_total' );
721
722 if ( FALSE === $subs_count || 'failed' == $subs_count['status'] ) {
723 Jetpack:: load_xml_rpc_client();
724
725 $xml = new Jetpack_IXR_Client( array( 'user_id' => JETPACK_MASTER_USER, ) );
726
727 $xml->query( 'jetpack.fetchSubscriberCount' );
728
729 if ( $xml->isError() ) { // if we get an error from .com, set the status to failed so that we will try again next time the data is requested
730 $subs_count = array(
731 'status' => 'failed',
732 'code' => $xml->getErrorCode(),
733 'message' => $xml->getErrorMessage(),
734 'value' => ( isset( $subs_count['value'] ) ) ? $subs_count['value'] : 0,
735 );
736 } else {
737 $subs_count = array(
738 'status' => 'success',
739 'value' => $xml->getResponse(),
740 );
741 }
742
743 set_transient( 'wpcom_subscribers_total', $subs_count, 3600 ); // try to cache the result for at least 1 hour
744 }
745
746 return $subs_count;
747 }
748
749 function update( $new_instance, $old_instance ) {
750 $instance = $old_instance;
751
752 $instance['title'] = wp_kses( stripslashes( $new_instance['title'] ), array() );
753 $instance['subscribe_text'] = wp_filter_post_kses( stripslashes( $new_instance['subscribe_text'] ) );
754 $instance['subscribe_placeholder'] = wp_kses( stripslashes( $new_instance['subscribe_placeholder'] ), array() );
755 $instance['subscribe_button'] = wp_kses( stripslashes( $new_instance['subscribe_button'] ), array() );
756 $instance['success_message'] = wp_kses( stripslashes( $new_instance['success_message'] ), array() );
757 $instance['show_subscribers_total'] = isset( $new_instance['show_subscribers_total'] ) && $new_instance['show_subscribers_total'];
758
759 return $instance;
760 }
761
762 public static function defaults() {
763 return array(
764 'title' => esc_html__( 'Subscribe to Blog via Email', 'jetpack' ),
765 'subscribe_text' => esc_html__( 'Enter your email address to subscribe to this blog and receive notifications of new posts by email.', 'jetpack' ),
766 'subscribe_placeholder' => esc_html__( 'Email Address', 'jetpack' ),
767 'subscribe_button' => esc_html__( 'Subscribe', 'jetpack' ),
768 'success_message' => esc_html__( 'Success! An email was just sent to confirm your subscription. Please find the email now and click activate to start subscribing', 'jetpack' ),
769 'show_subscribers_total' => true,
770 );
771 }
772
773 function form( $instance ) {
774 $instance = wp_parse_args( (array) $instance, $this->defaults() );
775
776 $title = stripslashes( $instance['title'] );
777 $subscribe_text = stripslashes( $instance['subscribe_text'] );
778 $subscribe_placeholder = stripslashes( $instance['subscribe_placeholder'] );
779 $subscribe_button = stripslashes( $instance['subscribe_button'] );
780 $success_message = stripslashes( $instance['success_message']);
781 $show_subscribers_total = checked( $instance['show_subscribers_total'], true, false );
782
783 $subs_fetch = $this->fetch_subscriber_count();
784
785 if ( 'failed' == $subs_fetch['status'] ) {
786 printf( '<div class="error inline"><p>' . __( '%s: %s', 'jetpack' ) . '</p></div>', esc_html( $subs_fetch['code'] ), esc_html( $subs_fetch['message'] ) );
787 }
788 $subscribers_total = number_format_i18n( $subs_fetch['value'] );
789 ?>
790 <p>
791 <label for="<?php echo $this->get_field_id( 'title' ); ?>">
792 <?php _e( 'Widget title:', 'jetpack' ); ?>
793 <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
794 </label>
795 </p>
796 <p>
797 <label for="<?php echo $this->get_field_id( 'subscribe_text' ); ?>">
798 <?php _e( 'Optional text to display to your readers:', 'jetpack' ); ?>
799 <textarea style="width: 95%" id="<?php echo $this->get_field_id( 'subscribe_text' ); ?>" name="<?php echo $this->get_field_name( 'subscribe_text' ); ?>" type="text"><?php echo esc_html( $subscribe_text ); ?></textarea>
800 </label>
801 </p>
802 <p>
803 <label for="<?php echo $this->get_field_id( 'subscribe_placeholder' ); ?>">
804 <?php esc_html_e( 'Subscribe Placeholder:', 'jetpack' ); ?>
805 <input class="widefat" id="<?php echo $this->get_field_id( 'subscribe_placeholder' ); ?>" name="<?php echo $this->get_field_name( 'subscribe_placeholder' ); ?>" type="text" value="<?php echo esc_attr( $subscribe_placeholder ); ?>" />
806 </label>
807 </p>
808 <p>
809 <label for="<?php echo $this->get_field_id( 'subscribe_button' ); ?>">
810 <?php _e( 'Subscribe Button:', 'jetpack' ); ?>
811 <input class="widefat" id="<?php echo $this->get_field_id( 'subscribe_button' ); ?>" name="<?php echo $this->get_field_name( 'subscribe_button' ); ?>" type="text" value="<?php echo esc_attr( $subscribe_button ); ?>" />
812 </label>
813 </p>
814 <p>
815 <label for="<?php echo $this->get_field_id( 'success_message' ); ?>">
816 <?php _e( 'Success Message Text:', 'jetpack' ); ?>
817 <textarea style="width: 95%" id="<?php echo $this->get_field_id( 'success_message' ); ?>" name="<?php echo $this->get_field_name( 'success_message' ); ?>" type="text"><?php echo esc_html( $success_message ); ?></textarea>
818 </label>
819 </p>
820 <p>
821 <label for="<?php echo $this->get_field_id( 'show_subscribers_total' ); ?>">
822 <input type="checkbox" id="<?php echo $this->get_field_id( 'show_subscribers_total' ); ?>" name="<?php echo $this->get_field_name( 'show_subscribers_total' ); ?>" value="1"<?php echo $show_subscribers_total; ?> />
823 <?php echo esc_html( sprintf( _n( 'Show total number of subscribers? (%s subscriber)', 'Show total number of subscribers? (%s subscribers)', $subscribers_total, 'jetpack' ), $subscribers_total ) ); ?>
824 </label>
825 </p>
826 <?php
827 }
828 }
829
830 add_shortcode( 'jetpack_subscription_form', 'jetpack_do_subscription_form' );
831
832 function jetpack_do_subscription_form( $args ) {
833 $args['show_subscribers_total'] = empty( $args['show_subscribers_total'] ) ? false : true;
834 $args = shortcode_atts( Jetpack_Subscriptions_Widget::defaults(), $args, 'jetpack_subscription_form' );
835 ob_start();
836 the_widget( 'Jetpack_Subscriptions_Widget', $args );
837 $output = ob_get_clean();
838 return $output;
839 }
840