Completed
Push — renovate/react-monorepo ( 545e89...65a81e )
by
unknown
268:48 queued 253:47
created

sharing-service.php ➔ sharing_display()   F

Complexity

Conditions 52
Paths > 20000

Size

Total Lines 275

Duplication

Lines 3
Ratio 1.09 %

Importance

Changes 0
Metric Value
cc 52
nc 139025
nop 2
dl 3
loc 275
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
use Automattic\Jetpack\Assets;
4
use Automattic\Jetpack\Redirect;
5
use Automattic\Jetpack\Status;
6
use Automattic\Jetpack\Sync\Settings;
7
8
include_once dirname( __FILE__ ) . '/sharing-sources.php';
9
10
define( 'WP_SHARING_PLUGIN_VERSION', JETPACK__VERSION );
11
12
class Sharing_Service {
13
	private $global               = false;
14
	public $default_sharing_label = '';
15
16
	/**
17
	 * Initialize the sharing service.
18
	 * Only run this method once upon module loading.
19
	 */
20
	public static function init() {
21
		add_filter( 'the_content', 'sharing_display', 19 );
22
		add_filter( 'the_excerpt', 'sharing_display', 19 );
23
	}
24
25
	public function __construct() {
26
		$this->default_sharing_label = __( 'Share this:', 'jetpack' );
27
	}
28
29
	/**
30
	 * Gets a generic list of all services, without any config
31
	 */
32
	public function get_all_services_blog() {
33
		$options = get_option( 'sharing-options' );
34
35
		$all      = $this->get_all_services();
36
		$services = array();
37
38
		foreach ( $all as $id => $name ) {
39
			if ( isset( $all[ $id ] ) ) {
40
				$config = array();
41
42
				// Pre-load custom modules otherwise they won't know who they are
43
				if ( substr( $id, 0, 7 ) == 'custom-' && is_array( $options[ $id ] ) ) {
44
					$config = $options[ $id ];
45
				}
46
47
				$services[ $id ] = new $all[ $id ]( $id, $config );
48
			}
49
		}
50
51
		return $services;
52
	}
53
54
	/**
55
	 * Gets a list of all available service names and classes
56
	 */
57
	public function get_all_services( $include_custom = true ) {
58
		// Default services
59
		// if you update this list, please update the REST API tests
60
		// in bin/tests/api/suites/SharingTest.php
61
		$services = array(
62
			'print'            => 'Share_Print',
63
			'facebook'         => 'Share_Facebook',
64
			'linkedin'         => 'Share_LinkedIn',
65
			'reddit'           => 'Share_Reddit',
66
			'twitter'          => 'Share_Twitter',
67
			'tumblr'           => 'Share_Tumblr',
68
			'pinterest'        => 'Share_Pinterest',
69
			'pocket'           => 'Share_Pocket',
70
			'telegram'         => 'Share_Telegram',
71
			'jetpack-whatsapp' => 'Jetpack_Share_WhatsApp',
72
			'skype'            => 'Share_Skype',
73
		);
74
75
		/**
76
		 * Filters if Email Sharing is enabled.
77
		 *
78
		 * E-Mail sharing is often problematic due to spam concerns, so this filter enables it to be quickly and simply toggled.
79
		 * @module sharedaddy
80
		 *
81
		 * @since 5.1.0
82
		 *
83
		 * @param bool $email Is e-mail sharing enabled? Default false if Akismet is not active or true if Akismet is active.
84
		 */
85
		if ( apply_filters( 'sharing_services_email', Jetpack::is_akismet_active() ) ) {
86
			$services['email'] = 'Share_Email';
87
		}
88
89
		if ( is_multisite() && is_plugin_active( 'press-this/press-this-plugin.php' ) ) {
90
			$services['press-this'] = 'Share_PressThis';
91
		}
92
93
		if ( $include_custom ) {
94
			// Add any custom services in
95
			$options = $this->get_global_options();
96
			foreach ( (array) $options['custom'] as $custom_id ) {
97
				$services[ $custom_id ] = 'Share_Custom';
98
			}
99
		}
100
101
		/**
102
		 * Filters the list of available Sharing Services.
103
		 *
104
		 * @module sharedaddy
105
		 *
106
		 * @since 1.1.0
107
		 *
108
		 * @param array $services Array of all available Sharing Services.
109
		 */
110
		return apply_filters( 'sharing_services', $services );
111
	}
112
113
	public function new_service( $label, $url, $icon ) {
114
		// Validate
115
		$label = trim( wp_html_excerpt( wp_kses( $label, array() ), 30 ) );
116
		$url   = trim( esc_url_raw( $url ) );
117
		$icon  = trim( esc_url_raw( $icon ) );
118
119
		if ( $label && $url && $icon ) {
120
			$options = get_option( 'sharing-options' );
121
			if ( ! is_array( $options ) ) {
122
				$options = array();
123
			}
124
125
			$service_id = 'custom-' . time();
126
127
			// Add a new custom service
128
			$options['global']['custom'][] = $service_id;
129
			if ( false !== $this->global ) {
130
				$this->global['custom'][] = $service_id;
131
			}
132
133
			update_option( 'sharing-options', $options );
134
135
			// Create a custom service and set the options for it
136
			$service = new Share_Custom(
137
				$service_id, array(
138
					'name' => $label,
139
					'url'  => $url,
140
					'icon' => $icon,
141
				)
142
			);
143
			$this->set_service( $service_id, $service );
144
145
			// Return the service
146
			return $service;
147
		}
148
149
		return false;
150
	}
151
152
	public function delete_service( $service_id ) {
153
		$options = get_option( 'sharing-options' );
154
		if ( isset( $options[ $service_id ] ) ) {
155
			unset( $options[ $service_id ] );
156
		}
157
158
		$key = array_search( $service_id, $options['global']['custom'] );
159
		if ( $key !== false ) {
160
			unset( $options['global']['custom'][ $key ] );
161
		}
162
163
		update_option( 'sharing-options', $options );
164
		return true;
165
	}
166
167
	public function set_blog_services( array $visible, array $hidden ) {
168
		$services = $this->get_all_services();
169
		// Validate the services
170
		$available = array_keys( $services );
171
172
		// Only allow services that we have defined
173
		$hidden  = array_intersect( $hidden, $available );
174
		$visible = array_intersect( $visible, $available );
175
176
		// Ensure we don't have the same ones in hidden and visible
177
		$hidden = array_diff( $hidden, $visible );
178
179
		/**
180
		 * Control the state of the list of sharing services.
181
		 *
182
		 * @module sharedaddy
183
		 *
184
		 * @since 1.1.0
185
		 *
186
		 * @param array $args {
187
		 *  Array of options describing the state of the sharing services.
188
		 *
189
		 *  @type array $services List of all available service names and classes.
190
		 *  @type array $available Validated list of all available service names and classes.
191
		 *  @type array $hidden List of services hidden behind a "More" button.
192
		 *  @type array $visible List of visible services.
193
		 *  @type array $this->get_blog_services() Array of Sharing Services currently enabled.
194
		 * }
195
		 */
196
		do_action(
197
			'sharing_get_services_state', array(
198
				'services'          => $services,
199
				'available'         => $available,
200
				'hidden'            => $hidden,
201
				'visible'           => $visible,
202
				'currently_enabled' => $this->get_blog_services(),
203
			)
204
		);
205
206
		return update_option(
207
			'sharing-services', array(
208
				'visible' => $visible,
209
				'hidden'  => $hidden,
210
			)
211
		);
212
	}
213
214
	public function get_blog_services() {
215
		$options  = get_option( 'sharing-options' );
216
		$enabled  = get_option( 'sharing-services' );
217
		$services = $this->get_all_services();
218
219
		/**
220
		 * Check if options exist and are well formatted.
221
		 * This avoids issues on sites with corrupted options.
222
		 * @see https://github.com/Automattic/jetpack/issues/6121
223
		 */
224
		if ( ! is_array( $options ) || ! isset( $options['button_style'], $options['global'] ) ) {
225
			$global_options = array( 'global' => $this->get_global_options() );
226
			$options        = is_array( $options )
227
				? array_merge( $options, $global_options )
228
				: $global_options;
229
		}
230
231
		$global = $options['global'];
232
233
		// Default services
234
		if ( ! is_array( $enabled ) ) {
235
			$enabled = array(
236
				'visible' => array(
237
					'twitter',
238
					'facebook',
239
				),
240
				'hidden'  => array(),
241
			);
242
243
			/**
244
			 * Filters the list of default Sharing Services.
245
			 *
246
			 * @module sharedaddy
247
			 *
248
			 * @since 1.1.0
249
			 *
250
			 * @param array $enabled Array of default Sharing Services.
251
			 */
252
			$enabled = apply_filters( 'sharing_default_services', $enabled );
253
		}
254
255
		// Cleanup after any filters that may have produced duplicate services
256 View Code Duplication
		if ( is_array( $enabled['visible'] ) ) {
257
			$enabled['visible'] = array_unique( $enabled['visible'] );
258
		} else {
259
			$enabled['visible'] = array();
260
		}
261
262 View Code Duplication
		if ( is_array( $enabled['hidden'] ) ) {
263
			$enabled['hidden'] = array_unique( $enabled['hidden'] );
264
		} else {
265
			$enabled['hidden'] = array();
266
		}
267
268
		// Form the enabled services
269
		$blog = array(
270
			'visible' => array(),
271
			'hidden'  => array(),
272
		);
273
274
		foreach ( $blog as $area => $stuff ) {
275
			foreach ( (array) $enabled[ $area ] as $service ) {
276
				if ( isset( $services[ $service ] ) ) {
277
					if ( ! isset( $options[ $service ] ) || ! is_array( $options[ $service ] ) ) {
278
						$options[ $service ] = array();
279
					}
280
					$blog[ $area ][ $service ] = new $services[ $service ]( $service, array_merge( $global, $options[ $service ] ) );
281
				}
282
			}
283
		}
284
285
		/**
286
		 * Filters the list of enabled Sharing Services.
287
		 *
288
		 * @module sharedaddy
289
		 *
290
		 * @since 1.1.0
291
		 *
292
		 * @param array $blog Array of enabled Sharing Services.
293
		 */
294
		$blog = apply_filters( 'sharing_services_enabled', $blog );
295
296
		// Add CSS for NASCAR
297
		if ( count( $blog['visible'] ) || count( $blog['hidden'] ) ) {
298
			add_filter( 'post_flair_block_css', 'post_flair_service_enabled_sharing' );
299
		}
300
301
		// Convenience for checking if a service is present
302
		$blog['all'] = array_flip( array_merge( array_keys( $blog['visible'] ), array_keys( $blog['hidden'] ) ) );
303
		return $blog;
304
	}
305
306
	public function get_service( $service_name ) {
307
		$services = $this->get_blog_services();
308
309
		if ( isset( $services['visible'][ $service_name ] ) ) {
310
			return $services['visible'][ $service_name ];
311
		}
312
313
		if ( isset( $services['hidden'][ $service_name ] ) ) {
314
			return $services['hidden'][ $service_name ];
315
		}
316
317
		return false;
318
	}
319
320
	public function set_global_options( $data ) {
321
		$options = get_option( 'sharing-options' );
322
323
		// No options yet.
324
		if ( ! is_array( $options ) ) {
325
			$options = array();
326
		}
327
328
		// Defaults.
329
		$options['global'] = array(
330
			'button_style'  => 'icon-text',
331
			'sharing_label' => $this->default_sharing_label,
332
			'open_links'    => 'same',
333
			'show'          => ! isset( $options['global'] ) ? array( 'post', 'page' ) : array(),
334
			'custom'        => isset( $options['global']['custom'] ) ? $options['global']['custom'] : array(),
335
		);
336
337
		/**
338
		 * Filters global sharing settings.
339
		 *
340
		 * @module sharedaddy
341
		 *
342
		 * @since 1.1.0
343
		 *
344
		 * @param array $options['global'] Array of global sharing settings.
345
		 */
346
		$options['global'] = apply_filters( 'sharing_default_global', $options['global'] );
347
348
		// Validate options and set from our data
349
		if ( isset( $data['button_style'] ) && in_array( $data['button_style'], array( 'icon-text', 'icon', 'text', 'official' ) ) ) {
350
			$options['global']['button_style'] = $data['button_style'];
351
		}
352
353
		if ( isset( $data['sharing_label'] ) ) {
354
			if ( $this->default_sharing_label === $data['sharing_label'] ) {
355
				$options['global']['sharing_label'] = false;
356
			} else {
357
				$options['global']['sharing_label'] = trim( wp_kses( stripslashes( $data['sharing_label'] ), array() ) );
358
			}
359
		}
360
361
		if ( isset( $data['open_links'] ) && in_array( $data['open_links'], array( 'new', 'same' ) ) ) {
362
			$options['global']['open_links'] = $data['open_links'];
363
		}
364
365
		$shows   = array_values( get_post_types( array( 'public' => true ) ) );
366
		$shows[] = 'index';
367
		if ( isset( $data['show'] ) ) {
368
			if ( is_scalar( $data['show'] ) ) {
369
				switch ( $data['show'] ) {
370
					case 'posts':
371
						$data['show'] = array( 'post', 'page' );
372
						break;
373
					case 'index':
374
						$data['show'] = array( 'index' );
375
						break;
376
					case 'posts-index':
377
						$data['show'] = array( 'post', 'page', 'index' );
378
						break;
379
				}
380
			}
381
382 View Code Duplication
			if ( $data['show'] = array_intersect( $data['show'], $shows ) ) {
383
				$options['global']['show'] = $data['show'];
384
			}
385
		}
386
387
		update_option( 'sharing-options', $options );
388
		return $options['global'];
389
	}
390
391
	public function get_global_options() {
392
		if ( $this->global === false ) {
393
			$options = get_option( 'sharing-options' );
394
395
			if ( is_array( $options ) && isset( $options['global'] ) && is_array( $options['global'] ) ) {
396
				$this->global = $options['global'];
0 ignored issues
show
Documentation Bug introduced by
It seems like $options['global'] of type array is incompatible with the declared type boolean of property $global.

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

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

Loading history...
397
			} else {
398
				$this->global = $this->set_global_options( $options );
399
			}
400
		}
401
402
		if ( ! isset( $this->global['show'] ) ) {
403
			$this->global['show'] = array( 'post', 'page' );
404
		} elseif ( is_scalar( $this->global['show'] ) ) {
405
			switch ( $this->global['show'] ) {
406
				case 'posts':
407
					$this->global['show'] = array( 'post', 'page' );
408
					break;
409
				case 'index':
410
					$this->global['show'] = array( 'index' );
411
					break;
412
				case 'posts-index':
413
					$this->global['show'] = array( 'post', 'page', 'index' );
414
					break;
415
			}
416
		}
417
418
		if ( false === $this->global['sharing_label'] ) {
419
			$this->global['sharing_label'] = $this->default_sharing_label;
420
		}
421
422
		return $this->global;
423
	}
424
425
	public function set_service( $id, Sharing_Source $service ) {
426
		// Update the options for this service
427
		$options = get_option( 'sharing-options' );
428
429
		// No options yet
430
		if ( ! is_array( $options ) ) {
431
			$options = array();
432
		}
433
434
		/**
435
		 * Get the state of a sharing button.
436
		 *
437
		 * @module sharedaddy
438
		 *
439
		 * @since 1.1.0
440
		 *
441
		 * @param array $args {
442
		 *  State of a sharing button.
443
		 *
444
		 *  @type string $id Service ID.
445
		 *  @type array $options Array of all sharing options.
446
		 *  @type array $service Details about a service.
447
		 * }
448
		 */
449
		do_action(
450
			'sharing_get_button_state', array(
451
				'id'      => $id,
452
				'options' => $options,
453
				'service' => $service,
454
			)
455
		);
456
457
		$options[ $id ] = $service->get_options();
0 ignored issues
show
Bug introduced by
The method get_options cannot be called on $service (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
458
459
		update_option( 'sharing-options', array_filter( $options ) );
460
	}
461
462
	// Soon to come to a .org plugin near you!
463
	public function get_total( $service_name = false, $post_id = false, $_blog_id = false ) {
464
		global $wpdb, $blog_id;
465
		if ( ! $_blog_id ) {
466
			$_blog_id = $blog_id;
467
		}
468 View Code Duplication
		if ( $service_name == 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...
469
			if ( $post_id > 0 ) {
470
				// total number of shares for this post
471
				return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND post_id = %d', $_blog_id, $post_id ) );
472
			} else {
473
				// total number of shares for this blog
474
				return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d', $_blog_id ) );
475
			}
476
		}
477
478 View Code Duplication
		if ( $post_id > 0 ) {
479
			return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND post_id = %d AND share_service = %s', $_blog_id, $post_id, $service_name ) );
480
		} else {
481
			return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d AND share_service = %s', $_blog_id, $service_name ) );
482
		}
483
	}
484
485
	public function get_services_total( $post_id = false ) {
486
		$totals   = array();
487
		$services = $this->get_blog_services();
488
489
		if ( ! empty( $services ) && isset( $services['all'] ) ) {
490
			foreach ( $services['all'] as $key => $value ) {
491
				$totals[ $key ] = new Sharing_Service_Total( $key, $this->get_total( $key, $post_id ) );
0 ignored issues
show
Documentation introduced by
$key is of type integer|string, but the function expects a boolean.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
492
			}
493
		}
494
		usort( $totals, array( 'Sharing_Service_Total', 'cmp' ) );
495
496
		return $totals;
497
	}
498
499 View Code Duplication
	public function get_posts_total() {
500
		$totals = array();
501
		global $wpdb, $blog_id;
502
503
		$my_data = $wpdb->get_results( $wpdb->prepare( 'SELECT post_id as id, SUM( count ) as total FROM sharing_stats WHERE blog_id = %d GROUP BY post_id ORDER BY count DESC ', $blog_id ) );
504
505
		if ( ! empty( $my_data ) ) {
506
			foreach ( $my_data as $row ) {
507
				$totals[] = new Sharing_Post_Total( $row->id, $row->total );
508
			}
509
		}
510
511
		usort( $totals, array( 'Sharing_Post_Total', 'cmp' ) );
512
513
		return $totals;
514
	}
515
}
516
517
class Sharing_Service_Total {
518
	public $id      = '';
519
	public $name    = '';
520
	public $service = '';
521
	public $total   = 0;
522
523
	public function __construct( $id, $total ) {
524
		$services      = new Sharing_Service();
525
		$this->id      = esc_html( $id );
526
		$this->service = $services->get_service( $id );
527
		$this->total   = (int) $total;
528
529
		$this->name = $this->service->get_name();
530
	}
531
532
	static function cmp( $a, $b ) {
533
		if ( $a->total == $b->total ) {
534
			return $a->name < $b->name;
535
		}
536
		return $a->total < $b->total;
537
	}
538
}
539
540
class Sharing_Post_Total {
541
	public $id    = 0;
542
	public $total = 0;
543
	public $title = '';
544
	public $url   = '';
545
546
	public function __construct( $id, $total ) {
547
		$this->id    = (int) $id;
548
		$this->total = (int) $total;
549
		$this->title = get_the_title( $this->id );
550
		$this->url   = get_permalink( $this->id );
551
	}
552
553
	static function cmp( $a, $b ) {
554
		if ( $a->total == $b->total ) {
555
			return $a->id < $b->id;
556
		}
557
		return $a->total < $b->total;
558
	}
559
}
560
561
function sharing_register_post_for_share_counts( $post_id ) {
562
	global $jetpack_sharing_counts;
563
564
	if ( ! isset( $jetpack_sharing_counts ) || ! is_array( $jetpack_sharing_counts ) ) {
565
		$jetpack_sharing_counts = array();
566
	}
567
568
	$jetpack_sharing_counts[ (int) $post_id ] = get_permalink( $post_id );
569
}
570
571
function sharing_maybe_enqueue_scripts() {
572
	$sharer         = new Sharing_Service();
573
	$global_options = $sharer->get_global_options();
574
575
	$enqueue = false;
576
	if ( is_singular() && in_array( get_post_type(), $global_options['show'] ) ) {
577
		$enqueue = true;
578 View Code Duplication
	} elseif ( in_array( 'index', $global_options['show'] ) && ( is_home() || is_front_page() || is_archive() || is_search() || in_array( get_post_type(), $global_options['show'] ) ) ) {
579
		$enqueue = true;
580
	}
581
582
	/**
583
	 * Filter to decide when sharing scripts should be enqueued.
584
	 *
585
	 * @module sharedaddy
586
	 *
587
	 * @since 3.2.0
588
	 *
589
	 * @param bool $enqueue Decide if the sharing scripts should be enqueued.
590
	 */
591
	return (bool) apply_filters( 'sharing_enqueue_scripts', $enqueue );
592
}
593
594
function sharing_add_footer() {
595
	if (
596
		class_exists( 'Jetpack_AMP_Support' )
597
		&& Jetpack_AMP_Support::is_amp_request()
598
	) {
599
		return;
600
	}
601
602
	global $jetpack_sharing_counts;
603
604
	/**
605
	 * Filter all JavaScript output by the sharing module.
606
	 *
607
	 * @module sharedaddy
608
	 *
609
	 * @since 1.1.0
610
	 *
611
	 * @param bool true Control whether the sharing module should add any JavaScript to the site. Default to true.
612
	 */
613
	if ( apply_filters( 'sharing_js', true ) && sharing_maybe_enqueue_scripts() ) {
614
615
		/**
616
		 * Filter the display of sharing counts next to the sharing buttons.
617
		 *
618
		 * @module sharedaddy
619
		 *
620
		 * @since 3.2.0
621
		 *
622
		 * @param bool true Control the display of counters next to the sharing buttons. Default to true.
623
		 */
624
		if ( apply_filters( 'jetpack_sharing_counts', true ) && is_array( $jetpack_sharing_counts ) && count( $jetpack_sharing_counts ) ) :
625
			$sharing_post_urls = array_filter( $jetpack_sharing_counts );
626
			if ( $sharing_post_urls ) :
0 ignored issues
show
Bug Best Practice introduced by
The expression $sharing_post_urls of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
627
				?>
628
629
	<script type="text/javascript">
630
		window.WPCOM_sharing_counts = <?php echo json_encode( array_flip( $sharing_post_urls ) ); ?>;
631
	</script>
632
				<?php
633
			endif;
634
		endif;
635
636
		wp_enqueue_script( 'sharing-js' );
637
		$sharing_js_options = array(
638
			'lang'            => get_base_recaptcha_lang_code(),
639
			/** This filter is documented in modules/sharedaddy/sharing-service.php */
640
			'counts'          => apply_filters( 'jetpack_sharing_counts', true ),
641
			'is_stats_active' => Jetpack::is_module_active( 'stats' ),
642
		);
643
		wp_localize_script( 'sharing-js', 'sharing_js_options', $sharing_js_options );
644
	}
645
	$sharer  = new Sharing_Service();
646
	$enabled = $sharer->get_blog_services();
647
	foreach ( array_merge( $enabled['visible'], $enabled['hidden'] ) as $service ) {
648
		$service->display_footer();
649
	}
650
}
651
652
function sharing_add_header() {
653
	$sharer  = new Sharing_Service();
654
	$enabled = $sharer->get_blog_services();
655
656
	foreach ( array_merge( $enabled['visible'], $enabled['hidden'] ) as $service ) {
657
		$service->display_header();
658
	}
659
660
	if ( count( $enabled['all'] ) > 0 && sharing_maybe_enqueue_scripts() ) {
661
		wp_enqueue_style( 'sharedaddy', plugin_dir_url( __FILE__ ) . 'sharing.css', array(), JETPACK__VERSION );
662
		wp_enqueue_style( 'social-logos' );
663
	}
664
665
}
666
add_action( 'wp_head', 'sharing_add_header', 1 );
667
668
function sharing_process_requests() {
669
	global $post;
670
671
	// Only process if: single post and share=X defined
672
	if ( ( is_page() || is_single() ) && isset( $_GET['share'] ) && is_string( $_GET['share'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
673
		$sharer = new Sharing_Service();
674
675
		$service = $sharer->get_service( $_GET['share'] );
676
		if ( $service ) {
677
			$service->process_request( $post, $_POST );
678
		}
679
	}
680
}
681
add_action( 'template_redirect', 'sharing_process_requests', 9 );
682
683
/**
684
 * Gets the url to customise the sharing buttons in Calypso.
685
 *
686
 * @return string the customisation URL or null if it couldn't be determinde.
687
 */
688
function get_sharing_buttons_customisation_url() {
689
	return Redirect::get_url( 'calypso-marketing-sharing-buttons', array( 'site' => ( new Status() )->get_site_suffix() ) );
690
}
691
692
/**
693
 * Append sharing links to text.
694
 *
695
 * @param string $text The original text to append sharing links onto.
696
 * @param bool   $echo Where to echo the text or return.
697
 *
698
 * @return string The original $text with, if conditions are met, the sharing links.
699
 */
700
function sharing_display( $text = '', $echo = false ) {
701
	global $post, $wp_current_filter;
702
703
	if ( Settings::is_syncing() ) {
704
		return $text;
705
	}
706
707
	if ( empty( $post ) ) {
708
		return $text;
709
	}
710
711
	if ( ( is_preview() || is_admin() ) && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
712
		return $text;
713
	}
714
715
	// Don't output flair on excerpts.
716
	if ( in_array( 'get_the_excerpt', (array) $wp_current_filter, true ) ) {
717
		return $text;
718
	}
719
720
	// Don't allow flair to be added to the_content more than once (prevent infinite loops).
721
	$done = false;
722
	foreach ( $wp_current_filter as $filter ) {
723
		if ( 'the_content' === $filter ) {
724
			if ( $done ) {
725
				return $text;
726
			} else {
727
				$done = true;
728
			}
729
		}
730
	}
731
732
	// check whether we are viewing the front page and whether the front page option is checked.
733
	$options         = get_option( 'sharing-options' );
734
	$display_options = null;
735
736
	if ( is_array( $options ) ) {
737
		$display_options = $options['global']['show'];
738
	}
739
740
	if ( is_front_page() && ( is_array( $display_options ) && ! in_array( 'index', $display_options, true ) ) ) {
741
		return $text;
742
	}
743
744
	if ( is_attachment() && in_array( 'the_excerpt', (array) $wp_current_filter, true ) ) {
745
		// Many themes run the_excerpt() conditionally on an attachment page, then run the_content().
746
		// We only want to output the sharing buttons once.  Let's stick with the_content().
747
		return $text;
748
	}
749
750
	$sharer = new Sharing_Service();
751
	$global = $sharer->get_global_options();
752
753
	$show = false;
754
	if ( ! is_feed() ) {
755
		if ( is_singular() && in_array( get_post_type(), $global['show'], true ) ) {
756
			$show = true;
757 View Code Duplication
		} elseif ( in_array( 'index', $global['show'], true ) && ( is_home() || is_front_page() || is_archive() || is_search() || in_array( get_post_type(), $global['show'], true ) ) ) {
758
			$show = true;
759
		}
760
	}
761
762
	/**
763
	 * Filter to decide if sharing buttons should be displayed.
764
	 *
765
	 * @module sharedaddy
766
	 *
767
	 * @since 1.1.0
768
	 *
769
	 * @param bool $show Should the sharing buttons be displayed.
770
	 * @param WP_Post $post The post to share.
771
	 */
772
	$show = apply_filters( 'sharing_show', $show, $post );
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...
773
774
	// Disabled for this post?
775
	$switched_status = get_post_meta( $post->ID, 'sharing_disabled', false );
776
777
	if ( ! empty( $switched_status ) ) {
778
		$show = false;
779
	}
780
781
	// Is the post private?
782
	$post_status = get_post_status( $post->ID );
783
784
	if ( 'private' === $post_status ) {
785
		$show = false;
786
	}
787
788
	/**
789
	 * Filter the Sharing buttons' Ajax action name Jetpack checks for.
790
	 * This allows the use of the buttons with your own Ajax implementation.
791
	 *
792
	 * @module sharedaddy
793
	 *
794
	 * @since 7.3.0
795
	 *
796
	 * @param string $sharing_ajax_action_name Name of the Sharing buttons' Ajax action.
797
	 */
798
	$ajax_action = apply_filters( 'sharing_ajax_action', 'get_latest_posts' );
799
800
	// Allow to be used in ajax requests for latest posts.
801
	if (
802
		defined( 'DOING_AJAX' )
803
		&& DOING_AJAX
804
		&& isset( $_REQUEST['action'] )
805
		&& $ajax_action === $_REQUEST['action']
806
	) {
807
		$show = true;
808
	}
809
810
	$sharing_content = '';
811
	$enabled         = false;
812
813
	if ( $show ) {
814
		/**
815
		 * Filters the list of enabled Sharing Services.
816
		 *
817
		 * @module sharedaddy
818
		 *
819
		 * @since 2.2.3
820
		 *
821
		 * @param array $sharer->get_blog_services() Array of Sharing Services currently enabled.
822
		 */
823
		$enabled = apply_filters( 'sharing_enabled', $sharer->get_blog_services() );
824
825
		if ( count( $enabled['all'] ) > 0 ) {
826
			$dir = get_option( 'text_direction' );
827
828
			// Wrapper.
829
			$sharing_content .= '<div class="sharedaddy sd-sharing-enabled"><div class="robots-nocontent sd-block sd-social sd-social-' . $global['button_style'] . ' sd-sharing">';
830
			if ( '' !== $global['sharing_label'] ) {
831
				$sharing_content .= sprintf(
832
					/**
833
					 * Filter the sharing buttons' headline structure.
834
					 *
835
					 * @module sharedaddy
836
					 *
837
					 * @since 4.4.0
838
					 *
839
					 * @param string $sharing_headline Sharing headline structure.
840
					 * @param string $global['sharing_label'] Sharing title.
841
					 * @param string $sharing Module name.
842
					 */
843
					apply_filters( 'jetpack_sharing_headline_html', '<h3 class="sd-title">%s</h3>', $global['sharing_label'], 'sharing' ),
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $global['sharing_label'].

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...
844
					esc_html( $global['sharing_label'] )
845
				);
846
			}
847
			$sharing_content .= '<div class="sd-content"><ul>';
848
849
			// Visible items.
850
			$visible = '';
851
			foreach ( $enabled['visible'] as $id => $service ) {
852
				$klasses = array( 'share-' . $service->get_class() );
853
				if ( $service->is_deprecated() ) {
854
					if ( ! current_user_can( 'manage_options' ) ) {
855
						continue;
856
					}
857
					$klasses[] = 'share-deprecated';
858
				}
859
				// Individual HTML for sharing service.
860
				$visible .= '<li class="' . implode( ' ', $klasses ) . '">' . $service->get_display( $post ) . '</li>';
861
			}
862
863
			$parts   = array();
864
			$parts[] = $visible;
865
			if ( count( $enabled['hidden'] ) > 0 ) {
866
				if ( count( $enabled['visible'] ) > 0 ) {
867
					$expand = __( 'More', 'jetpack' );
868
				} else {
869
					$expand = __( 'Share', 'jetpack' );
870
				}
871
				$parts[] = '<li><a href="#" class="sharing-anchor sd-button share-more"><span>' . $expand . '</span></a></li>';
872
			}
873
874
			if ( 'rtl' === $dir ) {
875
				$parts = array_reverse( $parts );
876
			}
877
878
			$sharing_content .= implode( '', $parts );
879
			$sharing_content .= '<li class="share-end"></li></ul>';
880
881
			// Link to customization options if user can manage them.
882
			if ( current_user_can( 'manage_options' ) ) {
883
				$link_url = get_sharing_buttons_customisation_url();
884
				if ( ! empty( $link_url ) ) {
885
					$link_text        = __( 'Customize buttons', 'jetpack' );
886
					$sharing_content .= '<p class="share-customize-link"><a href="' . esc_url( $link_url ) . '" target="_blank" rel="noopener noreferrer">' . esc_html( $link_text ) . '</a></p>';
887
				}
888
			}
889
890
			if ( count( $enabled['hidden'] ) > 0 ) {
891
				$sharing_content .= '<div class="sharing-hidden"><div class="inner" style="display: none;';
892
893
				if ( count( $enabled['hidden'] ) === 1 ) {
894
					$sharing_content .= 'width:150px;';
895
				}
896
897
				$sharing_content .= '">';
898
899
				if ( count( $enabled['hidden'] ) === 1 ) {
900
					$sharing_content .= '<ul style="background-image:none;">';
901
				} else {
902
					$sharing_content .= '<ul>';
903
				}
904
905
				$count = 1;
906
				foreach ( $enabled['hidden'] as $id => $service ) {
907
					// Individual HTML for sharing service.
908
					$klasses = array( 'share-' . $service->get_class() );
909
					if ( $service->is_deprecated() ) {
910
						if ( ! current_user_can( 'manage_options' ) ) {
911
							continue;
912
						}
913
						$klasses[] = 'share-deprecated';
914
					}
915
					$sharing_content .= '<li class="' . implode( ' ', $klasses ) . '">';
916
					$sharing_content .= $service->get_display( $post );
917
					$sharing_content .= '</li>';
918
919
					if ( ( $count % 2 ) === 0 ) {
920
						$sharing_content .= '<li class="share-end"></li>';
921
					}
922
923
					$count ++;
924
				}
925
926
				// End of wrapper.
927
				$sharing_content .= '<li class="share-end"></li></ul></div></div>';
928
			}
929
930
			$sharing_content .= '</div></div></div>';
931
932
			// Register our JS.
933
			if ( defined( 'JETPACK__VERSION' ) ) {
934
				$ver = JETPACK__VERSION;
935
			} else {
936
				$ver = '20201124';
937
			}
938
939
			// @todo: Investigate if we can load this JS in the footer instead.
940
			wp_register_script(
941
				'sharing-js',
942
				Assets::get_file_url_for_environment(
943
					'_inc/build/sharedaddy/sharing.min.js',
944
					'modules/sharedaddy/sharing.js'
945
				),
946
				array(),
947
				$ver,
948
				false
949
			);
950
951
			// Enqueue scripts for the footer.
952
			add_action( 'wp_footer', 'sharing_add_footer' );
953
		}
954
	}
955
956
	/**
957
	 * Filters the content markup of the Jetpack sharing links
958
	 *
959
	 * @module sharedaddy
960
	 *
961
	 * @since 3.8.0
962
	 * @since 6.2.0 Started sending $enabled as a second parameter.
963
	 *
964
	 * @param string $sharing_content Content markup of the Jetpack sharing links
965
	 * @param array  $enabled         Array of Sharing Services currently enabled.
966
	 */
967
	$sharing_markup = apply_filters( 'jetpack_sharing_display_markup', $sharing_content, $enabled );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $enabled.

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...
968
969
	if ( $echo ) {
970
		echo $text . $sharing_markup;
971
	} else {
972
		return $text . $sharing_markup;
973
	}
974
}
975
976
function get_base_recaptcha_lang_code() {
977
978
	$base_recaptcha_lang_code_mapping = array(
979
		'en'    => 'en',
980
		'nl'    => 'nl',
981
		'fr'    => 'fr',
982
		'fr-be' => 'fr',
983
		'fr-ca' => 'fr',
984
		'fr-ch' => 'fr',
985
		'de'    => 'de',
986
		'pt'    => 'pt',
987
		'pt-br' => 'pt',
988
		'ru'    => 'ru',
989
		'es'    => 'es',
990
		'tr'    => 'tr',
991
	);
992
993
	$blog_lang_code = get_bloginfo( 'language' );
994
	if ( isset( $base_recaptcha_lang_code_mapping[ $blog_lang_code ] ) ) {
995
		return $base_recaptcha_lang_code_mapping[ $blog_lang_code ];
996
	}
997
998
	// if no base mapping is found return default 'en'
999
	return 'en';
1000
}
1001
1002
Sharing_Service::init();
1003