PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.10
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.10
1.1.10 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 All 34 releases
← All changes | includes/devtools.php +47 -41 0.9.81.1.10 View file →
@@ -1,7 +1,7 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode — DevTools / debug bus.
3 + * OpenStation — DevTools / debug bus.
4 4 *
5 5 * Provides a generic per-session pub/sub channel that plugins use to
6 6 * stream debug data (SQL queries, HTTP timings, hook traces, custom
7 7 * events) from a server-side capture into a client-side inspector
@@ -9,27 +9,27 @@
9 9 *
10 10 * Architecture:
11 11 *
12 12 * 1. Inspector plugin allocates a session id with
13 - * `wp.desktop.devtools.debug.startSession()` and decides which
13 + * `wp.os.devtools.debug.startSession()` and decides which
14 14 * channels it cares about (`'query'`, `'log'`, …).
15 15 * 2. Inspector contributes `X-WP-Debug-Session: <id>` to the
16 16 * target window via
17 - * `wp.desktop.devtools.addRequestHeader( windowId, 'X-WP-Debug-Session', sessionId )`.
17 + * `wp.os.devtools.addRequestHeader( windowId, 'X-WP-Debug-Session', sessionId )`.
18 18 * 3. The target window's iframe attaches that header to every
19 19 * fetch / XHR / sendBeacon (the chromeless inline bridge merges
20 20 * contributed headers into outgoing requests).
21 21 * 4. Server-side capture hooks read the header via
22 - * {@see desktop_mode_debug_session_for_request()}, run their
22 + * {@see openstation_debug_session_for_request()}, run their
23 23 * capture (SAVEQUERIES, output buffering, etc.), and publish via
24 - * {@see desktop_mode_debug_publish()}.
24 + * {@see openstation_debug_publish()}.
25 25 * 5. Inspector subscribes via
26 - * `wp.desktop.devtools.debug.subscribe( sessionId, channel, cb )`.
26 + * `wp.os.devtools.debug.subscribe( sessionId, channel, cb )`.
27 27 * The shell polls `GET /desktop-mode/v1/debug` every second and
28 28 * replays new events to subscribers.
29 29 *
30 30 * Storage: a per-session ring buffer in a transient. Bounded by
31 - * {@see DESKTOP_MODE_DEBUG_RING_SIZE} so a misconfigured capture
31 + * {@see OPENSTATION_DEBUG_RING_SIZE} so a misconfigured capture
32 32 * loop can't fill the database. TTL is 1 hour — long enough for an
33 33 * inspector session to span a few page loads, short enough that
34 34 * abandoned sessions don't squat indefinitely.
35 35 *
@@ -37,9 +37,9 @@
37 37 * logged-in AND hold `manage_options`. Debug data leaks request /
38 38 * response details (query parameters, internal IDs) — locking it to
39 39 * site admins matches the cost of getting that wrong.
40 40 *
41 - * @package WPDesktopMode
41 + * @package OpenStation
42 42 */
43 43
44 44 defined( 'ABSPATH' ) || exit;
45 45
@@ -50,9 +50,9 @@
50 50 * page loads) survives on the buffer without truncation. Anything
51 51 * higher and a single transient row starts to push the row-size
52 52 * sanity threshold for typical wp_options storage.
53 53 */
54 -const DESKTOP_MODE_DEBUG_RING_SIZE = 500;
54 +const OPENSTATION_DEBUG_RING_SIZE = 500;
55 55
56 56 /**
57 57 * Transient TTL for a session ring buffer, in seconds.
58 58 *
@@ -58,9 +58,9 @@
58 58 *
59 59 * One hour. Inspector windows that stay open longer than that should
60 60 * heartbeat by republishing — at which point the TTL extends.
61 61 */
62 -const DESKTOP_MODE_DEBUG_SESSION_TTL = 3600;
62 +const OPENSTATION_DEBUG_SESSION_TTL = 3600;
63 63
64 64 /**
65 65 * Build the transient key for a (session, channel) pair.
66 66 *
@@ -67,10 +67,10 @@
67 67 * @param string $session_id Session id (as supplied by the client).
68 68 * @param string $channel Channel name (`'query'`, `'log'`, …).
69 69 * @return string Transient key safe for `set_transient`.
70 70 */
71 -function desktop_mode_debug_transient_key( $session_id, $channel ) {
72 - return 'desktop_mode_dbg_' . md5( (string) $session_id . '|' . (string) $channel );
71 +function openstation_debug_transient_key( $session_id, $channel ) {
72 + return 'openstation_dbg_' . md5( (string) $session_id . '|' . (string) $channel );
73 73 }
74 74
75 75 /**
76 76 * Read the debug session id from the current request's headers.
@@ -86,9 +86,9 @@
86 86 * a tight gate for `crypto.randomUUID()`-shaped ids.
87 87 *
88 88 * @return string Session id, or '' when absent / invalid.
89 89 */
90 -function desktop_mode_debug_session_for_request() {
90 +function openstation_debug_session_for_request() {
91 91 $raw = '';
92 92 if ( isset( $_SERVER['HTTP_X_WP_DEBUG_SESSION'] ) ) {
93 93 $raw = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_WP_DEBUG_SESSION'] ) );
94 94 }
@@ -109,9 +109,9 @@
109 109 * Publish a payload onto a (session, channel).
110 110 *
111 111 * The newest event is appended to the ring buffer; once the cap is
112 112 * reached, the oldest events are dropped FIFO. Fires the
113 - * `desktop_mode_debug_publish` action so observability widgets can
113 + * `openstation_debug_publish` action so observability widgets can
114 114 * tail the stream synchronously without going through the REST poll.
115 115 *
116 116 * @param string $session_id Session id from the client.
117 117 * @param string $channel Channel name. Free-form; convention is
@@ -121,15 +121,15 @@
121 121 * @return bool True when the event was appended (queued for storage);
122 122 * false only when `$session_id` or `$channel` is empty.
123 123 * `set_transient()` failures are not detected.
124 124 */
125 -function desktop_mode_debug_publish( $session_id, $channel, $payload ) {
125 +function openstation_debug_publish( $session_id, $channel, $payload ) {
126 126 $session_id = (string) $session_id;
127 127 $channel = (string) $channel;
128 128 if ( '' === $session_id || '' === $channel ) {
129 129 return false;
130 130 }
131 - $key = desktop_mode_debug_transient_key( $session_id, $channel );
131 + $key = openstation_debug_transient_key( $session_id, $channel );
132 132 $existing = get_transient( $key );
133 133 if ( ! is_array( $existing ) ) {
134 134 $existing = array(
135 135 'next_id' => 0,
@@ -135,11 +135,11 @@
135 135 'next_id' => 0,
136 136 'events' => array(),
137 137 );
138 138 }
139 - $next_id = isset( $existing['next_id'] ) ? (int) $existing['next_id'] : 0;
140 - $next_id++;
141 - $existing['next_id'] = $next_id;
139 + $next_id = isset( $existing['next_id'] ) ? (int) $existing['next_id'] : 0;
140 + ++$next_id;
141 + $existing['next_id'] = $next_id;
142 142 $existing['events'][] = array(
143 143 'id' => $next_id,
144 144 't' => (int) round( microtime( true ) * 1000 ),
145 145 'channel' => $channel,
@@ -144,16 +144,16 @@
144 144 't' => (int) round( microtime( true ) * 1000 ),
145 145 'channel' => $channel,
146 146 'payload' => $payload,
147 147 );
148 - $max = (int) apply_filters( 'desktop_mode_debug_ring_size', DESKTOP_MODE_DEBUG_RING_SIZE );
148 + $max = (int) apply_filters( 'openstation_debug_ring_size', OPENSTATION_DEBUG_RING_SIZE );
149 149 if ( $max < 1 ) {
150 - $max = DESKTOP_MODE_DEBUG_RING_SIZE;
150 + $max = OPENSTATION_DEBUG_RING_SIZE;
151 151 }
152 152 if ( count( $existing['events'] ) > $max ) {
153 153 $existing['events'] = array_slice( $existing['events'], -$max );
154 154 }
155 - set_transient( $key, $existing, DESKTOP_MODE_DEBUG_SESSION_TTL );
155 + set_transient( $key, $existing, OPENSTATION_DEBUG_SESSION_TTL );
156 156
157 157 /**
158 158 * Fires after a debug event is appended to the ring buffer.
159 159 *
@@ -164,9 +164,9 @@
164 164 * @param string $session_id Session id from the publishing call.
165 165 * @param string $channel Channel name.
166 166 * @param mixed $payload Published payload.
167 167 */
168 - do_action( 'desktop_mode_debug_publish', $session_id, $channel, $payload );
168 + do_action( 'openstation_debug_publish', $session_id, $channel, $payload );
169 169 return true;
170 170 }
171 171
172 172 /**
@@ -181,12 +181,15 @@
181 181 * @param int $since Highest id the client has seen.
182 182 * @param string|null $channel Optional channel filter.
183 183 * @return array
184 184 */
185 -function desktop_mode_debug_drain( $session_id, $since = 0, $channel = null ) {
185 +function openstation_debug_drain( $session_id, $since = 0, $channel = null ) {
186 186 $session_id = (string) $session_id;
187 187 if ( '' === $session_id ) {
188 - return array( 'events' => array(), 'cursor' => (int) $since );
188 + return array(
189 + 'events' => array(),
190 + 'cursor' => (int) $since,
191 + );
189 192 }
190 193
191 194 $channels = array();
192 195 if ( null !== $channel && '' !== (string) $channel ) {
@@ -195,11 +198,11 @@
195 198 // Without a channel filter the client wants every channel for
196 199 // this session. We don't keep an index of channels per session
197 200 // (would double-write on every publish); instead we let the
198 201 // caller pass a list, OR fan out via the
199 - // `desktop_mode_debug_channels` filter for plugins that know
202 + // `openstation_debug_channels` filter for plugins that know
200 203 // their full set up-front.
201 - $declared = apply_filters( 'desktop_mode_debug_channels', array(), $session_id );
204 + $declared = apply_filters( 'openstation_debug_channels', array(), $session_id );
202 205 if ( is_array( $declared ) ) {
203 206 foreach ( $declared as $ch ) {
204 207 if ( is_string( $ch ) && '' !== $ch ) {
205 208 $channels[] = $ch;
@@ -210,9 +213,9 @@
210 213
211 214 $cursor = (int) $since;
212 215 $out = array();
213 216 foreach ( $channels as $ch ) {
214 - $key = desktop_mode_debug_transient_key( $session_id, $ch );
217 + $key = openstation_debug_transient_key( $session_id, $ch );
215 218 $data = get_transient( $key );
216 219 if ( ! is_array( $data ) || empty( $data['events'] ) ) {
217 220 continue;
218 221 }
@@ -238,9 +241,12 @@
238 241 static function ( $a, $b ) {
239 242 return ( (int) $a['id'] ) - ( (int) $b['id'] );
240 243 }
241 244 );
242 - return array( 'events' => $out, 'cursor' => $cursor );
245 + return array(
246 + 'events' => $out,
247 + 'cursor' => $cursor,
248 + );
243 249 }
244 250
245 251 /**
246 252 * REST: GET /desktop-mode/v1/debug
@@ -246,15 +252,15 @@
246 252 * REST: GET /desktop-mode/v1/debug
247 253 *
248 254 * Returns events newer than `since` for the given session id.
249 255 * Supports both `channel=foo` (single) and `channels[]=foo&channels[]=bar`
250 - * (list); falls back to the `desktop_mode_debug_channels` filter
256 + * (list); falls back to the `openstation_debug_channels` filter
251 257 * when no channel param is supplied.
252 258 *
253 259 * @param WP_REST_Request $request REST request.
254 260 * @return WP_REST_Response
255 261 */
256 -function desktop_mode_rest_debug_drain( WP_REST_Request $request ) {
262 +function openstation_rest_debug_drain( WP_REST_Request $request ) {
257 263 $session_id = (string) $request->get_param( 'sessionId' );
258 264 $since = (int) $request->get_param( 'since' );
259 265 $channel = $request->get_param( 'channel' );
260 266 $channels = $request->get_param( 'channels' );
@@ -260,12 +266,12 @@
260 266 $channels = $request->get_param( 'channels' );
261 267
262 268 if ( is_array( $channels ) && count( $channels ) > 0 ) {
263 269 // Multi-channel drain — concatenate the per-channel results.
264 - $cursor = $since;
270 + $cursor = $since;
265 271 $all_events = array();
266 272 foreach ( $channels as $ch ) {
267 - $result = desktop_mode_debug_drain( $session_id, $since, (string) $ch );
273 + $result = openstation_debug_drain( $session_id, $since, (string) $ch );
268 274 foreach ( $result['events'] as $ev ) {
269 275 $all_events[] = $ev;
270 276 }
271 277 if ( $result['cursor'] > $cursor ) {
@@ -285,9 +291,9 @@
285 291 )
286 292 );
287 293 }
288 294
289 - $result = desktop_mode_debug_drain(
295 + $result = openstation_debug_drain(
290 296 $session_id,
291 297 $since,
292 298 is_string( $channel ) ? $channel : null
293 299 );
@@ -299,13 +305,13 @@
299 305 *
300 306 * Logged-in admins only — debug data exposes internal request shapes
301 307 * that should never leak to lower-privileged users. Plugins that need
302 308 * to relax this for a specific session can hook the
303 - * `desktop_mode_debug_rest_permission` filter (filters TRUE/FALSE).
309 + * `openstation_debug_rest_permission` filter (filters TRUE/FALSE).
304 310 *
305 311 * @return bool
306 312 */
307 -function desktop_mode_rest_debug_permission() {
313 +function openstation_rest_debug_permission() {
308 314 $allowed = is_user_logged_in() && current_user_can( 'manage_options' );
309 315 /**
310 316 * Filter the permission decision for the debug REST endpoint.
311 317 *
@@ -310,15 +316,15 @@
310 316 * Filter the permission decision for the debug REST endpoint.
311 317 *
312 318 * @param bool $allowed Default: caller is a logged-in admin.
313 319 */
314 - return (bool) apply_filters( 'desktop_mode_debug_rest_permission', $allowed );
320 + return (bool) apply_filters( 'openstation_debug_rest_permission', $allowed );
315 321 }
316 322
317 323 /**
318 324 * Register the debug REST routes.
319 325 */
320 -function desktop_mode_register_debug_rest_routes() {
326 +function openstation_register_debug_rest_routes() {
321 327 register_rest_route(
322 328 'desktop-mode/v1',
323 329 '/debug',
324 330 array(
@@ -323,10 +329,10 @@
323 329 '/debug',
324 330 array(
325 331 array(
326 332 'methods' => WP_REST_Server::READABLE,
327 - 'callback' => 'desktop_mode_rest_debug_drain',
328 - 'permission_callback' => 'desktop_mode_rest_debug_permission',
333 + 'callback' => 'openstation_rest_debug_drain',
334 + 'permission_callback' => 'openstation_rest_debug_permission',
329 335 'args' => array(
330 336 'sessionId' => array(
331 337 'required' => true,
332 338 'type' => 'string',
@@ -346,5 +352,5 @@
346 352 ),
347 353 )
348 354 );
349 355 }
350 -add_action( 'rest_api_init', 'desktop_mode_register_debug_rest_routes' );
356 +add_action( 'rest_api_init', 'openstation_register_debug_rest_routes' );