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