PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 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 5 months ago carousel 3 weeks ago comment-likes 9 months ago comments 3 months ago custom-post-types 2 months ago external-media 9 months ago google-fonts 2 months ago gravatar 6 years ago infinite-scroll 2 months ago likes 1 week ago markdown 3 months ago memberships 2 weeks ago photon-cdn 1 month ago plugin-search 3 months ago post-by-email 9 months ago related-posts 1 month ago scan 5 months ago seo-tools 1 week ago sharedaddy 1 week ago shortcodes 1 month ago shortlinks 2 months ago simple-payments 9 months ago site-icon 9 months ago sitemaps 1 week ago stats 8 months ago subscriptions 1 month ago theme-tools 3 weeks ago tiled-gallery 2 months ago verification-tools 3 months ago videopress 1 month ago widget-visibility 3 months ago widgets 2 weeks ago woocommerce-analytics 4 months ago wordads 2 months ago wpcom-tos 8 months ago account-protection.php 4 months ago ai.php 1 week ago blaze.php 9 months ago blocks.php 9 months ago canonical-urls.php 6 months ago carousel.php 9 months ago comment-likes.php 1 week ago comments.php 5 months ago contact-form.php 9 months ago copy-post.php 3 months ago custom-content-types.php 4 months ago google-fonts.php 4 months ago gravatar-hovercards.php 3 months ago infinite-scroll.php 9 months ago json-api.php 9 months ago latex.php 3 months ago likes.php 1 week ago markdown.php 9 months ago module-extras.php 3 weeks ago module-headings.php 1 week ago module-info.php 6 months ago monitor.php 2 months ago notes.php 1 month ago photon-cdn.php 9 months ago photon.php 9 months ago plugin-search.php 3 weeks ago podcast.php 1 month ago post-by-email.php 4 months ago post-list.php 9 months ago protect.php 4 months ago publicize.php 9 months ago related-posts.php 3 months ago search.php 9 months ago seo-tools.php 2 months ago sharedaddy.php 6 months ago shortcodes.php 9 months ago shortlinks.php 3 months ago simple-payments.php 9 months ago sitemaps.php 9 months ago sso.php 2 months ago stats.php 1 month ago subscriptions.php 1 month ago theme-tools.php 9 months ago tiled-gallery.php 9 months ago vaultpress.php 9 months ago verification-tools.php 4 months ago videopress.php 9 months ago waf.php 9 months ago widget-visibility.php 9 months ago widgets.php 9 months ago woocommerce-analytics.php 9 months ago wordads.php 9 months ago wpcom-reader.php 6 months ago wpgroho.js 1 year ago
likes.php
607 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 ( $this->settings->needs_own_sharing_menu( $sharedaddy_active ) ) {
112 /*
113 * Sharedaddy is what registers Settings > Sharing, and it is off, so we
114 * register that screen ourselves; our settings are displayed on it.
115 */
116 add_action( 'admin_menu', array( $this->settings, 'sharing_menu' ) );
117 } elseif ( $publicize_active && ! $sharedaddy_active ) {
118 // we have a sharing page but not the global options area.
119 add_action( 'pre_admin_screen_sharing', array( $this->settings, 'sharing_block' ), 20 );
120 add_action( 'pre_admin_screen_sharing', array( $this->settings, 'updated_message' ), -10 );
121 }
122
123 if ( ! $sharedaddy_active ) {
124 add_action( 'admin_init', array( $this->settings, 'process_update_requests_if_sharedaddy_not_loaded' ) );
125 add_action( 'sharing_global_options', array( $this->settings, 'admin_settings_showbuttonon_init' ), 19 );
126 add_action( 'sharing_admin_update', array( $this->settings, 'admin_settings_showbuttonon_callback' ), 19 );
127 add_action( 'admin_init', array( $this->settings, 'add_meta_box' ) );
128 } else {
129 add_filter( 'sharing_meta_box_title', array( $this->settings, 'add_likes_to_sharing_meta_box_title' ) );
130 add_action( 'start_sharing_meta_box_content', array( $this->settings, 'meta_box_content' ) );
131 }
132
133 add_action( 'admin_init', array( $this, 'admin_discussion_likes_settings_init' ) ); // Likes notifications.
134
135 add_action( 'wp_enqueue_scripts', array( $this, 'load_styles_register_scripts' ) );
136
137 add_action( 'save_post', array( $this->settings, 'meta_box_save' ) );
138 add_action( 'edit_attachment', array( $this->settings, 'meta_box_save' ) );
139 add_action( 'sharing_global_options', array( $this->settings, 'admin_settings_init' ), 20 );
140 add_action( 'sharing_admin_update', array( $this->settings, 'admin_settings_callback' ), 20 );
141 }
142
143 /**
144 * Set the social_notifications_like option to `on` when the Likes module is activated.
145 *
146 * @since 3.7.0
147 */
148 public function set_social_notifications_like() {
149 update_option( 'social_notifications_like', 'on' );
150 }
151
152 /**
153 * Delete the social_notifications_like option that was set to `on` on module activation.
154 *
155 * @since 3.7.0
156 */
157 public function delete_social_notifications_like() {
158 delete_option( 'social_notifications_like' );
159 }
160
161 /**
162 * Overrides default configuration url
163 *
164 * @uses admin_url
165 * @return string module settings URL
166 */
167 public function jetpack_likes_configuration_url() {
168 return admin_url( 'options-general.php?page=sharing#likes' );
169 }
170
171 /**
172 * Loads Jetpack's CSS on the sharing page so we can use .jetpack-targetable
173 */
174 public function load_jp_css() {
175 /**
176 * Do we really need `admin_styles`? With the new admin UI, it's breaking some bits.
177 * Jetpack::init()->admin_styles();
178 */
179 }
180
181 /**
182 * Load scripts and styles for front end.
183 */
184 public function load_styles_register_scripts() {
185 // Likes are only rendered on pages that display post content.
186 if ( ! is_singular() && ! is_home() && ! is_front_page() && ! is_archive() && ! is_search() ) {
187 return;
188 }
189
190 $style_url = Assets::get_file_url_for_environment(
191 '_inc/build/likes/style.min.css',
192 'modules/likes/style.css'
193 );
194 wp_enqueue_style( 'jetpack_likes', $style_url, array(), JETPACK__VERSION );
195 $style_path = plugin_dir_path( JETPACK__PLUGIN_FILE ) . (
196 /** This filter is documented in projects/plugins/jetpack/load-jetpack.php */
197 apply_filters( 'jetpack_should_use_minified_assets', true )
198 ? '_inc/build/likes/style.min.css'
199 : 'modules/likes/style.css'
200 );
201 wp_style_add_data( 'jetpack_likes', 'path', $style_path );
202 wp_register_script(
203 'jetpack_likes_queuehandler',
204 Assets::get_file_url_for_environment(
205 '_inc/build/likes/queuehandler.min.js',
206 'modules/likes/queuehandler.js'
207 ),
208 array(),
209 JETPACK__VERSION,
210 true
211 );
212 }
213
214 /**
215 * Adds in the jetpack-targetable class so when we visit sharing#likes our like settings get highlighted by a yellow box
216 *
217 * @param string $html row heading for the sharedaddy "which page" setting.
218 * @return string $html with the jetpack-targetable class and likes id. tbody gets closed after the like settings
219 */
220 public function configuration_target_area( $html = '' ) {
221 $html = "<tbody id='likes' class='jetpack-targetable'>" . $html;
222 return $html;
223 }
224
225 /**
226 * Options to be added to the discussion page (see also admin_settings_init, etc below for Sharing settings page)
227 */
228 public function admin_discussion_likes_settings_init() {
229 // Add a temporary section, until we can move the setting out of there and with the rest of the email notification settings.
230 add_settings_section( 'likes-notifications', __( 'Likes Notifications', 'jetpack' ), array( $this, 'admin_discussion_likes_settings_section' ), 'discussion' );
231 add_settings_field( 'social-notifications', __( 'Email me whenever', 'jetpack' ), array( $this, 'admin_discussion_likes_settings_field' ), 'discussion', 'likes-notifications' );
232 // Register the setting.
233 register_setting( 'discussion', 'social_notifications_like', array( $this, 'admin_discussion_likes_settings_validate' ) );
234 }
235
236 /** Add email notification options to WordPress discussion settings */
237 public function admin_discussion_likes_settings_section() {
238 // Atypical usage here. We emit jquery to move likes notification checkbox to be with the rest of the email notification settings.
239 ?>
240 <script type="text/javascript">
241 jQuery( function( $ ) {
242 var table = $( '#social_notifications_like' ).parents( 'table:first' ),
243 header = table.prevAll( 'h2:first' ),
244 newParent = $( '#moderation_notify' ).parent( 'label' ).parent();
245
246 if ( !table.length || !header.length || !newParent.length ) {
247 return;
248 }
249
250 newParent.append( '<br/>' ).append( table.end().parent( 'label' ).siblings().andSelf() );
251 header.remove();
252 table.remove();
253 } );
254 </script>
255 <?php
256 }
257
258 /** Check if email notifications for likes is on or off.
259 *
260 * @param string $option - which option we're checking (social_notifications_like).
261 */
262 public function admin_likes_get_option( $option ) {
263 $option_setting = get_option( $option, 'on' );
264
265 return (int) ( 'on' === $option_setting );
266 }
267
268 /** Display email notification for likes setting in WordPress' discussion settings. */
269 public function admin_discussion_likes_settings_field() {
270 $like = $this->admin_likes_get_option( 'social_notifications_like' );
271 ?>
272 <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>
273 <?php
274 }
275
276 /**
277 * Validate email notification settings.
278 *
279 * @param string $input - determines if checbox is on or off.
280 */
281 public function admin_discussion_likes_settings_validate( $input ) {
282 // If it's not set (was unchecked during form submission) or was set to off (during option update), return 'off'.
283 if ( ! $input || 'off' === $input ) {
284 return 'off';
285 }
286 // Otherwise return 'on'.
287 return 'on';
288 }
289
290 /** Initialize admin settings */
291 public function admin_init() {
292 add_filter( 'manage_posts_columns', array( $this, 'add_like_count_column' ) );
293 add_filter( 'manage_pages_columns', array( $this, 'add_like_count_column' ) );
294 add_action( 'manage_posts_custom_column', array( $this, 'likes_edit_column' ), 10, 2 );
295 add_action( 'manage_pages_custom_column', array( $this, 'likes_edit_column' ), 10, 2 );
296 add_action( 'admin_print_styles-edit.php', array( $this, 'load_admin_css' ) );
297 add_action( 'admin_print_scripts-edit.php', array( $this, 'enqueue_admin_scripts' ) );
298 }
299
300 /** Initialize action */
301 public function action_init() {
302 /*
303 * Only check if the module is enabled here because
304 * we are not currently in The Loop and do not yet have access to check
305 * the switch_like_status post meta flag for the post to be loaded.
306 */
307 if ( is_admin() || ! $this->settings->is_likes_module_enabled() ) {
308 return;
309 }
310
311 if ( ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) ||
312 ( defined( 'APP_REQUEST' ) && APP_REQUEST ) ||
313 ( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST ) ||
314 ( defined( 'COOKIE_AUTH_REQUEST' ) && COOKIE_AUTH_REQUEST ) ||
315 ( defined( 'JABBER_SERVER' ) && JABBER_SERVER ) ) {
316 return;
317 }
318
319 if (
320 class_exists( 'Jetpack_AMP_Support' )
321 && Jetpack_AMP_Support::is_amp_request()
322 ) {
323 return;
324 }
325
326 add_filter( 'the_content', array( $this, 'post_likes' ), 30, 1 );
327 add_filter( 'the_excerpt', array( $this, 'post_likes' ), 30, 1 );
328 }
329
330 /**
331 * Load the CSS needed for the wp-admin area.
332 */
333 public function load_admin_css() {
334 ?>
335 <style type="text/css">
336 .vers img { display: none; }
337 .metabox-prefs .vers img { display: inline; }
338 .fixed .column-likes { width: 2.5em; padding: 4px 0; text-align: left; }
339 .fixed .column-stats { width: 5em; white-space: nowrap; }
340 .fixed .column-likes .post-com-count {
341 -webkit-box-sizing: border-box;
342 -moz-box-sizing: border-box;
343 box-sizing: border-box;
344 display: inline-block;
345 padding: 0 4px;
346 min-width: 2em;
347 text-align: center;
348 height: 2em;
349 margin-top: 5px;
350 -webkit-border-radius: 5px;
351 border-radius: 5px;
352 background-color: #787c82;
353 color: #FFF;
354 font-size: 11px;
355 line-height: 21px;
356 }
357 .fixed .column-likes .post-com-count::after { border: none !important; }
358 .fixed .column-likes .post-com-count:hover { background-color: #2271b1; }
359 .fixed .column-likes .vers::before {
360 font: normal 20px/1 dashicons;
361 content: '\f155';
362 speak: none;
363 -webkit-font-smoothing: antialiased;
364 -moz-osx-font-smoothing: grayscale;
365 }
366 @media screen and (max-width: 782px) {
367 .fixed .column-likes {
368 display: none;
369 }
370 }
371 </style>
372 <?php
373 }
374
375 /**
376 * Load the JS required for loading the like counts.
377 */
378 public function enqueue_admin_scripts() {
379 if ( empty( $_GET['post_type'] ) || 'post' === $_GET['post_type'] || 'page' === $_GET['post_type'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
380 wp_enqueue_script(
381 'likes-post-count',
382 Assets::get_file_url_for_environment(
383 '_inc/build/likes/post-count.min.js',
384 'modules/likes/post-count.js'
385 ),
386 array( 'jquery' ),
387 JETPACK__VERSION,
388 false
389 );
390 wp_enqueue_script(
391 'likes-post-count-jetpack',
392 Assets::get_file_url_for_environment(
393 '_inc/build/likes/post-count-jetpack.min.js',
394 'modules/likes/post-count-jetpack.js'
395 ),
396 array( 'jquery', 'likes-post-count' ),
397 JETPACK__VERSION,
398 false
399 );
400 }
401 }
402
403 /**
404 * Add "Likes" column data to the post edit table in wp-admin.
405 *
406 * @param string $column_name - name of the column.
407 * @param int $post_id - the post id.
408 */
409 public function likes_edit_column( $column_name, $post_id ) {
410 if ( 'likes' === $column_name ) {
411
412 $blog_id = Jetpack_Options::get_option( 'id' );
413
414 $permalink = get_permalink( get_the_ID() );
415 ?>
416 <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; ?>">
417 <span class="comment-count">0</span>
418 </a>
419 <?php
420 }
421 }
422
423 /**
424 * Add a "Likes" column header to the post edit table in wp-admin.
425 *
426 * @param array $columns - array of columns in wp-admin.
427 */
428 public function add_like_count_column( $columns ) {
429 $date = $columns['date'];
430 unset( $columns['date'] );
431
432 $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>';
433 $columns['date'] = $date;
434
435 return $columns;
436 }
437
438 /**
439 * Append like button to content.
440 *
441 * @param string $content - content of the page.
442 */
443 public function post_likes( $content ) {
444 global $wp_current_filter;
445 $post_id = get_the_ID();
446
447 if ( ! is_numeric( $post_id ) || ! $this->settings->is_likes_visible() ) {
448 return $content;
449 }
450
451 // Do not output Likes on requests for ActivityPub requests.
452 if (
453 function_exists( '\Activitypub\is_activitypub_request' )
454 && \Activitypub\is_activitypub_request()
455 ) {
456 return $content;
457 }
458
459 // Ensure we don't display like button on post excerpts that are hooked inside the post content
460 if ( in_array( 'the_excerpt', (array) $wp_current_filter, true ) &&
461 in_array( 'the_content', (array) $wp_current_filter, true ) ) {
462 return $content;
463 }
464
465 $blog_id = Jetpack_Options::get_option( 'id' );
466 $url = home_url();
467 $url_parts = wp_parse_url( $url );
468 $domain = $url_parts['host'];
469
470 // Make sure to include the `queuehandler` scripts before the iframe otherwise the script won't find the iframe.
471 if ( ! has_action( 'wp_footer', 'jetpack_likes_master_iframe' ) ) {
472 add_action( 'wp_footer', 'jetpack_likes_master_iframe', 21 );
473 }
474
475 /**
476 * If the same post appears more then once on a page the page goes crazy
477 * we need a slightly more unique id / name for the widget wrapper.
478 */
479 $uniqid = uniqid();
480 $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 );
481 $name = sprintf( 'like-post-frame-%1$d-%2$d-%3$s', $blog_id, $post_id, $uniqid );
482 $wrapper = sprintf( 'like-post-wrapper-%1$d-%2$d-%3$s', $blog_id, $post_id, $uniqid );
483 $headline = sprintf(
484 /** This filter is already documented in modules/sharedaddy/sharing-service.php */
485 apply_filters( 'jetpack_sharing_headline_html', '<h3 class="sd-title">%s</h3>', esc_html__( 'Like this:', 'jetpack' ), 'likes' ),
486 esc_html__( 'Like this:', 'jetpack' )
487 );
488
489 $title = esc_html__( 'Like or Reblog', 'jetpack' );
490
491 /** This filter is documented in modules/likes/jetpack-likes-master-iframe.php */
492 $src = apply_filters( 'jetpack_likes_iframe_src', $src );
493
494 $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'>";
495 $html .= $headline;
496 require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-spinner.php';
497 $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>';
498 $html .= "<span class='sd-text-color'></span><a class='sd-link-color'></a>";
499 $html .= '</div>';
500
501 // Let's make sure that the script is enqueued.
502 wp_enqueue_script( 'jetpack_likes_queuehandler' );
503
504 return $content . $html;
505 }
506 }
507
508 /**
509 * Callback to get the value for the jetpack_likes_enabled field.
510 *
511 * Warning: this behavior is somewhat complicated!
512 * When the switch_like_status post_meta is unset, we follow the global setting in Sharing.
513 * When it is set to 0, we disable likes on the post, regardless of the global setting.
514 * When it is set to 1, we enable likes on the post, regardless of the global setting.
515 *
516 * @param array $post - post data we're checking.
517 *
518 * @return bool
519 */
520 function jetpack_post_likes_get_value( array $post ) {
521 if ( ! isset( $post['id'] ) ) {
522 return false;
523 }
524
525 $post_likes_switched = get_post_meta( $post['id'], 'switch_like_status', true );
526
527 /** This filter is documented in modules/jetpack-likes-settings.php */
528 $sitewide_likes_enabled = (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
529
530 // An empty string: post meta was not set, so go with the global setting.
531 if ( '' === $post_likes_switched ) {
532 return $sitewide_likes_enabled;
533 } elseif ( '0' === $post_likes_switched ) { // User overrode the global setting to disable likes.
534 return false;
535 } elseif ( '1' === $post_likes_switched ) { // User overrode the global setting to enable likes.
536 return true;
537 }
538 // No default fallback, let's stay explicit.
539 }
540
541 /**
542 * Callback to set switch_like_status post_meta when jetpack_likes_enabled is updated.
543 *
544 * Warning: this behavior is somewhat complicated!
545 * When the switch_like_status post_meta is unset, we follow the global setting in Sharing.
546 * When it is set to 0, we disable likes on the post, regardless of the global setting.
547 * When it is set to 1, we enable likes on the post, regardless of the global setting.
548 *
549 * @param bool $enable_post_likes - checks if post likes are enabled.
550 * @param object $post_object - object containing post data.
551 */
552 function jetpack_post_likes_update_value( $enable_post_likes, $post_object ) {
553 /** This filter is documented in modules/jetpack-likes-settings.php */
554 $sitewide_likes_enabled = (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
555
556 $should_switch_status = $enable_post_likes !== $sitewide_likes_enabled;
557
558 if ( $should_switch_status ) {
559 // Set the meta to 0 if the user wants to disable likes, 1 if user wants to enable.
560 $switch_like_status = ( $enable_post_likes ? 1 : 0 );
561 return update_post_meta( $post_object->ID, 'switch_like_status', $switch_like_status );
562 } else {
563 // Unset the meta otherwise.
564 return delete_post_meta( $post_object->ID, 'switch_like_status' );
565 }
566 }
567
568 /**
569 * Add Likes post_meta to the REST API Post response.
570 *
571 * @action rest_api_init
572 * @uses register_rest_field
573 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/
574 */
575 function jetpack_post_likes_register_rest_field() {
576 $post_types = get_post_types( array( 'public' => true ) );
577 foreach ( $post_types as $post_type ) {
578 register_rest_field(
579 $post_type,
580 'jetpack_likes_enabled',
581 array(
582 'get_callback' => 'jetpack_post_likes_get_value',
583 'update_callback' => 'jetpack_post_likes_update_value',
584 'schema' => array(
585 'description' => __( 'Are Likes enabled?', 'jetpack' ),
586 'type' => 'boolean',
587 ),
588 )
589 );
590
591 /**
592 * Ensures all public internal post-types support `likes`
593 * This feature support flag is used by the REST API and Gutenberg.
594 */
595 add_post_type_support( $post_type, 'jetpack-post-likes' );
596 }
597 }
598
599 // Add Likes post_meta to the REST API Post response.
600 add_action( 'rest_api_init', 'jetpack_post_likes_register_rest_field' );
601
602 // Some CPTs (e.g. Jetpack portfolios and testimonials) get registered with
603 // restapi_theme_init because they depend on theme support, so let's also hook to that.
604 add_action( 'restapi_theme_init', 'jetpack_post_likes_register_rest_field', 20 );
605
606 Jetpack_Likes::init();
607