Completed
Push — v2/videopress ( 00803f...fad9d3 )
by George
20:00 queued 09:44
created

Jetpack_Top_Posts_Widget   D

Complexity

Total Complexity 80

Size/Duplication

Total Lines 473
Duplicated Lines 6.55 %

Coupling/Cohesion

Components 1
Dependencies 1
Metric Value
wmc 80
lcom 1
cbo 1
dl 31
loc 473
rs 4.8717

9 Methods

Rating   Name   Duplication   Size   Complexity  
A enqueue_style() 0 4 1
A __construct() 16 16 2
F form() 5 80 15
D update() 5 31 10
F widget() 5 201 31
A get_by_likes() 0 8 2
C get_by_views() 0 45 8
A get_fallback_posts() 0 22 3
C get_posts() 0 48 8

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Jetpack_Top_Posts_Widget often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Jetpack_Top_Posts_Widget, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * Currently, this widget depends on the Stats Module. To not load this file
5
 * when the Stats Module is not active would potentially bypass Jetpack's
6
 * fatal error detection on module activation, so we always load this file.
7
 * Instead, we don't register the widget if the Stats Module isn't active.
8
 */
9
10
/**
11
 * Register the widget for use in Appearance -> Widgets
12
 */
13
add_action( 'widgets_init', 'jetpack_top_posts_widget_init' );
14
15
function jetpack_top_posts_widget_init() {
16
	// Currently, this widget depends on the Stats Module
17
	if (
18
		( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM )
19
	&&
20
		! function_exists( 'stats_get_csv' )
21
	) {
22
		return;
23
	}
24
25
	register_widget( 'Jetpack_Top_Posts_Widget' );
26
}
27
28
class Jetpack_Top_Posts_Widget extends WP_Widget {
29
	public $alt_option_name = 'widget_stats_topposts';
30
	public $default_title = '';
31
32 View Code Duplication
	function __construct() {
33
		parent::__construct(
34
			'top-posts',
35
			/** This filter is documented in modules/widgets/facebook-likebox.php */
36
			apply_filters( 'jetpack_widget_name', __( 'Top Posts &amp; Pages', 'jetpack' ) ),
37
			array(
38
				'description' => __( 'Shows your most viewed posts and pages.', 'jetpack' ),
39
			)
40
		);
41
42
		$this->default_title =  __( 'Top Posts &amp; Pages', 'jetpack' );
43
44
		if ( is_active_widget( false, false, $this->id_base ) ) {
45
			add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ) );
46
		}
47
	}
48
49
	function enqueue_style() {
50
		wp_register_style( 'jetpack-top-posts-widget', plugins_url( 'top-posts/style.css', __FILE__ ), array(), '20141013' );
51
		wp_enqueue_style( 'jetpack-top-posts-widget' );
52
	}
53
54
	function form( $instance ) {
55
		$title = isset( $instance['title' ] ) ? $instance['title'] : false;
56
		if ( false === $title ) {
57
			$title = $this->default_title;
58
		}
59
60
		$count = isset( $instance['count'] ) ? (int) $instance['count'] : 10;
61
		if ( $count < 1 || 10 < $count ) {
62
			$count = 10;
63
		}
64
65
		$allowed_post_types = array_values( get_post_types( array( 'public' => true ) ) );
66
		$types = isset( $instance['types'] ) ? (array) $instance['types'] : array( 'post', 'page' );
67
68
		// 'likes' are not available in Jetpack
69
		$ordering = isset( $instance['ordering'] ) && 'likes' === $instance['ordering'] ? 'likes' : 'views';
70
71 View Code Duplication
		if ( isset( $instance['display'] ) && in_array( $instance['display'], array( 'grid', 'list', 'text'  ) ) ) {
72
			$display = $instance['display'];
73
		} else {
74
			$display = 'text';
75
		}
76
77
		?>
78
79
		<p>
80
			<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:', 'jetpack' ); ?></label>
81
			<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
82
		</p>
83
84
		<p>
85
			<label for="<?php echo $this->get_field_id( 'count' ); ?>"><?php esc_html_e( 'Maximum number of posts to show (no more than 10):', 'jetpack' ); ?></label>
86
			<input id="<?php echo $this->get_field_id( 'count' ); ?>" name="<?php echo $this->get_field_name( 'count' ); ?>" type="number" value="<?php echo (int) $count; ?>" min="1" max="10" />
87
		</p>
88
89
		<?php if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) : ?>
90
		<p>
91
			<label><?php esc_html_e( 'Order Top Posts &amp; Pages By:', 'jetpack' ); ?></label>
92
			<ul>
93
				<li><label><input id="<?php echo $this->get_field_id( 'ordering' ); ?>-likes" name="<?php echo $this->get_field_name( 'ordering' ); ?>" type="radio" value="likes" <?php checked( 'likes', $ordering ); ?> /> <?php esc_html_e( 'Likes', 'jetpack' ); ?></label></li>
94
				<li><label><input id="<?php echo $this->get_field_id( 'ordering' ); ?>-views" name="<?php echo $this->get_field_name( 'ordering' ); ?>" type="radio" value="views" <?php checked( 'views', $ordering ); ?> /> <?php esc_html_e( 'Views', 'jetpack' ); ?></label></li>
95
			</ul>
96
		</p>
97
		<?php endif; ?>
98
99
		<p>
100
			<label for="<?php echo $this->get_field_id( 'types' ); ?>"><?php esc_html_e( 'Types of pages to display:', 'jetpack' ); ?></label>
101
			<ul>
102
				<?php foreach( $allowed_post_types as $type ) {
103
					// Get the Post Type name to display next to the checkbox
104
					$post_type_object = get_post_type_object( $type );
105
					$label = $post_type_object->labels->name;
106
107
					$checked = '';
108
					if ( in_array( $type, $types ) ) {
109
						$checked = 'checked="checked" ';
110
					} ?>
111
112
					<li><label>
113
						<input value="<?php echo esc_attr( $type ); ?>" name="<?php echo $this->get_field_name( 'types' ); ?>[]" id="<?php echo $this->get_field_id( 'types' ); ?>-<?php echo $type; ?>" type="checkbox" <?php echo $checked; ?>>
114
						<?php echo esc_html( $label ); ?>
115
					</label></li>
116
117
				<?php } // End foreach ?>
118
			</ul>
119
		</p>
120
121
		<p>
122
			<label><?php esc_html_e( 'Display as:', 'jetpack' ); ?></label>
123
			<ul>
124
				<li><label><input id="<?php echo $this->get_field_id( 'display' ); ?>-text" name="<?php echo $this->get_field_name( 'display' ); ?>" type="radio" value="text" <?php checked( 'text', $display ); ?> /> <?php esc_html_e( 'Text List', 'jetpack' ); ?></label></li>
125
				<li><label><input id="<?php echo $this->get_field_id( 'display' ); ?>-list" name="<?php echo $this->get_field_name( 'display' ); ?>" type="radio" value="list" <?php checked( 'list', $display ); ?> /> <?php esc_html_e( 'Image List', 'jetpack' ); ?></label></li>
126
				<li><label><input id="<?php echo $this->get_field_id( 'display' ); ?>-grid" name="<?php echo $this->get_field_name( 'display' ); ?>" type="radio" value="grid" <?php checked( 'grid', $display ); ?> /> <?php esc_html_e( 'Image Grid', 'jetpack' ); ?></label></li>
127
			</ul>
128
		</p>
129
130
		<p><?php esc_html_e( 'Top Posts &amp; Pages by views are calculated from 24-48 hours of stats. They take a while to change.', 'jetpack' ); ?></p>
131
132
		<?php
133
	}
134
135
	function update( $new_instance, $old_instance ) {
136
		$instance = array();
137
		$instance['title'] = wp_kses( $new_instance['title'], array() );
138
		if ( $instance['title'] === $this->default_title ) {
139
			$instance['title'] = false; // Store as false in case of language change
140
		}
141
142
		$instance['count'] = (int) $new_instance['count'];
143
		if ( $instance['count'] < 1 || 10 < $instance['count'] ) {
144
			$instance['count'] = 10;
145
		}
146
147
		// 'likes' are not available in Jetpack
148
		$instance['ordering'] = isset( $new_instance['ordering'] ) && 'likes' == $new_instance['ordering'] ? 'likes' : 'views';
149
150
		$allowed_post_types = array_values( get_post_types( array( 'public' => true ) ) );
151
		$instance['types'] = $new_instance['types'];
152
		foreach( $new_instance['types'] as $key => $type ) {
153
			if ( ! in_array( $type, $allowed_post_types ) ) {
154
				unset( $new_instance['types'][ $key ] );
155
			}
156
		}
157
158 View Code Duplication
		if ( isset( $new_instance['display'] ) && in_array( $new_instance['display'], array( 'grid', 'list', 'text'  ) ) ) {
159
			$instance['display'] = $new_instance['display'];
160
		} else {
161
			$instance['display'] = 'text';
162
		}
163
164
		return $instance;
165
	}
166
167
	function widget( $args, $instance ) {
168
		$title = isset( $instance['title' ] ) ? $instance['title'] : false;
169
		if ( false === $title ) {
170
			$title = $this->default_title;
171
		}
172
		/** This filter is documented in core/src/wp-includes/default-widgets.php */
173
		$title = apply_filters( 'widget_title', $title );
174
175
		$count = isset( $instance['count'] ) ? (int) $instance['count'] : false;
176
		if ( $count < 1 || 10 < $count ) {
177
			$count = 10;
178
		}
179
		/**
180
		 * Control the number of displayed posts.
181
		 *
182
		 * @module widgets
183
		 *
184
		 * @since 3.3.0
185
		 *
186
		 * @param string $count Number of Posts displayed in the Top Posts widget. Default is 10.
187
		 */
188
		$count = apply_filters( 'jetpack_top_posts_widget_count', $count );
189
190
		$types = isset( $instance['types'] ) ? (array) $instance['types'] : array( 'post', 'page' );
191
192
		// 'likes' are not available in Jetpack
193
		$ordering = isset( $instance['ordering'] ) && 'likes' == $instance['ordering'] ? 'likes' : 'views';
194
195 View Code Duplication
		if ( isset( $instance['display'] ) && in_array( $instance['display'], array( 'grid', 'list', 'text'  ) ) ) {
196
			$display = $instance['display'];
197
		} else {
198
			$display = 'text';
199
		}
200
201
		if ( 'text' != $display ) {
202
			$get_image_options = array(
203
				'fallback_to_avatars' => true,
204
				/** This filter is documented in modules/shortcodes/audio.php */
205
				'gravatar_default' => apply_filters( 'jetpack_static_url', set_url_scheme( 'http://en.wordpress.com/i/logo/white-gray-80.png' ) ),
206
			);
207
			if ( 'grid' == $display ) {
208
				$get_image_options['avatar_size'] = 200;
209
			} else {
210
				$get_image_options['avatar_size'] = 40;
211
			}
212
			/**
213
			 * Top Posts Widget Image options.
214
			 *
215
			 * @module widgets
216
			 *
217
			 * @since 1.8.0
218
			 *
219
			 * @param array $get_image_options {
220
			 * Array of Image options.
221
			 * @type bool true Should we default to Gravatars when no image is found? Default is true.
222
			 * @type string $gravatar_default Default Image URL if no Gravatar is found.
223
			 * @type int $avatar_size Default Image size.
224
			 * }
225
			 */
226
			$get_image_options = apply_filters( 'jetpack_top_posts_widget_image_options', $get_image_options );
227
		}
228
229
		if ( function_exists( 'wpl_get_blogs_most_liked_posts' ) && 'likes' == $ordering ) {
230
			$posts = $this->get_by_likes( $count );
231
		} else {
232
			$posts = $this->get_by_views( $count );
233
		}
234
235
		// Filter the returned posts. Remove all posts that do not match the chosen Post Types.
236
		if ( isset( $types ) ) {
237
			foreach ( $posts as $k => $post ) {
238
				if ( ! in_array( $post['post_type'], $types ) ) {
239
					unset( $posts[$k] );
240
				}
241
			}
242
		}
243
244
		if ( ! $posts ) {
245
			$posts = $this->get_fallback_posts();
246
		}
247
248
		echo $args['before_widget'];
249
		if ( ! empty( $title ) )
250
			echo $args['before_title'] . $title . $args['after_title'];
251
252
		if ( ! $posts ) {
253
			if ( current_user_can( 'edit_theme_options' ) ) {
254
				echo '<p>' . sprintf(
255
					__( 'There are no posts to display. <a href="%s">Want more traffic?</a>', 'jetpack' ),
256
					'http://en.support.wordpress.com/getting-more-site-traffic/'
257
				) . '</p>';
258
			}
259
260
			echo $args['after_widget'];
261
			return;
262
		}
263
264
		switch ( $display ) {
265
		case 'list' :
266
		case 'grid' :
267
			wp_enqueue_style( 'widget-grid-and-list' );
268
			foreach ( $posts as &$post ) {
269
				$image = Jetpack_PostImages::get_image( $post['post_id'], array( 'fallback_to_avatars' => true ) );
270
				$post['image'] = $image['src'];
271
				if ( 'blavatar' != $image['from'] && 'gravatar' != $image['from'] ) {
272
					$size = (int) $get_image_options['avatar_size'];
0 ignored issues
show
Bug introduced by
The variable $get_image_options does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
273
					$post['image'] = jetpack_photon_url( $post['image'], array( 'resize' => "$size,$size" ) );
274
				}
275
			}
276
277
			unset( $post );
278
279
			if ( 'grid' == $display ) {
280
				echo "<div class='widgets-grid-layout no-grav'>\n";
281
				foreach ( $posts as $post ) :
282
				?>
283
					<div class="widget-grid-view-image">
284
						<?php
285
						/**
286
						 * Fires before each Top Post result, inside <li>.
287
						 *
288
						 * @module widgets
289
						 *
290
						 * @since 3.2.0
291
						 *
292
						 * @param string $post['post_id'] Post ID.
293
						 */
294
						do_action( 'jetpack_widget_top_posts_before_post', $post['post_id'] );
295
						?>
296
						<a href="<?php echo esc_url( $post['permalink'] ); ?>" title="<?php echo esc_attr( wp_kses( $post['title'], array() ) ); ?>" class="bump-view" data-bump-view="tp">
297
							<?php $size = (int) $get_image_options['avatar_size']; ?>
298
							<img width="<?php echo absint( $size ); ?>" height="<?php echo absint( $size ); ?>" src="<?php echo esc_url( $post['image'] ); ?>" alt="<?php echo esc_attr( wp_kses( $post['title'], array() ) ); ?>" data-pin-nopin="true" />
299
						</a>
300
						<?php
301
						/**
302
						 * Fires after each Top Post result, inside <li>.
303
						 *
304
						 * @module widgets
305
						 *
306
						 * @since 3.2.0
307
						 *
308
						 * @param string $post['post_id'] Post ID.
309
						 */
310
						do_action( 'jetpack_widget_top_posts_after_post', $post['post_id'] );
311
						?>
312
					</div>
313
				<?php
314
				endforeach;
315
				echo "</div>\n";
316
			} else {
317
				echo "<ul class='widgets-list-layout no-grav'>\n";
318
				foreach ( $posts as $post ) :
319
				?>
320
					<li>
321
						<?php
322
						/** This action is documented in modules/widgets/top-posts.php */
323
						do_action( 'jetpack_widget_top_posts_before_post', $post['post_id'] );
324
						?>
325
						<a href="<?php echo esc_url( $post['permalink'] ); ?>" title="<?php echo esc_attr( wp_kses( $post['title'], array() ) ); ?>" class="bump-view" data-bump-view="tp">
326
							<?php $size = (int) $get_image_options['avatar_size']; ?>
327
							<img width="<?php echo absint( $size ); ?>" height="<?php echo absint( $size ); ?>" src="<?php echo esc_url( $post['image'] ); ?>" class='widgets-list-layout-blavatar' alt="<?php echo esc_attr( wp_kses( $post['title'], array() ) ); ?>" data-pin-nopin="true" />
328
						</a>
329
						<div class="widgets-list-layout-links">
330
							<a href="<?php echo esc_url( $post['permalink'] ); ?>" class="bump-view" data-bump-view="tp">
331
								<?php echo esc_html( wp_kses( $post['title'], array() ) ); ?>
332
							</a>
333
						</div>
334
						<?php
335
						/** This action is documented in modules/widgets/top-posts.php */
336
						do_action( 'jetpack_widget_top_posts_after_post', $post['post_id'] );
337
						?>
338
					</li>
339
				<?php
340
				endforeach;
341
				echo "</ul>\n";
342
			}
343
			break;
344
		default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
345
			echo '<ul>';
346
			foreach ( $posts as $post ) :
347
			?>
348
				<li>
349
					<?php
350
					/** This action is documented in modules/widgets/top-posts.php */
351
					do_action( 'jetpack_widget_top_posts_before_post', $post['post_id'] );
352
					?>
353
					<a href="<?php echo esc_url( $post['permalink'] ); ?>" class="bump-view" data-bump-view="tp">
354
						<?php echo esc_html( wp_kses( $post['title'], array() ) ); ?>
355
					</a>
356
					<?php
357
					/** This action is documented in modules/widgets/top-posts.php */
358
					do_action( 'jetpack_widget_top_posts_after_post', $post['post_id'] );
359
					?>
360
				</li>
361
			<?php
362
			endforeach;
363
			echo '</ul>';
364
		}
365
366
		echo $args['after_widget'];
367
	}
368
369
	/*
370
	 * Get most liked posts
371
	 *
372
	 * ONLY TO BE USED IN WPCOM
373
	 */
374
	function get_by_likes( $count ) {
375
		$post_likes = wpl_get_blogs_most_liked_posts();
376
		if ( !$post_likes ) {
377
			return array();
378
		}
379
380
		return $this->get_posts( array_keys( $post_likes ), $count );
381
	}
382
383
	function get_by_views( $count ) {
384
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
385
			global $wpdb;
386
387
			$post_views = wp_cache_get( "get_top_posts_$count", 'stats' );
388
			if ( false === $post_views ) {
389
				$post_views = array_shift( stats_get_daily_history( false, get_current_blog_id(), 'postviews', 'post_id', false, 2, '', $count * 2 + 10, true ) );
0 ignored issues
show
Bug introduced by
stats_get_daily_history(... $count * 2 + 10, true) cannot be passed to array_shift() as the parameter $array expects a reference.
Loading history...
390
				unset( $post_views[0] );
391
				wp_cache_add( "get_top_posts_$count", $post_views, 'stats', 1200);
392
			}
393
394
			return $this->get_posts( array_keys( $post_views ), $count );
395
		}
396
397
		/**
398
		 * Filter the number of days used to calculate Top Posts for the Top Posts widget.
399
		 *
400
		 * @module widgets
401
		 *
402
		 * @since 2.8.0
403
		 *
404
		 * @param int 2 Number of days. Default is 2.
405
		 */
406
		$days = (int) apply_filters( 'jetpack_top_posts_days', 2 );
407
408
		if ( $days < 1 ) {
409
			$days = 2;
410
		}
411
412
		if ( $days > 10 ) {
413
			$days = 10;
414
		}
415
416
		$post_view_posts = stats_get_csv( 'postviews', array( 'days' => absint( $days ), 'limit' => 11 ) );
417
		if ( ! $post_view_posts ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $post_view_posts of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
418
			return array();
419
		}
420
421
		$post_view_ids = array_filter( wp_list_pluck( $post_view_posts, 'post_id' ) );
422
		if ( ! $post_view_ids ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $post_view_ids of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
423
			return array();
424
		}
425
426
		return $this->get_posts( $post_view_ids, $count );
427
	}
428
429
	function get_fallback_posts() {
430
		if ( current_user_can( 'edit_theme_options' ) ) {
431
			return array();
432
		}
433
434
		$post_query = new WP_Query;
435
436
		$posts = $post_query->query( array(
437
			'posts_per_page' => 1,
438
			'post_status' => 'publish',
439
			'post_type' => array( 'post', 'page' ),
440
			'no_found_rows' => true,
441
		) );
442
443
		if ( ! $posts ) {
444
			return array();
445
		}
446
447
		$post = array_pop( $posts );
448
449
		return $this->get_posts( $post->ID, 1 );
450
	}
451
452
	function get_posts( $post_ids, $count ) {
453
		$counter = 0;
454
455
		$posts = array();
456
		foreach ( (array) $post_ids as $post_id ) {
457
			$post = get_post( $post_id );
458
459
			if ( ! $post )
460
				continue;
461
462
			// hide private and password protected posts
463
			if ( 'publish' != $post->post_status || ! empty( $post->post_password ) || empty( $post->ID ) )
464
				continue;
465
466
			// Both get HTML stripped etc on display
467
			if ( empty( $post->post_title ) ) {
468
				$title_source = $post->post_content;
469
				$title = wp_html_excerpt( $title_source, 50 );
470
				$title .= '&hellip;';
471
			} else {
472
				$title = $post->post_title;
473
			}
474
475
			$permalink = get_permalink( $post->ID );
476
477
			$post_type = $post->post_type;
478
479
			$posts[] = compact( 'title', 'permalink', 'post_id', 'post_type' );
480
			$counter++;
481
482
			if ( $counter == $count ) {
483
				break; // only need to load and show x number of likes
484
			}
485
		}
486
487
		/**
488
		 * Filter the Top Posts and Pages.
489
		 *
490
		 * @module widgets
491
		 *
492
		 * @since 3.0.0
493
		 *
494
		 * @param array $posts Array of the most popular posts.
495
		 * @param array $post_ids Array of Post IDs.
496
		 * @param string $count Number of Top Posts we want to display.
497
		 */
498
		return apply_filters( 'jetpack_widget_get_top_posts', $posts, $post_ids, $count );
499
	}
500
}
501