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/helpers.php +72 -45 0.9.81.1.10 View file →
@@ -1,9 +1,9 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode helper functions.
3 + * OpenStation helper functions.
4 4 *
5 - * @package WPDesktopMode
5 + * @package OpenStation
6 6 */
7 7
8 8 defined( 'ABSPATH' ) || exit;
9 9
@@ -15,15 +15,15 @@
15 15 * per-file ternaries didn't have: release zips ship the minified
16 16 * bundles only (the ~4–5 MB of dev bundles are a source-checkout
17 17 * artifact — see bin/package.sh), so a production site that happens
18 18 * to define SCRIPT_DEBUG would otherwise request dev files that
19 - * don't exist and 404 every desktop-mode script. Probe one
19 + * don't exist and 404 every openstation script. Probe one
20 20 * canonical dev bundle; if it's absent, this is a minified-only
21 21 * install and `.min` is the only truth available.
22 22 *
23 23 * @return string `'.min'` or `''`.
24 24 */
25 -function desktop_mode_asset_suffix() {
25 +function openstation_asset_suffix() {
26 26 static $suffix = null;
27 27 if ( null !== $suffix ) {
28 28 return $suffix;
29 29 }
@@ -30,20 +30,20 @@
30 30 if ( ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ) {
31 31 $suffix = '.min';
32 32 return $suffix;
33 33 }
34 - $suffix = file_exists( DESKTOP_MODE_DIR . 'assets/js/desktop.js' ) ? '' : '.min';
34 + $suffix = file_exists( OPENSTATION_DIR . 'assets/js/desktop.js' ) ? '' : '.min';
35 35 return $suffix;
36 36 }
37 37
38 38 /**
39 - * Checks whether a user has desktop mode enabled.
39 + * Checks whether a user has OpenStation enabled.
40 40 *
41 41 * Two gates, both must pass:
42 42 *
43 43 * 1. The user's `desktop_mode_mode` user-meta is `'1'` (the per-user
44 44 * opt-in toggle the admin-bar button writes via the AJAX endpoint).
45 - * 2. The `desktop_mode_mode_enabled` filter returns truthy for that user.
45 + * 2. The `openstation_mode_enabled` filter returns truthy for that user.
46 46 *
47 47 * Centralising the filter check here means render-time gates (chromeless
48 48 * detection, payload generation, REST permission callbacks) can rely on
49 49 * a single helper instead of every call site re-running the filter.
@@ -52,11 +52,11 @@
52 52 * filter — see docs/examples/gate-by-role.md.
53 53 *
54 54 * @param int $user_id Optional. User ID to check. Defaults to the
55 55 * current user.
56 - * @return bool True if the user has desktop mode active.
56 + * @return bool True if the user has OpenStation active.
57 57 */
58 -function desktop_mode_is_enabled( $user_id = 0 ) {
58 +function openstation_is_enabled( $user_id = 0 ) {
59 59 $user_id = (int) $user_id;
60 60 if ( $user_id <= 0 ) {
61 61 if ( ! is_user_logged_in() ) {
62 62 return false;
@@ -68,45 +68,45 @@
68 68 return false;
69 69 }
70 70
71 71 /**
72 - * Filters whether desktop mode is available for this user.
72 + * Filters whether OpenStation is available for this user.
73 73 *
74 - * See `docs/hooks-reference.md` (`desktop_mode_mode_enabled`) for the
74 + * See `docs/hooks-reference.md` (`openstation_mode_enabled`) for the
75 75 * full contract. Returning `false` here makes the helper return
76 76 * `false` for the user even when their meta is set, which propagates
77 77 * to every render-time gate that consults the helper.
78 78 *
79 - * @param bool $enabled Whether desktop mode is enabled. Default true.
79 + * @param bool $enabled Whether OpenStation is enabled. Default true.
80 80 * @param int $user_id The user ID being checked.
81 81 */
82 - return (bool) apply_filters( 'desktop_mode_mode_enabled', true, $user_id );
82 + return (bool) apply_filters( 'openstation_mode_enabled', true, $user_id );
83 83 }
84 84
85 85 /**
86 - * Shared REST permission gate for Desktop Mode's per-user endpoints.
86 + * Shared REST permission gate for OpenStation's per-user endpoints.
87 87 *
88 88 * Routes that only ever read or write the *current* user's own Desktop
89 89 * Mode state (OS settings, session, default-window, seen-intros, PWA
90 90 * state, presence) must not be reachable by accounts that haven't
91 - * actually entered Desktop Mode.
91 + * actually entered OpenStation.
92 92 *
93 93 * `current_user_can( 'read' )` alone is too loose: every authenticated
94 94 * role — Subscriber included — carries `read`, so the old gate let any
95 - * logged-in user touch these routes without ever enabling Desktop Mode.
96 - * We gate on {@see desktop_mode_is_enabled()} instead (the same opt-in +
97 - * `desktop_mode_mode_enabled` filter the shell itself uses) and return
95 + * logged-in user touch these routes without ever enabling OpenStation.
96 + * We gate on {@see openstation_is_enabled()} instead (the same opt-in +
97 + * `openstation_mode_enabled` filter the shell itself uses) and return
98 98 * the conventional 401/403 split so REST clients can tell "log in" from
99 99 * "not allowed".
100 100 *
101 - * This is the canonical gate; `desktop_mode_presence_rest_permission()`
101 + * This is the canonical gate; `openstation_presence_rest_permission()`
102 102 * pioneered the shape and now delegates here.
103 103 *
104 104 * @return true|WP_Error True when allowed; a `rest_forbidden` WP_Error
105 - * (401 when logged out, 403 when desktop mode is
105 + * (401 when logged out, 403 when OpenStation is
106 106 * not enabled for the account) otherwise.
107 107 */
108 -function desktop_mode_rest_require_enabled() {
108 +function openstation_rest_require_enabled() {
109 109 if ( ! is_user_logged_in() ) {
110 110 return new WP_Error(
111 111 'rest_forbidden',
112 112 __( 'Authentication required.', 'desktop-mode' ),
@@ -113,12 +113,12 @@
113 113 array( 'status' => 401 )
114 114 );
115 115 }
116 116
117 - if ( ! desktop_mode_is_enabled() ) {
117 + if ( ! openstation_is_enabled() ) {
118 118 return new WP_Error(
119 119 'rest_forbidden',
120 - __( 'Desktop mode is not enabled for your account.', 'desktop-mode' ),
120 + __( 'OpenStation is not enabled for your account.', 'desktop-mode' ),
121 121 array( 'status' => 403 )
122 122 );
123 123 }
124 124
@@ -128,15 +128,15 @@
128 128 // Chromeless / classic admin-bar suppression and the `wp_redirect`
129 129 // flag-preservation filter pair were moved to
130 130 // `includes/core/routing.php`. The functions and the
131 131 // add_filter / add_action hookings live there now; this file
132 -// remains the home of `desktop_mode_is_enabled()` (called from the
132 +// remains the home of `openstation_is_enabled()` (called from the
133 133 // routing helpers at hook-fire time, after every include has
134 134 // loaded), which is why `desktop-mode.php` can safely require
135 135 // routing.php BEFORE helpers.php.
136 136
137 137 /**
138 - * `desktop_mode_is_chromeless_request()` and `desktop_mode_is_classic_request()`
138 + * `openstation_is_chromeless_request()` and `openstation_is_classic_request()`
139 139 * were moved to `includes/core/routing.php` — see that
140 140 * file for the canonical definitions. The function names didn't
141 141 * change; PHP looks them up by name at call time, so every
142 142 * existing caller (helpers, render, hooks) keeps working.
@@ -150,9 +150,9 @@
150 150 * Exposed as a filter so themes/plugins can set a site-wide default
151 151 * without forking the TS build.
152 152 *
153 153 * ```php
154 - * add_filter( 'desktop_mode_default_wallpaper', function () {
154 + * add_filter( 'openstation_default_wallpaper', function () {
155 155 * return 'my-plugin/brand';
156 156 * } );
157 157 * ```
158 158 *
@@ -157,20 +157,20 @@
157 157 * ```
158 158 *
159 159 * The returned string is passed through `sanitize_key()` so a filter
160 160 * that returns an invalid slug degrades to the empty string (and the
161 - * shell falls back to its hard-coded `'dark'` preset).
161 + * shell falls back to its hard-coded default preset).
162 162 *
163 163 * @return string Wallpaper id. Empty string if the filter returns
164 164 * an invalid value.
165 165 */
166 -function desktop_mode_get_default_wallpaper() {
166 +function openstation_get_default_wallpaper() {
167 167 /**
168 168 * Filters the wallpaper id loaded on first boot / new user.
169 169 *
170 170 * @param string $id Default wallpaper slug.
171 171 */
172 - $id = apply_filters( 'desktop_mode_default_wallpaper', 'dark' );
172 + $id = apply_filters( 'openstation_default_wallpaper', 'galaxy' );
173 173 if ( ! is_string( $id ) ) {
174 174 return '';
175 175 }
176 176 return sanitize_key( $id );
@@ -179,11 +179,14 @@
179 179 /**
180 180 * The site's own name, ready to use as a window / icon title.
181 181 *
182 182 * The desktop shows objects, not the software running it — so the
183 - * folder that holds a site's content is titled after the site itself
184 - * ("Izzi's Gym"), not after WordPress. This is the single source for
185 - * that string.
183 + * *root folder* of a site's content is named after the site itself
184 + * ("Izzi's Gym"), not after WordPress. That is the breadcrumb root and
185 + * the Content Graph's site label; the app that browses it is called WP
186 + * Explorer, which is a different string (see
187 + * `openstation_my_wordpress_app_title()`). This is the single source
188 + * for the site one.
186 189 *
187 190 * `get_bloginfo( 'name' )` returns the display-filtered option, which
188 191 * carries HTML entities (`&amp;`, `&#039;`). Titles land in
189 192 * `title=` attributes and JS-rendered text nodes, so the entities are
@@ -192,9 +195,9 @@
192 195 *
193 196 * @return string Decoded site title. Falls back to `WordPress` when
194 197 * the site has no name set.
195 198 */
196 -function desktop_mode_site_title() {
199 +function openstation_site_title() {
197 200 $title = wp_specialchars_decode( (string) get_bloginfo( 'name' ), ENT_QUOTES );
198 201 $title = trim( $title );
199 202
200 203 if ( '' === $title ) {
@@ -201,11 +204,11 @@
201 204 $title = __( 'WordPress', 'desktop-mode' );
202 205 }
203 206
204 207 /**
205 - * Filters the site title used for desktop-mode window and icon
206 - * titles — the pinned site folder, its breadcrumb root, and any
207 - * "Open in <site>" action.
208 + * Filters the site title used for openstation window and icon
209 + * titles — WP Explorer's breadcrumb root, the Content Graph's site
210 + * label, and any "Open in <site>" action.
208 211 *
209 212 * Return a different string to label the desktop objects after
210 213 * something other than `blogname` (a brand, a network name, a
211 214 * per-user workspace label).
@@ -211,27 +214,51 @@
211 214 * per-user workspace label).
212 215 *
213 216 * @param string $title Decoded site title, never empty.
214 217 */
215 - $filtered = apply_filters( 'desktop_mode_site_title', $title );
218 + $filtered = apply_filters( 'openstation_site_title', $title );
216 219
217 220 return is_string( $filtered ) && '' !== trim( $filtered ) ? $filtered : $title;
218 221 }
219 222
220 223 /**
221 - * Build a `WP_Error` for a desktop-mode registration failure.
224 + * Decode a rendered title into the plain text the desktop paints with.
222 225 *
226 + * `wptexturize()` encodes the characters titles are full of — `&` as
227 + * `&#038;`, an apostrophe as `&#8217;` — and the shell writes titles
228 + * into text nodes, where the entity renders as itself. Same reasoning
229 + * as {@see openstation_site_title()}, one layer down.
230 + *
231 + * Decode BEFORE the tag strip, never after: `&lt;script&gt;` decodes
232 + * into a real tag, and stripping second is what removes it.
233 + *
234 + * @param string $rendered A title that has been through a display filter.
235 + * @return string Plain text, tag-free.
236 + */
237 +function openstation_plain_text_title( $rendered ) {
238 + $decoded = html_entity_decode(
239 + (string) $rendered,
240 + ENT_QUOTES,
241 + get_bloginfo( 'charset' )
242 + );
243 +
244 + return trim( wp_strip_all_tags( $decoded ) );
245 +}
246 +
247 +/**
248 + * Build a `WP_Error` for a openstation registration failure.
249 + *
223 250 * Centralises the error-code vocabulary used by every
224 - * `desktop_mode_register_*()` function so plugin authors see a
251 + * `openstation_register_*()` function so plugin authors see a
225 252 * consistent contract. The canonical error-code list lives in
226 253 * `docs/hooks-reference.md`.
227 254 *
228 - * @param string $code Short error slug (e.g. `desktop_mode_missing_title`).
255 + * @param string $code Short error slug (e.g. `openstation_missing_title`).
229 256 * @param string $message Human-readable message. Should be translated.
230 257 * @param array $data Optional extra context attached to the error.
231 258 * @return WP_Error
232 259 */
233 -function desktop_mode_registration_error( $code, $message, $data = array() ) {
260 +function openstation_registration_error( $code, $message, $data = array() ) {
234 261 return new WP_Error(
235 262 (string) $code,
236 263 (string) $message,
237 264 is_array( $data ) ? $data : array()
@@ -237,11 +264,11 @@
237 264 is_array( $data ) ? $data : array()
238 265 );
239 266 }
240 267
241 -// `desktop_mode_url_is_same_admin()`,
242 -// `desktop_mode_resolve_admin_target()` and
243 -// `desktop_mode_admin_target_allowlist()` were moved to
268 +// `openstation_url_is_same_admin()`,
269 +// `openstation_resolve_admin_target()` and
270 +// `openstation_admin_target_allowlist()` were moved to
244 271 // `includes/core/routing.php` — see that file for the
245 272 // canonical definitions. Function names didn't change; PHP's
246 273 // runtime resolution finds them across the module split.
247 274
@@ -250,6 +277,6 @@
250 277 // script/style handle resolvers were moved to
251 278 // `includes/core/payload.php`. Function names didn't
252 279 // change; existing callers find them via PHP's runtime function
253 280 // resolution. desktop-mode.php loads payload.php right after
254 -// helpers.php so the foundational helpers (desktop_mode_is_enabled
281 +// helpers.php so the foundational helpers (openstation_is_enabled
255 282 // etc.) are present when payload functions are invoked.