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/my-wordpress/window.php +69 -149 1.0.11.1.10 View file →
@@ -1,31 +1,27 @@
1 1 <?php
2 2 /**
3 - * OpenStation — My WordPress: window + pinned icon registration.
3 + * OpenStation — My WordPress: the explorer's identity + shared helpers.
4 4 *
5 - * Native window with id `desktop-mode-my-wordpress`, opened from a
6 - * pinned desktop icon that always sits in the top-left of the grid
7 - * (`pinned: true`, `position: -1`). The bundle renders a two-pane
8 - * file-explorer UI with breadcrumb navigation: root shows Posts,
9 - * Pages, Users, and Media folder tiles, and clicking one drills into
10 - * an infinite-scroll list of entities with a per-kind preview pane.
5 + * The app people open is `apps/my-wordpress/` — WP Explorer, rebuilt
6 + * on the App Framework. This module keeps what the port shares: the
7 + * name and the folder-mark icon (the app reads both from the helpers
8 + * here), the capability gate, and the inert entities compatibility
9 + * surface (see the note at the end of the file).
11 10 *
12 11 * **The app is called WP Explorer; the module is called my-wordpress.**
13 - * The display name is the only thing that changed — the window id, the
14 - * icon id, the script and style handles, the function prefix and every
15 - * `openstation_my_wordpress_*` filter are the names plugins and stored
16 - * desktop layouts already reference, so they stay put. See the frozen-
17 - * values rule in AGENTS.md; renaming any of them here would orphan a
18 - * user's pinned tile rather than move it.
12 + * The function prefix and every `openstation_my_wordpress_*` filter
13 + * are names plugins already reference — the frozen-values rule in
14 + * AGENTS.md keeps them put.
19 15 *
20 - * Filterable surface (mirrors the recycle-bin / posts-window modules):
16 + * Filterable surface:
21 17 *
22 - * - `openstation_my_wordpress_window_args`
23 - * - `openstation_my_wordpress_icon_args`
24 18 * - `openstation_my_wordpress_user_can_use`
25 - * - `openstation_my_wordpress_entities`
26 - * - `openstation_my_wordpress_template_html`
19 + * - `openstation_my_wordpress_entities` (inert — see the end note)
27 20 *
21 + * (`openstation_my_wordpress_icon_args`, `_window_args` and
22 + * `_template_html` went with the legacy window they configured.)
23 + *
28 24 * @package OpenStation
29 25 */
30 26
31 27 defined( 'ABSPATH' ) || exit;
@@ -95,8 +91,37 @@
95 91 *
96 92 * Mirrors the recycle-bin gate — anyone who can edit posts can
97 93 * browse posts and pages.
98 94 *
95 + * This is the module's one capability gate, and it is a **server-side
96 + * authorization** gate, not just a visibility one. It decides:
97 + *
98 + * - The non-REST post-type bridge: whether
99 + * `desktop-mode/v1/post-type/<slug>` routes register at all
100 + * (`rest-post-type.php`).
101 + * - The per-comment dossier route
102 + * `desktop-mode/v1/comment-stats/<id>` (`comment-stats.php`).
103 + * - The user and term dossier routes
104 + * `desktop-mode/v1/user-stats/<id>`,
105 + * `desktop-mode/v1/user-footprint/<id>` and
106 + * `desktop-mode/v1/term-stats/<taxonomy>/<id>` (`user-stats.php`,
107 + * `user-footprint.php`, `term-stats.php`), which then scope their
108 + * payloads to what the caller may read.
109 + * - Whether the WooCommerce integration's boot config ships, so the
110 + * client can reach the order / customer / product surfaces at all
111 + * — those routes still enforce their own Woo capabilities on top
112 + * (`integrations/woocommerce.php`).
113 + * - Whether preview-action scripts registered by plugins are
114 + * enqueued (`preview-actions.php`).
115 + * - Whether Station Home offers the "WP Explorer" quick action
116 + * (`apps/station-home/parts/snapshot.php`).
117 + *
118 + * It does **not** gate the app's own window or pinned launcher: WP
119 + * Explorer is an App Framework app and declares
120 + * `->capabilities( 'edit_posts' )` itself (`apps/my-wordpress/`).
121 + * Returning `true` here opens the surfaces above without opening the
122 + * window; to move the window too, filter the app's manifest.
123 + *
99 124 * @return bool
100 125 */
101 126 function openstation_my_wordpress_user_can_use() {
102 127 $can = current_user_can( 'edit_posts' );
@@ -101,10 +126,10 @@
101 126 function openstation_my_wordpress_user_can_use() {
102 127 $can = current_user_can( 'edit_posts' );
103 128
104 129 /**
105 - * Filter whether the current user can see the My WordPress
106 - * pinned icon and window.
130 + * Filter whether the current user can reach the My WordPress
131 + * module's surfaces — its REST routes included.
107 132 *
108 133 * @param bool $can Default: edit_posts capability.
109 134 */
110 135 return (bool) apply_filters( 'openstation_my_wordpress_user_can_use', $can );
@@ -182,8 +207,15 @@
182 207 * - `kind` — render strategy (`'post'` default, `'user'`, `'media'`).
183 208 * - `post_type` — WP post-type slug for cross-window broadcast topic `os.<slug>.changed`.
184 209 * - `thumbnails` — set false to keep the section icon on every tile
185 210 * instead of the entity's featured image.
211 + * - `editAction` — who edits this section's rows. A preview-action id
212 + * (see `openstation_my_wordpress_preview_actions`)
213 + * replaces "Open in editor" everywhere — pane button,
214 + * context-menu open entry, tile double-click. `false`
215 + * removes every edit affordance (double-click falls
216 + * back to the detail dossier; the bulk "Edit…" modal
217 + * is suppressed). Omit for the classic editor.
186 218 * - `group` — folder id this section nests under at the root
187 219 * (null / omitted renders it loose at the root).
188 220 * - `groupLabel` — folder label. `groupIcon`, `groupOrder` follow.
189 221 *
@@ -192,134 +224,22 @@
192 224 $filtered = apply_filters( 'openstation_my_wordpress_entities', $entities );
193 225 return is_array( $filtered ) ? array_values( $filtered ) : $entities;
194 226 }
195 227
196 -/**
197 - * Render the My WordPress window's static template body. The bundle
198 - * mounts its UI into `[data-os-my-wordpress-root]`.
228 +/*
229 + * No window, no template, no launcher. The explorer people open is
230 + * the `my-wordpress` APP (`apps/my-wordpress/`), which reclaimed the
231 + * "WP Explorer" name and the folder mark from this module's helpers
232 + * above. The legacy native window, its bundle and its pinned icon are
233 + * gone; every deep surface it used to host moved with the port — the
234 + * detail dossiers and the activity footprint render inside the app,
235 + * "open this object" travels through the shared stores in
236 + * `src/open-targets/explorer-open.ts` / `footprint-target.ts`, and
237 + * the Recycle Bin trashes dropped rows by their payload's `restPath`.
238 + *
239 + * `openstation_my_wordpress_entities()` and its filter remain as an
240 + * inert compatibility surface: subscribers registered against them
241 + * (WooCommerce's own among them) still run, and the pure helpers are
242 + * still what the tests pin — but nothing consumes the list to build a
243 + * window any more. The `openstation_my_wordpress_window_args` /
244 + * `openstation_my_wordpress_template_html` filters no longer fire.
199 245 */
200 -function openstation_my_wordpress_render_template() {
201 - ob_start();
202 - ?>
203 - <div class="desktop-mode-my-wordpress" data-os-my-wordpress-root>
204 - <header data-os-my-wordpress-breadcrumbs></header>
205 - <div class="os-my-wordpress__body" data-os-my-wordpress-body>
206 - <div class="os-my-wordpress__loading" data-os-my-wordpress-loading hidden>
207 - <os-spinner></os-spinner>
208 - </div>
209 - </div>
210 - <div class="os-folder-status-bar" data-os-my-wordpress-status></div>
211 - </div>
212 - <?php
213 - $html = (string) ob_get_clean();
214 -
215 - /**
216 - * Filter the My WordPress window's template HTML.
217 - *
218 - * @param string $html Default template HTML.
219 - */
220 - $filtered = (string) apply_filters( 'openstation_my_wordpress_template_html', $html );
221 -
222 - $allowed_html = function_exists( 'openstation_native_window_allowed_html' )
223 - ? openstation_native_window_allowed_html()
224 - : wp_kses_allowed_html( 'post' );
225 -
226 - echo wp_kses( $filtered, $allowed_html );
227 -}
228 -
229 -/**
230 - * Register the native window + the pinned wallpaper icon on `init`,
231 - * priority 99 — after `components.php` boots the registry, and late
232 - * enough that every plugin's `register_post_type()` call has already
233 - * run. The entity list is frozen into the window config here and only
234 - * emitted later on `admin_enqueue_scripts`, so a CPT registered after
235 - * this point would never reach the bundle.
236 - */
237 -function openstation_my_wordpress_register_window() {
238 - if ( ! openstation_my_wordpress_user_can_use() ) {
239 - return;
240 - }
241 -
242 - $site_title = openstation_site_title();
243 - $app_title = openstation_my_wordpress_app_title();
244 - $icon_uri = 'data:image/svg+xml;base64,' . base64_encode( openstation_my_wordpress_icon_svg() );
245 -
246 - $entities = openstation_my_wordpress_entities();
247 -
248 - $window_args = array(
249 - 'title' => $app_title,
250 - 'icon' => $icon_uri,
251 - 'template' => 'openstation_my_wordpress_render_template',
252 - 'script' => 'desktop-mode-my-wordpress',
253 - 'style' => 'desktop-mode-my-wordpress',
254 - 'width' => 960,
255 - 'height' => 640,
256 - 'min_width' => 640,
257 - 'min_height' => 420,
258 - 'placement' => 'none',
259 - 'config' => array(
260 - 'restRoot' => esc_url_raw( rest_url() ),
261 - 'restNonce' => wp_create_nonce( 'wp_rest' ),
262 - 'editPostUrlBase' => esc_url_raw( admin_url( 'post.php' ) ),
263 - 'editUserUrlBase' => esc_url_raw( admin_url( 'user-edit.php' ) ),
264 - 'siteName' => $site_title,
265 - 'entities' => $entities,
266 - 'groups' => function_exists( 'openstation_my_wordpress_collect_groups' )
267 - ? openstation_my_wordpress_collect_groups( $entities )
268 - : array(),
269 - 'perPage' => 24,
270 - 'mediaPerPage' => 48,
271 - 'previewActions' => function_exists( 'openstation_my_wordpress_collect_preview_actions' )
272 - ? openstation_my_wordpress_collect_preview_actions()
273 - : array(),
274 - ),
275 - );
276 -
277 - /**
278 - * Filter the args used to register the My WordPress native window.
279 - *
280 - * @param array $window_args Args passed to `openstation_register_window()`.
281 - */
282 - $window_args = (array) apply_filters( 'openstation_my_wordpress_window_args', $window_args );
283 -
284 - $registered = openstation_register_window( 'desktop-mode-my-wordpress', $window_args );
285 - if ( is_wp_error( $registered ) ) {
286 - // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
287 - error_log( '[openstation] My WordPress window registration failed: ' . $registered->get_error_message() );
288 - return;
289 - }
290 -
291 - $icon_args = array(
292 - 'title' => $app_title,
293 - 'icon' => $icon_uri,
294 - 'window' => 'desktop-mode-my-wordpress',
295 - 'pinned' => true,
296 - 'position' => -1,
297 - );
298 -
299 - /**
300 - * Filter the args used to register the My WordPress pinned icon.
301 - *
302 - * Removing `pinned` here lets the icon participate in normal
303 - * sort order — useful for sites that want the shortcut to feel
304 - * like any other plugin icon.
305 - *
306 - * @param array $icon_args Args passed to `openstation_register_icon()`.
307 - */
308 - $icon_args = (array) apply_filters( 'openstation_my_wordpress_icon_args', $icon_args );
309 -
310 - openstation_register_icon( 'desktop-mode-my-wordpress', $icon_args );
311 -}
312 -add_action( 'init', 'openstation_my_wordpress_register_window', 99 );
313 -
314 -/**
315 - * Enqueue the bundle's CSS in admin context. The script is lazy-
316 - * loaded by the native-window sync and so does not need an
317 - * `admin_enqueue_scripts` call.
318 - */
319 -function openstation_my_wordpress_enqueue_styles() {
320 - if ( ! openstation_my_wordpress_user_can_use() ) {
321 - return;
322 - }
323 - wp_enqueue_style( 'desktop-mode-my-wordpress' );
324 -}
325 -add_action( 'admin_enqueue_scripts', 'openstation_my_wordpress_enqueue_styles', 30 );