Completed
Push — update/remove-disconnect-link ( 4b6a2c )
by
unknown
73:18 queued 63:47
created

modules/widgets/top-posts.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
	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
				'customize_selective_refresh' => true,
40
			)
41
		);
42
43
		$this->default_title =  __( 'Top Posts &amp; Pages', 'jetpack' );
44
45 View Code Duplication
		if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
46
			add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ) );
47
		}
48
49
		/**
50
		 * Add explanation about how the statistics are calculated.
51
		 *
52
		 * @module widgets
53
		 *
54
		 * @since 3.9.3
55
		 */
56
		add_action( 'jetpack_widget_top_posts_after_fields', array( $this, 'stats_explanation' ) );
57
	}
58
59
	function enqueue_style() {
60
		wp_register_style( 'jetpack-top-posts-widget', plugins_url( 'top-posts/style.css', __FILE__ ), array(), '20141013' );
61
		wp_enqueue_style( 'jetpack-top-posts-widget' );
62
	}
63
64
	function form( $instance ) {
65
		$instance = wp_parse_args( (array) $instance, $this->defaults() );
66
67
		$title = stripslashes( $instance['title'] );
68
69
		$count = isset( $instance['count'] ) ? (int) $instance['count'] : 10;
70
		if ( $count < 1 || 10 < $count ) {
71
			$count = 10;
72
		}
73
74
		$allowed_post_types = array_values( get_post_types( array( 'public' => true ) ) );
75
		$types = isset( $instance['types'] ) ? (array) $instance['types'] : array( 'post', 'page' );
76
77
		// 'likes' are not available in Jetpack
78
		$ordering = isset( $instance['ordering'] ) && 'likes' === $instance['ordering'] ? 'likes' : 'views';
79
80 View Code Duplication
		if ( isset( $instance['display'] ) && in_array( $instance['display'], array( 'grid', 'list', 'text'  ) ) ) {
81
			$display = $instance['display'];
82
		} else {
83
			$display = 'text';
84
		}
85
86
		?>
87
88
		<p>
89
			<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:', 'jetpack' ); ?></label>
90
			<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 ); ?>" />
91
		</p>
92
93
		<p>
94
			<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>
95
			<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" />
96
		</p>
97
98
		<?php if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) : ?>
99
		<p>
100
			<label><?php esc_html_e( 'Order Top Posts &amp; Pages By:', 'jetpack' ); ?></label>
101
			<ul>
102
				<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>
103
				<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>
104
			</ul>
105
		</p>
106
		<?php endif; ?>
107
108
		<p>
109
			<label for="<?php echo $this->get_field_id( 'types' ); ?>"><?php esc_html_e( 'Types of pages to display:', 'jetpack' ); ?></label>
110
			<ul>
111
				<?php foreach( $allowed_post_types as $type ) {
112
					// Get the Post Type name to display next to the checkbox
113
					$post_type_object = get_post_type_object( $type );
114
					$label = $post_type_object->labels->name;
115
116
					$checked = '';
117
					if ( in_array( $type, $types ) ) {
118
						$checked = 'checked="checked" ';
119
					} ?>
120
121
					<li><label>
122
						<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; ?>>
123
						<?php echo esc_html( $label ); ?>
124
					</label></li>
125
126
				<?php } // End foreach ?>
127
			</ul>
128
		</p>
129
130
		<p>
131
			<label><?php esc_html_e( 'Display as:', 'jetpack' ); ?></label>
132
			<ul>
133
				<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>
134
				<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>
135
				<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>
136
			</ul>
137
		</p><?php
138
139
		/**
140
		 * Fires after the fields are displayed in the Top Posts Widget settings in wp-admin.
141
		 *
142
		 * Allow adding extra content after the fields are displayed.
143
		 *
144
		 * @module widgets
145
		 *
146
		 * @since 3.9.3
147
		 *
148
		 * @param array $args {
149
		 *     @param array $instance The widget instance.
150
		 *     @param object $this The class object.
151
		 * }
152
		 */
153
		do_action( 'jetpack_widget_top_posts_after_fields', array( $instance, $this ) );
154
	}
155
156
	/**
157
	 * Explains how the statics are calculated.
158
	 */
159
	function stats_explanation() {
160
		?>
161
162
		<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><?php
163
	}
164
165
	function update( $new_instance, $old_instance ) {
166
		$instance = array();
167
		$instance['title'] = wp_kses( $new_instance['title'], array() );
168
		if ( $instance['title'] === $this->default_title ) {
169
			$instance['title'] = false; // Store as false in case of language change
170
		}
171
172
		$instance['count'] = (int) $new_instance['count'];
173
		if ( $instance['count'] < 1 || 10 < $instance['count'] ) {
174
			$instance['count'] = 10;
175
		}
176
177
		// 'likes' are not available in Jetpack
178
		$instance['ordering'] = isset( $new_instance['ordering'] ) && 'likes' == $new_instance['ordering'] ? 'likes' : 'views';
179
180
		$allowed_post_types = array_values( get_post_types( array( 'public' => true ) ) );
181
		$instance['types'] = $new_instance['types'];
182
		foreach( $new_instance['types'] as $key => $type ) {
183
			if ( ! in_array( $type, $allowed_post_types ) ) {
184
				unset( $new_instance['types'][ $key ] );
185
			}
186
		}
187
188 View Code Duplication
		if ( isset( $new_instance['display'] ) && in_array( $new_instance['display'], array( 'grid', 'list', 'text'  ) ) ) {
189
			$instance['display'] = $new_instance['display'];
190
		} else {
191
			$instance['display'] = 'text';
192
		}
193
194
		/**
195
		 * Filters Top Posts Widget settings before they're saved.
196
		 *
197
		 * @module widgets
198
		 *
199
		 * @since 3.9.3
200
		 *
201
		 * @param array $instance The santized widget instance. Only contains data processed by the current widget.
202
		 * @param array $new_instance The new widget instance before sanitization.
203
		 */
204
		$instance = apply_filters( 'jetpack_top_posts_saving', $instance, $new_instance );
205
206
		return $instance;
207
	}
208
209
	function widget( $args, $instance ) {
210
		/** This action is documented in modules/widgets/gravatar-profile.php */
211
		do_action( 'jetpack_stats_extra', 'widget_view', 'top_posts' );
212
213
		$instance = wp_parse_args( (array) $instance, $this->defaults() );
214
215
		$title = isset( $instance['title' ] ) ? $instance['title'] : false;
216
		if ( false === $title ) {
217
			$title = $this->default_title;
218
		}
219
		/** This filter is documented in core/src/wp-includes/default-widgets.php */
220
		$title = apply_filters( 'widget_title', $title );
221
222
		$count = isset( $instance['count'] ) ? (int) $instance['count'] : false;
223
		if ( $count < 1 || 10 < $count ) {
224
			$count = 10;
225
		}
226
		/**
227
		 * Control the number of displayed posts.
228
		 *
229
		 * @module widgets
230
		 *
231
		 * @since 3.3.0
232
		 *
233
		 * @param string $count Number of Posts displayed in the Top Posts widget. Default is 10.
234
		 */
235
		$count = apply_filters( 'jetpack_top_posts_widget_count', $count );
236
237
		$types = isset( $instance['types'] ) ? (array) $instance['types'] : array( 'post', 'page' );
238
239
		// 'likes' are not available in Jetpack
240
		$ordering = isset( $instance['ordering'] ) && 'likes' == $instance['ordering'] ? 'likes' : 'views';
241
242 View Code Duplication
		if ( isset( $instance['display'] ) && in_array( $instance['display'], array( 'grid', 'list', 'text'  ) ) ) {
243
			$display = $instance['display'];
244
		} else {
245
			$display = 'text';
246
		}
247
248
		if ( 'text' != $display ) {
249
			$get_image_options = array(
250
				'fallback_to_avatars' => true,
251
				/** This filter is documented in modules/stats.php */
252
				'gravatar_default' => apply_filters( 'jetpack_static_url', set_url_scheme( 'https://en.wordpress.com/i/logo/white-gray-80.png' ) ),
253
				'avatar_size' => 40,
254
			);
255
			if ( 'grid' == $display ) {
256
				$get_image_options['avatar_size'] = 200;
257
			}
258
			/**
259
			 * Top Posts Widget Image options.
260
			 *
261
			 * @module widgets
262
			 *
263
			 * @since 1.8.0
264
			 *
265
			 * @param array $get_image_options {
266
			 * Array of Image options.
267
			 * @type bool true Should we default to Gravatars when no image is found? Default is true.
268
			 * @type string $gravatar_default Default Image URL if no Gravatar is found.
269
			 * @type int $avatar_size Default Image size.
270
			 * }
271
			 */
272
			$get_image_options = apply_filters( 'jetpack_top_posts_widget_image_options', $get_image_options );
273
		}
274
275
		if ( function_exists( 'wpl_get_blogs_most_liked_posts' ) && 'likes' == $ordering ) {
276
			$posts = $this->get_by_likes( $count );
277
		} else {
278
			$posts = $this->get_by_views( $count, $args );
279
		}
280
281
		// Filter the returned posts. Remove all posts that do not match the chosen Post Types.
282
		if ( isset( $types ) ) {
283
			foreach ( $posts as $k => $post ) {
284
				if ( ! in_array( $post['post_type'], $types ) ) {
285
					unset( $posts[$k] );
286
				}
287
			}
288
		}
289
290
		if ( ! $posts ) {
291
			$posts = $this->get_fallback_posts();
292
		}
293
294
		echo $args['before_widget'];
295
		if ( ! empty( $title ) )
296
			echo $args['before_title'] . $title . $args['after_title'];
297
298
		if ( ! $posts ) {
299 View Code Duplication
			if ( current_user_can( 'edit_theme_options' ) ) {
300
				echo '<p>' . sprintf(
301
					__( 'There are no posts to display. <a href="%s" target="_blank">Want more traffic?</a>', 'jetpack' ),
302
					'https://jetpack.com/support/getting-more-views-and-traffic/'
303
				) . '</p>';
304
			}
305
306
			echo $args['after_widget'];
307
			return;
308
		}
309
310
		switch ( $display ) {
311
		case 'list' :
312
		case 'grid' :
313
			foreach ( $posts as &$post ) {
314
				$image = Jetpack_PostImages::get_image( $post['post_id'], array( 'fallback_to_avatars' => true, 'avatar_size' => (int) $get_image_options['avatar_size'] ) );
0 ignored issues
show
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...
315
				$post['image'] = $image['src'];
316
				if ( 'blavatar' != $image['from'] && 'gravatar' != $image['from'] ) {
317
					$size = (int) $get_image_options['avatar_size'];
318
					$post['image'] = jetpack_photon_url( $post['image'], array( 'resize' => "$size,$size" ) );
319
				}
320
			}
321
322
			unset( $post );
323
324
			if ( 'grid' == $display ) {
325
				echo "<div class='widgets-grid-layout no-grav'>\n";
326
				foreach ( $posts as $post ) :
327
				?>
328
					<div class="widget-grid-view-image">
329
						<?php
330
						/**
331
						 * Fires before each Top Post result, inside <li>.
332
						 *
333
						 * @module widgets
334
						 *
335
						 * @since 3.2.0
336
						 *
337
						 * @param string $post['post_id'] Post ID.
338
						 */
339
						do_action( 'jetpack_widget_top_posts_before_post', $post['post_id'] );
340
341
						/**
342
						 * Filter the permalink of items in the Top Posts widget.
343
						 *
344
						 * @module widgets
345
						 *
346
						 * @since 4.4.0
347
						 *
348
						 * @param string $post['permalink'] Post permalink.
349
						 * @param array  $post              Post array.
350
						 */
351
						$filtered_permalink = apply_filters( 'jetpack_top_posts_widget_permalink', $post['permalink'], $post );
352
353
						?>
354
						<a href="<?php echo esc_url( $filtered_permalink ); ?>" title="<?php echo esc_attr( wp_kses( $post['title'], array() ) ); ?>" class="bump-view" data-bump-view="tp">
355
							<?php $size = (int) $get_image_options['avatar_size']; ?>
356
							<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" />
357
						</a>
358
						<?php
359
						/**
360
						 * Fires after each Top Post result, inside <li>.
361
						 *
362
						 * @module widgets
363
						 *
364
						 * @since 3.2.0
365
						 *
366
						 * @param string $post['post_id'] Post ID.
367
						 */
368
						do_action( 'jetpack_widget_top_posts_after_post', $post['post_id'] );
369
						?>
370
					</div>
371
				<?php
372
				endforeach;
373
				echo "</div>\n";
374
			} else {
375
				echo "<ul class='widgets-list-layout no-grav'>\n";
376
				foreach ( $posts as $post ) :
377
				?>
378
					<li>
379
						<?php
380
						/** This action is documented in modules/widgets/top-posts.php */
381
						do_action( 'jetpack_widget_top_posts_before_post', $post['post_id'] );
382
383
						/** This filter is documented in modules/widgets/top-posts.php */
384
						$filtered_permalink = apply_filters( 'jetpack_top_posts_widget_permalink', $post['permalink'], $post );
385
						?>
386
						<a href="<?php echo esc_url( $filtered_permalink ); ?>" title="<?php echo esc_attr( wp_kses( $post['title'], array() ) ); ?>" class="bump-view" data-bump-view="tp">
387
							<?php $size = (int) $get_image_options['avatar_size']; ?>
388
							<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" />
389
						</a>
390
						<div class="widgets-list-layout-links">
391
							<a href="<?php echo esc_url( $filtered_permalink ); ?>" class="bump-view" data-bump-view="tp">
392
								<?php echo esc_html( wp_kses( $post['title'], array() ) ); ?>
393
							</a>
394
						</div>
395
						<?php
396
						/** This action is documented in modules/widgets/top-posts.php */
397
						do_action( 'jetpack_widget_top_posts_after_post', $post['post_id'] );
398
						?>
399
					</li>
400
				<?php
401
				endforeach;
402
				echo "</ul>\n";
403
			}
404
			break;
405
		default :
406
			echo '<ul>';
407
			foreach ( $posts as $post ) :
408
			?>
409
				<li>
410
					<?php
411
					/** This action is documented in modules/widgets/top-posts.php */
412
					do_action( 'jetpack_widget_top_posts_before_post', $post['post_id'] );
413
414
					/** This filter is documented in modules/widgets/top-posts.php */
415
					$filtered_permalink = apply_filters( 'jetpack_top_posts_widget_permalink', $post['permalink'], $post );
416
					?>
417
					<a href="<?php echo esc_url( $filtered_permalink ); ?>" class="bump-view" data-bump-view="tp">
418
						<?php echo esc_html( wp_kses( $post['title'], array() ) ); ?>
419
					</a>
420
					<?php
421
					/** This action is documented in modules/widgets/top-posts.php */
422
					do_action( 'jetpack_widget_top_posts_after_post', $post['post_id'] );
423
					?>
424
				</li>
425
			<?php
426
			endforeach;
427
			echo '</ul>';
428
		}
429
430
		echo $args['after_widget'];
431
	}
432
433
	public static function defaults() {
434
		return array(
435
			'title'    => esc_html__( 'Top Posts &amp; Pages', 'jetpack' ),
436
			'count'    => absint( 10 ),
437
			'types'    => array( 'post', 'page' ),
438
			'ordering' => 'views',
439
			'display'  => 'text',
440
		);
441
	}
442
443
	/*
444
	 * Get most liked posts
445
	 *
446
	 * ONLY TO BE USED IN WPCOM
447
	 */
448
	function get_by_likes( $count ) {
449
		$post_likes = wpl_get_blogs_most_liked_posts();
450
		if ( !$post_likes ) {
451
			return array();
452
		}
453
454
		return $this->get_posts( array_keys( $post_likes ), $count );
455
	}
456
457
	function get_by_views( $count, $args ) {
458
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
459
			global $wpdb;
460
461
			$post_views = wp_cache_get( "get_top_posts_$count", 'stats' );
462
			if ( false === $post_views ) {
463
				$post_views = array_shift( stats_get_daily_history( false, get_current_blog_id(), 'postviews', 'post_id', false, 2, '', $count * 2 + 10, true ) );
464
				unset( $post_views[0] );
465
				wp_cache_add( "get_top_posts_$count", $post_views, 'stats', 1200);
466
			}
467
468
			return $this->get_posts( array_keys( $post_views ), $count );
469
		}
470
471
		/**
472
		 * Filter the number of days used to calculate Top Posts for the Top Posts widget.
473
		 * We do not recommend accessing more than 10 days of results at one.
474
		 * When more than 10 days of results are accessed at once, results should be cached via the WordPress transients API.
475
		 * Querying for -1 days will give results for an infinite number of days.
476
		 *
477
		 * @module widgets
478
		 *
479
		 * @since 3.9.3
480
		 *
481
		 * @param int 2 Number of days. Default is 2.
482
		 * @param array $args The widget arguments.
483
		 */
484
		$days = (int) apply_filters( 'jetpack_top_posts_days', 2, $args );
485
486
		/** Handling situations where the number of days makes no sense - allows for unlimited days where $days = -1 */
487
		if ( 0 == $days || false == $days ) {
488
			$days = 2;
489
		}
490
491
		$post_view_posts = stats_get_csv( 'postviews', array( 'days' => absint( $days ), 'limit' => 11 ) );
492
		if ( ! $post_view_posts ) {
493
			return array();
494
		}
495
496
		$post_view_ids = array_filter( wp_list_pluck( $post_view_posts, 'post_id' ) );
497
		if ( ! $post_view_ids ) {
498
			return array();
499
		}
500
501
		return $this->get_posts( $post_view_ids, $count );
502
	}
503
504
	function get_fallback_posts() {
505
		if ( current_user_can( 'edit_theme_options' ) ) {
506
			return array();
507
		}
508
509
		$post_query = new WP_Query;
510
511
		$posts = $post_query->query( array(
512
			'posts_per_page' => 1,
513
			'post_status' => 'publish',
514
			'post_type' => array( 'post', 'page' ),
515
			'no_found_rows' => true,
516
		) );
517
518
		if ( ! $posts ) {
519
			return array();
520
		}
521
522
		$post = array_pop( $posts );
523
524
		return $this->get_posts( $post->ID, 1 );
525
	}
526
527
	function get_posts( $post_ids, $count ) {
528
		$counter = 0;
529
530
		$posts = array();
531
		foreach ( (array) $post_ids as $post_id ) {
532
			$post = get_post( $post_id );
533
534
			if ( ! $post ) {
535
				continue;
536
			}
537
538
			/**
539
			 * Attachment pages use the 'inherit' post status by default.
540
			 * To be able to remove attachment pages from private and password protect posts,
541
			 * we need to replace their post status by the parent post' status.
542
			 */
543 View Code Duplication
			if ( 'inherit' == $post->post_status && 'attachment' == $post->post_type ) {
544
				$post->post_status = get_post_status( $post_id );
545
			}
546
547
			// hide private and password protected posts
548
			if ( 'publish' != $post->post_status || ! empty( $post->post_password ) ) {
549
				continue;
550
			}
551
552
			// Both get HTML stripped etc on display
553
			if ( empty( $post->post_title ) ) {
554
				$title_source = $post->post_content;
555
				$title = wp_html_excerpt( $title_source, 50 );
556
				$title .= '&hellip;';
557
			} else {
558
				$title = $post->post_title;
559
			}
560
561
			$permalink = get_permalink( $post->ID );
562
563
			$post_type = $post->post_type;
564
565
			$posts[] = compact( 'title', 'permalink', 'post_id', 'post_type' );
566
			$counter++;
567
568
			if ( $counter == $count ) {
569
				break; // only need to load and show x number of likes
570
			}
571
		}
572
573
		/**
574
		 * Filter the Top Posts and Pages.
575
		 *
576
		 * @module widgets
577
		 *
578
		 * @since 3.0.0
579
		 *
580
		 * @param array $posts Array of the most popular posts.
581
		 * @param array $post_ids Array of Post IDs.
582
		 * @param string $count Number of Top Posts we want to display.
583
		 */
584
		return apply_filters( 'jetpack_widget_get_top_posts', $posts, $post_ids, $count );
585
	}
586
}
587
588
/**
589
 * Create a shortcode to display the widget anywhere.
590
 *
591
 * @since 3.9.2
592
 */
593
function jetpack_do_top_posts_widget( $instance ) {
594
	// Post Types can't be entered as an array in the shortcode parameters.
595
	if ( isset( $instance['types'] ) && is_array( $instance['types'] ) ) {
596
		$instance['types'] = implode( ',', $instance['types'] );
597
	}
598
599
	$instance = shortcode_atts(
600
		Jetpack_Top_Posts_Widget::defaults(),
601
		$instance,
602
		'jetpack_top_posts_widget'
603
	);
604
605
	// Add a class to allow styling
606
	$args = array(
607
		'before_widget' => sprintf( '<div class="%s">', 'jetpack_top_posts_widget' ),
608
	);
609
610
	ob_start();
611
	the_widget( 'Jetpack_Top_Posts_Widget', $instance, $args );
612
	$output = ob_get_clean();
613
614
	return $output;
615
}
616
add_shortcode( 'jetpack_top_posts_widget', 'jetpack_do_top_posts_widget' );
617