| @@ -1,10 +1,10 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | - * Plugin Name: Desktop Mode | |
| 4 | - * Plugin URI: https://github.com/WordPress/desktop-mode | |
| 3 | + * Plugin Name: OpenStation | |
| 4 | + * Plugin URI: https://github.com/WordPress/openstation | |
| 5 | 5 | * Description: Renders the WordPress admin as a desktop OS. Admin screens become draggable, resizable, minimizable windows floating on a desktop with a dock. Purely opt-in per user. |
| 6 | - * Version: 0.9.2 | |
| 6 | + * Version: 1.1.10 | |
| 7 | 7 | * Requires at least: 6.0 |
| 8 | 8 | * Requires PHP: 7.4 |
| 9 | 9 | * Author: Daniel López Sánchez |
| 10 | 10 | * Author URI: https://github.com/allterraindeveloper |
| @@ -10,21 +10,77 @@ | ||
| 10 | 10 | * Author URI: https://github.com/allterraindeveloper |
| 11 | 11 | * License: GPLv2 or later |
| 12 | 12 | * License URI: https://www.gnu.org/licenses/gpl-2.0.html |
| 13 | 13 | * Text Domain: desktop-mode |
| 14 | + * Domain Path: /languages | |
| 14 | 15 | * |
| 15 | - * @package WPDesktopMode | |
| 16 | + * @package OpenStation | |
| 16 | 17 | */ |
| 17 | 18 | |
| 18 | 19 | defined( 'ABSPATH' ) || exit; |
| 19 | 20 | |
| 20 | -define( 'DESKTOP_MODE_VERSION', '0.9.2' ); | |
| 21 | -define( 'DESKTOP_MODE_FILE', __FILE__ ); | |
| 22 | -define( 'DESKTOP_MODE_DIR', plugin_dir_path( __FILE__ ) ); | |
| 23 | -define( 'DESKTOP_MODE_URL', plugin_dir_url( __FILE__ ) ); | |
| 21 | +define( 'OPENSTATION_VERSION', '1.1.10' ); | |
| 22 | +define( 'OPENSTATION_FILE', __FILE__ ); | |
| 23 | +define( 'OPENSTATION_DIR', plugin_dir_path( __FILE__ ) ); | |
| 24 | +define( 'OPENSTATION_URL', plugin_dir_url( __FILE__ ) ); | |
| 24 | 25 | |
| 26 | +/** | |
| 27 | + * Whether the current request needs the admin-rendering modules. | |
| 28 | + * | |
| 29 | + * Most of the plugin must load on every request — feature modules | |
| 30 | + * register REST routes, record content mutations that can originate | |
| 31 | + * on the frontend (comment submission, WooCommerce orders, plugin- | |
| 32 | + * driven post saves), and expose `openstation_register_*()` APIs | |
| 33 | + * that third-party plugins call from their own `init` hooks in any | |
| 34 | + * context. But the admin *rendering* layer (shell markup, asset | |
| 35 | + * enqueues, the chromeless bridge, admin notices, migrations, the | |
| 36 | + * `wp_ajax_*` save handler) only ever fires on hooks that don't | |
| 37 | + * exist outside wp-admin — so a pure frontend page view can skip | |
| 38 | + * parsing and wiring ~6,500 lines of it. | |
| 39 | + * | |
| 40 | + * Anything ambiguous loads everything: admin (including admin-ajax, | |
| 41 | + * where Heartbeat lands), REST (sniffed early — `REST_REQUEST` isn't | |
| 42 | + * defined until `parse_request`), cron, WP-CLI, and the PHPUnit | |
| 43 | + * environment (the test bootstrap loads the plugin outside admin | |
| 44 | + * context but exercises the render layer directly). | |
| 45 | + * | |
| 46 | + * @return bool True to load the admin-rendering modules. | |
| 47 | + */ | |
| 48 | +function openstation_request_needs_admin_modules() { | |
| 49 | + $needs = is_admin() | |
| 50 | + || wp_doing_cron() | |
| 51 | + || ( defined( 'WP_CLI' ) && WP_CLI ) | |
| 52 | + || ( defined( 'WP_TESTS_DOMAIN' ) ) | |
| 53 | + || ( defined( 'REST_REQUEST' ) && REST_REQUEST ); | |
| 54 | + | |
| 55 | + if ( ! $needs ) { | |
| 56 | + // Early REST sniff. False positives just load a little more | |
| 57 | + // code (safe direction); plain-permalink REST is covered by | |
| 58 | + // the `rest_route` query var. | |
| 59 | + $rest_prefix = function_exists( 'rest_get_url_prefix' ) ? rest_get_url_prefix() : 'wp-json'; | |
| 60 | + $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? (string) esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; | |
| 61 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- request-shape sniff only, no data is read. | |
| 62 | + if ( ( '' !== $rest_prefix && false !== strpos( $request_uri, '/' . $rest_prefix ) ) || isset( $_GET['rest_route'] ) ) { | |
| 63 | + $needs = true; | |
| 64 | + } | |
| 65 | + } | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * Filter whether the admin-rendering modules load on this request. | |
| 69 | + * | |
| 70 | + * Escape hatch for unusual setups — e.g. a frontend integration | |
| 71 | + * that internally dispatches `desktop-mode/v1` REST routes via | |
| 72 | + * `rest_do_request()` outside a sniffable REST request can force | |
| 73 | + * the full load by returning true. | |
| 74 | + * | |
| 75 | + * @param bool $needs Whether the current request loads the | |
| 76 | + * admin-rendering module set. | |
| 77 | + */ | |
| 78 | + return (bool) apply_filters( 'openstation_load_admin_modules', $needs ); | |
| 79 | +} | |
| 80 | + | |
| 25 | 81 | // Foundation primitives — must load before anything that consumes them. |
| 26 | -require_once DESKTOP_MODE_DIR . 'includes/core/registry-factory.php'; | |
| 82 | +require_once OPENSTATION_DIR . 'includes/core/registry-factory.php'; | |
| 27 | 83 | |
| 28 | 84 | // Routing helpers register filters at file-load time but call |
| 29 | 85 | // chromeless / classic detection helpers (still in helpers.php) |
| 30 | 86 | // at hook-fire time — both files load before any hook fires, so |
| @@ -29,76 +85,153 @@ | ||
| 29 | 85 | // chromeless / classic detection helpers (still in helpers.php) |
| 30 | 86 | // at hook-fire time — both files load before any hook fires, so |
| 31 | 87 | // the order is strict-but-flexible. Routing first because it is |
| 32 | 88 | // the smaller, more isolated piece. |
| 33 | -require_once DESKTOP_MODE_DIR . 'includes/core/routing.php'; | |
| 89 | +require_once OPENSTATION_DIR . 'includes/core/routing.php'; | |
| 34 | 90 | |
| 35 | -require_once DESKTOP_MODE_DIR . 'includes/helpers.php'; | |
| 91 | +require_once OPENSTATION_DIR . 'includes/helpers.php'; | |
| 36 | 92 | |
| 37 | 93 | // Dock + payload assembly. Loaded right after helpers.php so the |
| 38 | -// foundational `desktop_mode_is_enabled()` etc. exist by the time | |
| 94 | +// foundational `openstation_is_enabled()` etc. exist by the time | |
| 39 | 95 | // any payload function is invoked at hook-fire time. |
| 40 | -require_once DESKTOP_MODE_DIR . 'includes/core/payload.php'; | |
| 41 | -require_once DESKTOP_MODE_DIR . 'includes/ajax.php'; | |
| 42 | -require_once DESKTOP_MODE_DIR . 'includes/assets.php'; | |
| 43 | -require_once DESKTOP_MODE_DIR . 'includes/admin-bar.php'; | |
| 44 | -require_once DESKTOP_MODE_DIR . 'includes/session.php'; | |
| 45 | -require_once DESKTOP_MODE_DIR . 'includes/presence.php'; | |
| 46 | -require_once DESKTOP_MODE_DIR . 'includes/nonce-refresh.php'; | |
| 47 | -require_once DESKTOP_MODE_DIR . 'includes/sticky-notes/heartbeat.php'; | |
| 48 | -require_once DESKTOP_MODE_DIR . 'includes/os-settings.php'; | |
| 49 | -// One-time data migrations. After os-settings.php so the meta-key | |
| 50 | -// constant and save/sanitize helpers the migrations call already exist. | |
| 51 | -require_once DESKTOP_MODE_DIR . 'includes/migrations.php'; | |
| 52 | -require_once DESKTOP_MODE_DIR . 'includes/seen-intros.php'; | |
| 53 | -require_once DESKTOP_MODE_DIR . 'includes/welcome-dialog.php'; | |
| 54 | -require_once DESKTOP_MODE_DIR . 'includes/portal.php'; | |
| 55 | -require_once DESKTOP_MODE_DIR . 'includes/default-window.php'; | |
| 56 | -require_once DESKTOP_MODE_DIR . 'includes/themes-tabs.php'; | |
| 57 | -require_once DESKTOP_MODE_DIR . 'includes/media-query.php'; | |
| 58 | -require_once DESKTOP_MODE_DIR . 'includes/accents.php'; | |
| 59 | -require_once DESKTOP_MODE_DIR . 'includes/toast-types.php'; | |
| 60 | -require_once DESKTOP_MODE_DIR . 'includes/registries/native-windows.php'; | |
| 61 | -require_once DESKTOP_MODE_DIR . 'includes/registries/window-tabs.php'; | |
| 62 | -require_once DESKTOP_MODE_DIR . 'includes/registries/icons.php'; | |
| 63 | -require_once DESKTOP_MODE_DIR . 'includes/registries/wallpapers.php'; | |
| 64 | -require_once DESKTOP_MODE_DIR . 'includes/registries/widgets.php'; | |
| 65 | -require_once DESKTOP_MODE_DIR . 'includes/components.php'; | |
| 66 | -require_once DESKTOP_MODE_DIR . 'includes/commands.php'; | |
| 67 | -require_once DESKTOP_MODE_DIR . 'includes/settings-tabs.php'; | |
| 68 | -require_once DESKTOP_MODE_DIR . 'includes/dock-rail-renderer.php'; | |
| 69 | -require_once DESKTOP_MODE_DIR . 'includes/title-bar-buttons.php'; | |
| 70 | -require_once DESKTOP_MODE_DIR . 'includes/unfocus-effects.php'; | |
| 71 | -require_once DESKTOP_MODE_DIR . 'includes/window-chrome.php'; | |
| 72 | -require_once DESKTOP_MODE_DIR . 'includes/window-notices.php'; | |
| 73 | -require_once DESKTOP_MODE_DIR . 'includes/wallpapers.php'; | |
| 74 | -require_once DESKTOP_MODE_DIR . 'includes/widgets/heartbeat.php'; | |
| 75 | -require_once DESKTOP_MODE_DIR . 'includes/render.php'; | |
| 76 | -require_once DESKTOP_MODE_DIR . 'includes/extended-options.php'; | |
| 77 | -require_once DESKTOP_MODE_DIR . 'includes/oauth-relay.php'; | |
| 78 | -require_once DESKTOP_MODE_DIR . 'includes/devtools.php'; | |
| 79 | -require_once DESKTOP_MODE_DIR . 'includes/ai-copilot/bootstrap.php'; | |
| 80 | -require_once DESKTOP_MODE_DIR . 'includes/recycle-bin/bootstrap.php'; | |
| 81 | -require_once DESKTOP_MODE_DIR . 'includes/desktop-files/bootstrap.php'; | |
| 82 | -require_once DESKTOP_MODE_DIR . 'includes/posts-window/bootstrap.php'; | |
| 83 | -require_once DESKTOP_MODE_DIR . 'includes/pages-window/bootstrap.php'; | |
| 84 | -require_once DESKTOP_MODE_DIR . 'includes/users-window/bootstrap.php'; | |
| 85 | -require_once DESKTOP_MODE_DIR . 'includes/user-edit-window/bootstrap.php'; | |
| 86 | -require_once DESKTOP_MODE_DIR . 'includes/plugins-window/bootstrap.php'; | |
| 87 | -require_once DESKTOP_MODE_DIR . 'includes/comments-window/bootstrap.php'; | |
| 88 | -require_once DESKTOP_MODE_DIR . 'includes/my-wordpress/bootstrap.php'; | |
| 89 | -require_once DESKTOP_MODE_DIR . 'includes/content-graph/bootstrap.php'; | |
| 90 | -require_once DESKTOP_MODE_DIR . 'includes/pwa.php'; | |
| 91 | -require_once DESKTOP_MODE_DIR . 'includes/compat/divi.php'; | |
| 96 | +require_once OPENSTATION_DIR . 'includes/core/payload.php'; | |
| 97 | +require_once OPENSTATION_DIR . 'includes/assets.php'; | |
| 98 | +require_once OPENSTATION_DIR . 'includes/admin-bar.php'; | |
| 99 | +// Loaded before the session: `openstation_sanitize_session()` calls | |
| 100 | +// `openstation_sanitize_workspace_profile()` on every desktop it reads. | |
| 101 | +require_once OPENSTATION_DIR . 'includes/workspaces.php'; | |
| 102 | +require_once OPENSTATION_DIR . 'includes/session.php'; | |
| 103 | +require_once OPENSTATION_DIR . 'includes/multisite.php'; | |
| 104 | +require_once OPENSTATION_DIR . 'includes/presence.php'; | |
| 105 | +require_once OPENSTATION_DIR . 'includes/nonce-refresh.php'; | |
| 106 | +require_once OPENSTATION_DIR . 'includes/os-settings.php'; | |
| 107 | +require_once OPENSTATION_DIR . 'includes/mobile.php'; | |
| 108 | +// The About journal is still lazy — this file only registers its authenticated | |
| 109 | +// AJAX action. Load the registration unconditionally so alternate admin-ajax | |
| 110 | +// bootstraps cannot skip it while classifying the request shape. | |
| 111 | +require_once OPENSTATION_DIR . 'includes/about-feed.php'; | |
| 112 | +require_once OPENSTATION_DIR . 'includes/seen-intros.php'; | |
| 113 | +// One-time data migrations. After os-settings.php and seen-intros.php, | |
| 114 | +// whose meta-key constants and helpers the migrations call. | |
| 115 | +// | |
| 116 | +// Unconditional, unlike the rest of the admin-only set below, because | |
| 117 | +// its activation hook has to be registered on ANY request that can | |
| 118 | +// dispatch activation. `activate_plugin()` includes the plugin file and | |
| 119 | +// fires `activate_<basename>` in whatever context it was called from, | |
| 120 | +// and a programmatic activation (a Playground Blueprint, a provisioning | |
| 121 | +// script) need not look like an admin request at all. Registering the | |
| 122 | +// runner's `admin_init` hook on a frontend request costs nothing: it | |
| 123 | +// never fires there. | |
| 124 | +require_once OPENSTATION_DIR . 'includes/migrations.php'; | |
| 125 | +require_once OPENSTATION_DIR . 'includes/portal.php'; | |
| 126 | +require_once OPENSTATION_DIR . 'includes/default-window.php'; | |
| 127 | +// Solo window rendering mode (`?openstation_solo=<id>`). Unconditional | |
| 128 | +// because `includes/render/` reads its flag, and because extensions | |
| 129 | +// (the Electron adapter) call its helpers from their own hooks. | |
| 130 | +require_once OPENSTATION_DIR . 'includes/solo-window.php'; | |
| 131 | +// The shell screen (`admin.php?page=openstation`) and the one "this | |
| 132 | +// request paints the shell" predicate. Unconditional because modules | |
| 133 | +// loaded outside the admin block (PWA, native windows, desktop themes) | |
| 134 | +// gate on it. | |
| 135 | +require_once OPENSTATION_DIR . 'includes/shell-screen.php'; | |
| 136 | +require_once OPENSTATION_DIR . 'includes/themes-tabs.php'; | |
| 137 | +require_once OPENSTATION_DIR . 'includes/media-query.php'; | |
| 138 | +require_once OPENSTATION_DIR . 'includes/accents.php'; | |
| 139 | +require_once OPENSTATION_DIR . 'includes/toast-types.php'; | |
| 140 | +require_once OPENSTATION_DIR . 'includes/wp-icon-registry.php'; | |
| 141 | +require_once OPENSTATION_DIR . 'includes/registries/native-windows.php'; | |
| 142 | +require_once OPENSTATION_DIR . 'includes/registries/window-tabs.php'; | |
| 143 | +require_once OPENSTATION_DIR . 'includes/registries/icons.php'; | |
| 144 | +require_once OPENSTATION_DIR . 'includes/registries/wallpapers.php'; | |
| 145 | +require_once OPENSTATION_DIR . 'includes/registries/widgets.php'; | |
| 146 | +require_once OPENSTATION_DIR . 'includes/components.php'; | |
| 147 | +require_once OPENSTATION_DIR . 'includes/commands.php'; | |
| 148 | +require_once OPENSTATION_DIR . 'includes/settings-tabs.php'; | |
| 149 | +require_once OPENSTATION_DIR . 'includes/dock-rail-renderer.php'; | |
| 150 | +require_once OPENSTATION_DIR . 'includes/title-bar-buttons.php'; | |
| 151 | +require_once OPENSTATION_DIR . 'includes/window-actions.php'; | |
| 152 | +require_once OPENSTATION_DIR . 'includes/unfocus-effects.php'; | |
| 153 | +require_once OPENSTATION_DIR . 'includes/window-links.php'; | |
| 154 | +require_once OPENSTATION_DIR . 'includes/window-chrome.php'; | |
| 155 | +require_once OPENSTATION_DIR . 'includes/window-notices.php'; | |
| 156 | +require_once OPENSTATION_DIR . 'includes/wallpapers.php'; | |
| 157 | +require_once OPENSTATION_DIR . 'includes/mio.php'; | |
| 158 | +require_once OPENSTATION_DIR . 'includes/mio-portrait.php'; | |
| 159 | +require_once OPENSTATION_DIR . 'includes/widgets/heartbeat.php'; | |
| 160 | +require_once OPENSTATION_DIR . 'includes/widgets/widget-comments.php'; | |
| 161 | +require_once OPENSTATION_DIR . 'includes/widgets/widget-post-stats.php'; | |
| 162 | +require_once OPENSTATION_DIR . 'includes/widgets/widget-site-views.php'; | |
| 163 | +require_once OPENSTATION_DIR . 'includes/widgets/widget-jazz-quote.php'; | |
| 164 | +require_once OPENSTATION_DIR . 'includes/widgets/widget-starter.php'; | |
| 165 | +require_once OPENSTATION_DIR . 'includes/widgets/widget-notes.php'; | |
| 166 | +require_once OPENSTATION_DIR . 'includes/widgets/widget-drafts.php'; | |
| 167 | +require_once OPENSTATION_DIR . 'includes/widgets/widget-focus-timer.php'; | |
| 168 | +require_once OPENSTATION_DIR . 'includes/extended-options.php'; | |
| 169 | +require_once OPENSTATION_DIR . 'includes/oauth-relay.php'; | |
| 170 | +require_once OPENSTATION_DIR . 'includes/ai-copilot/bootstrap.php'; | |
| 171 | +// Content-changes must load before the recycle bin — the bin's | |
| 172 | +// changelog delegates into the generic recorder. | |
| 173 | +require_once OPENSTATION_DIR . 'includes/content-changes.php'; | |
| 174 | +require_once OPENSTATION_DIR . 'includes/recycle-bin/bootstrap.php'; | |
| 175 | +require_once OPENSTATION_DIR . 'includes/desktop-files/bootstrap.php'; | |
| 176 | +require_once OPENSTATION_DIR . 'includes/desktop-themes/bootstrap.php'; | |
| 177 | +require_once OPENSTATION_DIR . 'includes/notes/bootstrap.php'; | |
| 178 | +// Posts, Pages, Users, User Edit, Plugins and Comments are App | |
| 179 | +// Framework apps (`apps/posts/`, `apps/pages/`, `apps/users/`, | |
| 180 | +// `apps/user-edit/`, `apps/plugins/`, `apps/comments/`): each `.os.php` | |
| 181 | +// pulls in its own PHP parts (permissions, REST fields and routes, | |
| 182 | +// AJAX handlers) when the framework loads it on `init`. | |
| 183 | +// Station Home is an App Framework app (`apps/station-home/`); only | |
| 184 | +// its plugin-card registry — a public API plugins call on `init` — | |
| 185 | +// lives here, so it exists before any app loads. | |
| 186 | +require_once OPENSTATION_DIR . 'includes/station-home/cards.php'; | |
| 187 | +require_once OPENSTATION_DIR . 'includes/my-wordpress/bootstrap.php'; | |
| 188 | +require_once OPENSTATION_DIR . 'includes/content-graph/bootstrap.php'; | |
| 189 | +// The App Framework: `.os.php` windows under `apps/` (Code Blue lives | |
| 190 | +// there) and any directory a plugin adds. Loads after the registries | |
| 191 | +// it registers into and after the feature modules, so an app can | |
| 192 | +// hook them. | |
| 193 | +require_once OPENSTATION_DIR . 'includes/framework/wordpress.php'; | |
| 194 | +require_once OPENSTATION_DIR . 'includes/living-tree/bootstrap.php'; | |
| 195 | +require_once OPENSTATION_DIR . 'includes/games/bootstrap.php'; | |
| 196 | +require_once OPENSTATION_DIR . 'includes/agents/bootstrap.php'; | |
| 197 | +require_once OPENSTATION_DIR . 'includes/network/bootstrap.php'; | |
| 198 | +// First run: the install / first-enable stamps. Loads on every request | |
| 199 | +// because they are written from the AJAX toggle, the portal and the | |
| 200 | +// activation hook, none of them an admin render. | |
| 201 | +require_once OPENSTATION_DIR . 'includes/first-run/bootstrap.php'; | |
| 202 | +// Deactivation feedback: the dialog on the Plugins screen and the | |
| 203 | +// REST route it posts to. Unconditional so the route registers on | |
| 204 | +// REST requests; it stores nothing on the site. | |
| 205 | +require_once OPENSTATION_DIR . 'includes/feedback/bootstrap.php'; | |
| 206 | +require_once OPENSTATION_DIR . 'includes/pwa.php'; | |
| 207 | +require_once OPENSTATION_DIR . 'includes/compat/divi.php'; | |
| 92 | 208 | |
| 209 | +// Admin-rendering modules — every hook these register (`admin_init`, | |
| 210 | +// `admin_enqueue_scripts`, `in_admin_header`, `admin_head`, | |
| 211 | +// `admin_footer`, `admin_body_class`, `wp_ajax_*`) only fires inside | |
| 212 | +// wp-admin, so pure frontend page views skip them entirely. REST, | |
| 213 | +// cron, WP-CLI, admin-ajax, and the PHPUnit environment all load | |
| 214 | +// them (see openstation_request_needs_admin_modules()). Relative | |
| 215 | +// order preserved from the historical unconditional list. | |
| 216 | +if ( openstation_request_needs_admin_modules() ) { | |
| 217 | + require_once OPENSTATION_DIR . 'includes/ajax.php'; | |
| 218 | + require_once OPENSTATION_DIR . 'includes/welcome-dialog.php'; | |
| 219 | + require_once OPENSTATION_DIR . 'includes/update-notice.php'; | |
| 220 | + require_once OPENSTATION_DIR . 'includes/core-notices.php'; | |
| 221 | + require_once OPENSTATION_DIR . 'includes/plugin-notices.php'; | |
| 222 | + require_once OPENSTATION_DIR . 'includes/render.php'; | |
| 223 | + require_once OPENSTATION_DIR . 'includes/devtools.php'; | |
| 224 | +} | |
| 225 | + | |
| 93 | 226 | /** |
| 94 | 227 | * Cascade-deactivate plugins that declare `Requires Plugins: desktop-mode` |
| 95 | - * when Desktop Mode itself is being deactivated. | |
| 228 | + * when OpenStation itself is being deactivated. | |
| 96 | 229 | * |
| 97 | - * Without this, a third-party plugin like `wp-desktop-messages` keeps | |
| 98 | - * its `init` hook armed after Desktop Mode is turned off — the next | |
| 230 | + * Without this, a third-party plugin like `os-messages` keeps | |
| 231 | + * its `init` hook armed after OpenStation is turned off — the next | |
| 99 | 232 | * admin page load fires `init`, the hook calls |
| 100 | - * `desktop_mode_register_window()`, and the request fatals because the | |
| 233 | + * `openstation_register_window()`, and the request fatals because the | |
| 101 | 234 | * function lives in the plugin we just deactivated. The user lands on |
| 102 | 235 | * a white screen instead of the classic admin we redirected them to. |
| 103 | 236 | * |
| 104 | 237 | * WordPress's plugin dependency feature (6.5+) blocks ACTIVATION of a |
| @@ -105,9 +238,9 @@ | ||
| 105 | 238 | * plugin whose declared `Requires Plugins` aren't all active, but it |
| 106 | 239 | * does NOT auto-deactivate dependents when their requirement is |
| 107 | 240 | * deactivated through any path — the user is expected to do that |
| 108 | 241 | * themselves. The classic plugins.php list shows a warning; the REST |
| 109 | - * controller (`PUT /wp/v2/plugins/desktop-mode/desktop-mode`) we route | |
| 242 | + * controller (`PUT /wp/v2/plugins/desktop-mode/openstation`) we route | |
| 110 | 243 | * through has no such gate. So we cascade ourselves. |
| 111 | 244 | * |
| 112 | 245 | * Timing: `deactivate_plugins()` writes `active_plugins` to the DB |
| 113 | 246 | * AFTER its hook loop finishes. If we call `deactivate_plugins()` |
| @@ -120,26 +253,24 @@ | ||
| 120 | 253 | * Matching uses `WP_Plugin_Dependencies::get_dependents()` keyed on |
| 121 | 254 | * our own directory slug (`dirname( plugin_basename( __FILE__ ) )`), |
| 122 | 255 | * which is the same string the dependent's `Requires Plugins` header |
| 123 | 256 | * resolves against. The filter below lets sites widen or narrow the |
| 124 | - * cascade — e.g. add a plugin that wraps `desktop_mode_*` calls in | |
| 257 | + * cascade — e.g. add a plugin that wraps `openstation_*` calls in | |
| 125 | 258 | * `function_exists` guards and shouldn't be torn down with us. |
| 126 | 259 | * |
| 127 | 260 | * Silent deactivation (`$silent = true`) skips the dependent |
| 128 | 261 | * plugins' own deactivation hooks. Those callbacks routinely call |
| 129 | - * `desktop_mode_*` helpers expecting Desktop Mode to be wired up; | |
| 262 | + * `openstation_*` helpers expecting OpenStation to be wired up; | |
| 130 | 263 | * firing them mid-cascade can trigger the same fatal we're trying |
| 131 | 264 | * to prevent. Skipping them is the safer default. |
| 132 | - * | |
| 133 | - * @since 0.18.4 | |
| 134 | 265 | */ |
| 135 | -function desktop_mode_cascade_deactivate_dependents() { | |
| 266 | +function openstation_cascade_deactivate_dependents() { | |
| 136 | 267 | // Defer to `shutdown` so we run AFTER the outer |
| 137 | 268 | // `deactivate_plugins()` has flushed its own option update. |
| 138 | 269 | // Inline cascade gets clobbered by the outer's write-back. |
| 139 | - add_action( 'shutdown', 'desktop_mode_do_cascade_deactivate', 0 ); | |
| 270 | + add_action( 'shutdown', 'openstation_do_cascade_deactivate', 0 ); | |
| 140 | 271 | } |
| 141 | -register_deactivation_hook( DESKTOP_MODE_FILE, 'desktop_mode_cascade_deactivate_dependents' ); | |
| 272 | +register_deactivation_hook( OPENSTATION_FILE, 'openstation_cascade_deactivate_dependents' ); | |
| 142 | 273 | |
| 143 | 274 | /** |
| 144 | 275 | * The deferred cascade body — runs on `shutdown` after the |
| 145 | 276 | * outer `deactivate_plugins()` has persisted its update. |
| @@ -145,14 +276,12 @@ | ||
| 145 | 276 | * outer `deactivate_plugins()` has persisted its update. |
| 146 | 277 | * |
| 147 | 278 | * Split out from the `register_deactivation_hook` callback because |
| 148 | 279 | * that callback must register, not execute, the cascade. See |
| 149 | - * {@see desktop_mode_cascade_deactivate_dependents} for the timing | |
| 280 | + * {@see openstation_cascade_deactivate_dependents} for the timing | |
| 150 | 281 | * rationale. |
| 151 | - * | |
| 152 | - * @since 0.18.4 | |
| 153 | 282 | */ |
| 154 | -function desktop_mode_do_cascade_deactivate() { | |
| 283 | +function openstation_do_cascade_deactivate() { | |
| 155 | 284 | if ( ! class_exists( 'WP_Plugin_Dependencies' ) ) { |
| 156 | 285 | // Pre-6.5 — no native dependency tracking. Sites running an |
| 157 | 286 | // old Core won't have dependents declared via the header |
| 158 | 287 | // either; nothing to cascade. |
| @@ -160,9 +289,9 @@ | ||
| 160 | 289 | } |
| 161 | 290 | |
| 162 | 291 | WP_Plugin_Dependencies::initialize(); |
| 163 | 292 | |
| 164 | - $slug = dirname( plugin_basename( DESKTOP_MODE_FILE ) ); | |
| 293 | + $slug = dirname( plugin_basename( OPENSTATION_FILE ) ); | |
| 165 | 294 | if ( '' === $slug || '.' === $slug ) { |
| 166 | 295 | return; |
| 167 | 296 | } |
| 168 | 297 | |
| @@ -169,18 +298,16 @@ | ||
| 169 | 298 | $dependents = (array) WP_Plugin_Dependencies::get_dependents( $slug ); |
| 170 | 299 | |
| 171 | 300 | /** |
| 172 | 301 | * Filter the list of plugin files to cascade-deactivate when |
| 173 | - * Desktop Mode is deactivated. Defaults to every plugin whose | |
| 302 | + * OpenStation is deactivated. Defaults to every plugin whose | |
| 174 | 303 | * `Requires Plugins` header lists our directory slug. |
| 175 | 304 | * |
| 176 | - * @since 0.18.4 | |
| 177 | - * | |
| 178 | 305 | * @param string[] $dependents Plugin files (e.g. "foo/foo.php"). |
| 179 | - * @param string $slug Desktop Mode's directory slug. | |
| 306 | + * @param string $slug OpenStation's directory slug. | |
| 180 | 307 | */ |
| 181 | 308 | $dependents = (array) apply_filters( |
| 182 | - 'desktop_mode_cascade_deactivate_dependents', | |
| 309 | + 'openstation_cascade_deactivate_dependents', | |
| 183 | 310 | $dependents, |
| 184 | 311 | $slug |
| 185 | 312 | ); |
| 186 | 313 | |