Completed
Push — update/plugins-endpoint-add-tr... ( 2f1fad...d8c85d )
by
unknown
37:39 queued 29:55
created

Jetpack_Subscriptions::get_default_settings()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Module Name: Subscriptions
4
 * Module Description: Notify your readers of new posts and comments by 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: Engagement, Jumpstart
13
 * Additional Search Queries: subscriptions, subscription, email, follow, followers, subscribers, signup
14
 */
15
16
add_action( 'jetpack_modules_loaded', 'jetpack_subscriptions_load' );
17
18
function jetpack_subscriptions_load() {
19
	Jetpack::enable_module_configurable( __FILE__ );
20
	Jetpack::module_configuration_load( __FILE__, 'jetpack_subscriptions_configuration_load' );
21
}
22
23
function jetpack_subscriptions_configuration_load() {
24
	wp_safe_redirect( admin_url( 'options-discussion.php#jetpack-subscriptions-settings' ) );
25
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function jetpack_subscriptions_configuration_load() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
26
}
27
28
class Jetpack_Subscriptions {
29
	public $jetpack = false;
30
31
	public static $hash;
32
33
	/**
34
	 * Singleton
35
	 * @static
36
	 */
37
	static function init() {
38
		static $instance = false;
39
40
		if ( !$instance ) {
41
			$instance = new Jetpack_Subscriptions;
42
		}
43
44
		return $instance;
45
	}
46
47
	function __construct() {
48
		$this->jetpack = Jetpack::init();
0 ignored issues
show
Documentation Bug introduced by
It seems like \Jetpack::init() of type object<Jetpack> is incompatible with the declared type boolean of property $jetpack.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
49
50
		// Don't use COOKIEHASH as it could be shared across installs && is non-unique in multisite.
51
		// @see: https://twitter.com/nacin/status/378246957451333632
52
		self::$hash = md5( get_option( 'siteurl' ) );
53
54
		add_filter( 'jetpack_xmlrpc_methods', array( $this, 'xmlrpc_methods' ) );
55
56
		// @todo remove sync from subscriptions and move elsewhere...
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
57
58
		// Add Configuration Page
59
		add_action( 'admin_init', array( $this, 'configure' ) );
60
61
		// Set up the subscription widget.
62
		add_action( 'widgets_init', array( $this, 'widget_init' ) );
63
64
		// Catch subscription widget submits
65
		if ( isset( $_REQUEST['jetpack_subscriptions_widget'] ) )
66
			add_action( 'template_redirect', array( $this, 'widget_submit' ) );
67
68
		// Set up the comment subscription checkboxes
69
		add_action( 'comment_form', array( $this, 'comment_subscribe_init' ) );
70
71
		// Catch comment posts and check for subscriptions.
72
		add_action( 'comment_post', array( $this, 'comment_subscribe_submit' ), 50, 2 );
73
74
		// Adds post meta checkbox in the post submit metabox
75
		add_action( 'post_submitbox_misc_actions', array( $this, 'subscription_post_page_metabox' ) );
76
77
		add_action( 'transition_post_status', array( $this, 'maybe_send_subscription_email' ), 10, 3 );
78
79
		add_filter( 'jetpack_published_post_flags', array( $this, 'set_post_flags' ), 10, 2 );
80
	}
81
82
	/**
83
	 * Jetpack_Subscriptions::xmlrpc_methods()
84
	 *
85
	 * Register subscriptions methods with the Jetpack XML-RPC server.
86
	 * @param array $methods
87
	 */
88
	function xmlrpc_methods( $methods ) {
89
		return array_merge(
90
			$methods,
91
			array(
92
				'jetpack.subscriptions.subscribe' => array( $this, 'subscribe' ),
93
			)
94
		);
95
	}
96
97
	/*
98
	 * Disable Subscribe on Single Post
99
	 * Register post meta
100
	 */
101
	function subscription_post_page_metabox() {
102
		if (
103
			/**
104
			 * Filter whether or not to show the per-post subscription option.
105
			 *
106
			 * @module subscriptions
107
			 *
108
			 * @since 3.7.0
109
			 *
110
			 * @param bool true = show checkbox option on all new posts | false = hide the option.
111
			 */
112
			 ! apply_filters( 'jetpack_allow_per_post_subscriptions', false ) )
113
		{
114
			return;
115
		}
116
117
		if ( has_filter( 'jetpack_subscriptions_exclude_these_categories' ) || has_filter( 'jetpack_subscriptions_include_only_these_categories' ) ) {
118
			return;
119
		}
120
121
		global $post;
122
		$disable_subscribe_value = get_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', true );
123
		// Nonce it
124
		wp_nonce_field( 'disable_subscribe', 'disable_subscribe_nonce' );
125
		// only show checkbox if post hasn't been published and is a 'post' post type.
126
		if ( get_post_status( $post->ID ) !== 'publish' && get_post_type( $post->ID ) == 'post' ) : ?>
127
			<div class="misc-pub-section">
128
				<label for="_jetpack_dont_email_post_to_subs"><?php _e( 'Jetpack Subscriptions:', 'jetpack' ); ?></label><br>
129
				<input type="checkbox" name="_jetpack_dont_email_post_to_subs" id="jetpack-per-post-subscribe" value="1" <?php checked( $disable_subscribe_value, 1, true ); ?> />
130
				<?php _e( 'Don&#8217;t send this to subscribers', 'jetpack' ); ?>
131
			</div>
132
		<?php endif;
133
	}
134
135
	/**
136
	 * Checks whether or not the post should be emailed to subscribers
137
	 *
138
	 * It checks for the following things in order:
139
	 * - Usage of filter jetpack_subscriptions_exclude_these_categories
140
	 * - Usage of filter jetpack_subscriptions_include_only_these_categories
141
	 * - Existence of the per-post checkbox option
142
	 *
143
	 * Only one of these can be used at any given time.
144
	 *
145
	 * @param $new_status string - the "new" post status of the transition when saved
146
	 * @param $old_status string - the "old" post status of the transition when saved
147
	 * @param $post obj - The post object
148
	 */
149
	function maybe_send_subscription_email( $new_status, $old_status, $post ) {
150
		// Only do things on publish
151
		if ( 'publish' !== $new_status ) {
152
			return;
153
		}
154
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
155
			return;
156
		}
157
158
		/**
159
		 * If we're updating the post, let's make sure the flag to not send to subscribers
160
		 * is set to minimize the chances of sending posts multiple times.
161
		 */
162
		if ( 'publish' == $old_status ) {
163
			update_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', 1 );
164
		}
165
166
		if ( ! $this->should_email_post_to_subscribers( $post ) ) {
167
			update_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', 1 );
168
		}
169
	}
170
171
	public function should_email_post_to_subscribers( $post ) {
172
		$should_email = true;
173
		if ( get_post_meta( $post->ID, '_jetpack_dont_email_post_to_subs', true ) ) {
174
			return false;
175
		}
176
177
		/**
178
		 * Array of categories that will never trigger subscription emails.
179
		 *
180
		 * Will not send subscription emails from any post from within these categories.
181
		 *
182
		 * @module subscriptions
183
		 *
184
		 * @since 3.7.0
185
		 *
186
		 * @param array $args Array of category slugs or ID's.
187
		 */
188
		$excluded_categories = apply_filters( 'jetpack_subscriptions_exclude_these_categories', array() );
189
190
		// Never email posts from these categories
191
		if ( ! empty( $excluded_categories ) && in_category( $excluded_categories, $post->ID ) ) {
192
			$should_email = false;
193
		}
194
195
		/**
196
		 * ONLY send subscription emails for these categories
197
		 *
198
		 * Will ONLY send subscription emails to these categories.
199
		 *
200
		 * @module subscriptions
201
		 *
202
		 * @since 3.7.0
203
		 *
204
		 * @param array $args Array of category slugs or ID's.
205
		 */
206
		$only_these_categories = apply_filters( 'jetpack_subscriptions_exclude_all_categories_except', array() );
207
208
		// Only emails posts from these categories
209
		if ( ! empty( $only_these_categories ) && ! in_category( $only_these_categories, $post->ID ) ) {
210
			$should_email = false;
211
		}
212
213
		// Email the post, depending on the checkbox option
214
		if ( ! empty( $_POST['disable_subscribe_nonce'] ) && wp_verify_nonce( $_POST['disable_subscribe_nonce'], 'disable_subscribe' ) ) {
215
			if ( isset( $_POST['_jetpack_dont_email_post_to_subs'] ) ) {
216
				$should_email = false;
217
			}
218
		}
219
		return $should_email;
220
	}
221
222
	function set_post_flags( $flags, $post ) {
223
		if ( ! $this->should_email_post_to_subscribers( $post ) ) {
224
			$flags['_jetpack_dont_email_post_to_subs'] = true;
225
		}
226
		return $flags;
227
	}
228
229
	/**
230
	 * Jetpack_Subscriptions::configure()
231
	 *
232
	 * Jetpack Subscriptions configuration screen.
233
	 */
234
	function configure() {
235
		// Create the section
236
		add_settings_section(
237
			'jetpack_subscriptions',
238
			__( 'Jetpack Subscriptions Settings', 'jetpack' ),
239
			array( $this, 'subscriptions_settings_section' ),
240
			'discussion'
241
		);
242
243
		/** Subscribe to Posts ***************************************************/
244
245
		add_settings_field(
246
			'jetpack_subscriptions_post_subscribe',
247
			__( 'Follow Blog', 'jetpack' ),
248
			array( $this, 'subscription_post_subscribe_setting' ),
249
			'discussion',
250
			'jetpack_subscriptions'
251
		);
252
253
		register_setting(
254
			'discussion',
255
			'stb_enabled'
256
		);
257
258
		/** Subscribe to Comments ******************************************************/
259
260
		add_settings_field(
261
			'jetpack_subscriptions_comment_subscribe',
262
			__( 'Follow Comments', 'jetpack' ),
263
			array( $this, 'subscription_comment_subscribe_setting' ),
264
			'discussion',
265
			'jetpack_subscriptions'
266
		);
267
268
		register_setting(
269
			'discussion',
270
			'stc_enabled'
271
		);
272
273
		/** Subscription Messaging Options ******************************************************/
274
275
		register_setting(
276
			'reading',
277
			'subscription_options',
278
			array( $this, 'validate_settings' )
279
		);
280
281
		add_settings_section(
282
			'email_settings',
283
			__( 'Follower Settings', 'jetpack' ),
284
			array( $this, 'reading_section' ),
285
			'reading'
286
		);
287
288
		add_settings_field(
289
			'invitation',
290
			__( 'Blog follow email text', 'jetpack' ),
291
			array( $this, 'setting_invitation' ),
292
			'reading',
293
			'email_settings'
294
		);
295
296
		add_settings_field(
297
			'comment-follow',
298
			__( 'Comment follow email text', 'jetpack' ),
299
			array( $this, 'setting_comment_follow' ),
300
			'reading',
301
			'email_settings'
302
		);
303
	}
304
305
	/**
306
	 * Discussions setting section blurb
307
	 *
308
	 */
309
	function subscriptions_settings_section() {
310
	?>
311
312
		<p id="jetpack-subscriptions-settings"><?php _e( 'Change whether your visitors can subscribe to your posts or comments or both.', 'jetpack' ); ?></p>
313
314
	<?php
315
	}
316
317
	/**
318
	 * Post Subscriptions Toggle
319
	 *
320
	 */
321 View Code Duplication
	function subscription_post_subscribe_setting() {
322
323
		$stb_enabled = get_option( 'stb_enabled', 1 ); ?>
324
325
		<p class="description">
326
			<input type="checkbox" name="stb_enabled" id="jetpack-post-subscribe" value="1" <?php checked( $stb_enabled, 1 ); ?> />
327
			<?php _e( "Show a <em>'follow blog'</em> option in the comment form", 'jetpack' ); ?>
328
		</p>
329
	<?php
330
	}
331
332
	/**
333
	 * Comments Subscriptions Toggle
334
	 *
335
	 */
336 View Code Duplication
	function subscription_comment_subscribe_setting() {
337
338
		$stc_enabled = get_option( 'stc_enabled', 1 ); ?>
339
340
		<p class="description">
341
			<input type="checkbox" name="stc_enabled" id="jetpack-comment-subscribe" value="1" <?php checked( $stc_enabled, 1 ); ?> />
342
			<?php _e( "Show a <em>'follow comments'</em> option in the comment form", 'jetpack' ); ?>
343
		</p>
344
345
	<?php
346
	}
347
348
	function validate_settings( $settings ) {
349
		global $allowedposttags;
350
351
		$default = $this->get_default_settings();
352
353
		// Blog Follow
354
		$settings['invitation'] = trim( wp_kses( $settings['invitation'], $allowedposttags ) );
355
		if ( empty( $settings['invitation'] ) )
356
			$settings['invitation'] = $default['invitation'];
357
358
		// Comments Follow (single post)
359
		$settings['comment_follow'] = trim( wp_kses( $settings['comment_follow'], $allowedposttags ) );
360
		if ( empty( $settings['comment_follow'] ) )
361
			$settings['comment_follow'] = $default['comment_follow'];
362
363
		return $settings;
364
	}
365
366
	public function reading_section() {
367
		echo '<p id="follower-settings">';
368
		_e( 'These settings change emails sent from your blog to followers.', 'jetpack' );
369
		echo '</p>';
370
	}
371
372
	public function setting_invitation() {
373
		$settings = $this->get_settings();
374
		echo '<textarea name="subscription_options[invitation]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['invitation'] ) . '</textarea>';
375
		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>';
376
	}
377
378
	public function setting_comment_follow() {
379
		$settings = $this->get_settings();
380
		echo '<textarea name="subscription_options[comment_follow]" class="large-text" cols="50" rows="5">' . esc_textarea( $settings['comment_follow'] ) . '</textarea>';
381
		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>';
382
	}
383
384
	function get_default_settings() {
385
		return array(
386
			'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' ),
387
			'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' )
388
		);
389
	}
390
391
	function get_settings() {
392
		return wp_parse_args( (array) get_option( 'subscription_options', array() ), $this->get_default_settings() );
393
	}
394
395
	/**
396
	 * Jetpack_Subscriptions::subscribe()
397
	 *
398
	 * Send a synchronous XML-RPC subscribe to blog posts or subscribe to post comments request.
399
	 *
400
	 * @param string $email
401
	 * @param array  $post_ids (optional) defaults to 0 for blog posts only: array of post IDs to subscribe to blog's posts
0 ignored issues
show
Documentation introduced by
Should the type for parameter $post_ids not be integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
402
	 * @param bool   $async    (optional) Should the subscription be performed asynchronously?  Defaults to true.
403
	 *
404
	 * @return true|Jetpack_Error true on success
405
	 *	invalid_email   : not a valid email address
406
	 *	invalid_post_id : not a valid post ID
407
	 *	unknown_post_id : unknown post
408
	 *	not_subscribed  : strange error.  Jetpack servers at WordPress.com could subscribe the email.
409
	 *	disabled        : Site owner has disabled subscriptions.
410
	 *	active          : Already subscribed.
411
	 *	unknown         : strange error.  Jetpack servers at WordPress.com returned something malformed.
412
	 *	unknown_status  : strange error.  Jetpack servers at WordPress.com returned something I didn't understand.
413
	 */
414
	function subscribe( $email, $post_ids = 0, $async = true, $extra_data = array() ) {
415
		if ( !is_email( $email ) ) {
416
			return new Jetpack_Error( 'invalid_email' );
417
		}
418
419
		if ( !$async ) {
420
			Jetpack::load_xml_rpc_client();
421
			$xml = new Jetpack_IXR_ClientMulticall();
422
		}
423
424
		foreach ( (array) $post_ids as $post_id ) {
425
			$post_id = (int) $post_id;
426
			if ( $post_id < 0 ) {
427
				return new Jetpack_Error( 'invalid_post_id' );
428
			} else if ( $post_id && !$post = get_post( $post_id ) ) {
429
				return new Jetpack_Error( 'unknown_post_id' );
430
			}
431
432
			if ( $async ) {
433
				Jetpack::xmlrpc_async_call( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) );
434
			} else {
435
				$xml->addCall( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) );
0 ignored issues
show
Bug introduced by
The variable $xml does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
436
			}
437
		}
438
439
		if ( $async ) {
440
			return;
441
		}
442
443
		// Call
444
		$xml->query();
445
446
		if ( $xml->isError() ) {
447
			return $xml->get_jetpack_error();
448
		}
449
450
		$responses = $xml->getResponse();
451
452
		$r = array();
453
		foreach ( (array) $responses as $response ) {
454
			if ( isset( $response['faultCode'] ) || isset( $response['faultString'] ) ) {
455
				$r[] = $xml->get_jetpack_error( $response['faultCode'], $response['faultString'] );
456
				continue;
457
			}
458
459
			if ( !is_array( $response[0] ) || empty( $response[0]['status'] ) ) {
460
				$r[] = new Jetpack_Error( 'unknown' );
461
				continue;
462
			}
463
464
			switch ( $response[0]['status'] ) {
465
			case 'error' :
466
				$r[] = new Jetpack_Error( 'not_subscribed' );
467
				continue 2;
468
			case 'disabled' :
469
				$r[] = new Jetpack_Error( 'disabled' );
470
				continue 2;
471
			case 'active' :
472
				$r[] = new Jetpack_Error( 'active' );
473
				continue 2;
474
			case 'pending' :
475
				$r[] = true;
476
				continue 2;
477
			default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
478
				$r[] = new Jetpack_Error( 'unknown_status', (string) $response[0]['status'] );
479
				continue 2;
480
			}
481
		}
482
483
		return $r;
484
	}
485
486
	/**
487
	 * Jetpack_Subscriptions::widget_init()
488
	 *
489
	 * Initialize and register the Jetpack Subscriptions widget.
490
	 */
491
	function widget_init() {
492
		register_widget( 'Jetpack_Subscriptions_Widget' );
493
	}
494
495
	/**
496
	 * Jetpack_Subscriptions::widget_submit()
497
	 *
498
	 * When a user submits their email via the blog subscription widget, check the details and call the subsribe() method.
499
	 */
500
	function widget_submit() {
501
		// Check the nonce.
502
		if ( is_user_logged_in() ) {
503
			check_admin_referer( 'blogsub_subscribe_' . get_current_blog_id() );
504
		}
505
506
		if ( empty( $_REQUEST['email'] ) )
507
			return false;
508
509
		$redirect_fragment = false;
510
		if ( isset( $_REQUEST['redirect_fragment'] ) ) {
511
			$redirect_fragment = preg_replace( '/[^a-z0-9_-]/i', '', $_REQUEST['redirect_fragment'] );
512
		}
513
		if ( !$redirect_fragment ) {
514
			$redirect_fragment = 'subscribe-blog';
515
		}
516
517
		$subscribe = Jetpack_Subscriptions::subscribe(
518
												$_REQUEST['email'],
519
												0,
520
												false,
521
												array(
522
													'source'         => 'widget',
523
													'widget-in-use'  => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
524
													'comment_status' => '',
525
													'server_data'    => $_SERVER,
526
												)
527
		);
528
529
		if ( is_wp_error( $subscribe ) ) {
530
			$error = $subscribe->get_error_code();
531
		} else {
532
			$error = false;
533
			foreach ( $subscribe as $response ) {
0 ignored issues
show
Bug introduced by
The expression $subscribe of type object<Jetpack_Error>|null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
534
				if ( is_wp_error( $response ) ) {
535
					$error = $response->get_error_code();
536
					break;
537
				}
538
			}
539
		}
540
541
		switch ( $error ) {
542
			case false:
543
				$result = 'success';
544
				break;
545
			case 'invalid_email':
546
				$result = $error;
547
				break;
548
			case 'active':
549
			case 'blocked_email':
550
				$result = 'opted_out';
551
				break;
552
			case 'pending':
553
				$result = 'already';
554
				break;
555
			default:
556
				$result = 'error';
557
				break;
558
		}
559
560
		$redirect = add_query_arg( 'subscribe', $result );
561
562
		/**
563
		 * Fires on each subscription form submission.
564
		 *
565
		 * @module subscriptions
566
		 *
567
		 * @since 3.7.0
568
		 *
569
		 * @param string $result Result of form submission: success, invalid_email, already, error.
570
		 */
571
		do_action( 'jetpack_subscriptions_form_submission', $result );
572
573
		wp_safe_redirect( "$redirect#$redirect_fragment" );
574
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method widget_submit() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
575
	}
576
577
	/**
578
	 * Jetpack_Subscriptions::comment_subscribe_init()
579
	 *
580
	 * Set up and add the comment subscription checkbox to the comment form.
581
	 */
582
	function comment_subscribe_init() {
583
		global $post;
584
585
		$comments_checked = '';
586
		$blog_checked     = '';
587
588
		// Check for a comment / blog submission and set a cookie to retain the setting and check the boxes.
589
		if ( isset( $_COOKIE[ 'jetpack_comments_subscribe_' . self::$hash . '_' . $post->ID ] ) ) {
590
			$comments_checked = ' checked="checked"';
591
		}
592
593
		if ( isset( $_COOKIE[ 'jetpack_blog_subscribe_' . self::$hash ] ) ) {
594
			$blog_checked = ' checked="checked"';
595
		}
596
597
		// Some themes call this function, don't show the checkbox again
598
		remove_action( 'comment_form', 'subscription_comment_form' );
599
600
		// Check if Mark Jaquith's Subscribe to Comments plugin is active - if so, suppress Jetpack checkbox
601
602
		$str = '';
603
604
		if ( FALSE === has_filter( 'comment_form', 'show_subscription_checkbox' ) && 1 == get_option( 'stc_enabled', 1 ) && empty( $post->post_password ) && 'post' == get_post_type() ) {
605
			// Subscribe to comments checkbox
606
			$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 . ' /> ';
607
			$comment_sub_text = __( 'Notify me of follow-up comments by email.', 'jetpack' );
608
			$str .=	'<label class="subscribe-label" id="subscribe-label" for="subscribe_comments">' . esc_html(
609
				/**
610
				 * Filter the Subscribe to comments text appearing below the comment form.
611
				 *
612
				 * @module subscriptions
613
				 *
614
				 * @since 3.4.0
615
				 *
616
				 * @param string $comment_sub_text Subscribe to comments text.
617
				 */
618
				apply_filters( 'jetpack_subscribe_comment_label', $comment_sub_text )
619
			) . '</label>';
620
			$str .= '</p>';
621
		}
622
623
		if ( 1 == get_option( 'stb_enabled', 1 ) ) {
624
			// Subscribe to blog checkbox
625
			$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 . ' /> ';
626
			$blog_sub_text = __( 'Notify me of new posts by email.', 'jetpack' );
627
			$str .=	'<label class="subscribe-label" id="subscribe-blog-label" for="subscribe_blog">' . esc_html(
628
				/**
629
				 * Filter the Subscribe to blog text appearing below the comment form.
630
				 *
631
				 * @module subscriptions
632
				 *
633
				 * @since 3.4.0
634
				 *
635
				 * @param string $comment_sub_text Subscribe to blog text.
636
				 */
637
				apply_filters( 'jetpack_subscribe_blog_label', $blog_sub_text )
638
			) . '</label>';
639
			$str .= '</p>';
640
		}
641
642
		/**
643
		 * Filter the output of the subscription options appearing below the comment form.
644
		 *
645
		 * @module subscriptions
646
		 *
647
		 * @since 1.2.0
648
		 *
649
		 * @param string $str Comment Subscription form HTML output.
650
		 */
651
		echo apply_filters( 'jetpack_comment_subscription_form', $str );
652
	}
653
654
	/**
655
	 * Jetpack_Subscriptions::comment_subscribe_init()
656
	 *
657
	 * When a user checks the comment subscribe box and submits a comment, subscribe them to the comment thread.
658
	 */
659
	function comment_subscribe_submit( $comment_id, $approved ) {
660
		if ( 'spam' === $approved ) {
661
			return;
662
		}
663
664
		$comment = get_comment( $comment_id );
665
666
		// Set cookies for this post/comment
667
		$this->set_cookies( isset( $_REQUEST['subscribe_comments'] ), $comment->comment_post_ID, isset( $_REQUEST['subscribe_blog'] ) );
668
669
		if ( !isset( $_REQUEST['subscribe_comments'] ) && !isset( $_REQUEST['subscribe_blog'] ) )
670
			return;
671
672
		$post_ids = array();
673
674
		if ( isset( $_REQUEST['subscribe_comments'] ) )
675
			$post_ids[] = $comment->comment_post_ID;
676
677
		if ( isset( $_REQUEST['subscribe_blog'] ) )
678
			$post_ids[] = 0;
679
680
		Jetpack_Subscriptions::subscribe(
681
									$comment->comment_author_email,
682
									$post_ids,
0 ignored issues
show
Documentation introduced by
$post_ids is of type array, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
683
									true,
684
									array(
685
										'source'         => 'comment-form',
686
										'widget-in-use'  => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
687
										'comment_status' => $approved,
688
										'server_data'    => $_SERVER,
689
									)
690
		);
691
	}
692
693
	/**
694
	 * Jetpack_Subscriptions::set_cookies()
695
	 *
696
	 * Set a cookie to save state on the comment and post subscription checkboxes.
697
	 *
698
	 * @param bool $subscribe_to_post Whether the user chose to subscribe to subsequent comments on this post.
699
	 * @param int $post_id If $subscribe_to_post is true, the post ID they've subscribed to.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $post_id not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
700
	 * @param bool $subscribe_to_blog Whether the user chose to subscribe to all new posts on the blog.
701
	 */
702
	function set_cookies( $subscribe_to_post = false, $post_id = null, $subscribe_to_blog = false ) {
703
		$post_id = intval( $post_id );
704
705
		/** This filter is already documented in core/wp-includes/comment-functions.php */
706
		$cookie_lifetime = apply_filters( 'comment_cookie_lifetime',       30000000 );
707
708
		/**
709
		 * Filter the Jetpack Comment cookie path.
710
		 *
711
		 * @module subscriptions
712
		 *
713
		 * @since 2.5.0
714
		 *
715
		 * @param string COOKIEPATH Cookie path.
716
		 */
717
		$cookie_path     = apply_filters( 'jetpack_comment_cookie_path',   COOKIEPATH );
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 5 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
718
719
		/**
720
		 * Filter the Jetpack Comment cookie domain.
721
		 *
722
		 * @module subscriptions
723
		 *
724
		 * @since 2.5.0
725
		 *
726
		 * @param string COOKIE_DOMAIN Cookie domain.
727
		 */
728
		$cookie_domain   = apply_filters( 'jetpack_comment_cookie_domain', COOKIE_DOMAIN );
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 3 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
729
730
		if ( $subscribe_to_post && $post_id >= 0 ) {
731
			setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain );
732
		} else {
733
			setcookie( 'jetpack_comments_subscribe_' . self::$hash . '_' . $post_id, '', time() - 3600, $cookie_path, $cookie_domain );
734
		}
735
736
		if ( $subscribe_to_blog ) {
737
			setcookie( 'jetpack_blog_subscribe_' . self::$hash, 1, time() + $cookie_lifetime, $cookie_path, $cookie_domain );
738
		} else {
739
			setcookie( 'jetpack_blog_subscribe_' . self::$hash, '', time() - 3600, $cookie_path, $cookie_domain );
740
		}
741
	}
742
743
}
744
745
Jetpack_Subscriptions::init();
746
747
748
/***
749
 * Blog Subscription Widget
750
 */
751
752
class Jetpack_Subscriptions_Widget extends WP_Widget {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
753 View Code Duplication
	function __construct() {
754
		$widget_ops  = array( 'classname' => 'jetpack_subscription_widget', 'description' => __( 'Add an email signup form to allow people to subscribe to your blog.', 'jetpack' ) );
755
		$control_ops = array( 'width' => 300 );
756
757
		parent::__construct(
758
			'blog_subscription',
759
			/** This filter is documented in modules/widgets/facebook-likebox.php */
760
			apply_filters( 'jetpack_widget_name', __( 'Blog Subscriptions', 'jetpack' ) ),
761
			$widget_ops,
762
			$control_ops
763
		);
764
	}
765
766
	function widget( $args, $instance ) {
767
		if (
768
			( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) &&
769
			/** This filter is already documented in modules/contact-form/grunion-contact-form.php */
770
			false === apply_filters( 'jetpack_auto_fill_logged_in_user', false )
771
		) {
772
			$subscribe_email = '';
773
		} else {
774
			global $current_user;
775
			if ( ! empty( $current_user->user_email ) ) {
776
				$subscribe_email = esc_attr( $current_user->user_email );
777
			} else {
778
				$subscribe_email = '';
779
			}
780
		}
781
782
		/** This action is already documented in modules/widgets/gravatar-profile.php */
783
		do_action( 'jetpack_stats_extra', 'widget_view', 'jetpack_subscriptions' );
784
785
		$source                 = 'widget';
786
		$instance            	= wp_parse_args( (array) $instance, $this->defaults() );
787
		$subscribe_text      	= isset( $instance['subscribe_text'] )        ? stripslashes( $instance['subscribe_text'] )        : '';
788
		$subscribe_placeholder 	= isset( $instance['subscribe_placeholder'] ) ? stripslashes( $instance['subscribe_placeholder'] ) : '';
789
		$subscribe_button    	= isset( $instance['subscribe_button'] )      ? stripslashes( $instance['subscribe_button'] )      : '';
790
		$success_message    	= isset( $instance['success_message'] )       ? stripslashes( $instance['success_message'] )      : '';
791
		$widget_id              = esc_attr( !empty( $args['widget_id'] )      ? esc_attr( $args['widget_id'] ) : mt_rand( 450, 550 ) );
792
793
		$show_subscribers_total = (bool) $instance['show_subscribers_total'];
794
		$subscribers_total      = $this->fetch_subscriber_count(); // Only used for the shortcode [total-subscribers]
795
796
		// Give the input element a unique ID
797
		/**
798
		 * Filter the subscription form's ID prefix.
799
		 *
800
		 * @module subscriptions
801
		 *
802
		 * @since 2.7.0
803
		 *
804
		 * @param string subscribe-field Subscription form field prefix.
805
		 * @param int $widget_id Widget ID.
806
		 */
807
		$subscribe_field_id = apply_filters( 'subscribe_field_id', 'subscribe-field', $widget_id );
808
809
		// Enqueue the form's CSS
810
		wp_register_style( 'jetpack-subscriptions', plugins_url( 'subscriptions/subscriptions.css', __FILE__ ) );
811
		wp_enqueue_style( 'jetpack-subscriptions' );
812
813
		// Display the subscription form
814
		echo $args['before_widget'];
815
816
		// Only show the title if there actually is a title
817 View Code Duplication
		if( ! empty( $instance['title'] ) ) {
818
			echo $args['before_title'] . esc_attr( $instance['title'] ) . $args['after_title'] . "\n";
819
		}
820
821
		$referer = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
822
823
		// Display any errors
824
		if ( isset( $_GET['subscribe'] ) ) :
825
			switch ( $_GET['subscribe'] ) :
826
				case 'invalid_email' : ?>
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
827
					<p class="error"><?php esc_html_e( 'The email you entered was invalid. Please check and try again.', 'jetpack' ); ?></p>
828
				<?php break;
0 ignored issues
show
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
829
				case 'opted_out' : ?>
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
830
					<p class="error"><?php printf( __( 'The email address has opted out of subscription emails. <br /> You can manage your preferences at <a href="%1$s" title="%2$s" target="_blank">subscribe.wordpress.com</a>', 'jetpack' ),
831
							'https://subscribe.wordpress.com/',
832
							__( 'Manage your email preferences.', 'jetpack' )
833
						); ?>
834
				<?php break;
0 ignored issues
show
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
835
				case 'already' : ?>
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
836
					<p class="error"><?php esc_html_e( 'You have already subscribed to this site. Please check your inbox.', 'jetpack' ); ?></p>
837
				<?php break;
0 ignored issues
show
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
838
				case 'success' : ?>
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
839
					<div class="success"><?php echo wpautop( str_replace( '[total-subscribers]', number_format_i18n( $subscribers_total['value'] ), $success_message ) ); ?></div>
840
					<?php break;
0 ignored issues
show
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
841
				default : ?>
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
842
					<p class="error"><?php esc_html_e( 'There was an error when subscribing. Please try again.', 'jetpack' ); ?></p>
843
				<?php break;
0 ignored issues
show
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
844
			endswitch;
845
		endif;
846
847
		// Display a subscribe form
848
		if ( isset( $_GET['subscribe'] ) && 'success' == $_GET['subscribe'] ) { ?>
849
			<?php
850
		} else { ?>
851
			<form action="#" method="post" accept-charset="utf-8" id="subscribe-blog-<?php echo $widget_id; ?>">
852
				<?php
853
				if ( ! isset ( $_GET['subscribe'] ) || 'success' != $_GET['subscribe'] ) {
854
					?><div id="subscribe-text"><?php echo wpautop( str_replace( '[total-subscribers]', number_format_i18n( $subscribers_total['value'] ), $subscribe_text ) ); ?></div><?php
855
				}
856
857
				if ( $show_subscribers_total && 0 < $subscribers_total['value'] ) {
858
					echo wpautop( sprintf( _n( 'Join %s other subscriber', 'Join %s other subscribers', $subscribers_total['value'], 'jetpack' ), number_format_i18n( $subscribers_total['value'] ) ) );
859
				}
860
				if ( ! isset ( $_GET['subscribe'] ) || 'success' != $_GET['subscribe'] ) { ?>
861
					<p id="subscribe-email">
862
						<label id="jetpack-subscribe-label" for="<?php echo esc_attr( $subscribe_field_id ) . '-' . esc_attr( $widget_id ); ?>">
863
							<?php echo !empty( $subscribe_placeholder ) ? esc_html( $subscribe_placeholder ) : esc_html__( 'Email Address:', 'jetpack' ); ?>
864
						</label>
865
						<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 ); ?>" />
866
					</p>
867
868
					<p id="subscribe-submit">
869
						<input type="hidden" name="action" value="subscribe" />
870
						<input type="hidden" name="source" value="<?php echo esc_url( $referer ); ?>" />
871
						<input type="hidden" name="sub-type" value="<?php echo esc_attr( $source ); ?>" />
872
						<input type="hidden" name="redirect_fragment" value="<?php echo $widget_id; ?>" />
873
						<?php
874
							if ( is_user_logged_in() ) {
875
								wp_nonce_field( 'blogsub_subscribe_'. get_current_blog_id(), '_wpnonce', false );
876
							}
877
						?>
878
						<input type="submit" value="<?php echo esc_attr( $subscribe_button ); ?>" name="jetpack_subscriptions_widget" />
879
					</p>
880
				<?php }?>
881
			</form>
882
883
			<script>
884
			/*
885
			Custom functionality for safari and IE
886
			 */
887
			(function( d ) {
888
				// In case the placeholder functionality is available we remove labels
889
				if ( ( 'placeholder' in d.createElement( 'input' ) ) ) {
890
					var label = d.querySelector( 'label[for=subscribe-field-<?php echo $widget_id; ?>]' );
891
						label.style.clip 	 = 'rect(1px, 1px, 1px, 1px)';
892
						label.style.position = 'absolute';
893
						label.style.height   = '1px';
894
						label.style.width    = '1px';
895
						label.style.overflow = 'hidden';
896
				}
897
898
				// Make sure the email value is filled in before allowing submit
899
				var form = d.getElementById('subscribe-blog-<?php echo $widget_id; ?>'),
900
					input = d.getElementById('<?php echo esc_attr( $subscribe_field_id ) . '-' . esc_attr( $widget_id ); ?>'),
901
					handler = function( event ) {
902
						if ( '' === input.value ) {
903
							input.focus();
904
905
							if ( event.preventDefault ){
906
								event.preventDefault();
907
							}
908
909
							return false;
910
						}
911
					};
912
913
				if ( window.addEventListener ) {
914
					form.addEventListener( 'submit', handler, false );
915
				} else {
916
					form.attachEvent( 'onsubmit', handler );
917
				}
918
			})( document );
919
			</script>
920
		<?php } ?>
921
		<?php
922
923
		echo "\n" . $args['after_widget'];
924
	}
925
926
	function increment_subscriber_count( $current_subs_array = array() ) {
927
		$current_subs_array['value']++;
928
929
		set_transient( 'wpcom_subscribers_total', $current_subs_array, 3600 ); // try to cache the result for at least 1 hour
930
931
		return $current_subs_array;
932
	}
933
934
	function fetch_subscriber_count() {
935
		$subs_count = get_transient( 'wpcom_subscribers_total' );
936
937
		if ( FALSE === $subs_count || 'failed' == $subs_count['status'] ) {
938
			Jetpack:: load_xml_rpc_client();
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces after double colon; 1 found

This check looks for references to static members where there are spaces between the name of the type and the actual member.

An example:

Certificate:: TRIPLEDES_CBC

will actually work, but is not very readable.

Loading history...
939
940
			$xml = new Jetpack_IXR_Client( array( 'user_id' => JETPACK_MASTER_USER, ) );
941
942
			$xml->query( 'jetpack.fetchSubscriberCount' );
943
944
			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
945
				$subs_count = array(
946
					'status'  => 'failed',
947
					'code'    => $xml->getErrorCode(),
948
					'message' => $xml->getErrorMessage(),
949
					'value'	  => ( isset( $subs_count['value'] ) ) ? $subs_count['value'] : 0,
950
				);
951
			} else {
952
				$subs_count = array(
953
					'status' => 'success',
954
					'value'  => $xml->getResponse(),
955
				);
956
			}
957
958
			set_transient( 'wpcom_subscribers_total', $subs_count, 3600 ); // try to cache the result for at least 1 hour
959
		}
960
961
		return $subs_count;
962
	}
963
964
	function update( $new_instance, $old_instance ) {
965
		$instance = $old_instance;
966
967
		$instance['title']					= wp_kses( stripslashes( $new_instance['title'] ), array() );
968
		$instance['subscribe_text']			= wp_filter_post_kses( stripslashes( $new_instance['subscribe_text'] ) );
969
		$instance['subscribe_placeholder']	= wp_kses( stripslashes( $new_instance['subscribe_placeholder'] ), array() );
970
		$instance['subscribe_button']		= wp_kses( stripslashes( $new_instance['subscribe_button'] ), array() );
971
		$instance['success_message']		= wp_kses( stripslashes( $new_instance['success_message'] ), array() );
972
		$instance['show_subscribers_total']	= isset( $new_instance['show_subscribers_total'] ) && $new_instance['show_subscribers_total'];
973
974
		return $instance;
975
	}
976
977
	public static function defaults() {
978
		return array(
979
			'title'               	 => esc_html__( 'Subscribe to Blog via Email', 'jetpack' ),
980
			'subscribe_text'      	 => esc_html__( 'Enter your email address to subscribe to this blog and receive notifications of new posts by email.', 'jetpack' ),
981
			'subscribe_placeholder'	 => esc_html__( 'Email Address', 'jetpack' ),
982
			'subscribe_button'    	 => esc_html__( 'Subscribe', 'jetpack' ),
983
			'success_message'    	 => esc_html__( "Success! An email was just sent to confirm your subscription. Please find the email now and click 'Confirm Follow' to start subscribing.", 'jetpack' ),
984
			'show_subscribers_total' => true,
985
		);
986
	}
987
988
	function form( $instance ) {
989
		$instance = wp_parse_args( (array) $instance, $this->defaults() );
990
991
		$title               	= stripslashes( $instance['title'] );
992
		$subscribe_text      	= stripslashes( $instance['subscribe_text'] );
993
		$subscribe_placeholder 	= stripslashes( $instance['subscribe_placeholder'] );
994
		$subscribe_button    	= stripslashes( $instance['subscribe_button'] );
995
		$success_message		= stripslashes( $instance['success_message']);
996
		$show_subscribers_total = checked( $instance['show_subscribers_total'], true, false );
997
998
		$subs_fetch = $this->fetch_subscriber_count();
999
1000
		if ( 'failed' == $subs_fetch['status'] ) {
1001
			printf( '<div class="error inline"><p>' . __( '%s: %s', 'jetpack' ) . '</p></div>', esc_html( $subs_fetch['code'] ), esc_html( $subs_fetch['message'] ) );
1002
		}
1003
		$subscribers_total = number_format_i18n( $subs_fetch['value'] );
1004
?>
1005
<p>
1006
	<label for="<?php echo $this->get_field_id( 'title' ); ?>">
1007
		<?php _e( 'Widget title:', 'jetpack' ); ?>
1008
		<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 ); ?>" />
1009
	</label>
1010
</p>
1011
<p>
1012
	<label for="<?php echo $this->get_field_id( 'subscribe_text' ); ?>">
1013
		<?php _e( 'Optional text to display to your readers:', 'jetpack' ); ?>
1014
		<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>
1015
	</label>
1016
</p>
1017
<p>
1018
	<label for="<?php echo $this->get_field_id( 'subscribe_placeholder' ); ?>">
1019
		<?php esc_html_e( 'Subscribe Placeholder:', 'jetpack' ); ?>
1020
		<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 ); ?>" />
1021
	</label>
1022
</p>
1023
<p>
1024
	<label for="<?php echo $this->get_field_id( 'subscribe_button' ); ?>">
1025
		<?php _e( 'Subscribe Button:', 'jetpack' ); ?>
1026
		<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 ); ?>" />
1027
	</label>
1028
</p>
1029
<p>
1030
	<label for="<?php echo $this->get_field_id( 'success_message' ); ?>">
1031
		<?php _e( 'Success Message Text:', 'jetpack' ); ?>
1032
		<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>
1033
	</label>
1034
</p>
1035
<p>
1036
	<label for="<?php echo $this->get_field_id( 'show_subscribers_total' ); ?>">
1037
		<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; ?> />
1038
		<?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 ) ); ?>
1039
	</label>
1040
</p>
1041
<?php
1042
	}
1043
}
1044
1045
add_shortcode( 'jetpack_subscription_form', 'jetpack_do_subscription_form' );
1046
1047
function jetpack_do_subscription_form( $instance ) {
1048
	$instance['show_subscribers_total'] = empty( $instance['show_subscribers_total'] ) ? false : true;
1049
	$instance = shortcode_atts( Jetpack_Subscriptions_Widget::defaults(), $instance, 'jetpack_subscription_form' );
1050
	$args = array(
1051
		'before_widget' => sprintf( '<div class="%s">', 'jetpack_subscription_widget' ),
1052
	);
1053
	ob_start();
1054
	the_widget( 'Jetpack_Subscriptions_Widget', $instance, $args );
1055
	$output = ob_get_clean();
1056
	return $output;
1057
}
1058