PluginProbe ʕ •ᴥ•ʔ
Post Views Counter / 1.4.8
Post Views Counter v1.4.8
1.7.13 1.7.12 1.7.11 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.2 1.3.2.1 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.7.0 1.7.1 1.7.10 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9
post-views-counter / includes / functions.php
post-views-counter / includes Last commit date
class-admin.php 1 year ago class-columns.php 1 year ago class-counter.php 1 year ago class-crawler-detect.php 1 year ago class-cron.php 1 year ago class-dashboard.php 1 year ago class-frontend.php 1 year ago class-functions.php 1 year ago class-query.php 1 year ago class-settings-api.php 1 year ago class-settings.php 1 year ago class-update.php 1 year ago class-widgets.php 1 year ago functions.php 1 year ago
functions.php
737 lines
1 <?php
2 /**
3 * Post Views Counter pluggable template functions
4 *
5 * Override any of those functions by copying it to your theme or replace it via plugin
6 *
7 * @author Digital Factory
8 * @package Post Views Counter
9 * @since 1.0.0
10 */
11 // exit if accessed directly
12 if ( ! defined( 'ABSPATH' ) )
13 exit;
14
15 /**
16 * Get post views for a post or array of posts.
17 *
18 * @global object $wpdb
19 *
20 * @param int|array $post_id
21 * @param string $period
22 *
23 * @return int
24 */
25 if ( ! function_exists( 'pvc_get_post_views' ) ) {
26 function pvc_get_post_views( $post_id = 0, $period = 'total' ) {
27 global $wpdb;
28
29 // sanitize period
30 $period = sanitize_key( $period );
31
32 if ( empty( $post_id ) )
33 $post_id = get_the_ID();
34
35 if ( is_array( $post_id ) ) {
36 $numbers = array_filter( array_unique( array_map( 'intval', $post_id ) ) );
37 $post_id = implode( ',', $numbers );
38 } else {
39 $post_id = (int) $post_id;
40 $numbers = [ $post_id ];
41 }
42
43 // set where clause
44 $where = [ 'type' => 'type = 4' ];
45
46 // update where clause
47 $where = apply_filters( 'pvc_get_post_views_period_where', $where, $period, $post_id );
48
49 // updated where clause
50 $_where = [];
51
52 // sanitize where clause
53 foreach ( $where as $index => $value ) {
54 if ( $index === 'type' || $index === 'content' )
55 $_where[$index] = preg_replace( '/[^0-9]/', '', $value );
56 elseif ( $index === 'period' ) {
57 $values = preg_match_all( '/\d+/', $value, $matches );
58
59 // any values?
60 if ( $values !== false && $values > 0 )
61 $_where['period'] = $matches[0];
62 }
63 }
64
65 // get current number of ids
66 $ids_count = count( $numbers );
67
68 $where_clause = '';
69
70 // validate where clause
71 foreach( $_where as $index => $value ) {
72 if ( $index === 'type' ) {
73 $where_clause .= ' AND type = %d';
74 $numbers[] = (int) $value;
75 } elseif ( $index === 'content' ) {
76 $where_clause .= ' AND content = %d';
77 $numbers[] = (int) $value;
78 } elseif ( $index === 'period' ) {
79 $nop = count( $_where['period'] );
80
81 if ( $nop === 1 ) {
82 $where_clause .= ' AND CAST( period AS SIGNED ) = %d';
83 $numbers[] = (int) $_where['period'][0];
84 } elseif ( $nop === 2 ) {
85 $where_clause .= ' AND CAST( period AS SIGNED ) <= %d AND CAST( period AS SIGNED ) >= %d';
86 $numbers[] = (int) $_where['period'][0];
87 $numbers[] = (int) $_where['period'][1];
88 }
89 }
90 }
91
92 // prepare query
93 $query = $wpdb->prepare( "SELECT SUM(count) AS views FROM " . $wpdb->prefix . "post_views WHERE id IN (" . implode( ',', array_fill( 0, $ids_count, '%d' ) ) . ")" . $where_clause, $numbers );
94
95 // calculate query hash
96 $query_hash = md5( $query );
97
98 // get cached data
99 $post_views = wp_cache_get( $query_hash, 'pvc-get_post_views' );
100
101 // cached data not found?
102 if ( $post_views === false ) {
103 // get post views
104 $post_views = (int) $wpdb->get_var( $query );
105
106 // set the cache expiration, 5 minutes by default
107 $expire = absint( apply_filters( 'pvc_object_cache_expire', 300 ) );
108
109 // add cached post views
110 wp_cache_add( $query_hash, $post_views, 'pvc-get_post_views', $expire );
111 }
112
113 return (int) apply_filters( 'pvc_get_post_views', $post_views, $post_id, $period );
114 }
115 }
116
117 /**
118 * Get views query.
119 *
120 * @global object $wpdb
121 *
122 * @param array $args
123 *
124 * @return int|array
125 */
126 if ( ! function_exists( 'pvc_get_views' ) ) {
127 function pvc_get_views( $args = [] ) {
128 global $wpdb;
129
130 $range = [];
131 $defaults = [
132 'fields' => 'views',
133 'post_id' => '',
134 'post_type' => '',
135 'views_query' => [
136 'year' => '',
137 'month' => '',
138 'week' => '',
139 'day' => '',
140 'after' => '', // string or array
141 'before' => '', // string or array
142 'inclusive' => true
143 ]
144 ];
145
146 // merge default options with new arguments
147 $args = array_merge( $defaults, $args );
148
149 // check views query
150 if ( ! is_array( $args['views_query'] ) )
151 $args['views_query'] = $defaults['views_query'];
152
153 // merge views query too
154 $args['views_query'] = array_merge( $defaults['views_query'], $args['views_query'] );
155
156 // filter arguments
157 $args = apply_filters( 'pvc_get_views_args', $args );
158
159 // check post types
160 if ( is_string( $args['post_type'] ) )
161 $args['post_type'] = [ $args['post_type'] ];
162 elseif ( ! is_array( $args['post_type'] ) )
163 $args['post_type'] = [];
164
165 // get number of post types
166 $post_types_count = count( $args['post_type'] );
167
168 // check post ids
169 if ( is_array( $args['post_id'] ) && ! empty( $args['post_id'] ) )
170 $args['post_id'] = array_filter( array_unique( array_map( 'intval', $args['post_id'] ) ) );
171 elseif ( is_string( $args['post_id'] ) || is_numeric( $args['post_id'] ) ) {
172 $post_id = (int) $args['post_id'];
173
174 if ( $post_id === 0 )
175 $args['post_id'] = [];
176 else
177 $args['post_id'] = [ $post_id ];
178 } else
179 $args['post_id'] = [];
180
181 // get number of post ids
182 $post_ids_count = count( $args['post_id'] );
183
184 // placeholder for empty query data
185 $query_data = [ 1 ];
186
187 // set query data
188 if ( $post_ids_count === 0 && $post_types_count === 0 )
189 $query_data = [ 1 ];
190 elseif ( $post_ids_count === 0 )
191 $query_data = array_merge( $query_data, array_values( $args['post_type'] ) );
192 elseif ( $post_types_count === 0 )
193 $query_data = array_merge( $query_data, array_values( $args['post_id'] ) );
194 else
195 $query_data = array_merge( $query_data, array_values( $args['post_id'] ), array_values( $args['post_type'] ) );
196
197 // check fields
198 if ( ! in_array( $args['fields'], [ 'views', 'date=>views' ], true ) )
199 $args['fields'] = $defaults['fields'];
200
201 $query_chunks = [];
202 $views_query = '';
203
204 // views query after/before parameters work only when fields == views
205 if ( $args['fields'] === 'views' ) {
206 // check views query inclusive
207 if ( ! isset( $args['views_query']['inclusive'] ) )
208 $args['views_query']['inclusive'] = $defaults['views_query']['inclusive'];
209 else
210 $args['views_query']['inclusive'] = (bool) $args['views_query']['inclusive'];
211
212 // check after and before dates
213 foreach ( [ 'after' => '>', 'before' => '<' ] as $date => $type ) {
214 $year_ = null;
215 $month_ = null;
216 $week_ = null;
217 $day_ = null;
218
219 // check views query date
220 if ( ! empty( $args['views_query'][$date] ) ) {
221 // is it a date array?
222 if ( is_array( $args['views_query'][$date] ) ) {
223 // check views query $date date year
224 if ( ! empty( $args['views_query'][$date]['year'] ) )
225 $year_ = str_pad( (int) $args['views_query'][$date]['year'], 4, 0, STR_PAD_LEFT );
226
227 // check views query date month
228 if ( ! empty( $args['views_query'][$date]['month'] ) )
229 $month_ = str_pad( (int) $args['views_query'][$date]['month'], 2, 0, STR_PAD_LEFT );
230
231 // check views query date week
232 if ( ! empty( $args['views_query'][$date]['week'] ) )
233 $week_ = str_pad( (int) $args['views_query'][$date]['week'], 2, 0, STR_PAD_LEFT );
234
235 // check views query date day
236 if ( ! empty( $args['views_query'][$date]['day'] ) )
237 $day_ = str_pad( (int) $args['views_query'][$date]['day'], 2, 0, STR_PAD_LEFT );
238 // is it a date string?
239 } elseif ( is_string( $args['views_query'][$date] ) ) {
240 $time_ = strtotime( $args['views_query'][$date] );
241
242 // valid datetime?
243 if ( $time_ !== false ) {
244 // week does not exists here, string dates are always treated as year + month + day
245 list( $day_, $month_, $year_ ) = explode( ' ', date( "d m Y", $time_ ) );
246 }
247 }
248
249 // valid date?
250 if ( ! ( $year_ === null && $month_ === null && $week_ === null && $day_ === null ) ) {
251 $query_chunks[] = [
252 'year' => $year_,
253 'month' => $month_,
254 'day' => $day_,
255 'week' => $week_,
256 'type' => $type . ( $args['views_query']['inclusive'] ? '=' : '' )
257 ];
258 }
259 }
260 }
261
262 if ( ! empty( $query_chunks ) ) {
263 $valid_dates = true;
264
265 // after and before?
266 if ( count( $query_chunks ) === 2 ) {
267 // before and after dates should be the same
268 foreach ( [ 'year', 'month', 'day', 'week' ] as $date_type ) {
269 if ( ! ( ( $query_chunks[0][$date_type] !== null && $query_chunks[1][$date_type] !== null ) || ( $query_chunks[0][$date_type] === null && $query_chunks[1][$date_type] === null ) ) )
270 $valid_dates = false;
271 }
272 }
273
274 if ( $valid_dates ) {
275 foreach ( $query_chunks as $chunk ) {
276 // year
277 if ( isset( $chunk['year'] ) ) {
278 // year, week
279 if ( isset( $chunk['week'] ) )
280 $views_query .= " AND pvc.type = 1 AND CAST( pvc.period AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['year'] . $chunk['week'] );
281 // year, month
282 elseif ( isset( $chunk['month'] ) ) {
283 // year, month, day
284 if ( isset( $chunk['day'] ) )
285 $views_query .= " AND pvc.type = 0 AND CAST( pvc.period AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['year'] . $chunk['month'] . $chunk['day'] );
286 // year, month
287 else
288 $views_query .= " AND pvc.type = 2 AND CAST( pvc.period AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['year'] . $chunk['month'] );
289 // year
290 } else
291 $views_query .= " AND pvc.type = 3 AND CAST( pvc.period AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['year'] );
292 // month
293 } elseif ( isset( $chunk['month'] ) ) {
294 // month, day
295 if ( isset( $chunk['day'] ) ) {
296 $views_query .= " AND pvc.type = 0 AND CAST( RIGHT( pvc.period, 4 ) AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['month'] . $chunk['day'] );
297 // month
298 } else
299 $views_query .= " AND pvc.type = 2 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['month'] );
300 // week
301 } elseif ( isset( $chunk['week'] ) )
302 $views_query .= " AND pvc.type = 1 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['week'] );
303 // day
304 elseif ( isset( $chunk['day'] ) )
305 $views_query .= " AND pvc.type = 0 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['day'] );
306 }
307 }
308 }
309 }
310
311 $special_views_query = ( $views_query !== '' );
312
313 if ( $args['fields'] === 'date=>views' || $views_query === '' ) {
314 // check views query year
315 if ( ! empty( $args['views_query']['year'] ) )
316 $year = str_pad( (int) $args['views_query']['year'], 4, 0, STR_PAD_LEFT );
317
318 // check views query month
319 if ( ! empty( $args['views_query']['month'] ) )
320 $month = str_pad( (int) $args['views_query']['month'], 2, 0, STR_PAD_LEFT );
321
322 // check views query week
323 if ( ! empty( $args['views_query']['week'] ) )
324 $week = str_pad( (int) $args['views_query']['week'], 2, 0, STR_PAD_LEFT );
325
326 // check views query day
327 if ( ! empty( $args['views_query']['day'] ) )
328 $day = str_pad( (int) $args['views_query']['day'], 2, 0, STR_PAD_LEFT );
329
330 // year
331 if ( isset( $year ) ) {
332 // year, week
333 if ( isset( $week ) ) {
334 if ( $args['fields'] === 'date=>views' ) {
335 // create date based on week number
336 $date = new DateTime( $year . 'W' . $week );
337
338 // get monday
339 $monday = $date->format( 'd' );
340
341 // get month of monday
342 $monday_month = $date->format( 'm' );
343
344 // prepare range
345 for( $i = 1; $i <= 6; $i++ ) {
346 $range[(string) ( $date->format( 'Y' ) . $date->format( 'm' ) . $date->format( 'd' ) )] = 0;
347
348 $date->modify( '+1days' );
349 }
350
351 $range[(string) ( $date->format( 'Y' ) . $date->format( 'm' ) . $date->format( 'd' ) )] = 0;
352
353 // get month of sunday
354 $sunday_month = $date->format( 'm' );
355
356 $views_query = " AND pvc.type = 0 AND CAST( pvc.period AS SIGNED ) >= " . (int) ( $year . $monday_month . $monday ) . " AND CAST( pvc.period AS SIGNED ) <= " . (int) ( $date->format( 'Y' ) . $sunday_month . $date->format( 'd' ) );
357 } else
358 $views_query = " AND pvc.type = 1 AND CAST( pvc.period AS SIGNED ) = " . (int) ( $year . $week );
359 // year, month
360 } elseif ( isset( $month ) ) {
361 // year, month, day
362 if ( isset( $day ) ) {
363 if ( $args['fields'] === 'date=>views' )
364 // prepare range
365 $range[(string) ( $year . $month . $day )] = 0;
366
367 $views_query = " AND pvc.type = 0 AND CAST( pvc.period AS SIGNED ) = " . (int) ( $year . $month . $day );
368 // year, month
369 } else {
370 if ( $args['fields'] === 'date=>views' ) {
371 // create date
372 $date = new DateTime( $year . '-' . $month . '-01' );
373
374 // get last day
375 $last = $date->format( 't' );
376
377 // prepare range
378 for( $i = 1; $i <= $last; $i++ ) {
379 $range[(string) ( $year . $month . str_pad( $i, 2, 0, STR_PAD_LEFT ) )] = 0;
380 }
381
382 $views_query = " AND pvc.type = 0 AND CAST( pvc.period AS SIGNED ) >= " . (int) ( $year . $month ) . "01 AND CAST( pvc.period AS SIGNED ) <= " . (int) ( $year . $month . $last );
383 } else
384 $views_query = " AND pvc.type = 2 AND CAST( pvc.period AS SIGNED ) = " . (int) ( $year . $month );
385 }
386 // year
387 } else {
388 if ( $args['fields'] === 'date=>views' ) {
389 // prepare range
390 for( $i = 1; $i <= 12; $i++ ) {
391 $range[(string) ( $year . str_pad( $i, 2, 0, STR_PAD_LEFT ) )] = 0;
392 }
393
394 // create date
395 $date = new DateTime( $year . '-12-01' );
396
397 $views_query = " AND pvc.type = 2 AND CAST( pvc.period AS SIGNED ) >= " . (int) ( $year ) . "01 AND CAST( pvc.period AS SIGNED ) <= " . (int) ( $year ) . "12";
398 } else
399 $views_query = " AND pvc.type = 3 AND CAST( pvc.period AS SIGNED ) = " . (int) ( $year );
400 }
401 // month
402 } elseif ( isset( $month ) ) {
403 // month, day
404 if ( isset( $day ) ) {
405 $views_query = " AND pvc.type = 0 AND CAST( RIGHT( pvc.period, 4 ) AS SIGNED ) = " . (int) ( $month . $day );
406 // month
407 } else {
408 $views_query = " AND pvc.type = 2 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) = " . (int) ( $month );
409 }
410 // week
411 } elseif ( isset( $week ) ) {
412 $views_query = " AND pvc.type = 1 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) = " . (int) ( $week );
413 // day
414 } elseif ( isset( $day ) ) {
415 $views_query = " AND pvc.type = 0 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) = " . (int) ( $day );
416 }
417 }
418
419 $query = $wpdb->prepare(
420 "SELECT " . ( $args['fields'] === 'date=>views' ? 'pvc.period, ' : '' ) . "SUM( COALESCE( pvc.count, 0 ) ) AS post_views
421 FROM " . $wpdb->prefix . "posts wpp
422 LEFT JOIN " . $wpdb->prefix . "post_views pvc ON pvc.id = wpp.ID AND 1 = %d" . ( $views_query !== '' ? ' ' . $views_query : ' AND pvc.type = 4' ) . ( ! empty( $args['post_id'] ) ? ' AND pvc.id IN (' . implode( ',', array_fill( 0, $post_ids_count, '%d' ) ) . ')' : '' ) . "
423 " . ( ! empty( $args['post_type'] ) ? 'WHERE wpp.post_type IN (' . implode( ',', array_fill( 0, $post_types_count, '%s' ) ) . ')' : '' ) . "
424 " . ( $views_query !== '' && $special_views_query === false ? 'GROUP BY pvc.period HAVING post_views > 0' : '' ),
425 $query_data
426 );
427
428 // get cached data
429 $post_views = wp_cache_get( md5( $query ), 'pvc-get_views' );
430
431 // cached data not found?
432 if ( $post_views === false ) {
433 if ( $args['fields'] === 'date=>views' && ! empty( $range ) ) {
434 $results = $wpdb->get_results( $query );
435
436 if ( ! empty( $results ) ) {
437 foreach ( $results as $row ) {
438 $range[$row->period] = (int) $row->post_views;
439 }
440 }
441
442 $post_views = $range;
443 } else
444 $post_views = (int) $wpdb->get_var( $query );
445
446 // set the cache expiration, 5 minutes by default
447 $expire = absint( apply_filters( 'pvc_object_cache_expire', 300 ) );
448
449 wp_cache_add( md5( $query ), $post_views, 'pvc-get_views', $expire );
450 }
451
452 return apply_filters( 'pvc_get_views', $post_views );
453 }
454 }
455
456 /**
457 * Display post views for a given post.
458 *
459 * @param int $post_id
460 * @param bool $display
461 *
462 * @return string|void
463 */
464 if ( ! function_exists( 'pvc_post_views' ) ) {
465 function pvc_post_views( $post_id = 0, $display = true, $period = '' ) {
466 // get all data
467 $post_id = (int) ( empty( $post_id ) ? get_the_ID() : $post_id );
468
469 // get display options
470 $options = Post_Views_Counter()->options['display'];
471
472 // get post views
473 $views = pvc_get_post_views( $post_id, $period !== '' ? $period : $options['display_period'] );
474
475 // use number format?
476 $views = $options['use_format'] ? number_format_i18n( $views ) : $views;
477
478 // container class
479 $class = apply_filters( 'pvc_post_views_class', 'post-views content-post post-' . $post_id . ' entry-meta', $post_id );
480
481 // dynamic loading?
482 $class .= $options['dynamic_loading'] === true ? ' load-dynamic' : ' load-static';
483
484 // prepare display
485 $label = apply_filters( 'pvc_post_views_label', ( function_exists( 'icl_t' ) ? icl_t( 'Post Views Counter', 'Post Views Label', $options['label'] ) : $options['label'] ), $post_id );
486
487 // add dashicons class if needed
488 $icon_class = strpos( $options['icon_class'], 'dashicons' ) === false ? $options['icon_class'] : 'dashicons ' . $options['icon_class'];
489
490 // prepare icon output
491 $icon = apply_filters( 'pvc_post_views_icon', '<span class="post-views-icon ' . esc_attr( $icon_class ) . '"></span> ', $post_id );
492
493 // final views
494 $views = apply_filters( 'pvc_post_views_number_format', $views, $post_id );
495
496 $html = apply_filters(
497 'pvc_post_views_html',
498 '<div class="' . esc_attr( $class ) . '">
499 ' . ( $options['display_style']['icon'] ? $icon : '' )
500 . ( $options['display_style']['text'] ? '<span class="post-views-label">' . esc_html( $label ) . '</span> ' : '' )
501 . '<span class="post-views-count">' . $views . '</span>
502 </div>',
503 $post_id,
504 $views,
505 $label,
506 $icon
507 );
508
509 if ( $display )
510 echo $html;
511 else
512 return $html;
513 }
514 }
515
516 /**
517 * Get most viewed posts.
518 *
519 * @param array $args
520 *
521 * @return array
522 */
523 if ( ! function_exists( 'pvc_get_most_viewed_posts' ) ) {
524 function pvc_get_most_viewed_posts( $args = [] ) {
525 $args = array_merge(
526 [
527 'posts_per_page' => 10,
528 'order' => 'desc',
529 'post_type' => [ 'post' ],
530 'post_status' => [ 'publish' ],
531 'fields' => 'all',
532 'period' => 'total'
533 ],
534 $args
535 );
536
537 if ( ( is_array( $args['post_type'] ) && in_array( 'attachment', $args['post_type'], true ) ) || ( is_string( $args['post_type'] ) && $args['post_type'] === 'attachment' ) )
538 $args['post_status'][] = 'inherit';
539
540 $args = apply_filters( 'pvc_get_most_viewed_posts_args', $args );
541
542 // force to use filters
543 $args['suppress_filters'] = false;
544
545 // force to use post views as order
546 $args['orderby'] = 'post_views';
547
548 return apply_filters( 'pvc_get_most_viewed_posts', get_posts( $args ), $args );
549 }
550 }
551
552 /**
553 * Display a list of most viewed posts.
554 *
555 * @param array $args
556 * @param bool $display
557 *
558 * @return void|string
559 */
560 if ( ! function_exists( 'pvc_most_viewed_posts' ) ) {
561 function pvc_most_viewed_posts( $args = [], $display = true ) {
562 $defaults = [
563 'number_of_posts' => 5,
564 'post_type' => [ 'post' ],
565 'order' => 'desc',
566 'thumbnail_size' => 'thumbnail',
567 'list_type' => 'unordered',
568 'show_post_views' => true,
569 'show_post_thumbnail' => false,
570 'show_post_author' => false,
571 'show_post_excerpt' => false,
572 'no_posts_message' => __( 'No most viewed posts found.', 'post-views-counter' ),
573 'item_before' => '',
574 'item_after' => '',
575 'period' => 'total'
576 ];
577
578 $args = apply_filters( 'pvc_most_viewed_posts_args', wp_parse_args( $args, $defaults ) );
579
580 // get periods
581 $periods = apply_filters( 'pvc_display_period_options', [ 'total' => __( 'Total Views', 'post-views-counter' ) ] );
582
583 // sanitize arguments
584 $args['show_post_views'] = (bool) $args['show_post_views'];
585 $args['show_post_thumbnail'] = (bool) $args['show_post_thumbnail'];
586 $args['show_post_author'] = (bool) $args['show_post_author'];
587 $args['show_post_excerpt'] = (bool) $args['show_post_excerpt'];
588 $args['period'] = isset( $args['period'] ) && array_key_exists( $args['period'], $periods ) ? $args['period'] : $defaults['period'];
589 $args['post_type'] = isset( $args['post_type'] ) ? $args['post_type'] : $defaults['post_type'];
590
591 // no post types?
592 if ( empty( $args['post_type'] ) )
593 $html = $args['no_posts_message'];
594 else {
595 // get posts
596 $posts = pvc_get_most_viewed_posts( [
597 'posts_per_page' => isset( $args['number_of_posts'] ) ? (int) $args['number_of_posts'] : $defaults['number_of_posts'],
598 'order' => isset( $args['order'] ) ? $args['order'] : $defaults['order'],
599 'post_type' => $args['post_type'],
600 'period' => $args['period']
601 ] );
602
603 if ( ! empty( $posts ) ) {
604 $html = ( $args['list_type'] === 'unordered' ? '<ul>' : '<ol>' );
605
606 foreach ( $posts as $post ) {
607 setup_postdata( $post );
608
609 $html .= '<li>';
610 $html .= apply_filters( 'pvc_most_viewed_posts_item_before', $args['item_before'], $post );
611
612 if ( $args['show_post_thumbnail'] && has_post_thumbnail( $post->ID ) ) {
613 $html .= '<span class="post-thumbnail">' . get_the_post_thumbnail( $post->ID, $args['thumbnail_size'] ) . '</span>';
614 }
615
616 $html .= '<a class="post-title" href="' . get_permalink( $post->ID ) . '">' . get_the_title( $post->ID ) . '</a>' . ( $args['show_post_author'] ? ' <span class="author">(' . get_the_author_meta( 'display_name', $post->post_author ) . ')</span> ' : '' ) . ( $args['show_post_views'] ? ' <span class="count">(' . number_format_i18n( (int) ( property_exists( $post, 'post_views' ) ? $post->post_views : pvc_get_post_views( $post->ID, $args['period'] ) ) ) . ')</span>' : '' );
617
618 if ( $args['show_post_excerpt'] ) {
619 $excerpt = '';
620
621 if ( empty( $post->post_excerpt ) )
622 $text = $post->post_content;
623 else
624 $text = $post->post_excerpt;
625
626 if ( ! empty( $text ) )
627 $excerpt = wp_trim_words( str_replace( ']]>', ']]&gt;', strip_shortcodes( $text ) ), apply_filters( 'excerpt_length', 55 ), apply_filters( 'excerpt_more', ' ' . '[&hellip;]' ) );
628
629 if ( ! empty( $excerpt ) )
630 $html .= '<div class="post-excerpt">' . esc_html( $excerpt ) . '</div>';
631 }
632
633 $html .= apply_filters( 'pvc_most_viewed_posts_item_after', $args['item_after'], $post );
634 $html .= '</li>';
635 }
636
637 wp_reset_postdata();
638
639 $html .= ( $args['list_type'] === 'unordered' ? '</ul>' : '</ol>' );
640 } else
641 $html = $args['no_posts_message'];
642 }
643
644 $html = apply_filters( 'pvc_most_viewed_posts_html', $html, $args );
645
646 if ( $display )
647 echo $html;
648 else
649 return $html;
650 }
651 }
652
653 /**
654 * Update total number of post views for a post.
655 *
656 * @global object $wpdb
657 *
658 * @param int $post_id
659 * @param int $post_views
660 *
661 * @return bool|int
662 */
663 function pvc_update_post_views( $post_id = 0, $post_views = 0 ) {
664 global $wpdb;
665
666 // cast post ID
667 $post_id = (int) $post_id;
668
669 // get post
670 $post = get_post( $post_id );
671
672 // check if post exists
673 if ( empty( $post ) )
674 return false;
675
676 // cast number of views
677 $post_views = (int) $post_views;
678 $post_views = $post_views < 0 ? 0 : $post_views;
679
680 // change post views?
681 $post_views = apply_filters( 'pvc_update_post_views_count', $post_views, $post_id );
682
683 // insert or update database post views count
684 $wpdb->query( $wpdb->prepare( "INSERT INTO " . $wpdb->prefix . "post_views (id, type, period, count) VALUES (%d, %d, %s, %d) ON DUPLICATE KEY UPDATE count = %d", $post_id, 4, 'total', $post_views, $post_views ) );
685
686 // query fails only if it returns false
687 return apply_filters( 'pvc_update_post_views', $post_id );
688 }
689
690 /**
691 * View post manually function.
692 *
693 * By default this function has limitations. It works properly only between
694 * wp_loaded (minimum priority 10) and wp_head (maximum priority 6) actions and
695 * it can handle only one function execution per site request.
696 *
697 * To bypass these limitations there is a $bypass_content argument. It requires
698 * JavaScript or REST API as counter mode but it extends the ability to use
699 * pvc_view_post up to wp_print_footer_scripts (maximum priority 10) action. It
700 * also bypass one function execution limitation to allow multiple function
701 * calls during one site request. This also includes the correct saving of
702 * cookies.
703 *
704 * @since 1.2.0
705 *
706 * @param int $post_id
707 * @param bool $bypass_content
708 *
709 * @return bool
710 */
711 function pvc_view_post( $post_id = 0, $bypass_content = false ) {
712 // no post id?
713 if ( empty( $post_id ) ) {
714 // get current id
715 $post_id = get_the_ID();
716 } else {
717 // cast post id
718 $post_id = (int) $post_id;
719 }
720
721 // get post
722 $post = get_post( $post_id );
723
724 // invalid post?
725 if ( ! is_a( $post, 'WP_Post' ) )
726 return false;
727
728 // get main instance
729 $pvc = Post_Views_Counter();
730
731 if ( $bypass_content )
732 $pvc->counter->add_to_queue( $post_id );
733 else
734 $pvc->counter->check_post( $post_id );
735
736 return true;
737 }