Completed
Push — sync/module-sharing-rebased ( 34df7a...19446f )
by
unknown
11:01
created

Share_Skype   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 84
Duplicated Lines 29.76 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 1
dl 25
loc 84
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A get_name() 0 3 1
A get_display() 0 17 3
A process_request() 14 14 1
B display_footer() 0 26 2
A __construct() 11 14 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
28
		if ( isset( $settings['smart'] ) ) {
29
			$this->smart = $settings['smart'];
30
		}
31
	}
32
33
	public function http() {
34
		return is_ssl() ? 'https' : 'http';
35
	}
36
37
	public function get_id() {
38
		return $this->id;
39
	}
40
41
	public function get_class() {
42
		return $this->id;
43
	}
44
45
	public function get_share_url( $post_id ) {
46
		/**
47
		 * Filter the sharing permalink.
48
		 *
49
		 * @module sharedaddy
50
		 *
51
		 * @since 1.2.0
52
		 *
53
		 * @param string get_permalink( $post_id ) Post Permalink.
54
		 * @param int $post_id Post ID.
55
		 * @param int $this->id Sharing ID.
56
		 */
57
		return apply_filters( 'sharing_permalink', get_permalink( $post_id ), $post_id, $this->id );
58
	}
59
60
	public function get_share_title( $post_id ) {
61
		$post = get_post( $post_id );
62
		/**
63
		 * Filter the sharing title.
64
		 *
65
		 * @module sharedaddy
66
		 *
67
		 * @since 2.8.0
68
		 *
69
		 * @param string $post->post_title Post Title.
70
		 * @param int $post_id Post ID.
71
		 * @param int $this->id Sharing ID.
72
		 */
73
		$title = apply_filters( 'sharing_title', $post->post_title, $post_id, $this->id );
74
75
		return html_entity_decode( wp_kses( $title, null ) );
76
	}
77
78
	public function has_custom_button_style() {
79
		return false;
80
	}
81
82
	public function get_link( $url, $text, $title, $query = '', $id = false ) {
83
		$args = func_get_args();
84
		$klasses = array( 'share-' . $this->get_class(), 'sd-button' );
85
86
		if ( 'icon' == $this->button_style || 'icon-text' == $this->button_style ) {
87
			$klasses[] = 'share-icon';
88
		}
89
90
		if ( 'icon' == $this->button_style ) {
91
			$text = $title;
92
			$klasses[] = 'no-text';
93
94
			if ( true == $this->open_link_in_new ) {
95
				$text .= __( ' (Opens in new window)', 'jetpack' );
96
			}
97
		}
98
99
		/**
100
		 * Filter the sharing display ID.
101
		 *
102
		 * @module sharedaddy
103
		 *
104
		 * @since 3.4.0
105
		 *
106
		 * @param int|false $id Sharing ID.
107
		 * @param object $this Sharing service properties.
108
		 * @param array $args Array of sharing service options.
109
		 */
110
		$id = apply_filters( 'jetpack_sharing_display_id', $id, $this, $args );
111
		/**
112
		 * Filter the sharing display link.
113
		 *
114
		 * @module sharedaddy
115
		 *
116
		 * @since 2.8.0
117
		 *
118
		 * @param string $url Post URL.
119
		 * @param object $this Sharing service properties.
120
		 * @param int|false $id Sharing ID.
121
		 * @param array $args Array of sharing service options.
122
		 */
123
		$url = apply_filters( 'sharing_display_link', $url, $this, $id, $args ); // backwards compatibility
124
		/**
125
		 * Filter the sharing display link.
126
		 *
127
		 * @module sharedaddy
128
		 *
129
		 * @since 2.8.0
130
		 *
131
		 * @param string $url Post URL.
132
		 * @param object $this Sharing service properties.
133
		 * @param int|false $id Sharing ID.
134
		 * @param array $args Array of sharing service options.
135
		 */
136
		$url = apply_filters( 'jetpack_sharing_display_link', $url, $this, $id, $args );
137
		/**
138
		 * Filter the sharing display query.
139
		 *
140
		 * @module sharedaddy
141
		 *
142
		 * @since 2.8.0
143
		 *
144
		 * @param string $query Sharing service URL parameter.
145
		 * @param object $this Sharing service properties.
146
		 * @param int|false $id Sharing ID.
147
		 * @param array $args Array of sharing service options.
148
		 */
149
		$query = apply_filters( 'jetpack_sharing_display_query', $query, $this, $id, $args );
150
151
		if ( ! empty( $query ) ) {
152
			if ( false === stripos( $url, '?' ) ) {
153
				$url .= '?' . $query;
154
			} else {
155
				$url .= '&amp;' . $query;
156
			}
157
		}
158
159
		if ( 'text' == $this->button_style ) {
160
			$klasses[] = 'no-icon';
161
		}
162
163
		/**
164
		 * Filter the sharing display classes.
165
		 *
166
		 * @module sharedaddy
167
		 *
168
		 * @since 3.4.0
169
		 *
170
		 * @param array $klasses Sharing service classes.
171
		 * @param object $this Sharing service properties.
172
		 * @param int|false $id Sharing ID.
173
		 * @param array $args Array of sharing service options.
174
		 */
175
		$klasses = apply_filters( 'jetpack_sharing_display_classes', $klasses, $this, $id, $args );
176
		/**
177
		 * Filter the sharing display title.
178
		 *
179
		 * @module sharedaddy
180
		 *
181
		 * @since 3.4.0
182
		 *
183
		 * @param string $title Sharing service title.
184
		 * @param object $this Sharing service properties.
185
		 * @param int|false $id Sharing ID.
186
		 * @param array $args Array of sharing service options.
187
		 */
188
		$title = apply_filters( 'jetpack_sharing_display_title', $title, $this, $id, $args );
189
		/**
190
		 * Filter the sharing display text.
191
		 *
192
		 * @module sharedaddy
193
		 *
194
		 * @since 3.4.0
195
		 *
196
		 * @param string $text Sharing service text.
197
		 * @param object $this Sharing service properties.
198
		 * @param int|false $id Sharing ID.
199
		 * @param array $args Array of sharing service options.
200
		 */
201
		$text = apply_filters( 'jetpack_sharing_display_text', $text, $this, $id, $args );
202
203
		return sprintf(
204
			'<a rel="nofollow" data-shared="%s" class="%s" href="%s"%s title="%s"><span%s>%s</span></a>',
205
			( $id ? esc_attr( $id ) : '' ),
206
			implode( ' ', $klasses ),
207
			$url,
208
			( true == $this->open_link_in_new ) ? ' target="_blank"' : '',
209
			$title,
210
			( 'icon' == $this->button_style ) ? '></span><span class="sharing-screen-reader-text"' : '',
211
			$text
212
		);
213
	}
214
215
	/**
216
	 * Get an unfiltered post permalink to use when generating a sharing URL with get_link.
217
	 * Use instead of get_share_url for non-official styles as get_permalink ensures that process_request
218
	 * will be executed more reliably, in the case that the filtered URL uses a service that strips query parameters.
219
	 *
220
	 * @since 3.7.0
221
	 * @param int $post_id Post ID.
222
	 * @uses get_permalink
223
	 * @return string get_permalink( $post_id ) Post permalink.
224
	 */
225
	public function get_process_request_url( $post_id ) {
226
		return get_permalink( $post_id );
227
	}
228
229
	abstract public function get_name();
230
	abstract public function get_display( $post );
231
232
	public function display_header() {
233
	}
234
235
	public function display_footer() {
236
	}
237
238
	public function has_advanced_options() {
239
		return false;
240
	}
241
242
	public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
243
		$text = '&nbsp;';
244
		$button_style = ( ! empty( $button_style ) ) ? $button_style : $this->button_style;
245
		if ( ! $this->smart && ! $force_smart ) {
246
			if ( $button_style != 'icon' ) {
247
				$text = $this->get_name();
248
			}
249
		}
250
251
		$klasses = array( 'share-' . $this->get_class(), 'sd-button' );
252
253
		if ( $button_style == 'icon' || $button_style == 'icon-text' ) {
254
			$klasses[] = 'share-icon';
255
		}
256
257
		if ( $button_style == 'icon' ) {
258
			$klasses[] = 'no-text';
259
		}
260
261
		if ( $button_style == 'text' ) {
262
			$klasses[] = 'no-icon';
263
		}
264
265
		$link = sprintf(
266
			'<a rel="nofollow" class="%s" href="javascript:void(0)" title="%s"><span>%s</span></a>',
267
			implode( ' ', $klasses ),
268
			$this->get_name(),
269
			$text
270
		);
271
272
		$smart = ( $this->smart || $force_smart ) ? 'on' : 'off';
273
		$return = "<div class='option option-smart-$smart'>$link</div>";
274
		if ( $echo ) {
275
			echo $return;
276
		}
277
278
		return $return;
279
	}
280
281 View Code Duplication
	public function get_total( $post = false ) {
282
		global $wpdb, $blog_id;
283
284
		$name = strtolower( $this->get_id() );
285
286
		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...
287
			// get total number of shares for service
288
			return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND share_service = %s', $blog_id, $name ) );
289
		}
290
291
		// get total shares for a post
292
		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 ) );
293
	}
294
295 View Code Duplication
	public function get_posts_total() {
296
		global $wpdb, $blog_id;
297
298
		$totals = array();
299
		$name	= strtolower( $this->get_id() );
300
301
		$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 ) );
302
303
		if ( ! empty( $my_data ) ) {
304
			foreach ( $my_data as $row ) {
305
				$totals[] = new Sharing_Post_Total( $row->id, $row->total );
306
			}
307
		}
308
309
		usort( $totals, array( 'Sharing_Post_Total', 'cmp' ) );
310
311
		return $totals;
312
	}
313
314
	public function process_request( $post, array $post_data ) {
315
		/**
316
		 * Fires when a post is shared via one of the sharing buttons.
317
		 *
318
		 * @module sharedaddy
319
		 *
320
		 * @since 1.1.0
321
		 *
322
		 * @param array $args Aray of information about the sharing service.
323
		 */
324
		do_action( 'sharing_bump_stats', array( 'service' => $this, 'post' => $post ) );
325
	}
326
327
	public function js_dialog( $name, $params = array() ) {
328
		if ( true !== $this->open_link_in_new ) {
329
			return;
330
		}
331
332
		$defaults = array(
333
			'menubar'	=> 1,
334
			'resizable' => 1,
335
			'width'		=> 600,
336
			'height'	=> 400,
337
		);
338
		$params = array_merge( $defaults, $params );
339
		$opts = array();
340
		foreach ( $params as $key => $val ) {
341
			$opts[] = "$key=$val";
342
		}
343
		$opts = implode( ',', $opts );
344
345
		// Add JS after sharing-js has been enqueued.
346
		wp_add_inline_script( 'sharing-js',
347
			"var windowOpen;
348
			jQuery( document.body ).on( 'click', 'a.share-$name', function() {
349
				// If there's another sharing window open, close it.
350
				if ( 'undefined' !== typeof windowOpen ) {
351
					windowOpen.close();
352
				}
353
				windowOpen = window.open( jQuery( this ).attr( 'href' ), 'wpcom$name', '$opts' );
354
				return false;
355
			});"
356
		);
357
	}
358
}
359
360
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...
361
	public function has_advanced_options() {
362
		return true;
363
	}
364
365
	abstract public function display_options();
366
	abstract public function update_options( array $data );
367
	abstract public function get_options();
368
}
369
370
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...
371
	public $shortname = 'email';
372
	public $icon = '\f410';
373 View Code Duplication
	public function __construct( $id, array $settings ) {
374
		parent::__construct( $id, $settings );
375
376
		if ( 'official' == $this->button_style ) {
377
			$this->smart = true;
378
		} else {
379
			$this->smart = false;
380
		}
381
	}
382
383
	public function get_name() {
384
		return _x( 'Email', 'as sharing source', 'jetpack' );
385
	}
386
387
	// Default does nothing
388
	public function process_request( $post, array $post_data ) {
389
		$ajax = false;
390
		if ( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) == 'xmlhttprequest' ) {
391
			$ajax = true;
392
		}
393
394
		$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...
395
396
		if ( isset( $post_data['source_email'] ) && is_email( $post_data['source_email'] ) ) {
397
			$source_email = $post_data['source_email'];
398
		}
399
400
		if ( isset( $post_data['target_email'] ) && is_email( $post_data['target_email'] ) ) {
401
			$target_email = $post_data['target_email'];
402
		}
403
404
		if ( isset( $post_data['source_name'] ) && strlen( $post_data['source_name'] ) < 200 ) {
405
			$source_name = $post_data['source_name'];
406
		} elseif ( isset( $post_data['source_name'] ) ) {
407
			$source_name = substr( $post_data['source_name'], 0, 200 );
408
		} else {
409
			$source_name = '';
410
		}
411
412
		// Test email
413
		$error = 1;	  // Failure in data
414
		if ( empty( $post_data['source_f_name'] ) && $source_email && $target_email && $source_name ) {
415
			/**
416
			 * Allow plugins to stop the email sharing button from running the shared message through Akismet.
417
			 *
418
			 * @module sharedaddy
419
			 *
420
			 * @since 1.1.0
421
			 *
422
			 * @param bool true Should we check if the message isn't spam?
423
			 * @param object $post Post information.
424
			 * @param array $post_data Information about the shared message.
425
			 */
426
			if ( apply_filters( 'sharing_email_check', true, $post, $post_data ) ) {
427
				$data = array(
428
					'post'           => $post,
429
					'source'         => $source_email,
430
					'target'         => $target_email,
431
					'name'           => $source_name,
432
					'sharing_source' => $this,
433
				);
434
				// 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...
435
				/**
436
				 * Filter whether an email can be sent from the Email sharing button.
437
				 *
438
				 * @module sharedaddy
439
				 *
440
				 * @since 1.1.0
441
				 *
442
				 * @param array $data Array of information about the shared message.
443
				 */
444
				if ( ( $data = apply_filters( 'sharing_email_can_send', $data ) ) !== false ) {
445
					// Record stats
446
					parent::process_request( $data['post'], $post_data );
447
448
					/**
449
					 * Fires when an email is sent via the Email sharing button.
450
					 *
451
					 * @module sharedaddy
452
					 *
453
					 * @since 1.1.0
454
					 *
455
					 * @param array $data Array of information about the shared message.
456
					 */
457
					do_action( 'sharing_email_send_post', $data );
458
				}
459
460
				// Return a positive regardless of whether the user is subscribed or not
461
				if ( $ajax ) {
462
?>
463
<div class="response">
464
	<div class="response-title"><?php _e( 'This post has been shared!', 'jetpack' ); ?></div>
465
	<div class="response-sub"><?php printf( __( 'You have shared this post with %s', 'jetpack' ), esc_html( $target_email ) ); ?></div>
466
	<div class="response-close"><a href="#" class="sharing_cancel"><?php _e( 'Close', 'jetpack' ); ?></a></div>
467
</div>
468
<?php
469
				} else {
470
					wp_safe_redirect( get_permalink( $post->ID ) . '?shared=email' );
471
				}
472
473
				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...
474
			} else {
475
				$error = 2;	  // Email check failed
476
			}
477
		}
478
479
		if ( $ajax ) {
480
			echo $error;
481
		} else {
482
			wp_safe_redirect( get_permalink( $post->ID ) . '?shared=email&msg=fail' );
483
		}
484
485
		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...
486
	}
487
488
	public function get_display( $post ) {
489
		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' );
490
	}
491
492
	/**
493
	 * Outputs the hidden email dialog
494
	 */
495
	public function display_footer() {
496
		global $current_user;
497
498
		$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...
499
?>
500
	<div id="sharing_email" style="display: none;">
501
		<form action="<?php echo esc_url( $_SERVER['REQUEST_URI'] ); ?>" method="post">
502
			<label for="target_email"><?php _e( 'Send to Email Address', 'jetpack' ) ?></label>
503
			<input type="email" name="target_email" id="target_email" value="" />
504
505
			<?php if ( is_user_logged_in() ) : ?>
506
				<input type="hidden" name="source_name" value="<?php echo esc_attr( $current_user->display_name ); ?>" />
507
				<input type="hidden" name="source_email" value="<?php echo esc_attr( $current_user->user_email ); ?>" />
508
			<?php else : ?>
509
510
				<label for="source_name"><?php _e( 'Your Name', 'jetpack' ) ?></label>
511
				<input type="text" name="source_name" id="source_name" value="" />
512
513
				<label for="source_email"><?php _e( 'Your Email Address', 'jetpack' ) ?></label>
514
				<input type="email" name="source_email" id="source_email" value="" />
515
516
			<?php endif; ?>
517
			<input type="text" id="jetpack-source_f_name" name="source_f_name" class="input" value="" size="25" autocomplete="off" title="<?php esc_attr_e( 'This field is for validation and should not be changed', 'jetpack' ); ?>" />
518
			<?php
519
				/**
520
				 * Fires when the Email sharing dialog is loaded.
521
				 *
522
				 * @module sharedaddy
523
				 *
524
				 * @since 1.1.0
525
				 *
526
				 * @param string jetpack Eail sharing source.
527
				 */
528
				do_action( 'sharing_email_dialog', 'jetpack' );
529
			?>
530
531
			<img style="float: right; display: none" class="loading" src="<?php
532
			/** This filter is documented in modules/stats.php */
533
			echo apply_filters( 'jetpack_static_url', plugin_dir_url( __FILE__ ) . 'images/loading.gif' ); ?>" alt="loading" width="16" height="16" />
534
			<input type="submit" value="<?php esc_attr_e( 'Send Email', 'jetpack' ); ?>" class="sharing_send" />
535
			<a rel="nofollow" href="#cancel" class="sharing_cancel"><?php _e( 'Cancel', 'jetpack' ); ?></a>
536
537
			<div class="errors errors-1" style="display: none;">
538
				<?php _e( 'Post was not sent - check your email addresses!', 'jetpack' ); ?>
539
			</div>
540
541
			<div class="errors errors-2" style="display: none;">
542
				<?php _e( 'Email check failed, please try again', 'jetpack' ); ?>
543
			</div>
544
545
			<div class="errors errors-3" style="display: none;">
546
				<?php _e( 'Sorry, your blog cannot share posts by email.', 'jetpack' ); ?>
547
			</div>
548
		</form>
549
	</div>
550
<?php
551
	}
552
}
553
554
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...
555
	public $shortname = 'twitter';
556
	public $icon = '\f202';
557
	// 'https://dev.twitter.com/rest/reference/get/help/configuration' ( 2015/02/06 ) short_url_length is 22, short_url_length_https is 23
558
	public $short_url_length = 24;
559
560 View Code Duplication
	public function __construct( $id, array $settings ) {
561
		parent::__construct( $id, $settings );
562
563
		if ( 'official' == $this->button_style ) {
564
			$this->smart = true;
565
		} else {
566
			$this->smart = false;
567
		}
568
	}
569
570
	public function get_name() {
571
		return __( 'Twitter', 'jetpack' );
572
	}
573
574
	function sharing_twitter_via( $post ) {
575
		/**
576
		 * Allow third-party plugins to customize the Twitter username used as "twitter:site" Twitter Card Meta Tag.
577
		 *
578
		 * @module sharedaddy
579
		 *
580
		 * @since 3.0.0
581
		 *
582
		 * @param string $string Twitter Username.
583
		 * @param array $args Array of Open Graph Meta Tags and Twitter Cards tags.
584
		 */
585
		$twitter_site_tag_value = apply_filters( 'jetpack_twitter_cards_site_tag', '', array() );
586
587
		/*
588
		 * Hack to remove the unwanted behavior of adding 'via @jetpack' which
589
		 * was introduced with the adding of the Twitter cards.
590
		 * This should be a temporary solution until a better method is setup.
591
		 */
592
		if ( 'jetpack' == $twitter_site_tag_value ) {
593
			$twitter_site_tag_value = '';
594
		}
595
596
		/**
597
		 * Filters the Twitter username used as "via" in the Twitter sharing button.
598
		 *
599
		 * @module sharedaddy
600
		 *
601
		 * @since 1.7.0
602
		 *
603
		 * @param string $twitter_site_tag_value Twitter Username.
604
		 * @param int $post->ID Post ID.
605
		 */
606
		$twitter_site_tag_value = apply_filters( 'jetpack_sharing_twitter_via', $twitter_site_tag_value, $post->ID );
607
608
		// Strip out anything other than a letter, number, or underscore.
609
		// This will prevent the inadvertent inclusion of an extra @, as well as normalizing the handle.
610
		return preg_replace( '/[^\da-z_]+/i', '', $twitter_site_tag_value );
611
	}
612
613
	public function get_related_accounts( $post ) {
614
		/**
615
		 * Filter the list of related Twitter accounts added to the Twitter sharing button.
616
		 *
617
		 * @module sharedaddy
618
		 *
619
		 * @since 1.7.0
620
		 *
621
		 * @param array $args Array of Twitter usernames. Format is 'username' => 'Optional description'
622
		 * @param int $post->ID Post ID.
623
		 */
624
		$related_accounts = apply_filters( 'jetpack_sharing_twitter_related', array(), $post->ID );
625
626
		// Example related string: account1,account2:Account 2 description,account3
627
		$related = array();
628
629
		foreach ( $related_accounts as $related_account_username => $related_account_description ) {
630
			// Join the description onto the end of the username
631
			if ( $related_account_description ) {
632
				$related_account_username .= ':' . $related_account_description;
633
			}
634
635
			$related[] = $related_account_username;
636
		}
637
638
		return implode( ',', $related );
639
	}
640
641
	public function get_display( $post ) {
642
		$via = $this->sharing_twitter_via( $post );
643
644
		if ( $via ) {
645
			$via = 'data-via="' . esc_attr( $via ) . '"';
646
		} else {
647
			$via = '';
648
		}
649
650
		$related = $this->get_related_accounts( $post );
651
		if ( ! empty( $related ) && $related !== $via ) {
652
			$related = 'data-related="' . esc_attr( $related ) . '"';
653
		} else {
654
			$related = '';
655
		}
656
657
		if ( $this->smart ) {
658
			$share_url = $this->get_share_url( $post->ID );
659
			$post_title = $this->get_share_title( $post->ID );
660
			return sprintf(
661
				'<a href="https://twitter.com/share" class="twitter-share-button" data-url="%1$s" data-text="%2$s" %3$s %4$s>Tweet</a>',
662
				esc_url( $share_url ),
663
				esc_attr( $post_title ),
664
				$via,
665
				$related
666
			);
667
		} else {
668
			if (
669
				/**
670
				 * Allow plugins to disable sharing counts for specific sharing services.
671
				 *
672
				 * @module sharedaddy
673
				 *
674
				 * @since 3.0.0
675
				 *
676
				 * @param bool true Should sharing counts be enabled for this specific service. Default to true.
677
				 * @param int $post->ID Post ID.
678
				 * @param string $str Sharing service name.
679
				 */
680
				apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'twitter' )
681
			) {
682
				sharing_register_post_for_share_counts( $post->ID );
683
			}
684
			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 );
685
		}
686
	}
687
688
	public function process_request( $post, array $post_data ) {
689
		$post_title = $this->get_share_title( $post->ID );
690
		$post_link = $this->get_share_url( $post->ID );
691
692
		if ( function_exists( 'mb_stripos' ) ) {
693
			$strlen = 'mb_strlen';
694
			$substr = 'mb_substr';
695
		} else {
696
			$strlen = 'strlen';
697
			$substr = 'substr';
698
		}
699
700
		$via = $this->sharing_twitter_via( $post );
701
		$related = $this->get_related_accounts( $post );
702
		if ( $via ) {
703
			$sig = " via @$via";
704
			if ( $related === $via ) {
705
				$related = false;
706
			}
707
		} else {
708
			$via = false;
709
			$sig = '';
710
		}
711
712
		$suffix_length = $this->short_url_length + $strlen( $sig );
713
		// $sig is handled by twitter in their 'via' argument.
714
		// $post_link is handled by twitter in their 'url' argument.
715
		if ( 280 < $strlen( $post_title ) + $suffix_length ) {
716
			// The -1 is for "\xE2\x80\xA6", a UTF-8 ellipsis.
717
			$text = $substr( $post_title, 0, 280 - $suffix_length - 1 ) . "\xE2\x80\xA6";
718
		} else {
719
			$text = $post_title;
720
		}
721
722
		// Record stats
723
		parent::process_request( $post, $post_data );
724
725
		$url = $post_link;
726
		$twitter_url = add_query_arg(
727
			rawurlencode_deep( array_filter( compact( 'via', 'related', 'text', 'url' ) ) ),
728
			'https://twitter.com/intent/tweet'
729
		);
730
731
		// Redirect to Twitter
732
		wp_redirect( $twitter_url );
733
		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...
734
	}
735
736
	public function has_custom_button_style() {
737
		return $this->smart;
738
	}
739
740
	public function display_footer() {
741
		if ( $this->smart ) {
742
			?>
743
			<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>
744
			<?php
745
		} else {
746
			$this->js_dialog( $this->shortname, array( 'height' => 350 ) );
747
		}
748
	}
749
}
750
751
752
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...
753
	public $shortname = 'reddit';
754
	public $icon = '\f222';
755 View Code Duplication
	public function __construct( $id, array $settings ) {
756
		parent::__construct( $id, $settings );
757
758
		if ( 'official' == $this->button_style ) {
759
			$this->smart = true;
760
		} else {
761
			$this->smart = false;
762
		}
763
	}
764
765
	public function get_name() {
766
		return __( 'Reddit', 'jetpack' );
767
	}
768
769
	public function get_display( $post ) {
770
		if ( $this->smart ) {
771
			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>';
772 View Code Duplication
		} else {
773
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Reddit', 'share to', 'jetpack' ), __( 'Click to share on Reddit', 'jetpack' ), 'share=reddit' );
774
		}
775
	}
776
777 View Code Duplication
	public function process_request( $post, array $post_data ) {
778
		$reddit_url = $this->http() . '://reddit.com/submit?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) );
779
780
		// Record stats
781
		parent::process_request( $post, $post_data );
782
783
		// Redirect to Reddit
784
		wp_redirect( $reddit_url );
785
		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...
786
	}
787
}
788
789
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...
790
	public $shortname = 'linkedin';
791
	public $icon = '\f207';
792 View Code Duplication
	public function __construct( $id, array $settings ) {
793
		parent::__construct( $id, $settings );
794
795
		if ( 'official' == $this->button_style ) {
796
			$this->smart = true;
797
		} else {
798
			$this->smart = false;
799
		}
800
	}
801
802
	public function get_name() {
803
		return __( 'LinkedIn', 'jetpack' );
804
	}
805
806
	public function has_custom_button_style() {
807
		return $this->smart;
808
	}
809
810
	public function get_display( $post ) {
811
		$display = '';
812
813
		if ( $this->smart ) {
814
			$share_url = $this->get_share_url( $post->ID );
815
			$display .= sprintf( '<div class="linkedin_button"><script type="in/share" data-url="%s" data-counter="right"></script></div>', esc_url( $share_url ) );
816 View Code Duplication
		} else {
817
			$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 );
818
		}
819
820
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
821
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'linkedin' ) ) {
822
			sharing_register_post_for_share_counts( $post->ID );
823
		}
824
825
		return $display;
826
	}
827
828 View Code Duplication
	public function process_request( $post, array $post_data ) {
829
830
		$post_link = $this->get_share_url( $post->ID );
831
832
		// Using the same URL as the official button, which is *not* LinkedIn's documented sharing link
833
		// https://www.linkedin.com/cws/share?url={url}&token=&isFramed=false
834
		$linkedin_url = add_query_arg( array(
835
			'url' => rawurlencode( $post_link ),
836
		), 'https://www.linkedin.com/cws/share?token=&isFramed=false' );
837
838
		// Record stats
839
		parent::process_request( $post, $post_data );
840
841
		// Redirect to LinkedIn
842
		wp_redirect( $linkedin_url );
843
		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...
844
	}
845
846 View Code Duplication
	public function display_footer() {
847
		if ( ! $this->smart ) {
848
			$this->js_dialog( $this->shortname, array( 'width' => 580, 'height' => 450 ) );
849
		} else {
850
			?><script type="text/javascript">
851
			jQuery( document ).ready( function() {
852
				jQuery.getScript( 'https://platform.linkedin.com/in.js?async=true', function success() {
853
					IN.init();
854
				});
855
			});
856
			jQuery( document.body ).on( 'post-load', function() {
857
				if ( typeof IN != 'undefined' )
858
					IN.parse();
859
			});
860
			</script><?php
861
		}
862
	}
863
}
864
865
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...
866
	public $shortname = 'facebook';
867
	public $icon = '\f204';
868
	private $share_type = 'default';
869
870 View Code Duplication
	public function __construct( $id, array $settings ) {
871
		parent::__construct( $id, $settings );
872
873
		if ( isset( $settings['share_type'] ) ) {
874
			$this->share_type = $settings['share_type'];
875
		}
876
877
		if ( 'official' == $this->button_style ) {
878
			$this->smart = true;
879
		} else {
880
			$this->smart = false;
881
		}
882
	}
883
884
	public function get_name() {
885
		return __( 'Facebook', 'jetpack' );
886
	}
887
888
	public function display_header() {
889
	}
890
891
	function guess_locale_from_lang( $lang ) {
892
		if ( 'en' == $lang || 'en_US' == $lang || ! $lang ) {
893
			return 'en_US';
894
		}
895
896 View Code Duplication
		if ( ! class_exists( 'GP_Locales' ) ) {
897
			if ( ! defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) || ! file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) {
898
				return false;
899
			}
900
901
			require JETPACK__GLOTPRESS_LOCALES_PATH;
902
		}
903
904
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
905
			// WP.com: get_locale() returns 'it'
906
			$locale = GP_Locales::by_slug( $lang );
907
		} else {
908
			// Jetpack: get_locale() returns 'it_IT';
909
			$locale = GP_Locales::by_field( 'wp_locale', $lang );
910
		}
911
912
		if ( ! $locale ) {
913
			return false;
914
		}
915
916
		if ( empty( $locale->facebook_locale ) ) {
917
			if ( empty( $locale->wp_locale ) ) {
918
				return false;
919
			} else {
920
				// Facebook SDK is smart enough to fall back to en_US if a
921
				// locale isn't supported. Since supported Facebook locales
922
				// can fall out of sync, we'll attempt to use the known
923
				// wp_locale value and rely on said fallback.
924
				return $locale->wp_locale;
925
			}
926
		}
927
928
		return $locale->facebook_locale;
929
	}
930
931
	public function get_display( $post ) {
932
		if ( $this->smart ) {
933
			$share_url = $this->get_share_url( $post->ID );
934
			$fb_share_html = '<div class="fb-share-button" data-href="' . esc_attr( $share_url ) . '" data-layout="button_count"></div>';
935
			/**
936
			 * Filter the output of the Facebook Sharing button.
937
			 *
938
			 * @module sharedaddy
939
			 *
940
			 * @since 3.6.0
941
			 *
942
			 * @param string $fb_share_html Facebook Sharing button HTML.
943
			 * @param string $share_url URL of the post to share.
944
			 */
945
			return apply_filters( 'jetpack_sharing_facebook_official_button_output', $fb_share_html, $share_url );
946
		}
947
948
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
949
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'facebook' ) ) {
950
			sharing_register_post_for_share_counts( $post->ID );
951
		}
952
		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 );
953
	}
954
955 View Code Duplication
	public function process_request( $post, array $post_data ) {
956
		$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 ) );
957
958
		// Record stats
959
		parent::process_request( $post, $post_data );
960
961
		// Redirect to Facebook
962
		wp_redirect( $fb_url );
963
		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...
964
	}
965
966
	public function display_footer() {
967
		$this->js_dialog( $this->shortname );
968
		if ( $this->smart ) {
969
			$locale = $this->guess_locale_from_lang( get_locale() );
970
			if ( ! $locale ) {
971
				$locale = 'en_US';
972
			}
973
			/**
974
			 * Filter the App ID used in the official Facebook Share button.
975
			 *
976
			 * @since 3.8.0
977
			 *
978
			 * @param int $fb_app_id Facebook App ID. Default to 249643311490 (WordPress.com's App ID).
979
			 */
980
			$fb_app_id = apply_filters( 'jetpack_sharing_facebook_app_id', '249643311490' );
981
			if ( is_numeric( $fb_app_id ) ) {
982
				$fb_app_id = '&appId=' . $fb_app_id;
983
			} else {
984
				$fb_app_id = '';
985
			}
986
			?><div id="fb-root"></div>
987
			<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>
988
			<script>
989
			jQuery( document.body ).on( 'post-load', function() {
990
				if ( 'undefined' !== typeof FB ) {
991
					FB.XFBML.parse();
992
				}
993
			} );
994
			</script>
995
			<?php
996
		}
997
	}
998
}
999
1000
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...
1001
	public $shortname = 'print';
1002
	public $icon = '\f469';
1003 View Code Duplication
	public function __construct( $id, array $settings ) {
1004
		parent::__construct( $id, $settings );
1005
1006
		if ( 'official' == $this->button_style ) {
1007
			$this->smart = true;
1008
		} else {
1009
			$this->smart = false;
1010
		}
1011
	}
1012
1013
	public function get_name() {
1014
		return __( 'Print', 'jetpack' );
1015
	}
1016
1017
	public function get_display( $post ) {
1018
		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' ) );
1019
	}
1020
}
1021
1022
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...
1023
	public $shortname = 'pressthis';
1024
	public $icon = '\f205';
1025 View Code Duplication
	public function __construct( $id, array $settings ) {
1026
		parent::__construct( $id, $settings );
1027
1028
		if ( 'official' == $this->button_style ) {
1029
			$this->smart = true;
1030
		} else {
1031
			$this->smart = false;
1032
		}
1033
	}
1034
1035
	public function get_name() {
1036
		return __( 'Press This', 'jetpack' );
1037
	}
1038
1039
	public function process_request( $post, array $post_data ) {
1040
		global $current_user, $wp_version;
1041
1042
		$primary_blog = (int) get_user_meta( $current_user->ID, 'primary_blog', true );
1043
		if ( $primary_blog ) {
1044
			$primary_blog_details = get_blog_details( $primary_blog );
1045
		} else {
1046
			$primary_blog_details = false;
1047
		}
1048
1049
		if ( $primary_blog_details ) {
1050
			$blogs = array( $primary_blog_details );
1051
		} elseif ( function_exists( 'get_active_blogs_for_user' ) ) {
1052
			$blogs = get_active_blogs_for_user();
1053
			if ( empty( $blogs ) ) {
1054
				$blogs = get_blogs_of_user( $current_user->ID );
1055
			}
1056
		} else {
1057
			$blogs = get_blogs_of_user( $current_user->ID );
1058
		}
1059
1060
		if ( empty( $blogs ) ) {
1061
			wp_safe_redirect( get_permalink( $post->ID ) );
1062
			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...
1063
		}
1064
1065
		$blog = current( $blogs );
1066
1067
		$args = array(
1068
			'u' => rawurlencode( $this->get_share_url( $post->ID ) ),
1069
			);
1070
1071
		if ( version_compare( $wp_version, '4.9-RC1-42107', '>=' ) ) {
1072
			$args[ 'url-scan-submit' ] = 'Scan';
1073
			$args[ '_wpnonce' ]        = wp_create_nonce( 'scan-site' );
1074
1075
		} else { // Remove once 4.9 is the minimum.
1076
			$args['t'] = rawurlencode( $this->get_share_title( $post->ID ) );
1077
			if ( isset( $_GET['sel'] ) ) {
1078
				$args['s'] = rawurlencode( $_GET['sel'] );
1079
			}
1080
		}
1081
1082
		$url = $blog->siteurl . '/wp-admin/press-this.php';
1083
		$url = add_query_arg( $args, $url );
1084
1085
		// Record stats
1086
		parent::process_request( $post, $post_data );
1087
1088
		// Redirect to Press This
1089
		wp_redirect( $url );
1090
		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...
1091
	}
1092
1093
	public function get_display( $post ) {
1094
		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' );
1095
	}
1096
}
1097
1098
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...
1099
	public $shortname = 'googleplus1';
1100
	public $icon = '\f218';
1101
	private $state = false;
1102
1103 View Code Duplication
	public function __construct( $id, array $settings ) {
1104
		parent::__construct( $id, $settings );
1105
1106
		if ( 'official' == $this->button_style ) {
1107
			$this->smart = true;
1108
		} else {
1109
			$this->smart = false;
1110
		}
1111
	}
1112
1113
	public function get_name() {
1114
		return __( 'Google', 'jetpack' );
1115
	}
1116
1117
	public function has_custom_button_style() {
1118
		return $this->smart;
1119
	}
1120
1121
	public function get_display( $post ) {
1122
1123
		if ( $this->smart ) {
1124
			$share_url = $this->get_share_url( $post->ID );
1125
			return '<div class="googleplus1_button"><div class="g-plus" data-action="share" data-annotation="bubble" data-href="' . esc_url( $share_url ) . '"></div></div>';
1126 View Code Duplication
		} else {
1127
			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 );
1128
		}
1129
	}
1130
1131
	public function get_state() {
1132
		return $this->state;
1133
	}
1134
1135
	public function process_request( $post, array $post_data ) {
1136
1137
		if ( isset( $post_data['state'] ) ) {
1138
			$this->state = $post_data['state'];
1139
		}
1140
		// Record stats
1141
		parent::process_request( $post, $post_data );
1142
1143
		// Redirect to Google +'s sharing endpoint
1144
		$url = 'https://plus.google.com/share?url=' . rawurlencode( $this->get_share_url( $post->ID ) );
1145
		wp_redirect( $url );
1146
		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...
1147
	}
1148
1149 View Code Duplication
	public function display_footer() {
1150
		global $post;
1151
1152
		if ( $this->smart ) { ?>
1153
			<script>
1154
			function renderGooglePlus1() {
1155
				if ( 'undefined' === typeof gapi ) {
1156
					return;
1157
				}
1158
1159
				jQuery( '.g-plus' ).each(function() {
1160
					var $button = jQuery( this );
1161
1162
					if ( ! $button.data( 'gplus-rendered' ) ) {
1163
						gapi.plusone.render( this, {
1164
							href: $button.attr( 'data-href' ),
1165
							size: $button.attr( 'data-size' ),
1166
							annotation: $button.attr( 'data-annotation' )
1167
						});
1168
1169
						$button.data( 'gplus-rendered', true );
1170
					}
1171
				});
1172
			}
1173
1174
			(function() {
1175
				var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
1176
				po.src = 'https://apis.google.com/js/platform.js';
1177
				po.innerHTML = '{"parsetags": "explicit"}';
1178
				po.onload = renderGooglePlus1;
1179
				var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
1180
			})();
1181
1182
			jQuery( document.body ).on( 'post-load', renderGooglePlus1 );
1183
			</script>
1184
			<?php
1185
		} else {
1186
			$this->js_dialog( 'google-plus-1', array( 'width' => 480, 'height' => 550 ) );
1187
		}
1188
	}
1189
1190 View Code Duplication
	public function get_total( $post = false ) {
1191
		global $wpdb, $blog_id;
1192
1193
		$name = strtolower( $this->get_id() );
1194
1195
		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...
1196
			// get total number of shares for service
1197
			return $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND share_service = %s', $blog_id, $name ) );
1198
		}
1199
1200
		// get total shares for a post
1201
		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 ) );
1202
	}
1203
}
1204
1205
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...
1206
	private $name;
1207
	private $icon;
1208
	private $url;
1209
	public $smart = true;
1210
	public $shortname;
1211
1212
	public function get_class() {
1213
		return 'custom share-custom-' . sanitize_html_class( strtolower( $this->name ) );
1214
	}
1215
1216
	public function __construct( $id, array $settings ) {
1217
		parent::__construct( $id, $settings );
1218
1219
		$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...
1220
1221
		if ( isset( $settings['name'] ) ) {
1222
			$this->name = $settings['name'];
1223
			$this->shortname = preg_replace( '/[^a-z0-9]*/', '', $settings['name'] );
1224
		}
1225
1226
		if ( isset( $settings['icon'] ) ) {
1227
			$this->icon = $settings['icon'];
1228
1229
			$new_icon = esc_url_raw( wp_specialchars_decode( $this->icon, ENT_QUOTES ) );
1230
			$i = 0;
1231
			while ( $new_icon != $this->icon ) {
1232
				if ( $i > 5 ) {
1233
					$this->icon = false;
1234
					break;
1235
				} else {
1236
					$this->icon = $new_icon;
1237
					$new_icon = esc_url_raw( wp_specialchars_decode( $this->icon, ENT_QUOTES ) );
1238
				}
1239
				$i++;
1240
			}
1241
		}
1242
1243
		if ( isset( $settings['url'] ) ) {
1244
			$this->url = $settings['url'];
1245
		}
1246
	}
1247
1248
	public function get_name() {
1249
		return $this->name;
1250
	}
1251
1252
	public function get_display( $post ) {
1253
		$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 );
1254
		return str_replace( '<span>', '<span style="' . esc_attr( 'background-image:url("' . addcslashes( esc_url_raw( $this->icon ), '"' ) . '");' ) . '">', $str );
1255
	}
1256
1257
	public function process_request( $post, array $post_data ) {
1258
		$url = str_replace( '&amp;', '&', $this->url );
1259
		$url = str_replace( '%post_id%', rawurlencode( $post->ID ), $url );
1260
		$url = str_replace( '%post_url%', rawurlencode( $this->get_share_url( $post->ID ) ), $url );
1261
		$url = str_replace( '%post_full_url%', rawurlencode( get_permalink( $post->ID ) ), $url );
1262
		$url = str_replace( '%post_title%', rawurlencode( $this->get_share_title( $post->ID ) ), $url );
1263
		$url = str_replace( '%home_url%', rawurlencode( home_url() ), $url );
1264
		$url = str_replace( '%post_slug%', rawurlencode( $post->post_name ), $url );
1265
1266
		if ( strpos( $url, '%post_tags%' ) !== false ) {
1267
			$tags	= get_the_tags( $post->ID );
1268
			$tagged = '';
1269
1270
			if ( $tags ) {
1271
				$tagged_raw = array();
1272
				foreach ( $tags as $tag ) {
1273
					$tagged_raw[] = rawurlencode( $tag->name );
1274
				}
1275
1276
				$tagged = implode( ',', $tagged_raw );
1277
			}
1278
1279
			$url = str_replace( '%post_tags%', $tagged, $url );
1280
		}
1281
1282
		if ( strpos( $url, '%post_excerpt%' ) !== false ) {
1283
			$url_excerpt = $post->post_excerpt;
1284
			if ( empty( $url_excerpt ) ) {
1285
				$url_excerpt = $post->post_content;
1286
			}
1287
1288
			$url_excerpt = strip_tags( strip_shortcodes( $url_excerpt ) );
1289
			$url_excerpt = wp_html_excerpt( $url_excerpt, 100 );
1290
			$url_excerpt = rtrim( preg_replace( '/[^ .]*$/', '', $url_excerpt ) );
1291
			$url = str_replace( '%post_excerpt%', rawurlencode( $url_excerpt ), $url );
1292
		}
1293
1294
		// Record stats
1295
		parent::process_request( $post, $post_data );
1296
1297
		// Redirect
1298
		wp_redirect( $url );
1299
		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...
1300
	}
1301
1302
	public function display_options() {
1303
?>
1304
<div class="input">
1305
	<table class="form-table">
1306
		<tbody>
1307
			<tr>
1308
				<th scope="row"><?php _e( 'Label', 'jetpack' ); ?></th>
1309
				<td><input type="text" name="name" value="<?php echo esc_attr( $this->name ); ?>" /></td>
1310
			</tr>
1311
1312
			<tr>
1313
				<th scope="row"><?php _e( 'URL', 'jetpack' ); ?></th>
1314
				<td><input type="text" name="url" value="<?php echo esc_attr( $this->url ); ?>" /></td>
1315
			</tr>
1316
1317
			<tr>
1318
				<th scope="row"><?php _e( 'Icon', 'jetpack' ); ?></th>
1319
				<td><input type="text" name="icon" value="<?php echo esc_attr( $this->icon ); ?>" /></td>
1320
			</tr>
1321
1322
			<tr>
1323
				<th scope="row"></th>
1324
				<td>
1325
					<input class="button-secondary" type="submit" value="<?php esc_attr_e( 'Save', 'jetpack' ); ?>" />
1326
					<a href="#" class="remove"><small><?php _e( 'Remove Service', 'jetpack' ); ?></small></a>
1327
				</td>
1328
			</tr>
1329
		</tbody>
1330
	</table>
1331
</div>
1332
<?php
1333
	}
1334
1335
	public function update_options( array $data ) {
1336
		$name  = trim( wp_html_excerpt( wp_kses( stripslashes( $data['name'] ), array() ), 30 ) );
1337
		$url   = trim( esc_url_raw( $data['url'] ) );
1338
		$icon  = trim( esc_url_raw( $data['icon'] ) );
1339
1340
		if ( $name ) {
1341
			$this->name = $name;
1342
		}
1343
1344
		if ( $url ) {
1345
			$this->url	= $url;
1346
		}
1347
1348
		if ( $icon ) {
1349
			$this->icon = $icon;
1350
		}
1351
	}
1352
1353
	public function get_options() {
1354
		return array(
1355
			'name' => $this->name,
1356
			'icon' => $this->icon,
1357
			'url'  => $this->url,
1358
		);
1359
	}
1360
1361
	public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
1362
		$opts = $this->get_options();
1363
1364
		$text = '&nbsp;';
1365
		if ( ! $this->smart ) {
1366
			if ( $this->button_style != 'icon' ) {
1367
				$text = $this->get_name();
1368
			}
1369
		}
1370
1371
		$klasses = array( 'share-' . $this->shortname );
1372
1373
		if ( $this->button_style == 'icon' || $this->button_style == 'icon-text' ) {
1374
			$klasses[] = 'share-icon';
1375
		}
1376
1377
		if ( $this->button_style == 'icon' ) {
1378
			$text = '';
1379
			$klasses[] = 'no-text';
1380
		}
1381
1382
		if ( $this->button_style == 'text' ) {
1383
			$klasses[] = 'no-icon';
1384
		}
1385
1386
		$link = sprintf(
1387
			'<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>',
1388
			implode( ' ', $klasses ),
1389
			$this->get_name(),
1390
			addcslashes( esc_url_raw( $opts['icon'] ), '"' ),
1391
			$text
1392
		);
1393
		?>
1394
		<div class="option option-smart-off">
1395
		<?php echo $link ; ?>
1396
		</div><?php
1397
	}
1398
}
1399
1400
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...
1401
	public $shortname = 'tumblr';
1402
	public $icon = '\f214';
1403 View Code Duplication
	public function __construct( $id, array $settings ) {
1404
		parent::__construct( $id, $settings );
1405
		if ( 'official' == $this->button_style ) {
1406
			$this->smart = true;
1407
		} else {
1408
			$this->smart = false;
1409
		}
1410
	}
1411
1412
	public function get_name() {
1413
		return __( 'Tumblr', 'jetpack' );
1414
	}
1415
1416
	public function get_display( $post ) {
1417
		if ( $this->smart ) {
1418
			$target = '';
1419
			if ( true == $this->open_link_in_new ) {
1420
				$target = '_blank';
1421
			}
1422
1423
			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>';
1424 View Code Duplication
		 } else {
1425
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Tumblr', 'share to', 'jetpack' ), __( 'Click to share on Tumblr', 'jetpack' ), 'share=tumblr' );
1426
		}
1427
	}
1428
1429 View Code Duplication
	public function process_request( $post, array $post_data ) {
1430
		// Record stats
1431
		parent::process_request( $post, $post_data );
1432
1433
		// Redirect to Tumblr's sharing endpoint (a la their bookmarklet)
1434
		$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=';
1435
		wp_redirect( $url );
1436
		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...
1437
	}
1438
	// http://www.tumblr.com/share?v=3&u=URL&t=TITLE&s=
1439 View Code Duplication
	public function display_footer() {
1440
		if ( $this->smart ) {
1441
			?><script type="text/javascript" src="https://platform.tumblr.com/v1/share.js"></script><?php
1442
		} else {
1443
			$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1444
		}
1445
	}
1446
}
1447
1448
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...
1449
	public $shortname = 'pinterest';
1450
	public $icon = '\f209';
1451
1452 View Code Duplication
	public function __construct( $id, array $settings ) {
1453
		parent::__construct( $id, $settings );
1454
		if ( 'official' == $this->button_style ) {
1455
			$this->smart = true;
1456
		} else {
1457
			$this->smart = false;
1458
		}
1459
	}
1460
1461
	public function get_name() {
1462
		return __( 'Pinterest', 'jetpack' );
1463
	}
1464
1465
	public function get_image( $post ) {
1466
		if ( class_exists( 'Jetpack_PostImages' ) ) {
1467
			$image = Jetpack_PostImages::get_image( $post->ID, array( 'fallback_to_avatars' => true ) );
1468
			if ( ! empty( $image ) ) {
1469
				return $image['src'];
1470
			}
1471
		}
1472
1473
		/**
1474
		 * Filters the default image used by the Pinterest Pin It share button.
1475
		 *
1476
		 * @module sharedaddy
1477
		 *
1478
		 * @since 3.6.0
1479
		 *
1480
		 * @param string $url Default image URL.
1481
		 */
1482
		return apply_filters( 'jetpack_sharing_pinterest_default_image', 'https://s0.wp.com/i/blank.jpg' );
1483
	}
1484
1485
	public function get_external_url( $post ) {
1486
		$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 );
1487
1488
		/**
1489
		 * Filters the Pinterest share URL used in sharing button output.
1490
		 *
1491
		 * @module sharedaddy
1492
		 *
1493
		 * @since 3.6.0
1494
		 *
1495
		 * @param string $url Pinterest share URL.
1496
		 */
1497
		return apply_filters( 'jetpack_sharing_pinterest_share_url', $url );
1498
	}
1499
1500
	public function get_widget_type() {
1501
		/**
1502
		 * Filters the Pinterest widget type.
1503
		 *
1504
		 * @see https://business.pinterest.com/en/widget-builder
1505
		 *
1506
		 * @module sharedaddy
1507
		 *
1508
		 * @since 3.6.0
1509
		 *
1510
		 * @param string $type Pinterest widget type. Default of 'buttonPin' for single-image selection. 'buttonBookmark' for multi-image modal.
1511
		 */
1512
		return apply_filters( 'jetpack_sharing_pinterest_widget_type', 'buttonPin' );
1513
	}
1514
1515
	public function get_display( $post ) {
1516
		$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...
1517
1518
		if ( $this->smart ) {
1519
			$display = sprintf(
1520
				'<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>',
1521
				esc_url( $this->get_external_url( $post ) ),
1522
				esc_attr( $this->get_widget_type() )
1523
			);
1524 View Code Duplication
		} else {
1525
			$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 );
1526
		}
1527
1528
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1529
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'linkedin' ) ) {
1530
			sharing_register_post_for_share_counts( $post->ID );
1531
		}
1532
1533
		return $display;
1534
	}
1535
1536
	public function process_request( $post, array $post_data ) {
1537
		// Record stats
1538
		parent::process_request( $post, $post_data );
1539
		// If we're triggering the multi-select panel, then we don't need to redirect to Pinterest
1540
		if ( ! isset( $_GET['js_only'] ) ) {
1541
			$pinterest_url = esc_url_raw( $this->get_external_url( $post ) );
1542
			wp_redirect( $pinterest_url );
1543
		} else {
1544
			echo '// share count bumped';
1545
		}
1546
		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...
1547
	}
1548
1549
	public function display_footer() {
1550
		/**
1551
		 * Filter the Pin it button appearing when hovering over images when using the official button style.
1552
		 *
1553
		 * @module sharedaddy
1554
		 *
1555
		 * @since 3.6.0
1556
		 *
1557
		 * @param bool $jetpack_pinit_over True by default, displays the Pin it button when hovering over images.
1558
		 */
1559
		$jetpack_pinit_over = apply_filters( 'jetpack_pinit_over_button', true );
1560
		?>
1561
		<?php if ( $this->smart ) : ?>
1562
			<script type="text/javascript">
1563
				// Pinterest shared resources
1564
				var s = document.createElement("script");
1565
				s.type = "text/javascript";
1566
				s.async = true;
1567
				<?php if ( $jetpack_pinit_over ) {
1568
				echo "s.setAttribute('data-pin-hover', true);";
1569
				} ?>
1570
				s.src = window.location.protocol + "//assets.pinterest.com/js/pinit.js";
1571
				var x = document.getElementsByTagName("script")[0];
1572
				x.parentNode.insertBefore(s, x);
1573
				// if 'Pin it' button has 'counts' make container wider
1574
				jQuery(window).load( function(){ jQuery( 'li.share-pinterest a span:visible' ).closest( '.share-pinterest' ).width( '80px' ); } );
1575
			</script>
1576
		<?php elseif ( 'buttonPin' != $this->get_widget_type() ) : ?>
1577
			<script type="text/javascript">
1578
				jQuery(document).ready( function(){
1579
					jQuery('body').on('click', 'a.share-pinterest', function(e){
1580
						e.preventDefault();
1581
						// Load Pinterest Bookmarklet code
1582
						var s = document.createElement("script");
1583
						s.type = "text/javascript";
1584
						s.src = window.location.protocol + "//assets.pinterest.com/js/pinmarklet.js?r=" + ( Math.random() * 99999999 );
1585
						var x = document.getElementsByTagName("script")[0];
1586
						x.parentNode.insertBefore(s, x);
1587
						// Trigger Stats
1588
						var s = document.createElement("script");
1589
						s.type = "text/javascript";
1590
						s.src = this + ( this.toString().indexOf( '?' ) ? '&' : '?' ) + 'js_only=1';
1591
						var x = document.getElementsByTagName("script")[0];
1592
						x.parentNode.insertBefore(s, x);
1593
					});
1594
				});
1595
			</script>
1596
		<?php endif;
1597
	}
1598
}
1599
1600
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...
1601
	public $shortname = 'pocket';
1602
	public $icon = '\f224';
1603
1604 View Code Duplication
	public function __construct( $id, array $settings ) {
1605
		parent::__construct( $id, $settings );
1606
1607
		if ( 'official' == $this->button_style ) {
1608
			$this->smart = true;
1609
		} else {
1610
			$this->smart = false;
1611
		}
1612
	}
1613
1614
	public function get_name() {
1615
		return __( 'Pocket', 'jetpack' );
1616
	}
1617
1618 View Code Duplication
	public function process_request( $post, array $post_data ) {
1619
		// Record stats
1620
		parent::process_request( $post, $post_data );
1621
1622
		$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 ) ) );
1623
		wp_redirect( $pocket_url );
1624
		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...
1625
	}
1626
1627
	public function get_display( $post ) {
1628
		if ( $this->smart ) {
1629
			$post_count = 'horizontal';
1630
1631
			$button = '';
1632
			$button .= '<div class="pocket_button">';
1633
			$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' ) );
1634
			$button .= '</div>';
1635
1636
			return $button;
1637 View Code Duplication
		} else {
1638
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Pocket', 'share to', 'jetpack' ), __( 'Click to share on Pocket', 'jetpack' ), 'share=pocket' );
1639
		}
1640
1641
	}
1642
1643 View Code Duplication
	function display_footer() {
1644
		if ( $this->smart ) :
1645
		?>
1646
		<script>
1647
		// Don't use Pocket's default JS as it we need to force init new Pocket share buttons loaded via JS.
1648
		function jetpack_sharing_pocket_init() {
1649
			jQuery.getScript( 'https://widgets.getpocket.com/v1/j/btn.js?v=1' );
1650
		}
1651
		jQuery( document ).ready( jetpack_sharing_pocket_init );
1652
		jQuery( document.body ).on( 'post-load', jetpack_sharing_pocket_init );
1653
		</script>
1654
		<?php
1655
		else :
1656
			$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1657
		endif;
1658
1659
	}
1660
1661
}
1662
1663
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...
1664
	public $shortname = 'telegram';
1665
1666
	public function __construct( $id, array $settings ) {
1667
		parent::__construct( $id, $settings );
1668
	}
1669
1670
	public function get_name() {
1671
		return __( 'Telegram', 'jetpack' );
1672
	}
1673 View Code Duplication
	public function process_request( $post, array $post_data ) {
1674
		// Record stats
1675
		parent::process_request( $post, $post_data );
1676
		$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 ) ) );
1677
		wp_redirect( $telegram_url );
1678
		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...
1679
	}
1680
1681
	public function get_display( $post ) {
1682
		return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Telegram', 'share to', 'jetpack' ), __( 'Click to share on Telegram', 'jetpack' ), 'share=telegram' );
1683
	}
1684
1685
	function display_footer() {
1686
		$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1687
	}
1688
}
1689
1690
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...
1691
	public $shortname = 'jetpack-whatsapp';
1692
1693
	public function __construct( $id, array $settings ) {
1694
		parent::__construct( $id, $settings );
1695
	}
1696
1697
	public function get_name() {
1698
		return __( 'WhatsApp', 'jetpack' );
1699
	}
1700
1701
	public function get_display( $post ) {
1702
		return $this->get_link( 'https://api.whatsapp.com/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' ) );
1703
	}
1704
}
1705
1706
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...
1707
	public $shortname = 'skype';
1708
	public $icon = '\f220';
1709
	private $share_type = 'default';
1710
1711 View Code Duplication
	public function __construct( $id, array $settings ) {
1712
		parent::__construct( $id, $settings );
1713
1714
		if ( isset( $settings['share_type'] ) ) {
1715
			$this->share_type = $settings['share_type'];
1716
		}
1717
1718
		if ( 'official' == $this->button_style ) {
1719
			$this->smart = true;
1720
		} else {
1721
			$this->smart = false;
1722
		}
1723
1724
	}
1725
1726
	public function get_name() {
1727
		return __( 'Skype', 'jetpack' );
1728
	}
1729
1730
	public function get_display( $post ) {
1731
		if ( $this->smart ) {
1732
			$skype_share_html = sprintf(
1733
				'<div class="skype-share" data-href="%1$s" data-lang="%2$s" data-style="small" data-source="jetpack" ></div>',
1734
				esc_attr( $this->get_share_url( $post->ID ) ),
1735
				'en-US'
1736
			);
1737
			return $skype_share_html;
1738
		}
1739
1740
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1741
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'skype' ) ) {
1742
			sharing_register_post_for_share_counts( $post->ID );
1743
		}
1744
		return $this->get_link(
1745
			$this->get_process_request_url( $post->ID ), _x( 'Skype', 'share to', 'jetpack' ), __( 'Click to share on Skype', 'jetpack' ), 'share=skype', 'sharing-skype-' . $post->ID );
1746
	}
1747
1748 View Code Duplication
	public function process_request( $post, array $post_data ) {
1749
		$skype_url = sprintf(
1750
			'https://web.skype.com/share?url=%1$s&lang=%2$s=&source=jetpack',
1751
			rawurlencode( $this->get_share_url( $post->ID ) ),
1752
			'en-US'
1753
		);
1754
1755
		// Record stats
1756
		parent::process_request( $post, $post_data );
1757
1758
		// Redirect to Skype
1759
		wp_redirect( $skype_url );
1760
		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...
1761
	}
1762
1763
	public function display_footer() {
1764
		if ( $this->smart ) :
1765
			?>
1766
			<script>
1767
				(function(r, d, s) {
1768
					r.loadSkypeWebSdkAsync = r.loadSkypeWebSdkAsync || function(p) {
1769
							var js, sjs = d.getElementsByTagName(s)[0];
1770
							if (d.getElementById(p.id)) { return; }
1771
							js = d.createElement(s);
1772
							js.id = p.id;
1773
							js.src = p.scriptToLoad;
1774
							js.onload = p.callback
1775
							sjs.parentNode.insertBefore(js, sjs);
1776
						};
1777
					var p = {
1778
						scriptToLoad: 'https://swx.cdn.skype.com/shared/v/latest/skypewebsdk.js',
1779
						id: 'skype_web_sdk'
1780
					};
1781
					r.loadSkypeWebSdkAsync(p);
1782
				})(window, document, 'script');
1783
			</script>
1784
			<?php
1785
		else :
1786
			$this->js_dialog( $this->shortname, array( 'width' => 305, 'height' => 665 ) );
1787
		endif;
1788
	}
1789
}
1790