PluginProbe ʕ •ᴥ•ʔ
Post Views Counter / 1.7.5
Post Views Counter v1.7.5
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 5 months ago class-columns-modal.php 5 months ago class-columns.php 5 months ago class-counter.php 5 months ago class-crawler-detect.php 5 months ago class-cron.php 5 months ago class-dashboard.php 5 months ago class-frontend.php 5 months ago class-functions.php 5 months ago class-import.php 5 months ago class-integration-gutenberg.php 5 months ago class-integrations.php 5 months ago class-query.php 5 months ago class-settings-api.php 5 months ago class-settings-display.php 5 months ago class-settings-general.php 5 months ago class-settings-integrations.php 5 months ago class-settings-other.php 5 months ago class-settings-reports.php 5 months ago class-settings.php 5 months ago class-toolbar.php 5 months ago class-traffic-signals.php 5 months ago class-update.php 5 months ago class-widgets.php 5 months ago functions.php 5 months ago
class-dashboard.php
668 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', '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_enqueue_script( 'pvc-admin-dashboard', POST_VIEWS_COUNTER_URL . '/js/admin-dashboard.js', [ 'jquery', 'pvc-chartjs' ], $pvc->defaults['version'], true );
79
80 // prepare script data
81 $script_data = [
82 'ajaxURL' => admin_url( 'admin-ajax.php' ),
83 'nonce' => wp_create_nonce( 'pvc-dashboard-widget' ),
84 'nonceUser' => wp_create_nonce( 'pvc-dashboard-user-options' )
85 ];
86
87 $script_data = apply_filters( 'pvc_admin_dashboard_script_data', $script_data );
88
89 wp_add_inline_script( 'pvc-admin-dashboard', 'var pvcArgs = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
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 a chart of most viewed post types.', 'post-views-counter' ),
104 'content' => '<canvas id="pvc-post-views-chart" height="' . (int) $this->calculate_canvas_size( Post_Views_Counter()->options['general']['post_types_count'] ) . '"></canvas>',
105 'position' => 2
106 ],
107 [
108 'id' => 'post-most-viewed',
109 'title' => __( 'Top Posts', 'post-views-counter' ),
110 'description' => __( 'Displays a list of most viewed single posts or pages.', 'post-views-counter' ),
111 'content' => '<div id="pvc-post-most-viewed-content" class="pvc-table-responsive"></div>',
112 'position' => 3
113 ]
114 ];
115
116 // filter items, do not allow to remove main items
117 $new_items = apply_filters( 'pvc_dashboard_widget_items', [] );
118
119 // any new items?
120 if ( is_array( $new_items ) && ! empty( $new_items ) ) {
121 foreach ( $new_items as $item ) {
122 // add new item
123 array_push( $items, $item );
124 }
125 }
126
127 // sort dashboard items by position
128 array_multisort( array_column( $items, 'position' ), SORT_ASC, SORT_NUMERIC, $items );
129
130 // set widget items
131 $this->widget_items = $items;
132 }
133
134 public function get_widget_items() {
135 // return widget items
136 return $this->widget_items;
137 }
138
139 /**
140 * Calculate canvas height based on number of legend items.
141 *
142 * @param array $data
143 * @param bool $expression
144 * @return int
145 */
146 public function calculate_canvas_size( $data, $expression = true ) {
147 if ( $expression && ! empty( $data ) ) {
148 // treat every 4 legend items as 1 line - 23 pixels
149 $height = 23 * ( (int) ceil( count( $data ) / 4 ) - 1 );
150 } else
151 $height = 0;
152
153 return (int) ( 170 + $height );
154 }
155
156 /**
157 * Render dashboard widget.
158 *
159 * @return void
160 */
161 public function dashboard_widget() {
162 // get user options
163 $user_options = get_user_meta( get_current_user_id(), 'pvc_dashboard', true );
164
165 // empty options?
166 if ( empty( $user_options ) || ! is_array( $user_options ) )
167 $user_options = [];
168
169 // sanitize options
170 $user_options = map_deep( $user_options, 'sanitize_text_field' );
171
172 // get menu items
173 $menu_items = ! empty( $user_options['menu_items'] ) ? $user_options['menu_items'] : [];
174
175 // get widget items
176 $items = $this->widget_items;
177
178 $html = '
179 <div id="pvc-dashboard-accordion" class="pvc-accordion">';
180
181 foreach ( $items as $item ) {
182 $html .= $this->generate_dashboard_widget_item( $item, $menu_items );
183 }
184
185 $html .= '
186 <div class="pvc-dashboard-block"><span>' . esc_html__( 'Powered by', 'post-views-counter' ) . ' <a href="https://postviewscounter.com/?utm_source=post-views-counter-lite&utm_medium=link&utm_campaign=powered-by" target="_blank">Post Views Counter</a></span></div>
187 </div>';
188
189 echo $html;
190 }
191
192 /**
193 * Generate dashboard widget item HTML.
194 *
195 * @param array $item
196 * @param array $menu_items
197 *
198 * @return string
199 */
200 public function generate_dashboard_widget_item( $item, $menu_items ) {
201 // get allowed html tags
202 $allowed_html = wp_kses_allowed_html( 'post' );
203 $allowed_html['canvas'] = [
204 'id' => [],
205 'height' => []
206 ];
207
208 ob_start(); ?>
209
210 <div id="pvc-<?php esc_attr_e( $item['id'] ); ?>" class="pvc-accordion-item<?php echo ( in_array( $item['id'], $menu_items, true ) ? ' pvc-collapsed' : '' ); ?>">
211 <div class="pvc-accordion-header">
212 <div class="pvc-accordion-toggle"><span class="pvc-accordion-title"><?php esc_html_e( $item['title'] ); ?></span><span class="pvc-tooltip" aria-label="<?php esc_html_e( $item['description'] ); ?>" data-microtip-position="top" data-microtip-size="large" role="tooltip"><span class="pvc-tooltip-icon"></span></span></div>
213 <div class="pvc-accordion-actions">
214 <!--<a href="javascript:void(0);" class="pvc-accordion-action dashicons dashicons-admin-generic"></a>-->
215 <a href="javascript:void(0);" class="pvc-accordion-action pvc-toggle-indicator"></a>
216 </div>
217 </div>
218 <div class="pvc-accordion-content">
219 <div class="pvc-dashboard-container loading">
220 <div class="pvc-dashboard-content-top">
221 <?php do_action( 'pvc_dashboard_widget_content_top', $item['id'] ); ?>
222 </div>
223 <div class="pvc-data-container">
224 <?php echo wp_kses( $item['content'], $allowed_html ); ?>
225 <span class="spinner"></span>
226 </div>
227 <div class="pvc-dashboard-content-bottom">
228 <div class="pvc-date-nav pvc-months">
229 <?php
230 // generate dates
231 echo wp_kses_post( $this->generate_months( current_time( 'timestamp', false ), $item['id'] ) );
232 ?>
233 </div>
234 <?php do_action( 'pvc_dashboard_widget_content_bottom', $item['id'] ); ?>
235 </div>
236 </div>
237 </div>
238 </div>
239
240 <?php
241 // Output current buffer
242 return ob_get_clean();
243 }
244
245 /**
246 * Render dashboard widget with post views.
247 *
248 * @return void
249 */
250 public function dashboard_post_views_chart() {
251 if ( ! apply_filters( 'pvc_user_can_see_stats', current_user_can( 'publish_posts' ) ) || ! check_ajax_referer( 'pvc-dashboard-widget', 'nonce' ) )
252 wp_die( __( 'You do not have permission to access this page.', 'post-views-counter' ) );
253
254 // get period
255 $period = isset( $_POST['period'] ) && ! empty( $_POST['period'] ) ? preg_replace( '/[^a-z0-9_|]/', '', $_POST['period'] ) : apply_filters( 'pvc_dashboard_widget_default_period', 'this_month', 'post-views' );
256
257 // get post types
258 $post_types = Post_Views_Counter()->options['general']['post_types_count'];
259
260 // empty options?
261 if ( empty( $post_types ) || ! is_array( $post_types ) )
262 $post_types = [];
263
264 // sanitize post_types
265 $post_types = map_deep( $post_types, 'sanitize_text_field' );
266
267 // get dashboard user options
268 $user_options = $this->get_dashboard_user_options( get_current_user_id(), 'post_types' );
269
270 // empty options?
271 if ( empty( $user_options ) || ! is_array( $user_options ) )
272 $user_options = [];
273
274 // sanitize options
275 $user_options = map_deep( $user_options, 'sanitize_text_field' );
276
277 // get colors
278 $colors = Post_Views_Counter()->functions->get_colors();
279
280 // parameters to be used in filter
281 $args = [
282 'widget' => 'post_views',
283 'period' => $period,
284 'post_types' => $post_types,
285 'user_options' => $user_options
286 ];
287
288 $data = [
289 'widget' => 'post-views',
290 'design' => [
291 'fill' => true,
292 'backgroundColor' => 'rgba(' . $colors['r'] . ',' . $colors['g'] . ',' . $colors['b'] . ', 0.2)',
293 'borderColor' => 'rgba(' . $colors['r'] . ',' . $colors['g'] . ',' . $colors['b'] . ', 1)',
294 'borderWidth' => 1.2,
295 'borderDash' => [],
296 'pointBorderColor' => 'rgba(' . $colors['r'] . ',' . $colors['g'] . ',' . $colors['b'] . ', 1)',
297 'pointBackgroundColor' => 'rgba(255, 255, 255, 1)',
298 'pointBorderWidth' => 1.2
299 ],
300 'data' => [
301 'datasets' => [
302 [
303 'label' => __( 'Total Views', 'post-views-counter' ),
304 'post_type' => '_pvc_total_views',
305 'hidden' => in_array( '_pvc_total_views', $user_options, true ),
306 'data' => []
307 ]
308 ]
309 ],
310 ];
311
312 // convert period
313 $time = pvc_period2timestamp( $period );
314
315 // get date chunks
316 $date = date( 'Y m W d t', $time );
317 $date_chunks = explode( ' ', $date );
318
319 // get date
320 $year = (int) $date_chunks[0];
321 $month = sanitize_text_field( $date_chunks[1] );
322 $dates_number = (int) $date_chunks[4];
323
324 // get previous date chunks
325 $previous_time = strtotime( '-1 months', $time );
326 $previous_date = date( 'Y m W d t', $previous_time );
327 $previous_date_chunks = explode( ' ', $previous_date );
328
329 // get current date
330 $current_date = date_create( 'now', wp_timezone() )->format('Y m W d t');
331 $current_date_chunks = explode( ' ', $current_date );
332
333 // generate dates
334 $data['dates'] = $this->generate_months( $time );
335
336 // generate chart data
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( apply_filters( 'pvc_dashboard_post_views_query_args',
363 [
364 'fields' => 'date=>views',
365 'post_type' => $post_type,
366 'views_query' => [
367 'year' => $year,
368 'month' => $month,
369 'hide_empty' => true
370 ]
371 ], $period
372 ) )
373 );
374 }
375
376 foreach ( $post_type_data as $post_type_id => $post_views ) {
377 foreach ( $post_views as $id => $views ) {
378 // generate chart data for specific post types
379 $data['data']['datasets'][$post_type_id]['data'][] = $views;
380
381 if ( ! array_key_exists( $id, $sum ) )
382 $sum[$id] = 0;
383
384 $sum[$id] += $views;
385 }
386 }
387 }
388
389 // this month all days
390 for ( $i = 1; $i <= $dates_number; $i++ ) {
391 // generate chart data
392 $data['data']['labels'][] = ( $i % 2 === 0 ? '' : $i );
393 $data['data']['dates'][] = date_i18n( get_option( 'date_format' ), strtotime( $year . '-' . $month . '-' . str_pad( $i, 2, '0', STR_PAD_LEFT ) ) );
394 $data['data']['datasets'][0]['data'][] = ( array_key_exists( $i - 1, $sum ) ? $sum[$i - 1] : 0 );
395 }
396
397 echo wp_json_encode( apply_filters( 'pvc_dashboard_post_views_data', $data, $args ) );
398 exit;
399 }
400
401 /**
402 * Render dashboard widget with most viewed posts.
403 *
404 * @return void
405 */
406 public function dashboard_post_most_viewed() {
407 if ( ! apply_filters( 'pvc_user_can_see_stats', current_user_can( 'publish_posts' ) ) || ! check_ajax_referer( 'pvc-dashboard-widget', 'nonce' ) )
408 wp_die( __( 'You do not have permission to access this page.', 'post-views-counter' ) );
409
410 // get main instance
411 $pvc = Post_Views_Counter();
412
413 // get post types
414 $post_types = Post_Views_Counter()->options['general']['post_types_count'];
415
416 // empty options?
417 if ( empty( $post_types ) || ! is_array( $post_types ) )
418 $post_types = [];
419
420 // sanitize post_types
421 $post_types = map_deep( $post_types, 'sanitize_text_field' );
422
423 // get period
424 $period = isset( $_POST['period'] ) && ! empty( $_POST['period'] ) ? preg_replace( '/[^a-z0-9_|]/', '', $_POST['period'] ) : apply_filters( 'pvc_dashboard_widget_default_period', 'this_month', 'post-most-viewed' );
425
426 // parameters to be used in filter
427 $args = [
428 'widget' => 'post_most_viewed',
429 'period' => $period,
430 'post_types' => $post_types
431 ];
432
433 $data = [
434 'widget' => 'post-most-viewed',
435 'html' => ''
436 ];
437
438 // convert period
439 $time = pvc_period2timestamp( $period );
440
441 // get date chunks
442 $date = date( 'Y m W d t', $time );
443 $date_chunks = explode( ' ', $date );
444
445 // get date
446 $year = (int) $date_chunks[0];
447 $month = sanitize_text_field( $date_chunks[1] );
448
449 // generate dates
450 $data['dates'] = $this->generate_months( $time );
451
452 // query args
453 $query_args = apply_filters( 'pvc_dashboard_post_most_viewed_query_args', [
454 'post_type' => $post_types,
455 'posts_per_page' => 10,
456 'paged' => false,
457 'suppress_filters' => false,
458 'no_found_rows' => true,
459 'views_query' => [
460 'year' => $year,
461 'month' => $month,
462 'hide_empty' => true
463 ]
464 ], $period );
465
466 $posts = pvc_get_most_viewed_posts( $query_args );
467
468 $html = '
469 <table id="pvc-post-most-viewed-table" class="pvc-table pvc-table-hover">
470 <thead>
471 <tr>
472 <th scope="col">#</th>
473 <th scope="col">' . esc_html__( 'Post', 'post-views-counter' ) . '</th>
474 <th scope="col">' . esc_html__( 'Views', 'post-views-counter' ) . '</th>
475 </tr>
476 </thead>
477 <tbody>';
478
479 if ( $posts ) {
480 // active post types
481 $active_post_types = [];
482
483 foreach ( $posts as $index => $post ) {
484 setup_postdata( $post );
485
486 $html .= '
487 <tr>
488 <th scope="col">' . ( $index + 1 ) . '</th>';
489
490 // check post type existence
491 if ( array_key_exists( $post->post_type, $active_post_types ) )
492 $post_type_exists = $active_post_types[$post->post_type];
493 else
494 $post_type_exists = $active_post_types[$post->post_type] = post_type_exists( $post->post_type );
495
496 $title = get_the_title( $post );
497
498 if ( $title === '' )
499 $title = __( '(no title)' );
500
501 // post link
502 $link = '<a href="' . esc_url( get_permalink( $post->ID ) ) . '" target="_blank">' . esc_html( $title ) . '</a>';
503
504 // edit post link
505 if ( $post_type_exists && current_user_can( 'edit_post', $post->ID ) ) {
506 $link .= ' <a href="' . esc_url( get_edit_post_link( $post->ID ) ) . '" class="cn-edit-link" target="_blank">' . esc_html__( 'Edit', 'post-views-counter' ) . '</a>';
507 }
508
509 $html .= '
510 <td>' . $link . '</td>';
511
512 $html .= '
513 <td>' . number_format_i18n( $post->post_views ) . '</td>
514 </tr>';
515 }
516 } else {
517 $html .= '
518 <tr class="no-posts">
519 <td colspan="3">' . esc_html__( 'No most viewed posts found.', 'post-views-counter' ) . '</td>
520 </tr>';
521 }
522
523 $html .= '
524 </tbody>
525 </table>';
526
527 $data['html'] = $html;
528
529 echo wp_json_encode( apply_filters( 'pvc_dashboard_post_most_viewed_data', $data, $args ) );
530 exit;
531 }
532
533 /**
534 * Generate dashboard widget months HTML.
535 *
536 * @param int $timestamp
537 * @return string
538 */
539 public function generate_months( $timestamp, $item = '' ) {
540 $dates = [
541 explode( ' ', date( 'm F Y', strtotime( '-1 months', $timestamp ) ) ),
542 explode( ' ', date( 'm F Y', $timestamp ) ),
543 explode( ' ', date( 'm F Y', strtotime( '+1 months', $timestamp ) ) )
544 ];
545
546 $current = date( 'Ym', current_time( 'timestamp', false ) );
547
548 if ( (int) $current <= (int) ( $dates[1][2] . $dates[1][0] ) )
549 $next = '<span class="next">' . $dates[2][1] . ' ' . $dates[2][2] . ' ›</span>';
550 else
551 $next = '<a class="next" href="#" data-date="' . ( $dates[2][2] . $dates[2][0] ) . '">' . $dates[2][1] . ' ' . $dates[2][2] . ' ›</a>';
552
553 $dates_formatted = apply_filters( 'pvc_dashboard_widget_generate_months_formatted', [
554 'prev' => '<a class="prev" href="#" data-date="' . ( $dates[0][2] . $dates[0][0] ) . '">‹ ' . $dates[0][1] . ' ' . $dates[0][2] . '</a>',
555 'current' => '<span class="current">' . $dates[1][1] . ' ' . $dates[1][2] . '</span>',
556 'next' => $next
557 ], $timestamp, $item );
558
559 return wp_kses_post( apply_filters( 'pvc_dashboard_widget_generate_months_html', $dates_formatted['prev'] . $dates_formatted['current'] . $dates_formatted['next'], $timestamp, $item ) );
560 }
561
562 /**
563 * Update dashboard widget user options.
564 *
565 * @return void
566 */
567 public function update_dashboard_user_options() {
568 if ( ! check_ajax_referer( 'pvc-dashboard-user-options', 'nonce' ) )
569 wp_die( __( 'You do not have permission to access this page.', 'post-views-counter' ) );
570
571 // valid data?
572 if ( isset( $_POST['nonce'], $_POST['options'] ) && ! empty( $_POST['options'] ) ) {
573 // get sanitized options
574 $update = map_deep( $_POST['options'], 'sanitize_text_field' );
575
576 // get user ID
577 $user_id = get_current_user_id();
578
579 // get user dashboard data
580 $user_options = get_user_meta( $user_id, 'pvc_dashboard', true );
581
582 // empty userdata?
583 if ( ! is_array( $user_options ) || empty( $user_options ) )
584 $user_options = [];
585
586 // empty post types?
587 if ( ! array_key_exists( 'post_types', $user_options ) || ! is_array( $user_options['post_types'] ) )
588 $user_options['post_types'] = [];
589
590 // hide post type?
591 if ( ! empty( $update['post_type'] ) ) {
592 // get allowed post types
593 $allowed_post_types = Post_Views_Counter()->options['general']['post_types_count'];
594
595 // simulate total post views as post type
596 $allowed_post_types[] = '_pvc_total_views';
597
598 if ( in_array( $update['post_type'], $allowed_post_types, true ) ) {
599 if ( isset( $update['hidden'] ) && $update['hidden'] === 'true' ) {
600 if ( ! in_array( $update['post_type'], $user_options['post_types'], true ) )
601 $user_options['post_types'][] = $update['post_type'];
602 } else {
603 if ( ( $key = array_search( $update['post_type'], $user_options['post_types'] ) ) !== false )
604 unset( $user_options['post_types'][$key] );
605 }
606 }
607 }
608
609 // empty menu items?
610 if ( ! array_key_exists( 'menu_items', $user_options ) || ! is_array( $user_options['menu_items'] ) )
611 $user_options['menu_items'] = [];
612
613 if ( ! empty( $update['menu_items'] ) && is_array( $update['menu_items'] ) ) {
614 $user_options['menu_items'] = [];
615
616 // get allowed menu items
617 $allowed_menu_items = array_column( $this->widget_items, 'id' );
618
619 foreach ( $update['menu_items'] as $menu_item => $hidden ) {
620 if ( in_array( $menu_item, $allowed_menu_items, true ) && $hidden === 'true' )
621 $user_options['menu_items'][] = $menu_item;
622 }
623 }
624
625 // filter user options
626 $user_options = apply_filters( 'pvc_update_dashboard_user_options', $user_options, $update, $user_id );
627
628 // update userdata
629 update_user_meta( $user_id, 'pvc_dashboard', $user_options );
630
631 echo wp_send_json_success();
632 }
633
634 echo wp_send_json_error();
635 exit;
636 }
637
638 /**
639 * Get user dashboard data.
640 *
641 * @param int $user_id
642 * @param string $data_type
643 * @return array
644 */
645 public function get_dashboard_user_options( $user_id = 0, $data_type = '' ) {
646 $user_options = get_user_meta( $user_id, 'pvc_dashboard', true );
647
648 if ( ! is_array( $user_options ) || empty( $user_options ) )
649 $user_options = [];
650
651 if ( ! array_key_exists( $data_type, $user_options ) || ! is_array( $user_options[$data_type] ) )
652 $user_options[$data_type] = [];
653
654 return $user_options[$data_type];
655 }
656
657 /**
658 * Convert period to timestamp.
659 *
660 * @deprecated
661 * @param string $period
662 * @return int
663 */
664 public function period2timestamp( $period ) {
665 return pvc_period2timestamp( $period );
666 }
667 }
668