Completed
Push — fix/issue-5159 ( e5f9c0...935047 )
by
unknown
55:37 queued 42:38
created

Sharing_Source::get_share_title()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
abstract class Sharing_Source {
4
	public    $button_style;
5
	public    $smart;
6
	protected $open_link_in_new;
7
	protected $id;
8
9
	public function __construct( $id, array $settings ) {
10
		$this->id = $id;
11
		/**
12
		 * Filter the way sharing links open.
13
		 *
14
		 * By default, sharing links open in a new window.
15
		 *
16
		 * @module sharedaddy
17
		 *
18
		 * @since 3.4.0
19
		 *
20
		 * @param bool true Should Sharing links open in a new window. Default to true.
21
		 */
22
		$this->open_link_in_new = apply_filters( 'jetpack_open_sharing_in_new_window', true );
23
24
		if ( isset( $settings['button_style'] ) )
25
			$this->button_style = $settings['button_style'];
26
27
		if ( isset( $settings['smart'] ) )
28
			$this->smart = $settings['smart'];
29
	}
30
31
	public function http() {
32
		return is_ssl() ? 'https' : 'http';
33
	}
34
35
	public function get_id() {
36
		return $this->id;
37
	}
38
39
	public function get_class() {
40
		return $this->id;
41
	}
42
43
	public function get_share_url( $post_id ) {
44
		/**
45
		 * Filter the sharing permalink.
46
		 *
47
		 * @module sharedaddy
48
		 *
49
		 * @since 1.2.0
50
		 *
51
		 * @param string get_permalink( $post_id ) Post Permalink.
52
		 * @param int $post_id Post ID.
53
		 * @param int $this->id Sharing ID.
54
		 */
55
		return apply_filters( 'sharing_permalink', get_permalink( $post_id ), $post_id, $this->id );
56
	}
57
58
	public function get_share_title( $post_id ) {
59
		$post = get_post( $post_id );
60
		/**
61
		 * Filter the sharing title.
62
		 *
63
		 * @module sharedaddy
64
		 *
65
		 * @since 2.8.0
66
		 *
67
		 * @param string $post->post_title Post Title.
68
		 * @param int $post_id Post ID.
69
		 * @param int $this->id Sharing ID.
70
		 */
71
		$title = apply_filters( 'sharing_title', $post->post_title, $post_id, $this->id );
72
73
		return html_entity_decode( wp_kses( $title, null ) );
74
	}
75
76
	public function has_custom_button_style() {
77
		return false;
78
	}
79
80
	public function get_link( $url, $text, $title, $query = '', $id = false ) {
81
		$args = func_get_args();
82
		$klasses = array( 'share-'.$this->get_class(), 'sd-button' );
83
84
		if ( 'icon' == $this->button_style || 'icon-text' == $this->button_style )
85
			$klasses[] = 'share-icon';
86
87
		if ( 'icon' == $this->button_style ) {
88
			$text = $title;
89
			$klasses[] = 'no-text';
90
91
			if ( true == $this->open_link_in_new )
92
				$text .= __( ' (Opens in new window)', 'jetpack' );
93
		}
94
95
		/**
96
		 * Filter the sharing display ID.
97
		 *
98
		 * @module sharedaddy
99
		 *
100
		 * @since 3.4.0
101
		 *
102
		 * @param int|false $id Sharing ID.
103
		 * @param object $this Sharing service properties.
104
		 * @param array $args Array of sharing service options.
105
		 */
106
		$id = apply_filters( 'jetpack_sharing_display_id', $id, $this, $args );
107
		/**
108
		 * Filter the sharing display link.
109
		 *
110
		 * @module sharedaddy
111
		 *
112
		 * @since 2.8.0
113
		 *
114
		 * @param string $url Post URL.
115
		 * @param object $this Sharing service properties.
116
		 * @param int|false $id Sharing ID.
117
		 * @param array $args Array of sharing service options.
118
		 */
119
		$url = apply_filters( 'sharing_display_link', $url, $this, $id, $args ); // backwards compatibility
120
		/**
121
		 * Filter the sharing display link.
122
		 *
123
		 * @module sharedaddy
124
		 *
125
		 * @since 2.8.0
126
		 *
127
		 * @param string $url Post URL.
128
		 * @param object $this Sharing service properties.
129
		 * @param int|false $id Sharing ID.
130
		 * @param array $args Array of sharing service options.
131
		 */
132
		$url = apply_filters( 'jetpack_sharing_display_link', $url, $this, $id, $args );
133
		/**
134
		 * Filter the sharing display query.
135
		 *
136
		 * @module sharedaddy
137
		 *
138
		 * @since 2.8.0
139
		 *
140
		 * @param string $query Sharing service URL parameter.
141
		 * @param object $this Sharing service properties.
142
		 * @param int|false $id Sharing ID.
143
		 * @param array $args Array of sharing service options.
144
		 */
145
		$query = apply_filters( 'jetpack_sharing_display_query', $query, $this, $id, $args );
146
147
		if ( !empty( $query ) ) {
148
			if ( false === stripos( $url, '?' ) )
149
				$url .= '?'.$query;
150
			else
151
				$url .= '&amp;'.$query;
152
		}
153
154
		if ( 'text' == $this->button_style )
155
			$klasses[] = 'no-icon';
156
157
		/**
158
		 * Filter the sharing display classes.
159
		 *
160
		 * @module sharedaddy
161
		 *
162
		 * @since 3.4.0
163
		 *
164
		 * @param array $klasses Sharing service classes.
165
		 * @param object $this Sharing service properties.
166
		 * @param int|false $id Sharing ID.
167
		 * @param array $args Array of sharing service options.
168
		 */
169
		$klasses = apply_filters( 'jetpack_sharing_display_classes', $klasses, $this, $id, $args );
170
		/**
171
		 * Filter the sharing display title.
172
		 *
173
		 * @module sharedaddy
174
		 *
175
		 * @since 3.4.0
176
		 *
177
		 * @param string $title Sharing service title.
178
		 * @param object $this Sharing service properties.
179
		 * @param int|false $id Sharing ID.
180
		 * @param array $args Array of sharing service options.
181
		 */
182
		$title = apply_filters( 'jetpack_sharing_display_title', $title, $this, $id, $args );
183
		/**
184
		 * Filter the sharing display text.
185
		 *
186
		 * @module sharedaddy
187
		 *
188
		 * @since 3.4.0
189
		 *
190
		 * @param string $text Sharing service text.
191
		 * @param object $this Sharing service properties.
192
		 * @param int|false $id Sharing ID.
193
		 * @param array $args Array of sharing service options.
194
		 */
195
		$text = apply_filters( 'jetpack_sharing_display_text', $text, $this, $id, $args );
196
197
		return sprintf(
198
			'<a rel="nofollow" data-shared="%s" class="%s" href="%s"%s title="%s"><span%s>%s</span></a>',
199
			( $id ? esc_attr( $id ) : '' ),
200
			implode( ' ', $klasses ),
201
			$url,
202
			( true == $this->open_link_in_new ) ? ' target="_blank"' : '',
203
			$title,
204
			( 'icon' == $this->button_style ) ? '></span><span class="sharing-screen-reader-text"' : '',
205
206
			$text
207
		);
208
	}
209
210
	/**
211
	 * Get an unfiltered post permalink to use when generating a sharing URL with get_link.
212
	 * Use instead of get_share_url for non-official styles as get_permalink ensures that process_request
213
	 * will be executed more reliably, in the case that the filtered URL uses a service that strips query parameters.
214
	 *
215
	 * @since 3.7.0
216
	 * @param int $post_id Post ID.
217
	 * @uses get_permalink
218
	 * @return string get_permalink( $post_id ) Post permalink.
219
	 */
220
	public function get_process_request_url( $post_id ) {
221
		return get_permalink( $post_id );
222
	}
223
224
	abstract public function get_name();
225
	abstract public function get_display( $post );
226
227
	public function display_header() {
228
	}
229
230
	public function display_footer() {
231
	}
232
233
	public function has_advanced_options() {
234
		return false;
235
	}
236
237
	public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
238
		$text = '&nbsp;';
239
		$button_style = ( ! empty( $button_style ) ) ? $button_style : $this->button_style;
240
		if ( !$this->smart && ! $force_smart )
241
			if ( $button_style != 'icon' )
242
				$text = $this->get_name();
243
244
		$klasses = array( 'share-'.$this->get_class(), 'sd-button' );
245
246
		if ( $button_style == 'icon' || $button_style == 'icon-text' )
247
			$klasses[] = 'share-icon';
248
249
		if ( $button_style == 'icon' )
250
			$klasses[] = 'no-text';
251
252
		if ( $button_style == 'text' )
253
			$klasses[] = 'no-icon';
254
255
		$link = sprintf(
256
			'<a rel="nofollow" class="%s" href="javascript:void(0)" title="%s"><span>%s</span></a>',
257
			implode( ' ', $klasses ),
258
			$this->get_name(),
259
			$text
260
		);
261
262
		$smart = ( $this->smart || $force_smart ) ? 'on' : 'off';
263
		$return = "<div class='option option-smart-$smart'>$link</div>";
264
		if ( $echo )
265
			echo $return;
266
267
		return $return;
268
	}
269
270 View Code Duplication
	public function get_total( $post = false ) {
271
		global $wpdb, $blog_id;
272
273
		$name = strtolower( $this->get_id() );
274
275
		if ( $post == false ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
276
			// get total number of shares for service
277
			return (int) $wpdb->get_var( $wpdb->prepare( "SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND share_service = %s", $blog_id, $name ) );
278
		}
279
280
		// get total shares for a post
281
		return (int) $wpdb->get_var( $wpdb->prepare( "SELECT count FROM sharing_stats WHERE blog_id = %d AND post_id = %d AND share_service = %s", $blog_id, $post->ID, $name ) );
282
	}
283
284 View Code Duplication
	public function get_posts_total() {
285
		global $wpdb, $blog_id;
286
287
		$totals = array();
288
		$name   = strtolower( $this->get_id() );
289
290
		$my_data = $wpdb->get_results( $wpdb->prepare( "SELECT post_id as id, SUM( count ) as total FROM sharing_stats WHERE blog_id = %d AND share_service = %s GROUP BY post_id ORDER BY count DESC ", $blog_id, $name ) );
291
292
		if ( !empty( $my_data ) )
293
			foreach( $my_data as $row )
294
				$totals[] = new Sharing_Post_Total( $row->id, $row->total );
295
296
		usort( $totals, array( 'Sharing_Post_Total', 'cmp' ) );
297
298
		return $totals;
299
	}
300
301
	public function process_request( $post, array $post_data ) {
302
		/**
303
		 * Fires when a post is shared via one of the sharing buttons.
304
		 *
305
		 * @module sharedaddy
306
		 *
307
		 * @since 1.1.0
308
		 *
309
		 * @param array $args Aray of information about the sharing service.
310
		 */
311
		do_action( 'sharing_bump_stats', array( 'service' => $this, 'post' => $post ) );
312
	}
313
314
	public function js_dialog( $name, $params = array() ) {
315
		if ( true !== $this->open_link_in_new )
316
			return;
317
318
		$defaults = array(
319
			'menubar'   => 1,
320
			'resizable' => 1,
321
			'width'     => 600,
322
			'height'    => 400,
323
		);
324
		$params = array_merge( $defaults, $params );
325
		$opts = array();
326
		foreach( $params as $key => $val ) {
327
			$opts[] = "$key=$val";
328
		}
329
		$opts = implode( ',', $opts );
330
331
		// Add JS after sharing-js has been enqueued.
332
		wp_add_inline_script( 'sharing-js',
333
			"var windowOpen;
334
			jQuery( document.body ).on( 'click', 'a.share-$name', function() {
335
				// If there's another sharing window open, close it.
336
				if ( 'undefined' !== typeof windowOpen ) {
337
					windowOpen.close();
338
				}
339
				windowOpen = window.open( jQuery( this ).attr( 'href' ), 'wpcom$name', '$opts' );
340
				return false;
341
			});"
342
		);
343
	}
344
}
345
346
abstract class Sharing_Advanced_Source extends Sharing_Source {
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...
347
	public function has_advanced_options() {
348
		return true;
349
	}
350
351
	abstract public function display_options();
352
	abstract public function update_options( array $data );
353
	abstract public function get_options();
354
}
355
356
357
class Share_Email extends Sharing_Source {
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...
358
	public $shortname = 'email';
359
	public $genericon = '\f410';
360 View Code Duplication
	public function __construct( $id, array $settings ) {
361
		parent::__construct( $id, $settings );
362
363
		if ( 'official' == $this->button_style )
364
			$this->smart = true;
365
		else
366
			$this->smart = false;
367
	}
368
369
	public function get_name() {
370
		return _x( 'Email', 'as sharing source', 'jetpack' );
371
	}
372
373
	// Default does nothing
374
	public function process_request( $post, array $post_data ) {
375
		$ajax = false;
376
		if ( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) == 'xmlhttprequest' )
377
			$ajax = true;
378
379
		$source_email = $target_email = $source_name = false;
0 ignored issues
show
Unused Code introduced by
$source_name is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
380
381
		if ( isset( $post_data['source_email'] ) && is_email( $post_data['source_email'] ) )
382
			$source_email = $post_data['source_email'];
383
384
		if ( isset( $post_data['target_email'] ) && is_email( $post_data['target_email'] ) )
385
			$target_email = $post_data['target_email'];
386
387
		if ( isset( $post_data['source_name'] ) && strlen( $post_data['source_name'] ) < 200 ) {
388
			$source_name = $post_data['source_name'];
389
		} elseif ( isset( $post_data['source_name'] ) ) {
390
			$source_name = substr( $post_data['source_name'], 0, 200 );
391
		} else {
392
			$source_name = '';
393
		}
394
395
		// Test email
396
		$error = 1;   // Failure in data
397
		if ( empty( $post_data['source_f_name'] ) && $source_email && $target_email && $source_name ) {
398
			/**
399
			 * Allow plugins to stop the email sharing button from running the shared message through Akismet.
400
			 *
401
			 * @module sharedaddy
402
			 *
403
			 * @since 1.1.0
404
			 *
405
			 * @param bool true Should we check if the message isn't spam?
406
			 * @param object $post Post information.
407
			 * @param array $post_data Information about the shared message.
408
			 */
409
			if ( apply_filters( 'sharing_email_check', true, $post, $post_data ) ) {
410
				$data = array(
411
					'post'   => $post,
412
					'source' => $source_email,
413
					'target' => $target_email,
414
					'name'   => $source_name
415
				);
416
				// todo: implement an error message when email doesn't get sent.
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...
417
				/**
418
				 * Filter whether an email can be sent from the Email sharing button.
419
				 *
420
				 * @module sharedaddy
421
				 *
422
				 * @since 1.1.0
423
				 *
424
				 * @param array $data Array of information about the shared message.
425
				 */
426
				if ( ( $data = apply_filters( 'sharing_email_can_send', $data ) ) !== false ) {
427
					// Record stats
428
					parent::process_request( $data['post'], $post_data );
429
430
					/**
431
					 * Fires when an email is sent via the Email sharing button.
432
					 *
433
					 * @module sharedaddy
434
					 *
435
					 * @since 1.1.0
436
					 *
437
					 * @param array $data Array of information about the shared message.
438
					 */
439
					do_action( 'sharing_email_send_post', $data );
440
				}
441
442
				// Return a positive regardless of whether the user is subscribed or not
443
				if ( $ajax ) {
444
?>
445
<div class="response">
446
	<div class="response-title"><?php _e( 'This post has been shared!', 'jetpack' ); ?></div>
447
 	<div class="response-sub"><?php printf( __( 'You have shared this post with %s', 'jetpack' ), esc_html( $target_email ) ); ?></div>
448
 	<div class="response-close"><a href="#" class="sharing_cancel"><?php _e( 'Close', 'jetpack' ); ?></a></div>
449
</div>
450
<?php
451
				}
452
				else
453
					wp_safe_redirect( get_permalink( $post->ID ).'?shared=email' );
454
455
				die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
456
			}
457
			else
458
				$error = 2;   // Email check failed
459
		}
460
461
		if ( $ajax )
462
			echo $error;
463
		else
464
			wp_safe_redirect( get_permalink( $post->ID ).'?shared=email&msg=fail' );
465
466
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
467
	}
468
469
	public function get_display( $post ) {
470
		return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Email', 'share to', 'jetpack' ), __( 'Click to email this to a friend', 'jetpack' ), 'share=email' );
471
	}
472
473
	/**
474
	 * Outputs the hidden email dialog
475
	 */
476
	public function display_footer() {
477
		global $current_user;
478
479
		$visible = $status = false;
0 ignored issues
show
Unused Code introduced by
$status is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
Unused Code introduced by
$visible is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
480
?>
481
	<div id="sharing_email" style="display: none;">
482
		<form action="<?php echo esc_url( $_SERVER['REQUEST_URI'] ); ?>" method="post">
483
			<label for="target_email"><?php _e( 'Send to Email Address', 'jetpack' ) ?></label>
484
			<input type="email" name="target_email" id="target_email" value="" />
485
486
			<?php if ( is_user_logged_in() ) : ?>
487
				<input type="hidden" name="source_name" value="<?php echo esc_attr( $current_user->display_name ); ?>" />
488
				<input type="hidden" name="source_email" value="<?php echo esc_attr( $current_user->user_email ); ?>" />
489
			<?php else : ?>
490
491
				<label for="source_name"><?php _e( 'Your Name', 'jetpack' ) ?></label>
492
				<input type="text" name="source_name" id="source_name" value="" />
493
494
				<label for="source_email"><?php _e( 'Your Email Address', 'jetpack' ) ?></label>
495
				<input type="email" name="source_email" id="source_email" value="" />
496
497
			<?php endif; ?>
498
			<input type="text" id="jetpack-source_f_name" name="source_f_name" class="input" value="" size="25" autocomplete="off" />
499
			<script>jQuery( document ).ready( function(){ document.getElementById('jetpack-source_f_name').value = '' });</script>
500
			<?php
501
				/**
502
				 * Fires when the Email sharing dialog is loaded.
503
				 *
504
				 * @module sharedaddy
505
				 *
506
				 * @since 1.1.0
507
				 *
508
				 * @param string jetpack Eail sharing source.
509
				 */
510
				do_action( 'sharing_email_dialog', 'jetpack' );
511
			?>
512
513
			<img style="float: right; display: none" class="loading" src="<?php
514
			/** This filter is documented in modules/stats.php */
515
			echo apply_filters( 'jetpack_static_url', plugin_dir_url( __FILE__ ) . 'images/loading.gif' ); ?>" alt="loading" width="16" height="16" />
516
			<input type="submit" value="<?php esc_attr_e( 'Send Email', 'jetpack' ); ?>" class="sharing_send" />
517
			<a rel="nofollow" href="#cancel" class="sharing_cancel"><?php _e( 'Cancel', 'jetpack' ); ?></a>
518
519
			<div class="errors errors-1" style="display: none;">
520
				<?php _e( 'Post was not sent - check your email addresses!', 'jetpack' ); ?>
521
			</div>
522
523
			<div class="errors errors-2" style="display: none;">
524
				<?php _e( 'Email check failed, please try again', 'jetpack' ); ?>
525
			</div>
526
527
			<div class="errors errors-3" style="display: none;">
528
				<?php _e( 'Sorry, your blog cannot share posts by email.', 'jetpack' ); ?>
529
			</div>
530
		</form>
531
	</div>
532
<?php
533
	}
534
}
535
536
class Share_Twitter extends Sharing_Source {
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...
537
	public $shortname = 'twitter';
538
	public $genericon = '\f202';
539
	// 'https://dev.twitter.com/rest/reference/get/help/configuration' ( 2015/02/06 ) short_url_length is 22, short_url_length_https is 23
540
	public $short_url_length = 24;
541
542 View Code Duplication
	public function __construct( $id, array $settings ) {
543
		parent::__construct( $id, $settings );
544
545
		if ( 'official' == $this->button_style )
546
			$this->smart = true;
547
		else
548
			$this->smart = false;
549
	}
550
551
	public function get_name() {
552
		return __( 'Twitter', 'jetpack' );
553
	}
554
555
	function sharing_twitter_via( $post ) {
556
		/**
557
		 * Allow third-party plugins to customize the Twitter username used as "twitter:site" Twitter Card Meta Tag.
558
		 *
559
		 * @module sharedaddy
560
		 *
561
		 * @since 3.0.0
562
		 *
563
		 * @param string $string Twitter Username.
564
		 * @param array $args Array of Open Graph Meta Tags and Twitter Cards tags.
565
		 */
566
		$twitter_site_tag_value = apply_filters( 'jetpack_twitter_cards_site_tag', '', array() );
567
568
		/*
569
		 * Hack to remove the unwanted behavior of adding 'via @jetpack' which
570
		 * was introduced with the adding of the Twitter cards.
571
		 * This should be a temporary solution until a better method is setup.
572
		 */
573
		if( 'jetpack' == $twitter_site_tag_value ) {
574
			$twitter_site_tag_value = '';
575
		}
576
577
		/**
578
		 * Filters the Twitter username used as "via" in the Twitter sharing button.
579
		 *
580
		 * @module sharedaddy
581
		 *
582
		 * @since 1.7.0
583
		 *
584
		 * @param string $twitter_site_tag_value Twitter Username.
585
		 * @param int $post->ID Post ID.
586
		 */
587
		$twitter_site_tag_value = apply_filters( 'jetpack_sharing_twitter_via', $twitter_site_tag_value, $post->ID );
588
589
		// Strip out anything other than a letter, number, or underscore.
590
		// This will prevent the inadvertent inclusion of an extra @, as well as normalizing the handle.
591
		return preg_replace( '/[^\da-z_]+/i', '', $twitter_site_tag_value );
592
	}
593
594
	public function get_related_accounts( $post ) {
595
		/**
596
		 * Filter the list of related Twitter accounts added to the Twitter sharing button.
597
		 *
598
		 * @module sharedaddy
599
		 *
600
		 * @since 1.7.0
601
		 *
602
		 * @param array $args Array of Twitter usernames. Format is 'username' => 'Optional description'
603
		 * @param int $post->ID Post ID.
604
		 */
605
		$related_accounts = apply_filters( 'jetpack_sharing_twitter_related', array(), $post->ID );
606
607
		// Example related string: account1,account2:Account 2 description,account3
608
		$related = array();
609
610
		foreach ( $related_accounts as $related_account_username => $related_account_description ) {
611
			// Join the description onto the end of the username
612
			if ( $related_account_description )
613
				$related_account_username .= ':' . $related_account_description;
614
615
			$related[] = $related_account_username;
616
		}
617
618
		return implode( ',', $related );
619
	}
620
621
	public function get_display( $post ) {
622
		$via = $this->sharing_twitter_via( $post );
623
624
		if ( $via ) {
625
			$via = 'data-via="' . esc_attr( $via ) . '"';
626
		} else {
627
			$via = '';
628
		}
629
630
		$related = $this->get_related_accounts( $post );
631
		if ( ! empty( $related ) && $related !== $via ) {
632
			$related = 'data-related="' . esc_attr( $related ) . '"';
633
		} else {
634
			$related = '';
635
		}
636
637
		if ( $this->smart ) {
638
			$share_url = $this->get_share_url( $post->ID );
639
			$post_title = $this->get_share_title( $post->ID );
640
			return sprintf(
641
				'<a href="https://twitter.com/share" class="twitter-share-button" data-url="%1$s" data-text="%2$s" %3$s %4$s>Tweet</a>',
642
				esc_url( $share_url ),
643
				esc_attr( $post_title ),
644
				$via,
645
				$related
646
			);
647
		} else {
648
			if (
649
				/**
650
				 * Allow plugins to disable sharing counts for specific sharing services.
651
				 *
652
				 * @module sharedaddy
653
				 *
654
				 * @since 3.0.0
655
				 *
656
				 * @param bool true Should sharing counts be enabled for this specific service. Default to true.
657
				 * @param int $post->ID Post ID.
658
				 * @param string $str Sharing service name.
659
				 */
660
				apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'twitter' )
661
			) {
662
				sharing_register_post_for_share_counts( $post->ID );
663
			}
664
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Twitter', 'share to', 'jetpack' ), __( 'Click to share on Twitter', 'jetpack' ), 'share=twitter', 'sharing-twitter-' . $post->ID );
665
		}
666
	}
667
668
	public function process_request( $post, array $post_data ) {
669
		$post_title = $this->get_share_title( $post->ID );
670
		$post_link = $this->get_share_url( $post->ID );
671
672
		if ( function_exists( 'mb_stripos' ) ) {
673
			$strlen = 'mb_strlen';
674
			$substr = 'mb_substr';
675
		} else {
676
			$strlen = 'strlen';
677
			$substr = 'substr';
678
		}
679
680
		$via = $this->sharing_twitter_via( $post );
681
		$related = $this->get_related_accounts( $post );
682
		if ( $via ) {
683
			$sig = " via @$via";
684
			if ( $related === $via ) {
685
				$related = false;
686
			}
687
		} else {
688
			$via = false;
689
			$sig = '';
690
		}
691
692
		$suffix_length = $this->short_url_length + $strlen( $sig );
693
		// $sig is handled by twitter in their 'via' argument.
694
		// $post_link is handled by twitter in their 'url' argument.
695
		if ( 140 < $strlen( $post_title ) + $suffix_length ) {
696
			// The -1 is for "\xE2\x80\xA6", a UTF-8 ellipsis.
697
			$text = $substr( $post_title, 0, 140 - $suffix_length - 1 ) . "\xE2\x80\xA6";
698
		} else {
699
			$text = $post_title;
700
		}
701
702
		// Record stats
703
		parent::process_request( $post, $post_data );
704
705
		$url = $post_link;
706
		$twitter_url = add_query_arg(
707
			rawurlencode_deep( array_filter( compact( 'via', 'related', 'text', 'url' ) ) ),
708
			'https://twitter.com/intent/tweet'
709
		);
710
711
		// Redirect to Twitter
712
		wp_redirect( $twitter_url );
713
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
714
	}
715
716
	public function has_custom_button_style() {
717
		return $this->smart;
718
	}
719
720
	public function display_footer() {
721
		if ( $this->smart ) {
722
			?>
723
			<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
724
			<?php
725
		} else {
726
			$this->js_dialog( $this->shortname, array( 'height' => 350 ) );
727
		}
728
	}
729
}
730
731
732
class Share_Reddit extends Sharing_Source {
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...
733
	public $shortname = 'reddit';
734
	public $genericon = '\f222';
735 View Code Duplication
	public function __construct( $id, array $settings ) {
736
		parent::__construct( $id, $settings );
737
738
		if ( 'official' == $this->button_style )
739
			$this->smart = true;
740
		else
741
			$this->smart = false;
742
	}
743
744
	public function get_name() {
745
		return __( 'Reddit', 'jetpack' );
746
	}
747
748
	public function get_display( $post ) {
749
		if ( $this->smart )
750
			return '<div class="reddit_button"><iframe src="' . $this->http() . '://www.reddit.com/static/button/button1.html?newwindow=true&width=120&amp;url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&amp;title=' . rawurlencode( $this->get_share_title( $post->ID ) ) . '" height="22" width="120" scrolling="no" frameborder="0"></iframe></div>';
751 View Code Duplication
		else
752
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Reddit', 'share to', 'jetpack' ), __( 'Click to share on Reddit', 'jetpack' ), 'share=reddit' );
753
	}
754
755 View Code Duplication
	public function process_request( $post, array $post_data ) {
756
		$reddit_url = $this->http() . '://reddit.com/submit?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) );
757
758
		// Record stats
759
		parent::process_request( $post, $post_data );
760
761
		// Redirect to Reddit
762
		wp_redirect( $reddit_url );
763
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
764
	}
765
}
766
767
class Share_LinkedIn extends Sharing_Source {
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...
768
	public $shortname = 'linkedin';
769
	public $genericon = '\f207';
770 View Code Duplication
	public function __construct( $id, array $settings ) {
771
		parent::__construct( $id, $settings );
772
773
		if ( 'official' == $this->button_style )
774
			$this->smart = true;
775
		else
776
			$this->smart = false;
777
	}
778
779
	public function get_name() {
780
		return __( 'LinkedIn', 'jetpack' );
781
	}
782
783
	public function has_custom_button_style() {
784
		return $this->smart;
785
	}
786
787
	public function get_display( $post ) {
788
		$display = '';
789
790
		if ( $this->smart ) {
791
			$share_url = $this->get_share_url( $post->ID );
792
			$display .= sprintf( '<div class="linkedin_button"><script type="in/share" data-url="%s" data-counter="right"></script></div>', esc_url( $share_url ) );
793 View Code Duplication
		} else {
794
			$display = $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'LinkedIn', 'share to', 'jetpack' ), __( 'Click to share on LinkedIn', 'jetpack' ), 'share=linkedin', 'sharing-linkedin-' . $post->ID );
795
		}
796
797
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
798
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'linkedin' ) ) {
799
			sharing_register_post_for_share_counts( $post->ID );
800
		}
801
802
		return $display;
803
	}
804
805 View Code Duplication
	public function process_request( $post, array $post_data ) {
806
807
		$post_link = $this->get_share_url( $post->ID );
808
809
		// Using the same URL as the official button, which is *not* LinkedIn's documented sharing link
810
		// https://www.linkedin.com/cws/share?url={url}&token=&isFramed=false
811
812
		$linkedin_url = add_query_arg( array(
813
			'url' => rawurlencode( $post_link ),
814
		), 'https://www.linkedin.com/cws/share?token=&isFramed=false' );
815
816
		// Record stats
817
		parent::process_request( $post, $post_data );
818
819
		// Redirect to LinkedIn
820
		wp_redirect( $linkedin_url );
821
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
822
	}
823
824 View Code Duplication
	public function display_footer() {
825
		if ( !$this->smart ) {
826
			$this->js_dialog( $this->shortname, array( 'width' => 580, 'height' => 450 ) );
827
		} else {
828
			?><script type="text/javascript">
829
			jQuery( document ).ready( function() {
830
			    jQuery.getScript( 'https://platform.linkedin.com/in.js?async=true', function success() {
831
			        IN.init();
832
			    });
833
			});
834
			jQuery( document.body ).on( 'post-load', function() {
835
				if ( typeof IN != 'undefined' )
836
					IN.parse();
837
			});
838
			</script><?php
839
		}
840
	}
841
}
842
843
class Share_Facebook extends Sharing_Source {
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...
844
	public $shortname = 'facebook';
845
	public $genericon = '\f204';
846
	private $share_type = 'default';
847
848 View Code Duplication
	public function __construct( $id, array $settings ) {
849
		parent::__construct( $id, $settings );
850
851
		if ( isset( $settings['share_type'] ) )
852
			$this->share_type = $settings['share_type'];
853
854
		if ( 'official' == $this->button_style )
855
			$this->smart = true;
856
		else
857
			$this->smart = false;
858
	}
859
860
	public function get_name() {
861
		return __( 'Facebook', 'jetpack' );
862
	}
863
864
	public function display_header() {
865
	}
866
867 View Code Duplication
	function guess_locale_from_lang( $lang ) {
868
		if ( 'en' == $lang || 'en_US' == $lang || !$lang ) {
869
			return 'en_US';
870
		}
871
872
		if ( !class_exists( 'GP_Locales' ) ) {
873
			if ( !defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) || !file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) {
874
				return false;
875
			}
876
877
			require JETPACK__GLOTPRESS_LOCALES_PATH;
878
		}
879
880
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
881
			// WP.com: get_locale() returns 'it'
882
			$locale = GP_Locales::by_slug( $lang );
883
		} else {
884
			// Jetpack: get_locale() returns 'it_IT';
885
			$locale = GP_Locales::by_field( 'wp_locale', $lang );
886
		}
887
888
		if ( ! $locale ) {
889
			return false;
890
		}
891
892
		if ( empty( $locale->facebook_locale ) ) {
893
			if ( empty( $locale->wp_locale ) ) {
894
				return false;
895
			} else {
896
				// Facebook SDK is smart enough to fall back to en_US if a
897
				// locale isn't supported. Since supported Facebook locales
898
				// can fall out of sync, we'll attempt to use the known
899
				// wp_locale value and rely on said fallback.
900
				return $locale->wp_locale;
901
			}
902
		}
903
904
		return $locale->facebook_locale;
905
	}
906
907
	public function get_display( $post ) {
908
		if ( $this->smart ) {
909
			$share_url = $this->get_share_url( $post->ID );
910
			$fb_share_html = '<div class="fb-share-button" data-href="' . esc_attr( $share_url ) . '" data-layout="button_count"></div>';
911
			/**
912
			 * Filter the output of the Facebook Sharing button.
913
			 *
914
			 * @module sharedaddy
915
			 *
916
			 * @since 3.6.0
917
			 *
918
			 * @param string $fb_share_html Facebook Sharing button HTML.
919
			 * @param string $share_url URL of the post to share.
920
			 */
921
			return apply_filters( 'jetpack_sharing_facebook_official_button_output', $fb_share_html, $share_url );
922
		}
923
924
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
925
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'facebook' ) ) {
926
			sharing_register_post_for_share_counts( $post->ID );
927
		}
928
		return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Facebook', 'share to', 'jetpack' ), __( 'Click to share on Facebook', 'jetpack' ), 'share=facebook', 'sharing-facebook-' . $post->ID );
929
	}
930
931 View Code Duplication
	public function process_request( $post, array $post_data ) {
932
		$fb_url = $this->http() . '://www.facebook.com/sharer.php?u=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&t=' . rawurlencode( $this->get_share_title( $post->ID ) );
933
934
		// Record stats
935
		parent::process_request( $post, $post_data );
936
937
		// Redirect to Facebook
938
		wp_redirect( $fb_url );
939
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
940
	}
941
942
	public function display_footer() {
943
		$this->js_dialog( $this->shortname );
944
		if ( $this->smart ) {
945
			$locale = $this->guess_locale_from_lang( get_locale() );
946
			if ( ! $locale ) {
947
				$locale = 'en_US';
948
			}
949
			/**
950
			 * Filter the App ID used in the official Facebook Share button.
951
			 *
952
			 * @since 3.8.0
953
			 *
954
			 * @param int $fb_app_id Facebook App ID. Default to 249643311490 (WordPress.com's App ID).
955
			 */
956
			$fb_app_id = apply_filters( 'jetpack_sharing_facebook_app_id', '249643311490' );
957
			if ( is_numeric( $fb_app_id ) ) {
958
				$fb_app_id = '&appId=' . $fb_app_id;
959
			} else {
960
				$fb_app_id = '';
961
			}
962
			?><div id="fb-root"></div>
963
			<script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = 'https://connect.facebook.net/<?php echo $locale; ?>/sdk.js#xfbml=1<?php echo $fb_app_id; ?>&version=v2.3'; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script>
964
			<script>
965
			jQuery( document.body ).on( 'post-load', function() {
966
				if ( 'undefined' !== typeof FB ) {
967
					FB.XFBML.parse();
968
				}
969
			} );
970
			</script>
971
			<?php
972
		}
973
	}
974
}
975
976
class Share_Print extends Sharing_Source {
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...
977
	public $shortname = 'print';
978
	public $genericon = '\f469';
979 View Code Duplication
	public function __construct( $id, array $settings ) {
980
		parent::__construct( $id, $settings );
981
982
		if ( 'official' == $this->button_style )
983
			$this->smart = true;
984
		else
985
			$this->smart = false;
986
	}
987
988
	public function get_name() {
989
		return __( 'Print', 'jetpack' );
990
	}
991
992
	public function get_display( $post ) {
993
		return $this->get_link( $this->get_process_request_url( $post->ID ) . ( ( is_single() || is_page() ) ? '#print': '' ), _x( 'Print', 'share to', 'jetpack' ), __( 'Click to print', 'jetpack' ) );
994
	}
995
}
996
997
class Share_PressThis extends Sharing_Source {
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...
998
	public $shortname = 'pressthis';
999
	public $genericon = '\f205';
1000 View Code Duplication
	public function __construct( $id, array $settings ) {
1001
		parent::__construct( $id, $settings );
1002
1003
		if ( 'official' == $this->button_style )
1004
			$this->smart = true;
1005
		else
1006
			$this->smart = false;
1007
	}
1008
1009
	public function get_name() {
1010
		return __( 'Press This', 'jetpack' );
1011
	}
1012
1013
	public function process_request( $post, array $post_data ) {
1014
		global $current_user;
1015
1016
		$primary_blog = (int) get_user_meta( $current_user->ID, 'primary_blog', true );
1017
		if ( $primary_blog ) {
1018
			$primary_blog_details = get_blog_details( $primary_blog );
1019
		} else {
1020
			$primary_blog_details = false;
1021
		}
1022
1023
		if ( $primary_blog_details ) {
1024
			$blogs = array( $primary_blog_details );
1025
		} elseif ( function_exists( 'get_active_blogs_for_user' ) ) {
1026
			$blogs = get_active_blogs_for_user();
1027
			if ( empty( $blogs ) ) {
1028
				$blogs = get_blogs_of_user( $current_user->ID );
1029
			}
1030
		} else {
1031
			$blogs = get_blogs_of_user( $current_user->ID );
1032
		}
1033
1034
		if ( empty( $blogs ) ) {
1035
			wp_safe_redirect( get_permalink( $post->ID ) );
1036
			die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
1037
		}
1038
1039
		$blog = current( $blogs );
1040
1041
		$url = $blog->siteurl.'/wp-admin/press-this.php?u='.rawurlencode( $this->get_share_url( $post->ID ) ).'&t='.rawurlencode( $this->get_share_title( $post->ID ) );
1042
1043
		if ( isset( $_GET['sel'] ) )
1044
			$url .= '&s='.rawurlencode( $_GET['sel'] );
1045
1046
		// Record stats
1047
		parent::process_request( $post, $post_data );
1048
1049
		// Redirect to Press This
1050
		wp_safe_redirect( $url );
1051
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
1052
	}
1053
1054
	public function get_display( $post ) {
1055
		return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Press This', 'share to', 'jetpack' ), __( 'Click to Press This!', 'jetpack' ), 'share=press-this' );
1056
	}
1057
}
1058
1059
class Share_GooglePlus1 extends Sharing_Source {
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...
1060
	public $shortname = 'googleplus1';
1061
	public $genericon = '\f218';
1062
	private $state = false;
1063
1064 View Code Duplication
	public function __construct( $id, array $settings ) {
1065
		parent::__construct( $id, $settings );
1066
1067
		if ( 'official' == $this->button_style )
1068
			$this->smart = true;
1069
		else
1070
			$this->smart = false;
1071
	}
1072
1073
	public function get_name() {
1074
		return __( 'Google', 'jetpack' );
1075
	}
1076
1077
	public function has_custom_button_style() {
1078
		return $this->smart;
1079
	}
1080
1081
	public function get_display( $post ) {
1082
1083
		if ( $this->smart ) {
1084
			$share_url = $this->get_share_url( $post->ID );
1085
			return '<div class="googleplus1_button"><div class="g-plus" data-action="share" data-annotation="bubble" data-href="' . esc_url( $share_url ) . '"></div></div>';
1086 View Code Duplication
		} else {
1087
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Google', 'share to', 'jetpack' ), __( 'Click to share on Google+', 'jetpack' ), 'share=google-plus-1', 'sharing-google-' . $post->ID );
1088
		}
1089
	}
1090
1091
	public function get_state() {
1092
		return $this->state;
1093
	}
1094
1095
	public function process_request( $post, array $post_data ) {
1096
1097
		if ( isset( $post_data['state'] ) ) {
1098
			$this->state = $post_data['state'];
1099
		}
1100
		// Record stats
1101
		parent::process_request( $post, $post_data );
1102
1103
		// Redirect to Google +'s sharing endpoint
1104
		$url = 'https://plus.google.com/share?url=' . rawurlencode( $this->get_share_url( $post->ID ) );
1105
		wp_redirect( $url );
1106
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
1107
	}
1108
1109 View Code Duplication
	public function display_footer() {
1110
		global $post;
1111
1112
		if ( $this->smart ) { ?>
1113
			<script>
1114
			function renderGooglePlus1() {
1115
				if ( 'undefined' === typeof gapi ) {
1116
					return;
1117
				}
1118
1119
				jQuery( '.g-plus' ).each(function() {
1120
					var $button = jQuery( this );
1121
1122
					if ( ! $button.data( 'gplus-rendered' ) ) {
1123
						gapi.plusone.render( this, {
1124
							href: $button.attr( 'data-href' ),
1125
							size: $button.attr( 'data-size' ),
1126
							annotation: $button.attr( 'data-annotation' )
1127
						});
1128
1129
						$button.data( 'gplus-rendered', true );
1130
					}
1131
				});
1132
			}
1133
1134
			(function() {
1135
				var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
1136
				po.src = 'https://apis.google.com/js/plusone.js';
1137
				po.innerHTML = '{"parsetags": "explicit"}';
1138
				po.onload = renderGooglePlus1;
1139
				var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
1140
			})();
1141
1142
			jQuery( document.body ).on( 'post-load', renderGooglePlus1 );
1143
			</script>
1144
			<?php
1145
		} else {
1146
			$this->js_dialog( 'google-plus-1', array( 'width' => 480, 'height' => 550 ) );
1147
		}
1148
	}
1149
1150 View Code Duplication
	public function get_total( $post = false ) {
1151
		global $wpdb, $blog_id;
1152
1153
		$name = strtolower( $this->get_id() );
1154
1155
		if ( $post == false ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1156
			// get total number of shares for service
1157
			return $wpdb->get_var( $wpdb->prepare( "SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND share_service = %s", $blog_id, $name ) );
1158
		}
1159
1160
		//get total shares for a post
1161
		return $wpdb->get_var( $wpdb->prepare( "SELECT count FROM sharing_stats WHERE blog_id = %d AND post_id = %d AND share_service = %s", $blog_id, $post->ID, $name ) );
1162
	}
1163
}
1164
1165
class Share_Custom extends Sharing_Advanced_Source {
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...
1166
	private $name;
1167
	private $icon;
1168
	private $url;
1169
	public $smart = true;
1170
	public $shortname;
1171
1172
	public function get_class() {
1173
		return 'custom share-custom-' . sanitize_html_class( strtolower( $this->name ) );
1174
	}
1175
1176
	public function __construct( $id, array $settings ) {
1177
		parent::__construct( $id, $settings );
1178
1179
		$opts = $this->get_options();
0 ignored issues
show
Unused Code introduced by
$opts is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1180
1181
		if ( isset( $settings['name'] ) ) {
1182
			$this->name = $settings['name'];
1183
			$this->shortname = preg_replace( '/[^a-z0-9]*/', '', $settings['name'] );
1184
		}
1185
1186
		if ( isset( $settings['icon'] ) ) {
1187
			$this->icon = $settings['icon'];
1188
1189
			$new_icon = esc_url_raw( wp_specialchars_decode( $this->icon, ENT_QUOTES ) );
1190
			$i = 0;
1191
			while ( $new_icon != $this->icon ) {
1192
				if ( $i > 5 ) {
1193
					$this->icon = false;
1194
					break;
1195
				} else {
1196
					$this->icon = $new_icon;
1197
					$new_icon = esc_url_raw( wp_specialchars_decode( $this->icon, ENT_QUOTES ) );
1198
				}
1199
				$i++;
1200
			}
1201
		}
1202
1203
		if ( isset( $settings['url'] ) )
1204
			$this->url = $settings['url'];
1205
	}
1206
1207
	public function get_name() {
1208
		return $this->name;
1209
	}
1210
1211
	public function get_display( $post ) {
1212
		$str = $this->get_link( $this->get_process_request_url( $post->ID ), esc_html( $this->name ), sprintf( __( 'Click to share on %s', 'jetpack' ), esc_attr( $this->name ) ), 'share='.$this->id );
1213
		return str_replace( '<span>', '<span style="' . esc_attr( 'background-image:url("' . addcslashes( esc_url_raw( $this->icon ), '"' ) . '");' ) . '">', $str );
1214
	}
1215
1216
	public function process_request( $post, array $post_data ) {
1217
		$url = str_replace( '&amp;', '&', $this->url );
1218
		$url = str_replace( '%post_url%', rawurlencode( $this->get_share_url( $post->ID ) ), $url );
1219
		$url = str_replace( '%post_full_url%', rawurlencode( get_permalink( $post->ID ) ), $url );
1220
		$url = str_replace( '%post_title%', rawurlencode( $this->get_share_title( $post->ID ) ), $url );
1221
1222
		if ( strpos( $url, '%post_tags%' ) !== false ) {
1223
			$tags   = get_the_tags( $post->ID );
1224
			$tagged = '';
1225
1226
			if ( $tags ) {
1227
				foreach ( $tags AS $tag ) {
1228
					$tagged[] = rawurlencode( $tag->name );
1229
				}
1230
1231
				$tagged = implode( ',', $tagged );
1232
			}
1233
1234
			$url = str_replace( '%post_tags%', $tagged, $url );
1235
		}
1236
1237
		if ( strpos( $url, '%post_excerpt%' ) !== false ) {
1238
			$url_excerpt = $post->post_excerpt;
1239
			if ( empty( $url_excerpt ) )
1240
				$url_excerpt = $post->post_content;
1241
1242
			$url_excerpt = strip_tags( strip_shortcodes( $url_excerpt ) );
1243
			$url_excerpt = wp_html_excerpt( $url_excerpt, 100 );
1244
			$url_excerpt = rtrim( preg_replace( '/[^ .]*$/', '', $url_excerpt ) );
1245
			$url = str_replace( '%post_excerpt%', rawurlencode( $url_excerpt ), $url );
1246
		}
1247
1248
		// Record stats
1249
		parent::process_request( $post, $post_data );
1250
1251
		// Redirect
1252
		wp_redirect( $url );
1253
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
1254
	}
1255
1256
	public function display_options() {
1257
?>
1258
<div class="input">
1259
	<table class="form-table">
1260
		<tbody>
1261
			<tr>
1262
				<th scope="row"><?php _e( 'Label', 'jetpack' ); ?></th>
1263
				<td><input type="text" name="name" value="<?php echo esc_attr( $this->name ); ?>" /></td>
1264
			</tr>
1265
1266
			<tr>
1267
				<th scope="row"><?php _e( 'URL', 'jetpack' ); ?></th>
1268
				<td><input type="text" name="url" value="<?php echo esc_attr( $this->url ); ?>" /></td>
1269
			</tr>
1270
1271
			<tr>
1272
				<th scope="row"><?php _e( 'Icon', 'jetpack' ); ?></th>
1273
				<td><input type="text" name="icon" value="<?php echo esc_attr( $this->icon ); ?>" /></td>
1274
			</tr>
1275
1276
			<tr>
1277
				<th scope="row"></th>
1278
				<td>
1279
					<input class="button-secondary" type="submit" value="<?php esc_attr_e( 'Save', 'jetpack' ); ?>" />
1280
					<a href="#" class="remove"><small><?php _e( 'Remove Service', 'jetpack' ); ?></small></a>
1281
				</td>
1282
			</tr>
1283
		</tbody>
1284
	</table>
1285
</div>
1286
<?php
1287
	}
1288
1289
	public function update_options( array $data ) {
1290
		$name  = trim( wp_html_excerpt( wp_kses( stripslashes( $data['name'] ), array() ), 30 ) );
1291
		$url   = trim( esc_url_raw( $data['url'] ) );
1292
		$icon  = trim( esc_url_raw( $data['icon'] ) );
1293
1294
		if ( $name )
1295
			$this->name = $name;
1296
1297
		if ( $url )
1298
			$this->url  = $url;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 2 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...
1299
1300
		if ( $icon )
1301
			$this->icon = $icon;
1302
	}
1303
1304
	public function get_options() {
1305
		return array(
1306
			'name' => $this->name,
1307
			'icon' => $this->icon,
1308
			'url'  => $this->url,
1309
		);
1310
	}
1311
1312
	public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
1313
		$opts = $this->get_options();
1314
1315
		$text = '&nbsp;';
1316
		if ( !$this->smart )
1317
			if ( $this->button_style != 'icon' )
1318
				$text = $this->get_name();
1319
1320
		$klasses = array( 'share-'.$this->shortname );
1321
1322
		if ( $this->button_style == 'icon' || $this->button_style == 'icon-text' )
1323
			$klasses[] = 'share-icon';
1324
1325
		if ( $this->button_style == 'icon' ) {
1326
			$text = '';
1327
			$klasses[] = 'no-text';
1328
		}
1329
1330
		if ( $this->button_style == 'text' )
1331
			$klasses[] = 'no-icon';
1332
1333
		$link = sprintf(
1334
			'<a rel="nofollow" class="%s" href="javascript:void(0)" title="%s"><span style="background-image:url(&quot;%s&quot;) !important;background-position:left center;background-repeat:no-repeat;">%s</span></a>',
1335
			implode( ' ', $klasses ),
1336
			$this->get_name(),
1337
			addcslashes( esc_url_raw( $opts['icon'] ), '"' ),
1338
			$text
1339
		);
1340
		?>
1341
		<div class="option option-smart-off">
1342
		<?php echo $link ; ?>
1343
		</div><?php
1344
	}
1345
}
1346
1347
class Share_Tumblr extends Sharing_Source {
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...
1348
	public $shortname = 'tumblr';
1349
	public $genericon = '\f214';
1350 View Code Duplication
	public function __construct( $id, array $settings ) {
1351
		parent::__construct( $id, $settings );
1352
		if ( 'official' == $this->button_style )
1353
			$this->smart = true;
1354
		else
1355
			$this->smart = false;
1356
	}
1357
1358
	public function get_name() {
1359
		return __( 'Tumblr', 'jetpack' );
1360
	}
1361
1362
	public function get_display( $post ) {
1363
		if ( $this->smart ) {
1364
			$target = '';
1365
			if ( true == $this->open_link_in_new )
1366
				$target = '_blank';
1367
1368
			return '<a target="' . $target . '" href="https://www.tumblr.com/share/link/?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&name=' . rawurlencode( $this->get_share_title( $post->ID ) ) . '" title="' . __( 'Share on Tumblr', 'jetpack' ) . '" style="display:inline-block; text-indent:-9999px; overflow:hidden; width:62px; height:20px; background:url(\'https://platform.tumblr.com/v1/share_2.png\') top left no-repeat transparent;">' . __( 'Share on Tumblr', 'jetpack' ) . '</a>';
1369 View Code Duplication
		 } else {
1370
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Tumblr', 'share to', 'jetpack' ), __( 'Click to share on Tumblr', 'jetpack' ), 'share=tumblr' );
1371
		}
1372
	}
1373
1374 View Code Duplication
	public function process_request( $post, array $post_data ) {
1375
		// Record stats
1376
		parent::process_request( $post, $post_data );
1377
1378
		// Redirect to Tumblr's sharing endpoint (a la their bookmarklet)
1379
		$url = 'https://www.tumblr.com/share?v=3&u=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&t=' . rawurlencode( $this->get_share_title( $post->ID ) ) . '&s=';
1380
		wp_redirect( $url );
1381
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
1382
	}
1383
	// http://www.tumblr.com/share?v=3&u=URL&t=TITLE&s=
1384 View Code Duplication
	public function display_footer() {
1385
		if ( $this->smart ) {
1386
			?><script type="text/javascript" src="https://platform.tumblr.com/v1/share.js"></script><?php
1387
		} else {
1388
			$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1389
		}
1390
	}
1391
}
1392
1393
class Share_Pinterest extends Sharing_Source {
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...
1394
	public $shortname = 'pinterest';
1395
	public $genericon = '\f209';
1396
1397 View Code Duplication
	public function __construct( $id, array $settings ) {
1398
		parent::__construct( $id, $settings );
1399
		if ( 'official' == $this->button_style )
1400
			$this->smart = true;
1401
		else
1402
			$this->smart = false;
1403
	}
1404
1405
	public function get_name() {
1406
		return __( 'Pinterest', 'jetpack' );
1407
	}
1408
1409
	public function get_image( $post ) {
1410
		if ( class_exists( 'Jetpack_PostImages' ) ) {
1411
			$image = Jetpack_PostImages::get_image( $post->ID, array( 'fallback_to_avatars' => true ) );
1412
			if ( ! empty( $image ) ) {
1413
				return $image['src'];
1414
			}
1415
		}
1416
1417
		/**
1418
		 * Filters the default image used by the Pinterest Pin It share button.
1419
		 *
1420
		 * @module sharedaddy
1421
		 *
1422
		 * @since 3.6.0
1423
		 *
1424
		 * @param string $url Default image URL.
1425
		 */
1426
		return apply_filters( 'jetpack_sharing_pinterest_default_image', 'https://s0.wp.com/i/blank.jpg' );
1427
	}
1428
1429
	public function get_external_url( $post ) {
1430
		$url = 'https://www.pinterest.com/pin/create/button/?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&media=' . rawurlencode( $this->get_image( $post ) ) . '&description=' . rawurlencode( $post->post_title );
1431
1432
		/**
1433
		 * Filters the Pinterest share URL used in sharing button output.
1434
		 *
1435
		 * @module sharedaddy
1436
		 *
1437
		 * @since 3.6.0
1438
		 *
1439
		 * @param string $url Pinterest share URL.
1440
		 */
1441
		return apply_filters( 'jetpack_sharing_pinterest_share_url', $url );
1442
	}
1443
1444
	public function get_widget_type() {
1445
		/**
1446
		 * Filters the Pinterest widget type.
1447
		 *
1448
		 * @see https://business.pinterest.com/en/widget-builder
1449
		 *
1450
		 * @module sharedaddy
1451
		 *
1452
		 * @since 3.6.0
1453
		 *
1454
		 * @param string $type Pinterest widget type. Default of 'buttonPin' for single-image selection. 'buttonBookmark' for multi-image modal.
1455
		 */
1456
		return apply_filters( 'jetpack_sharing_pinterest_widget_type', 'buttonPin' );
1457
	}
1458
1459
	public function get_display( $post ) {
1460
		$display = '';
0 ignored issues
show
Unused Code introduced by
$display is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1461
1462
		if ( $this->smart ) {
1463
			$display = sprintf(
1464
				'<div class="pinterest_button"><a href="%s" data-pin-do="%s" data-pin-config="beside"><img src="//assets.pinterest.com/images/pidgets/pinit_fg_en_rect_gray_20.png" /></a></div>',
1465
				esc_url( $this->get_external_url( $post ) ),
1466
				esc_attr( $this->get_widget_type() )
1467
			);
1468 View Code Duplication
		} else {
1469
			$display = $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Pinterest', 'share to', 'jetpack' ), __( 'Click to share on Pinterest', 'jetpack' ), 'share=pinterest', 'sharing-pinterest-' . $post->ID );
1470
		}
1471
1472
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1473
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'linkedin' ) ) {
1474
			sharing_register_post_for_share_counts( $post->ID );
1475
		}
1476
1477
		return $display;
1478
	}
1479
1480
	public function process_request( $post, array $post_data ) {
1481
		// Record stats
1482
		parent::process_request( $post, $post_data );
1483
		// If we're triggering the multi-select panel, then we don't need to redirect to Pinterest
1484
		if ( !isset( $_GET['js_only'] ) ) {
1485
			$pinterest_url = esc_url_raw( $this->get_external_url( $post ) );
1486
			wp_redirect( $pinterest_url );
1487
		} else {
1488
			echo '// share count bumped';
1489
		}
1490
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
1491
	}
1492
1493
	public function display_footer() {
1494
		/**
1495
		 * Filter the Pin it button appearing when hovering over images when using the official button style.
1496
		 *
1497
		 * @module sharedaddy
1498
		 *
1499
		 * @since 3.6.0
1500
		 *
1501
		 * @param bool $jetpack_pinit_over True by default, displays the Pin it button when hovering over images.
1502
		 */
1503
		$jetpack_pinit_over = apply_filters( 'jetpack_pinit_over_button', true );
1504
		?>
1505
		<?php if ( $this->smart ) : ?>
1506
			<script type="text/javascript">
1507
				// Pinterest shared resources
1508
				var s = document.createElement("script");
1509
				s.type = "text/javascript";
1510
				s.async = true;
1511
				<?php if ( $jetpack_pinit_over ) echo "s.setAttribute('data-pin-hover', true);"; ?>
1512
				s.src = window.location.protocol + "//assets.pinterest.com/js/pinit.js";
1513
				var x = document.getElementsByTagName("script")[0];
1514
				x.parentNode.insertBefore(s, x);
1515
				// if 'Pin it' button has 'counts' make container wider
1516
				jQuery(window).load( function(){ jQuery( 'li.share-pinterest a span:visible' ).closest( '.share-pinterest' ).width( '80px' ); } );
1517
			</script>
1518
		<?php elseif ( 'buttonPin' != $this->get_widget_type() ) : ?>
1519
			<script type="text/javascript">
1520
				jQuery(document).ready( function(){
1521
					jQuery('body').on('click', 'a.share-pinterest', function(e){
1522
						e.preventDefault();
1523
						// Load Pinterest Bookmarklet code
1524
						var s = document.createElement("script");
1525
						s.type = "text/javascript";
1526
						s.src = window.location.protocol + "//assets.pinterest.com/js/pinmarklet.js?r=" + ( Math.random() * 99999999 );
1527
						var x = document.getElementsByTagName("script")[0];
1528
						x.parentNode.insertBefore(s, x);
1529
						// Trigger Stats
1530
						var s = document.createElement("script");
1531
						s.type = "text/javascript";
1532
						s.src = this + ( this.toString().indexOf( '?' ) ? '&' : '?' ) + 'js_only=1';
1533
						var x = document.getElementsByTagName("script")[0];
1534
						x.parentNode.insertBefore(s, x);
1535
					});
1536
				});
1537
			</script>
1538
		<?php endif;
1539
	}
1540
}
1541
1542
class Share_Pocket extends Sharing_Source {
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...
1543
	public $shortname = 'pocket';
1544
	public $genericon = '\f224';
1545
1546 View Code Duplication
	public function __construct( $id, array $settings ) {
1547
		parent::__construct( $id, $settings );
1548
1549
		if ( 'official' == $this->button_style )
1550
			$this->smart = true;
1551
		else
1552
			$this->smart = false;
1553
	}
1554
1555
	public function get_name() {
1556
		return __( 'Pocket', 'jetpack' );
1557
	}
1558
1559 View Code Duplication
	public function process_request( $post, array $post_data ) {
1560
		// Record stats
1561
		parent::process_request( $post, $post_data );
1562
1563
		$pocket_url = esc_url_raw( 'https://getpocket.com/save/?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) ) );
1564
		wp_redirect( $pocket_url );
1565
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
1566
	}
1567
1568
	public function get_display( $post ) {
1569
		if ( $this->smart ) {
1570
			$post_count = 'horizontal';
1571
1572
			$button = '';
1573
			$button .= '<div class="pocket_button">';
1574
			$button .= sprintf( '<a href="https://getpocket.com/save" class="pocket-btn" data-lang="%s" data-save-url="%s" data-pocket-count="%s" >%s</a>', 'en', esc_attr( $this->get_share_url( $post->ID ) ), $post_count, esc_attr__( 'Pocket', 'jetpack' ) );
1575
			$button .= '</div>';
1576
1577
			return $button;
1578 View Code Duplication
		} else {
1579
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Pocket', 'share to', 'jetpack' ), __( 'Click to share on Pocket', 'jetpack' ), 'share=pocket' );
1580
		}
1581
1582
	}
1583
1584 View Code Duplication
	function display_footer() {
1585
		if ( $this->smart ) :
1586
		?>
1587
		<script>
1588
		// Don't use Pocket's default JS as it we need to force init new Pocket share buttons loaded via JS.
1589
		function jetpack_sharing_pocket_init() {
1590
			jQuery.getScript( 'https://widgets.getpocket.com/v1/j/btn.js?v=1' );
1591
		}
1592
		jQuery( document ).ready( jetpack_sharing_pocket_init );
1593
		jQuery( document.body ).on( 'post-load', jetpack_sharing_pocket_init );
1594
		</script>
1595
		<?php
1596
		else :
1597
			$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1598
		endif;
1599
1600
	}
1601
1602
}
1603
1604
class Share_Telegram extends Sharing_Source {
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...
1605
	public $shortname = 'telegram';
1606
1607
	public function __construct( $id, array $settings ) {
1608
		parent::__construct( $id, $settings );
1609
	}
1610
1611
	public function get_name() {
1612
		return __( 'Telegram', 'jetpack' );
1613
	}
1614 View Code Duplication
	public function process_request( $post, array $post_data ) {
1615
		// Record stats
1616
		parent::process_request( $post, $post_data );
1617
		$telegram_url = esc_url_raw( 'https://telegram.me/share/url?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&text=' . rawurlencode( $this->get_share_title( $post->ID ) ) );
1618
		wp_redirect( $telegram_url );
1619
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
1620
	}
1621
1622
	public function get_display( $post ) {
1623
		return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Telegram', 'share to', 'jetpack' ), __( 'Click to share on Telegram', 'jetpack' ), 'share=telegram' );
1624
	}
1625
1626
	function display_footer() {
1627
		$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1628
	}
1629
}
1630
1631
class Jetpack_Share_WhatsApp extends Sharing_Source {
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...
1632
	public $shortname = 'jetpack-whatsapp';
1633
1634
	public function __construct( $id, array $settings ) {
1635
		parent::__construct( $id, $settings );
1636
	}
1637
1638
	public function get_name() {
1639
		return __( 'WhatsApp', 'jetpack' );
1640
	}
1641
1642
	public function get_display( $post ) {
1643
		return $this->get_link( 'whatsapp://send?text=' . rawurlencode( $this->get_share_title( $post->ID ) ) . ' ' . rawurlencode( $this->get_share_url( $post->ID ) ), _x( 'WhatsApp', 'share to', 'jetpack' ), __( 'Click to share on WhatsApp', 'jetpack' ) );
1644
	}
1645
}
1646
1647
class Share_Skype extends Sharing_Source {
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...
1648
	public $shortname = 'skype';
1649
	public $genericon = '\f220';
1650
	private $share_type = 'default';
1651
1652 View Code Duplication
	public function __construct( $id, array $settings ) {
1653
		parent::__construct( $id, $settings );
1654
1655
		if ( isset( $settings['share_type'] ) ) {
1656
			$this->share_type = $settings['share_type'];
1657
		}
1658
1659
		if ( 'official' == $this->button_style ) {
1660
			$this->smart = true;
1661
		} else {
1662
			$this->smart = false;
1663
		}
1664
	}
1665
1666
	public function get_name() {
1667
		return __( 'Skype', 'jetpack' );
1668
	}
1669
1670
	public function get_display( $post ) {
1671
		if ( $this->smart ) {
1672
			$skype_share_html = sprintf(
1673
				'<div class="skype-share" data-href="%1$s" data-lang="%2$s" data-style="small" data-source="jetpack" ></div>',
1674
				esc_attr( $this->get_share_url( $post->ID ) ),
1675
				'en-US'
1676
			);
1677
			return $skype_share_html;
1678
		}
1679
1680
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1681
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'skype' ) ) {
1682
			sharing_register_post_for_share_counts( $post->ID );
1683
		}
1684
		return $this->get_link(
1685
			$this->get_process_request_url( $post->ID ), _x( 'Skype', 'share to', 'jetpack' ), __( 'Share on Skype', 'jetpack' ), 'share=skype', 'sharing-skype-' . $post->ID );
1686
	}
1687
1688 View Code Duplication
	public function process_request( $post, array $post_data ) {
1689
		$skype_url = sprintf(
1690
			'https://web.skype.com/share?url=%1$s&lang=%2$s=&source=jetpack',
1691
			rawurlencode( $this->get_share_url( $post->ID ) ),
1692
			'en-US'
1693
		);
1694
1695
		// Record stats
1696
		parent::process_request( $post, $post_data );
1697
1698
		// Redirect to Skype
1699
		wp_redirect( $skype_url );
1700
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method process_request() 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...
1701
	}
1702
1703 View Code Duplication
	public function display_footer() {
1704
		if ( $this->smart ) :
1705
		?>
1706
		<script>
1707
		(function(r, d, s) {
1708
			r.loadSkypeWebSdkAsync = r.loadSkypeWebSdkAsync || function(p) {
1709
				var js, sjs = d.getElementsByTagName(s)[0];
1710
				if (d.getElementById(p.id)) { return; }
1711
				js = d.createElement(s);
1712
				js.id = p.id;
1713
				js.src = p.scriptToLoad;
1714
				js.onload = p.callback
1715
				sjs.parentNode.insertBefore(js, sjs);
1716
			};
1717
			var p = {
1718
				scriptToLoad: 'https://swx.cdn.skype.com/shared/v/latest/skypewebsdk.js',
1719
				id: 'skype_web_sdk'
1720
			};
1721
			r.loadSkypeWebSdkAsync(p);
1722
		})(window, document, 'script');
1723
		</script>
1724
		<?php
1725
		else :
1726
			$this->js_dialog( $this->shortname, array( 'width' => 305, 'height' => 665 ) );
1727
		endif;
1728
	}
1729
}
1730