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