Completed
Push — remove/grunt ( 82bad1...654b22 )
by
unknown
14:04
created

Share_Twitter   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 210
Duplicated Lines 3.81 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 8
loc 210
rs 10
c 0
b 0
f 0
wmc 22
lcom 1
cbo 1

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 8 9 2
A get_name() 0 3 1
A sharing_twitter_via() 0 39 2
A get_related_accounts() 0 28 3
B get_display() 0 46 6
B process_request() 0 47 5
A has_custom_button_style() 0 3 1
A display_footer() 0 9 2

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 ) ? ' rel="noopener noreferrer" 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
	/**
575
	 * Determine the Twitter 'via' value for a post.
576
	 *
577
	 * @param  WP_Post|int $post Post object or post ID.
578
	 * @return string Twitter handle without the preceding @.
579
	 **/
580
	public static function sharing_twitter_via( $post ) {
581
		$post = get_post( $post );
582
		/**
583
		 * Allow third-party plugins to customize the Twitter username used as "twitter:site" Twitter Card Meta Tag.
584
		 *
585
		 * @module sharedaddy
586
		 *
587
		 * @since 3.0.0
588
		 *
589
		 * @param string $string Twitter Username.
590
		 * @param array $args Array of Open Graph Meta Tags and Twitter Cards tags.
591
		 */
592
		$twitter_site_tag_value = apply_filters( 'jetpack_twitter_cards_site_tag', '', array() );
593
594
		/*
595
		 * Hack to remove the unwanted behavior of adding 'via @jetpack' which
596
		 * was introduced with the adding of the Twitter cards.
597
		 * This should be a temporary solution until a better method is setup.
598
		 */
599
		if ( 'jetpack' == $twitter_site_tag_value ) {
600
			$twitter_site_tag_value = '';
601
		}
602
603
		/**
604
		 * Filters the Twitter username used as "via" in the Twitter sharing button.
605
		 *
606
		 * @module sharedaddy
607
		 *
608
		 * @since 1.7.0
609
		 *
610
		 * @param string $twitter_site_tag_value Twitter Username.
611
		 * @param int $post->ID Post ID.
612
		 */
613
		$twitter_site_tag_value = apply_filters( 'jetpack_sharing_twitter_via', $twitter_site_tag_value, $post->ID );
614
615
		// Strip out anything other than a letter, number, or underscore.
616
		// This will prevent the inadvertent inclusion of an extra @, as well as normalizing the handle.
617
		return preg_replace( '/[^\da-z_]+/i', '', $twitter_site_tag_value );
618
	}
619
620
	/**
621
	 * Determine the 'related' Twitter accounts for a post.
622
	 *
623
	 * @param  WP_Post|int $post Post object or post ID.
624
	 * @return string Comma-separated list of Twitter handles.
625
	 **/
626
	public static function get_related_accounts( $post ) {
627
		$post = get_post( $post );
628
		/**
629
		 * Filter the list of related Twitter accounts added to the Twitter sharing button.
630
		 *
631
		 * @module sharedaddy
632
		 *
633
		 * @since 1.7.0
634
		 *
635
		 * @param array $args Array of Twitter usernames. Format is 'username' => 'Optional description'
636
		 * @param int $post->ID Post ID.
637
		 */
638
		$related_accounts = apply_filters( 'jetpack_sharing_twitter_related', array(), $post->ID );
639
640
		// Example related string: account1,account2:Account 2 description,account3
641
		$related = array();
642
643
		foreach ( $related_accounts as $related_account_username => $related_account_description ) {
644
			// Join the description onto the end of the username
645
			if ( $related_account_description ) {
646
				$related_account_username .= ':' . $related_account_description;
647
			}
648
649
			$related[] = $related_account_username;
650
		}
651
652
		return implode( ',', $related );
653
	}
654
655
	public function get_display( $post ) {
656
		$via = $this->sharing_twitter_via( $post );
657
658
		if ( $via ) {
659
			$via = 'data-via="' . esc_attr( $via ) . '"';
660
		} else {
661
			$via = '';
662
		}
663
664
		$related = $this->get_related_accounts( $post );
665
		if ( ! empty( $related ) && $related !== $via ) {
666
			$related = 'data-related="' . esc_attr( $related ) . '"';
667
		} else {
668
			$related = '';
669
		}
670
671
		if ( $this->smart ) {
672
			$share_url = $this->get_share_url( $post->ID );
673
			$post_title = $this->get_share_title( $post->ID );
674
			return sprintf(
675
				'<a href="https://twitter.com/share" class="twitter-share-button" data-url="%1$s" data-text="%2$s" %3$s %4$s>Tweet</a>',
676
				esc_url( $share_url ),
677
				esc_attr( $post_title ),
678
				$via,
679
				$related
680
			);
681
		} else {
682
			if (
683
				/**
684
				 * Allow plugins to disable sharing counts for specific sharing services.
685
				 *
686
				 * @module sharedaddy
687
				 *
688
				 * @since 3.0.0
689
				 *
690
				 * @param bool true Should sharing counts be enabled for this specific service. Default to true.
691
				 * @param int $post->ID Post ID.
692
				 * @param string $str Sharing service name.
693
				 */
694
				apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'twitter' )
695
			) {
696
				sharing_register_post_for_share_counts( $post->ID );
697
			}
698
			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 );
699
		}
700
	}
701
702
	public function process_request( $post, array $post_data ) {
703
		$post_title = $this->get_share_title( $post->ID );
704
		$post_link = $this->get_share_url( $post->ID );
705
706
		if ( function_exists( 'mb_stripos' ) ) {
707
			$strlen = 'mb_strlen';
708
			$substr = 'mb_substr';
709
		} else {
710
			$strlen = 'strlen';
711
			$substr = 'substr';
712
		}
713
714
		$via = $this->sharing_twitter_via( $post );
715
		$related = $this->get_related_accounts( $post );
716
		if ( $via ) {
717
			$sig = " via @$via";
718
			if ( $related === $via ) {
719
				$related = false;
720
			}
721
		} else {
722
			$via = false;
723
			$sig = '';
724
		}
725
726
		$suffix_length = $this->short_url_length + $strlen( $sig );
727
		// $sig is handled by twitter in their 'via' argument.
728
		// $post_link is handled by twitter in their 'url' argument.
729
		if ( 280 < $strlen( $post_title ) + $suffix_length ) {
730
			// The -1 is for "\xE2\x80\xA6", a UTF-8 ellipsis.
731
			$text = $substr( $post_title, 0, 280 - $suffix_length - 1 ) . "\xE2\x80\xA6";
732
		} else {
733
			$text = $post_title;
734
		}
735
736
		// Record stats
737
		parent::process_request( $post, $post_data );
738
739
		$url = $post_link;
740
		$twitter_url = add_query_arg(
741
			rawurlencode_deep( array_filter( compact( 'via', 'related', 'text', 'url' ) ) ),
742
			'https://twitter.com/intent/tweet'
743
		);
744
745
		// Redirect to Twitter
746
		wp_redirect( $twitter_url );
747
		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...
748
	}
749
750
	public function has_custom_button_style() {
751
		return $this->smart;
752
	}
753
754
	public function display_footer() {
755
		if ( $this->smart ) {
756
			?>
757
			<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>
758
			<?php
759
		} else {
760
			$this->js_dialog( $this->shortname, array( 'height' => 350 ) );
761
		}
762
	}
763
}
764
765
766
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...
767
	public $shortname = 'reddit';
768
	public $icon = '\f222';
769 View Code Duplication
	public function __construct( $id, array $settings ) {
770
		parent::__construct( $id, $settings );
771
772
		if ( 'official' == $this->button_style ) {
773
			$this->smart = true;
774
		} else {
775
			$this->smart = false;
776
		}
777
	}
778
779
	public function get_name() {
780
		return __( 'Reddit', 'jetpack' );
781
	}
782
783
	public function get_display( $post ) {
784
		if ( $this->smart ) {
785
			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>';
786 View Code Duplication
		} else {
787
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Reddit', 'share to', 'jetpack' ), __( 'Click to share on Reddit', 'jetpack' ), 'share=reddit' );
788
		}
789
	}
790
791 View Code Duplication
	public function process_request( $post, array $post_data ) {
792
		$reddit_url = $this->http() . '://reddit.com/submit?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) );
793
794
		// Record stats
795
		parent::process_request( $post, $post_data );
796
797
		// Redirect to Reddit
798
		wp_redirect( $reddit_url );
799
		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...
800
	}
801
}
802
803
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...
804
	public $shortname = 'linkedin';
805
	public $icon = '\f207';
806 View Code Duplication
	public function __construct( $id, array $settings ) {
807
		parent::__construct( $id, $settings );
808
809
		if ( 'official' == $this->button_style ) {
810
			$this->smart = true;
811
		} else {
812
			$this->smart = false;
813
		}
814
	}
815
816
	public function get_name() {
817
		return __( 'LinkedIn', 'jetpack' );
818
	}
819
820
	public function has_custom_button_style() {
821
		return $this->smart;
822
	}
823
824
	public function get_display( $post ) {
825
		$display = '';
826
827
		if ( $this->smart ) {
828
			$share_url = $this->get_share_url( $post->ID );
829
			$display .= sprintf( '<div class="linkedin_button"><script type="in/share" data-url="%s" data-counter="right"></script></div>', esc_url( $share_url ) );
830 View Code Duplication
		} else {
831
			$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 );
832
		}
833
834
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
835
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'linkedin' ) ) {
836
			sharing_register_post_for_share_counts( $post->ID );
837
		}
838
839
		return $display;
840
	}
841
842 View Code Duplication
	public function process_request( $post, array $post_data ) {
843
844
		$post_link = $this->get_share_url( $post->ID );
845
846
		// Using the same URL as the official button, which is *not* LinkedIn's documented sharing link
847
		// https://www.linkedin.com/cws/share?url={url}&token=&isFramed=false
848
		$linkedin_url = add_query_arg( array(
849
			'url' => rawurlencode( $post_link ),
850
		), 'https://www.linkedin.com/cws/share?token=&isFramed=false' );
851
852
		// Record stats
853
		parent::process_request( $post, $post_data );
854
855
		// Redirect to LinkedIn
856
		wp_redirect( $linkedin_url );
857
		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...
858
	}
859
860 View Code Duplication
	public function display_footer() {
861
		if ( ! $this->smart ) {
862
			$this->js_dialog( $this->shortname, array( 'width' => 580, 'height' => 450 ) );
863
		} else {
864
			?><script type="text/javascript">
865
			jQuery( document ).ready( function() {
866
				jQuery.getScript( 'https://platform.linkedin.com/in.js?async=true', function success() {
867
					IN.init();
868
				});
869
			});
870
			jQuery( document.body ).on( 'post-load', function() {
871
				if ( typeof IN != 'undefined' )
872
					IN.parse();
873
			});
874
			</script><?php
875
		}
876
	}
877
}
878
879
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...
880
	public $shortname = 'facebook';
881
	public $icon = '\f204';
882
	private $share_type = 'default';
883
884 View Code Duplication
	public function __construct( $id, array $settings ) {
885
		parent::__construct( $id, $settings );
886
887
		if ( isset( $settings['share_type'] ) ) {
888
			$this->share_type = $settings['share_type'];
889
		}
890
891
		if ( 'official' == $this->button_style ) {
892
			$this->smart = true;
893
		} else {
894
			$this->smart = false;
895
		}
896
	}
897
898
	public function get_name() {
899
		return __( 'Facebook', 'jetpack' );
900
	}
901
902
	public function display_header() {
903
	}
904
905 View Code Duplication
	function guess_locale_from_lang( $lang ) {
906
		if ( 'en' == $lang || 'en_US' == $lang || ! $lang ) {
907
			return 'en_US';
908
		}
909
910
		if ( ! class_exists( 'GP_Locales' ) ) {
911
			if ( ! defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) || ! file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) {
912
				return false;
913
			}
914
915
			require JETPACK__GLOTPRESS_LOCALES_PATH;
916
		}
917
918
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
919
			// WP.com: get_locale() returns 'it'
920
			$locale = GP_Locales::by_slug( $lang );
921
		} else {
922
			// Jetpack: get_locale() returns 'it_IT';
923
			$locale = GP_Locales::by_field( 'wp_locale', $lang );
924
		}
925
926
		if ( ! $locale ) {
927
			return false;
928
		}
929
930
		if ( empty( $locale->facebook_locale ) ) {
931
			if ( empty( $locale->wp_locale ) ) {
932
				return false;
933
			} else {
934
				// Facebook SDK is smart enough to fall back to en_US if a
935
				// locale isn't supported. Since supported Facebook locales
936
				// can fall out of sync, we'll attempt to use the known
937
				// wp_locale value and rely on said fallback.
938
				return $locale->wp_locale;
939
			}
940
		}
941
942
		return $locale->facebook_locale;
943
	}
944
945
	public function get_display( $post ) {
946
		if ( $this->smart ) {
947
			$share_url = $this->get_share_url( $post->ID );
948
			$fb_share_html = '<div class="fb-share-button" data-href="' . esc_attr( $share_url ) . '" data-layout="button_count"></div>';
949
			/**
950
			 * Filter the output of the Facebook Sharing button.
951
			 *
952
			 * @module sharedaddy
953
			 *
954
			 * @since 3.6.0
955
			 *
956
			 * @param string $fb_share_html Facebook Sharing button HTML.
957
			 * @param string $share_url URL of the post to share.
958
			 */
959
			return apply_filters( 'jetpack_sharing_facebook_official_button_output', $fb_share_html, $share_url );
960
		}
961
962
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
963
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'facebook' ) ) {
964
			sharing_register_post_for_share_counts( $post->ID );
965
		}
966
		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 );
967
	}
968
969 View Code Duplication
	public function process_request( $post, array $post_data ) {
970
		$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 ) );
971
972
		// Record stats
973
		parent::process_request( $post, $post_data );
974
975
		// Redirect to Facebook
976
		wp_redirect( $fb_url );
977
		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...
978
	}
979
980
	public function display_footer() {
981
		$this->js_dialog( $this->shortname );
982
		if ( $this->smart ) {
983
			$locale = $this->guess_locale_from_lang( get_locale() );
984
			if ( ! $locale ) {
985
				$locale = 'en_US';
986
			}
987
			/**
988
			 * Filter the App ID used in the official Facebook Share button.
989
			 *
990
			 * @since 3.8.0
991
			 *
992
			 * @param int $fb_app_id Facebook App ID. Default to 249643311490 (WordPress.com's App ID).
993
			 */
994
			$fb_app_id = apply_filters( 'jetpack_sharing_facebook_app_id', '249643311490' );
995
			if ( is_numeric( $fb_app_id ) ) {
996
				$fb_app_id = '&appId=' . $fb_app_id;
997
			} else {
998
				$fb_app_id = '';
999
			}
1000
			?><div id="fb-root"></div>
1001
			<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>
1002
			<script>
1003
			jQuery( document.body ).on( 'post-load', function() {
1004
				if ( 'undefined' !== typeof FB ) {
1005
					FB.XFBML.parse();
1006
				}
1007
			} );
1008
			</script>
1009
			<?php
1010
		}
1011
	}
1012
}
1013
1014
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...
1015
	public $shortname = 'print';
1016
	public $icon = '\f469';
1017 View Code Duplication
	public function __construct( $id, array $settings ) {
1018
		parent::__construct( $id, $settings );
1019
1020
		if ( 'official' == $this->button_style ) {
1021
			$this->smart = true;
1022
		} else {
1023
			$this->smart = false;
1024
		}
1025
	}
1026
1027
	public function get_name() {
1028
		return __( 'Print', 'jetpack' );
1029
	}
1030
1031
	public function get_display( $post ) {
1032
		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' ) );
1033
	}
1034
}
1035
1036
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...
1037
	public $shortname = 'pressthis';
1038
	public $icon = '\f205';
1039 View Code Duplication
	public function __construct( $id, array $settings ) {
1040
		parent::__construct( $id, $settings );
1041
1042
		if ( 'official' == $this->button_style ) {
1043
			$this->smart = true;
1044
		} else {
1045
			$this->smart = false;
1046
		}
1047
	}
1048
1049
	public function get_name() {
1050
		return __( 'Press This', 'jetpack' );
1051
	}
1052
1053
	public function process_request( $post, array $post_data ) {
1054
		global $current_user, $wp_version;
1055
1056
		$primary_blog = (int) get_user_meta( $current_user->ID, 'primary_blog', true );
1057
		if ( $primary_blog ) {
1058
			$primary_blog_details = get_blog_details( $primary_blog );
1059
		} else {
1060
			$primary_blog_details = false;
1061
		}
1062
1063
		if ( $primary_blog_details ) {
1064
			$blogs = array( $primary_blog_details );
1065
		} elseif ( function_exists( 'get_active_blogs_for_user' ) ) {
1066
			$blogs = get_active_blogs_for_user();
1067
			if ( empty( $blogs ) ) {
1068
				$blogs = get_blogs_of_user( $current_user->ID );
1069
			}
1070
		} else {
1071
			$blogs = get_blogs_of_user( $current_user->ID );
1072
		}
1073
1074
		if ( empty( $blogs ) ) {
1075
			wp_safe_redirect( get_permalink( $post->ID ) );
1076
			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...
1077
		}
1078
1079
		$blog = current( $blogs );
1080
1081
		$args = array(
1082
			'u' => rawurlencode( $this->get_share_url( $post->ID ) ),
1083
			);
1084
1085
		if ( version_compare( $wp_version, '4.9-RC1-42107', '>=' ) ) {
1086
			$args[ 'url-scan-submit' ] = 'Scan';
1087
			$args[ '_wpnonce' ]        = wp_create_nonce( 'scan-site' );
1088
1089
		} else { // Remove once 4.9 is the minimum.
1090
			$args['t'] = rawurlencode( $this->get_share_title( $post->ID ) );
1091
			if ( isset( $_GET['sel'] ) ) {
1092
				$args['s'] = rawurlencode( $_GET['sel'] );
1093
			}
1094
		}
1095
1096
		$url = $blog->siteurl . '/wp-admin/press-this.php';
1097
		$url = add_query_arg( $args, $url );
1098
1099
		// Record stats
1100
		parent::process_request( $post, $post_data );
1101
1102
		// Redirect to Press This
1103
		wp_redirect( $url );
1104
		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...
1105
	}
1106
1107
	public function get_display( $post ) {
1108
		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' );
1109
	}
1110
}
1111
1112
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...
1113
	public $shortname = 'googleplus1';
1114
	public $icon = '\f218';
1115
	private $state = false;
1116
1117 View Code Duplication
	public function __construct( $id, array $settings ) {
1118
		parent::__construct( $id, $settings );
1119
1120
		if ( 'official' == $this->button_style ) {
1121
			$this->smart = true;
1122
		} else {
1123
			$this->smart = false;
1124
		}
1125
	}
1126
1127
	public function get_name() {
1128
		return __( 'Google', 'jetpack' );
1129
	}
1130
1131
	public function has_custom_button_style() {
1132
		return $this->smart;
1133
	}
1134
1135
	public function get_display( $post ) {
1136
1137
		if ( $this->smart ) {
1138
			$share_url = $this->get_share_url( $post->ID );
1139
			return '<div class="googleplus1_button"><div class="g-plus" data-action="share" data-annotation="bubble" data-href="' . esc_url( $share_url ) . '"></div></div>';
1140 View Code Duplication
		} else {
1141
			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 );
1142
		}
1143
	}
1144
1145
	public function get_state() {
1146
		return $this->state;
1147
	}
1148
1149
	public function process_request( $post, array $post_data ) {
1150
1151
		if ( isset( $post_data['state'] ) ) {
1152
			$this->state = $post_data['state'];
1153
		}
1154
		// Record stats
1155
		parent::process_request( $post, $post_data );
1156
1157
		// Redirect to Google +'s sharing endpoint
1158
		$url = 'https://plus.google.com/share?url=' . rawurlencode( $this->get_share_url( $post->ID ) );
1159
		wp_redirect( $url );
1160
		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...
1161
	}
1162
1163 View Code Duplication
	public function display_footer() {
1164
		global $post;
1165
1166
		if ( $this->smart ) { ?>
1167
			<script>
1168
			function renderGooglePlus1() {
1169
				if ( 'undefined' === typeof gapi ) {
1170
					return;
1171
				}
1172
1173
				jQuery( '.g-plus' ).each(function() {
1174
					var $button = jQuery( this );
1175
1176
					if ( ! $button.data( 'gplus-rendered' ) ) {
1177
						gapi.plusone.render( this, {
1178
							href: $button.attr( 'data-href' ),
1179
							size: $button.attr( 'data-size' ),
1180
							annotation: $button.attr( 'data-annotation' )
1181
						});
1182
1183
						$button.data( 'gplus-rendered', true );
1184
					}
1185
				});
1186
			}
1187
1188
			(function() {
1189
				var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
1190
				po.src = 'https://apis.google.com/js/platform.js';
1191
				po.innerHTML = '{"parsetags": "explicit"}';
1192
				po.onload = renderGooglePlus1;
1193
				var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
1194
			})();
1195
1196
			jQuery( document.body ).on( 'post-load', renderGooglePlus1 );
1197
			</script>
1198
			<?php
1199
		} else {
1200
			$this->js_dialog( 'google-plus-1', array( 'width' => 480, 'height' => 550 ) );
1201
		}
1202
	}
1203
1204 View Code Duplication
	public function get_total( $post = false ) {
1205
		global $wpdb, $blog_id;
1206
1207
		$name = strtolower( $this->get_id() );
1208
1209
		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...
1210
			// get total number of shares for service
1211
			return $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND share_service = %s', $blog_id, $name ) );
1212
		}
1213
1214
		// get total shares for a post
1215
		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 ) );
1216
	}
1217
}
1218
1219
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...
1220
	private $name;
1221
	private $icon;
1222
	private $url;
1223
	public $smart = true;
1224
	public $shortname;
1225
1226
	public function get_class() {
1227
		return 'custom share-custom-' . sanitize_html_class( strtolower( $this->name ) );
1228
	}
1229
1230
	public function __construct( $id, array $settings ) {
1231
		parent::__construct( $id, $settings );
1232
1233
		$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...
1234
1235
		if ( isset( $settings['name'] ) ) {
1236
			$this->name = $settings['name'];
1237
			$this->shortname = preg_replace( '/[^a-z0-9]*/', '', $settings['name'] );
1238
		}
1239
1240
		if ( isset( $settings['icon'] ) ) {
1241
			$this->icon = $settings['icon'];
1242
1243
			$new_icon = esc_url_raw( wp_specialchars_decode( $this->icon, ENT_QUOTES ) );
1244
			$i = 0;
1245
			while ( $new_icon != $this->icon ) {
1246
				if ( $i > 5 ) {
1247
					$this->icon = false;
1248
					break;
1249
				} else {
1250
					$this->icon = $new_icon;
1251
					$new_icon = esc_url_raw( wp_specialchars_decode( $this->icon, ENT_QUOTES ) );
1252
				}
1253
				$i++;
1254
			}
1255
		}
1256
1257
		if ( isset( $settings['url'] ) ) {
1258
			$this->url = $settings['url'];
1259
		}
1260
	}
1261
1262
	public function get_name() {
1263
		return $this->name;
1264
	}
1265
1266
	public function get_display( $post ) {
1267
		$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 );
1268
		return str_replace( '<span>', '<span style="' . esc_attr( 'background-image:url("' . addcslashes( esc_url_raw( $this->icon ), '"' ) . '");' ) . '">', $str );
1269
	}
1270
1271
	public function process_request( $post, array $post_data ) {
1272
		$url = str_replace( '&amp;', '&', $this->url );
1273
		$url = str_replace( '%post_id%', rawurlencode( $post->ID ), $url );
1274
		$url = str_replace( '%post_url%', rawurlencode( $this->get_share_url( $post->ID ) ), $url );
1275
		$url = str_replace( '%post_full_url%', rawurlencode( get_permalink( $post->ID ) ), $url );
1276
		$url = str_replace( '%post_title%', rawurlencode( $this->get_share_title( $post->ID ) ), $url );
1277
		$url = str_replace( '%home_url%', rawurlencode( home_url() ), $url );
1278
		$url = str_replace( '%post_slug%', rawurlencode( $post->post_name ), $url );
1279
1280
		if ( strpos( $url, '%post_tags%' ) !== false ) {
1281
			$tags	= get_the_tags( $post->ID );
1282
			$tagged = '';
1283
1284
			if ( $tags ) {
1285
				$tagged_raw = array();
1286
				foreach ( $tags as $tag ) {
1287
					$tagged_raw[] = rawurlencode( $tag->name );
1288
				}
1289
1290
				$tagged = implode( ',', $tagged_raw );
1291
			}
1292
1293
			$url = str_replace( '%post_tags%', $tagged, $url );
1294
		}
1295
1296
		if ( strpos( $url, '%post_excerpt%' ) !== false ) {
1297
			$url_excerpt = $post->post_excerpt;
1298
			if ( empty( $url_excerpt ) ) {
1299
				$url_excerpt = $post->post_content;
1300
			}
1301
1302
			$url_excerpt = strip_tags( strip_shortcodes( $url_excerpt ) );
1303
			$url_excerpt = wp_html_excerpt( $url_excerpt, 100 );
1304
			$url_excerpt = rtrim( preg_replace( '/[^ .]*$/', '', $url_excerpt ) );
1305
			$url = str_replace( '%post_excerpt%', rawurlencode( $url_excerpt ), $url );
1306
		}
1307
1308
		// Record stats
1309
		parent::process_request( $post, $post_data );
1310
1311
		// Redirect
1312
		wp_redirect( $url );
1313
		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...
1314
	}
1315
1316
	public function display_options() {
1317
?>
1318
<div class="input">
1319
	<table class="form-table">
1320
		<tbody>
1321
			<tr>
1322
				<th scope="row"><?php _e( 'Label', 'jetpack' ); ?></th>
1323
				<td><input type="text" name="name" value="<?php echo esc_attr( $this->name ); ?>" /></td>
1324
			</tr>
1325
1326
			<tr>
1327
				<th scope="row"><?php _e( 'URL', 'jetpack' ); ?></th>
1328
				<td><input type="text" name="url" value="<?php echo esc_attr( $this->url ); ?>" /></td>
1329
			</tr>
1330
1331
			<tr>
1332
				<th scope="row"><?php _e( 'Icon', 'jetpack' ); ?></th>
1333
				<td><input type="text" name="icon" value="<?php echo esc_attr( $this->icon ); ?>" /></td>
1334
			</tr>
1335
1336
			<tr>
1337
				<th scope="row"></th>
1338
				<td>
1339
					<input class="button-secondary" type="submit" value="<?php esc_attr_e( 'Save', 'jetpack' ); ?>" />
1340
					<a href="#" class="remove"><small><?php _e( 'Remove Service', 'jetpack' ); ?></small></a>
1341
				</td>
1342
			</tr>
1343
		</tbody>
1344
	</table>
1345
</div>
1346
<?php
1347
	}
1348
1349
	public function update_options( array $data ) {
1350
		$name  = trim( wp_html_excerpt( wp_kses( stripslashes( $data['name'] ), array() ), 30 ) );
1351
		$url   = trim( esc_url_raw( $data['url'] ) );
1352
		$icon  = trim( esc_url_raw( $data['icon'] ) );
1353
1354
		if ( $name ) {
1355
			$this->name = $name;
1356
		}
1357
1358
		if ( $url ) {
1359
			$this->url	= $url;
1360
		}
1361
1362
		if ( $icon ) {
1363
			$this->icon = $icon;
1364
		}
1365
	}
1366
1367
	public function get_options() {
1368
		return array(
1369
			'name' => $this->name,
1370
			'icon' => $this->icon,
1371
			'url'  => $this->url,
1372
		);
1373
	}
1374
1375
	public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
1376
		$opts = $this->get_options();
1377
1378
		$text = '&nbsp;';
1379
		if ( ! $this->smart ) {
1380
			if ( $this->button_style != 'icon' ) {
1381
				$text = $this->get_name();
1382
			}
1383
		}
1384
1385
		$klasses = array( 'share-' . $this->shortname );
1386
1387
		if ( $this->button_style == 'icon' || $this->button_style == 'icon-text' ) {
1388
			$klasses[] = 'share-icon';
1389
		}
1390
1391
		if ( $this->button_style == 'icon' ) {
1392
			$text = '';
1393
			$klasses[] = 'no-text';
1394
		}
1395
1396
		if ( $this->button_style == 'text' ) {
1397
			$klasses[] = 'no-icon';
1398
		}
1399
1400
		$link = sprintf(
1401
			'<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>',
1402
			implode( ' ', $klasses ),
1403
			$this->get_name(),
1404
			addcslashes( esc_url_raw( $opts['icon'] ), '"' ),
1405
			$text
1406
		);
1407
		?>
1408
		<div class="option option-smart-off">
1409
		<?php echo $link ; ?>
1410
		</div><?php
1411
	}
1412
}
1413
1414
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...
1415
	public $shortname = 'tumblr';
1416
	public $icon = '\f214';
1417 View Code Duplication
	public function __construct( $id, array $settings ) {
1418
		parent::__construct( $id, $settings );
1419
		if ( 'official' == $this->button_style ) {
1420
			$this->smart = true;
1421
		} else {
1422
			$this->smart = false;
1423
		}
1424
	}
1425
1426
	public function get_name() {
1427
		return __( 'Tumblr', 'jetpack' );
1428
	}
1429
1430
	public function get_display( $post ) {
1431
		if ( $this->smart ) {
1432
			$target = '';
1433
			if ( true == $this->open_link_in_new ) {
1434
				$target = '_blank';
1435
			}
1436
1437
			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>';
1438 View Code Duplication
		 } else {
1439
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Tumblr', 'share to', 'jetpack' ), __( 'Click to share on Tumblr', 'jetpack' ), 'share=tumblr' );
1440
		}
1441
	}
1442
1443 View Code Duplication
	public function process_request( $post, array $post_data ) {
1444
		// Record stats
1445
		parent::process_request( $post, $post_data );
1446
1447
		// Redirect to Tumblr's sharing endpoint (a la their bookmarklet)
1448
		$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=';
1449
		wp_redirect( $url );
1450
		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...
1451
	}
1452
	// http://www.tumblr.com/share?v=3&u=URL&t=TITLE&s=
1453 View Code Duplication
	public function display_footer() {
1454
		if ( $this->smart ) {
1455
			?><script type="text/javascript" src="https://platform.tumblr.com/v1/share.js"></script><?php
1456
		} else {
1457
			$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1458
		}
1459
	}
1460
}
1461
1462
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...
1463
	public $shortname = 'pinterest';
1464
	public $icon = '\f209';
1465
1466 View Code Duplication
	public function __construct( $id, array $settings ) {
1467
		parent::__construct( $id, $settings );
1468
		if ( 'official' == $this->button_style ) {
1469
			$this->smart = true;
1470
		} else {
1471
			$this->smart = false;
1472
		}
1473
	}
1474
1475
	public function get_name() {
1476
		return __( 'Pinterest', 'jetpack' );
1477
	}
1478
1479
	public function get_image( $post ) {
1480
		if ( class_exists( 'Jetpack_PostImages' ) ) {
1481
			$image = Jetpack_PostImages::get_image( $post->ID, array( 'fallback_to_avatars' => true ) );
1482
			if ( ! empty( $image ) ) {
1483
				return $image['src'];
1484
			}
1485
		}
1486
1487
		/**
1488
		 * Filters the default image used by the Pinterest Pin It share button.
1489
		 *
1490
		 * @module sharedaddy
1491
		 *
1492
		 * @since 3.6.0
1493
		 *
1494
		 * @param string $url Default image URL.
1495
		 */
1496
		return apply_filters( 'jetpack_sharing_pinterest_default_image', 'https://s0.wp.com/i/blank.jpg' );
1497
	}
1498
1499
	public function get_external_url( $post ) {
1500
		$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 );
1501
1502
		/**
1503
		 * Filters the Pinterest share URL used in sharing button output.
1504
		 *
1505
		 * @module sharedaddy
1506
		 *
1507
		 * @since 3.6.0
1508
		 *
1509
		 * @param string $url Pinterest share URL.
1510
		 */
1511
		return apply_filters( 'jetpack_sharing_pinterest_share_url', $url );
1512
	}
1513
1514
	public function get_widget_type() {
1515
		/**
1516
		 * Filters the Pinterest widget type.
1517
		 *
1518
		 * @see https://business.pinterest.com/en/widget-builder
1519
		 *
1520
		 * @module sharedaddy
1521
		 *
1522
		 * @since 3.6.0
1523
		 *
1524
		 * @param string $type Pinterest widget type. Default of 'buttonPin' for single-image selection. 'buttonBookmark' for multi-image modal.
1525
		 */
1526
		return apply_filters( 'jetpack_sharing_pinterest_widget_type', 'buttonPin' );
1527
	}
1528
1529
	public function get_display( $post ) {
1530
		$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...
1531
1532
		if ( $this->smart ) {
1533
			$display = sprintf(
1534
				'<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>',
1535
				esc_url( $this->get_external_url( $post ) ),
1536
				esc_attr( $this->get_widget_type() )
1537
			);
1538 View Code Duplication
		} else {
1539
			$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 );
1540
		}
1541
1542
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1543
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'linkedin' ) ) {
1544
			sharing_register_post_for_share_counts( $post->ID );
1545
		}
1546
1547
		return $display;
1548
	}
1549
1550
	public function process_request( $post, array $post_data ) {
1551
		// Record stats
1552
		parent::process_request( $post, $post_data );
1553
		// If we're triggering the multi-select panel, then we don't need to redirect to Pinterest
1554
		if ( ! isset( $_GET['js_only'] ) ) {
1555
			$pinterest_url = esc_url_raw( $this->get_external_url( $post ) );
1556
			wp_redirect( $pinterest_url );
1557
		} else {
1558
			echo '// share count bumped';
1559
		}
1560
		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...
1561
	}
1562
1563
	public function display_footer() {
1564
		/**
1565
		 * Filter the Pin it button appearing when hovering over images when using the official button style.
1566
		 *
1567
		 * @module sharedaddy
1568
		 *
1569
		 * @since 3.6.0
1570
		 *
1571
		 * @param bool $jetpack_pinit_over True by default, displays the Pin it button when hovering over images.
1572
		 */
1573
		$jetpack_pinit_over = apply_filters( 'jetpack_pinit_over_button', true );
1574
		?>
1575
		<?php if ( $this->smart ) : ?>
1576
			<script type="text/javascript">
1577
				// Pinterest shared resources
1578
				var s = document.createElement("script");
1579
				s.type = "text/javascript";
1580
				s.async = true;
1581
				<?php if ( $jetpack_pinit_over ) {
1582
				echo "s.setAttribute('data-pin-hover', true);";
1583
				} ?>
1584
				s.src = window.location.protocol + "//assets.pinterest.com/js/pinit.js";
1585
				var x = document.getElementsByTagName("script")[0];
1586
				x.parentNode.insertBefore(s, x);
1587
				// if 'Pin it' button has 'counts' make container wider
1588
				jQuery(window).load( function(){ jQuery( 'li.share-pinterest a span:visible' ).closest( '.share-pinterest' ).width( '80px' ); } );
1589
			</script>
1590
		<?php elseif ( 'buttonPin' != $this->get_widget_type() ) : ?>
1591
			<script type="text/javascript">
1592
				jQuery(document).ready( function(){
1593
					jQuery('body').on('click', 'a.share-pinterest', function(e){
1594
						e.preventDefault();
1595
						// Load Pinterest Bookmarklet code
1596
						var s = document.createElement("script");
1597
						s.type = "text/javascript";
1598
						s.src = window.location.protocol + "//assets.pinterest.com/js/pinmarklet.js?r=" + ( Math.random() * 99999999 );
1599
						var x = document.getElementsByTagName("script")[0];
1600
						x.parentNode.insertBefore(s, x);
1601
						// Trigger Stats
1602
						var s = document.createElement("script");
1603
						s.type = "text/javascript";
1604
						s.src = this + ( this.toString().indexOf( '?' ) ? '&' : '?' ) + 'js_only=1';
1605
						var x = document.getElementsByTagName("script")[0];
1606
						x.parentNode.insertBefore(s, x);
1607
					});
1608
				});
1609
			</script>
1610
		<?php endif;
1611
	}
1612
}
1613
1614
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...
1615
	public $shortname = 'pocket';
1616
	public $icon = '\f224';
1617
1618 View Code Duplication
	public function __construct( $id, array $settings ) {
1619
		parent::__construct( $id, $settings );
1620
1621
		if ( 'official' == $this->button_style ) {
1622
			$this->smart = true;
1623
		} else {
1624
			$this->smart = false;
1625
		}
1626
	}
1627
1628
	public function get_name() {
1629
		return __( 'Pocket', 'jetpack' );
1630
	}
1631
1632 View Code Duplication
	public function process_request( $post, array $post_data ) {
1633
		// Record stats
1634
		parent::process_request( $post, $post_data );
1635
1636
		$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 ) ) );
1637
		wp_redirect( $pocket_url );
1638
		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...
1639
	}
1640
1641
	public function get_display( $post ) {
1642
		if ( $this->smart ) {
1643
			$post_count = 'horizontal';
1644
1645
			$button = '';
1646
			$button .= '<div class="pocket_button">';
1647
			$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' ) );
1648
			$button .= '</div>';
1649
1650
			return $button;
1651 View Code Duplication
		} else {
1652
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Pocket', 'share to', 'jetpack' ), __( 'Click to share on Pocket', 'jetpack' ), 'share=pocket' );
1653
		}
1654
1655
	}
1656
1657 View Code Duplication
	function display_footer() {
1658
		if ( $this->smart ) :
1659
		?>
1660
		<script>
1661
		// Don't use Pocket's default JS as it we need to force init new Pocket share buttons loaded via JS.
1662
		function jetpack_sharing_pocket_init() {
1663
			jQuery.getScript( 'https://widgets.getpocket.com/v1/j/btn.js?v=1' );
1664
		}
1665
		jQuery( document ).ready( jetpack_sharing_pocket_init );
1666
		jQuery( document.body ).on( 'post-load', jetpack_sharing_pocket_init );
1667
		</script>
1668
		<?php
1669
		else :
1670
			$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1671
		endif;
1672
1673
	}
1674
1675
}
1676
1677
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...
1678
	public $shortname = 'telegram';
1679
1680
	public function __construct( $id, array $settings ) {
1681
		parent::__construct( $id, $settings );
1682
	}
1683
1684
	public function get_name() {
1685
		return __( 'Telegram', 'jetpack' );
1686
	}
1687 View Code Duplication
	public function process_request( $post, array $post_data ) {
1688
		// Record stats
1689
		parent::process_request( $post, $post_data );
1690
		$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 ) ) );
1691
		wp_redirect( $telegram_url );
1692
		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...
1693
	}
1694
1695
	public function get_display( $post ) {
1696
		return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Telegram', 'share to', 'jetpack' ), __( 'Click to share on Telegram', 'jetpack' ), 'share=telegram' );
1697
	}
1698
1699
	function display_footer() {
1700
		$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1701
	}
1702
}
1703
1704
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...
1705
	public $shortname = 'jetpack-whatsapp';
1706
1707
	public function __construct( $id, array $settings ) {
1708
		parent::__construct( $id, $settings );
1709
	}
1710
1711
	public function get_name() {
1712
		return __( 'WhatsApp', 'jetpack' );
1713
	}
1714
1715
	public function get_display( $post ) {
1716
		return $this->get_link( 'https://api.whatsapp.com/send?text=' . rawurlencode( $this->get_share_title( $post->ID ) . ' ' . $this->get_share_url( $post->ID ) ), _x( 'WhatsApp', 'share to', 'jetpack' ), __( 'Click to share on WhatsApp', 'jetpack' ) );
1717
	}
1718
}
1719
1720
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...
1721
	public $shortname = 'skype';
1722
	public $icon = '\f220';
1723
	private $share_type = 'default';
1724
1725 View Code Duplication
	public function __construct( $id, array $settings ) {
1726
		parent::__construct( $id, $settings );
1727
1728
		if ( isset( $settings['share_type'] ) ) {
1729
			$this->share_type = $settings['share_type'];
1730
		}
1731
1732
		if ( 'official' == $this->button_style ) {
1733
			$this->smart = true;
1734
		} else {
1735
			$this->smart = false;
1736
		}
1737
1738
	}
1739
1740
	public function get_name() {
1741
		return __( 'Skype', 'jetpack' );
1742
	}
1743
1744
	public function get_display( $post ) {
1745
		if ( $this->smart ) {
1746
			$skype_share_html = sprintf(
1747
				'<div class="skype-share" data-href="%1$s" data-lang="%2$s" data-style="small" data-source="jetpack" ></div>',
1748
				esc_attr( $this->get_share_url( $post->ID ) ),
1749
				'en-US'
1750
			);
1751
			return $skype_share_html;
1752
		}
1753
1754
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1755
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'skype' ) ) {
1756
			sharing_register_post_for_share_counts( $post->ID );
1757
		}
1758
		return $this->get_link(
1759
			$this->get_process_request_url( $post->ID ), _x( 'Skype', 'share to', 'jetpack' ), __( 'Click to share on Skype', 'jetpack' ), 'share=skype', 'sharing-skype-' . $post->ID );
1760
	}
1761
1762 View Code Duplication
	public function process_request( $post, array $post_data ) {
1763
		$skype_url = sprintf(
1764
			'https://web.skype.com/share?url=%1$s&lang=%2$s=&source=jetpack',
1765
			rawurlencode( $this->get_share_url( $post->ID ) ),
1766
			'en-US'
1767
		);
1768
1769
		// Record stats
1770
		parent::process_request( $post, $post_data );
1771
1772
		// Redirect to Skype
1773
		wp_redirect( $skype_url );
1774
		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...
1775
	}
1776
1777
	public function display_footer() {
1778
		if ( $this->smart ) :
1779
			?>
1780
			<script>
1781
				(function(r, d, s) {
1782
					r.loadSkypeWebSdkAsync = r.loadSkypeWebSdkAsync || function(p) {
1783
							var js, sjs = d.getElementsByTagName(s)[0];
1784
							if (d.getElementById(p.id)) { return; }
1785
							js = d.createElement(s);
1786
							js.id = p.id;
1787
							js.src = p.scriptToLoad;
1788
							js.onload = p.callback
1789
							sjs.parentNode.insertBefore(js, sjs);
1790
						};
1791
					var p = {
1792
						scriptToLoad: 'https://swx.cdn.skype.com/shared/v/latest/skypewebsdk.js',
1793
						id: 'skype_web_sdk'
1794
					};
1795
					r.loadSkypeWebSdkAsync(p);
1796
				})(window, document, 'script');
1797
			</script>
1798
			<?php
1799
		else :
1800
			$this->js_dialog( $this->shortname, array( 'width' => 305, 'height' => 665 ) );
1801
		endif;
1802
	}
1803
}
1804