PluginProbe ʕ •ᴥ•ʔ
Post Views Counter / 1.4.7
Post Views Counter v1.4.7
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 2 years ago class-columns.php 2 years ago class-counter.php 2 years ago class-crawler-detect.php 2 years ago class-cron.php 2 years ago class-dashboard.php 2 years ago class-frontend.php 2 years ago class-functions.php 2 years ago class-query.php 2 years ago class-settings-api.php 2 years ago class-settings.php 2 years ago class-update.php 2 years ago class-widgets.php 2 years ago functions.php 2 years ago
functions.php
734 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 * @return int
23 */
24 if ( ! function_exists( 'pvc_get_post_views' ) ) {
25
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 /**
119 * Get views query.
120 *
121 * @global object $wpdb
122 *
123 * @param array $args
124 * @return int|array
125 */
126 if ( ! function_exists( 'pvc_get_views' ) ) {
127
128 function pvc_get_views( $args = [] ) {
129
130 global $wpdb;
131
132 $range = [];
133 $defaults = [
134 'fields' => 'views',
135 'post_id' => '',
136 'post_type' => '',
137 'views_query' => [
138 'year' => '',
139 'month' => '',
140 'week' => '',
141 'day' => '',
142 'after' => '', // string or array
143 'before' => '', // string or array
144 'inclusive' => true
145 ]
146 ];
147
148 // merge default options with new arguments
149 $args = array_merge( $defaults, $args );
150
151 // check views query
152 if ( ! is_array( $args['views_query'] ) )
153 $args['views_query'] = $defaults['views_query'];
154
155 // merge views query too
156 $args['views_query'] = array_merge( $defaults['views_query'], $args['views_query'] );
157
158 // filter arguments
159 $args = apply_filters( 'pvc_get_views_args', $args );
160
161 // check post types
162 if ( is_string( $args['post_type'] ) )
163 $args['post_type'] = [ $args['post_type'] ];
164 elseif ( ! is_array( $args['post_type'] ) )
165 $args['post_type'] = [];
166
167 // get number of post types
168 $post_types_count = count( $args['post_type'] );
169
170 // check post ids
171 if ( is_array( $args['post_id'] ) && ! empty( $args['post_id'] ) )
172 $args['post_id'] = array_filter( array_unique( array_map( 'intval', $args['post_id'] ) ) );
173 elseif ( is_string( $args['post_id'] ) || is_numeric( $args['post_id'] ) ) {
174 $post_id = (int) $args['post_id'];
175
176 if ( $post_id === 0 )
177 $args['post_id'] = [];
178 else
179 $args['post_id'] = [ $post_id ];
180 } else
181 $args['post_id'] = [];
182
183 // get number of post ids
184 $post_ids_count = count( $args['post_id'] );
185
186 // placeholder for empty query data
187 $query_data = [ 1 ];
188
189 // set query data
190 if ( $post_ids_count === 0 && $post_types_count === 0 )
191 $query_data = [ 1 ];
192 elseif ( $post_ids_count === 0 )
193 $query_data = array_merge( $query_data, array_values( $args['post_type'] ) );
194 elseif ( $post_types_count === 0 )
195 $query_data = array_merge( $query_data, array_values( $args['post_id'] ) );
196 else
197 $query_data = array_merge( $query_data, array_values( $args['post_id'] ), array_values( $args['post_type'] ) );
198
199 // check fields
200 if ( ! in_array( $args['fields'], [ 'views', 'date=>views' ], true ) )
201 $args['fields'] = $defaults['fields'];
202
203 $query_chunks = [];
204 $views_query = '';
205
206 // views query after/before parameters work only when fields == views
207 if ( $args['fields'] === 'views' ) {
208 // check views query inclusive
209 if ( ! isset( $args['views_query']['inclusive'] ) )
210 $args['views_query']['inclusive'] = $defaults['views_query']['inclusive'];
211 else
212 $args['views_query']['inclusive'] = (bool) $args['views_query']['inclusive'];
213
214 // check after and before dates
215 foreach ( [ 'after' => '>', 'before' => '<' ] as $date => $type ) {
216 $year_ = null;
217 $month_ = null;
218 $week_ = null;
219 $day_ = null;
220
221 // check views query date
222 if ( ! empty( $args['views_query'][$date] ) ) {
223 // is it a date array?
224 if ( is_array( $args['views_query'][$date] ) ) {
225 // check views query $date date year
226 if ( ! empty( $args['views_query'][$date]['year'] ) )
227 $year_ = str_pad( (int) $args['views_query'][$date]['year'], 4, 0, STR_PAD_LEFT );
228
229 // check views query date month
230 if ( ! empty( $args['views_query'][$date]['month'] ) )
231 $month_ = str_pad( (int) $args['views_query'][$date]['month'], 2, 0, STR_PAD_LEFT );
232
233 // check views query date week
234 if ( ! empty( $args['views_query'][$date]['week'] ) )
235 $week_ = str_pad( (int) $args['views_query'][$date]['week'], 2, 0, STR_PAD_LEFT );
236
237 // check views query date day
238 if ( ! empty( $args['views_query'][$date]['day'] ) )
239 $day_ = str_pad( (int) $args['views_query'][$date]['day'], 2, 0, STR_PAD_LEFT );
240 // is it a date string?
241 } elseif ( is_string( $args['views_query'][$date] ) ) {
242 $time_ = strtotime( $args['views_query'][$date] );
243
244 // valid datetime?
245 if ( $time_ !== false ) {
246 // week does not exists here, string dates are always treated as year + month + day
247 list( $day_, $month_, $year_ ) = explode( ' ', date( "d m Y", $time_ ) );
248 }
249 }
250
251 // valid date?
252 if ( ! ( $year_ === null && $month_ === null && $week_ === null && $day_ === null ) ) {
253 $query_chunks[] = [
254 'year' => $year_,
255 'month' => $month_,
256 'day' => $day_,
257 'week' => $week_,
258 'type' => $type . ( $args['views_query']['inclusive'] ? '=' : '' )
259 ];
260 }
261 }
262 }
263
264 if ( ! empty( $query_chunks ) ) {
265 $valid_dates = true;
266
267 // after and before?
268 if ( count( $query_chunks ) === 2 ) {
269 // before and after dates should be the same
270 foreach ( [ 'year', 'month', 'day', 'week' ] as $date_type ) {
271 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 ) ) )
272 $valid_dates = false;
273 }
274 }
275
276 if ( $valid_dates ) {
277 foreach ( $query_chunks as $chunk ) {
278 // year
279 if ( isset( $chunk['year'] ) ) {
280 // year, week
281 if ( isset( $chunk['week'] ) )
282 $views_query .= " AND pvc.type = 1 AND CAST( pvc.period AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['year'] . $chunk['week'] );
283 // year, month
284 elseif ( isset( $chunk['month'] ) ) {
285 // year, month, day
286 if ( isset( $chunk['day'] ) )
287 $views_query .= " AND pvc.type = 0 AND CAST( pvc.period AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['year'] . $chunk['month'] . $chunk['day'] );
288 // year, month
289 else
290 $views_query .= " AND pvc.type = 2 AND CAST( pvc.period AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['year'] . $chunk['month'] );
291 // year
292 } else
293 $views_query .= " AND pvc.type = 3 AND CAST( pvc.period AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['year'] );
294 // month
295 } elseif ( isset( $chunk['month'] ) ) {
296 // month, day
297 if ( isset( $chunk['day'] ) ) {
298 $views_query .= " AND pvc.type = 0 AND CAST( RIGHT( pvc.period, 4 ) AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['month'] . $chunk['day'] );
299 // month
300 } else
301 $views_query .= " AND pvc.type = 2 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['month'] );
302 // week
303 } elseif ( isset( $chunk['week'] ) )
304 $views_query .= " AND pvc.type = 1 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['week'] );
305 // day
306 elseif ( isset( $chunk['day'] ) )
307 $views_query .= " AND pvc.type = 0 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) " . $chunk['type'] . " " . (int) ( $chunk['day'] );
308 }
309 }
310 }
311 }
312
313 $special_views_query = ( $views_query !== '' );
314
315 if ( $args['fields'] === 'date=>views' || $views_query === '' ) {
316 // check views query year
317 if ( ! empty( $args['views_query']['year'] ) )
318 $year = str_pad( (int) $args['views_query']['year'], 4, 0, STR_PAD_LEFT );
319
320 // check views query month
321 if ( ! empty( $args['views_query']['month'] ) )
322 $month = str_pad( (int) $args['views_query']['month'], 2, 0, STR_PAD_LEFT );
323
324 // check views query week
325 if ( ! empty( $args['views_query']['week'] ) )
326 $week = str_pad( (int) $args['views_query']['week'], 2, 0, STR_PAD_LEFT );
327
328 // check views query day
329 if ( ! empty( $args['views_query']['day'] ) )
330 $day = str_pad( (int) $args['views_query']['day'], 2, 0, STR_PAD_LEFT );
331
332 // year
333 if ( isset( $year ) ) {
334 // year, week
335 if ( isset( $week ) ) {
336 if ( $args['fields'] === 'date=>views' ) {
337 // create date based on week number
338 $date = new DateTime( $year . 'W' . $week );
339
340 // get monday
341 $monday = $date->format( 'd' );
342
343 // get month of monday
344 $monday_month = $date->format( 'm' );
345
346 // prepare range
347 for( $i = 1; $i <= 6; $i++ ) {
348 $range[(string) ( $date->format( 'Y' ) . $date->format( 'm' ) . $date->format( 'd' ) )] = 0;
349
350 $date->modify( '+1days' );
351 }
352
353 $range[(string) ( $date->format( 'Y' ) . $date->format( 'm' ) . $date->format( 'd' ) )] = 0;
354
355 // get month of sunday
356 $sunday_month = $date->format( 'm' );
357
358 $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' ) );
359 } else
360 $views_query = " AND pvc.type = 1 AND CAST( pvc.period AS SIGNED ) = " . (int) ( $year . $week );
361 // year, month
362 } elseif ( isset( $month ) ) {
363 // year, month, day
364 if ( isset( $day ) ) {
365 if ( $args['fields'] === 'date=>views' )
366 // prepare range
367 $range[(string) ( $year . $month . $day )] = 0;
368
369 $views_query = " AND pvc.type = 0 AND CAST( pvc.period AS SIGNED ) = " . (int) ( $year . $month . $day );
370 // year, month
371 } else {
372 if ( $args['fields'] === 'date=>views' ) {
373 // create date
374 $date = new DateTime( $year . '-' . $month . '-01' );
375
376 // get last day
377 $last = $date->format( 't' );
378
379 // prepare range
380 for( $i = 1; $i <= $last; $i++ ) {
381 $range[(string) ( $year . $month . str_pad( $i, 2, 0, STR_PAD_LEFT ) )] = 0;
382 }
383
384 $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 );
385 } else
386 $views_query = " AND pvc.type = 2 AND CAST( pvc.period AS SIGNED ) = " . (int) ( $year . $month );
387 }
388 // year
389 } else {
390 if ( $args['fields'] === 'date=>views' ) {
391 // prepare range
392 for( $i = 1; $i <= 12; $i++ ) {
393 $range[(string) ( $year . str_pad( $i, 2, 0, STR_PAD_LEFT ) )] = 0;
394 }
395
396 // create date
397 $date = new DateTime( $year . '-12-01' );
398
399 $views_query = " AND pvc.type = 2 AND CAST( pvc.period AS SIGNED ) >= " . (int) ( $year ) . "01 AND CAST( pvc.period AS SIGNED ) <= " . (int) ( $year ) . "12";
400 } else
401 $views_query = " AND pvc.type = 3 AND CAST( pvc.period AS SIGNED ) = " . (int) ( $year );
402 }
403 // month
404 } elseif ( isset( $month ) ) {
405 // month, day
406 if ( isset( $day ) ) {
407 $views_query = " AND pvc.type = 0 AND CAST( RIGHT( pvc.period, 4 ) AS SIGNED ) = " . (int) ( $month . $day );
408 // month
409 } else {
410 $views_query = " AND pvc.type = 2 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) = " . (int) ( $month );
411 }
412 // week
413 } elseif ( isset( $week ) ) {
414 $views_query = " AND pvc.type = 1 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) = " . (int) ( $week );
415 // day
416 } elseif ( isset( $day ) ) {
417 $views_query = " AND pvc.type = 0 AND CAST( RIGHT( pvc.period, 2 ) AS SIGNED ) = " . (int) ( $day );
418 }
419 }
420
421 $query = $wpdb->prepare(
422 "SELECT " . ( $args['fields'] === 'date=>views' ? 'pvc.period, ' : '' ) . "SUM( COALESCE( pvc.count, 0 ) ) AS post_views
423 FROM " . $wpdb->prefix . "posts wpp
424 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' ) ) . ')' : '' ) . "
425 " . ( ! empty( $args['post_type'] ) ? 'WHERE wpp.post_type IN (' . implode( ',', array_fill( 0, $post_types_count, '%s' ) ) . ')' : '' ) . "
426 " . ( $views_query !== '' && $special_views_query === false ? 'GROUP BY pvc.period HAVING post_views > 0' : '' ),
427 $query_data
428 );
429
430 // get cached data
431 $post_views = wp_cache_get( md5( $query ), 'pvc-get_views' );
432
433 // cached data not found?
434 if ( $post_views === false ) {
435 if ( $args['fields'] === 'date=>views' && ! empty( $range ) ) {
436 $results = $wpdb->get_results( $query );
437
438 if ( ! empty( $results ) ) {
439 foreach ( $results as $row ) {
440 $range[$row->period] = (int) $row->post_views;
441 }
442 }
443
444 $post_views = $range;
445 } else
446 $post_views = (int) $wpdb->get_var( $query );
447
448 // set the cache expiration, 5 minutes by default
449 $expire = absint( apply_filters( 'pvc_object_cache_expire', 300 ) );
450
451 wp_cache_add( md5( $query ), $post_views, 'pvc-get_views', $expire );
452 }
453
454 return apply_filters( 'pvc_get_views', $post_views );
455 }
456
457 }
458
459 /**
460 * Display post views for a given post.
461 *
462 * @param int|array $post_id
463 * @param bool $display
464 * @return string|void
465 */
466 if ( ! function_exists( 'pvc_post_views' ) ) {
467
468 function pvc_post_views( $post_id = 0, $display = true ) {
469 // get all data
470 $post_id = (int) ( empty( $post_id ) ? get_the_ID() : $post_id );
471
472 // get display options
473 $options = Post_Views_Counter()->options['display'];
474
475 // get post views
476 $views = pvc_get_post_views( $post_id, $options['display_period'] );
477
478 // use number format?
479 $views = $options['use_format'] ? number_format_i18n( $views ) : $views;
480
481 // container class
482 $class = apply_filters( 'pvc_post_views_class', 'post-views content-post post-' . $post_id . ' entry-meta', $post_id );
483
484 // dynamic loading?
485 $class .= $options['dynamic_loading'] === true ? ' load-dynamic' : ' load-static';
486
487 // prepare display
488 $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 );
489
490 // add dashicons class if needed
491 $icon_class = strpos( $options['icon_class'], 'dashicons' ) === false ? $options['icon_class'] : 'dashicons ' . $options['icon_class'];
492
493 // prepare icon output
494 $icon = apply_filters( 'pvc_post_views_icon', '<span class="post-views-icon ' . esc_attr( $icon_class ) . '"></span> ', $post_id );
495
496 // final views
497 $views = apply_filters( 'pvc_post_views_number_format', $views, $post_id );
498
499 $html = apply_filters(
500 'pvc_post_views_html',
501 '<div class="' . esc_attr( $class ) . '">
502 ' . ( $options['display_style']['icon'] ? $icon : '' )
503 . ( $options['display_style']['text'] ? '<span class="post-views-label">' . esc_html( $label ) . '</span> ' : '' )
504 . '<span class="post-views-count">' . $views . '</span>
505 </div>',
506 $post_id,
507 $views,
508 $label,
509 $icon
510 );
511
512 if ( $display )
513 echo $html;
514 else
515 return $html;
516 }
517
518 }
519
520 /**
521 * Get most viewed posts.
522 *
523 * @param array $args
524 * @return array
525 */
526 if ( ! function_exists( 'pvc_get_most_viewed_posts' ) ) {
527
528 function pvc_get_most_viewed_posts( $args = [] ) {
529 $args = array_merge(
530 [
531 'posts_per_page' => 10,
532 'order' => 'desc',
533 'post_type' => 'post',
534 'fields' => ''
535 ],
536 $args
537 );
538
539 $args = apply_filters( 'pvc_get_most_viewed_posts_args', $args );
540
541 // force to use filters
542 $args['suppress_filters'] = false;
543
544 // force to use post views as order
545 $args['orderby'] = 'post_views';
546
547 return apply_filters( 'pvc_get_most_viewed_posts', get_posts( $args ), $args );
548 }
549
550 }
551
552 /**
553 * Display a list of most viewed posts.
554 *
555 * @param array $post_id
556 * @param bool $display
557 * @return mixed
558 */
559 if ( ! function_exists( 'pvc_most_viewed_posts' ) ) {
560
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 Posts', 'post-views-counter' ),
573 'item_before' => '',
574 'item_after' => ''
575 ];
576
577 $args = apply_filters( 'pvc_most_viewed_posts_args', wp_parse_args( $args, $defaults ) );
578
579 $args['show_post_views'] = (bool) $args['show_post_views'];
580 $args['show_post_thumbnail'] = (bool) $args['show_post_thumbnail'];
581 $args['show_post_author'] = (bool) $args['show_post_author'];
582 $args['show_post_excerpt'] = (bool) $args['show_post_excerpt'];
583
584 $posts = pvc_get_most_viewed_posts(
585 [
586 'posts_per_page' => ( isset( $args['number_of_posts'] ) ? (int) $args['number_of_posts'] : $defaults['number_of_posts'] ),
587 'order' => ( isset( $args['order'] ) ? $args['order'] : $defaults['order'] ),
588 'post_type' => ( isset( $args['post_type'] ) ? $args['post_type'] : $defaults['post_type'] )
589 ]
590 );
591
592 if ( ! empty( $posts ) ) {
593 $html = ( $args['list_type'] === 'unordered' ? '<ul>' : '<ol>' );
594
595 foreach ( $posts as $post ) {
596 setup_postdata( $post );
597
598 $html .= '
599 <li>';
600
601 $html .= apply_filters( 'pvc_most_viewed_posts_item_before', $args['item_before'], $post );
602
603 if ( $args['show_post_thumbnail'] && has_post_thumbnail( $post->ID ) ) {
604 $html .= '
605 <span class="post-thumbnail">
606 ' . get_the_post_thumbnail( $post->ID, $args['thumbnail_size'] ) . '
607 </span>';
608 }
609
610 $html .= '
611 <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( pvc_get_post_views( $post->ID ) ) . ')</span>' : '' );
612
613 $excerpt = '';
614
615 if ( $args['show_post_excerpt'] ) {
616 if ( empty( $post->post_excerpt ) )
617 $text = $post->post_content;
618 else
619 $text = $post->post_excerpt;
620
621 if ( ! empty( $text ) )
622 $excerpt = wp_trim_words( str_replace( ']]>', ']]&gt;', strip_shortcodes( $text ) ), apply_filters( 'excerpt_length', 55 ), apply_filters( 'excerpt_more', ' ' . '[&hellip;]' ) );
623 }
624
625 if ( ! empty( $excerpt ) )
626 $html .= '
627
628 <div class="post-excerpt">' . esc_html( $excerpt ) . '</div>';
629
630 $html .= apply_filters( 'pvc_most_viewed_posts_item_after', $args['item_after'], $post );
631
632 $html .= '
633 </li>';
634 }
635
636 wp_reset_postdata();
637
638 $html .= ( $args['list_type'] === 'unordered' ? '</ul>' : '</ol>' );
639 } else
640 $html = $args['no_posts_message'];
641
642 $html = apply_filters( 'pvc_most_viewed_posts_html', $html, $args );
643
644 if ( $display )
645 echo $html;
646 else
647 return $html;
648 }
649
650 }
651
652 /**
653 * Update total number of post views for a post.
654 *
655 * @global object $wpdb
656 *
657 * @param int $post_id Post ID
658 * @param int $post_views Number of post views
659 * @return bool|int
660 */
661 function pvc_update_post_views( $post_id = 0, $post_views = 0 ) {
662 global $wpdb;
663
664 // cast post ID
665 $post_id = (int) $post_id;
666
667 // get post
668 $post = get_post( $post_id );
669
670 // check if post exists
671 if ( empty( $post ) )
672 return false;
673
674 // cast number of views
675 $post_views = (int) $post_views;
676 $post_views = $post_views < 0 ? 0 : $post_views;
677
678 // change post views?
679 $post_views = apply_filters( 'pvc_update_post_views_count', $post_views, $post_id );
680
681 // insert or update database post views count
682 $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 ) );
683
684 // query fails only if it returns false
685 return apply_filters( 'pvc_update_post_views', $post_id );
686 }
687
688 /**
689 * View post manually function.
690 *
691 * By default this function has limitations. It works properly only between
692 * wp_loaded (minimum priority 10) and wp_head (maximum priority 6) actions and
693 * it can handle only one function execution per site request.
694 *
695 * To bypass these limitations there is a $bypass_content argument. It requires
696 * JavaScript or REST API as counter mode but it extends the ability to use
697 * pvc_view_post up to wp_print_footer_scripts (maximum priority 10) action. It
698 * also bypass one function execution limitation to allow multiple function
699 * calls during one site request. This also includes the correct saving of
700 * cookies.
701 *
702 * @since 1.2.0
703 *
704 * @param int $post_id
705 * @param bool $bypass_content
706 * @return bool
707 */
708 function pvc_view_post( $post_id = 0, $bypass_content = false ) {
709 // no post id?
710 if ( empty( $post_id ) ) {
711 // get current id
712 $post_id = get_the_ID();
713 } else {
714 // cast post id
715 $post_id = (int) $post_id;
716 }
717
718 // get post
719 $post = get_post( $post_id );
720
721 // invalid post?
722 if ( ! is_a( $post, 'WP_Post' ) )
723 return false;
724
725 // get main instance
726 $pvc = Post_Views_Counter();
727
728 if ( $bypass_content )
729 $pvc->counter->add_to_queue( $post_id );
730 else
731 $pvc->counter->check_post( $post_id );
732
733 return true;
734 }