PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 15.9-a.7
Jetpack – WP Security, Backup, Speed, & Growth v15.9-a.7
15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / modules / likes.php
jetpack / modules Last commit date
canonical-urls 2 months ago carousel 2 days ago comment-likes 6 months ago comments 1 week ago custom-post-types 3 months ago external-media 6 months ago google-fonts 4 months ago gravatar 5 years ago infinite-scroll 1 week ago likes 1 week ago markdown 1 week ago memberships 1 week ago photon-cdn 1 month ago plugin-search 4 weeks ago post-by-email 6 months ago related-posts 2 days ago scan 2 months ago seo-tools 1 week ago sharedaddy 1 week ago shortcodes 1 week ago shortlinks 1 week ago simple-payments 6 months ago site-icon 6 months ago sitemaps 1 week ago stats 5 months ago subscriptions 2 days ago theme-tools 2 weeks ago tiled-gallery 1 week ago verification-tools 2 weeks ago videopress 1 week ago widget-visibility 1 week ago widgets 2 days ago woocommerce-analytics 1 month ago wordads 1 month ago wpcom-tos 5 months ago account-protection.php 1 month ago blaze.php 6 months ago blocks.php 6 months ago canonical-urls.php 3 months ago carousel.php 6 months ago comment-likes.php 6 months ago comments.php 2 months ago contact-form.php 6 months ago copy-post.php 2 weeks ago custom-content-types.php 1 month ago google-fonts.php 1 month ago gravatar-hovercards.php 1 week ago infinite-scroll.php 6 months ago json-api.php 6 months ago latex.php 1 week ago likes.php 4 weeks ago markdown.php 6 months ago module-extras.php 6 months ago module-headings.php 1 week ago module-info.php 3 months ago monitor.php 2 days ago notes.php 5 months ago photon-cdn.php 6 months ago photon.php 6 months ago plugin-search.php 4 weeks ago post-by-email.php 1 month ago post-list.php 6 months ago protect.php 1 month ago publicize.php 6 months ago related-posts.php 2 weeks ago search.php 6 months ago seo-tools.php 6 months ago sharedaddy.php 3 months ago shortcodes.php 6 months ago shortlinks.php 2 weeks ago simple-payments.php 6 months ago sitemaps.php 6 months ago sso.php 6 months ago stats.php 1 week ago subscriptions.php 1 week ago theme-tools.php 6 months ago tiled-gallery.php 6 months ago vaultpress.php 6 months ago verification-tools.php 1 month ago videopress.php 6 months ago waf.php 6 months ago widget-visibility.php 6 months ago widgets.php 6 months ago woocommerce-analytics.php 6 months ago wordads.php 6 months ago wpcom-reader.php 3 months ago wpgroho.js 1 year ago
likes.php
601 lines
1 <?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Module Name: Likes
4 * Module Description: Let readers like your posts to show appreciation and encourage interaction.
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 * NOTE: While the front-end behavior currently varies, try to keep the data
17 * model here the same as on wpcom to facilitate Simple→Atomic moves and
18 * possible future work to recombine the front-ends.
19 */
20
21 // phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
22
23 use Automattic\Jetpack\Assets;
24 use Automattic\Jetpack\Status\Host;
25
26 if ( ! defined( 'ABSPATH' ) ) {
27 exit( 0 );
28 }
29
30 add_filter(
31 'wp_resource_hints',
32 function ( $hints, $relation_type ) {
33 if ( 'dns-prefetch' !== $relation_type ) {
34 return $hints;
35 }
36
37 // Only hint on pages where Likes can render.
38 if ( ! is_singular() && ! is_home() && ! is_front_page() && ! is_archive() && ! is_search() ) {
39 return $hints;
40 }
41
42 return array_merge(
43 $hints,
44 array(
45 '//widgets.wp.com',
46 '//s0.wp.com',
47 '//0.gravatar.com',
48 '//1.gravatar.com',
49 '//2.gravatar.com',
50 )
51 );
52 },
53 10,
54 2
55 );
56
57 require_once __DIR__ . '/likes/jetpack-likes-master-iframe.php';
58 require_once __DIR__ . '/likes/jetpack-likes-settings.php';
59
60 /**
61 * Jetpack Like Class
62 */
63 class Jetpack_Likes {
64 /**
65 * Jetpack_Likes_Settings object
66 *
67 * @var Jetpack_Likes_Settings
68 */
69 public $settings;
70
71 /**
72 * Initialize class
73 */
74 public static function init() {
75 static $instance = null;
76
77 if ( ! $instance ) {
78 $instance = new Jetpack_Likes();
79 }
80
81 return $instance;
82 }
83
84 /**
85 * Constructs Likes class
86 */
87 public function __construct() {
88 $this->settings = new Jetpack_Likes_Settings();
89
90 // We need to run on wp hook rather than init because we check is_amp_endpoint()
91 // when bootstrapping hooks.
92 add_action( 'wp', array( $this, 'action_init' ), 99 );
93
94 add_action( 'admin_init', array( $this, 'admin_init' ) );
95
96 add_action( 'jetpack_activate_module_likes', array( $this, 'set_social_notifications_like' ) );
97 add_action( 'jetpack_deactivate_module_likes', array( $this, 'delete_social_notifications_like' ) );
98
99 // The `enable_module_configurable` method doesn't exist in the WP.com loader implementation.
100 if ( ! ( new Host() )->is_wpcom_simple() ) {
101 Jetpack::enable_module_configurable( __FILE__ );
102 }
103
104 add_filter( 'jetpack_module_configuration_url_likes', array( $this, 'jetpack_likes_configuration_url' ) );
105 add_action( 'admin_print_scripts-settings_page_sharing', array( $this, 'load_jp_css' ) );
106 add_filter( 'sharing_show_buttons_on_row_start', array( $this, 'configuration_target_area' ) );
107
108 $publicize_active = Jetpack::is_module_active( 'publicize' );
109 $sharedaddy_active = Jetpack::is_module_active( 'sharedaddy' );
110
111 if ( $publicize_active && ! $sharedaddy_active ) {
112 // we have a sharing page but not the global options area.
113 add_action( 'pre_admin_screen_sharing', array( $this->settings, 'sharing_block' ), 20 );
114 add_action( 'pre_admin_screen_sharing', array( $this->settings, 'updated_message' ), -10 );
115 }
116
117 if ( ! $sharedaddy_active ) {
118 add_action( 'admin_init', array( $this->settings, 'process_update_requests_if_sharedaddy_not_loaded' ) );
119 add_action( 'sharing_global_options', array( $this->settings, 'admin_settings_showbuttonon_init' ), 19 );
120 add_action( 'sharing_admin_update', array( $this->settings, 'admin_settings_showbuttonon_callback' ), 19 );
121 add_action( 'admin_init', array( $this->settings, 'add_meta_box' ) );
122 } else {
123 add_filter( 'sharing_meta_box_title', array( $this->settings, 'add_likes_to_sharing_meta_box_title' ) );
124 add_action( 'start_sharing_meta_box_content', array( $this->settings, 'meta_box_content' ) );
125 }
126
127 add_action( 'admin_init', array( $this, 'admin_discussion_likes_settings_init' ) ); // Likes notifications.
128
129 add_action( 'wp_enqueue_scripts', array( $this, 'load_styles_register_scripts' ) );
130
131 add_action( 'save_post', array( $this->settings, 'meta_box_save' ) );
132 add_action( 'edit_attachment', array( $this->settings, 'meta_box_save' ) );
133 add_action( 'sharing_global_options', array( $this->settings, 'admin_settings_init' ), 20 );
134 add_action( 'sharing_admin_update', array( $this->settings, 'admin_settings_callback' ), 20 );
135 }
136
137 /**
138 * Set the social_notifications_like option to `on` when the Likes module is activated.
139 *
140 * @since 3.7.0
141 */
142 public function set_social_notifications_like() {
143 update_option( 'social_notifications_like', 'on' );
144 }
145
146 /**
147 * Delete the social_notifications_like option that was set to `on` on module activation.
148 *
149 * @since 3.7.0
150 */
151 public function delete_social_notifications_like() {
152 delete_option( 'social_notifications_like' );
153 }
154
155 /**
156 * Overrides default configuration url
157 *
158 * @uses admin_url
159 * @return string module settings URL
160 */
161 public function jetpack_likes_configuration_url() {
162 return admin_url( 'options-general.php?page=sharing#likes' );
163 }
164
165 /**
166 * Loads Jetpack's CSS on the sharing page so we can use .jetpack-targetable
167 */
168 public function load_jp_css() {
169 /**
170 * Do we really need `admin_styles`? With the new admin UI, it's breaking some bits.
171 * Jetpack::init()->admin_styles();
172 */
173 }
174
175 /**
176 * Load scripts and styles for front end.
177 */
178 public function load_styles_register_scripts() {
179 // Likes are only rendered on pages that display post content.
180 if ( ! is_singular() && ! is_home() && ! is_front_page() && ! is_archive() && ! is_search() ) {
181 return;
182 }
183
184 $style_url = Assets::get_file_url_for_environment(
185 '_inc/build/likes/style.min.css',
186 'modules/likes/style.css'
187 );
188 wp_enqueue_style( 'jetpack_likes', $style_url, array(), JETPACK__VERSION );
189 $style_path = plugin_dir_path( JETPACK__PLUGIN_FILE ) . (
190 /** This filter is documented in projects/plugins/jetpack/load-jetpack.php */
191 apply_filters( 'jetpack_should_use_minified_assets', true )
192 ? '_inc/build/likes/style.min.css'
193 : 'modules/likes/style.css'
194 );
195 wp_style_add_data( 'jetpack_likes', 'path', $style_path );
196 wp_register_script(
197 'jetpack_likes_queuehandler',
198 Assets::get_file_url_for_environment(
199 '_inc/build/likes/queuehandler.min.js',
200 'modules/likes/queuehandler.js'
201 ),
202 array(),
203 JETPACK__VERSION,
204 true
205 );
206 }
207
208 /**
209 * Adds in the jetpack-targetable class so when we visit sharing#likes our like settings get highlighted by a yellow box
210 *
211 * @param string $html row heading for the sharedaddy "which page" setting.
212 * @return string $html with the jetpack-targetable class and likes id. tbody gets closed after the like settings
213 */
214 public function configuration_target_area( $html = '' ) {
215 $html = "<tbody id='likes' class='jetpack-targetable'>" . $html;
216 return $html;
217 }
218
219 /**
220 * Options to be added to the discussion page (see also admin_settings_init, etc below for Sharing settings page)
221 */
222 public function admin_discussion_likes_settings_init() {
223 // Add a temporary section, until we can move the setting out of there and with the rest of the email notification settings.
224 add_settings_section( 'likes-notifications', __( 'Likes Notifications', 'jetpack' ), array( $this, 'admin_discussion_likes_settings_section' ), 'discussion' );
225 add_settings_field( 'social-notifications', __( 'Email me whenever', 'jetpack' ), array( $this, 'admin_discussion_likes_settings_field' ), 'discussion', 'likes-notifications' );
226 // Register the setting.
227 register_setting( 'discussion', 'social_notifications_like', array( $this, 'admin_discussion_likes_settings_validate' ) );
228 }
229
230 /** Add email notification options to WordPress discussion settings */
231 public function admin_discussion_likes_settings_section() {
232 // Atypical usage here. We emit jquery to move likes notification checkbox to be with the rest of the email notification settings.
233 ?>
234 <script type="text/javascript">
235 jQuery( function( $ ) {
236 var table = $( '#social_notifications_like' ).parents( 'table:first' ),
237 header = table.prevAll( 'h2:first' ),
238 newParent = $( '#moderation_notify' ).parent( 'label' ).parent();
239
240 if ( !table.length || !header.length || !newParent.length ) {
241 return;
242 }
243
244 newParent.append( '<br/>' ).append( table.end().parent( 'label' ).siblings().andSelf() );
245 header.remove();
246 table.remove();
247 } );
248 </script>
249 <?php
250 }
251
252 /** Check if email notifications for likes is on or off.
253 *
254 * @param string $option - which option we're checking (social_notifications_like).
255 */
256 public function admin_likes_get_option( $option ) {
257 $option_setting = get_option( $option, 'on' );
258
259 return (int) ( 'on' === $option_setting );
260 }
261
262 /** Display email notification for likes setting in WordPress' discussion settings. */
263 public function admin_discussion_likes_settings_field() {
264 $like = $this->admin_likes_get_option( 'social_notifications_like' );
265 ?>
266 <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>
267 <?php
268 }
269
270 /**
271 * Validate email notification settings.
272 *
273 * @param string $input - determines if checbox is on or off.
274 */
275 public function admin_discussion_likes_settings_validate( $input ) {
276 // If it's not set (was unchecked during form submission) or was set to off (during option update), return 'off'.
277 if ( ! $input || 'off' === $input ) {
278 return 'off';
279 }
280 // Otherwise return 'on'.
281 return 'on';
282 }
283
284 /** Initialize admin settings */
285 public function admin_init() {
286 add_filter( 'manage_posts_columns', array( $this, 'add_like_count_column' ) );
287 add_filter( 'manage_pages_columns', array( $this, 'add_like_count_column' ) );
288 add_action( 'manage_posts_custom_column', array( $this, 'likes_edit_column' ), 10, 2 );
289 add_action( 'manage_pages_custom_column', array( $this, 'likes_edit_column' ), 10, 2 );
290 add_action( 'admin_print_styles-edit.php', array( $this, 'load_admin_css' ) );
291 add_action( 'admin_print_scripts-edit.php', array( $this, 'enqueue_admin_scripts' ) );
292 }
293
294 /** Initialize action */
295 public function action_init() {
296 /*
297 * Only check if the module is enabled here because
298 * we are not currently in The Loop and do not yet have access to check
299 * the switch_like_status post meta flag for the post to be loaded.
300 */
301 if ( is_admin() || ! $this->settings->is_likes_module_enabled() ) {
302 return;
303 }
304
305 if ( ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) ||
306 ( defined( 'APP_REQUEST' ) && APP_REQUEST ) ||
307 ( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST ) ||
308 ( defined( 'COOKIE_AUTH_REQUEST' ) && COOKIE_AUTH_REQUEST ) ||
309 ( defined( 'JABBER_SERVER' ) && JABBER_SERVER ) ) {
310 return;
311 }
312
313 if (
314 class_exists( 'Jetpack_AMP_Support' )
315 && Jetpack_AMP_Support::is_amp_request()
316 ) {
317 return;
318 }
319
320 add_filter( 'the_content', array( $this, 'post_likes' ), 30, 1 );
321 add_filter( 'the_excerpt', array( $this, 'post_likes' ), 30, 1 );
322 }
323
324 /**
325 * Load the CSS needed for the wp-admin area.
326 */
327 public function load_admin_css() {
328 ?>
329 <style type="text/css">
330 .vers img { display: none; }
331 .metabox-prefs .vers img { display: inline; }
332 .fixed .column-likes { width: 2.5em; padding: 4px 0; text-align: left; }
333 .fixed .column-stats { width: 5em; white-space: nowrap; }
334 .fixed .column-likes .post-com-count {
335 -webkit-box-sizing: border-box;
336 -moz-box-sizing: border-box;
337 box-sizing: border-box;
338 display: inline-block;
339 padding: 0 4px;
340 min-width: 2em;
341 text-align: center;
342 height: 2em;
343 margin-top: 5px;
344 -webkit-border-radius: 5px;
345 border-radius: 5px;
346 background-color: #787c82;
347 color: #FFF;
348 font-size: 11px;
349 line-height: 21px;
350 }
351 .fixed .column-likes .post-com-count::after { border: none !important; }
352 .fixed .column-likes .post-com-count:hover { background-color: #2271b1; }
353 .fixed .column-likes .vers::before {
354 font: normal 20px/1 dashicons;
355 content: '\f155';
356 speak: none;
357 -webkit-font-smoothing: antialiased;
358 -moz-osx-font-smoothing: grayscale;
359 }
360 @media screen and (max-width: 782px) {
361 .fixed .column-likes {
362 display: none;
363 }
364 }
365 </style>
366 <?php
367 }
368
369 /**
370 * Load the JS required for loading the like counts.
371 */
372 public function enqueue_admin_scripts() {
373 if ( empty( $_GET['post_type'] ) || 'post' === $_GET['post_type'] || 'page' === $_GET['post_type'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
374 wp_enqueue_script(
375 'likes-post-count',
376 Assets::get_file_url_for_environment(
377 '_inc/build/likes/post-count.min.js',
378 'modules/likes/post-count.js'
379 ),
380 array( 'jquery' ),
381 JETPACK__VERSION,
382 false
383 );
384 wp_enqueue_script(
385 'likes-post-count-jetpack',
386 Assets::get_file_url_for_environment(
387 '_inc/build/likes/post-count-jetpack.min.js',
388 'modules/likes/post-count-jetpack.js'
389 ),
390 array( 'jquery', 'likes-post-count' ),
391 JETPACK__VERSION,
392 false
393 );
394 }
395 }
396
397 /**
398 * Add "Likes" column data to the post edit table in wp-admin.
399 *
400 * @param string $column_name - name of the column.
401 * @param int $post_id - the post id.
402 */
403 public function likes_edit_column( $column_name, $post_id ) {
404 if ( 'likes' === $column_name ) {
405
406 $blog_id = Jetpack_Options::get_option( 'id' );
407
408 $permalink = get_permalink( get_the_ID() );
409 ?>
410 <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; ?>">
411 <span class="comment-count">0</span>
412 </a>
413 <?php
414 }
415 }
416
417 /**
418 * Add a "Likes" column header to the post edit table in wp-admin.
419 *
420 * @param array $columns - array of columns in wp-admin.
421 */
422 public function add_like_count_column( $columns ) {
423 $date = $columns['date'];
424 unset( $columns['date'] );
425
426 $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>';
427 $columns['date'] = $date;
428
429 return $columns;
430 }
431
432 /**
433 * Append like button to content.
434 *
435 * @param string $content - content of the page.
436 */
437 public function post_likes( $content ) {
438 global $wp_current_filter;
439 $post_id = get_the_ID();
440
441 if ( ! is_numeric( $post_id ) || ! $this->settings->is_likes_visible() ) {
442 return $content;
443 }
444
445 // Do not output Likes on requests for ActivityPub requests.
446 if (
447 function_exists( '\Activitypub\is_activitypub_request' )
448 && \Activitypub\is_activitypub_request()
449 ) {
450 return $content;
451 }
452
453 // Ensure we don't display like button on post excerpts that are hooked inside the post content
454 if ( in_array( 'the_excerpt', (array) $wp_current_filter, true ) &&
455 in_array( 'the_content', (array) $wp_current_filter, true ) ) {
456 return $content;
457 }
458
459 $blog_id = Jetpack_Options::get_option( 'id' );
460 $url = home_url();
461 $url_parts = wp_parse_url( $url );
462 $domain = $url_parts['host'];
463
464 // Make sure to include the `queuehandler` scripts before the iframe otherwise the script won't find the iframe.
465 if ( ! has_action( 'wp_footer', 'jetpack_likes_master_iframe' ) ) {
466 add_action( 'wp_footer', 'jetpack_likes_master_iframe', 21 );
467 }
468
469 /**
470 * If the same post appears more then once on a page the page goes crazy
471 * we need a slightly more unique id / name for the widget wrapper.
472 */
473 $uniqid = uniqid();
474 $src = sprintf( 'https://widgets.wp.com/likes/?ver=%1$s#blog_id=%2$d&amp;post_id=%3$d&amp;origin=%4$s&amp;obj_id=%2$d-%3$d-%5$s', rawurlencode( JETPACK__VERSION ), $blog_id, $post_id, $domain, $uniqid );
475 $name = sprintf( 'like-post-frame-%1$d-%2$d-%3$s', $blog_id, $post_id, $uniqid );
476 $wrapper = sprintf( 'like-post-wrapper-%1$d-%2$d-%3$s', $blog_id, $post_id, $uniqid );
477 $headline = sprintf(
478 /** This filter is already documented in modules/sharedaddy/sharing-service.php */
479 apply_filters( 'jetpack_sharing_headline_html', '<h3 class="sd-title">%s</h3>', esc_html__( 'Like this:', 'jetpack' ), 'likes' ),
480 esc_html__( 'Like this:', 'jetpack' )
481 );
482
483 $title = esc_html__( 'Like or Reblog', 'jetpack' );
484
485 /** This filter is documented in modules/likes/jetpack-likes-master-iframe.php */
486 $src = apply_filters( 'jetpack_likes_iframe_src', $src );
487
488 $html = "<div class='sharedaddy sd-block sd-like jetpack-likes-widget-wrapper jetpack-likes-widget-unloaded' id='$wrapper' data-src='$src' data-name='$name' data-title='$title'>";
489 $html .= $headline;
490 require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-spinner.php';
491 $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">' . Jetpack_Spinner::render( 18 ) . '<span class="screen-reader-text">' . esc_html__( 'Loading…', 'jetpack' ) . '</span></span></div>';
492 $html .= "<span class='sd-text-color'></span><a class='sd-link-color'></a>";
493 $html .= '</div>';
494
495 // Let's make sure that the script is enqueued.
496 wp_enqueue_script( 'jetpack_likes_queuehandler' );
497
498 return $content . $html;
499 }
500 }
501
502 /**
503 * Callback to get the value for the jetpack_likes_enabled field.
504 *
505 * Warning: this behavior is somewhat complicated!
506 * When the switch_like_status post_meta is unset, we follow the global setting in Sharing.
507 * When it is set to 0, we disable likes on the post, regardless of the global setting.
508 * When it is set to 1, we enable likes on the post, regardless of the global setting.
509 *
510 * @param array $post - post data we're checking.
511 *
512 * @return bool
513 */
514 function jetpack_post_likes_get_value( array $post ) {
515 if ( ! isset( $post['id'] ) ) {
516 return false;
517 }
518
519 $post_likes_switched = get_post_meta( $post['id'], 'switch_like_status', true );
520
521 /** This filter is documented in modules/jetpack-likes-settings.php */
522 $sitewide_likes_enabled = (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
523
524 // An empty string: post meta was not set, so go with the global setting.
525 if ( '' === $post_likes_switched ) {
526 return $sitewide_likes_enabled;
527 } elseif ( '0' === $post_likes_switched ) { // User overrode the global setting to disable likes.
528 return false;
529 } elseif ( '1' === $post_likes_switched ) { // User overrode the global setting to enable likes.
530 return true;
531 }
532 // No default fallback, let's stay explicit.
533 }
534
535 /**
536 * Callback to set switch_like_status post_meta when jetpack_likes_enabled is updated.
537 *
538 * Warning: this behavior is somewhat complicated!
539 * When the switch_like_status post_meta is unset, we follow the global setting in Sharing.
540 * When it is set to 0, we disable likes on the post, regardless of the global setting.
541 * When it is set to 1, we enable likes on the post, regardless of the global setting.
542 *
543 * @param bool $enable_post_likes - checks if post likes are enabled.
544 * @param object $post_object - object containing post data.
545 */
546 function jetpack_post_likes_update_value( $enable_post_likes, $post_object ) {
547 /** This filter is documented in modules/jetpack-likes-settings.php */
548 $sitewide_likes_enabled = (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
549
550 $should_switch_status = $enable_post_likes !== $sitewide_likes_enabled;
551
552 if ( $should_switch_status ) {
553 // Set the meta to 0 if the user wants to disable likes, 1 if user wants to enable.
554 $switch_like_status = ( $enable_post_likes ? 1 : 0 );
555 return update_post_meta( $post_object->ID, 'switch_like_status', $switch_like_status );
556 } else {
557 // Unset the meta otherwise.
558 return delete_post_meta( $post_object->ID, 'switch_like_status' );
559 }
560 }
561
562 /**
563 * Add Likes post_meta to the REST API Post response.
564 *
565 * @action rest_api_init
566 * @uses register_rest_field
567 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/
568 */
569 function jetpack_post_likes_register_rest_field() {
570 $post_types = get_post_types( array( 'public' => true ) );
571 foreach ( $post_types as $post_type ) {
572 register_rest_field(
573 $post_type,
574 'jetpack_likes_enabled',
575 array(
576 'get_callback' => 'jetpack_post_likes_get_value',
577 'update_callback' => 'jetpack_post_likes_update_value',
578 'schema' => array(
579 'description' => __( 'Are Likes enabled?', 'jetpack' ),
580 'type' => 'boolean',
581 ),
582 )
583 );
584
585 /**
586 * Ensures all public internal post-types support `likes`
587 * This feature support flag is used by the REST API and Gutenberg.
588 */
589 add_post_type_support( $post_type, 'jetpack-post-likes' );
590 }
591 }
592
593 // Add Likes post_meta to the REST API Post response.
594 add_action( 'rest_api_init', 'jetpack_post_likes_register_rest_field' );
595
596 // Some CPTs (e.g. Jetpack portfolios and testimonials) get registered with
597 // restapi_theme_init because they depend on theme support, so let's also hook to that.
598 add_action( 'restapi_theme_init', 'jetpack_post_likes_register_rest_field', 20 );
599
600 Jetpack_Likes::init();
601