Completed
Push — update/remove-omni-search-test... ( 6db49e...ed8043 )
by
unknown
30:51 queued 20:39
created

Sharing_Service   D

Complexity

Total Complexity 80

Size/Duplication

Total Lines 458
Duplicated Lines 11.57 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 80
lcom 1
cbo 4
dl 53
loc 458
rs 4.8717
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
B get_all_services_blog() 0 20 5
B new_service() 0 31 6
A delete_service() 0 12 3
B set_blog_services() 0 39 1
B get_all_services() 0 57 7
F get_blog_services() 10 84 14
A get_service() 0 11 3
F set_global_options() 16 67 15
C get_global_options() 0 33 11
B set_service() 0 30 2
B get_total() 13 20 5
A get_services_total() 0 12 4
A get_posts_total() 14 14 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

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

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Sharing_Service often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Sharing_Service, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
include_once dirname( __FILE__ ).'/sharing-sources.php';
4
5
define( 'WP_SHARING_PLUGIN_VERSION', JETPACK__VERSION );
6
7
class Sharing_Service {
8
	private $global = false;
9
	public $default_sharing_label = '';
10
11
	public function __construct() {
12
		$this->default_sharing_label = __( 'Share this:', 'jetpack' );
13
	}
14
15
	/**
16
	 * Gets a generic list of all services, without any config
17
	 */
18
	public function get_all_services_blog() {
19
		$options  = get_option( 'sharing-options' );
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 2 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
20
21
		$all = $this->get_all_services();
22
		$services = array();
23
24
		foreach ( $all AS $id => $name ) {
25
			if ( isset( $all[$id] ) ) {
26
				$config = array();
27
28
				// Pre-load custom modules otherwise they won't know who they are
29
				if ( substr( $id, 0, 7 ) == 'custom-' && is_array( $options[$id] ) )
30
					$config = $options[$id];
31
32
				$services[$id] = new $all[$id]( $id, $config );
33
			}
34
		}
35
36
		return $services;
37
	}
38
39
	/**
40
	 * Gets a list of all available service names and classes
41
	 */
42
	public function get_all_services( $include_custom = true ) {
43
		global $wp_version;
44
		// Default services
45
		// if you update this list, please update the REST API tests
46
		// in bin/tests/api/suites/SharingTest.php
47
		$services = array(
48
			'print'             => 'Share_Print',
49
			'facebook'          => 'Share_Facebook',
50
			'linkedin'          => 'Share_LinkedIn',
51
			'reddit'            => 'Share_Reddit',
52
			'twitter'           => 'Share_Twitter',
53
			'google-plus-1'     => 'Share_GooglePlus1',
54
			'tumblr'            => 'Share_Tumblr',
55
			'pinterest'         => 'Share_Pinterest',
56
			'pocket'            => 'Share_Pocket',
57
			'telegram'          => 'Share_Telegram',
58
			'jetpack-whatsapp'  => 'Jetpack_Share_WhatsApp',
59
			'skype'             => 'Share_Skype',
60
		);
61
62
		/**
63
		 * Filters if Email Sharing is enabled.
64
		 *
65
		 * E-Mail sharing is often problematic due to spam concerns, so this filter enables it to be quickly and simply toggled.
66
		 * @module sharedaddy
67
		 *
68
		 * @since 5.1.0
69
		 *
70
		 * @param bool $email Is e-mail sharing enabled? Default false if Akismet is not active or true if Akismet is active.
71
		 */
72
		if ( apply_filters( 'sharing_services_email', Jetpack::is_akismet_active() ) ) {
73
			$services['email'] = 'Share_Email';
74
		}
75
76
		if ( is_multisite() && ( version_compare( $wp_version, '4.9-RC1-42107', '<' ) || is_plugin_active( 'press-this/press-this-plugin.php' ) ) ) {
77
			$services['press-this'] = 'Share_PressThis';
78
		}
79
80
		if ( $include_custom ) {
81
			// Add any custom services in
82
			$options = $this->get_global_options();
83
			foreach ( (array) $options['custom'] AS $custom_id ) {
84
				$services[$custom_id] = 'Share_Custom';
85
			}
86
		}
87
88
		/**
89
		 * Filters the list of available Sharing Services.
90
		 *
91
		 * @module sharedaddy
92
		 *
93
		 * @since 1.1.0
94
		 *
95
		 * @param array $services Array of all available Sharing Services.
96
		 */
97
		return apply_filters( 'sharing_services', $services );
98
	}
99
100
	public function new_service( $label, $url, $icon ) {
101
		// Validate
102
		$label = trim( wp_html_excerpt( wp_kses( $label, array() ), 30 ) );
103
		$url   = trim( esc_url_raw( $url ) );
104
		$icon  = trim( esc_url_raw( $icon ) );
105
106
		if ( $label && $url && $icon ) {
107
			$options = get_option( 'sharing-options' );
108
			if ( !is_array( $options ) )
109
				$options = array();
110
111
			$service_id = 'custom-'.time();
112
113
			// Add a new custom service
114
			$options['global']['custom'][] = $service_id;
115
			if ( false !== $this->global ) {
116
				$this->global['custom'][] = $service_id;
117
			}
118
119
			update_option( 'sharing-options', $options );
120
121
			// Create a custom service and set the options for it
122
			$service = new Share_Custom( $service_id, array( 'name' => $label, 'url' => $url, 'icon' => $icon ) );
123
			$this->set_service( $service_id, $service );
124
125
			// Return the service
126
			return $service;
127
		}
128
129
		return false;
130
	}
131
132
	public function delete_service( $service_id ) {
133
		$options = get_option( 'sharing-options' );
134
		if ( isset( $options[$service_id] ) )
135
			unset( $options[$service_id] );
136
137
		$key = array_search( $service_id, $options['global']['custom'] );
138
		if ( $key !== false )
139
			unset( $options['global']['custom'][$key] );
140
141
		update_option( 'sharing-options', $options );
142
		return true;
143
	}
144
145
	public function set_blog_services( array $visible, array $hidden ) {
146
		$services =  $this->get_all_services();
147
		// Validate the services
148
		$available = array_keys( $services );
149
150
		// Only allow services that we have defined
151
		$hidden  = array_intersect( $hidden, $available );
152
		$visible = array_intersect( $visible, $available );
153
154
		// Ensure we don't have the same ones in hidden and visible
155
		$hidden = array_diff( $hidden, $visible );
156
157
		/**
158
		 * Control the state of the list of sharing services.
159
		 *
160
		 * @module sharedaddy
161
		 *
162
		 * @since 1.1.0
163
		 *
164
		 * @param array $args {
165
		 *	Array of options describing the state of the sharing services.
166
		 *
167
		 *	@type array $services List of all available service names and classes.
168
		 *	@type array $available Validated list of all available service names and classes.
169
		 *	@type array $hidden List of services hidden behind a "More" button.
170
		 *	@type array $visible List of visible services.
171
		 *	@type array $this->get_blog_services() Array of Sharing Services currently enabled.
172
		 * }
173
		 */
174
		do_action( 'sharing_get_services_state', array(
175
			'services'			=> $services,
176
			'available' 		=> $available,
177
			'hidden' 			=> $hidden,
178
			'visible' 			=> $visible,
179
			'currently_enabled' => $this->get_blog_services()
180
		) );
181
182
		return update_option( 'sharing-services', array( 'visible' => $visible, 'hidden' => $hidden ) );
183
	}
184
185
	public function get_blog_services() {
186
		$options  = get_option( 'sharing-options' );
187
		$enabled  = get_option( 'sharing-services' );
188
		$services = $this->get_all_services();
189
190
		/**
191
		 * Check if options exist and are well formatted.
192
		 * This avoids issues on sites with corrupted options.
193
		 * @see https://github.com/Automattic/jetpack/issues/6121
194
		 */
195
		if ( ! is_array( $options ) || ! isset( $options['button_style'], $options['global'] ) ) {
196
			$global_options = array( 'global' => $this->get_global_options() );
197
			$options = is_array( $options )
198
				? array_merge( $options, $global_options )
199
				: $global_options;
200
		}
201
202
		$global = $options['global'];
203
204
		// Default services
205
		if ( ! is_array( $enabled ) ) {
206
			$enabled = array(
207
				'visible' => array(),
208
				'hidden' => array()
209
			);
210
211
			/**
212
			 * Filters the list of default Sharing Services.
213
			 *
214
			 * @module sharedaddy
215
			 *
216
			 * @since 1.1.0
217
			 *
218
			 * @param array $enabled Array of default Sharing Services.
219
			 */
220
			$enabled = apply_filters( 'sharing_default_services', $enabled );
221
		}
222
223
		// Cleanup after any filters that may have produced duplicate services
224 View Code Duplication
		if ( is_array( $enabled['visible'] ) ) {
225
			$enabled['visible'] = array_unique( $enabled['visible'] );
226
		} else {
227
			$enabled['visible'] = array();
228
		}
229
230 View Code Duplication
		if ( is_array( $enabled['hidden'] ) ) {
231
			$enabled['hidden']  = array_unique( $enabled['hidden'] );
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 2 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
232
		} else {
233
			$enabled['hidden'] = array();
234
		}
235
236
		// Form the enabled services
237
		$blog = array( 'visible' => array(), 'hidden' => array() );
238
239
		foreach ( $blog AS $area => $stuff ) {
240
			foreach ( (array)$enabled[$area] AS $service ) {
241
				if ( isset( $services[$service] ) ) {
242
					if ( ! isset( $options[ $service ] ) || ! is_array( $options[ $service ] ) ) {
243
						$options[ $service ] = array();
244
					}
245
					$blog[ $area ][ $service ] = new $services[ $service ]( $service, array_merge( $global, $options[ $service ] ) );
246
				}
247
			}
248
		}
249
250
		/**
251
		 * Filters the list of enabled Sharing Services.
252
		 *
253
		 * @module sharedaddy
254
		 *
255
		 * @since 1.1.0
256
		 *
257
		 * @param array $blog Array of enabled Sharing Services.
258
		 */
259
		$blog = apply_filters( 'sharing_services_enabled', $blog );
260
261
		// Add CSS for NASCAR
262
		if ( count( $blog['visible'] ) || count( $blog['hidden'] ) )
263
			add_filter( 'post_flair_block_css', 'post_flair_service_enabled_sharing' );
264
265
		// Convenience for checking if a service is present
266
		$blog['all'] = array_flip( array_merge( array_keys( $blog['visible'] ), array_keys( $blog['hidden'] ) ) );
267
		return $blog;
268
	}
269
270
	public function get_service( $service_name ) {
271
		$services = $this->get_blog_services();
272
273
		if ( isset( $services['visible'][$service_name] ) )
274
			return $services['visible'][$service_name];
275
276
		if ( isset( $services['hidden'][$service_name] ) )
277
			return $services['hidden'][$service_name];
278
279
		return false;
280
	}
281
282
	public function set_global_options( $data ) {
283
		$options = get_option( 'sharing-options' );
284
285
		// No options yet
286
		if ( !is_array( $options ) )
287
			$options = array();
288
289
		// Defaults
290
		$options['global'] = array(
291
			'button_style'  => 'icon-text',
292
			'sharing_label' => $this->default_sharing_label,
293
			'open_links'    => 'same',
294
			'show'          => array(),
295
			'custom'        => isset( $options['global']['custom'] ) ? $options['global']['custom'] : array()
296
		);
297
298
		/**
299
		 * Filters global sharing settings.
300
		 *
301
		 * @module sharedaddy
302
		 *
303
		 * @since 1.1.0
304
		 *
305
		 * @param array $options['global'] Array of global sharing settings.
306
		 */
307
		$options['global'] = apply_filters( 'sharing_default_global', $options['global'] );
308
309
		// Validate options and set from our data
310
		if ( isset( $data['button_style'] ) && in_array( $data['button_style'], array( 'icon-text', 'icon', 'text', 'official' ) ) )
311
			$options['global']['button_style'] = $data['button_style'];
312
313
		if ( isset( $data['sharing_label'] ) ) {
314
			if ( $this->default_sharing_label === $data['sharing_label'] ) {
315
				$options['global']['sharing_label'] = false;
316
			} else {
317
				$options['global']['sharing_label'] = trim( wp_kses( stripslashes( $data['sharing_label'] ), array() ) );
318
			}
319
		}
320
321
		if ( isset( $data['open_links'] ) && in_array( $data['open_links'], array( 'new', 'same' ) ) )
322
			$options['global']['open_links'] = $data['open_links'];
323
324
		$shows = array_values( get_post_types( array( 'public' => true ) ) );
325
		$shows[] = 'index';
326
		if ( isset( $data['show'] ) ) {
327 View Code Duplication
			if ( is_scalar( $data['show'] ) ) {
328
				switch ( $data['show'] ) {
329
				case 'posts' :
330
					$data['show'] = array( 'post', 'page' );
331
					break;
332
				case 'index' :
333
					$data['show'] = array( 'index' );
334
					break;
335
				case 'posts-index' :
336
					$data['show'] = array( 'post', 'page', 'index' );
337
					break;
338
				}
339
			}
340
341 View Code Duplication
			if ( $data['show'] = array_intersect( $data['show'], $shows ) ) {
342
				$options['global']['show'] = $data['show'];
343
			}
344
		}
345
346
		update_option( 'sharing-options', $options );
347
		return $options['global'];
348
	}
349
350
	public function get_global_options() {
351
		if ( $this->global === false ) {
352
			$options = get_option( 'sharing-options' );
353
354
			if ( is_array( $options ) && isset( $options['global'] ) && is_array( $options['global'] ) ) {
355
				$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...
356
			} else {
357
				$this->global = $this->set_global_options( $options['global'] );
358
			}
359
		}
360
361
		if ( ! isset( $this->global['show'] ) ) {
362
			$this->global['show'] = array( 'post', 'page' );
363
		} elseif ( is_scalar( $this->global['show'] ) ) {
364
			switch ( $this->global['show'] ) {
365
			case 'posts' :
366
				$this->global['show'] = array( 'post', 'page' );
367
				break;
368
			case 'index' :
369
				$this->global['show'] = array( 'index' );
370
				break;
371
			case 'posts-index' :
372
				$this->global['show'] = array( 'post', 'page', 'index' );
373
				break;
374
			}
375
		}
376
377
		if ( false === $this->global['sharing_label'] ) {
378
			$this->global['sharing_label'] = $this->default_sharing_label;
379
		}
380
381
		return $this->global;
382
	}
383
384
	public function set_service( $id, Sharing_Source $service ) {
385
		// Update the options for this service
386
		$options = get_option( 'sharing-options' );
387
388
		// No options yet
389
		if ( ! is_array( $options ) ) {
390
			$options = array();
391
		}
392
393
		/**
394
		 * Get the state of a sharing button.
395
		 *
396
		 * @module sharedaddy
397
		 *
398
		 * @since 1.1.0
399
		 *
400
		 * @param array $args {
401
		 *	State of a sharing button.
402
		 *
403
		 *	@type string $id Service ID.
404
		 *	@type array $options Array of all sharing options.
405
		 *	@type array $service Details about a service.
406
		 * }
407
		 */
408
		do_action( 'sharing_get_button_state', array( 'id' => $id, 'options' => $options, 'service' => $service ) );
409
410
		$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...
411
412
		update_option( 'sharing-options', array_filter( $options ) );
413
	}
414
415
	// Soon to come to a .org plugin near you!
416
	public function get_total( $service_name = false, $post_id = false, $_blog_id = false ) {
417
		global $wpdb, $blog_id;
418
		if ( !$_blog_id ) {
419
			$_blog_id = $blog_id;
420
		}
421 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...
422
			if ( $post_id > 0 ) {
423
				// total number of shares for this post
424
				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 ) );
425
			} else {
426
				// total number of shares for this blog
427
				return (int) $wpdb->get_var( $wpdb->prepare( "SELECT SUM( count ) FROM sharing_stats WHERE blog_id = %d", $_blog_id ) );
428
			}
429
		}
430
431 View Code Duplication
		if ( $post_id > 0 )
432
			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 ) );
433
		else
434
			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 ) );
435
	}
436
437
	public function get_services_total( $post_id = false ) {
438
		$totals = array();
439
		$services = $this->get_blog_services();
440
441
		if ( !empty( $services ) && isset( $services[ 'all' ] ) )
442
			foreach( $services[ 'all' ] as $key => $value ) {
443
				$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...
444
			}
445
		usort( $totals, array( 'Sharing_Service_Total', 'cmp' ) );
446
447
		return $totals;
448
	}
449
450 View Code Duplication
	public function get_posts_total() {
451
		$totals = array();
452
		global $wpdb, $blog_id;
453
454
		$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 ) );
455
456
		if ( !empty( $my_data ) )
457
			foreach( $my_data as $row )
458
				$totals[] = new Sharing_Post_Total( $row->id, $row->total );
459
460
		usort( $totals, array( 'Sharing_Post_Total', 'cmp' ) );
461
462
		return $totals;
463
	}
464
}
465
466
class Sharing_Service_Total {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
467
	public $id 		= '';
468
	public $name 		= '';
469
	public $service	= '';
470
	public $total 		= 0;
471
472
	public function __construct( $id, $total ) {
473
		$services 		= new Sharing_Service();
474
		$this->id 		= esc_html( $id );
475
		$this->service 	= $services->get_service( $id );
476
		$this->total 	= (int) $total;
477
478
		$this->name 	= $this->service->get_name();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 2 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
479
	}
480
481
	static function cmp( $a, $b ) {
482
		if ( $a->total == $b->total )
483
			return $a->name < $b->name;
484
		return $a->total < $b->total;
485
	}
486
}
487
488
class Sharing_Post_Total {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
489
	public $id    = 0;
490
	public $total = 0;
491
	public $title = '';
492
	public $url   = '';
493
494
	public function __construct( $id, $total ) {
495
		$this->id 		= (int) $id;
496
		$this->total 	= (int) $total;
497
		$this->title	= get_the_title( $this->id );
498
		$this->url		= get_permalink( $this->id );
499
	}
500
501
	static function cmp( $a, $b ) {
502
		if ( $a->total == $b->total )
503
			return $a->id < $b->id;
504
		return $a->total < $b->total;
505
	}
506
}
507
508
function sharing_register_post_for_share_counts( $post_id ) {
509
	global $jetpack_sharing_counts;
510
511
	if ( ! isset( $jetpack_sharing_counts ) || ! is_array( $jetpack_sharing_counts ) )
512
		$jetpack_sharing_counts = array();
513
514
	$jetpack_sharing_counts[ (int) $post_id ] = get_permalink( $post_id );
515
}
516
517
function sharing_maybe_enqueue_scripts() {
518
	$sharer          = new Sharing_Service();
519
	$global_options  = $sharer->get_global_options();
520
521
	$enqueue         = false;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 9 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
522 View Code Duplication
	if ( is_singular() && in_array( get_post_type(), $global_options['show'] ) ) {
523
		$enqueue = true;
524
	} elseif ( in_array( 'index', $global_options['show'] ) && ( is_home() || is_front_page() || is_archive() || is_search() || in_array( get_post_type(), $global_options['show'] ) ) ) {
525
		$enqueue = true;
526
	}
527
528
	/**
529
	 * Filter to decide when sharing scripts should be enqueued.
530
	 *
531
	 * @module sharedaddy
532
	 *
533
	 * @since 3.2.0
534
	 *
535
	 * @param bool $enqueue Decide if the sharing scripts should be enqueued.
536
	 */
537
	return (bool) apply_filters( 'sharing_enqueue_scripts', $enqueue );
538
}
539
540
function sharing_add_footer() {
541
	global $jetpack_sharing_counts;
542
543
	/**
544
	 * Filter all JavaScript output by the sharing module.
545
	 *
546
	 * @module sharedaddy
547
	 *
548
	 * @since 1.1.0
549
	 *
550
	 * @param bool true Control whether the sharing module should add any JavaScript to the site. Default to true.
551
	 */
552
	if ( apply_filters( 'sharing_js', true ) && sharing_maybe_enqueue_scripts() ) {
553
554
		/**
555
		 * Filter the display of sharing counts next to the sharing buttons.
556
		 *
557
		 * @module sharedaddy
558
		 *
559
		 * @since 3.2.0
560
		 *
561
		 * @param bool true Control the display of counters next to the sharing buttons. Default to true.
562
		 */
563
		if ( apply_filters( 'jetpack_sharing_counts', true ) && is_array( $jetpack_sharing_counts ) && count( $jetpack_sharing_counts ) ) :
564
			$sharing_post_urls = array_filter( $jetpack_sharing_counts );
565
			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...
566
?>
567
568
	<script type="text/javascript">
569
		window.WPCOM_sharing_counts = <?php echo json_encode( array_flip( $sharing_post_urls ) ); ?>;
570
	</script>
571
<?php
572
			endif;
573
		endif;
574
575
		wp_enqueue_script( 'sharing-js' );
576
		$sharing_js_options = array(
577
			'lang'   => get_base_recaptcha_lang_code(),
578
			/** This filter is documented in modules/sharedaddy/sharing-service.php */
579
			'counts' => apply_filters( 'jetpack_sharing_counts', true )
580
		);
581
		wp_localize_script( 'sharing-js', 'sharing_js_options', $sharing_js_options);
582
	}
583
	$sharer = new Sharing_Service();
584
	$enabled = $sharer->get_blog_services();
585
	foreach ( array_merge( $enabled['visible'], $enabled['hidden'] ) AS $service ) {
586
		$service->display_footer();
587
	}
588
}
589
590
function sharing_add_header() {
591
	$sharer = new Sharing_Service();
592
	$enabled = $sharer->get_blog_services();
593
594
	foreach ( array_merge( $enabled['visible'], $enabled['hidden'] ) AS $service ) {
595
		$service->display_header();
596
	}
597
598
	if ( count( $enabled['all'] ) > 0 && sharing_maybe_enqueue_scripts() ) {
599
		wp_enqueue_style( 'sharedaddy', plugin_dir_url( __FILE__ ) .'sharing.css', array(), JETPACK__VERSION );
600
		wp_enqueue_style( 'social-logos' );
601
	}
602
603
}
604
add_action( 'wp_head', 'sharing_add_header', 1 );
605
606
function sharing_process_requests() {
607
	global $post;
608
609
	// Only process if: single post and share=X defined
610
	if ( ( is_page() || is_single() ) && isset( $_GET['share'] ) ) {
611
		$sharer = new Sharing_Service();
612
613
		$service = $sharer->get_service( $_GET['share'] );
614
		if ( $service ) {
615
			$service->process_request( $post, $_POST );
616
		}
617
	}
618
}
619
add_action( 'template_redirect', 'sharing_process_requests', 9 );
620
621
function sharing_display( $text = '', $echo = false ) {
622
	global $post, $wp_current_filter;
623
624
	require_once JETPACK__PLUGIN_DIR . '/sync/class.jetpack-sync-settings.php';
625
	if ( Jetpack_Sync_Settings::is_syncing() ) {
626
		return $text;
627
	}
628
629
	if ( empty( $post ) )
630
		return $text;
631
632
	if ( ( is_preview() || is_admin() ) && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
633
		return $text;
634
	}
635
636
	// Don't output flair on excerpts
637
	if ( in_array( 'get_the_excerpt', (array) $wp_current_filter ) ) {
638
		return $text;
639
	}
640
641
	// Don't allow flair to be added to the_content more than once (prevent infinite loops)
642
	$done = false;
643
	foreach ( $wp_current_filter as $filter ) {
644
		if ( 'the_content' == $filter ) {
645
			if ( $done )
646
				return $text;
647
			else
648
				$done = true;
649
		}
650
	}
651
652
	// check whether we are viewing the front page and whether the front page option is checked
653
	$options = get_option( 'sharing-options' );
654
	$display_options = $options['global']['show'];
655
656
	if ( is_front_page() && ( is_array( $display_options ) && ! in_array( 'index', $display_options ) ) )
657
		return $text;
658
659
	if ( is_attachment() && in_array( 'the_excerpt', (array) $wp_current_filter ) ) {
660
		// Many themes run the_excerpt() conditionally on an attachment page, then run the_content().
661
		// We only want to output the sharing buttons once.  Let's stick with the_content().
662
		return $text;
663
	}
664
665
	$sharer = new Sharing_Service();
666
	$global = $sharer->get_global_options();
667
668
	$show = false;
669 View Code Duplication
	if ( !is_feed() ) {
670
		if ( is_singular() && in_array( get_post_type(), $global['show'] ) ) {
671
			$show = true;
672
		} elseif ( in_array( 'index', $global['show'] ) && ( is_home() || is_front_page() || is_archive() || is_search() || in_array( get_post_type(), $global['show'] ) ) ) {
673
			$show = true;
674
		}
675
	}
676
677
	/**
678
	 * Filter to decide if sharing buttons should be displayed.
679
	 *
680
	 * @module sharedaddy
681
	 *
682
	 * @since 1.1.0
683
	 *
684
	 * @param bool $show Should the sharing buttons be displayed.
685
	 * @param WP_Post $post The post to share.
686
	 */
687
	$show = apply_filters( 'sharing_show', $show, $post );
688
689
	// Disabled for this post?
690
	$switched_status = get_post_meta( $post->ID, 'sharing_disabled', false );
691
692
	if ( !empty( $switched_status ) )
693
		$show = false;
694
695
	// Private post?
696
	$post_status = get_post_status( $post->ID );
697
698
	if ( 'private' === $post_status ) {
699
		$show = false;
700
	}
701
702
	// Allow to be used on P2 ajax requests for latest posts.
703
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_REQUEST['action'] ) && 'get_latest_posts' == $_REQUEST['action'] )
704
		$show = true;
705
706
	$sharing_content = '';
707
708
	if ( $show ) {
709
		/**
710
		 * Filters the list of enabled Sharing Services.
711
		 *
712
		 * @module sharedaddy
713
		 *
714
		 * @since 2.2.3
715
		 *
716
		 * @param array $sharer->get_blog_services() Array of Sharing Services currently enabled.
717
		 */
718
		$enabled = apply_filters( 'sharing_enabled', $sharer->get_blog_services() );
719
720
		if ( count( $enabled['all'] ) > 0 ) {
721
			global $post;
722
723
			$dir = get_option( 'text_direction' );
724
725
			// Wrapper
726
			$sharing_content .= '<div class="sharedaddy sd-sharing-enabled"><div class="robots-nocontent sd-block sd-social sd-social-' . $global['button_style'] . ' sd-sharing">';
727
			if ( $global['sharing_label'] != '' ) {
728
				$sharing_content .= sprintf(
729
					/**
730
					 * Filter the sharing buttons' headline structure.
731
					 *
732
					 * @module sharedaddy
733
					 *
734
					 * @since 4.4.0
735
					 *
736
					 * @param string $sharing_headline Sharing headline structure.
737
					 * @param string $global['sharing_label'] Sharing title.
738
					 * @param string $sharing Module name.
739
					 */
740
					apply_filters( 'jetpack_sharing_headline_html', '<h3 class="sd-title">%s</h3>', $global['sharing_label'], 'sharing' ),
741
					esc_html( $global['sharing_label'] )
742
				);
743
			}
744
			$sharing_content .= '<div class="sd-content"><ul>';
745
746
			// Visible items
747
			$visible = '';
748
			foreach ( $enabled['visible'] as $id => $service ) {
749
				// Individual HTML for sharing service
750
				$visible .= '<li class="share-' . $service->get_class() . '">' . $service->get_display( $post ) . '</li>';
751
			}
752
753
			$parts = array();
754
			$parts[] = $visible;
755
			if ( count( $enabled['hidden'] ) > 0 ) {
756
				if ( count( $enabled['visible'] ) > 0 )
757
					$expand = __( 'More', 'jetpack' );
758
				else
759
					$expand = __( 'Share', 'jetpack' );
760
				$parts[] = '<li><a href="#" class="sharing-anchor sd-button share-more"><span>'.$expand.'</span></a></li>';
761
			}
762
763
			if ( $dir == 'rtl' )
764
				$parts = array_reverse( $parts );
765
766
			$sharing_content .= implode( '', $parts );
767
			$sharing_content .= '<li class="share-end"></li></ul>';
768
769
			if ( count( $enabled['hidden'] ) > 0 ) {
770
				$sharing_content .= '<div class="sharing-hidden"><div class="inner" style="display: none;';
771
772
				if ( count( $enabled['hidden'] ) == 1 )
773
					$sharing_content .= 'width:150px;';
774
775
				$sharing_content .= '">';
776
777
				if ( count( $enabled['hidden'] ) == 1 )
778
					$sharing_content .= '<ul style="background-image:none;">';
779
				else
780
					$sharing_content .= '<ul>';
781
782
				$count = 1;
783
				foreach ( $enabled['hidden'] as $id => $service ) {
784
					// Individual HTML for sharing service
785
					$sharing_content .= '<li class="share-'.$service->get_class().'">';
786
					$sharing_content .= $service->get_display( $post );
787
					$sharing_content .= '</li>';
788
789
					if ( ( $count % 2 ) == 0 )
790
						$sharing_content .= '<li class="share-end"></li>';
791
792
					$count ++;
793
				}
794
795
				// End of wrapper
796
				$sharing_content .= '<li class="share-end"></li></ul></div></div>';
797
			}
798
799
			$sharing_content .= '</div></div></div>';
800
801
			// Register our JS
802
			if ( defined( 'JETPACK__VERSION' ) ) {
803
				$ver = JETPACK__VERSION;
804
			} else {
805
				$ver = '20141212';
806
			}
807
			wp_register_script(
808
				'sharing-js',
809
				Jetpack::get_file_url_for_environment(
810
					'_inc/build/sharedaddy/sharing.min.js',
811
					WP_SHARING_PLUGIN_URL . 'sharing.js'
812
				),
813
				array( 'jquery' ),
814
				$ver
815
			);
816
817
			// Enqueue scripts for the footer
818
			add_action( 'wp_footer', 'sharing_add_footer' );
819
		}
820
	}
821
822
	/**
823
	 * Filters the content markup of the Jetpack sharing links
824
	 *
825
	 * @module sharedaddy
826
	 *
827
	 * @since 3.8.0
828
	 *
829
	 * @param string $sharing_content Content markup of the Jetpack sharing links
830
	 */
831
	$sharing_markup = apply_filters( 'jetpack_sharing_display_markup', $sharing_content );
832
833
	if ( $echo )
834
		echo $text . $sharing_markup;
835
	else
836
		return $text . $sharing_markup;
837
}
838
839
add_filter( 'the_content', 'sharing_display', 19 );
840
add_filter( 'the_excerpt', 'sharing_display', 19 );
841
function get_base_recaptcha_lang_code() {
842
843
	$base_recaptcha_lang_code_mapping = array(
844
		'en'    => 'en',
845
		'nl'    => 'nl',
846
		'fr'    => 'fr',
847
		'fr-be' => 'fr',
848
		'fr-ca' => 'fr',
849
		'fr-ch' => 'fr',
850
		'de'    => 'de',
851
		'pt'    => 'pt',
852
		'pt-br' => 'pt',
853
		'ru'    => 'ru',
854
		'es'    => 'es',
855
		'tr'    => 'tr'
856
	);
857
858
	$blog_lang_code = function_exists( 'get_blog_lang_code' ) ? get_blog_lang_code() : get_bloginfo( 'language' );
859
	if( isset( $base_recaptcha_lang_code_mapping[ $blog_lang_code ] ) )
860
		return $base_recaptcha_lang_code_mapping[ $blog_lang_code ];
861
862
	// if no base mapping is found return default 'en'
863
	return 'en';
864
}
865