Completed
Push — dependabot/npm_and_yarn/ini-1.... ( 6a445d...18502d )
by Yaroslav
08:59 queued 10s
created

Share_Pinterest::get_display()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 20

Duplication

Lines 3
Ratio 15 %

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 1
dl 3
loc 20
rs 9.6
c 0
b 0
f 0
1
<?php
2
3
use Automattic\Jetpack\Device_Detection\User_Agent_Info;
4
5
abstract class Sharing_Source {
6
	public	  $button_style;
7
	public	  $smart;
8
	protected $open_link_in_new;
9
	protected $id;
10
11
	public function __construct( $id, array $settings ) {
12
		$this->id = $id;
13
		/**
14
		 * Filter the way sharing links open.
15
		 *
16
		 * By default, sharing links open in a new window.
17
		 *
18
		 * @module sharedaddy
19
		 *
20
		 * @since 3.4.0
21
		 *
22
		 * @param bool true Should Sharing links open in a new window. Default to true.
23
		 */
24
		$this->open_link_in_new = apply_filters( 'jetpack_open_sharing_in_new_window', true );
25
26
		if ( isset( $settings['button_style'] ) ) {
27
			$this->button_style = $settings['button_style'];
28
		}
29
30
		if ( isset( $settings['smart'] ) ) {
31
			$this->smart = $settings['smart'];
32
		}
33
	}
34
35
	public function is_deprecated() {
36
		return false;
37
	}
38
39
	public function http() {
40
		return is_ssl() ? 'https' : 'http';
41
	}
42
43
	public function get_id() {
44
		return $this->id;
45
	}
46
47
	public function get_class() {
48
		return $this->id;
49
	}
50
51
	public function get_share_url( $post_id ) {
52
		/**
53
		 * Filter the sharing permalink.
54
		 *
55
		 * @module sharedaddy
56
		 *
57
		 * @since 1.2.0
58
		 *
59
		 * @param string get_permalink( $post_id ) Post Permalink.
60
		 * @param int $post_id Post ID.
61
		 * @param int $this->id Sharing ID.
62
		 */
63
		return apply_filters( 'sharing_permalink', get_permalink( $post_id ), $post_id, $this->id );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post_id.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
64
	}
65
66
	public function get_share_title( $post_id ) {
67
		$post = get_post( $post_id );
68
		/**
69
		 * Filter the sharing title.
70
		 *
71
		 * @module sharedaddy
72
		 *
73
		 * @since 2.8.0
74
		 *
75
		 * @param string $post->post_title Post Title.
76
		 * @param int $post_id Post ID.
77
		 * @param int $this->id Sharing ID.
78
		 */
79
		$title = apply_filters( 'sharing_title', $post->post_title, $post_id, $this->id );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post_id.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
80
81
		return html_entity_decode( wp_kses( $title, null ) );
82
	}
83
84
	public function has_custom_button_style() {
85
		return false;
86
	}
87
88
	public function get_link( $url, $text, $title, $query = '', $id = false ) {
89
		$args = func_get_args();
90
		$klasses = array( 'share-' . $this->get_class(), 'sd-button' );
91
92
		if ( 'icon' == $this->button_style || 'icon-text' == $this->button_style ) {
93
			$klasses[] = 'share-icon';
94
		}
95
96
		if ( 'icon' == $this->button_style ) {
97
			$text = $title;
98
			$klasses[] = 'no-text';
99
100
			if ( true == $this->open_link_in_new ) {
101
				$text .= __( ' (Opens in new window)', 'jetpack' );
102
			}
103
		}
104
105
		/**
106
		 * Filter the sharing display ID.
107
		 *
108
		 * @module sharedaddy
109
		 *
110
		 * @since 3.4.0
111
		 *
112
		 * @param int|false $id Sharing ID.
113
		 * @param object $this Sharing service properties.
114
		 * @param array $args Array of sharing service options.
115
		 */
116
		$id = apply_filters( 'jetpack_sharing_display_id', $id, $this, $args );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $this.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
117
		/**
118
		 * Filter the sharing display link.
119
		 *
120
		 * @module sharedaddy
121
		 *
122
		 * @since 2.8.0
123
		 *
124
		 * @param string $url Post URL.
125
		 * @param object $this Sharing service properties.
126
		 * @param int|false $id Sharing ID.
127
		 * @param array $args Array of sharing service options.
128
		 */
129
		$url = apply_filters( 'sharing_display_link', $url, $this, $id, $args ); // backwards compatibility
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $this.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
130
		/**
131
		 * Filter the sharing display link.
132
		 *
133
		 * @module sharedaddy
134
		 *
135
		 * @since 2.8.0
136
		 *
137
		 * @param string $url Post URL.
138
		 * @param object $this Sharing service properties.
139
		 * @param int|false $id Sharing ID.
140
		 * @param array $args Array of sharing service options.
141
		 */
142
		$url = apply_filters( 'jetpack_sharing_display_link', $url, $this, $id, $args );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $this.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
143
		/**
144
		 * Filter the sharing display query.
145
		 *
146
		 * @module sharedaddy
147
		 *
148
		 * @since 2.8.0
149
		 *
150
		 * @param string $query Sharing service URL parameter.
151
		 * @param object $this Sharing service properties.
152
		 * @param int|false $id Sharing ID.
153
		 * @param array $args Array of sharing service options.
154
		 */
155
		$query = apply_filters( 'jetpack_sharing_display_query', $query, $this, $id, $args );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $this.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
156
157
		if ( ! empty( $query ) ) {
158
			if ( false === stripos( $url, '?' ) ) {
159
				$url .= '?' . $query;
160
			} else {
161
				$url .= '&amp;' . $query;
162
			}
163
		}
164
165
		if ( 'text' == $this->button_style ) {
166
			$klasses[] = 'no-icon';
167
		}
168
169
		/**
170
		 * Filter the sharing display classes.
171
		 *
172
		 * @module sharedaddy
173
		 *
174
		 * @since 3.4.0
175
		 *
176
		 * @param array $klasses Sharing service classes.
177
		 * @param object $this Sharing service properties.
178
		 * @param int|false $id Sharing ID.
179
		 * @param array $args Array of sharing service options.
180
		 */
181
		$klasses = apply_filters( 'jetpack_sharing_display_classes', $klasses, $this, $id, $args );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $this.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
182
		/**
183
		 * Filter the sharing display title.
184
		 *
185
		 * @module sharedaddy
186
		 *
187
		 * @since 3.4.0
188
		 *
189
		 * @param string $title Sharing service title.
190
		 * @param object $this Sharing service properties.
191
		 * @param int|false $id Sharing ID.
192
		 * @param array $args Array of sharing service options.
193
		 */
194
		$title = apply_filters( 'jetpack_sharing_display_title', $title, $this, $id, $args );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $this.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
195
		/**
196
		 * Filter the sharing display text.
197
		 *
198
		 * @module sharedaddy
199
		 *
200
		 * @since 3.4.0
201
		 *
202
		 * @param string $text Sharing service text.
203
		 * @param object $this Sharing service properties.
204
		 * @param int|false $id Sharing ID.
205
		 * @param array $args Array of sharing service options.
206
		 */
207
		$text = apply_filters( 'jetpack_sharing_display_text', $text, $this, $id, $args );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $this.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
208
209
		return sprintf(
210
			'<a rel="nofollow%s" data-shared="%s" class="%s" href="%s"%s title="%s"><span%s>%s</span></a>',
211
			( true == $this->open_link_in_new ) ? ' noopener noreferrer' : '',
212
			( $id ? esc_attr( $id ) : '' ),
213
			implode( ' ', $klasses ),
214
			$url,
215
			( true == $this->open_link_in_new ) ? ' target="_blank"' : '',
216
			$title,
217
			( 'icon' == $this->button_style ) ? '></span><span class="sharing-screen-reader-text"' : '',
218
			$text
219
		);
220
	}
221
222
	/**
223
	 * Get an unfiltered post permalink to use when generating a sharing URL with get_link.
224
	 * Use instead of get_share_url for non-official styles as get_permalink ensures that process_request
225
	 * will be executed more reliably, in the case that the filtered URL uses a service that strips query parameters.
226
	 *
227
	 * @since 3.7.0
228
	 * @param int $post_id Post ID.
229
	 * @uses get_permalink
230
	 * @return string get_permalink( $post_id ) Post permalink.
231
	 */
232
	public function get_process_request_url( $post_id ) {
233
		return get_permalink( $post_id );
234
	}
235
236
	abstract public function get_name();
237
	abstract public function get_display( $post );
238
239
	public function display_header() {
240
	}
241
242
	public function display_footer() {
243
	}
244
245
	public function has_advanced_options() {
246
		return false;
247
	}
248
249
	/**
250
	 * Get the AMP specific markup for a sharing button.
251
	 *
252
	 * @param \WP_Post $post The current post being viewed.
253
	 */
254
	public function get_amp_display( $post ) {
255
		// Only display markup if we're on a post.
256
		if ( empty( $post ) ) {
257
			return false;
258
		}
259
260
		return $this->build_amp_markup();
261
	}
262
263
	/**
264
	 * Generates and returns the markup for an AMP sharing button.
265
	 *
266
	 * @param array $attrs Custom attributes for rendering the social icon.
267
	 */
268
	protected function build_amp_markup( $attrs = array() ) {
269
270
		$title = sprintf(
271
			/* translators: placeholder is a service name, such as "Twitter" or "Facebook". */
272
			__( 'Click to share on %s', 'jetpack' ),
273
			$this->get_name()
274
		);
275
276
		$attrs        = array_merge(
277
			array(
278
				'type'       => $this->get_id(),
279
				'height'     => '32px',
280
				'width'      => '32px',
281
				'aria-label' => $title,
282
				'title'      => $title,
283
			),
284
			$attrs
285
		);
286
		$sharing_link = '<amp-social-share';
287
		foreach ( $attrs as $key => $value ) {
288
			$sharing_link .= sprintf( ' %s="%s"', sanitize_key( $key ), esc_attr( $value ) );
289
		}
290
		$sharing_link .= '></amp-social-share>';
291
		return $sharing_link;
292
	}
293
294
	public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
295
		$text = '&nbsp;';
296
		$button_style = ( ! empty( $button_style ) ) ? $button_style : $this->button_style;
297
		if ( ! $this->smart && ! $force_smart ) {
298
			if ( $button_style != 'icon' ) {
299
				$text = $this->get_name();
300
			}
301
		}
302
303
		$klasses = array( 'share-' . $this->get_class(), 'sd-button' );
304
305
		if ( $button_style == 'icon' || $button_style == 'icon-text' ) {
306
			$klasses[] = 'share-icon';
307
		}
308
309
		if ( $button_style == 'icon' ) {
310
			$klasses[] = 'no-text';
311
		}
312
313
		if ( $button_style == 'text' ) {
314
			$klasses[] = 'no-icon';
315
		}
316
317
		$is_deprecated = $this->is_deprecated();
318
319
		$link = sprintf(
320
			'<a rel="nofollow" class="%s" href="javascript:void(0)" title="%s"><span>%s</span></a>',
321
			implode( ' ', $klasses ),
322
			esc_attr(
323
				$is_deprecated
324
					/* translators: %1$s is the name of a deprecated Sharing Service like "Google+" */
325
					? sprintf( __( 'The %1$s service has shut down. This sharing button is not displayed to your visitors and should be removed.', 'jetpack' ), $this->get_name() )
326
					: $this->get_name()
327
			),
328
			esc_html(
329
				$is_deprecated
330
					/* translators: %1$s is the name of a deprecated Sharing Service like "Google+" */
331
					? sprintf( __( '%1$s has shut down', 'jetpack' ), $this->get_name() )
332
					: $text
333
			)
334
		);
335
336
		$smart = ( $this->smart || $force_smart ) ? 'on' : 'off';
337
		$return = "<div class='option option-smart-$smart'>$link</div>";
338
		if ( $echo ) {
339
			echo $return;
340
		}
341
342
		return $return;
343
	}
344
345
	public function get_total( $post = false ) {
346
		global $wpdb, $blog_id;
347
348
		$name = strtolower( $this->get_id() );
349
350
		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...
351
			// get total number of shares for service
352
			return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND share_service = %s', $blog_id, $name ) );
353
		}
354
355
		// get total shares for a post
356
		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 ) );
357
	}
358
359 View Code Duplication
	public function get_posts_total() {
360
		global $wpdb, $blog_id;
361
362
		$totals = array();
363
		$name	= strtolower( $this->get_id() );
364
365
		$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 ) );
366
367
		if ( ! empty( $my_data ) ) {
368
			foreach ( $my_data as $row ) {
369
				$totals[] = new Sharing_Post_Total( $row->id, $row->total );
370
			}
371
		}
372
373
		usort( $totals, array( 'Sharing_Post_Total', 'cmp' ) );
374
375
		return $totals;
376
	}
377
378
	public function process_request( $post, array $post_data ) {
379
		/**
380
		 * Fires when a post is shared via one of the sharing buttons.
381
		 *
382
		 * @module sharedaddy
383
		 *
384
		 * @since 1.1.0
385
		 *
386
		 * @param array $args Aray of information about the sharing service.
387
		 */
388
		do_action( 'sharing_bump_stats', array( 'service' => $this, 'post' => $post ) );
389
	}
390
391
	public function js_dialog( $name, $params = array() ) {
392
		if ( true !== $this->open_link_in_new ) {
393
			return;
394
		}
395
396
		$defaults = array(
397
			'menubar'	=> 1,
398
			'resizable' => 1,
399
			'width'		=> 600,
400
			'height'	=> 400,
401
		);
402
		$params = array_merge( $defaults, $params );
403
		$opts = array();
404
		foreach ( $params as $key => $val ) {
405
			$opts[] = "$key=$val";
406
		}
407
		$opts = implode( ',', $opts );
408
409
		// Add JS after sharing-js has been enqueued.
410
		wp_add_inline_script( 'sharing-js',
411
			"var windowOpen;
412
			document.body.addEventListener( 'click', function ( event ) {
413
				if ( event.target && (
414
					event.target.matches && event.target.matches( 'a.share-$name' ) ||
415
					event.target.msMatchesSelector && event.target.msMatchesSelector( 'a.share-$name' )
416
				) ) {
417
					// If there's another sharing window open, close it.
418
					if ( typeof windowOpen !== 'undefined' ) {
419
						windowOpen.close();
420
					}
421
					windowOpen = window.open( event.target.getAttribute( 'href' ), 'wpcom$name', '$opts' );
422
					return false;
423
				}
424
			} );"
425
		);
426
	}
427
}
428
429
abstract class Deprecated_Sharing_Source extends Sharing_Source {
430
	public	  $button_style = 'text';
431
	public	  $smart = false;
432
	protected $open_link_in_new = false;
433
	protected $id;
434
	protected $deprecated = true;
435
436
	final public function __construct( $id, array $settings ) {
437
		$this->id = $id;
438
439
		if ( isset( $settings['button_style'] ) ) {
440
			$this->button_style = $settings['button_style'];
441
		}
442
	}
443
444
	final public function is_deprecated() {
445
		return true;
446
	}
447
448
	final public function get_share_url( $post_id ) {
449
		return get_permalink( $post_id );
450
	}
451
452
	/**
453
	 * No AMP display for deprecated sources.
454
	 *
455
	 * @param \WP_Post $post The current post being viewed.
456
	 */
457
	final public function get_amp_display( $post ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
458
		return false;
459
	}
460
461
	final public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
462
		return parent::display_preview( $echo, false, $button_style );
463
	}
464
465
	final public function get_total( $post = false ) {
466
		return 0;
467
	}
468
469
	final public function get_posts_total() {
470
		return 0;
471
	}
472
473
	final public function process_request( $post, array $post_data ) {
474
		parent::process_request( $post, $post_data );
475
	}
476
477
	final public function get_display( $post ) {
478
		if ( current_user_can( 'manage_options' ) ) {
479
			return $this->display_deprecated( $post );
480
		}
481
482
		return '';
483
	}
484
485
	public function display_deprecated( $post ) {
486
		return $this->get_link(
487
			$this->get_share_url( $post->ID ),
488
			/* translators: %1$s is the name of a deprecated Sharing Service like "Google+" */
489
			sprintf( __( '%1$s has shut down', 'jetpack' ), $this->get_name() ),
490
			/* translators: %1$s is the name of a deprecated Sharing Service like "Google+" */
491
			sprintf( __( 'The %1$s service has shut down. This sharing button is not displayed to your visitors and should be removed.', 'jetpack' ), $this->get_name() )
492
		);
493
	}
494
}
495
496
abstract class Sharing_Advanced_Source extends Sharing_Source {
497
	public function has_advanced_options() {
498
		return true;
499
	}
500
501
	abstract public function display_options();
502
	abstract public function update_options( array $data );
503
	abstract public function get_options();
504
}
505
506
class Share_Email extends Sharing_Source {
507
	public $shortname = 'email';
508
	public $icon = '\f410';
509 View Code Duplication
	public function __construct( $id, array $settings ) {
510
		parent::__construct( $id, $settings );
511
512
		if ( 'official' == $this->button_style ) {
513
			$this->smart = true;
514
		} else {
515
			$this->smart = false;
516
		}
517
	}
518
519
	public function get_name() {
520
		return _x( 'Email', 'as sharing source', 'jetpack' );
521
	}
522
523
	// Default does nothing
524
	public function process_request( $post, array $post_data ) {
525
		$ajax = false;
526
		if ( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) == 'xmlhttprequest' ) {
527
			$ajax = true;
528
		}
529
530
		$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...
531
532
		if ( isset( $post_data['source_email'] ) && is_email( $post_data['source_email'] ) ) {
533
			$source_email = $post_data['source_email'];
534
		}
535
536
		if ( isset( $post_data['target_email'] ) && is_email( $post_data['target_email'] ) ) {
537
			$target_email = $post_data['target_email'];
538
		}
539
540
		if ( isset( $post_data['source_name'] ) && strlen( $post_data['source_name'] ) < 200 ) {
541
			$source_name = $post_data['source_name'];
542
		} elseif ( isset( $post_data['source_name'] ) ) {
543
			$source_name = substr( $post_data['source_name'], 0, 200 );
544
		} else {
545
			$source_name = '';
546
		}
547
548
		// Test email
549
		$error = 1;	  // Failure in data
550
		if ( empty( $post_data['source_f_name'] ) && $source_email && $target_email && $source_name ) {
551
			/**
552
			 * Allow plugins to stop the email sharing button from running the shared message through Akismet.
553
			 *
554
			 * @module sharedaddy
555
			 *
556
			 * @since 1.1.0
557
			 *
558
			 * @param bool true Should we check if the message isn't spam?
559
			 * @param object $post Post information.
560
			 * @param array $post_data Information about the shared message.
561
			 */
562
			if ( apply_filters( 'sharing_email_check', true, $post, $post_data ) ) {
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
563
				$data = array(
564
					'post'           => $post,
565
					'source'         => $source_email,
566
					'target'         => $target_email,
567
					'name'           => $source_name,
568
					'sharing_source' => $this,
569
				);
570
				// todo: implement an error message when email doesn't get sent.
571
				/**
572
				 * Filter whether an email can be sent from the Email sharing button.
573
				 *
574
				 * @module sharedaddy
575
				 *
576
				 * @since 1.1.0
577
				 *
578
				 * @param array $data Array of information about the shared message.
579
				 */
580
				if ( ( $data = apply_filters( 'sharing_email_can_send', $data ) ) !== false ) {
581
					// Record stats
582
					parent::process_request( $data['post'], $post_data );
583
584
					/**
585
					 * Fires when an email is sent via the Email sharing button.
586
					 *
587
					 * @module sharedaddy
588
					 *
589
					 * @since 1.1.0
590
					 *
591
					 * @param array $data Array of information about the shared message.
592
					 */
593
					do_action( 'sharing_email_send_post', $data );
594
				}
595
596
				// Return a positive regardless of whether the user is subscribed or not
597
				if ( $ajax ) {
598
?>
599
<div class="response">
600
	<div class="response-title"><?php _e( 'This post has been shared!', 'jetpack' ); ?></div>
601
	<div class="response-sub"><?php printf( __( 'You have shared this post with %s', 'jetpack' ), esc_html( $target_email ) ); ?></div>
602
	<div class="response-close"><a href="#" class="sharing_cancel"><?php _e( 'Close', 'jetpack' ); ?></a></div>
603
</div>
604
<?php
605
				} else {
606
					wp_safe_redirect( get_permalink( $post->ID ) . '?shared=email' );
607
				}
608
609
				die();
610
			} else {
611
				$error = 2;	  // Email check failed
612
			}
613
		}
614
615
		if ( $ajax ) {
616
			echo $error;
617
		} else {
618
			wp_safe_redirect( get_permalink( $post->ID ) . '?shared=email&msg=fail' );
619
		}
620
621
		die();
622
	}
623
624
	public function get_display( $post ) {
625
		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' );
626
	}
627
628
	/**
629
	 * No AMP display for email.
630
	 *
631
	 * @param \WP_Post $post The current post being viewed.
632
	 */
633
	public function get_amp_display( $post ) { // phpcs:ignore
634
		return false;
635
	}
636
637
	/**
638
	 * Outputs the hidden email dialog
639
	 */
640
	public function display_footer() {
641
		global $current_user;
642
643
		$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...
644
?>
645
	<div id="sharing_email" style="display: none;">
646
		<form action="<?php echo esc_url( $_SERVER['REQUEST_URI'] ); ?>" method="post">
647
			<label for="target_email"><?php _e( 'Send to Email Address', 'jetpack' ) ?></label>
648
			<input type="email" name="target_email" id="target_email" value="" />
649
650
			<?php if ( is_user_logged_in() ) : ?>
651
				<input type="hidden" name="source_name" value="<?php echo esc_attr( $current_user->display_name ); ?>" />
652
				<input type="hidden" name="source_email" value="<?php echo esc_attr( $current_user->user_email ); ?>" />
653
			<?php else : ?>
654
655
				<label for="source_name"><?php _e( 'Your Name', 'jetpack' ) ?></label>
656
				<input type="text" name="source_name" id="source_name" value="" />
657
658
				<label for="source_email"><?php _e( 'Your Email Address', 'jetpack' ) ?></label>
659
				<input type="email" name="source_email" id="source_email" value="" />
660
661
			<?php endif; ?>
662
			<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' ); ?>" />
663
			<?php
664
				/**
665
				 * Fires when the Email sharing dialog is loaded.
666
				 *
667
				 * @module sharedaddy
668
				 *
669
				 * @since 1.1.0
670
				 *
671
				 * @param string jetpack Eail sharing source.
672
				 */
673
				do_action( 'sharing_email_dialog', 'jetpack' );
674
			?>
675
676
			<img style="float: right; display: none" class="loading" src="<?php
677
			/** This filter is documented in modules/stats.php */
678
			echo apply_filters( 'jetpack_static_url', plugin_dir_url( __FILE__ ) . 'images/loading.gif' ); ?>" alt="loading" width="16" height="16" />
679
			<input type="submit" value="<?php esc_attr_e( 'Send Email', 'jetpack' ); ?>" class="sharing_send" />
680
			<a rel="nofollow" href="#cancel" class="sharing_cancel" role="button"><?php _e( 'Cancel', 'jetpack' ); ?></a>
681
682
			<div class="errors errors-1" style="display: none;">
683
				<?php _e( 'Post was not sent - check your email addresses!', 'jetpack' ); ?>
684
			</div>
685
686
			<div class="errors errors-2" style="display: none;">
687
				<?php _e( 'Email check failed, please try again', 'jetpack' ); ?>
688
			</div>
689
690
			<div class="errors errors-3" style="display: none;">
691
				<?php _e( 'Sorry, your blog cannot share posts by email.', 'jetpack' ); ?>
692
			</div>
693
		</form>
694
	</div>
695
<?php
696
	}
697
}
698
699
class Share_Twitter extends Sharing_Source {
700
	public $shortname = 'twitter';
701
	public $icon = '\f202';
702
	// 'https://dev.twitter.com/rest/reference/get/help/configuration' ( 2015/02/06 ) short_url_length is 22, short_url_length_https is 23
703
	public $short_url_length = 24;
704
705 View Code Duplication
	public function __construct( $id, array $settings ) {
706
		parent::__construct( $id, $settings );
707
708
		if ( 'official' == $this->button_style ) {
709
			$this->smart = true;
710
		} else {
711
			$this->smart = false;
712
		}
713
	}
714
715
	public function get_name() {
716
		return __( 'Twitter', 'jetpack' );
717
	}
718
719
	/**
720
	 * Determine the Twitter 'via' value for a post.
721
	 *
722
	 * @param  WP_Post|int $post Post object or post ID.
723
	 * @return string Twitter handle without the preceding @.
724
	 **/
725
	public static function sharing_twitter_via( $post ) {
726
		$post = get_post( $post );
727
		/**
728
		 * Allow third-party plugins to customize the Twitter username used as "twitter:site" Twitter Card Meta Tag.
729
		 *
730
		 * @module sharedaddy
731
		 *
732
		 * @since 3.0.0
733
		 *
734
		 * @param string $string Twitter Username.
735
		 * @param array $args Array of Open Graph Meta Tags and Twitter Cards tags.
736
		 */
737
		$twitter_site_tag_value = apply_filters(
738
			'jetpack_twitter_cards_site_tag',
739
			'',
740
			/** This action is documented in modules/sharedaddy/sharing-sources.php */
741
			array( 'twitter:creator' => apply_filters( 'jetpack_sharing_twitter_via', '', $post->ID ) )
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post->ID.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Unused Code introduced by
The call to apply_filters() has too many arguments starting with array('twitter:creator' ...r_via', '', $post->ID)).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
742
		);
743
744
		/*
745
		 * Hack to remove the unwanted behavior of adding 'via @jetpack' which
746
		 * was introduced with the adding of the Twitter cards.
747
		 * This should be a temporary solution until a better method is setup.
748
		 */
749
		if ( 'jetpack' == $twitter_site_tag_value ) {
750
			$twitter_site_tag_value = '';
751
		}
752
753
		/**
754
		 * Filters the Twitter username used as "via" in the Twitter sharing button.
755
		 *
756
		 * @module sharedaddy
757
		 *
758
		 * @since 1.7.0
759
		 *
760
		 * @param string $twitter_site_tag_value Twitter Username.
761
		 * @param int $post->ID Post ID.
762
		 */
763
		$twitter_site_tag_value = apply_filters( 'jetpack_sharing_twitter_via', $twitter_site_tag_value, $post->ID );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post->ID.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
764
765
		// Strip out anything other than a letter, number, or underscore.
766
		// This will prevent the inadvertent inclusion of an extra @, as well as normalizing the handle.
767
		return preg_replace( '/[^\da-z_]+/i', '', $twitter_site_tag_value );
768
	}
769
770
	/**
771
	 * Determine the 'related' Twitter accounts for a post.
772
	 *
773
	 * @param  WP_Post|int $post Post object or post ID.
774
	 * @return string Comma-separated list of Twitter handles.
775
	 **/
776
	public static function get_related_accounts( $post ) {
777
		$post = get_post( $post );
778
		/**
779
		 * Filter the list of related Twitter accounts added to the Twitter sharing button.
780
		 *
781
		 * @module sharedaddy
782
		 *
783
		 * @since 1.7.0
784
		 *
785
		 * @param array $args Array of Twitter usernames. Format is 'username' => 'Optional description'
786
		 * @param int $post->ID Post ID.
787
		 */
788
		$related_accounts = apply_filters( 'jetpack_sharing_twitter_related', array(), $post->ID );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post->ID.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
789
790
		// Example related string: account1,account2:Account 2 description,account3
791
		$related = array();
792
793
		foreach ( $related_accounts as $related_account_username => $related_account_description ) {
794
			// Join the description onto the end of the username
795
			if ( $related_account_description ) {
796
				$related_account_username .= ':' . $related_account_description;
797
			}
798
799
			$related[] = $related_account_username;
800
		}
801
802
		return implode( ',', $related );
803
	}
804
805
	public function get_display( $post ) {
806
		$via = $this->sharing_twitter_via( $post );
807
808
		if ( $via ) {
809
			$via = 'data-via="' . esc_attr( $via ) . '"';
810
		} else {
811
			$via = '';
812
		}
813
814
		$related = $this->get_related_accounts( $post );
815
		if ( ! empty( $related ) && $related !== $via ) {
816
			$related = 'data-related="' . esc_attr( $related ) . '"';
817
		} else {
818
			$related = '';
819
		}
820
821
		if ( $this->smart ) {
822
			$share_url = $this->get_share_url( $post->ID );
823
			$post_title = $this->get_share_title( $post->ID );
824
			return sprintf(
825
				'<a href="https://twitter.com/share" class="twitter-share-button" data-url="%1$s" data-text="%2$s" %3$s %4$s>Tweet</a>',
826
				esc_url( $share_url ),
827
				esc_attr( $post_title ),
828
				$via,
829
				$related
830
			);
831
		} else {
832
			if (
833
				/**
834
				 * Allow plugins to disable sharing counts for specific sharing services.
835
				 *
836
				 * @module sharedaddy
837
				 *
838
				 * @since 3.0.0
839
				 *
840
				 * @param bool true Should sharing counts be enabled for this specific service. Default to true.
841
				 * @param int $post->ID Post ID.
842
				 * @param string $str Sharing service name.
843
				 */
844
				apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'twitter' )
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post->ID.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
845
			) {
846
				sharing_register_post_for_share_counts( $post->ID );
847
			}
848
			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 );
849
		}
850
	}
851
852
	public function process_request( $post, array $post_data ) {
853
		$post_title = $this->get_share_title( $post->ID );
854
		$post_link = $this->get_share_url( $post->ID );
855
856
		if ( function_exists( 'mb_stripos' ) ) {
857
			$strlen = 'mb_strlen';
858
			$substr = 'mb_substr';
859
		} else {
860
			$strlen = 'strlen';
861
			$substr = 'substr';
862
		}
863
864
		$via = $this->sharing_twitter_via( $post );
865
		$related = $this->get_related_accounts( $post );
866
		if ( $via ) {
867
			$sig = " via @$via";
868
			if ( $related === $via ) {
869
				$related = false;
870
			}
871
		} else {
872
			$via = false;
873
			$sig = '';
874
		}
875
876
		$suffix_length = $this->short_url_length + $strlen( $sig );
877
		// $sig is handled by twitter in their 'via' argument.
878
		// $post_link is handled by twitter in their 'url' argument.
879
		if ( 280 < $strlen( $post_title ) + $suffix_length ) {
880
			// The -1 is for "\xE2\x80\xA6", a UTF-8 ellipsis.
881
			$text = $substr( $post_title, 0, 280 - $suffix_length - 1 ) . "\xE2\x80\xA6";
882
		} else {
883
			$text = $post_title;
884
		}
885
886
		// Record stats
887
		parent::process_request( $post, $post_data );
888
889
		$url = $post_link;
890
		$twitter_url = add_query_arg(
891
			rawurlencode_deep( array_filter( compact( 'via', 'related', 'text', 'url' ) ) ),
892
			'https://twitter.com/intent/tweet'
893
		);
894
895
		// Redirect to Twitter
896
		wp_redirect( $twitter_url );
897
		die();
898
	}
899
900
	public function has_custom_button_style() {
901
		return $this->smart;
902
	}
903
904
	public function display_footer() {
905
		if ( $this->smart ) {
906
			?>
907
			<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>
908
			<?php
909
		} else {
910
			$this->js_dialog( $this->shortname, array( 'height' => 350 ) );
911
		}
912
	}
913
}
914
915
916
class Share_Reddit extends Sharing_Source {
917
	public $shortname = 'reddit';
918
	public $icon = '\f222';
919 View Code Duplication
	public function __construct( $id, array $settings ) {
920
		parent::__construct( $id, $settings );
921
922
		if ( 'official' == $this->button_style ) {
923
			$this->smart = true;
924
		} else {
925
			$this->smart = false;
926
		}
927
	}
928
929
	public function get_name() {
930
		return __( 'Reddit', 'jetpack' );
931
	}
932
933
	public function get_display( $post ) {
934
		if ( $this->smart ) {
935
			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>';
936 View Code Duplication
		} else {
937
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Reddit', 'share to', 'jetpack' ), __( 'Click to share on Reddit', 'jetpack' ), 'share=reddit' );
938
		}
939
	}
940
941
	/**
942
	 * AMP display for Reddit.
943
	 *
944
	 * @param \WP_Post $post The current post being viewed.
945
	 */
946 View Code Duplication
	public function get_amp_display( $post ) {
947
		$attrs = array(
948
			'data-share-endpoint' => esc_url_raw( 'https://reddit.com/submit?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) ) ),
949
		);
950
951
		return $this->build_amp_markup( $attrs );
952
	}
953
954 View Code Duplication
	public function process_request( $post, array $post_data ) {
955
		$reddit_url = $this->http() . '://reddit.com/submit?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) );
956
957
		// Record stats
958
		parent::process_request( $post, $post_data );
959
960
		// Redirect to Reddit
961
		wp_redirect( $reddit_url );
962
		die();
963
	}
964
}
965
966
class Share_LinkedIn extends Sharing_Source {
967
	public $shortname = 'linkedin';
968
	public $icon = '\f207';
969 View Code Duplication
	public function __construct( $id, array $settings ) {
970
		parent::__construct( $id, $settings );
971
972
		if ( 'official' == $this->button_style ) {
973
			$this->smart = true;
974
		} else {
975
			$this->smart = false;
976
		}
977
	}
978
979
	public function get_name() {
980
		return __( 'LinkedIn', 'jetpack' );
981
	}
982
983
	public function has_custom_button_style() {
984
		return $this->smart;
985
	}
986
987
	public function get_display( $post ) {
988
		$display = '';
989
990
		if ( $this->smart ) {
991
			$share_url = $this->get_share_url( $post->ID );
992
			$display .= sprintf( '<div class="linkedin_button"><script type="in/share" data-url="%s" data-counter="right"></script></div>', esc_url( $share_url ) );
993 View Code Duplication
		} else {
994
			$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 );
995
		}
996
997
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
998
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'linkedin' ) ) {
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post->ID.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
999
			sharing_register_post_for_share_counts( $post->ID );
1000
		}
1001
1002
		return $display;
1003
	}
1004
1005 View Code Duplication
	public function process_request( $post, array $post_data ) {
1006
1007
		$post_link = $this->get_share_url( $post->ID );
1008
1009
		// Using the same URL as the official button, which is *not* LinkedIn's documented sharing link
1010
		// https://www.linkedin.com/cws/share?url={url}&token=&isFramed=false
1011
		$linkedin_url = add_query_arg( array(
1012
			'url' => rawurlencode( $post_link ),
1013
		), 'https://www.linkedin.com/cws/share?token=&isFramed=false' );
1014
1015
		// Record stats
1016
		parent::process_request( $post, $post_data );
1017
1018
		// Redirect to LinkedIn
1019
		wp_redirect( $linkedin_url );
1020
		die();
1021
	}
1022
1023 View Code Duplication
	public function display_footer() {
1024
		if ( ! $this->smart ) {
1025
			$this->js_dialog( $this->shortname, array( 'width' => 580, 'height' => 450 ) );
1026
		} else {
1027
			?>
1028
			<script type="text/javascript">
1029
				( function () {
1030
					var currentScript = document.currentScript;
1031
1032
					// Helper function to load an external script.
1033
					function loadScript( url, cb ) {
1034
						var script = document.createElement( 'script' );
1035
						var prev = currentScript || document.getElementsByTagName( 'script' )[ 0 ];
1036
						script.setAttribute( 'async', true );
1037
						script.setAttribute( 'src', url );
1038
						script.setAttribute( 'onload', cb );
1039
						prev.parentNode.insertBefore( script, prev );
1040
					}
1041
1042
					function init() {
1043
						loadScript( 'https://platform.linkedin.com/in.js?async=true', function () {
1044
							if ( typeof IN !== 'undefined' ) {
1045
								IN.init();
1046
							}
1047
						} );
1048
					}
1049
1050
					if ( document.readyState === 'loading' ) {
1051
						document.addEventListener( 'DOMContentLoaded', init );
1052
					} else {
1053
						init();
1054
					}
1055
1056
					document.body.addEventListener( 'is.post-load', function() {
1057
						if ( typeof IN !== 'undefined' ) {
1058
							IN.parse();
1059
						}
1060
					} );
1061
				} )();
1062
			</script>
1063
			<?php
1064
		}
1065
	}
1066
}
1067
1068
class Share_Facebook extends Sharing_Source {
1069
	public $shortname = 'facebook';
1070
	public $icon = '\f204';
1071
	private $share_type = 'default';
1072
1073 View Code Duplication
	public function __construct( $id, array $settings ) {
1074
		parent::__construct( $id, $settings );
1075
1076
		if ( isset( $settings['share_type'] ) ) {
1077
			$this->share_type = $settings['share_type'];
1078
		}
1079
1080
		if ( 'official' == $this->button_style ) {
1081
			$this->smart = true;
1082
		} else {
1083
			$this->smart = false;
1084
		}
1085
	}
1086
1087
	public function get_name() {
1088
		return __( 'Facebook', 'jetpack' );
1089
	}
1090
1091
	public function display_header() {
1092
	}
1093
1094 View Code Duplication
	function guess_locale_from_lang( $lang ) {
1095
		if ( 'en' == $lang || 'en_US' == $lang || ! $lang ) {
1096
			return 'en_US';
1097
		}
1098
1099
		if ( ! class_exists( 'GP_Locales' ) ) {
1100
			if ( ! defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) || ! file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) {
1101
				return false;
1102
			}
1103
1104
			require JETPACK__GLOTPRESS_LOCALES_PATH;
1105
		}
1106
1107
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
1108
			// WP.com: get_locale() returns 'it'
1109
			$locale = GP_Locales::by_slug( $lang );
1110
		} else {
1111
			// Jetpack: get_locale() returns 'it_IT';
1112
			$locale = GP_Locales::by_field( 'wp_locale', $lang );
1113
		}
1114
1115
		if ( ! $locale ) {
1116
			return false;
1117
		}
1118
1119
		if ( empty( $locale->facebook_locale ) ) {
1120
			if ( empty( $locale->wp_locale ) ) {
1121
				return false;
1122
			} else {
1123
				// Facebook SDK is smart enough to fall back to en_US if a
1124
				// locale isn't supported. Since supported Facebook locales
1125
				// can fall out of sync, we'll attempt to use the known
1126
				// wp_locale value and rely on said fallback.
1127
				return $locale->wp_locale;
1128
			}
1129
		}
1130
1131
		return $locale->facebook_locale;
1132
	}
1133
1134
	public function get_display( $post ) {
1135
		if ( $this->smart ) {
1136
			$share_url = $this->get_share_url( $post->ID );
1137
			$fb_share_html = '<div class="fb-share-button" data-href="' . esc_attr( $share_url ) . '" data-layout="button_count"></div>';
1138
			/**
1139
			 * Filter the output of the Facebook Sharing button.
1140
			 *
1141
			 * @module sharedaddy
1142
			 *
1143
			 * @since 3.6.0
1144
			 *
1145
			 * @param string $fb_share_html Facebook Sharing button HTML.
1146
			 * @param string $share_url URL of the post to share.
1147
			 */
1148
			return apply_filters( 'jetpack_sharing_facebook_official_button_output', $fb_share_html, $share_url );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $share_url.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1149
		}
1150
1151
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1152
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'facebook' ) ) {
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post->ID.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1153
			sharing_register_post_for_share_counts( $post->ID );
1154
		}
1155
		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 );
1156
	}
1157
1158
	/**
1159
	 * AMP display for Facebook.
1160
	 *
1161
	 * @param \WP_Post $post The current post being viewed.
1162
	 */
1163
	public function get_amp_display( $post ) {
1164
		$attrs = array(
1165
			/** This filter is documented in modules/sharedaddy/sharing-sources.php */
1166
			'data-param-app_id' => apply_filters( 'jetpack_sharing_facebook_app_id', '249643311490' ),
1167
		);
1168
1169
		return $this->build_amp_markup( $attrs );
1170
	}
1171
1172 View Code Duplication
	public function process_request( $post, array $post_data ) {
1173
		$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 ) );
1174
1175
		// Record stats
1176
		parent::process_request( $post, $post_data );
1177
1178
		// Redirect to Facebook
1179
		wp_redirect( $fb_url );
1180
		die();
1181
	}
1182
1183
	public function display_footer() {
1184
		$this->js_dialog( $this->shortname );
1185
		if ( $this->smart ) {
1186
			$locale = $this->guess_locale_from_lang( get_locale() );
1187
			if ( ! $locale ) {
1188
				$locale = 'en_US';
1189
			}
1190
			/**
1191
			 * Filter the App ID used in the official Facebook Share button.
1192
			 *
1193
			 * @since 3.8.0
1194
			 *
1195
			 * @param int $fb_app_id Facebook App ID. Default to 249643311490 (WordPress.com's App ID).
1196
			 */
1197
			$fb_app_id = apply_filters( 'jetpack_sharing_facebook_app_id', '249643311490' );
1198
			if ( is_numeric( $fb_app_id ) ) {
1199
				$fb_app_id = '&appId=' . $fb_app_id;
1200
			} else {
1201
				$fb_app_id = '';
1202
			}
1203
			?><div id="fb-root"></div>
1204
			<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>
1205
			<script>
1206
			document.body.addEventListener( 'is.post-load', function() {
1207
				if ( 'undefined' !== typeof FB ) {
1208
					FB.XFBML.parse();
1209
				}
1210
			} );
1211
			</script>
1212
			<?php
1213
		}
1214
	}
1215
}
1216
1217
class Share_Print extends Sharing_Source {
1218
	public $shortname = 'print';
1219
	public $icon = '\f469';
1220 View Code Duplication
	public function __construct( $id, array $settings ) {
1221
		parent::__construct( $id, $settings );
1222
1223
		if ( 'official' == $this->button_style ) {
1224
			$this->smart = true;
1225
		} else {
1226
			$this->smart = false;
1227
		}
1228
	}
1229
1230
	public function get_name() {
1231
		return __( 'Print', 'jetpack' );
1232
	}
1233
1234
	public function get_display( $post ) {
1235
		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' ) );
1236
	}
1237
1238
	/**
1239
	 * AMP display for Print.
1240
	 *
1241
	 * @param \WP_Post $post The current post being viewed.
1242
	 */
1243
	public function get_amp_display( $post ) {
1244
		if ( empty( $post ) ) {
1245
			return false;
1246
		}
1247
1248
		return '<button class="amp-social-share print" on="tap:AMP.print">Print</button>';
1249
	}
1250
}
1251
1252
class Share_PressThis extends Sharing_Source {
1253
	public $shortname = 'pressthis';
1254
	public $icon = '\f205';
1255 View Code Duplication
	public function __construct( $id, array $settings ) {
1256
		parent::__construct( $id, $settings );
1257
1258
		if ( 'official' == $this->button_style ) {
1259
			$this->smart = true;
1260
		} else {
1261
			$this->smart = false;
1262
		}
1263
	}
1264
1265
	public function get_name() {
1266
		return __( 'Press This', 'jetpack' );
1267
	}
1268
1269
	public function process_request( $post, array $post_data ) {
1270
		global $current_user;
1271
1272
		$primary_blog = (int) get_user_meta( $current_user->ID, 'primary_blog', true );
1273
		if ( $primary_blog ) {
1274
			$primary_blog_details = get_blog_details( $primary_blog );
1275
		} else {
1276
			$primary_blog_details = false;
1277
		}
1278
1279
		if ( $primary_blog_details ) {
1280
			$blogs = array( $primary_blog_details );
1281
		} elseif ( function_exists( 'get_active_blogs_for_user' ) ) {
1282
			$blogs = get_active_blogs_for_user();
1283
			if ( empty( $blogs ) ) {
1284
				$blogs = get_blogs_of_user( $current_user->ID );
1285
			}
1286
		} else {
1287
			$blogs = get_blogs_of_user( $current_user->ID );
1288
		}
1289
1290
		if ( empty( $blogs ) ) {
1291
			wp_safe_redirect( get_permalink( $post->ID ) );
1292
			die();
1293
		}
1294
1295
		$blog = current( $blogs );
1296
1297
		$args = array(
1298
			'u' => rawurlencode( $this->get_share_url( $post->ID ) ),
1299
			);
1300
1301
		$args[ 'url-scan-submit' ] = 'Scan';
1302
		$args[ '_wpnonce' ]        = wp_create_nonce( 'scan-site' );
1303
1304
		$url = $blog->siteurl . '/wp-admin/press-this.php';
1305
		$url = add_query_arg( $args, $url );
1306
1307
		// Record stats
1308
		parent::process_request( $post, $post_data );
1309
1310
		// Redirect to Press This
1311
		wp_redirect( $url );
1312
		die();
1313
	}
1314
1315
	public function get_display( $post ) {
1316
		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' );
1317
	}
1318
1319
	/**
1320
	 * No AMP display for PressThis.
1321
	 *
1322
	 * @param \WP_Post $post The current post being viewed.
1323
	 */
1324
	public function get_amp_display( $post ) { // phpcs:ignore
1325
		return false;
1326
	}
1327
}
1328
1329
class Share_Custom extends Sharing_Advanced_Source {
1330
	private $name;
1331
	private $icon;
1332
	private $url;
1333
	public $smart = true;
1334
	public $shortname;
1335
1336
	public function get_class() {
1337
		return 'custom share-custom-' . sanitize_html_class( strtolower( $this->name ) );
1338
	}
1339
1340
	public function __construct( $id, array $settings ) {
1341
		parent::__construct( $id, $settings );
1342
1343
		$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...
1344
1345
		if ( isset( $settings['name'] ) ) {
1346
			$this->name = $settings['name'];
1347
			$this->shortname = preg_replace( '/[^a-z0-9]*/', '', $settings['name'] );
1348
		}
1349
1350
		if ( isset( $settings['icon'] ) ) {
1351
			$this->icon = $settings['icon'];
1352
1353
			$new_icon = esc_url_raw( wp_specialchars_decode( $this->icon, ENT_QUOTES ) );
1354
			$i = 0;
1355
			while ( $new_icon != $this->icon ) {
1356
				if ( $i > 5 ) {
1357
					$this->icon = false;
1358
					break;
1359
				} else {
1360
					$this->icon = $new_icon;
1361
					$new_icon = esc_url_raw( wp_specialchars_decode( $this->icon, ENT_QUOTES ) );
1362
				}
1363
				$i++;
1364
			}
1365
		}
1366
1367
		if ( isset( $settings['url'] ) ) {
1368
			$this->url = $settings['url'];
1369
		}
1370
	}
1371
1372
	public function get_name() {
1373
		return $this->name;
1374
	}
1375
1376
	public function get_display( $post ) {
1377
		$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 );
1378
		return str_replace( '<span>', '<span style="' . esc_attr( 'background-image:url("' . addcslashes( esc_url_raw( $this->icon ), '"' ) . '");' ) . '">', $str );
1379
	}
1380
1381
	/**
1382
	 * No AMP display for custom elements.
1383
	 *
1384
	 * @param \WP_Post $post The current post being viewed.
1385
	 */
1386
	public function get_amp_display( $post ) { // phpcs:ignore
1387
		return false;
1388
	}
1389
1390
	public function process_request( $post, array $post_data ) {
1391
		$url = str_replace( '&amp;', '&', $this->url );
1392
		$url = str_replace( '%post_id%', rawurlencode( $post->ID ), $url );
1393
		$url = str_replace( '%post_url%', rawurlencode( $this->get_share_url( $post->ID ) ), $url );
1394
		$url = str_replace( '%post_full_url%', rawurlencode( get_permalink( $post->ID ) ), $url );
1395
		$url = str_replace( '%post_title%', rawurlencode( $this->get_share_title( $post->ID ) ), $url );
1396
		$url = str_replace( '%home_url%', rawurlencode( home_url() ), $url );
1397
		$url = str_replace( '%post_slug%', rawurlencode( $post->post_name ), $url );
1398
1399
		if ( strpos( $url, '%post_tags%' ) !== false ) {
1400
			$tags	= get_the_tags( $post->ID );
1401
			$tagged = '';
1402
1403
			if ( $tags ) {
1404
				$tagged_raw = array();
1405
				foreach ( $tags as $tag ) {
1406
					$tagged_raw[] = rawurlencode( $tag->name );
1407
				}
1408
1409
				$tagged = implode( ',', $tagged_raw );
1410
			}
1411
1412
			$url = str_replace( '%post_tags%', $tagged, $url );
1413
		}
1414
1415
		if ( strpos( $url, '%post_excerpt%' ) !== false ) {
1416
			$url_excerpt = $post->post_excerpt;
1417
			if ( empty( $url_excerpt ) ) {
1418
				$url_excerpt = $post->post_content;
1419
			}
1420
1421
			$url_excerpt = strip_tags( strip_shortcodes( $url_excerpt ) );
1422
			$url_excerpt = wp_html_excerpt( $url_excerpt, 100 );
1423
			$url_excerpt = rtrim( preg_replace( '/[^ .]*$/', '', $url_excerpt ) );
1424
			$url = str_replace( '%post_excerpt%', rawurlencode( $url_excerpt ), $url );
1425
		}
1426
1427
		// Record stats
1428
		parent::process_request( $post, $post_data );
1429
1430
		// Redirect
1431
		wp_redirect( $url );
1432
		die();
1433
	}
1434
1435
	public function display_options() {
1436
?>
1437
<div class="input">
1438
	<table class="form-table">
1439
		<tbody>
1440
			<tr>
1441
				<th scope="row"><?php _e( 'Label', 'jetpack' ); ?></th>
1442
				<td><input type="text" name="name" value="<?php echo esc_attr( $this->name ); ?>" /></td>
1443
			</tr>
1444
1445
			<tr>
1446
				<th scope="row"><?php _e( 'URL', 'jetpack' ); ?></th>
1447
				<td><input type="text" name="url" value="<?php echo esc_attr( $this->url ); ?>" /></td>
1448
			</tr>
1449
1450
			<tr>
1451
				<th scope="row"><?php _e( 'Icon', 'jetpack' ); ?></th>
1452
				<td><input type="text" name="icon" value="<?php echo esc_attr( $this->icon ); ?>" /></td>
1453
			</tr>
1454
1455
			<tr>
1456
				<th scope="row"></th>
1457
				<td>
1458
					<input class="button-secondary" type="submit" value="<?php esc_attr_e( 'Save', 'jetpack' ); ?>" />
1459
					<a href="#" class="remove"><small><?php _e( 'Remove Service', 'jetpack' ); ?></small></a>
1460
				</td>
1461
			</tr>
1462
		</tbody>
1463
	</table>
1464
</div>
1465
<?php
1466
	}
1467
1468
	public function update_options( array $data ) {
1469
		$name  = trim( wp_html_excerpt( wp_kses( stripslashes( $data['name'] ), array() ), 30 ) );
1470
		$url   = trim( esc_url_raw( $data['url'] ) );
1471
		$icon  = trim( esc_url_raw( $data['icon'] ) );
1472
1473
		if ( $name ) {
1474
			$this->name = $name;
1475
		}
1476
1477
		if ( $url ) {
1478
			$this->url	= $url;
1479
		}
1480
1481
		if ( $icon ) {
1482
			$this->icon = $icon;
1483
		}
1484
	}
1485
1486
	public function get_options() {
1487
		return array(
1488
			'name' => $this->name,
1489
			'icon' => $this->icon,
1490
			'url'  => $this->url,
1491
		);
1492
	}
1493
1494
	public function display_preview( $echo = true, $force_smart = false, $button_style = null ) {
1495
		$opts = $this->get_options();
1496
1497
		$text = '&nbsp;';
1498
		if ( ! $this->smart ) {
1499
			if ( $this->button_style != 'icon' ) {
1500
				$text = $this->get_name();
1501
			}
1502
		}
1503
1504
		$klasses = array( 'share-' . $this->shortname );
1505
1506
		if ( $this->button_style == 'icon' || $this->button_style == 'icon-text' ) {
1507
			$klasses[] = 'share-icon';
1508
		}
1509
1510
		if ( $this->button_style == 'icon' ) {
1511
			$text = '';
1512
			$klasses[] = 'no-text';
1513
		}
1514
1515
		if ( $this->button_style == 'text' ) {
1516
			$klasses[] = 'no-icon';
1517
		}
1518
1519
		$link = sprintf(
1520
			'<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>',
1521
			implode( ' ', $klasses ),
1522
			$this->get_name(),
1523
			addcslashes( esc_url_raw( $opts['icon'] ), '"' ),
1524
			$text
1525
		);
1526
		?>
1527
		<div class="option option-smart-off">
1528
		<?php echo $link ; ?>
1529
		</div><?php
1530
	}
1531
}
1532
1533
class Share_Tumblr extends Sharing_Source {
1534
	public $shortname = 'tumblr';
1535
	public $icon = '\f214';
1536 View Code Duplication
	public function __construct( $id, array $settings ) {
1537
		parent::__construct( $id, $settings );
1538
		if ( 'official' == $this->button_style ) {
1539
			$this->smart = true;
1540
		} else {
1541
			$this->smart = false;
1542
		}
1543
	}
1544
1545
	public function get_name() {
1546
		return __( 'Tumblr', 'jetpack' );
1547
	}
1548
1549
	public function get_display( $post ) {
1550
		if ( $this->smart ) {
1551
			$target = '';
1552
			if ( true == $this->open_link_in_new ) {
1553
				$target = '_blank';
1554
			}
1555
1556
			/**
1557
			 * If we are looking at a single post, let Tumblr figure out the post type (text, photo, link, quote, chat, or video)
1558
			 * based on the content available on the page.
1559
			 * If we are not looking at a single post, content from other posts can appear on the page and Tumblr will pick that up.
1560
			 * In this case, we want Tumblr to focus on our current post, so we will limit the post type to link, where we can give Tumblr a link to our post.
1561
			 */
1562
			if ( ! is_single() ) {
1563
				$posttype = 'data-posttype="link"';
1564
			} else {
1565
				$posttype = '';
1566
			}
1567
1568
			// Documentation: https://www.tumblr.com/docs/en/share_button
1569
			return sprintf(
1570
				'<a class="tumblr-share-button" target="%1$s" href="%2$s" data-title="%3$s" data-content="%4$s" title="%5$s"%6$s>%5$s</a>',
1571
				$target,
1572
				'https://www.tumblr.com/share',
1573
				$this->get_share_title( $post->ID ),
1574
				$this->get_share_url( $post->ID ),
1575
				__( 'Share on Tumblr', 'jetpack' ),
1576
				$posttype
1577
			);
1578 View Code Duplication
		 } else {
1579
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Tumblr', 'share to', 'jetpack' ), __( 'Click to share on Tumblr', 'jetpack' ), 'share=tumblr' );
1580
		}
1581
	}
1582
1583 View Code Duplication
	public function process_request( $post, array $post_data ) {
1584
		// Record stats
1585
		parent::process_request( $post, $post_data );
1586
1587
		// Redirect to Tumblr's sharing endpoint (a la their bookmarklet)
1588
		$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=';
1589
		wp_redirect( $url );
1590
		die();
1591
	}
1592
1593 View Code Duplication
	public function display_footer() {
1594
		if ( $this->smart ) {
1595
			?><script id="tumblr-js" type="text/javascript" src="https://assets.tumblr.com/share-button.js"></script><?php
1596
		} else {
1597
			$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1598
		}
1599
	}
1600
}
1601
1602
class Share_Pinterest extends Sharing_Source {
1603
	public $shortname = 'pinterest';
1604
	public $icon = '\f209';
1605
1606 View Code Duplication
	public function __construct( $id, array $settings ) {
1607
		parent::__construct( $id, $settings );
1608
		if ( 'official' == $this->button_style ) {
1609
			$this->smart = true;
1610
		} else {
1611
			$this->smart = false;
1612
		}
1613
	}
1614
1615
	public function get_name() {
1616
		return __( 'Pinterest', 'jetpack' );
1617
	}
1618
1619
	public function get_image( $post ) {
1620
		if ( class_exists( 'Jetpack_PostImages' ) ) {
1621
			$image = Jetpack_PostImages::get_image( $post->ID, array( 'fallback_to_avatars' => true ) );
1622
			if ( ! empty( $image ) ) {
1623
				return $image['src'];
1624
			}
1625
		}
1626
1627
		/**
1628
		 * Filters the default image used by the Pinterest Pin It share button.
1629
		 *
1630
		 * @module sharedaddy
1631
		 *
1632
		 * @since 3.6.0
1633
		 *
1634
		 * @param string $url Default image URL.
1635
		 */
1636
		return apply_filters( 'jetpack_sharing_pinterest_default_image', 'https://s0.wp.com/i/blank.jpg' );
1637
	}
1638
1639
	public function get_external_url( $post ) {
1640
		$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 );
1641
1642
		/**
1643
		 * Filters the Pinterest share URL used in sharing button output.
1644
		 *
1645
		 * @module sharedaddy
1646
		 *
1647
		 * @since 3.6.0
1648
		 *
1649
		 * @param string $url Pinterest share URL.
1650
		 */
1651
		return apply_filters( 'jetpack_sharing_pinterest_share_url', $url );
1652
	}
1653
1654
	public function get_widget_type() {
1655
		/**
1656
		 * Filters the Pinterest widget type.
1657
		 *
1658
		 * @see https://business.pinterest.com/en/widget-builder
1659
		 *
1660
		 * @module sharedaddy
1661
		 *
1662
		 * @since 3.6.0
1663
		 *
1664
		 * @param string $type Pinterest widget type. Default of 'buttonPin' for single-image selection. 'buttonBookmark' for multi-image modal.
1665
		 */
1666
		return apply_filters( 'jetpack_sharing_pinterest_widget_type', 'buttonPin' );
1667
	}
1668
1669
	public function get_display( $post ) {
1670
		$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...
1671
1672
		if ( $this->smart ) {
1673
			$display = sprintf(
1674
				'<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>',
1675
				esc_url( $this->get_external_url( $post ) ),
1676
				esc_attr( $this->get_widget_type() )
1677
			);
1678 View Code Duplication
		} else {
1679
			$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 );
1680
		}
1681
1682
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1683
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'linkedin' ) ) {
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post->ID.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1684
			sharing_register_post_for_share_counts( $post->ID );
1685
		}
1686
1687
		return $display;
1688
	}
1689
1690
	public function process_request( $post, array $post_data ) {
1691
		// Record stats
1692
		parent::process_request( $post, $post_data );
1693
		// If we're triggering the multi-select panel, then we don't need to redirect to Pinterest
1694
		if ( ! isset( $_GET['js_only'] ) ) {
1695
			$pinterest_url = esc_url_raw( $this->get_external_url( $post ) );
1696
			wp_redirect( $pinterest_url );
1697
		} else {
1698
			echo '// share count bumped';
1699
		}
1700
		die();
1701
	}
1702
1703
	public function display_footer() {
1704
		/**
1705
		 * Filter the Pin it button appearing when hovering over images when using the official button style.
1706
		 *
1707
		 * @module sharedaddy
1708
		 *
1709
		 * @since 3.6.0
1710
		 *
1711
		 * @param bool $jetpack_pinit_over True by default, displays the Pin it button when hovering over images.
1712
		 */
1713
		$jetpack_pinit_over = apply_filters( 'jetpack_pinit_over_button', true );
1714
		?>
1715
		<?php if ( $this->smart ) : ?>
1716
			<script type="text/javascript">
1717
				( function () {
1718
					// Pinterest shared resources
1719
					var s = document.createElement( 'script' );
1720
					s.type = 'text/javascript';
1721
					s.async = true;
1722
					<?php
1723
					if ( $jetpack_pinit_over ) {
1724
						echo "s.setAttribute( 'data-pin-hover', true );";
1725
					}
1726
					?>
1727
					s.src = window.location.protocol + '//assets.pinterest.com/js/pinit.js';
1728
					var x = document.getElementsByTagName( 'script' )[ 0 ];
1729
					x.parentNode.insertBefore(s, x);
1730
					// if 'Pin it' button has 'counts' make container wider
1731
					function init() {
1732
						var shares = document.querySelectorAll( 'li.share-pinterest' );
1733
						for ( var i = 0; i < shares.length; i++ ) {
1734
							var share = shares[ i ];
1735
							if ( share.querySelector( 'a span:visible' ) ) {
1736
								share.style.width = '80px';
1737
							}
1738
						}
1739
					}
1740
1741
					if ( document.readyState !== 'complete' ) {
1742
						document.addEventListener( 'load', init );
1743
					} else {
1744
						init();
1745
					}
1746
				} )();
1747
			</script>
1748
		<?php elseif ( 'buttonPin' != $this->get_widget_type() ) : ?>
1749
			<script type="text/javascript">
1750
				( function () {
1751
					function init() {
1752
						document.body.addEventListener( 'click', function ( e ) {
1753
							if ( e.target && (
1754
								e.target.matches && e.target.matches( 'a.share-pinterest' ) ||
1755
								e.target.msMatchesSelector && e.target.msMatchesSelector( 'a.share-pinterest' )
1756
							) ) {
1757
								e.preventDefault();
1758
								// Load Pinterest Bookmarklet code
1759
								var s = document.createElement( 'script' );
1760
								s.type = 'text/javascript';
1761
								s.src = window.location.protocol + '//assets.pinterest.com/js/pinmarklet.js?r=' + ( Math.random() * 99999999 );
1762
								var x = document.getElementsByTagName( 'script' )[ 0 ];
1763
								x.parentNode.insertBefore( s, x );
1764
								// Trigger Stats
1765
								var s = document.createElement( 'script' );
1766
								s.type = 'text/javascript';
1767
								s.src = e.target.href + ( e.target.href.indexOf( '?' ) ? '&' : '?' ) + 'js_only=1';
1768
								var x = document.getElementsByTagName( 'script' )[ '0' ];
1769
								x.parentNode.insertBefore( s, x );
1770
							}
1771
						} );
1772
					}
1773
1774
					if ( document.readyState === 'loading' ) {
1775
						document.addEventListener( 'DOMContentLoaded', init );
1776
					} else {
1777
						init();
1778
					}
1779
				} )();
1780
			</script>
1781
		<?php endif;
1782
	}
1783
}
1784
1785
class Share_Pocket extends Sharing_Source {
1786
	public $shortname = 'pocket';
1787
	public $icon = '\f224';
1788
1789 View Code Duplication
	public function __construct( $id, array $settings ) {
1790
		parent::__construct( $id, $settings );
1791
1792
		if ( 'official' == $this->button_style ) {
1793
			$this->smart = true;
1794
		} else {
1795
			$this->smart = false;
1796
		}
1797
	}
1798
1799
	public function get_name() {
1800
		return __( 'Pocket', 'jetpack' );
1801
	}
1802
1803 View Code Duplication
	public function process_request( $post, array $post_data ) {
1804
		// Record stats
1805
		parent::process_request( $post, $post_data );
1806
1807
		$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 ) ) );
1808
		wp_redirect( $pocket_url );
1809
		exit;
1810
	}
1811
1812
	public function get_display( $post ) {
1813
		if ( $this->smart ) {
1814
			$post_count = 'horizontal';
1815
1816
			$button = '';
1817
			$button .= '<div class="pocket_button">';
1818
			$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' ) );
1819
			$button .= '</div>';
1820
1821
			return $button;
1822 View Code Duplication
		} else {
1823
			return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Pocket', 'share to', 'jetpack' ), __( 'Click to share on Pocket', 'jetpack' ), 'share=pocket' );
1824
		}
1825
1826
	}
1827
1828
	/**
1829
	 * AMP display for Pocket.
1830
	 *
1831
	 * @param \WP_Post $post The current post being viewed.
1832
	 */
1833 View Code Duplication
	public function get_amp_display( $post ) {
1834
		$attrs = array(
1835
			'data-share-endpoint' => esc_url_raw( 'https://getpocket.com/save/?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&title=' . rawurlencode( $this->get_share_title( $post->ID ) ) ),
1836
		);
1837
1838
		return $this->build_amp_markup( $attrs );
1839
	}
1840
1841 View Code Duplication
	function display_footer() {
1842
		if ( $this->smart ) :
1843
		?>
1844
		<script>
1845
		( function () {
1846
			var currentScript = document.currentScript;
1847
1848
			// Don't use Pocket's default JS as it we need to force init new Pocket share buttons loaded via JS.
1849
			function jetpack_sharing_pocket_init() {
1850
				var script = document.createElement( 'script' );
1851
				var prev = currentScript || document.getElementsByTagName( 'script' )[ 0 ];
1852
				script.setAttribute( 'async', true );
1853
				script.setAttribute( 'src', 'https://widgets.getpocket.com/v1/j/btn.js?v=1' );
1854
				prev.parentNode.insertBefore( script, prev );
1855
			}
1856
1857
			if ( document.readyState === 'loading' ) {
1858
				document.addEventListener( 'DOMContentLoaded', jetpack_sharing_pocket_init );
1859
			} else {
1860
				jetpack_sharing_pocket_init();
1861
			}
1862
			document.body.addEventListener( 'is.post-load', jetpack_sharing_pocket_init );
1863
		} )();
1864
		</script>
1865
		<?php
1866
		else :
1867
			$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1868
		endif;
1869
1870
	}
1871
1872
}
1873
1874
class Share_Telegram extends Sharing_Source {
1875
	public $shortname = 'telegram';
1876
1877
	public function __construct( $id, array $settings ) {
1878
		parent::__construct( $id, $settings );
1879
	}
1880
1881
	public function get_name() {
1882
		return __( 'Telegram', 'jetpack' );
1883
	}
1884 View Code Duplication
	public function process_request( $post, array $post_data ) {
1885
		// Record stats
1886
		parent::process_request( $post, $post_data );
1887
		$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 ) ) );
1888
		wp_redirect( $telegram_url );
1889
		exit;
1890
	}
1891
1892
	public function get_display( $post ) {
1893
		return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'Telegram', 'share to', 'jetpack' ), __( 'Click to share on Telegram', 'jetpack' ), 'share=telegram' );
1894
	}
1895
1896
	/**
1897
	 * AMP display for Telegram.
1898
	 *
1899
	 * @param \WP_Post $post The current post being viewed.
1900
	 */
1901 View Code Duplication
	public function get_amp_display( $post ) {
1902
		$attrs = array(
1903
			'data-share-endpoint' => esc_url_raw( 'https://telegram.me/share/url?url=' . rawurlencode( $this->get_share_url( $post->ID ) ) . '&text=' . rawurlencode( $this->get_share_title( $post->ID ) ) ),
1904
		);
1905
1906
		return $this->build_amp_markup( $attrs );
1907
	}
1908
1909
	function display_footer() {
1910
		$this->js_dialog( $this->shortname, array( 'width' => 450, 'height' => 450 ) );
1911
	}
1912
}
1913
1914
class Jetpack_Share_WhatsApp extends Sharing_Source {
1915
	public $shortname = 'jetpack-whatsapp';
1916
1917
	public function __construct( $id, array $settings ) {
1918
		parent::__construct( $id, $settings );
1919
	}
1920
1921
	public function get_name() {
1922
		return __( 'WhatsApp', 'jetpack' );
1923
	}
1924
1925
	public function get_display( $post ) {
1926
		return $this->get_link( $this->get_process_request_url( $post->ID ), _x( 'WhatsApp', 'share to', 'jetpack' ), __( 'Click to share on WhatsApp', 'jetpack' ), 'share=jetpack-whatsapp' );
1927
	}
1928
1929
	/**
1930
	 * AMP display for Whatsapp.
1931
	 *
1932
	 * @param \WP_Post $post The current post being viewed.
1933
	 */
1934
	public function get_amp_display( $post ) {
1935
		$attrs = array(
1936
			'type' => 'whatsapp',
1937
		);
1938
1939
		return $this->build_amp_markup( $attrs );
1940
	}
1941
1942
	public function process_request( $post, array $post_data ) {
1943
		// Record stats
1944
		parent::process_request( $post, $post_data );
1945
1946
		// Firefox for desktop doesn't handle the "api.whatsapp.com" URL properly, so use "web.whatsapp.com"
1947
		if ( User_Agent_Info::is_firefox_desktop() ) {
1948
			$url = 'https://web.whatsapp.com/send?text=';
1949
		} else {
1950
			$url = 'https://api.whatsapp.com/send?text=';
1951
		}
1952
1953
		$url .= rawurlencode( $this->get_share_title( $post->ID ) . ' ' . $this->get_share_url( $post->ID ) );
1954
		wp_redirect( $url );
1955
		exit;
1956
	}
1957
}
1958
1959
class Share_Skype extends Sharing_Source {
1960
	public $shortname = 'skype';
1961
	public $icon = '\f220';
1962
	private $share_type = 'default';
1963
1964 View Code Duplication
	public function __construct( $id, array $settings ) {
1965
		parent::__construct( $id, $settings );
1966
1967
		if ( isset( $settings['share_type'] ) ) {
1968
			$this->share_type = $settings['share_type'];
1969
		}
1970
1971
		if ( 'official' == $this->button_style ) {
1972
			$this->smart = true;
1973
		} else {
1974
			$this->smart = false;
1975
		}
1976
1977
	}
1978
1979
	public function get_name() {
1980
		return __( 'Skype', 'jetpack' );
1981
	}
1982
1983
	public function get_display( $post ) {
1984
		if ( $this->smart ) {
1985
			$skype_share_html = sprintf(
1986
				'<div class="skype-share" data-href="%1$s" data-lang="%2$s" data-style="small" data-source="jetpack" ></div>',
1987
				esc_attr( $this->get_share_url( $post->ID ) ),
1988
				'en-US'
1989
			);
1990
			return $skype_share_html;
1991
		}
1992
1993
		/** This filter is already documented in modules/sharedaddy/sharing-sources.php */
1994
		if ( apply_filters( 'jetpack_register_post_for_share_counts', true, $post->ID, 'skype' ) ) {
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $post->ID.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1995
			sharing_register_post_for_share_counts( $post->ID );
1996
		}
1997
		return $this->get_link(
1998
			$this->get_process_request_url( $post->ID ), _x( 'Skype', 'share to', 'jetpack' ), __( 'Click to share on Skype', 'jetpack' ), 'share=skype', 'sharing-skype-' . $post->ID );
1999
	}
2000
2001
	/**
2002
	 * AMP display for Skype.
2003
	 *
2004
	 * @param \WP_Post $post The current post being viewed.
2005
	 */
2006
	public function get_amp_display( $post ) {
2007
		$attrs = array(
2008
			'data-share-endpoint' => sprintf(
2009
				'https://web.skype.com/share?url=%1$s&lang=%2$s=&source=jetpack',
2010
				rawurlencode( $this->get_share_url( $post->ID ) ),
2011
				'en-US'
2012
			),
2013
		);
2014
2015
		return $this->build_amp_markup( $attrs );
2016
	}
2017
2018 View Code Duplication
	public function process_request( $post, array $post_data ) {
2019
		$skype_url = sprintf(
2020
			'https://web.skype.com/share?url=%1$s&lang=%2$s=&source=jetpack',
2021
			rawurlencode( $this->get_share_url( $post->ID ) ),
2022
			'en-US'
2023
		);
2024
2025
		// Record stats
2026
		parent::process_request( $post, $post_data );
2027
2028
		// Redirect to Skype
2029
		wp_redirect( $skype_url );
2030
		die();
2031
	}
2032
2033 View Code Duplication
	public function display_footer() {
2034
		if ( $this->smart ) :
2035
			?>
2036
			<script>
2037
				(function(r, d, s) {
2038
					r.loadSkypeWebSdkAsync = r.loadSkypeWebSdkAsync || function(p) {
2039
							var js, sjs = d.getElementsByTagName(s)[0];
2040
							if (d.getElementById(p.id)) { return; }
2041
							js = d.createElement(s);
2042
							js.id = p.id;
2043
							js.src = p.scriptToLoad;
2044
							js.onload = p.callback
2045
							sjs.parentNode.insertBefore(js, sjs);
2046
						};
2047
					var p = {
2048
						scriptToLoad: 'https://swx.cdn.skype.com/shared/v/latest/skypewebsdk.js',
2049
						id: 'skype_web_sdk'
2050
					};
2051
					r.loadSkypeWebSdkAsync(p);
2052
				})(window, document, 'script');
2053
			</script>
2054
			<?php
2055
		else :
2056
			$this->js_dialog( $this->shortname, array( 'width' => 305, 'height' => 665 ) );
2057
		endif;
2058
	}
2059
}
2060