PluginProbe ʕ •ᴥ•ʔ
Post Views Counter / 1.3.11
Post Views Counter v1.3.11
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 / class-dashboard.php
post-views-counter / includes Last commit date
class-admin.php 4 years ago class-columns.php 4 years ago class-counter.php 4 years ago class-crawler-detect.php 4 years ago class-cron.php 4 years ago class-dashboard.php 4 years ago class-frontend.php 4 years ago class-functions.php 4 years ago class-query.php 4 years ago class-settings-api.php 4 years ago class-settings.php 4 years ago class-update.php 4 years ago class-widgets.php 4 years ago functions.php 4 years ago
class-dashboard.php
760 lines
1 <?php
2 // exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) )
4 exit;
5
6 /**
7 * Post_Views_Counter_Dashboard class.
8 *
9 * @class Post_Views_Counter_Dashboard
10 */
11 class Post_Views_Counter_Dashboard {
12
13 private $widget_items = [];
14
15 /**
16 * Class constructor.
17 *
18 * @return void
19 */
20 public function __construct() {
21 // actions
22 add_action( 'admin_init', [ $this, 'init_admin_dashboard' ] );
23 }
24
25 /**
26 * Dashboard initialization.
27 *
28 * @global string $pagenow
29 *
30 * @return void
31 */
32 public function init_admin_dashboard() {
33 global $pagenow;
34
35 // setup widget items
36 $this->setup_widget_items();
37
38 // do it only on dashboard page
39 if ( $pagenow === 'index.php' ) {
40 // filter user_can_see_stats
41 if ( ! apply_filters( 'pvc_user_can_see_stats', current_user_can( 'publish_posts' ) ) )
42 return;
43
44 add_action( 'wp_dashboard_setup', [ $this, 'wp_dashboard_setup' ], 1 );
45 add_action( 'admin_enqueue_scripts', [ $this, 'admin_scripts_styles' ] );
46 // ajax endpoints
47 } elseif ( $pagenow === 'admin-ajax.php' ) {
48 add_action( 'wp_ajax_pvc_dashboard_post_most_viewed', [ $this, 'dashboard_post_most_viewed' ] );
49 add_action( 'wp_ajax_pvc_dashboard_post_views_chart', [ $this, 'dashboard_post_views_chart' ] );
50 add_action( 'wp_ajax_pvc_dashboard_user_options', [ $this, 'update_dashboard_user_options' ] );
51 }
52 }
53
54 /**
55 * Add dashboard widget.
56 *
57 * @return void
58 */
59 public function wp_dashboard_setup() {
60 // add dashboard widget
61 wp_add_dashboard_widget( 'pvc_dashboard', __( 'Post Views Counter', 'post-views-counter' ), [ $this, 'dashboard_widget' ] );
62 }
63
64 /**
65 * Enqueue admin scripts and styles.
66 *
67 * @return void
68 */
69 public function admin_scripts_styles() {
70 // get main instance
71 $pvc = Post_Views_Counter();
72
73 // styles
74 wp_enqueue_style( 'pvc-admin-dashboard', POST_VIEWS_COUNTER_URL . '/css/admin-dashboard.css', [], $pvc->defaults['version'] );
75 wp_enqueue_style( 'pvc-microtip', POST_VIEWS_COUNTER_URL . '/assets/microtip/microtip.min.css', [], '1.0.0' );
76
77 // scripts
78 wp_register_script( 'pvc-chartjs', POST_VIEWS_COUNTER_URL . '/assets/chartjs/chart.min.js', [ 'jquery' ], '3.7.0', true );
79 wp_enqueue_script( 'pvc-admin-dashboard', POST_VIEWS_COUNTER_URL . '/js/admin-dashboard.js', [ 'jquery', 'pvc-chartjs' ], $pvc->defaults['version'], true );
80
81 wp_localize_script(
82 'pvc-admin-dashboard',
83 'pvcArgs',
84 [
85 'ajaxURL' => admin_url( 'admin-ajax.php' ),
86 'nonce' => wp_create_nonce( 'pvc-dashboard-widget' ),
87 'nonceUser' => wp_create_nonce( 'pvc-dashboard-user-options' )
88 ]
89 );
90 }
91
92 /**
93 * Setup dashboard widget items.
94 *
95 * @return void
96 */
97 private function setup_widget_items() {
98 // standard items
99 $items = [
100 [
101 'id' => 'post-views',
102 'title' => __( 'Post Views', 'post-views-counter' ),
103 'description' => __( 'Displays the chart of most viewed post types for a selected time period.', 'post-views-counter' ),
104 'content' => '<canvas id="pvc-post-views-chart" height="' . $this->calculate_canvas_size( Post_Views_Counter()->options['general']['post_types_count'] ) . '"></canvas>'
105 ],
106 [
107 'id' => 'post-most-viewed',
108 'title' => __( 'Top Posts', 'post-views-counter' ),
109 'description' => __( 'Displays the list of most viewed posts and pages on your website.', 'post-views-counter' ),
110 'content' => '<div id="pvc-post-most-viewed-content" class="pvc-table-responsive"></div>'
111 ]
112 ];
113
114 // filter items, do not allow to remove main items
115 $new_items = apply_filters( 'pvc_dashboard_widget_items', [] );
116
117 // any new items?
118 if ( is_array( $new_items ) && ! empty( $new_items ) ) {
119 foreach ( $new_items as $item ) {
120 // add new item
121 array_push( $items, $item );
122 }
123 }
124
125 // set widget items
126 $this->widget_items = $items;
127 }
128
129 /**
130 * Calculate canvas height based on number of legend items.
131 *
132 * @param array $data
133 * @param bool $expression
134 * @return int
135 */
136 public function calculate_canvas_size( $data, $expression = true ) {
137 if ( $expression && ! empty( $data ) ) {
138 // treat every 4 legend items as 1 line - 23 pixels
139 $height = 23 * ( (int) ceil( count( $data ) / 4 ) - 1 );
140 } else
141 $height = 0;
142
143 return (int) ( 170 + $height );
144 }
145
146 /**
147 * Render dashboard widget.
148 *
149 * @return void
150 */
151 public function dashboard_widget() {
152 // get user options
153 $user_options = get_user_meta( get_current_user_id(), 'pvc_dashboard', true );
154
155 // empty options?
156 if ( empty( $user_options ) || ! is_array( $user_options ) )
157 $user_options = [];
158
159 // sanitize options
160 $user_options = map_deep( $user_options, 'sanitize_text_field' );
161
162 // get menu items
163 $menu_items = ! empty( $user_options['menu_items'] ) ? $user_options['menu_items'] : [];
164
165 // generate months
166 $months_html = wp_kses_post( $this->generate_months( current_time( 'timestamp', false ) ) );
167
168 // get widget items
169 $items = $this->widget_items;
170
171 $html = '
172 <div id="pvc-dashboard-accordion" class="pvc-accordion">';
173
174 foreach ( $items as $item ) {
175 $html .= $this->generate_dashboard_widget_item( $item, $menu_items, $months_html );
176 }
177
178 $html .= '
179 </div>';
180
181 echo $html;
182 }
183
184 /**
185 * Generate dashboard widget item HTML.
186 *
187 * @param array $item
188 * @param array $menu_items
189 * @param string $esc_months_html
190 * @return string
191 */
192 public function generate_dashboard_widget_item( $item, $menu_items, $esc_months_html ) {
193 // allows a list of HTML Entities such as
194 $allowed_html = wp_kses_allowed_html( 'post' );
195 $allowed_html['canvas'] = [
196 'id' => [],
197 'height' => []
198 ];
199
200 return '
201 <div id="pvc-' . esc_attr( $item['id'] ) . '" class="pvc-accordion-item' . ( in_array( $item['id'], $menu_items, true ) ? ' pvc-collapsed' : '' ) . '">
202 <div class="pvc-accordion-header">
203 <div class="pvc-accordion-toggle"><span class="pvc-accordion-title">' . esc_html( $item['title'] ) . '</span><span class="pvc-tooltip" aria-label="' . esc_html( $item['description'] ) . '" data-microtip-position="top" data-microtip-size="large" role="tooltip"><span class="pvc-tooltip-icon"></span></span></div>
204 <!--
205 <div class="pvc-accordion-actions">
206 <a href="javascript:void(0);" class="pvc-accordion-action dashicons dashicons-admin-generic"></a>
207 </div>
208 -->
209 </div>
210 <div class="pvc-accordion-content">
211 <div class="pvc-dashboard-container loading">
212 <div class="pvc-data-container">
213 ' . wp_kses( $item['content'], $allowed_html ) . '
214 <span class="spinner"></span>
215 </div>
216 <div class="pvc-months">' . $esc_months_html . '</div>
217 </div>
218 </div>
219 </div>';
220 }
221
222 /**
223 * Render dashboard widget with post views.
224 *
225 * @global array $_wp_admin_css_colors
226 *
227 * @return void
228 */
229 public function dashboard_post_views_chart() {
230 if ( ! apply_filters( 'pvc_user_can_see_stats', current_user_can( 'publish_posts' ) ) )
231 wp_die( _( 'You do not have permission to access this page.', 'post-views-counter' ) );
232
233 if ( ! check_ajax_referer( 'pvc-dashboard-widget', 'nonce' ) )
234 wp_die( __( 'You do not have permission to access this page.', 'post-views-counter' ) );
235
236 // get period
237 $period = isset( $_POST['period'] ) ? sanitize_text_field( $_POST['period'] ) : 'this_month';
238
239 // get post types
240 $post_types = Post_Views_Counter()->options['general']['post_types_count'];
241
242 // get dashboard user options
243 $user_options = $this->get_dashboard_user_options( get_current_user_id(), 'post_types' );
244
245 // get current date
246 $now = getdate( current_time( 'timestamp', get_option( 'gmt_offset' ) ) );
247
248 // get color schemes
249 global $_wp_admin_css_colors;
250
251 // set default color;
252 $color = [
253 'r' => 105,
254 'g' => 168,
255 'b' => 187
256 ];
257
258 if ( ! empty( $_wp_admin_css_colors ) ) {
259 // get current admin color scheme name
260 $current_color_scheme = get_user_option( 'admin_color' );
261
262 if ( empty( $current_color_scheme ) )
263 $current_color_scheme = 'fresh';
264
265 if ( isset( $_wp_admin_css_colors[$current_color_scheme] ) )
266 $color = $this->hex2rgb( $_wp_admin_css_colors[$current_color_scheme]->colors[2] );
267 }
268
269 // set chart labels
270 switch ( $period ) {
271 case 'this_week':
272 //@TODO
273 $data = [
274 'design' => [
275 'fill' => true,
276 'backgroundColor' => 'rgba(' . $color['r'] . ',' . $color['g'] . ',' . $color['b'] . ', 0.2)',
277 'borderColor' => 'rgba(' . $color['r'] . ',' . $color['g'] . ',' . $color['b'] . ', 1)',
278 'borderWidth' => 1.2,
279 'borderDash' => [],
280 'pointBorderColor' => 'rgba(' . $color['r'] . ',' . $color['g'] . ',' . $color['b'] . ', 1)',
281 'pointBackgroundColor' => 'rgba(255, 255, 255, 1)',
282 'pointBorderWidth' => 1.2
283 ]
284 ];
285
286 $data['data']['datasets'][0]['label'] = __( 'Post Views', 'post-views-counter' );
287 $data['data']['datasets'][0]['post_type'] = '_pvc_total_views';
288
289 for ( $day = 0; $day <= 6; $day++ ) {
290 $date = strtotime( $now['mday'] . '-' . $now['mon'] . '-' . $now['year'] . ' + ' . $day . ' days - ' . $now['wday'] . ' days' );
291 $query = new WP_Query(
292 wp_parse_args(
293 [
294 'post_type' => $post_types,
295 'posts_per_page' => -1,
296 'paged' => false,
297 'orderby' => 'post_views',
298 'suppress_filters' => false,
299 'no_found_rows' => true
300 ],
301 [
302 'views_query' => [
303 'year' => date( 'Y', $date ),
304 'month' => date( 'n', $date ),
305 'day' => date( 'd', $date )
306 ]
307 ]
308 )
309 );
310
311 $data['data']['labels'][] = date_i18n( 'j', $date );
312 $data['data']['dates'][] = date_i18n( get_option( 'date_format' ), $date );
313 $data['data']['datasets'][0]['data'][] = $query->total_views;
314 $data['data']['datasets'][$day]['data'][] = $query->total_views;
315 }
316 break;
317
318 case 'this_year':
319 $data = [
320 'design' => [
321 'fill' => true,
322 'backgroundColor' => 'rgba(' . $color['r'] . ',' . $color['g'] . ',' . $color['b'] . ', 0.2)',
323 'borderColor' => 'rgba(' . $color['r'] . ',' . $color['g'] . ',' . $color['b'] . ', 1)',
324 'borderWidth' => 1.2,
325 'borderDash' => [],
326 'pointBorderColor' => 'rgba(' . $color['r'] . ',' . $color['g'] . ',' . $color['b'] . ', 1)',
327 'pointBackgroundColor' => 'rgba(255, 255, 255, 1)',
328 'pointBorderWidth' => 1.2
329 ]
330 ];
331
332 $data['data']['datasets'][0]['label'] = __( 'Total Views', 'post-views-counter' );
333 $data['data']['datasets'][0]['post_type'] = '_pvc_total_views';
334 $data['data']['datasets'][0]['hidden'] = in_array( '_pvc_total_views', $user_options, true );
335 $data['data']['datasets'][0]['data'] = [];
336
337 $sum = [];
338
339 // any post types?
340 if ( ! empty( $post_types ) ) {
341 // reindex post types
342 $post_types = array_combine( range( 1, count( $post_types ) ), array_values( $post_types ) );
343
344 $post_type_data = [];
345
346 foreach ( $post_types as $id => $post_type ) {
347 $post_type_obj = get_post_type_object( $post_type );
348
349 // unrecognized post type? (mainly from deactivated plugins)
350 if ( empty( $post_type_obj ) )
351 $label = $post_type;
352 else
353 $label = $post_type_obj->labels->name;
354
355 $data['data']['datasets'][$id]['label'] = $label;
356 $data['data']['datasets'][$id]['post_type'] = $post_type;
357 $data['data']['datasets'][$id]['hidden'] = in_array( $post_type, $user_options, true );
358 $data['data']['datasets'][$id]['data'] = [];
359
360 // get month views
361 $post_type_data[$id] = array_values(
362 pvc_get_views(
363 [
364 'fields' => 'date=>views',
365 'post_type' => $post_type,
366 'views_query' => [
367 'year' => date( 'Y' ),
368 'month' => '',
369 'week' => '',
370 'day' => ''
371 ]
372 ]
373 )
374 );
375 }
376
377 foreach ( $post_type_data as $post_type_id => $post_views ) {
378 foreach ( $post_views as $id => $views ) {
379 // generate chart data for specific post types
380 $data['data']['datasets'][$post_type_id]['data'][] = $views;
381
382 if ( ! array_key_exists( $id, $sum ) )
383 $sum[$id] = 0;
384
385 $sum[$id] += $views;
386 }
387 }
388 }
389
390 // this month all days
391 for ( $i = 1; $i <= 12; $i ++ ) {
392 // generate chart data
393 $data['data']['labels'][] = $i;
394 $data['data']['dates'][] = date_i18n( 'F Y', strtotime( date( 'Y' ) . '-' . str_pad( $i, 2, '0', STR_PAD_LEFT ) . '-01' ) );
395 $data['data']['datasets'][0]['data'][] = ( array_key_exists( $i - 1, $sum ) ? $sum[$i - 1] : 0 );
396 }
397 break;
398
399 case 'this_month':
400 default:
401 // convert period
402 $time = $this->period2timestamp( $period );
403
404 // get date chunks
405 $date = explode( ' ', date( "m Y t F", $time ) );
406
407 $data = [
408 'months' => $this->generate_months( $time ),
409 'design' => [
410 'fill' => true,
411 'backgroundColor' => 'rgba(' . $color['r'] . ',' . $color['g'] . ',' . $color['b'] . ', 0.2)',
412 'borderColor' => 'rgba(' . $color['r'] . ',' . $color['g'] . ',' . $color['b'] . ', 1)',
413 'borderWidth' => 1.2,
414 'borderDash' => [],
415 'pointBorderColor' => 'rgba(' . $color['r'] . ',' . $color['g'] . ',' . $color['b'] . ', 1)',
416 'pointBackgroundColor' => 'rgba(255, 255, 255, 1)',
417 'pointBorderWidth' => 1.2
418 ]
419 ];
420
421 $data['data']['datasets'][0]['label'] = __( 'Total Views', 'post-views-counter' );
422 $data['data']['datasets'][0]['post_type'] = '_pvc_total_views';
423 $data['data']['datasets'][0]['hidden'] = in_array( '_pvc_total_views', $user_options, true );
424 $data['data']['datasets'][0]['data'] = [];
425
426 $sum = [];
427
428 // any post types?
429 if ( ! empty( $post_types ) ) {
430 // reindex post types
431 $post_types = array_combine( range( 1, count( $post_types ) ), array_values( $post_types ) );
432
433 $post_type_data = [];
434
435 foreach ( $post_types as $id => $post_type ) {
436 $post_type_obj = get_post_type_object( $post_type );
437
438 // unrecognized post type? (mainly from deactivated plugins)
439 if ( empty( $post_type_obj ) )
440 $label = $post_type;
441 else
442 $label = $post_type_obj->labels->name;
443
444 $data['data']['datasets'][$id]['label'] = $label;
445 $data['data']['datasets'][$id]['post_type'] = $post_type;
446 $data['data']['datasets'][$id]['hidden'] = in_array( $post_type, $user_options, true );
447 $data['data']['datasets'][$id]['data'] = [];
448
449 // get month views
450 $post_type_data[$id] = array_values(
451 pvc_get_views(
452 [
453 'fields' => 'date=>views',
454 'post_type' => $post_type,
455 'views_query' => [
456 'year' => $date[1],
457 'month' => $date[0],
458 'week' => '',
459 'day' => '',
460 'hide_empty' => true
461 ]
462 ]
463 )
464 );
465 }
466
467 foreach ( $post_type_data as $post_type_id => $post_views ) {
468 foreach ( $post_views as $id => $views ) {
469 // generate chart data for specific post types
470 $data['data']['datasets'][$post_type_id]['data'][] = $views;
471
472 if ( ! array_key_exists( $id, $sum ) )
473 $sum[$id] = 0;
474
475 $sum[$id] += $views;
476 }
477 }
478 }
479
480 // this month all days
481 for ( $i = 1; $i <= $date[2]; $i ++ ) {
482 // generate chart data
483 $data['data']['labels'][] = ( $i % 2 === 0 ? '' : $i );
484 $data['data']['dates'][] = date_i18n( get_option( 'date_format' ), strtotime( $date[1] . '-' . $date[0] . '-' . str_pad( $i, 2, '0', STR_PAD_LEFT ) ) );
485 $data['data']['datasets'][0]['data'][] = ( array_key_exists( $i - 1, $sum ) ? $sum[$i - 1] : 0 );
486 }
487 break;
488 }
489
490 echo json_encode( $data );
491
492 exit;
493 }
494
495 /**
496 * Render dashboard widget with most viewed posts.
497 *
498 * @return void
499 */
500 public function dashboard_post_most_viewed() {
501 if ( ! apply_filters( 'pvc_user_can_see_stats', current_user_can( 'publish_posts' ) ) )
502 wp_die( _( 'You do not have permission to access this page.', 'post-views-counter' ) );
503
504 if ( ! check_ajax_referer( 'pvc-dashboard-widget', 'nonce' ) )
505 wp_die( __( 'You do not have permission to access this page.', 'post-views-counter' ) );
506
507 // get post types
508 $post_types = Post_Views_Counter()->options['general']['post_types_count'];
509
510 // get period
511 $period = isset( $_POST['period'] ) ? sanitize_text_field( $_POST['period'] ) : 'this_month';
512
513 // convert period
514 $time = $this->period2timestamp( $period );
515
516 // get date chunks
517 $date = explode( ' ', date( "m Y t F", $time ) );
518
519 // get stats
520 $query_args = [
521 'post_type' => $post_types,
522 'posts_per_page' => 10,
523 'paged' => false,
524 'suppress_filters' => false,
525 'no_found_rows' => true,
526 'views_query' => [
527 'year' => $date[1],
528 'month' => $date[0],
529 'hide_empty' => true
530 ]
531 ];
532
533 $posts = pvc_get_most_viewed_posts( $query_args );
534
535 $data = [
536 'months' => $this->generate_months( $time ),
537 'html' => ''
538 ];
539
540 $html = '
541 <table id="pvc-post-most-viewed-table" class="pvc-table pvc-table-hover">
542 <thead>
543 <tr>
544 <th scope="col">#</th>
545 <th scope="col">' . esc_html__( 'Post', 'post-views-counter' ) . '</th>
546 <th scope="col">' . esc_html__( 'Post Views', 'post-views-counter' ) . '</th>
547 </tr>
548 </thead>
549 <tbody>';
550
551 if ( $posts ) {
552 // active post types
553 $active_post_types = [];
554
555 foreach ( $posts as $index => $post ) {
556 setup_postdata( $post );
557
558 $html .= '
559 <tr>
560 <th scope="col">' . ( $index + 1 ) . '</th>';
561
562 if ( array_key_exists( $post->post_type, $active_post_types ) )
563 $post_type_exists = $active_post_types[$post->post_type];
564 else
565 $post_type_exists = $active_post_types[$post->post_type] = post_type_exists( $post->post_type );
566
567 if ( $post_type_exists && current_user_can( 'edit_post', $post->ID ) )
568 $html .= '
569 <td><a href="' . esc_url( get_edit_post_link( $post->ID ) ) . '">' . esc_html( get_the_title( $post ) ) . '</a></td>';
570 else
571 $html .= '
572 <td>' . esc_html( get_the_title( $post ) ). '</td>';
573
574 $html .= '
575 <td>' . number_format_i18n( $post->post_views ) . '</td>
576 </tr>';
577 }
578 } else {
579 $html .= '
580 <tr class="no-posts">
581 <td colspan="3">' . esc_html__( 'No most viewed posts found', 'post-views-counter' ) . '</td>
582 </tr>';
583 }
584
585 $html .= '
586 </tbody>
587 </table>';
588
589 $data['html'] = $html;
590
591 echo json_encode( $data );
592
593 exit;
594 }
595
596 /**
597 * Generate dashboard widget months HTML.
598 *
599 * @param int $timestamp
600 * @return string
601 */
602 public function generate_months( $timestamp ) {
603 $dates = [
604 explode( ' ', date( "m F Y", strtotime( "-1 months", $timestamp ) ) ),
605 explode( ' ', date( "m F Y", $timestamp ) ),
606 explode( ' ', date( "m F Y", strtotime( "+1 months", $timestamp ) ) )
607 ];
608
609 $current = date( "Ym", current_time( 'timestamp', false ) );
610
611 if ( (int) $current <= (int) ( $dates[1][2] . $dates[1][0] ) )
612 $next = '<span class="next">' . $dates[2][1] . ' ' . $dates[2][2] . ' ›</span>';
613 else
614 $next = '<a class="next" href="#" data-date="' . ( $dates[2][0] . '|' . $dates[2][2] ) . '">' . $dates[2][1] . ' ' . $dates[2][2] . ' ›</a>';
615
616 $dates = [
617 'prev' => '<a class="prev" href="#" data-date="' . ( $dates[0][0] . '|' . $dates[0][2] ) . '">‹ ' . $dates[0][1] . ' ' . $dates[0][2] . '</a>',
618 'current' => '<span class="current">' . $dates[1][1] . ' ' . $dates[1][2] . '</span>',
619 'next' => $next
620 ];
621
622 return $dates['prev'] . $dates['current'] . $dates['next'];
623 }
624
625 /**
626 * Update dashboard widget user options.
627 *
628 * @return void
629 */
630 public function update_dashboard_user_options() {
631 if ( ! check_ajax_referer( 'pvc-dashboard-user-options', 'nonce' ) )
632 wp_die( __( 'You do not have permission to access this page.', 'post-views-counter' ) );
633
634 // valid data?
635 if ( isset( $_POST['nonce'], $_POST['options'] ) && ! empty( $_POST['options'] ) ) {
636 // get sanitized options
637 $update = map_deep( $_POST['options'], 'sanitize_text_field' );
638
639 // get user ID
640 $user_id = get_current_user_id();
641
642 // get user dashboard data
643 $user_options = get_user_meta( $user_id, 'pvc_dashboard', true );
644
645 // empty userdata?
646 if ( ! is_array( $user_options ) || empty( $user_options ) )
647 $user_options = [];
648
649 // empty post types?
650 if ( ! array_key_exists( 'post_types', $user_options ) || ! is_array( $user_options['post_types'] ) )
651 $user_options['post_types'] = [];
652
653 // hide post type?
654 if ( ! empty( $update['post_type'] ) ) {
655 // get allowed post types
656 $allowed_post_types = Post_Views_Counter()->options['general']['post_types_count'];
657
658 // simulate total post views as post type
659 $allowed_post_types[] = '_pvc_total_views';
660
661 if ( in_array( $update['post_type'], $allowed_post_types, true ) ) {
662 if ( isset( $update['hidden'] ) && $update['hidden'] === 'true' ) {
663 if ( ! in_array( $update['post_type'], $user_options['post_types'], true ) )
664 $user_options['post_types'][] = $update['post_type'];
665 } else {
666 if ( ( $key = array_search( $update['post_type'], $user_options['post_types'] ) ) !== false )
667 unset( $user_options['post_types'][$key] );
668 }
669 }
670 }
671
672 // empty menu items?
673 if ( ! array_key_exists( 'menu_items', $user_options ) || ! is_array( $user_options['menu_items'] ) )
674 $user_options['menu_items'] = [];
675
676 if ( ! empty( $update['menu_items'] ) && is_array( $update['menu_items'] ) ) {
677 $user_options['menu_items'] = [];
678
679 // get allowed menu items
680 $allowed_menu_items = array_column( $this->widget_items, 'id' );
681
682 foreach ( $update['menu_items'] as $menu_item => $hidden ) {
683 if ( in_array( $menu_item, $allowed_menu_items, true ) && $hidden === 'true' )
684 $user_options['menu_items'][] = $menu_item;
685 }
686 }
687
688 // filter user options
689 $user_options = apply_filters( 'pvc_update_dashboard_user_options', $user_options, $update, $user_id );
690
691 // update userdata
692 update_user_meta( $user_id, 'pvc_dashboard', $user_options );
693 }
694
695 exit;
696 }
697
698 /**
699 * Get user dashboard data.
700 *
701 * @param int $user_id
702 * @param string $data_type
703 * @return array
704 */
705 public function get_dashboard_user_options( $user_id, $data_type ) {
706 $user_options = get_user_meta( $user_id, 'pvc_dashboard', true );
707
708 if ( ! is_array( $user_options ) || empty( $user_options ) )
709 $user_options = [];
710
711 if ( ! array_key_exists( $data_type, $user_options ) || ! is_array( $user_options[$data_type] ) )
712 $user_options[$data_type] = [];
713
714 return $user_options[$data_type];
715 }
716
717 /**
718 * Convert period to timestamp.
719 *
720 * @param string $period
721 * @return int
722 */
723 public function period2timestamp( $period ) {
724 // whitelisted period?
725 if ( in_array( $period, [ 'this_week', 'this_year', 'this_month' ], true ) ) {
726 $timestamp = current_time( 'timestamp', false );
727 } else {
728 if ( preg_match( '/^([0-9]{2}\|[0-9]{4})$/', $period ) === 1 ) {
729 // month|year
730 $date = explode( '|', $period, 2 );
731
732 // get timestamp
733 $timestamp = strtotime( (string) $date[1] . '-' . (string) $date[0] . '-13' );
734 } else
735 $timestamp = current_time( 'timestamp', false );
736 }
737
738 return $timestamp;
739 }
740
741 /**
742 * Convert HEX to RGB color.
743 *
744 * @param string $color
745 * @return bool|array
746 */
747 public function hex2rgb( $color ) {
748 if ( $color[0] === '#' )
749 $color = substr( $color, 1 );
750
751 if ( strlen( $color ) == 6 )
752 list( $r, $g, $b ) = [ $color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5] ];
753 elseif ( strlen( $color ) == 3 )
754 list( $r, $g, $b ) = [ $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] ];
755 else
756 return false;
757
758 return [ 'r' => hexdec( $r ), 'g' => hexdec( $g ), 'b' => hexdec( $b ) ];
759 }
760 }