PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 2.4.7
Jetpack – WP Security, Backup, Speed, & Growth v2.4.7
16.2-beta 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 All 501 releases
jetpack / modules / likes.php

likes.php in Jetpack – WP Security, Backup, Speed, & Growth 2.4.7, at modules/likes.php

1,140 lines 39.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Module Name: Likes
4 * Module Description: Likes are a way for people to show their appreciation for content you have written. It’s also a way for you to show the world how popular your content has become.
5 * First Introduced: 2.2
6 * Sort Order: 4
7 * Requires Connection: Yes
8 * Auto Activate: No
9 */
10 class Jetpack_Likes {
11 var $version = '20130620a';
12
13 public static function init() {
14 static $instance = NULL;
15
16 if ( ! $instance ) {
17 $instance = new Jetpack_Likes;
18 }
19
20 return $instance;
21 }
22
23 function __construct() {
24 $this->in_jetpack = ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? false : true;
25
26 add_action( 'init', array( &$this, 'action_init' ) );
27 add_action( 'admin_init', array( $this, 'admin_init' ) );
28
29 if ( $this->in_jetpack ) {
30 add_action( 'jetpack_activate_module_likes', array( $this, 'module_toggle' ) );
31 add_action( 'jetpack_deactivate_module_likes', array( $this, 'module_toggle' ) );
32
33 Jetpack::enable_module_configurable( __FILE__ );
34 Jetpack::module_configuration_load( __FILE__, array( $this, 'configuration_redirect' ) );
35
36 add_action('admin_print_scripts-settings_page_sharing', array( &$this, 'load_jp_css' ) );
37 add_filter( 'sharing_show_buttons_on_row_start', array( $this, 'configuration_target_area' ) );
38
39 $active = Jetpack::get_active_modules();
40
41 if ( ! in_array( 'sharedaddy', $active ) && ! in_array( 'publicize', $active ) ) {
42 add_action( 'admin_menu', array( $this, 'sharing_menu' ) ); // we don't have a sharing page yet
43 }
44
45 if ( in_array( 'publicize', $active ) && ! in_array( 'sharedaddy', $active ) ) {
46 add_action( 'pre_admin_screen_sharing', array( $this, 'sharing_block' ), 20 ); // we have a sharing page but not the global options area
47 add_action( 'pre_admin_screen_sharing', array( $this, 'updated_message' ), -10 );
48 }
49
50 if( ! in_array( 'sharedaddy', $active ) ) {
51 add_action( 'admin_init', array( $this, 'process_update_requests_if_sharedaddy_not_loaded' ) );
52 add_action( 'sharing_global_options', array( $this, 'admin_settings_showbuttonon_init' ), 19 );
53 add_action( 'sharing_admin_update', array( $this, 'admin_settings_showbuttonon_callback' ), 19 );
54 add_action( 'admin_init', array( $this, 'add_meta_box' ) );
55 } else {
56 add_filter( 'sharing_meta_box_title', array( $this, 'add_likes_to_sharing_meta_box_title' ) );
57 add_action( 'start_sharing_meta_box_content', array( $this, 'meta_box_content' ) );
58 }
59
60 Jetpack_Sync::sync_options( __FILE__, 'social_notifications_like' );
61
62 } else { // wpcom
63 add_action( 'admin_init', array( $this, 'add_meta_box' ) );
64 add_action( 'end_likes_meta_box_content', array( $this, 'sharing_meta_box_content' ) );
65 add_filter( 'likes_meta_box_title', array( $this, 'add_likes_to_sharing_meta_box_title' ) );
66 }
67
68 add_action( 'admin_init', array( $this, 'admin_discussion_likes_settings_init' ) ); // Likes notifications
69
70 add_action( 'admin_bar_menu', array( $this, 'admin_bar_likes' ), 60 );
71
72 add_action( 'save_post', array( $this, 'meta_box_save' ) );
73 add_action( 'sharing_global_options', array( $this, 'admin_settings_init' ), 20 );
74 add_action( 'sharing_admin_update', array( $this, 'admin_settings_callback' ), 20 );
75 }
76
77 function module_toggle() {
78 $jetpack = Jetpack::init();
79 $jetpack->sync->register( 'noop' );
80 }
81
82 /**
83 * Redirects to the likes section of the sharing page.
84 */
85 function configuration_redirect() {
86 wp_safe_redirect( admin_url( 'options-general.php?page=sharing#likes' ) );
87 die();
88 }
89
90 /**
91 * Loads Jetpack's CSS on the sharing page so we can use .jetpack-targetable
92 */
93 function load_jp_css() {
94 Jetpack::init()->admin_styles();
95 }
96
97 /**
98 * Adds in the jetpack-targetable class so when we visit sharing#likes our like settings get highlighted by a yellow box
99 * @param string $html row heading for the sharedaddy "which page" setting
100 * @return string html with the jetpack-targetable class and likes id. tbody gets closed after the like settings
101 */
102 function configuration_target_area( $html = '' ) {
103 $html = "<tbody id='likes' class='jetpack-targetable'>" . $html;
104 return $html;
105 }
106
107 /**
108 * Replaces the "Sharing" title for the post screen metabox with "Likes and Shares"
109 * @param string $title The current title of the metabox, not needed/used.
110 */
111 function add_likes_to_sharing_meta_box_title( $title ) {
112 return __( 'Likes and Shares', 'jetpack' );
113 }
114
115 /**
116 * Adds a metabox to the post screen if the sharing one doesn't currently exist.
117 */
118 function add_meta_box() {
119 if ( apply_filters( 'post_flair_disable', false ) )
120 return;
121
122 $post_types = get_post_types( array( 'public' => true ) );
123 $title = apply_filters( 'likes_meta_box_title', __( 'Likes', 'jetpack' ) );
124 foreach( $post_types as $post_type ) {
125 add_meta_box( 'likes_meta', $title, array( $this, 'meta_box_content' ), $post_type, 'advanced', 'high' );
126 }
127 }
128
129 function meta_box_save( $post_id ) {
130 if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
131 return $post_id;
132
133 // Record sharing disable. Only needs to be done for WPCOM
134 if ( ! $this->in_jetpack ) {
135 if ( isset( $_POST['post_type'] ) && ( 'post' == $_POST['post_type'] || 'page' == $_POST['post_type'] ) ) {
136 if ( isset( $_POST['wpl_sharing_status_hidden'] ) && !isset( $_POST['wpl_enable_post_sharing'] ) ) {
137 update_post_meta( $post_id, 'sharing_disabled', 1 );
138 } else {
139 delete_post_meta( $post_id, 'sharing_disabled' );
140 }
141 }
142 }
143
144 if ( empty( $_POST['wpl_like_status_hidden'] ) )
145 return $post_id;
146
147 if ( 'post' == $_POST['post_type'] ) {
148 if ( !current_user_can( 'edit_post', $post_id ) ) {
149 return $post_id;
150 }
151 }
152
153 // Record a change in like status for this post - only if it contradicts the
154 // site like setting.
155 if ( ( $this->is_enabled_sitewide() && empty( $_POST['wpl_enable_post_likes'] ) ) || ( ! $this->is_enabled_sitewide() && !empty( $_POST['wpl_enable_post_likes'] ) ) ) {
156 update_post_meta( $post_id, 'switch_like_status', 1 );
157 //$g_gif = file_get_contents( 'http://stats.wordpress.com/g.gif?v=wpcom-no-pv&x_likes=switched_post_like_status' ); @todo stat
158 } else {
159 delete_post_meta( $post_id, 'switch_like_status' );
160 }
161
162 return $post_id;
163 }
164
165 /**
166 * Shows the likes option in the post screen metabox.
167 */
168 function meta_box_content( $post ) {
169 $post_id = ! empty( $post->ID ) ? (int) $post->ID : get_the_ID();
170 $checked = true;
171 $disabled = ! $this->is_enabled_sitewide();
172 $switched_status = get_post_meta( $post_id, 'switch_like_status', true );
173
174 if ( $disabled && empty( $switched_status ) || false == $disabled && !empty( $switched_status ) )
175 $checked = false;
176
177 do_action( 'start_likes_meta_box_content', $post );
178 ?>
179
180 <p>
181 <label for="wpl_enable_post_likes">
182 <input type="checkbox" name="wpl_enable_post_likes" id="wpl_enable_post_likes" value="1" <?php checked( $checked ); ?>>
183 <?php esc_html_e( 'Show likes.', 'jetpack' ); ?>
184 </label>
185 <input type="hidden" name="wpl_like_status_hidden" value="1" />
186 </p> <?php
187 do_action( 'end_likes_meta_box_content', $post );
188 }
189
190 /**
191 * WordPress.com: Metabox option for sharing (sharedaddy will handle this on the JP blog)
192 */
193 function sharing_meta_box_content( $post ) {
194 $post_id = ! empty( $post->ID ) ? (int) $post->ID : get_the_ID();
195 $disabled = get_post_meta( $post_id, 'sharing_disabled', true ); ?>
196 <p>
197 <label for="wpl_enable_post_sharing">
198 <input type="checkbox" name="wpl_enable_post_sharing" id="wpl_enable_post_sharing" value="1" <?php checked( !$disabled ); ?>>
199 <?php _e( 'Show sharing buttons.', 'jetpack' ); ?>
200 </label>
201 <input type="hidden" name="wpl_sharing_status_hidden" value="1" />
202 </p> <?php
203 }
204
205 /**
206 * Options to be added to the discussion page (see also admin_settings_init, etc below for Sharing settings page)
207 */
208
209 function admin_discussion_likes_settings_init() {
210 // Add a temporary section, until we can move the setting out of there and with the rest of the email notification settings
211 add_settings_section( 'likes-notifications', __( 'Likes Notifications', 'jetpack' ), array( $this, 'admin_discussion_likes_settings_section' ), 'discussion' );
212 add_settings_field( 'social-notifications', __( 'Email me whenever', 'jetpack' ), array( $this, 'admin_discussion_likes_settings_field' ), 'discussion', 'likes-notifications' );
213 // Register the setting
214 register_setting( 'discussion', 'social_notifications_like', array( $this, 'admin_discussion_likes_settings_validate' ) );
215 }
216
217 function admin_discussion_likes_settings_section() {
218 // Atypical usage here. We emit jquery to move likes notification checkbox to be with the rest of the email notification settings
219 ?>
220 <script type="text/javascript">
221 jQuery( function( $ ) {
222 var table = $( '#social_notifications_like' ).parents( 'table:first' ),
223 header = table.prevAll( 'h3:first' ),
224 newParent = $( '#moderation_notify' ).parent( 'label' ).parent();
225
226 if ( !table.size() || !header.size() || !newParent.size() ) {
227 return;
228 }
229
230 newParent.append( '<br/>' ).append( table.end().parent( 'label' ).siblings().andSelf() );
231 header.remove();
232 table.remove();
233 } );
234 </script>
235 <?php
236 }
237
238 function admin_likes_get_option( $option ) {
239 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
240 $option_setting = get_blog_option( get_current_blog_id(), $option );
241 } else {
242 $option_setting = get_option( $option );
243 }
244
245 return intval( 'on' == $option_setting );
246 }
247
248 function admin_discussion_likes_settings_field() {
249 $like = $this->admin_likes_get_option( 'social_notifications_like' );
250 ?>
251 <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>
252 <?php
253 }
254
255 function admin_discussion_likes_settings_validate( $input ) {
256 // If it's not set (was unchecked during form submission) or was set to off (during option update), return 'off'.
257 if ( !$input || 'off' == $input )
258 return 'off';
259
260 // Otherwise, return 'on'.
261 return 'on';
262 }
263
264 /**
265 * The actual options block to be inserted into the sharing page.
266 */
267 function admin_settings_init() { ?>
268 <tr>
269 <th scope="row">
270 <label><?php esc_html_e( 'WordPress.com Likes are', 'jetpack' ); ?></label>
271 </th>
272 <td>
273 <div>
274 <label>
275 <input type="radio" class="code" name="wpl_default" value="on" <?php checked( $this->is_enabled_sitewide(), true ); ?> />
276 <?php esc_html_e( 'On for all posts', 'jetpack' ); ?>
277 </label>
278 </div>
279 <div>
280 <label>
281 <input type="radio" class="code" name="wpl_default" value="off" <?php checked( $this->is_enabled_sitewide(), false ); ?> />
282 <?php esc_html_e( 'Turned on per post', 'jetpack' ); ?>
283 </label>
284 <div>
285 </td>
286 </tr> <?php /*
287 <tr>
288 <th scope="row">
289 <label><?php esc_html_e( 'Comment Likes', 'jetpack' ); ?></label>
290 </th>
291 <td>
292 <div>
293 <label>
294 <input type="checkbox" class="code" name="jetpack_comment_likes_enabled" value="1" <?php checked( $this->is_comments_enabled(), true ); ?> />
295 <?php esc_html_e( 'Allow people to like comments', 'jetpack' ); ?>
296 </label>
297 </div>
298 </td>
299 </tr> */ ?>
300 </tbody> <?php // closes the tbody attached to sharing_show_buttons_on_row_start... ?>
301 <?php }
302
303 /**
304 * If sharedaddy is not loaded, we don't have the "Show buttons on" yet, so we need to add that since it affects likes too.
305 */
306 function admin_settings_showbuttonon_init() { ?>
307 <?php echo apply_filters( 'sharing_show_buttons_on_row_start', '<tr valign="top">' ); ?>
308 <th scope="row"><label><?php _e( 'Show buttons on', 'jetpack' ); ?></label></th>
309 <td>
310 <?php
311 $br = false;
312 $shows = array_values( get_post_types( array( 'public' => true ) ) );
313 array_unshift( $shows, 'index' );
314 $global = $this->get_options();
315 foreach ( $shows as $show ) :
316 if ( 'index' == $show ) {
317 $label = __( 'Front Page, Archive Pages, and Search Results', 'jetpack' );
318 } else {
319 $post_type_object = get_post_type_object( $show );
320 $label = $post_type_object->labels->name;
321 }
322 ?>
323 <?php if ( $br ) echo '<br />'; ?><label><input type="checkbox"<?php checked( in_array( $show, $global['show'] ) ); ?> name="show[]" value="<?php echo esc_attr( $show ); ?>" /> <?php echo esc_html( $label ); ?></label>
324 <?php $br = true; endforeach; ?>
325 </td>
326 <?php echo apply_filters( 'sharing_show_buttons_on_row_end', '</tr>' ); ?>
327 <?php }
328
329
330 /**
331 * If sharedaddy is not loaded, we still need to save the the settings of the "Show buttons on" option.
332 */
333 function admin_settings_showbuttonon_callback() {
334 $options = get_option( 'sharing-options' );
335 if ( !is_array( $options ) )
336 $options = array();
337
338 $shows = array_values( get_post_types( array( 'public' => true ) ) );
339 $shows[] = 'index';
340 $data = $_POST;
341
342 if ( isset( $data['show'] ) ) {
343 if ( is_scalar( $data['show'] ) ) {
344 switch ( $data['show'] ) {
345 case 'posts' :
346 $data['show'] = array( 'post', 'page' );
347 break;
348 case 'index' :
349 $data['show'] = array( 'index' );
350 break;
351 case 'posts-index' :
352 $data['show'] = array( 'post', 'page', 'index' );
353 break;
354 }
355 }
356
357 if ( $data['show'] = array_intersect( $data['show'], $shows ) ) {
358 $options['global']['show'] = $data['show'];
359 }
360 } else {
361 $options['global']['show'] = array();
362 }
363
364 update_option( 'sharing-options', $options );
365 }
366
367 /**
368 * Adds the admin update hook so we can save settings even if Sharedaddy is not enabled.
369 */
370 function process_update_requests_if_sharedaddy_not_loaded() {
371 if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'sharing.php' || $_GET['page'] == 'sharing' ) ) {
372 if ( isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'sharing-options' ) ) {
373 do_action( 'sharing_admin_update' );
374 wp_safe_redirect( admin_url( 'options-general.php?page=sharing&update=saved' ) );
375 die();
376 }
377 }
378 }
379
380 /**
381 * Saves the setting in the database, bumps a stat on WordPress.com
382 */
383 function admin_settings_callback() {
384 // We're looking for these, and doing a dance to set some stats and save
385 // them together in array option.
386 $new_state = !empty( $_POST['wpl_default'] ) ? $_POST['wpl_default'] : 'on';
387 $db_state = $this->is_enabled_sitewide();
388
389 /** Default State *********************************************************/
390
391 // Checked (enabled)
392 switch( $new_state ) {
393 case 'off' :
394 if ( true == $db_state && ! $this->in_jetpack ) {
395 $g_gif = file_get_contents( 'http://stats.wordpress.com/g.gif?v=wpcom-no-pv&x_likes=disabled_likes' );
396 }
397 update_option( 'disabled_likes', 1 );
398 break;
399 case 'on' :
400 default:
401 if ( false == $db_state && ! $this->in_jetpack ) {
402 $g_gif = file_get_contents( 'http://stats.wordpress.com/g.gif?v=wpcom-no-pv&x_likes=reenabled_likes' );
403 }
404 delete_option( 'disabled_likes' );
405 break;
406 }
407
408
409 // comment setting
410 $new_comments_state = !empty( $_POST['jetpack_comment_likes_enabled'] ) ? $_POST['jetpack_comment_likes_enabled'] : false;
411 switch( (bool) $new_comments_state ) {
412 case true:
413 update_option( 'jetpack_comment_likes_enabled', 1 );
414 break;
415 case false:
416 default:
417 update_option( 'jetpack_comment_likes_enabled', 0 );
418 break;
419 }
420 }
421
422 /**
423 * Adds the 'sharing' menu to the settings menu.
424 * Only ran if sharedaddy and publicize are not already active.
425 */
426 function sharing_menu() {
427 add_submenu_page( 'options-general.php', esc_html__( 'Sharing Settings', 'jetpack' ), esc_html__( 'Sharing', 'jetpack' ), 'manage_options', 'sharing', array( $this, 'sharing_page' ) );
428 }
429
430 /**
431 * Provides a sharing page with the sharing_global_options hook
432 * so we can display the setting.
433 * Only ran if sharedaddy and publicize are not already active.
434 */
435 function sharing_page() {
436 $this->updated_message(); ?>
437 <div class="wrap">
438 <div class="icon32" id="icon-options-general"><br /></div>
439 <h2><?php esc_html_e( 'Sharing Settings', 'jetpack' ); ?></h2>
440 <?php do_action( 'pre_admin_screen_sharing' ) ?>
441 <?php $this->sharing_block(); ?>
442 </div> <?php
443 }
444
445 /**
446 * Returns the settings have been saved message.
447 */
448 function updated_message() {
449 if ( isset( $_GET['update'] ) && $_GET['update'] == 'saved' )
450 echo '<div class="updated"><p>' . esc_html__( 'Settings have been saved', 'jetpack' ) . '</p></div>';
451 }
452
453 /**
454 * Returns just the "sharing buttons" w/ like option block, so it can be inserted into different sharing page contexts
455 */
456 function sharing_block() { ?>
457 <h3><?php esc_html_e( 'Sharing Buttons', 'jetpack' ); ?></h3>
458 <form method="post" action="">
459 <table class="form-table">
460 <tbody>
461 <?php do_action( 'sharing_global_options' ); ?>
462 </tbody>
463 </table>
464
465 <p class="submit">
466 <input type="submit" name="submit" class="button-primary" value="<?php esc_attr_e( 'Save Changes', 'jetpack' ); ?>" />
467 </p>
468
469 <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'sharing-options' );?>" />
470 </form> <?php
471 }
472
473 function admin_init() {
474 add_filter( 'manage_posts_columns', array( $this, 'add_like_count_column' ) );
475 add_filter( 'manage_pages_columns', array( $this, 'add_like_count_column' ) );
476 add_action( 'manage_posts_custom_column', array( $this, 'likes_edit_column' ), 10, 2 );
477 add_action( 'manage_pages_custom_column', array( $this, 'likes_edit_column' ), 10, 2 );
478 add_action( 'admin_print_styles-edit.php', array( $this, 'load_admin_css' ) );
479 add_action( "admin_print_scripts-edit.php", array( $this, 'enqueue_admin_scripts' ) );
480 }
481
482 function action_init() {
483 if ( is_admin() )
484 return;
485
486 if ( ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) ||
487 ( defined( 'APP_REQUEST' ) && APP_REQUEST ) ||
488 ( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST ) ||
489 ( defined( 'COOKIE_AUTH_REQUEST' ) && COOKIE_AUTH_REQUEST ) ||
490 ( defined( 'JABBER_SERVER' ) && JABBER_SERVER ) )
491 return;
492
493 // Comment Likes widget has been disabled, pending performance improvements.
494 // add_filter( 'comment_text', array( &$this, 'comment_likes' ), 10, 2 );
495
496 if ( $this->in_jetpack ) {
497 add_filter( 'the_content', array( &$this, 'post_likes' ), 30, 1 );
498 wp_enqueue_script( 'postmessage', plugins_url( '_inc/postmessage.js', dirname(__FILE__) ), array( 'jquery' ), JETPACK__VERSION, false );
499 wp_enqueue_script( 'jquery_inview', plugins_url( '_inc/jquery.inview.js', dirname(__FILE__) ), array( 'jquery' ), JETPACK__VERSION, false );
500 wp_enqueue_script( 'jetpack_resize', plugins_url( '_inc/jquery.jetpack-resize.js' , dirname(__FILE__) ), array( 'jquery' ), JETPACK__VERSION, false );
501 wp_enqueue_style( 'jetpack_likes', plugins_url( 'likes/style.css', __FILE__ ), array(), JETPACK__VERSION );
502
503 } else {
504 add_filter( 'post_flair', array( &$this, 'post_likes' ), 30, 1 );
505 add_filter( 'post_flair_block_css', array( $this, 'post_flair_service_enabled_like' ) );
506
507 wp_enqueue_script( 'postmessage', '/wp-content/js/postmessage.js', array( 'jquery' ), JETPACK__VERSION, false );
508 wp_enqueue_script( 'jquery_inview', '/wp-content/js/jquery/jquery.inview.js', array( 'jquery' ), JETPACK__VERSION, false );
509 wp_enqueue_script( 'jetpack_resize', '/wp-content/js/jquery/jquery.jetpack-resize.js', array( 'jquery' ), JETPACK__VERSION, false );
510 wp_enqueue_style( 'jetpack_likes', plugins_url( 'jetpack-likes.css', __FILE__ ), array(), JETPACK__VERSION );
511 }
512 }
513
514 /**
515 * Load the CSS needed for the wp-admin area.
516 */
517 function load_admin_css() { ?>
518 <style type="text/css">
519 .fixed .column-likes { width: 5em; padding-top: 8px; text-align: center !important; }
520 .fixed .column-stats { width: 5em; }
521 .fixed .column-likes .post-com-count { background-image: none; }
522 .fixed .column-likes .comment-count { background-color: #888; }
523 .fixed .column-likes .comment-count:hover { background-color: #D54E21; }
524 .mp6 .fixed .column-likes .post-com-count::after { border: none !important; }
525 .mp6 .fixed .column-likes .comment-count { background-color: #bbb; }
526 .mp6 .fixed .column-likes .comment-count:hover { background-color: #2ea2cc; }
527 .mp6 .fixed .column-likes .vers img { display: none; }
528 .mp6 .fixed .column-likes .vers:before {font:20px/1 dashicons;content: '\f155';-webkit-font-smoothing:antialiased;}
529 </style> <?php
530 }
531
532 /**
533 * Load the JS required for loading the like counts.
534 */
535 function enqueue_admin_scripts() {
536 if ( empty( $_GET['post_type'] ) || 'post' == $_GET['post_type'] || 'page' == $_GET['post_type'] ) {
537 if ( $this->in_jetpack ) {
538 wp_enqueue_script( 'likes-post-count', plugins_url( 'modules/likes/post-count.js', dirname( __FILE__ ) ), array( 'jquery' ), JETPACK__VERSION );
539 wp_enqueue_script( 'likes-post-count-jetpack', plugins_url( 'modules/likes/post-count-jetpack.js', dirname( __FILE__ ) ), array( 'likes-post-count' ), JETPACK__VERSION );
540 } else {
541 wp_enqueue_script( 'jquery.wpcom-proxy-request', "/wp-content/js/jquery/jquery.wpcom-proxy-request.js", array('jquery'), NULL, true );
542 wp_enqueue_script( 'likes-post-count', plugins_url( 'likes/post-count.js', dirname( __FILE__ ) ), array( 'jquery' ), JETPACK__VERSION );
543 wp_enqueue_script( 'likes-post-count-wpcom', plugins_url( 'likes/post-count-wpcom.js', dirname( __FILE__ ) ), array( 'likes-post-count', 'jquery.wpcom-proxy-request' ), JETPACK__VERSION );
544 }
545 }
546 }
547
548 /**
549 * Add "Likes" column data to the post edit table in wp-admin.
550 *
551 * @param string $column_name
552 * @param int $post_id
553 */
554 function likes_edit_column( $column_name, $post_id ) {
555 if ( 'likes' == $column_name ) {
556
557 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
558 $blog_id = get_current_blog_id();
559 } else {
560 $jetpack = Jetpack::init();
561 $blog_id = $jetpack->get_option( 'id' );
562 }
563
564 $permalink = get_permalink( get_the_ID() ); ?>
565 <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; ?>">
566 <span class="comment-count">0</span>
567 </a>
568 <?php
569 }
570 }
571
572 /**
573 * Add a "Likes" column header to the post edit table in wp-admin.
574 *
575 * @param array $columns
576 * @return array
577 */
578 function add_like_count_column( $columns ) {
579 $date = $columns['date'];
580 unset( $columns['date'] );
581
582 $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>';
583 $columns['date'] = $date;
584
585 return $columns;
586 }
587
588 function post_likes( $content ) {
589 global $post;
590
591 if ( ! $this->is_likes_visible() )
592 return $content;
593
594 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
595 $blog_id = get_current_blog_id();
596 $bloginfo = get_blog_details( (int) $blog_id );
597 $domain = $bloginfo->domain;
598 } else {
599 $jetpack = Jetpack::init();
600 $blog_id = $jetpack->get_option( 'id' );
601 $url = home_url();
602 $url_parts = parse_url( $url );
603 $domain = $url_parts['host'];
604 }
605
606 add_filter( 'wp_footer', array( $this, 'likes_master' ) );
607
608 /**
609 * if the same post appears more then once on a page the page goes crazy
610 * we need a slightly more unique id / name for the widget wrapper.
611 */
612 $uniqid = uniqid();
613
614 $src = sprintf( '//widgets.wp.com/likes/#blog_id=%1$d&amp;post_id=%2$d&amp;origin=%3$s&amp;obj_id=%1$d-%2$d-%4$s', $blog_id, $post->ID, $domain, $uniqid );
615 $name = sprintf( 'like-post-frame-%1$d-%2$d-%3$s', $blog_id, $post->ID, $uniqid );
616 $wrapper = sprintf( 'like-post-wrapper-%1$d-%2$d-%3$s', $blog_id, $post->ID, $uniqid );
617
618 $html = "<div class='sharedaddy sd-block sd-like jetpack-likes-widget-wrapper jetpack-likes-widget-unloaded' id='$wrapper' data-src='$src' data-name='$name'><h3 class='sd-title'>" . esc_html__( 'Like this:', 'jetpack' ) . '</h3>';
619 $html .= "<div class='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>';
620 $html .= "<span class='sd-text-color'></span><a class='sd-link-color'></a>";
621 $html .= '</div>';
622
623 return $content . $html;
624 }
625
626 function comment_likes( $content, $comment = null ) {
627 if ( empty( $comment ) )
628 return $content;
629
630 if ( ! $this->is_comments_enabled() )
631 return $content;
632
633 $protocol = 'http';
634 if ( is_ssl() )
635 $protocol = 'https';
636
637 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
638 $blog_id = get_current_blog_id();
639 $bloginfo = get_blog_details( (int) $blog_id );
640 $domain = $bloginfo->domain;
641 } else {
642 $jetpack = Jetpack::init();
643 $blog_id = $jetpack->get_option( 'id' );
644 $url = home_url();
645 $url_parts = parse_url( $url );
646 $domain = $url_parts['host'];
647 }
648
649 add_filter( 'wp_footer', array( $this, 'likes_master' ) );
650
651 $src = sprintf( '%1$s://widgets.wp.com/likes/#blog_id=%2$d&amp;comment_id=%3$d&amp;origin=%1$s://%4$s', $protocol, $blog_id, $comment->comment_ID, $domain );
652 $name = sprintf( 'like-comment-frame-%1$d-%2$d', $blog_id, $comment->comment_ID );
653 $wrapper = sprintf( 'like-comment-wrapper-%1$d-%2$d', $blog_id, $comment->comment_ID );
654
655 $html = "<div><div class='jetpack-likes-widget-wrapper jetpack-likes-widget-unloaded' id='$wrapper'>";
656 $html .= "<iframe class='comment-likes-widget jetpack-likes-widget' name='$name' height='16px' width='100%' data='$src'></iframe>";
657 $html .= '</div></div>';
658 return $content . $html;
659 }
660
661 function post_flair_service_enabled_like( $classes ) {
662 $classes[] = 'sd-like-enabled';
663 return $classes;
664 }
665
666 function admin_bar_likes() {
667 global $wp_admin_bar, $post;
668
669 if ( ! $this->is_admin_bar_button_visible() ) {
670 return;
671 }
672
673 $protocol = 'http';
674 if ( is_ssl() )
675 $protocol = 'https';
676
677 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
678 $blog_id = get_current_blog_id();
679 $bloginfo = get_blog_details( (int) $blog_id );
680 $domain = $bloginfo->domain;
681 } else {
682 $jetpack = Jetpack::init();
683 $blog_id = $jetpack->get_option( 'id' );
684 $url = home_url();
685 $url_parts = parse_url( $url );
686 $domain = $url_parts['host'];
687 }
688
689 add_filter( 'wp_footer', array( $this, 'likes_master' ) );
690
691 $src = sprintf( '%1$s://widgets.wp.com/likes/#blog_id=%2$d&amp;post_id=%3$d&amp;origin=%1$s://%4$s', $protocol, $blog_id, $post->ID, $domain );
692
693 $html = "<iframe class='admin-bar-likes-widget jetpack-likes-widget' scrolling='no' frameBorder='0' name='admin-bar-likes-widget' src='$src'></iframe>";
694
695 $node = array(
696 'id' => 'admin-bar-likes-widget',
697 'meta' => array(
698 'html' => $html
699 )
700 );
701
702 $wp_admin_bar->add_node( $node );
703 }
704
705 function likes_master() {
706 $protocol = 'http';
707 if ( is_ssl() )
708 $protocol = 'https';
709
710 $locale = ( '' == get_locale() || 'en' == get_locale() ) ? '' : '&amp;lang=' . strtolower( substr( get_locale(), 0, 2 ) );
711 $src = sprintf( '%1$s://widgets.wp.com/likes/master.html?ver=%2$s#ver=%2$s%3$s&amp;mp6=%4$d', $protocol, $this->version, $locale, apply_filters( 'mp6_enabled', 0 ) );
712
713 $likersText = wp_kses( __( '<span>%d</span> bloggers like this:', 'jetpack' ), array( 'span' => array() ) );
714 ?>
715 <iframe src='<?php echo $src; ?>' scrolling='no' id='likes-master' name='likes-master' style='display:none;'></iframe>
716 <div id='likes-other-gravatars'><div class="likes-text"><?php echo $likersText; ?></div><ul class="wpl-avatars sd-like-gravatars"></ul></div>
717 <script type="text/javascript">
718 //<![CDATA[
719 var jetpackLikesWidgetQueue = [];
720 var jetpackLikesMasterReady = false;
721
722 function JetpackLikespostMessage( message, target ) {
723 if ( "string" === typeof message ){
724 try{
725 message = JSON.parse( message );
726 }
727 catch(e) {
728 return;
729 }
730 }
731
732 pm( {
733 target: target,
734 type: 'likesMessage',
735 data: message,
736 origin: '*'
737 } );
738 }
739
740 function JetpackLikesMessageListener( event ) {
741 if ( "undefined" == typeof event.event )
742 return;
743
744 if ( 'masterReady' == event.event ) {
745 jQuery( document ).ready( function() {
746 jetpackLikesMasterReady = true;
747
748 var stylesData = {
749 event: 'injectStyles'
750 };
751
752 if ( jQuery( 'iframe.admin-bar-likes-widget' ).length > 0 ) {
753 JetpackLikespostMessage( { event: 'adminBarEnabled' }, window.frames[ 'likes-master' ] );
754
755 stylesData.adminBarStyles = {
756 background: jQuery( '#wpadminbar .quicklinks li#wp-admin-bar-wpl-like > a' ).css( 'background' )
757 };
758 }
759
760 if ( !window.addEventListener )
761 jQuery( '#wp-admin-bar-admin-bar-likes-widget' ).hide();
762
763 stylesData.textStyles = {
764 color: jQuery( '.sd-text-color').css( 'color' ),
765 fontFamily: jQuery( '.sd-text-color' ).css( 'font-family' ),
766 fontSize: jQuery( '.sd-text-color' ).css( 'font-size' ),
767 direction: jQuery( '.sd-text-color' ).css( 'direction' ),
768 fontWeight: jQuery( '.sd-text-color' ).css( 'font-weight' ),
769 fontStyle: jQuery( '.sd-text-color' ).css( 'font-style' ),
770 textDecoration: jQuery( '.sd-text-color' ).css('text-decoration')
771 };
772
773 stylesData.linkStyles = {
774 color: jQuery( '.sd-link-color' ).css('color'),
775 fontFamily: jQuery( '.sd-link-color' ).css('font-family'),
776 fontSize: jQuery( '.sd-link-color' ).css('font-size'),
777 textDecoration: jQuery( '.sd-link-color' ).css('text-decoration'),
778 fontWeight: jQuery( '.sd-link-color' ).css( 'font-weight' ),
779 fontStyle: jQuery( '.sd-link-color' ).css( 'font-style' )
780 };
781
782 JetpackLikespostMessage( stylesData, window.frames[ 'likes-master' ] );
783
784 var requests = [];
785 jQuery( '.jetpack-likes-widget-wrapper' ).each( function( i ) {
786 var regex = /like-(post|comment)-wrapper-(\d+)-(\d+)-(\w+)/;
787 var match = regex.exec( this.id );
788 if ( ! match || match.length != 5 )
789 return;
790
791 var info = {
792 blog_id: match[2],
793 width: this.width
794 };
795
796 if ( 'post' == match[1] ) {
797 info.post_id = match[3];
798 } else if ( 'comment' == match[1] ) {
799 info.comment_id = match[3];
800 }
801
802 info.obj_id = match[4];
803
804 requests.push( info );
805 });
806
807 JetpackLikespostMessage( { event: 'initialBatch', requests: requests }, window.frames['likes-master'] );
808
809 jQuery( document ).on( 'inview', 'div.jetpack-likes-widget-unloaded', function() {
810 jetpackLikesWidgetQueue.push( this.id );
811 });
812 });
813 }
814
815 if ( 'showLikeWidget' == event.event ) {
816 setTimeout( JetpackLikesWidgetQueueHandler, 10 );
817 jQuery( '#' + event.id + ' .post-likes-widget-placeholder' ).fadeOut( 'fast', function() {
818 jQuery( '#' + event.id + ' .post-likes-widget' ).fadeIn( 'fast', function() {
819 JetpackLikespostMessage( { event: 'likeWidgetDisplayed', blog_id: event.blog_id, post_id: event.post_id, obj_id: event.obj_id }, window.frames['likes-master'] );
820 });
821 });
822 }
823
824 if ( 'showOtherGravatars' == event.event ) {
825 var $container = jQuery( '#likes-other-gravatars' );
826 var $list = $container.find( 'ul' );
827
828 $container.hide();
829 $list.html( '' );
830
831 $container.find( '.likes-text span' ).text( event.total );
832
833 jQuery.each( event.likers, function( i, liker ) {
834 $list.append( '<li class="' + liker.css_class + '"><a href="' + liker.profile_URL + '" class="wpl-liker" rel="nofollow" target="_parent"><img src="' + liker.avatar_URL + '" alt="' + liker.name + '" width="30" height="30" style="padding-right: 3px;" /></a></li>');
835 } );
836
837 var offset = jQuery( "[name='" + event.parent + "']" ).offset();
838
839 $container.css( 'left', offset.left + event.position.left - 10 + 'px' );
840 $container.css( 'top', offset.top + event.position.top - 33 + 'px' );
841
842 var rowLength = Math.floor( event.width / 37 );
843 var height = ( Math.ceil( event.likers.length / rowLength ) * 37 ) + 13;
844 if ( height > 204 ) {
845 height = 204;
846 }
847
848 $container.css( 'height', height + 'px' );
849 $container.css( 'width', rowLength * 37 - 7 + 'px' );
850
851 $list.css( 'width', rowLength * 37 + 'px' );
852
853 $container.fadeIn( 'slow' );
854
855 var scrollbarWidth = $list[0].offsetWidth - $list[0].clientWidth;
856 if ( scrollbarWidth > 0 ) {
857 $container.width( $container.width() + scrollbarWidth );
858 $list.width( $list.width() + scrollbarWidth );
859 }
860 }
861 }
862
863 pm.bind( 'likesMessage', function(e) { JetpackLikesMessageListener(e); } );
864
865 jQuery( document ).click( function( e ) {
866 var $container = jQuery( '#likes-other-gravatars' );
867
868 if ( $container.has( e.target ).length === 0 ) {
869 $container.fadeOut( 'slow' );
870 }
871 });
872
873 function JetpackLikesWidgetQueueHandler() {
874 var wrapperID;
875 if ( ! jetpackLikesMasterReady ) {
876 setTimeout( JetpackLikesWidgetQueueHandler, 500 );
877 return;
878 }
879
880 if ( jetpackLikesWidgetQueue.length > 0 ) {
881 // We may have a widget that needs creating now
882 var found = false;
883 while( jetpackLikesWidgetQueue.length > 0 ) {
884 // Grab the first member of the queue that isn't already loading.
885 wrapperID = jetpackLikesWidgetQueue.splice( 0, 1 )[0];
886 if ( jQuery( '#' + wrapperID ).hasClass( 'jetpack-likes-widget-unloaded' ) ) {
887 found = true;
888 break;
889 }
890 }
891 if ( ! found ) {
892 setTimeout( JetpackLikesWidgetQueueHandler, 500 );
893 return;
894 }
895 } else if ( jQuery( 'div.jetpack-likes-widget-unloaded' ).length > 0 ) {
896 // Get the next unloaded widget
897 wrapperID = jQuery( 'div.jetpack-likes-widget-unloaded' ).first()[0].id;
898 if ( ! wrapperID ) {
899 // Everything is currently loaded
900 setTimeout( JetpackLikesWidgetQueueHandler, 500 );
901 return;
902 }
903 }
904
905 var $wrapper = jQuery( '#' + wrapperID );
906 $wrapper.find( 'iframe' ).remove();
907
908 if ( $wrapper.hasClass( 'slim-likes-widget' ) ) {
909 $wrapper.find( '.post-likes-widget-placeholder' ).after( "<iframe class='post-likes-widget jetpack-likes-widget' name='" + $wrapper.data( 'name' ) + "' height='22px' width='68px' frameBorder='0' scrolling='no' src='" + $wrapper.data( 'src' ) + "'></iframe>" );
910 } else {
911 $wrapper.find( '.post-likes-widget-placeholder' ).after( "<iframe class='post-likes-widget jetpack-likes-widget' name='" + $wrapper.data( 'name' ) + "' height='55px' width='100%' frameBorder='0' src='" + $wrapper.data( 'src' ) + "'></iframe>" );
912 }
913
914 $wrapper.removeClass( 'jetpack-likes-widget-unloaded' ).addClass( 'jetpack-likes-widget-loading' );
915
916 $wrapper.find( 'iframe' ).load( function( e ) {
917 var $iframe = jQuery( e.target );
918 $wrapper.removeClass( 'jetpack-likes-widget-loading' ).addClass( 'jetpack-likes-widget-loaded' );
919
920 JetpackLikespostMessage( { event: 'loadLikeWidget', name: $iframe.attr( 'name' ), width: $iframe.width() }, window.frames[ 'likes-master' ] );
921
922 if ( $wrapper.hasClass( 'slim-likes-widget' ) ) {
923 $wrapper.find( 'iframe' ).Jetpack( 'resizeable' );
924 }
925 });
926 setTimeout( JetpackLikesWidgetQueueHandler, 250 );
927 }
928 JetpackLikesWidgetQueueHandler();
929 //]]>
930 </script>
931 <?php
932 }
933
934 /**
935 * Get the 'disabled_likes' option from the DB of the current blog.
936 *
937 * @return array
938 */
939 function get_options() {
940 $setting = array();
941 $setting['disabled'] = get_option( 'disabled_likes' );
942 $sharing = get_option( 'sharing-options' );
943
944 // Default visibility settings
945 if ( ! isset( $sharing['global']['show'] ) ) {
946 $sharing['global']['show'] = array( 'post', 'page' );
947
948 // Scalar check
949 } elseif ( is_scalar( $sharing['global']['show'] ) ) {
950 switch ( $sharing['global']['show'] ) {
951 case 'posts' :
952 $sharing['global']['show'] = array( 'post', 'page' );
953 break;
954 case 'index' :
955 $sharing['global']['show'] = array( 'index' );
956 break;
957 case 'posts-index' :
958 $sharing['global']['show'] = array( 'post', 'page', 'index' );
959 break;
960 }
961 }
962
963 // Ensure it's always an array (even if not previously empty or scalar)
964 $setting['show'] = !empty( $sharing['global']['show'] ) ? (array) $sharing['global']['show'] : array();
965
966 return apply_filters( 'wpl_get_options', $setting );
967 }
968
969 /** _is_ functions ************************************************************/
970
971 /**
972 * Are likes visible in this context?
973 *
974 * Some of this code was taken and modified from sharing_display() to ensure
975 * similar logic and filters apply here, too.
976 */
977 function is_likes_visible() {
978
979 global $wp_current_filter; // Used to check 'get_the_excerpt' filter
980 global $post; // Used to apply 'sharing_show' filter
981
982 // Never show on feeds or previews
983 if ( is_feed() || is_preview() || is_comments_popup() ) {
984 $enabled = false;
985
986 // Not a feed or preview, so what is it?
987 } else {
988
989 if ( in_the_loop() ) {
990 // If in the loop, check if the current post is likeable
991 $enabled = $this->is_post_likeable();
992 } else {
993 // Otherwise, check and see if likes are enabled sitewide
994 $enabled = $this->is_enabled_sitewide();
995 }
996
997 if ( post_password_required() )
998 $enabled = false;
999
1000 /** Other Checks ******************************************************/
1001
1002 // Do not show on excerpts
1003 if ( in_array( 'get_the_excerpt', (array) $wp_current_filter ) ) {
1004 $enabled = false;
1005
1006 // Sharing Setting Overrides ****************************************
1007 } else {
1008 // Single post
1009 if ( is_singular( 'post' ) ) {
1010 if ( ! $this->is_single_post_enabled() ) {
1011 $enabled = false;
1012 }
1013
1014 // Single page
1015 } elseif ( is_page() ) {
1016 if ( ! $this->is_single_page_enabled() ) {
1017 $enabled = false;
1018 }
1019
1020 // Attachment
1021 } elseif ( is_attachment() ) {
1022 if ( ! $this->is_attachment_enabled() ) {
1023 $enabled = false;
1024 }
1025
1026 // All other loops
1027 } elseif ( ! $this->is_index_enabled() ) {
1028 $enabled = false;
1029 }
1030 }
1031 }
1032
1033 // Run through the sharing filters
1034 $enabled = apply_filters( 'sharing_show', $enabled, $post );
1035
1036 return (bool) apply_filters( 'wpl_is_likes_visible', $enabled );
1037 }
1038
1039 /**
1040 * Returns the current state of the "WordPress.com Likes are" option.
1041 * @return boolean true if enabled sitewide, false if not
1042 */
1043 function is_enabled_sitewide() {
1044 return (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
1045 }
1046
1047 /**
1048 * Returns if comment likes are enabled. Defaults to 'on'
1049 * @todo decide what the default should be
1050 * @return boolean true if we should show comment likes, false if not
1051 */
1052 function is_comments_enabled() {
1053 return (bool) apply_filters( 'jetpack_comment_likes_enabled', get_option( 'jetpack_comment_likes_enabled', true ) );
1054 }
1055
1056 function is_admin_bar_button_visible() {
1057 global $wp_admin_bar;
1058
1059 if ( ! is_object( $wp_admin_bar ) )
1060 return false;
1061
1062 if ( ( ! is_singular( 'post' ) && ! is_attachment() && ! is_page() ) )
1063 return false;
1064
1065 if ( ! $this->is_likes_visible() )
1066 return false;
1067
1068 if ( ! $this->is_post_likeable() )
1069 return false;
1070
1071 return (bool) apply_filters( 'jetpack_admin_bar_likes_enabled', true );
1072 }
1073
1074 /**
1075 * Are likes enabled for this post?
1076 *
1077 * @param int $post_id
1078 * @retun bool
1079 */
1080 function is_post_likeable( $post_id = 0 ) {
1081 $post = get_post( $post_id );
1082 if ( !$post || is_wp_error( $post ) ) {
1083 return false;
1084 }
1085
1086 $sitewide_likes_enabled = (bool) Jetpack_Likes::is_enabled_sitewide();
1087 $post_likes_switched = (bool) get_post_meta( $post->ID, 'switch_like_status', true );
1088
1089 $post_likes_enabled = $sitewide_likes_enabled;
1090 if ( $post_likes_switched ) {
1091 $post_likes_enabled = ! $post_likes_enabled;
1092 }
1093
1094 return $post_likes_enabled;
1095 }
1096
1097 /**
1098 * Are Post Likes enabled on archive/front/search pages?
1099 *
1100 * @return bool
1101 */
1102 function is_index_enabled() {
1103 $options = $this->get_options();
1104 return (bool) apply_filters( 'wpl_is_index_disabled', (bool) in_array( 'index', $options['show'] ) );
1105 }
1106
1107 /**
1108 * Are Post Likes enabled on single posts?
1109 *
1110 * @return bool
1111 */
1112 function is_single_post_enabled() {
1113 $options = $this->get_options();
1114 return (bool) apply_filters( 'wpl_is_single_post_disabled', (bool) in_array( 'post', $options['show'] ) );
1115 }
1116
1117 /**
1118 * Are Post Likes enabled on single pages?
1119 *
1120 * @return bool
1121 */
1122 function is_single_page_enabled() {
1123 $options = $this->get_options();
1124 return (bool) apply_filters( 'wpl_is_single_page_disabled', (bool) in_array( 'page', $options['show'] ) );
1125 }
1126
1127 /**
1128 * Are Media Likes enabled on single pages?
1129 *
1130 * @return bool
1131 */
1132 function is_attachment_enabled() {
1133 $options = $this->get_options();
1134 return (bool) apply_filters( 'wpl_is_attachment_disabled', (bool) in_array( 'attachment', $options['show'] ) );
1135 }
1136
1137 }
1138
1139 Jetpack_Likes::init();
1140