PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.8
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.8
1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 0.8.6 All 33 releases
desktop-mode / includes / widgets / widget-site-views.php

widget-site-views.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.8, at includes/widgets/widget-site-views.php

158 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OpenStation — Site Views Widget.
4 *
5 * Sparkline graph of page views over the last 7 days with
6 * week-over-week delta. Tries Jetpack Stats first, falls back
7 * to a _post_views_YYYY-MM-DD meta-key aggregator.
8 *
9 * Refresh: every 10 minutes.
10 * Requires: OpenStation 0.18.0+ (openstation_register_widget).
11 *
12 * @package OpenStation
13 */
14
15 defined( 'ABSPATH' ) || exit;
16
17 /**
18 * Register the REST endpoint that aggregates per-post view counts
19 * from the _post_views_YYYY-MM-DD meta key (plain-WP fallback).
20 *
21 * Route: GET /desktop-mode/v1/site-views-meta
22 * Permission: edit_posts.
23 */
24 function openstation_register_site_views_rest_route() {
25 register_rest_route(
26 'desktop-mode/v1',
27 '/site-views-meta',
28 array(
29 'methods' => WP_REST_Server::READABLE,
30 'callback' => 'openstation_site_views_meta_callback',
31 'permission_callback' => static function () {
32 return current_user_can( 'edit_posts' );
33 },
34 )
35 );
36 }
37 add_action( 'rest_api_init', 'openstation_register_site_views_rest_route' );
38
39 /**
40 * Aggregate _post_views_YYYY-MM-DD meta across all posts for 14 days.
41 *
42 * The result is cached in a 5-minute transient: the aggregation runs
43 * 14 SUM() queries over postmeta, the widget only refreshes every
44 * 10 minutes, and the data is site-wide (not per-user) — so every
45 * concurrent viewer can share one computation. View counts accrue
46 * continuously, so a short TTL is the invalidation strategy; no
47 * event-based purge is needed.
48 *
49 * @param WP_REST_Request $request REST request.
50 * @return array
51 */
52 function openstation_site_views_meta_callback( $request ) {
53 global $wpdb;
54
55 $cached = get_transient( 'desktop_mode_site_views_meta' );
56 if ( is_array( $cached ) ) {
57 return $cached;
58 }
59
60 $rows = array();
61 $today = current_time( 'Y-m-d' );
62
63 for ( $i = 0; $i < 14; $i++ ) {
64 $date = gmdate( 'Y-m-d', strtotime( $today . ' -' . $i . ' days' ) );
65 $meta_key = '_post_views_' . $date;
66 $total = (int) $wpdb->get_var(
67 $wpdb->prepare(
68 "SELECT COALESCE( SUM( CAST( meta_value AS UNSIGNED ) ), 0 )
69 FROM {$wpdb->postmeta}
70 WHERE meta_key = %s",
71 $meta_key
72 )
73 );
74 $rows[] = array(
75 'date' => $date,
76 'views' => $total,
77 );
78 }
79
80 $has_data = array_sum( array_column( $rows, 'views' ) ) > 0;
81
82 $result = array(
83 'source' => 'post-meta',
84 'has_data' => $has_data,
85 'days' => array_reverse( $rows ),
86 );
87
88 set_transient( 'desktop_mode_site_views_meta', $result, 5 * MINUTE_IN_SECONDS );
89
90 return $result;
91 }
92
93 /**
94 * Register the JS + CSS assets.
95 */
96 function openstation_register_site_views_widget_assets() {
97 $suffix = openstation_asset_suffix();
98 $version = defined( 'OPENSTATION_VERSION' ) ? OPENSTATION_VERSION : '0';
99
100 $js_path = OPENSTATION_DIR . 'assets/js/widget-site-views' . $suffix . '.js';
101 $css_path = OPENSTATION_DIR . 'assets/js/widget-site-views' . $suffix . '.css';
102
103 wp_register_style(
104 'os-site-views-widget',
105 OPENSTATION_URL . 'assets/js/widget-site-views' . $suffix . '.css',
106 array(),
107 file_exists( $css_path ) ? (string) filemtime( $css_path ) : $version
108 );
109
110 wp_register_script(
111 'os-site-views-widget',
112 OPENSTATION_URL . 'assets/js/widget-site-views' . $suffix . '.js',
113 array( 'wp-api-fetch' ),
114 file_exists( $js_path ) ? (string) filemtime( $js_path ) : $version,
115 true
116 );
117 }
118 add_action( 'init', 'openstation_register_site_views_widget_assets', 5 );
119
120 /**
121 * Eagerly enqueue the CSS on shell pages.
122 */
123 function openstation_enqueue_site_views_widget_styles() {
124 if ( function_exists( 'openstation_is_enabled' ) && ! openstation_is_enabled() ) {
125 return;
126 }
127 if ( function_exists( 'openstation_is_chromeless_request' ) && openstation_is_chromeless_request() ) {
128 return;
129 }
130 wp_enqueue_style( 'os-site-views-widget' );
131 }
132 add_action( 'admin_enqueue_scripts', 'openstation_enqueue_site_views_widget_styles', 20 );
133
134 /**
135 * Register the widget definition.
136 */
137 function openstation_register_site_views_widget() {
138 if ( ! function_exists( 'openstation_register_widget' ) ) {
139 return;
140 }
141 openstation_register_widget(
142 'desktop-mode/site-views',
143 array(
144 'label' => __( 'Site Views', 'desktop-mode' ),
145 'description' => __( 'Sparkline of page views over the last 7 days with week-over-week delta.', 'desktop-mode' ),
146 'icon' => 'dashicons-chart-area',
147 'script' => 'os-site-views-widget',
148 'movable' => true,
149 'resizable' => true,
150 'min_width' => 240,
151 'min_height' => 160,
152 'default_width' => 300,
153 'default_height' => 200,
154 )
155 );
156 }
157 add_action( 'init', 'openstation_register_site_views_widget', 6 );
158