Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
9.41% covered (danger)
9.41%
8 / 85
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
Jetpack_Comment_Likes
10.26% covered (danger)
10.26%
8 / 78
0.00% covered (danger)
0.00%
0 / 9
553.91
0.00% covered (danger)
0.00%
0 / 1
 init
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 __construct
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
30
 admin_init
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 comment_likes_edit_column
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 enqueue_admin_styles_scripts
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 add_like_count_column
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 frontend_init
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 load_styles_register_scripts
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
 comment_likes
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
90
1<?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2/**
3 * Module Name: Comment Likes
4 * Module Description: Enable visitors to like individual comments and boost engagement.
5 * Sort Order: 39
6 * Recommendation Order: 17
7 * First Introduced: 5.1
8 * Requires Connection: Yes
9 * Auto Activate: No
10 * Module Tags: Social
11 * Additional Search Queries: like widget, like button, like, likes
12 *
13 * @package automattic/jetpack
14 */
15
16use Automattic\Jetpack\Assets;
17use Automattic\Jetpack\Sharing_Likes\Post_Likes_Switch;
18
19if ( ! defined( 'ABSPATH' ) ) {
20    exit( 0 );
21}
22
23Assets::add_resource_hint( '//widgets.wp.com', 'dns-prefetch' );
24
25require_once __DIR__ . '/likes/jetpack-likes-master-iframe.php';
26require_once __DIR__ . '/likes/jetpack-likes-settings.php';
27
28/**
29 * Jetpack Comment Like Class
30 */
31class Jetpack_Comment_Likes {
32
33    /**
34     * Jetpack_Likes_Settings object
35     *
36     * @var Jetpack_Likes_Settings
37     */
38    public $settings;
39
40    /**
41     * Blog ID
42     *
43     * @var int
44     */
45    public $blog_id;
46
47    /**
48     * Site home URL domain
49     *
50     * @var string
51     */
52    public $domain;
53
54    /**
55     * Initialize comment like module
56     */
57    public static function init() {
58        static $instance = null;
59
60        if ( ! $instance ) {
61            $instance = new Jetpack_Comment_Likes();
62        }
63
64        return $instance;
65    }
66
67    /**
68     * Construct comment like module.
69     */
70    private function __construct() {
71        $this->settings = new Jetpack_Likes_Settings();
72        $this->blog_id  = Jetpack_Options::get_option( 'id' );
73        $url_parts      = wp_parse_url( home_url() );
74
75        // Abort if domain can't be determined.
76        if ( ! $url_parts || ! isset( $url_parts['host'] ) ) {
77            return;
78        }
79        $this->domain = $url_parts['host'];
80
81        add_action( 'template_redirect', array( $this, 'frontend_init' ) );
82        add_action( 'admin_init', array( $this, 'admin_init' ) );
83
84        /*
85         * Comment likes are gated on the Likes settings, so when the Likes module is
86         * off this module still needs the per-post metabox that carries them.
87         */
88        if ( ! Jetpack::is_module_active( 'likes' ) ) {
89            if ( Jetpack::is_module_active( 'sharedaddy' ) ) {
90                add_filter( 'sharing_meta_box_title', array( $this->settings, 'add_likes_to_sharing_meta_box_title' ) );
91                add_action( 'start_sharing_meta_box_content', array( $this->settings, 'meta_box_content' ) );
92            } else {
93                add_action( 'admin_init', array( $this->settings, 'add_meta_box' ) );
94            }
95
96            add_action( 'save_post', array( $this->settings, 'meta_box_save' ) );
97            add_action( 'edit_attachment', array( $this->settings, 'meta_box_save' ) );
98        }
99    }
100
101    /**
102     * Initialize admin section
103     */
104    public function admin_init() {
105        add_filter( 'manage_edit-comments_columns', array( $this, 'add_like_count_column' ) );
106        add_action( 'manage_comments_custom_column', array( $this, 'comment_likes_edit_column' ), 10, 2 );
107        add_action( 'admin_print_styles-edit-comments.php', array( $this, 'enqueue_admin_styles_scripts' ) );
108    }
109
110    /**
111     * Displays number of comment likes in comment admin page.
112     *
113     * @param string $column_name name of the column.
114     * @param int    $comment_id ID of the comment.
115     */
116    public function comment_likes_edit_column( $column_name, $comment_id ) {
117        if ( 'comment_likes' !== $column_name ) {
118            return;
119        }
120
121        $permalink = get_permalink( get_the_ID() );
122        ?>
123        <a
124        data-comment-id="<?php echo absint( $comment_id ); ?>"
125        data-blog-id="<?php echo absint( $this->blog_id ); ?>"
126        class="comment-like-count"
127        id="comment-like-count-<?php echo absint( $comment_id ); ?>"
128        href="<?php echo esc_url( $permalink ); ?>#comment-<?php echo absint( $comment_id ); ?>"
129        >
130            <span class="like-count">0</span>
131        </a>
132        <?php
133    }
134
135    /**
136     * Enqueue admin style scripts.
137     */
138    public function enqueue_admin_styles_scripts() {
139        wp_enqueue_style( 'comment-like-count', plugins_url( 'comment-likes/admin-style.css', __FILE__ ), array(), JETPACK__VERSION );
140        wp_enqueue_script(
141            'comment-like-count',
142            Assets::get_file_url_for_environment(
143                '_inc/build/comment-likes/comment-like-count.min.js',
144                'modules/comment-likes/comment-like-count.js'
145            ),
146            array( 'jquery' ),
147            JETPACK__VERSION,
148            false
149        );
150    }
151
152    /**
153     * Adds like count column to admin page.
154     *
155     * @param array $columns column of admin table.
156     */
157    public function add_like_count_column( $columns ) {
158        $columns['comment_likes'] = '<span class="vers"></span>';
159        return $columns;
160    }
161
162    /**
163     * Initialize front end
164     */
165    public function frontend_init() {
166        if ( class_exists( Jetpack_AMP_Support::class ) && Jetpack_AMP_Support::is_amp_request() ) {
167            return;
168        }
169
170        add_action( 'wp_enqueue_scripts', array( $this, 'load_styles_register_scripts' ) );
171        add_filter( 'comment_text', array( $this, 'comment_likes' ), 10, 2 );
172    }
173
174    /**
175     * Load styling scripts
176     */
177    public function load_styles_register_scripts() {
178        if ( ! $this->settings->is_likes_visible() ) {
179            return;
180        }
181
182        if ( ! wp_style_is( 'open-sans', 'registered' ) ) {
183            wp_register_style( 'open-sans', 'https://fonts.googleapis.com/css?family=Open+Sans', array(), JETPACK__VERSION );
184        }
185        wp_enqueue_style( 'jetpack_likes', plugins_url( 'likes/style.css', __FILE__ ), array( 'open-sans' ), JETPACK__VERSION );
186        wp_enqueue_script( 'jetpack_likes_queuehandler', plugins_url( 'likes/queuehandler.js', __FILE__ ), array(), JETPACK__VERSION, true );
187    }
188
189    /**
190     * Display like count.
191     *
192     * @param string $content text content of the comment itself.
193     * @param object $comment comment object containing comment data.
194     */
195    public function comment_likes( $content, $comment = null ) {
196        if ( empty( $comment ) ) {
197            return $content;
198        }
199
200        if ( ! $this->settings->is_likes_visible() ) {
201            return $content;
202        }
203
204        $comment_id = get_comment_ID();
205        if ( empty( $comment_id ) && ! empty( $comment->comment_ID ) ) {
206            $comment_id = $comment->comment_ID;
207        }
208
209        if ( empty( $content ) || empty( $comment_id ) ) {
210            return $content;
211        }
212
213        if ( empty( $comment->comment_approved ) ) {
214            return $content;
215        }
216
217        // In case master iframe hasn't been loaded. This could be the case when Post Likes module is disabled,
218        // or on pages on which we have comments but post likes are disabled.
219        if ( false === has_action( 'wp_footer', 'jetpack_likes_master_iframe' ) ) {
220            add_action( 'wp_footer', 'jetpack_likes_master_iframe', 21 );
221        }
222
223        $uniqid = uniqid();
224
225        $src     = sprintf( 'https://widgets.wp.com/likes/#blog_id=%1$d&amp;comment_id=%2$d&amp;origin=%3$s&amp;obj_id=%1$d-%2$d-%4$s', $this->blog_id, $comment_id, $this->domain, $uniqid );
226        $name    = sprintf( 'like-comment-frame-%1$d-%2$d-%3$s', $this->blog_id, $comment_id, $uniqid );
227        $wrapper = sprintf( 'like-comment-wrapper-%1$d-%2$d-%3$s', $this->blog_id, $comment_id, $uniqid );
228
229        $html  = '';
230        $html .= "<div class='jetpack-comment-likes-widget-wrapper jetpack-likes-widget-unloaded' id='$wrapper' data-src='$src' data-name='$name'>";
231        $html .= "<div class='likes-widget-placeholder comment-likes-widget-placeholder comment-likes'><span class='loading'>" . esc_html__( 'Loading...', 'jetpack' ) . '</span></div>';
232        $html .= "<div class='comment-likes-widget jetpack-likes-widget comment-likes'><span class='comment-like-feedback'></span>";
233        $html .= "<span class='sd-text-color'></span><a class='sd-link-color'></a>";
234        $html .= '</div></div>';
235
236        /**
237         * Filters the Comment Likes button content.
238         *
239         * @module comment-likes
240         *
241         * @since 5.1.0
242         *
243         * @param string $html Comment Likes button content.
244         */
245        $like_button = apply_filters( 'comment_like_button', $html );
246
247        return $content . $like_button;
248    }
249}
250
251// Comment likes follow the per-post Likes switch, so the block editor needs it without the Likes module.
252Post_Likes_Switch::init();
253
254Jetpack_Comment_Likes::init();