Completed
Push — add/redirect-everything ( 50f94e...5deed2 )
by
unknown
181:35 queued 174:43
created

Sharing_Service::new_service()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 5
nop 3
dl 0
loc 38
rs 8.6897
c 0
b 0
f 0
1
<?php
2
3
use Automattic\Jetpack\Assets;
4
use Automattic\Jetpack\Sync\Settings;
5
6
include_once dirname( __FILE__ ) . '/sharing-sources.php';
7
8
define( 'WP_SHARING_PLUGIN_VERSION', JETPACK__VERSION );
9
10
class Sharing_Service {
11
	private $global               = false;
12
	public $default_sharing_label = '';
13
14
	/**
15
	 * Initialize the sharing service.
16
	 * Only run this method once upon module loading.
17
	 */
18
	public static function init() {
19
		add_filter( 'the_content', 'sharing_display', 19 );
20
		add_filter( 'the_excerpt', 'sharing_display', 19 );
21
	}
22
23
	public function __construct() {
24
		$this->default_sharing_label = __( 'Share this:', 'jetpack' );
25
	}
26
27
	/**
28
	 * Gets a generic list of all services, without any config
29
	 */
30
	public function get_all_services_blog() {
31
		$options = get_option( 'sharing-options' );
32
33
		$all      = $this->get_all_services();
34
		$services = array();
35
36
		foreach ( $all as $id => $name ) {
37
			if ( isset( $all[ $id ] ) ) {
38
				$config = array();
39
40
				// Pre-load custom modules otherwise they won't know who they are
41
				if ( substr( $id, 0, 7 ) == 'custom-' && is_array( $options[ $id ] ) ) {
42
					$config = $options[ $id ];
43
				}
44
45
				$services[ $id ] = new $all[ $id ]( $id, $config );
46
			}
47
		}
48
49
		return $services;
50
	}
51
52
	/**
53
	 * Gets a list of all available service names and classes
54
	 */
55
	public function get_all_services( $include_custom = true ) {
56
		// Default services
57
		// if you update this list, please update the REST API tests
58
		// in bin/tests/api/suites/SharingTest.php
59
		$services = array(
60
			'print'            => 'Share_Print',
61
			'facebook'         => 'Share_Facebook',
62
			'linkedin'         => 'Share_LinkedIn',
63
			'reddit'           => 'Share_Reddit',
64
			'twitter'          => 'Share_Twitter',
65
			'tumblr'           => 'Share_Tumblr',
66
			'pinterest'        => 'Share_Pinterest',
67
			'pocket'           => 'Share_Pocket',
68
			'telegram'         => 'Share_Telegram',
69
			'jetpack-whatsapp' => 'Jetpack_Share_WhatsApp',
70
			'skype'            => 'Share_Skype',
71
		);
72
73
		/**
74
		 * Filters if Email Sharing is enabled.
75
		 *
76
		 * E-Mail sharing is often problematic due to spam concerns, so this filter enables it to be quickly and simply toggled.
77
		 * @module sharedaddy
78
		 *
79
		 * @since 5.1.0
80
		 *
81
		 * @param bool $email Is e-mail sharing enabled? Default false if Akismet is not active or true if Akismet is active.
82
		 */
83
		if ( apply_filters( 'sharing_services_email', Jetpack::is_akismet_active() ) ) {
84
			$services['email'] = 'Share_Email';
85
		}
86
87
		if ( is_multisite() && is_plugin_active( 'press-this/press-this-plugin.php' ) ) {
88
			$services['press-this'] = 'Share_PressThis';
89
		}
90
91
		if ( $include_custom ) {
92
			// Add any custom services in
93
			$options = $this->get_global_options();
94
			foreach ( (array) $options['custom'] as $custom_id ) {
95
				$services[ $custom_id ] = 'Share_Custom';
96
			}
97
		}
98
99
		/**
100
		 * Filters the list of available Sharing Services.
101
		 *
102
		 * @module sharedaddy
103
		 *
104
		 * @since 1.1.0
105
		 *
106
		 * @param array $services Array of all available Sharing Services.
107
		 */
108
		return apply_filters( 'sharing_services', $services );
109
	}
110
111
	public function new_service( $label, $url, $icon ) {
112
		// Validate
113
		$label = trim( wp_html_excerpt( wp_kses( $label, array() ), 30 ) );
114
		$url   = trim( esc_url_raw( $url ) );
115
		$icon  = trim( esc_url_raw( $icon ) );
116
117
		if ( $label && $url && $icon ) {
118
			$options = get_option( 'sharing-options' );
119
			if ( ! is_array( $options ) ) {
120
				$options = array();
121
			}
122
123
			$service_id = 'custom-' . time();
124
125
			// Add a new custom service
126
			$options['global']['custom'][] = $service_id;
127
			if ( false !== $this->global ) {
128
				$this->global['custom'][] = $service_id;
129
			}
130
131
			update_option( 'sharing-options', $options );
132
133
			// Create a custom service and set the options for it
134
			$service = new Share_Custom(
135
				$service_id, array(
136
					'name' => $label,
137
					'url'  => $url,
138
					'icon' => $icon,
139
				)
140
			);
141
			$this->set_service( $service_id, $service );
142
143
			// Return the service
144
			return $service;
145
		}
146
147
		return false;
148
	}
149
150
	public function delete_service( $service_id ) {
151
		$options = get_option( 'sharing-options' );
152
		if ( isset( $options[ $service_id ] ) ) {
153
			unset( $options[ $service_id ] );
154
		}
155
156
		$key = array_search( $service_id, $options['global']['custom'] );
157
		if ( $key !== false ) {
158
			unset( $options['global']['custom'][ $key ] );
159
		}
160
161
		update_option( 'sharing-options', $options );
162
		return true;
163
	}
164
165
	public function set_blog_services( array $visible, array $hidden ) {
166
		$services = $this->get_all_services();
167
		// Validate the services
168
		$available = array_keys( $services );
169
170
		// Only allow services that we have defined
171
		$hidden  = array_intersect( $hidden, $available );
172
		$visible = array_intersect( $visible, $available );
173
174
		// Ensure we don't have the same ones in hidden and visible
175
		$hidden = array_diff( $hidden, $visible );
176
177
		/**
178
		 * Control the state of the list of sharing services.
179
		 *
180
		 * @module sharedaddy
181
		 *
182
		 * @since 1.1.0
183
		 *
184
		 * @param array $args {
185
		 *  Array of options describing the state of the sharing services.
186
		 *
187
		 *  @type array $services List of all available service names and classes.
188
		 *  @type array $available Validated list of all available service names and classes.
189
		 *  @type array $hidden List of services hidden behind a "More" button.
190
		 *  @type array $visible List of visible services.
191
		 *  @type array $this->get_blog_services() Array of Sharing Services currently enabled.
192
		 * }
193
		 */
194
		do_action(
195
			'sharing_get_services_state', array(
196
				'services'          => $services,
197
				'available'         => $available,
198
				'hidden'            => $hidden,
199
				'visible'           => $visible,
200
				'currently_enabled' => $this->get_blog_services(),
201
			)
202
		);
203
204
		return update_option(
205
			'sharing-services', array(
206
				'visible' => $visible,
207
				'hidden'  => $hidden,
208
			)
209
		);
210
	}
211
212
	public function get_blog_services() {
213
		$options  = get_option( 'sharing-options' );
214
		$enabled  = get_option( 'sharing-services' );
215
		$services = $this->get_all_services();
216
217
		/**
218
		 * Check if options exist and are well formatted.
219
		 * This avoids issues on sites with corrupted options.
220
		 * @see https://github.com/Automattic/jetpack/issues/6121
221
		 */
222
		if ( ! is_array( $options ) || ! isset( $options['button_style'], $options['global'] ) ) {
223
			$global_options = array( 'global' => $this->get_global_options() );
224
			$options        = is_array( $options )
225
				? array_merge( $options, $global_options )
226
				: $global_options;
227
		}
228
229
		$global = $options['global'];
230
231
		// Default services
232
		if ( ! is_array( $enabled ) ) {
233
			$enabled = array(
234
				'visible' => array(
235
					'twitter',
236
					'facebook',
237
				),
238
				'hidden'  => array(),
239
			);
240
241
			/**
242
			 * Filters the list of default Sharing Services.
243
			 *
244
			 * @module sharedaddy
245
			 *
246
			 * @since 1.1.0
247
			 *
248
			 * @param array $enabled Array of default Sharing Services.
249
			 */
250
			$enabled = apply_filters( 'sharing_default_services', $enabled );
251
		}
252
253
		// Cleanup after any filters that may have produced duplicate services
254 View Code Duplication
		if ( is_array( $enabled['visible'] ) ) {
255
			$enabled['visible'] = array_unique( $enabled['visible'] );
256
		} else {
257
			$enabled['visible'] = array();
258
		}
259
260 View Code Duplication
		if ( is_array( $enabled['hidden'] ) ) {
261
			$enabled['hidden'] = array_unique( $enabled['hidden'] );
262
		} else {
263
			$enabled['hidden'] = array();
264
		}
265
266
		// Form the enabled services
267
		$blog = array(
268
			'visible' => array(),
269
			'hidden'  => array(),
270
		);
271
272
		foreach ( $blog as $area => $stuff ) {
273
			foreach ( (array) $enabled[ $area ] as $service ) {
274
				if ( isset( $services[ $service ] ) ) {
275
					if ( ! isset( $options[ $service ] ) || ! is_array( $options[ $service ] ) ) {
276
						$options[ $service ] = array();
277
					}
278
					$blog[ $area ][ $service ] = new $services[ $service ]( $service, array_merge( $global, $options[ $service ] ) );
279
				}
280
			}
281
		}
282
283
		/**
284
		 * Filters the list of enabled Sharing Services.
285
		 *
286
		 * @module sharedaddy
287
		 *
288
		 * @since 1.1.0
289
		 *
290
		 * @param array $blog Array of enabled Sharing Services.
291
		 */
292
		$blog = apply_filters( 'sharing_services_enabled', $blog );
293
294
		// Add CSS for NASCAR
295
		if ( count( $blog['visible'] ) || count( $blog['hidden'] ) ) {
296
			add_filter( 'post_flair_block_css', 'post_flair_service_enabled_sharing' );
297
		}
298
299
		// Convenience for checking if a service is present
300
		$blog['all'] = array_flip( array_merge( array_keys( $blog['visible'] ), array_keys( $blog['hidden'] ) ) );
301
		return $blog;
302
	}
303
304
	public function get_service( $service_name ) {
305
		$services = $this->get_blog_services();
306
307
		if ( isset( $services['visible'][ $service_name ] ) ) {
308
			return $services['visible'][ $service_name ];
309
		}
310
311
		if ( isset( $services['hidden'][ $service_name ] ) ) {
312
			return $services['hidden'][ $service_name ];
313
		}
314
315
		return false;
316
	}
317
318
	public function set_global_options( $data ) {
319
		$options = get_option( 'sharing-options' );
320
321
		// No options yet.
322
		if ( ! is_array( $options ) ) {
323
			$options = array();
324
		}
325
326
		// Defaults.
327
		$options['global'] = array(
328
			'button_style'  => 'icon-text',
329
			'sharing_label' => $this->default_sharing_label,
330
			'open_links'    => 'same',
331
			'show'          => ! isset( $options['global'] ) ? array( 'post', 'page' ) : array(),
332
			'custom'        => isset( $options['global']['custom'] ) ? $options['global']['custom'] : array(),
333
		);
334
335
		/**
336
		 * Filters global sharing settings.
337
		 *
338
		 * @module sharedaddy
339
		 *
340
		 * @since 1.1.0
341
		 *
342
		 * @param array $options['global'] Array of global sharing settings.
343
		 */
344
		$options['global'] = apply_filters( 'sharing_default_global', $options['global'] );
345
346
		// Validate options and set from our data
347
		if ( isset( $data['button_style'] ) && in_array( $data['button_style'], array( 'icon-text', 'icon', 'text', 'official' ) ) ) {
348
			$options['global']['button_style'] = $data['button_style'];
349
		}
350
351
		if ( isset( $data['sharing_label'] ) ) {
352
			if ( $this->default_sharing_label === $data['sharing_label'] ) {
353
				$options['global']['sharing_label'] = false;
354
			} else {
355
				$options['global']['sharing_label'] = trim( wp_kses( stripslashes( $data['sharing_label'] ), array() ) );
356
			}
357
		}
358
359
		if ( isset( $data['open_links'] ) && in_array( $data['open_links'], array( 'new', 'same' ) ) ) {
360
			$options['global']['open_links'] = $data['open_links'];
361
		}
362
363
		$shows   = array_values( get_post_types( array( 'public' => true ) ) );
364
		$shows[] = 'index';
365
		if ( isset( $data['show'] ) ) {
366 View Code Duplication
			if ( is_scalar( $data['show'] ) ) {
367
				switch ( $data['show'] ) {
368
					case 'posts':
369
						$data['show'] = array( 'post', 'page' );
370
						break;
371
					case 'index':
372
						$data['show'] = array( 'index' );
373
						break;
374
					case 'posts-index':
375
						$data['show'] = array( 'post', 'page', 'index' );
376
						break;
377
				}
378
			}
379
380 View Code Duplication
			if ( $data['show'] = array_intersect( $data['show'], $shows ) ) {
381
				$options['global']['show'] = $data['show'];
382
			}
383
		}
384
385
		update_option( 'sharing-options', $options );
386
		return $options['global'];
387
	}
388
389
	public function get_global_options() {
390
		if ( $this->global === false ) {
391
			$options = get_option( 'sharing-options' );
392
393
			if ( is_array( $options ) && isset( $options['global'] ) && is_array( $options['global'] ) ) {
394
				$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...
395
			} else {
396
				$this->global = $this->set_global_options( $options );
397
			}
398
		}
399
400
		if ( ! isset( $this->global['show'] ) ) {
401
			$this->global['show'] = array( 'post', 'page' );
402
		} elseif ( is_scalar( $this->global['show'] ) ) {
403
			switch ( $this->global['show'] ) {
404
				case 'posts':
405
					$this->global['show'] = array( 'post', 'page' );
406
					break;
407
				case 'index':
408
					$this->global['show'] = array( 'index' );
409
					break;
410
				case 'posts-index':
411
					$this->global['show'] = array( 'post', 'page', 'index' );
412
					break;
413
			}
414
		}
415
416
		if ( false === $this->global['sharing_label'] ) {
417
			$this->global['sharing_label'] = $this->default_sharing_label;
418
		}
419
420
		return $this->global;
421
	}
422
423
	public function set_service( $id, Sharing_Source $service ) {
424
		// Update the options for this service
425
		$options = get_option( 'sharing-options' );
426
427
		// No options yet
428
		if ( ! is_array( $options ) ) {
429
			$options = array();
430
		}
431
432
		/**
433
		 * Get the state of a sharing button.
434
		 *
435
		 * @module sharedaddy
436
		 *
437
		 * @since 1.1.0
438
		 *
439
		 * @param array $args {
440
		 *  State of a sharing button.
441
		 *
442
		 *  @type string $id Service ID.
443
		 *  @type array $options Array of all sharing options.
444
		 *  @type array $service Details about a service.
445
		 * }
446
		 */
447
		do_action(
448
			'sharing_get_button_state', array(
449
				'id'      => $id,
450
				'options' => $options,
451
				'service' => $service,
452
			)
453
		);
454
455
		$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...
456
457
		update_option( 'sharing-options', array_filter( $options ) );
458
	}
459
460
	// Soon to come to a .org plugin near you!
461
	public function get_total( $service_name = false, $post_id = false, $_blog_id = false ) {
462
		global $wpdb, $blog_id;
463
		if ( ! $_blog_id ) {
464
			$_blog_id = $blog_id;
465
		}
466 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...
467
			if ( $post_id > 0 ) {
468
				// total number of shares for this post
469
				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 ) );
470
			} else {
471
				// total number of shares for this blog
472
				return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d', $_blog_id ) );
473
			}
474
		}
475
476 View Code Duplication
		if ( $post_id > 0 ) {
477
			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 ) );
478
		} else {
479
			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 ) );
480
		}
481
	}
482
483
	public function get_services_total( $post_id = false ) {
484
		$totals   = array();
485
		$services = $this->get_blog_services();
486
487
		if ( ! empty( $services ) && isset( $services['all'] ) ) {
488
			foreach ( $services['all'] as $key => $value ) {
489
				$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...
490
			}
491
		}
492
		usort( $totals, array( 'Sharing_Service_Total', 'cmp' ) );
493
494
		return $totals;
495
	}
496
497 View Code Duplication
	public function get_posts_total() {
498
		$totals = array();
499
		global $wpdb, $blog_id;
500
501
		$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 ) );
502
503
		if ( ! empty( $my_data ) ) {
504
			foreach ( $my_data as $row ) {
505
				$totals[] = new Sharing_Post_Total( $row->id, $row->total );
506
			}
507
		}
508
509
		usort( $totals, array( 'Sharing_Post_Total', 'cmp' ) );
510
511
		return $totals;
512
	}
513
}
514
515
class Sharing_Service_Total {
516
	public $id      = '';
517
	public $name    = '';
518
	public $service = '';
519
	public $total   = 0;
520
521
	public function __construct( $id, $total ) {
522
		$services      = new Sharing_Service();
523
		$this->id      = esc_html( $id );
524
		$this->service = $services->get_service( $id );
525
		$this->total   = (int) $total;
526
527
		$this->name = $this->service->get_name();
528
	}
529
530
	static function cmp( $a, $b ) {
531
		if ( $a->total == $b->total ) {
532
			return $a->name < $b->name;
533
		}
534
		return $a->total < $b->total;
535
	}
536
}
537
538
class Sharing_Post_Total {
539
	public $id    = 0;
540
	public $total = 0;
541
	public $title = '';
542
	public $url   = '';
543
544
	public function __construct( $id, $total ) {
545
		$this->id    = (int) $id;
546
		$this->total = (int) $total;
547
		$this->title = get_the_title( $this->id );
548
		$this->url   = get_permalink( $this->id );
549
	}
550
551
	static function cmp( $a, $b ) {
552
		if ( $a->total == $b->total ) {
553
			return $a->id < $b->id;
554
		}
555
		return $a->total < $b->total;
556
	}
557
}
558
559
function sharing_register_post_for_share_counts( $post_id ) {
560
	global $jetpack_sharing_counts;
561
562
	if ( ! isset( $jetpack_sharing_counts ) || ! is_array( $jetpack_sharing_counts ) ) {
563
		$jetpack_sharing_counts = array();
564
	}
565
566
	$jetpack_sharing_counts[ (int) $post_id ] = get_permalink( $post_id );
567
}
568
569
function sharing_maybe_enqueue_scripts() {
570
	$sharer         = new Sharing_Service();
571
	$global_options = $sharer->get_global_options();
572
573
	$enqueue = false;
574
	if ( is_singular() && in_array( get_post_type(), $global_options['show'] ) ) {
575
		$enqueue = true;
576 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'] ) ) ) {
577
		$enqueue = true;
578
	}
579
580
	/**
581
	 * Filter to decide when sharing scripts should be enqueued.
582
	 *
583
	 * @module sharedaddy
584
	 *
585
	 * @since 3.2.0
586
	 *
587
	 * @param bool $enqueue Decide if the sharing scripts should be enqueued.
588
	 */
589
	return (bool) apply_filters( 'sharing_enqueue_scripts', $enqueue );
590
}
591
592
function sharing_add_footer() {
593
	if (
594
		class_exists( 'Jetpack_AMP_Support' )
595
		&& Jetpack_AMP_Support::is_amp_request()
596
	) {
597
		return;
598
	}
599
600
	global $jetpack_sharing_counts;
601
602
	/**
603
	 * Filter all JavaScript output by the sharing module.
604
	 *
605
	 * @module sharedaddy
606
	 *
607
	 * @since 1.1.0
608
	 *
609
	 * @param bool true Control whether the sharing module should add any JavaScript to the site. Default to true.
610
	 */
611
	if ( apply_filters( 'sharing_js', true ) && sharing_maybe_enqueue_scripts() ) {
612
613
		/**
614
		 * Filter the display of sharing counts next to the sharing buttons.
615
		 *
616
		 * @module sharedaddy
617
		 *
618
		 * @since 3.2.0
619
		 *
620
		 * @param bool true Control the display of counters next to the sharing buttons. Default to true.
621
		 */
622
		if ( apply_filters( 'jetpack_sharing_counts', true ) && is_array( $jetpack_sharing_counts ) && count( $jetpack_sharing_counts ) ) :
623
			$sharing_post_urls = array_filter( $jetpack_sharing_counts );
624
			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...
625
				?>
626
627
	<script type="text/javascript">
628
		window.WPCOM_sharing_counts = <?php echo json_encode( array_flip( $sharing_post_urls ) ); ?>;
629
	</script>
630
				<?php
631
			endif;
632
		endif;
633
634
		wp_enqueue_script( 'sharing-js' );
635
		$sharing_js_options = array(
636
			'lang'            => get_base_recaptcha_lang_code(),
637
			/** This filter is documented in modules/sharedaddy/sharing-service.php */
638
			'counts'          => apply_filters( 'jetpack_sharing_counts', true ),
639
			'is_stats_active' => Jetpack::is_module_active( 'stats' ),
640
		);
641
		wp_localize_script( 'sharing-js', 'sharing_js_options', $sharing_js_options );
642
	}
643
	$sharer  = new Sharing_Service();
644
	$enabled = $sharer->get_blog_services();
645
	foreach ( array_merge( $enabled['visible'], $enabled['hidden'] ) as $service ) {
646
		$service->display_footer();
647
	}
648
}
649
650
function sharing_add_header() {
651
	$sharer  = new Sharing_Service();
652
	$enabled = $sharer->get_blog_services();
653
654
	foreach ( array_merge( $enabled['visible'], $enabled['hidden'] ) as $service ) {
655
		$service->display_header();
656
	}
657
658
	if ( count( $enabled['all'] ) > 0 && sharing_maybe_enqueue_scripts() ) {
659
		wp_enqueue_style( 'sharedaddy', plugin_dir_url( __FILE__ ) . 'sharing.css', array(), JETPACK__VERSION );
660
		wp_enqueue_style( 'social-logos' );
661
	}
662
663
}
664
add_action( 'wp_head', 'sharing_add_header', 1 );
665
666
function sharing_process_requests() {
667
	global $post;
668
669
	// Only process if: single post and share=X defined
670
	if ( ( is_page() || is_single() ) && isset( $_GET['share'] ) ) {
671
		$sharer = new Sharing_Service();
672
673
		$service = $sharer->get_service( $_GET['share'] );
674
		if ( $service ) {
675
			$service->process_request( $post, $_POST );
676
		}
677
	}
678
}
679
add_action( 'template_redirect', 'sharing_process_requests', 9 );
680
681
/**
682
 * Append sharing links to text.
683
 *
684
 * @param string $text The original text to append sharing links onto.
685
 * @param bool   $echo Where to echo the text or return.
686
 *
687
 * @return string The original $text with, if conditions are met, the sharing links.
688
 */
689
function sharing_display( $text = '', $echo = false ) {
690
	global $post, $wp_current_filter;
691
692
	if ( Settings::is_syncing() ) {
693
		return $text;
694
	}
695
696
	if ( empty( $post ) ) {
697
		return $text;
698
	}
699
700
	if ( ( is_preview() || is_admin() ) && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
701
		return $text;
702
	}
703
704
	// Don't output flair on excerpts.
705
	if ( in_array( 'get_the_excerpt', (array) $wp_current_filter, true ) ) {
706
		return $text;
707
	}
708
709
	// Don't allow flair to be added to the_content more than once (prevent infinite loops).
710
	$done = false;
711
	foreach ( $wp_current_filter as $filter ) {
712
		if ( 'the_content' === $filter ) {
713
			if ( $done ) {
714
				return $text;
715
			} else {
716
				$done = true;
717
			}
718
		}
719
	}
720
721
	// check whether we are viewing the front page and whether the front page option is checked.
722
	$options         = get_option( 'sharing-options' );
723
	$display_options = null;
724
725
	if ( is_array( $options ) ) {
726
		$display_options = $options['global']['show'];
727
	}
728
729
	if ( is_front_page() && ( is_array( $display_options ) && ! in_array( 'index', $display_options, true ) ) ) {
730
		return $text;
731
	}
732
733
	if ( is_attachment() && in_array( 'the_excerpt', (array) $wp_current_filter, true ) ) {
734
		// Many themes run the_excerpt() conditionally on an attachment page, then run the_content().
735
		// We only want to output the sharing buttons once.  Let's stick with the_content().
736
		return $text;
737
	}
738
739
	$sharer = new Sharing_Service();
740
	$global = $sharer->get_global_options();
741
742
	$show = false;
743
	if ( ! is_feed() ) {
744
		if ( is_singular() && in_array( get_post_type(), $global['show'], true ) ) {
745
			$show = true;
746 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 ) ) ) {
747
			$show = true;
748
		}
749
	}
750
751
	/**
752
	 * Filter to decide if sharing buttons should be displayed.
753
	 *
754
	 * @module sharedaddy
755
	 *
756
	 * @since 1.1.0
757
	 *
758
	 * @param bool $show Should the sharing buttons be displayed.
759
	 * @param WP_Post $post The post to share.
760
	 */
761
	$show = apply_filters( 'sharing_show', $show, $post );
762
763
	// Disabled for this post?
764
	$switched_status = get_post_meta( $post->ID, 'sharing_disabled', false );
765
766
	if ( ! empty( $switched_status ) ) {
767
		$show = false;
768
	}
769
770
	// Is the post private?
771
	$post_status = get_post_status( $post->ID );
772
773
	if ( 'private' === $post_status ) {
774
		$show = false;
775
	}
776
777
	/**
778
	 * Filter the Sharing buttons' Ajax action name Jetpack checks for.
779
	 * This allows the use of the buttons with your own Ajax implementation.
780
	 *
781
	 * @module sharedaddy
782
	 *
783
	 * @since 7.3.0
784
	 *
785
	 * @param string $sharing_ajax_action_name Name of the Sharing buttons' Ajax action.
786
	 */
787
	$ajax_action = apply_filters( 'sharing_ajax_action', 'get_latest_posts' );
788
789
	// Allow to be used in ajax requests for latest posts.
790
	if (
791
		defined( 'DOING_AJAX' )
792
		&& DOING_AJAX
793
		&& isset( $_REQUEST['action'] )
794
		&& $ajax_action === $_REQUEST['action']
795
	) {
796
		$show = true;
797
	}
798
799
	$sharing_content = '';
800
	$enabled         = false;
801
802
	if ( $show ) {
803
		/**
804
		 * Filters the list of enabled Sharing Services.
805
		 *
806
		 * @module sharedaddy
807
		 *
808
		 * @since 2.2.3
809
		 *
810
		 * @param array $sharer->get_blog_services() Array of Sharing Services currently enabled.
811
		 */
812
		$enabled = apply_filters( 'sharing_enabled', $sharer->get_blog_services() );
813
814
		if ( count( $enabled['all'] ) > 0 ) {
815
			$dir = get_option( 'text_direction' );
816
817
			// Wrapper.
818
			$sharing_content .= '<div class="sharedaddy sd-sharing-enabled"><div class="robots-nocontent sd-block sd-social sd-social-' . $global['button_style'] . ' sd-sharing">';
819
			if ( '' !== $global['sharing_label'] ) {
820
				$sharing_content .= sprintf(
821
					/**
822
					 * Filter the sharing buttons' headline structure.
823
					 *
824
					 * @module sharedaddy
825
					 *
826
					 * @since 4.4.0
827
					 *
828
					 * @param string $sharing_headline Sharing headline structure.
829
					 * @param string $global['sharing_label'] Sharing title.
830
					 * @param string $sharing Module name.
831
					 */
832
					apply_filters( 'jetpack_sharing_headline_html', '<h3 class="sd-title">%s</h3>', $global['sharing_label'], 'sharing' ),
833
					esc_html( $global['sharing_label'] )
834
				);
835
			}
836
			$sharing_content .= '<div class="sd-content"><ul>';
837
838
			// Visible items.
839
			$visible = '';
840
			foreach ( $enabled['visible'] as $id => $service ) {
841
				$klasses = array( 'share-' . $service->get_class() );
842
				if ( $service->is_deprecated() ) {
843
					if ( ! current_user_can( 'manage_options' ) ) {
844
						continue;
845
					}
846
					$klasses[] = 'share-deprecated';
847
				}
848
				// Individual HTML for sharing service.
849
				$visible .= '<li class="' . implode( ' ', $klasses ) . '">' . $service->get_display( $post ) . '</li>';
850
			}
851
852
			$parts   = array();
853
			$parts[] = $visible;
854
			if ( count( $enabled['hidden'] ) > 0 ) {
855
				if ( count( $enabled['visible'] ) > 0 ) {
856
					$expand = __( 'More', 'jetpack' );
857
				} else {
858
					$expand = __( 'Share', 'jetpack' );
859
				}
860
				$parts[] = '<li><a href="#" class="sharing-anchor sd-button share-more"><span>' . $expand . '</span></a></li>';
861
			}
862
863
			if ( 'rtl' === $dir ) {
864
				$parts = array_reverse( $parts );
865
			}
866
867
			$sharing_content .= implode( '', $parts );
868
			$sharing_content .= '<li class="share-end"></li></ul>';
869
870
			if ( count( $enabled['hidden'] ) > 0 ) {
871
				$sharing_content .= '<div class="sharing-hidden"><div class="inner" style="display: none;';
872
873
				if ( count( $enabled['hidden'] ) === 1 ) {
874
					$sharing_content .= 'width:150px;';
875
				}
876
877
				$sharing_content .= '">';
878
879
				if ( count( $enabled['hidden'] ) === 1 ) {
880
					$sharing_content .= '<ul style="background-image:none;">';
881
				} else {
882
					$sharing_content .= '<ul>';
883
				}
884
885
				$count = 1;
886
				foreach ( $enabled['hidden'] as $id => $service ) {
887
					// Individual HTML for sharing service.
888
					$klasses = array( 'share-' . $service->get_class() );
889
					if ( $service->is_deprecated() ) {
890
						if ( ! current_user_can( 'manage_options' ) ) {
891
							continue;
892
						}
893
						$klasses[] = 'share-deprecated';
894
					}
895
					$sharing_content .= '<li class="' . implode( ' ', $klasses ) . '">';
896
					$sharing_content .= $service->get_display( $post );
897
					$sharing_content .= '</li>';
898
899
					if ( ( $count % 2 ) === 0 ) {
900
						$sharing_content .= '<li class="share-end"></li>';
901
					}
902
903
					$count ++;
904
				}
905
906
				// End of wrapper.
907
				$sharing_content .= '<li class="share-end"></li></ul></div></div>';
908
			}
909
910
			$sharing_content .= '</div></div></div>';
911
912
			// Register our JS.
913
			if ( defined( 'JETPACK__VERSION' ) ) {
914
				$ver = JETPACK__VERSION;
915
			} else {
916
				$ver = '20141212';
917
			}
918
919
			// @todo: Investigate if we can load this JS in the footer instead.
920
			wp_register_script(
921
				'sharing-js',
922
				Assets::get_file_url_for_environment(
923
					'_inc/build/sharedaddy/sharing.min.js',
924
					'modules/sharedaddy/sharing.js'
925
				),
926
				array( 'jquery' ),
927
				$ver,
928
				false
929
			);
930
931
			// Enqueue scripts for the footer.
932
			add_action( 'wp_footer', 'sharing_add_footer' );
933
		}
934
	}
935
936
	/**
937
	 * Filters the content markup of the Jetpack sharing links
938
	 *
939
	 * @module sharedaddy
940
	 *
941
	 * @since 3.8.0
942
	 * @since 6.2.0 Started sending $enabled as a second parameter.
943
	 *
944
	 * @param string $sharing_content Content markup of the Jetpack sharing links
945
	 * @param array  $enabled         Array of Sharing Services currently enabled.
946
	 */
947
	$sharing_markup = apply_filters( 'jetpack_sharing_display_markup', $sharing_content, $enabled );
948
949
	if ( $echo ) {
950
		echo $text . $sharing_markup;
951
	} else {
952
		return $text . $sharing_markup;
953
	}
954
}
955
956
function get_base_recaptcha_lang_code() {
957
958
	$base_recaptcha_lang_code_mapping = array(
959
		'en'    => 'en',
960
		'nl'    => 'nl',
961
		'fr'    => 'fr',
962
		'fr-be' => 'fr',
963
		'fr-ca' => 'fr',
964
		'fr-ch' => 'fr',
965
		'de'    => 'de',
966
		'pt'    => 'pt',
967
		'pt-br' => 'pt',
968
		'ru'    => 'ru',
969
		'es'    => 'es',
970
		'tr'    => 'tr',
971
	);
972
973
	$blog_lang_code = function_exists( 'get_blog_lang_code' ) ? get_blog_lang_code() : get_bloginfo( 'language' );
974
	if ( isset( $base_recaptcha_lang_code_mapping[ $blog_lang_code ] ) ) {
975
		return $base_recaptcha_lang_code_mapping[ $blog_lang_code ];
976
	}
977
978
	// if no base mapping is found return default 'en'
979
	return 'en';
980
}
981
982
Sharing_Service::init();
983