Completed
Push — try/likes-button-for-fse ( 484b03 )
by
unknown
11:38
created

likes.php ➔ load_assets()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
/**
3
 * Module Name: Likes
4
 * Module Description: Give visitors an easy way to show they appreciate your content.
5
 * First Introduced: 2.2
6
 * Sort Order: 23
7
 * Requires Connection: Yes
8
 * Auto Activate: No
9
 * Module Tags: Social
10
 * Feature: Engagement
11
 * Additional Search Queries: like, likes, wordpress.com
12
 *
13
 * @package automattic/jetpack
14
 */
15
16
use Automattic\Jetpack\Assets;
17
use Automattic\Jetpack\Blocks;
18
19
Assets::add_resource_hint(
20
	array(
21
		'//widgets.wp.com',
22
		'//s0.wp.com',
23
		'//0.gravatar.com',
24
		'//1.gravatar.com',
25
		'//2.gravatar.com',
26
	),
27
	'dns-prefetch'
28
);
29
30
require_once __DIR__ . '/likes/jetpack-likes-master-iframe.php';
31
require_once __DIR__ . '/likes/jetpack-likes-settings.php';
32
33
/**
34
 * Jetpack Like Class
35
 */
36
class Jetpack_Likes {
37
38
	/**
39
	 * Initialize class
40
	 */
41
	public static function init() {
42
		static $instance = null;
43
44
		if ( ! $instance ) {
45
			$instance = new Jetpack_Likes();
46
		}
47
48
		return $instance;
49
	}
50
51
	/**
52
	 * Constructs Likes class
53
	 */
54
	public function __construct() {
55
		$this->in_jetpack = ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? false : true;
0 ignored issues
show
Bug introduced by
The property in_jetpack does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
56
		$this->settings   = new Jetpack_Likes_Settings();
0 ignored issues
show
Bug introduced by
The property settings does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
57
58
		// We need to run on wp hook rather than init because we check is_amp_endpoint()
59
		// when bootstrapping hooks.
60
		add_action( 'wp', array( $this, 'action_init' ), 99 );
61
62
		add_action( 'admin_init', array( $this, 'admin_init' ) );
63
64
		if ( $this->in_jetpack ) {
65
			add_action( 'jetpack_activate_module_likes', array( $this, 'set_social_notifications_like' ) );
66
			add_action( 'jetpack_deactivate_module_likes', array( $this, 'delete_social_notifications_like' ) );
67
68
			Jetpack::enable_module_configurable( __FILE__ );
69
			add_filter( 'jetpack_module_configuration_url_likes', array( $this, 'jetpack_likes_configuration_url' ) );
70
			add_action( 'admin_print_scripts-settings_page_sharing', array( $this, 'load_jp_css' ) );
71
			add_filter( 'sharing_show_buttons_on_row_start', array( $this, 'configuration_target_area' ) );
72
73
			$active = Jetpack::get_active_modules();
74
75 View Code Duplication
			if ( ! in_array( 'sharedaddy', $active, true ) && ! in_array( 'publicize', $active, true ) ) {
76
				// we don't have a sharing page yet.
77
				add_action( 'admin_menu', array( $this->settings, 'sharing_menu' ) );
78
			}
79
80 View Code Duplication
			if ( in_array( 'publicize', $active, true ) && ! in_array( 'sharedaddy', $active, true ) ) {
81
				// we have a sharing page but not the global options area.
82
				add_action( 'pre_admin_screen_sharing', array( $this->settings, 'sharing_block' ), 20 );
83
				add_action( 'pre_admin_screen_sharing', array( $this->settings, 'updated_message' ), -10 );
84
			}
85
86 View Code Duplication
			if ( ! in_array( 'sharedaddy', $active, true ) ) {
87
				add_action( 'admin_init', array( $this->settings, 'process_update_requests_if_sharedaddy_not_loaded' ) );
88
				add_action( 'sharing_global_options', array( $this->settings, 'admin_settings_showbuttonon_init' ), 19 );
89
				add_action( 'sharing_admin_update', array( $this->settings, 'admin_settings_showbuttonon_callback' ), 19 );
90
				add_action( 'admin_init', array( $this->settings, 'add_meta_box' ) );
91
			} else {
92
				add_filter( 'sharing_meta_box_title', array( $this->settings, 'add_likes_to_sharing_meta_box_title' ) );
93
				add_action( 'start_sharing_meta_box_content', array( $this->settings, 'meta_box_content' ) );
94
			}
95
		} else { // wpcom.
96
			add_action( 'wpmu_new_blog', array( $this, 'enable_comment_likes' ), 10, 1 );
97
			add_action( 'admin_init', array( $this->settings, 'add_meta_box' ) );
98
			add_action( 'end_likes_meta_box_content', array( $this->settings, 'sharing_meta_box_content' ) );
99
			add_filter( 'likes_meta_box_title', array( $this->settings, 'add_likes_to_sharing_meta_box_title' ) );
100
		}
101
102
		add_action( 'admin_init', array( $this, 'admin_discussion_likes_settings_init' ) ); // Likes notifications.
103
104
		add_action( 'admin_bar_menu', array( $this, 'admin_bar_likes' ), 60 );
105
106
		add_action( 'wp_enqueue_scripts', array( $this, 'load_styles_register_scripts' ) );
107
108
		add_action( 'save_post', array( $this->settings, 'meta_box_save' ) );
109
		add_action( 'edit_attachment', array( $this->settings, 'meta_box_save' ) );
110
		add_action( 'sharing_global_options', array( $this->settings, 'admin_settings_init' ), 20 );
111
		add_action( 'sharing_admin_update', array( $this->settings, 'admin_settings_callback' ), 20 );
112
	}
113
114
	/**
115
	 * Set the social_notifications_like option to `on` when the Likes module is activated.
116
	 *
117
	 * @since 3.7.0
118
	 */
119
	public function set_social_notifications_like() {
120
		update_option( 'social_notifications_like', 'on' );
121
	}
122
123
	/**
124
	 * Delete the social_notifications_like option that was set to `on` on module activation.
125
	 *
126
	 * @since 3.7.0
127
	 */
128
	public function delete_social_notifications_like() {
129
		delete_option( 'social_notifications_like' );
130
	}
131
132
	/**
133
	 * Overrides default configuration url
134
	 *
135
	 * @uses admin_url
136
	 * @return string module settings URL
137
	 */
138
	public function jetpack_likes_configuration_url() {
139
		return admin_url( 'options-general.php?page=sharing#likes' );
140
	}
141
142
	/**
143
	 * Loads Jetpack's CSS on the sharing page so we can use .jetpack-targetable
144
	 */
145
	public function load_jp_css() {
146
		/**
147
		* Do we really need `admin_styles`? With the new admin UI, it's breaking some bits.
148
		* Jetpack::init()->admin_styles();
149
		*/
150
	}
151
152
	/**
153
	 * Load scripts and styles for front end.
154
	 */
155
	public function load_styles_register_scripts() {
156
		if ( $this->in_jetpack ) {
157
			wp_enqueue_style( 'jetpack_likes', plugins_url( 'likes/style.css', __FILE__ ), array(), JETPACK__VERSION );
158
			$this->register_scripts();
159
		}
160
	}
161
162
	/**
163
	 * Stub for is_post_likeable, since some wpcom functions call this directly on the class
164
	 * Are likes enabled for this post?
165
	 *
166
	 * @param int $post_id id of the post.
167
	 * @return bool
168
	 */
169
	public static function is_post_likeable( $post_id = 0 ) {
170
		_deprecated_function( __METHOD__, 'jetpack-5.4', 'Jetpack_Likes_Settings()->is_post_likeable' );
171
		$settings = new Jetpack_Likes_Settings();
172
		return $settings->is_post_likeable( $post_id );
173
	}
174
175
	/**
176
	 * Stub for is_likes_visible, since some themes were calling it directly from this class
177
	 *
178
	 * @deprecated 5.4
179
	 * @return bool
180
	 */
181
	public function is_likes_visible() {
182
		_deprecated_function( __METHOD__, 'jetpack-5.4', 'Jetpack_Likes_Settings()->is_likes_visible' );
183
184
		$settings = new Jetpack_Likes_Settings();
185
		return $settings->is_likes_visible();
186
	}
187
188
	/**
189
	 * Adds in the jetpack-targetable class so when we visit sharing#likes our like settings get highlighted by a yellow box
190
	 *
191
	 * @param string $html row heading for the sharedaddy "which page" setting.
192
	 * @return string $html with the jetpack-targetable class and likes id. tbody gets closed after the like settings
193
	 */
194
	public function configuration_target_area( $html = '' ) {
195
		$html = "<tbody id='likes' class='jetpack-targetable'>" . $html;
196
		return $html;
197
	}
198
199
	/**
200
	 * Options to be added to the discussion page (see also admin_settings_init, etc below for Sharing settings page)
201
	 */
202
	public function admin_discussion_likes_settings_init() {
203
		// Add a temporary section, until we can move the setting out of there and with the rest of the email notification settings.
204
		add_settings_section( 'likes-notifications', __( 'Likes Notifications', 'jetpack' ), array( $this, 'admin_discussion_likes_settings_section' ), 'discussion' );
205
		add_settings_field( 'social-notifications', __( 'Email me whenever', 'jetpack' ), array( $this, 'admin_discussion_likes_settings_field' ), 'discussion', 'likes-notifications' );
206
		// Register the setting.
207
		register_setting( 'discussion', 'social_notifications_like', array( $this, 'admin_discussion_likes_settings_validate' ) );
208
	}
209
210
	/** Add email notification options to WordPress discussion settings */
211
	public function admin_discussion_likes_settings_section() {
212
		// Atypical usage here.  We emit jquery to move likes notification checkbox to be with the rest of the email notification settings.
213
		?>
214
	<script type="text/javascript">
215
	jQuery( function( $ )  {
216
		var table = $( '#social_notifications_like' ).parents( 'table:first' ),
217
			header = table.prevAll( 'h2:first' ),
218
			newParent = $( '#moderation_notify' ).parent( 'label' ).parent();
219
220
		if ( !table.length || !header.length || !newParent.length ) {
221
			return;
222
		}
223
224
		newParent.append( '<br/>' ).append( table.end().parent( 'label' ).siblings().andSelf() );
225
		header.remove();
226
		table.remove();
227
	} );
228
	</script>
229
		<?php
230
	}
231
232
	/** Check if email notifications for likes is on or off.
233
	 *
234
	 * @param string $option - which option we're checking (social_notifications_like).
235
	 */
236
	public function admin_likes_get_option( $option ) {
237
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
238
			$option_setting = get_blog_option( get_current_blog_id(), $option, 'on' );
239
		} else {
240
			$option_setting = get_option( $option, 'on' );
241
		}
242
243
		return (int) ( 'on' === $option_setting );
244
	}
245
246
	/** Display email notification for likes setting in WordPress' discussion settings. */
247
	public function admin_discussion_likes_settings_field() {
248
		$like = $this->admin_likes_get_option( 'social_notifications_like' );
249
		?>
250
		<label><input type="checkbox" id="social_notifications_like" name="social_notifications_like" value="1" <?php checked( $like ); ?> /> <?php esc_html_e( 'Someone likes one of my posts', 'jetpack' ); ?></label>
251
		<?php
252
	}
253
254
	/**
255
	 * Validate email notification settings.
256
	 *
257
	 * @param string $input - determines if checbox is on or off.
258
	 */
259
	public function admin_discussion_likes_settings_validate( $input ) {
260
		// If it's not set (was unchecked during form submission) or was set to off (during option update), return 'off'.
261
		if ( ! $input || 'off' === $input ) {
262
			return 'off';
263
		}
264
		// Otherwise return 'on'.
265
		return 'on';
266
	}
267
268
	/** Initialize admin settings */
269
	public function admin_init() {
270
		add_filter( 'manage_posts_columns', array( $this, 'add_like_count_column' ) );
271
		add_filter( 'manage_pages_columns', array( $this, 'add_like_count_column' ) );
272
		add_action( 'manage_posts_custom_column', array( $this, 'likes_edit_column' ), 10, 2 );
273
		add_action( 'manage_pages_custom_column', array( $this, 'likes_edit_column' ), 10, 2 );
274
		add_action( 'admin_print_styles-edit.php', array( $this, 'load_admin_css' ) );
275
		add_action( 'admin_print_scripts-edit.php', array( $this, 'enqueue_admin_scripts' ) );
276
	}
277
278
	/** Initialize action */
279
	public function action_init() {
280
		if ( is_admin() || ! $this->settings->is_likes_visible() ) {
281
			return;
282
		}
283
284
		if ( ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) ||
285
			( defined( 'APP_REQUEST' ) && APP_REQUEST ) ||
286
			( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST ) ||
287
			( defined( 'COOKIE_AUTH_REQUEST' ) && COOKIE_AUTH_REQUEST ) ||
288
			( defined( 'JABBER_SERVER' ) && JABBER_SERVER ) ) {
289
			return;
290
		}
291
292
		if (
293
			class_exists( 'Jetpack_AMP_Support' )
294
			&& Jetpack_AMP_Support::is_amp_request()
295
		) {
296
			return;
297
		}
298
299
		if ( $this->in_jetpack ) {
300
			add_filter( 'the_content', array( $this, 'post_likes' ), 30, 1 );
301
			add_filter( 'the_excerpt', array( $this, 'post_likes' ), 30, 1 );
302
303
		} else {
304
			add_filter( 'post_flair', array( $this, 'post_likes' ), 30, 1 );
305
			add_filter( 'post_flair_block_css', array( $this, 'post_flair_service_enabled_like' ) );
306
307
			wp_enqueue_script( 'postmessage', '/wp-content/js/postmessage.js', array(), JETPACK__VERSION, true );
308
			wp_enqueue_script( 'jetpack_resize', '/wp-content/js/jquery/jquery.jetpack-resize.js', array( 'jquery' ), JETPACK__VERSION, true );
309
			wp_enqueue_script( 'jetpack_likes_queuehandler', plugins_url( 'queuehandler.js', __FILE__ ), array( 'jquery', 'postmessage', 'jetpack_resize' ), JETPACK__VERSION, true );
310
			wp_enqueue_style( 'jetpack_likes', plugins_url( 'jetpack-likes.css', __FILE__ ), array(), JETPACK__VERSION );
311
		}
312
	}
313
314
	/**
315
	 * Register scripts.
316
	 */
317
	public function register_scripts() {
318
		wp_register_script(
319
			'postmessage',
320
			Assets::get_file_url_for_environment( '_inc/build/postmessage.min.js', '_inc/postmessage.js' ),
321
			array(),
322
			JETPACK__VERSION,
323
			true
324
		);
325
		wp_register_script(
326
			'jetpack_resize',
327
			Assets::get_file_url_for_environment(
328
				'_inc/build/jquery.jetpack-resize.min.js',
329
				'_inc/jquery.jetpack-resize.js'
330
			),
331
			array( 'jquery' ),
332
			JETPACK__VERSION,
333
			true
334
		);
335
		wp_register_script(
336
			'jetpack_likes_queuehandler',
337
			Assets::get_file_url_for_environment(
338
				'_inc/build/likes/queuehandler.min.js',
339
				'modules/likes/queuehandler.js'
340
			),
341
			array( 'jquery', 'postmessage', 'jetpack_resize' ),
342
			JETPACK__VERSION,
343
			true
344
		);
345
	}
346
347
	/**
348
	 * Load the CSS needed for the wp-admin area.
349
	 */
350
	public function load_admin_css() {
351
		?>
352
		<style type="text/css">
353
			.vers img { display: none; }
354
			.metabox-prefs .vers img { display: inline; }
355
			.fixed .column-likes { width: 5.5em; padding: 8px 0; text-align: left; }
356
			.fixed .column-stats { width: 5em; }
357
			.fixed .column-likes .post-com-count {
358
				-webkit-box-sizing: border-box;
359
				-moz-box-sizing: border-box;
360
				box-sizing: border-box;
361
				display: inline-block;
362
				padding: 0 8px;
363
				height: 2em;
364
				margin-top: 5px;
365
				-webkit-border-radius: 5px;
366
				border-radius: 5px;
367
				background-color: #787c82;
368
				color: #FFF;
369
				font-size: 11px;
370
				line-height: 21px;
371
			}
372
			.fixed .column-likes .post-com-count::after { border: none !important; }
373
			.fixed .column-likes .post-com-count:hover { background-color: #2271b1; }
374
			.fixed .column-likes .vers:before {
375
				font: normal 20px/1 dashicons;
376
				content: '\f155';
377
				speak: none;
378
				-webkit-font-smoothing: antialiased;
379
				-moz-osx-font-smoothing: grayscale;
380
			}
381
			@media screen and (max-width: 782px) {
382
				.fixed .column-likes {
383
					display: none;
384
				}
385
			}
386
		</style>
387
		<?php
388
	}
389
390
	/**
391
	 * Load the JS required for loading the like counts.
392
	 */
393
	public function enqueue_admin_scripts() {
394
		if ( empty( $_GET['post_type'] ) || 'post' === $_GET['post_type'] || 'page' === $_GET['post_type'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
395
			if ( $this->in_jetpack ) {
396
				wp_enqueue_script(
397
					'likes-post-count',
398
					Assets::get_file_url_for_environment(
399
						'_inc/build/likes/post-count.min.js',
400
						'modules/likes/post-count.js'
401
					),
402
					array( 'jquery' ),
403
					JETPACK__VERSION,
404
					$in_footer = false
405
				);
406
				wp_enqueue_script(
407
					'likes-post-count-jetpack',
408
					Assets::get_file_url_for_environment(
409
						'_inc/build/likes/post-count-jetpack.min.js',
410
						'modules/likes/post-count-jetpack.js'
411
					),
412
					array( 'likes-post-count' ),
413
					JETPACK__VERSION,
414
					$in_footer = false
415
				);
416
			} else {
417
				wp_enqueue_script( 'jquery.wpcom-proxy-request', '/wp-content/js/jquery/jquery.wpcom-proxy-request.js', array( 'jquery' ), JETPACK__VERSION, true );
418
				wp_enqueue_script( 'likes-post-count', plugins_url( 'likes/post-count.js', __DIR__ ), array( 'jquery' ), JETPACK__VERSION, $in_footer = false );
419
				wp_enqueue_script( 'likes-post-count-wpcom', plugins_url( 'likes/post-count-wpcom.js', __DIR__ ), array( 'likes-post-count', 'jquery.wpcom-proxy-request' ), JETPACK__VERSION, $in_footer = false );
420
			}
421
		}
422
	}
423
424
	/**
425
	 * Add "Likes" column data to the post edit table in wp-admin.
426
	 *
427
	 * @param string $column_name - name of the column.
428
	 * @param int    $post_id - the post id.
429
	 */
430
	public function likes_edit_column( $column_name, $post_id ) {
431
		if ( 'likes' === $column_name ) {
432
433
			if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
434
				$blog_id = get_current_blog_id();
435
			} else {
436
				$blog_id = Jetpack_Options::get_option( 'id' );
437
			}
438
439
			$permalink = get_permalink( get_the_ID() );
440
			?>
441
			<a title="" data-post-id="<?php echo (int) $post_id; ?>" class="post-com-count post-like-count" id="post-like-count-<?php echo (int) $post_id; ?>" data-blog-id="<?php echo (int) $blog_id; ?>" href="<?php echo esc_url( $permalink ); ?>#like-<?php echo (int) $post_id; ?>">
442
				<span class="comment-count">0</span>
443
			</a>
444
			<?php
445
		}
446
	}
447
448
	/**
449
	 * Add a "Likes" column header to the post edit table in wp-admin.
450
	 *
451
	 * @param array $columns - array of columns in wp-admin.
452
	 */
453
	public function add_like_count_column( $columns ) {
454
		$date = $columns['date'];
455
		unset( $columns['date'] );
456
457
		$columns['likes'] = '<span class="vers"><img title="' . esc_attr__( 'Likes', 'jetpack' ) . '" alt="' . esc_attr__( 'Likes', 'jetpack' ) . '" src="//s0.wordpress.com/i/like-grey-icon.png" /><span class="screen-reader-text">' . __( 'Likes', 'jetpack' ) . '</span></span>';
458
		$columns['date']  = $date;
459
460
		return $columns;
461
	}
462
463
	/**
464
	 * Append like button to content.
465
	 *
466
	 * @param string $content - content of the page.
467
	 */
468
	public function post_likes( $content ) {
469
		// Don't automatically append the Like button to the content if we're in an FSE theme.
470
		// If the content is empty, assume that we're rendering the Likes block on its own and proceed.
471
		if (
472
			function_exists( 'gutenberg_is_fse_theme' ) &&
473
			gutenberg_is_fse_theme() &&
474
			! empty( $content )
475
		) {
476
			return $content;
477
		}
478
479
		$post_id = get_the_ID();
480
481
		if ( ! is_numeric( $post_id ) || ! $this->settings->is_likes_visible() ) {
482
			return $content;
483
		}
484
485 View Code Duplication
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
486
			$blog_id  = get_current_blog_id();
487
			$bloginfo = get_blog_details( (int) $blog_id );
488
			$domain   = $bloginfo->domain;
489
		} else {
490
			$blog_id   = Jetpack_Options::get_option( 'id' );
491
			$url       = home_url();
492
			$url_parts = wp_parse_url( $url );
493
			$domain    = $url_parts['host'];
494
		}
495
		// Make sure to include the scripts before the iframe otherwise weird things happen.
496
		add_action( 'wp_footer', 'jetpack_likes_master_iframe', 21 );
497
498
		/**
499
		* If the same post appears more then once on a page the page goes crazy
500
		* we need a slightly more unique id / name for the widget wrapper.
501
		*/
502
		$uniqid = uniqid();
503
504
		$src      = sprintf( 'https://widgets.wp.com/likes/#blog_id=%1$d&amp;post_id=%2$d&amp;origin=%3$s&amp;obj_id=%1$d-%2$d-%4$s', $blog_id, $post_id, $domain, $uniqid );
505
		$name     = sprintf( 'like-post-frame-%1$d-%2$d-%3$s', $blog_id, $post_id, $uniqid );
506
		$wrapper  = sprintf( 'like-post-wrapper-%1$d-%2$d-%3$s', $blog_id, $post_id, $uniqid );
507
		$headline = sprintf(
508
			/** This filter is already documented in modules/sharedaddy/sharing-service.php */
509
			apply_filters( 'jetpack_sharing_headline_html', '<h3 class="sd-title">%s</h3>', esc_html__( 'Like this:', 'jetpack' ), 'likes' ),
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with esc_html__('Like this:', 'jetpack').

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...
510
			esc_html__( 'Like this:', 'jetpack' )
511
		);
512
513
		$html  = "<div class='sharedaddy sd-block sd-like jetpack-likes-widget-wrapper jetpack-likes-widget-unloaded' id='$wrapper' data-src='$src' data-name='$name'>";
514
		$html .= $headline;
515
		$html .= "<div class='likes-widget-placeholder post-likes-widget-placeholder' style='height: 55px;'><span class='button'><span>" . esc_html__( 'Like', 'jetpack' ) . '</span></span> <span class="loading">' . esc_html__( 'Loading...', 'jetpack' ) . '</span></div>';
516
		$html .= "<span class='sd-text-color'></span><a class='sd-link-color'></a>";
517
		$html .= '</div>';
518
519
		// Let's make sure that the script is enqueued.
520
		wp_enqueue_script( 'jetpack_likes_queuehandler' );
521
522
		return $content . $html;
523
	}
524
525
	/**
526
	 * Adds sd-like-enabled CSS class
527
	 *
528
	 * @param array $classes CSS class for post flair.
529
	 */
530
	public function post_flair_service_enabled_like( $classes ) {
531
		$classes[] = 'sd-like-enabled';
532
		return $classes;
533
	}
534
535
	/** Checks if admin bar is visible.*/
536
	public function is_admin_bar_button_visible() {
537
		global $wp_admin_bar;
538
539
		if ( ! is_object( $wp_admin_bar ) ) {
540
			return false;
541
		}
542
543
		if ( ( ! is_singular( 'post' ) && ! is_attachment() && ! is_page() ) ) {
544
			return false;
545
		}
546
547
		if ( ! $this->settings->is_likes_visible() ) {
548
			return false;
549
		}
550
551
		if ( ! $this->settings->is_post_likeable() ) {
552
			return false;
553
		}
554
555
		/**
556
		 * Filters whether the Like button is enabled in the admin bar.
557
		 *
558
		 * @module likes
559
		 *
560
		 * @since 2.2.0
561
		 *
562
		 * @param bool true Should the Like button be visible in the Admin bar. Default to true.
563
		 */
564
		return (bool) apply_filters( 'jetpack_admin_bar_likes_enabled', true );
565
	}
566
567
	/** Adds like section in admin bar. */
568
	public function admin_bar_likes() {
569
		global $wp_admin_bar;
570
571
		$post_id = get_the_ID();
572
573
		if ( ! is_numeric( $post_id ) || ! $this->is_admin_bar_button_visible() ) {
574
			return;
575
		}
576
577
		$protocol = 'http';
578
		if ( is_ssl() ) {
579
			$protocol = 'https';
580
		}
581 View Code Duplication
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
582
			$blog_id  = get_current_blog_id();
583
			$bloginfo = get_blog_details( (int) $blog_id );
584
			$domain   = $bloginfo->domain;
585
		} else {
586
			$blog_id   = Jetpack_Options::get_option( 'id' );
587
			$url       = home_url();
588
			$url_parts = wp_parse_url( $url );
589
			$domain    = $url_parts['host'];
590
		}
591
		// Make sure to include the scripts before the iframe otherwise weird things happen.
592
		add_action( 'wp_footer', 'jetpack_likes_master_iframe', 21 );
593
594
		$src = sprintf( 'https://widgets.wp.com/likes/#blog_id=%2$d&amp;post_id=%3$d&amp;origin=%1$s://%4$s', $protocol, $blog_id, $post_id, $domain );
595
596
		$html = "<iframe class='admin-bar-likes-widget jetpack-likes-widget' scrolling='no' frameBorder='0' name='admin-bar-likes-widget' src='$src'></iframe>";
597
598
		$node = array(
599
			'id'   => 'admin-bar-likes-widget',
600
			'meta' => array(
601
				'html' => $html,
602
			),
603
		);
604
605
		$wp_admin_bar->add_node( $node );
606
	}
607
}
608
609
/**
610
 * Callback to get the value for the jetpack_likes_enabled field.
611
 *
612
 * Warning: this behavior is somewhat complicated!
613
 * When the switch_like_status post_meta is unset, we follow the global setting in Sharing.
614
 * When it is set to 0, we disable likes on the post, regardless of the global setting.
615
 * When it is set to 1, we enable likes on the post, regardless of the global setting.
616
 *
617
 * @param array $post - post data we're checking.
618
 */
619
function jetpack_post_likes_get_value( array $post ) {
620
	$post_likes_switched = get_post_meta( $post['id'], 'switch_like_status', true );
621
622
	/** This filter is documented in modules/jetpack-likes-settings.php */
623
	$sitewide_likes_enabled = (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
624
625
	// An empty string: post meta was not set, so go with the global setting.
626
	if ( '' === $post_likes_switched ) {
627
		return $sitewide_likes_enabled;
628
	} elseif ( '0' === $post_likes_switched ) { // User overrode the global setting to disable likes.
629
		return false;
630
	} elseif ( '1' === $post_likes_switched ) { // User overrode the global setting to enable likes.
631
		return true;
632
	}
633
	// No default fallback, let's stay explicit.
634
}
635
636
/**
637
 * Callback to set switch_like_status post_meta when jetpack_likes_enabled is updated.
638
 *
639
 * Warning: this behavior is somewhat complicated!
640
 * When the switch_like_status post_meta is unset, we follow the global setting in Sharing.
641
 * When it is set to 0, we disable likes on the post, regardless of the global setting.
642
 * When it is set to 1, we enable likes on the post, regardless of the global setting.
643
 *
644
 * @param bool   $enable_post_likes - checks if post likes are enabled.
645
 * @param object $post_object - object containing post data.
646
 */
647
function jetpack_post_likes_update_value( $enable_post_likes, $post_object ) {
648
	/** This filter is documented in modules/jetpack-likes-settings.php */
649
	$sitewide_likes_enabled = (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
650
651
	$should_switch_status = $enable_post_likes !== $sitewide_likes_enabled;
652
653
	if ( $should_switch_status ) {
654
		// Set the meta to 0 if the user wants to disable likes, 1 if user wants to enable.
655
		$switch_like_status = ( $enable_post_likes ? 1 : 0 );
656
		return update_post_meta( $post_object->ID, 'switch_like_status', $switch_like_status );
657
	} else {
658
		// Unset the meta otherwise.
659
		return delete_post_meta( $post_object->ID, 'switch_like_status' );
660
	}
661
}
662
663
/**
664
 * Add Likes post_meta to the REST API Post response.
665
 *
666
 * @action rest_api_init
667
 * @uses register_rest_field
668
 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/
669
 */
670 View Code Duplication
function jetpack_post_likes_register_rest_field() {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
671
	$post_types = get_post_types( array( 'public' => true ) );
672
	foreach ( $post_types as $post_type ) {
673
		register_rest_field(
674
			$post_type,
675
			'jetpack_likes_enabled',
676
			array(
677
				'get_callback'    => 'jetpack_post_likes_get_value',
678
				'update_callback' => 'jetpack_post_likes_update_value',
679
				'schema'          => array(
680
					'description' => __( 'Are Likes enabled?', 'jetpack' ),
681
					'type'        => 'boolean',
682
				),
683
			)
684
		);
685
686
		/**
687
		 * Ensures all public internal post-types support `likes`
688
		 * This feature support flag is used by the REST API and Gutenberg.
689
		 */
690
		add_post_type_support( $post_type, 'jetpack-post-likes' );
691
	}
692
}
693
694
// Add Likes post_meta to the REST API Post response.
695
add_action( 'rest_api_init', 'jetpack_post_likes_register_rest_field' );
696
697
// Some CPTs (e.g. Jetpack portfolios and testimonials) get registered with
698
// restapi_theme_init because they depend on theme support, so let's also hook to that.
699
add_action( 'restapi_theme_init', 'jetpack_post_likes_register_rest_field', 20 );
700
701
/**
702
 * Set the Likes and Sharing Gutenberg extension availability.
703
 */
704
function jetpack_post_likes_set_extension_availability() {
705
	Jetpack_Gutenberg::set_extension_available( 'likes' );
706
}
707
708
add_action( 'jetpack_register_gutenberg_extensions', 'jetpack_post_likes_set_extension_availability' );
709
710
Jetpack_Likes::init();
711
712
const FEATURE_NAME = 'likes';
713
const BLOCK_NAME   = 'jetpack/' . FEATURE_NAME;
714
715
/**
716
 * Registers the block for use in Gutenberg
717
 * This is done via an action so that we can disable
718
 * registration if we need to.
719
 */
720
function register_block() {
721
	Blocks::jetpack_register_block(
722
		BLOCK_NAME,
723
		array( 'render_callback' => __NAMESPACE__ . '\load_assets' )
724
	);
725
}
726
add_action( 'init', __NAMESPACE__ . '\register_block' );
727
728
/**
729
 * Likes block registration/dependency declaration.
730
 *
731
 * @param array  $attr    Array containing the Likes block attributes.
732
 * @param string $content String containing the Likes block content.
733
 *
734
 * @return string
735
 */
736
function load_assets( $attr, $content ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
737
	Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME );
738
739
	$likes_instance = Jetpack_Likes::init();
740
741
	$server_rendered_content = $likes_instance->post_likes( '' );
742
	return $server_rendered_content;
743
}
744