Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
24.28% covered (danger)
24.28%
42 / 173
14.29% covered (danger)
14.29%
4 / 28
CRAP
0.00% covered (danger)
0.00%
0 / 1
Comments
23.98% covered (danger)
23.98%
41 / 171
14.29% covered (danger)
14.29%
4 / 28
1433.90
0.00% covered (danger)
0.00%
0 / 1
 name
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 id_field
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 table_name
n/a
0 / 0
n/a
0 / 0
1
 table
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get_object_by_id
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 init_listeners
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
1 / 1
3
 handle_comment_contents_modification
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
20
 init_full_sync_listeners
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_whitelisted_comment_types
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 get_whitelisted_comment_types_sql
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 only_allow_white_listed_comment_types
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
 filter_blacklisted_post_types
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 only_allow_white_listed_comment_type_transitions
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 filter_jetpack_sync_before_enqueue_wp_insert_comment
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 is_comment_type_allowed
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 init_before_send
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 enqueue_full_sync_actions
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 estimate_full_sync_actions
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 get_where_sql
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 get_full_sync_actions
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 count_full_sync_actions
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 expand_wp_comment_status_change
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 expand_wp_insert_comment
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 filter_comment
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 is_whitelisted_comment_meta
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 filter_meta
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
30
 expand_comment_ids
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
2
 extract_comments_and_meta
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 get_next_chunk
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2/**
3 * Comments sync module.
4 *
5 * @package automattic/jetpack-sync
6 */
7
8namespace Automattic\Jetpack\Sync\Modules;
9
10use Automattic\Jetpack\Sync\Modules;
11use Automattic\Jetpack\Sync\Settings;
12
13if ( ! defined( 'ABSPATH' ) ) {
14    exit( 0 );
15}
16
17/**
18 * Class to handle sync for comments.
19 */
20class Comments extends Module {
21
22    /**
23     * Sync module name.
24     *
25     * @access public
26     *
27     * @return string
28     */
29    public function name() {
30        return 'comments';
31    }
32
33    /**
34     * The id field in the database.
35     *
36     * @access public
37     *
38     * @return string
39     */
40    public function id_field() {
41        return 'comment_ID';
42    }
43
44    /**
45     * The table name.
46     *
47     * @access public
48     *
49     * @return string
50     * @deprecated since 3.11.0 Use table() instead.
51     */
52    public function table_name() {
53        _deprecated_function( __METHOD__, '3.11.0', 'Automattic\\Jetpack\\Sync\\Comments->table' );
54        return 'comments';
55    }
56
57    /**
58     * The table in the database with the prefix.
59     *
60     * @access public
61     *
62     * @return string|bool
63     */
64    public function table() {
65        global $wpdb;
66        return $wpdb->comments;
67    }
68
69    /**
70     * Retrieve a comment by its ID.
71     *
72     * @access public
73     *
74     * @param string $object_type Type of the sync object.
75     * @param int    $id          ID of the sync object.
76     * @return \WP_Comment|bool Filtered \WP_Comment object, or false if the object is not a comment.
77     */
78    public function get_object_by_id( $object_type, $id ) {
79        $comment_id = (int) $id;
80        if ( 'comment' === $object_type ) {
81            $comment = get_comment( $comment_id );
82            if ( $comment ) {
83                return $this->filter_comment( $comment );
84            }
85        }
86
87        return false;
88    }
89
90    /**
91     * Initialize comments action listeners.
92     * Also responsible for initializing comment meta listeners.
93     *
94     * @access public
95     *
96     * @param callable $callable Action handler callable.
97     */
98    public function init_listeners( $callable ) {
99        add_action( 'wp_insert_comment', $callable, 10, 2 );
100        add_action( 'deleted_comment', $callable );
101        add_action( 'trashed_comment', $callable );
102        add_action( 'spammed_comment', $callable );
103        add_action( 'trashed_post_comments', $callable, 10, 2 );
104        add_action( 'untrash_post_comments', $callable );
105        add_action( 'comment_approved_to_unapproved', $callable );
106        add_action( 'comment_unapproved_to_approved', $callable );
107        add_action( 'jetpack_modified_comment_contents', $callable, 10, 2 );
108        add_action( 'untrashed_comment', $callable, 10, 2 );
109        add_action( 'unspammed_comment', $callable, 10, 2 );
110        add_filter( 'wp_update_comment_data', array( $this, 'handle_comment_contents_modification' ), 10, 3 );
111
112        // comment actions.
113        add_filter( 'jetpack_sync_before_enqueue_wp_insert_comment', array( $this, 'filter_jetpack_sync_before_enqueue_wp_insert_comment' ) );
114        add_filter( 'jetpack_sync_before_enqueue_deleted_comment', array( $this, 'only_allow_white_listed_comment_types' ) );
115        add_filter( 'jetpack_sync_before_enqueue_trashed_comment', array( $this, 'only_allow_white_listed_comment_types' ) );
116        add_filter( 'jetpack_sync_before_enqueue_untrashed_comment', array( $this, 'only_allow_white_listed_comment_types' ) );
117        add_filter( 'jetpack_sync_before_enqueue_spammed_comment', array( $this, 'only_allow_white_listed_comment_types' ) );
118        add_filter( 'jetpack_sync_before_enqueue_unspammed_comment', array( $this, 'only_allow_white_listed_comment_types' ) );
119
120        // comment status transitions.
121        add_filter( 'jetpack_sync_before_enqueue_comment_approved_to_unapproved', array( $this, 'only_allow_white_listed_comment_type_transitions' ) );
122        add_filter( 'jetpack_sync_before_enqueue_comment_unapproved_to_approved', array( $this, 'only_allow_white_listed_comment_type_transitions' ) );
123
124        // Post Actions.
125        add_filter( 'jetpack_sync_before_enqueue_trashed_post_comments', array( $this, 'filter_blacklisted_post_types' ) );
126        add_filter( 'jetpack_sync_before_enqueue_untrash_post_comments', array( $this, 'filter_blacklisted_post_types' ) );
127
128        /**
129         * Even though it's messy, we implement these hooks because
130         * the edit_comment hook doesn't include the data
131         * so this saves us a DB read for every comment event.
132         */
133        foreach ( $this->get_whitelisted_comment_types() as $comment_type ) {
134            foreach ( array( 'unapproved', 'approved' ) as $comment_status ) {
135                $comment_action_name = "comment_{$comment_status}_{$comment_type}";
136                add_action( $comment_action_name, $callable, 10, 2 );
137                add_filter(
138                    'jetpack_sync_before_enqueue_' . $comment_action_name,
139                    array(
140                        $this,
141                        'expand_wp_insert_comment',
142                    )
143                );
144            }
145        }
146
147        // Listen for meta changes.
148        $this->init_listeners_for_meta_type( 'comment', $callable );
149        $this->init_meta_whitelist_handler( 'comment', array( $this, 'filter_meta' ) );
150    }
151
152    /**
153     * Handler for any comment content updates.
154     *
155     * @access public
156     *
157     * @param array $new_comment              The new, processed comment data.
158     * @param array $old_comment              The old, unslashed comment data.
159     * @param array $new_comment_with_slashes The new, raw comment data.
160     * @return array The new, processed comment data.
161     */
162    public function handle_comment_contents_modification( $new_comment, $old_comment, $new_comment_with_slashes ) {
163        $changes        = array();
164        $content_fields = array(
165            'comment_author',
166            'comment_author_email',
167            'comment_author_url',
168            'comment_content',
169        );
170        foreach ( $content_fields as $field ) {
171            if ( $new_comment_with_slashes[ $field ] !== $old_comment[ $field ] ) {
172                $changes[ $field ] = array( $new_comment[ $field ], $old_comment[ $field ] );
173            }
174        }
175
176        if ( ! empty( $changes ) ) {
177            /**
178             * Signals to the sync listener that this comment's contents were modified and a sync action
179             * reflecting the change(s) to the content should be sent
180             *
181             * @since 1.6.3
182             * @since-jetpack 4.9.0
183             *
184             * @param int $new_comment['comment_ID'] ID of comment whose content was modified
185             * @param mixed $changes Array of changed comment fields with before and after values
186             */
187            do_action( 'jetpack_modified_comment_contents', $new_comment['comment_ID'], $changes );
188        }
189        return $new_comment;
190    }
191
192    /**
193     * Initialize comments action listeners for full sync.
194     *
195     * @access public
196     *
197     * @param callable $callable Action handler callable.
198     */
199    public function init_full_sync_listeners( $callable ) {
200        add_action( 'jetpack_full_sync_comments', $callable ); // Also send comments meta.
201    }
202
203    /**
204     * Gets a filtered list of comment types that sync can hook into.
205     *
206     * @access public
207     *
208     * @return array Defaults to [ '', 'trackback', 'pingback' ].
209     */
210    public function get_whitelisted_comment_types() {
211        /**
212         * Comment types present in this list will sync their status changes to WordPress.com.
213         *
214         * @since 1.6.3
215         * @since-jetpack 7.6.0
216         *
217         * @param array A list of comment types.
218         */
219        return apply_filters(
220            'jetpack_sync_whitelisted_comment_types',
221            array( '', 'comment', 'trackback', 'pingback', 'review' )
222        );
223    }
224
225    /**
226     * Returns escaped SQL for whitelisted comment types.
227     * Can be injected directly into a WHERE clause.
228     *
229     * @access public
230     *
231     * @return string SQL WHERE clause.
232     */
233    public function get_whitelisted_comment_types_sql() {
234        return 'comment_type IN (\'' . implode( '\', \'', array_map( 'esc_sql', $this->get_whitelisted_comment_types() ) ) . '\')';
235    }
236
237    /**
238     * Prevents any comment types that are not in the whitelist from being enqueued and sent to WordPress.com.
239     *
240     * @param array $args Arguments passed to wp_insert_comment, deleted_comment, spammed_comment, etc.
241     *
242     * @return bool or array $args Arguments passed to wp_insert_comment, deleted_comment, spammed_comment, etc.
243     */
244    public function only_allow_white_listed_comment_types( $args ) {
245        $comment = false;
246
247        if ( isset( $args[1] ) ) {
248            // comment object is available.
249            $comment = $args[1];
250        } elseif ( is_numeric( $args[0] ) ) {
251            // comment_id is available.
252            $comment = get_comment( $args[0] );
253        }
254
255        if (
256            isset( $comment->comment_type )
257            && ! in_array( $comment->comment_type, $this->get_whitelisted_comment_types(), true )
258        ) {
259            return false;
260        }
261
262        return $args;
263    }
264
265    /**
266     * Filter all blacklisted post types.
267     *
268     * @param array $args Hook arguments.
269     * @return array|false Hook arguments, or false if the post type is a blacklisted one.
270     */
271    public function filter_blacklisted_post_types( $args ) {
272        $post_id      = $args[0];
273        $posts_module = Modules::get_module( 'posts' );
274        '@phan-var Posts $posts_module';
275
276        if ( false !== $posts_module && ! $posts_module->is_post_type_allowed( $post_id ) ) {
277            return false;
278        }
279
280        return $args;
281    }
282
283    /**
284     * Prevents any comment types that are not in the whitelist from being enqueued and sent to WordPress.com.
285     *
286     * @param array $args Arguments passed to wp_{old_status}_to_{new_status}.
287     *
288     * @return bool or array $args Arguments passed to wp_{old_status}_to_{new_status}
289     */
290    public function only_allow_white_listed_comment_type_transitions( $args ) {
291        $comment = $args[0];
292
293        if ( ! in_array( $comment->comment_type, $this->get_whitelisted_comment_types(), true ) ) {
294            return false;
295        }
296
297        return $args;
298    }
299
300    /**
301     * Prevents any comment types that are not in the whitelist from being enqueued and sent to WordPress.com.
302     * Also expands comment data before being enqueued.
303     *
304     * @param array $args Arguments passed to wp_insert_comment.
305     *
306     * @return false or array $args Arguments passed to wp_insert_comment or false if the comment type is a blacklisted one.
307     */
308    public function filter_jetpack_sync_before_enqueue_wp_insert_comment( $args ) {
309        if ( false === $this->only_allow_white_listed_comment_types( $args ) ) {
310            return false;
311        }
312
313        return $this->expand_wp_insert_comment( $args );
314    }
315
316    /**
317     * Whether a comment type is allowed.
318     * A comment type is allowed if it's present in the comment type whitelist.
319     *
320     * @param int $comment_id ID of the comment.
321     * @return boolean Whether the comment type is allowed.
322     */
323    public function is_comment_type_allowed( $comment_id ) {
324        $comment = get_comment( $comment_id );
325
326        if ( isset( $comment->comment_type ) ) {
327            return in_array( $comment->comment_type, $this->get_whitelisted_comment_types(), true );
328        }
329        return false;
330    }
331
332    /**
333     * Initialize the module in the sender.
334     *
335     * @access public
336     */
337    public function init_before_send() {
338
339        // Full sync.
340        $sync_module = Modules::get_module( 'full-sync' );
341        if ( $sync_module instanceof Full_Sync_Immediately ) {
342            add_filter( 'jetpack_sync_before_send_jetpack_full_sync_comments', array( $this, 'extract_comments_and_meta' ) );
343        } else {
344            add_filter( 'jetpack_sync_before_send_jetpack_full_sync_comments', array( $this, 'expand_comment_ids' ) );
345        }
346    }
347
348    /**
349     * Enqueue the comments actions for full sync.
350     *
351     * @access public
352     *
353     * @param array   $config               Full sync configuration for this sync module.
354     * @param int     $max_items_to_enqueue Maximum number of items to enqueue.
355     * @param boolean $state                True if full sync has finished enqueueing this module, false otherwise.
356     * @return array Number of actions enqueued, and next module state.
357     */
358    public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $state ) {
359        global $wpdb;
360        return $this->enqueue_all_ids_as_action( 'jetpack_full_sync_comments', $wpdb->comments, 'comment_ID', $this->get_where_sql( $config ), $max_items_to_enqueue, $state );
361    }
362
363    /**
364     * Retrieve an estimated number of actions that will be enqueued.
365     *
366     * @access public
367     *
368     * @param array $config Full sync configuration for this sync module.
369     * @return int Number of items yet to be enqueued.
370     */
371    public function estimate_full_sync_actions( $config ) {
372        global $wpdb;
373
374        $query = "SELECT count(*) FROM $wpdb->comments";
375
376        $where_sql = $this->get_where_sql( $config );
377        if ( $where_sql ) {
378            $query .= ' WHERE ' . $where_sql;
379        }
380
381        // TODO: Call $wpdb->prepare on the following query.
382        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
383        $count = (int) $wpdb->get_var( $query );
384
385        return (int) ceil( $count / self::ARRAY_CHUNK_SIZE );
386    }
387
388    /**
389     * Retrieve the WHERE SQL clause based on the module config.
390     *
391     * @access public
392     *
393     * @param array $config Full sync configuration for this sync module.
394     * @return string WHERE SQL clause, or `null` if no comments are specified in the module config.
395     */
396    public function get_where_sql( $config ) {
397        $where_sql = $this->get_whitelisted_comment_types_sql();
398
399        if ( is_array( $config ) && ! empty( $config ) ) {
400            return 'comment_ID IN (' . implode( ',', array_map( 'intval', $config ) ) . ')';
401        }
402
403        return $where_sql;
404    }
405
406    /**
407     * Retrieve the actions that will be sent for this module during a full sync.
408     *
409     * @access public
410     *
411     * @return array Full sync actions of this module.
412     */
413    public function get_full_sync_actions() {
414        return array( 'jetpack_full_sync_comments' );
415    }
416
417    /**
418     * Count all the actions that are going to be sent.
419     *
420     * @access public
421     *
422     * @param array $action_names Names of all the actions that will be sent.
423     * @return int Number of actions.
424     */
425    public function count_full_sync_actions( $action_names ) {
426        return $this->count_actions( $action_names, array( 'jetpack_full_sync_comments' ) );
427    }
428
429    /**
430     * Expand the comment status change before the data is serialized and sent to the server.
431     *
432     * @access public
433     * @todo This is not used currently - let's implement it.
434     *
435     * @param array $args The hook parameters.
436     * @return array The expanded hook parameters.
437     */
438    public function expand_wp_comment_status_change( $args ) {
439        return array( $args[0], $this->filter_comment( $args[1] ) );
440    }
441
442    /**
443     * Expand the comment creation before the data is added to the Sync queue.
444     *
445     * @access public
446     *
447     * @param array $args The hook parameters.
448     * @return array The expanded hook parameters.
449     */
450    public function expand_wp_insert_comment( $args ) {
451        return array( $args[0], $this->filter_comment( $args[1] ) );
452    }
453
454    /**
455     * Filter a comment object to the fields we need.
456     *
457     * @access public
458     *
459     * @param \WP_Comment $comment The unfiltered comment object.
460     * @return \WP_Comment Filtered comment object.
461     */
462    public function filter_comment( $comment ) {
463        /**
464         * Filters whether to prevent sending comment data to .com
465         *
466         * Passing true to the filter will prevent the comment data from being sent
467         * to the WordPress.com.
468         * Instead we pass data that will still enable us to do a checksum against the
469         * Jetpacks data but will prevent us from displaying the data on in the API as well as
470         * other services.
471         *
472         * @since 1.6.3
473         * @since-jetpack 4.2.0
474         *
475         * @param boolean false prevent post data from bing synced to WordPress.com
476         * @param mixed $comment WP_COMMENT object
477         */
478        if ( apply_filters( 'jetpack_sync_prevent_sending_comment_data', false, $comment ) ) {
479            $blocked_comment                   = new \stdClass();
480            $blocked_comment->comment_ID       = $comment->comment_ID;
481            $blocked_comment->comment_date     = $comment->comment_date;
482            $blocked_comment->comment_date_gmt = $comment->comment_date_gmt;
483            $blocked_comment->comment_approved = 'jetpack_sync_blocked';
484            return $blocked_comment;
485        }
486
487        return $comment;
488    }
489
490    /**
491     * Whether a certain comment meta key is whitelisted for sync.
492     *
493     * @access public
494     *
495     * @param string $meta_key Comment meta key.
496     * @return boolean Whether the meta key is whitelisted.
497     */
498    public function is_whitelisted_comment_meta( $meta_key ) {
499        return in_array( $meta_key, Settings::get_setting( 'comment_meta_whitelist' ), true );
500    }
501
502    /**
503     * Handler for filtering out non-whitelisted comment meta.
504     *
505     * @access public
506     *
507     * @param array $args Hook args.
508     * @return array|boolean False if not whitelisted, the original hook args otherwise.
509     */
510    public function filter_meta( $args ) {
511        if ( ! is_array( $args ) || count( $args ) < 3 ) {
512            return false;
513        }
514        if ( $this->is_comment_type_allowed( $args[1] ) && $this->is_whitelisted_comment_meta( $args[2] ) ) {
515            return $args;
516        }
517
518        return false;
519    }
520
521    /**
522     * Expand the comment IDs to comment objects and meta before being serialized and sent to the server.
523     *
524     * @access public
525     *
526     * @param array $args The hook parameters.
527     * @return array The expanded hook parameters.
528     */
529    public function expand_comment_ids( $args ) {
530        list( $comment_ids, $previous_interval_end ) = $args;
531        $comments                                    = get_comments(
532            array(
533                'include_unapproved' => true,
534                'comment__in'        => $comment_ids,
535                'orderby'            => 'comment_ID',
536                'order'              => 'DESC',
537            )
538        );
539
540        return array(
541            $comments,
542            $this->get_metadata( $comment_ids, 'comment', Settings::get_setting( 'comment_meta_whitelist' ) ),
543            $previous_interval_end,
544        );
545    }
546
547    /**
548     * Expand the comment IDs to comment objects and meta before being serialized and sent to the server.
549     *
550     * @access public
551     *
552     * @param array $args The hook parameters.
553     * @return array The expanded hook parameters.
554     */
555    public function extract_comments_and_meta( $args ) {
556        list( $filtered_comments, $previous_end ) = $args;
557        return array(
558            $filtered_comments['objects'],
559            $filtered_comments['meta'],
560            $previous_end,
561        );
562    }
563
564    /**
565     * Given the Module Configuration and Status return the next chunk of items to send.
566     * This function also expands the posts and metadata and filters them based on the maximum size constraints.
567     *
568     * @param array $config This module Full Sync configuration.
569     * @param array $status This module Full Sync status.
570     * @param int   $chunk_size Chunk size.
571     *
572     * @return array
573     */
574    public function get_next_chunk( $config, $status, $chunk_size ) {
575
576        $comment_ids = parent::get_next_chunk( $config, $status, $chunk_size );
577        // If no comment IDs were fetched, return an empty array.
578        if ( empty( $comment_ids ) ) {
579            return array();
580        }
581        $comments = get_comments(
582            array(
583                'comment__in' => $comment_ids,
584                'orderby'     => 'comment_ID',
585                'order'       => 'DESC',
586            )
587        );
588        // If no comments were fetched, make sure to return the expected structure so that status is updated correctly.
589        if ( empty( $comments ) ) {
590            return array(
591                'object_ids' => $comment_ids,
592                'objects'    => array(),
593                'meta'       => array(),
594            );
595        }
596        // Get the comment IDs from the comments that were fetched.
597        $fetched_comment_ids = wp_list_pluck( $comments, 'comment_ID' );
598        $metadata            = $this->get_metadata( $fetched_comment_ids, 'comment', Settings::get_setting( 'comment_meta_whitelist' ) );
599
600        // Filter the comments and metadata based on the maximum size constraints.
601        list( $filtered_comment_ids, $filtered_comments, $filtered_comments_metadata ) = $this->filter_objects_and_metadata_by_size(
602            'comment',
603            $comments,
604            $metadata,
605            self::MAX_META_LENGTH, // Replace with appropriate comment meta length constant.
606            self::MAX_SIZE_FULL_SYNC
607        );
608
609        return array(
610            'object_ids' => $filtered_comment_ids,
611            'objects'    => $filtered_comments,
612            'meta'       => $filtered_comments_metadata,
613        );
614    }
615}