PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.5
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.5
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
desktop-mode / desktop-mode.php

desktop-mode.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 0.9.5, at desktop-mode.php

210 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Desktop Mode
4 * Plugin URI: https://github.com/WordPress/desktop-mode
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.5
7 * Requires at least: 6.0
8 * Requires PHP: 7.4
9 * Author: Daniel López Sánchez
10 * Author URI: https://github.com/allterraindeveloper
11 * License: GPLv2 or later
12 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
13 * Text Domain: desktop-mode
14 *
15 * @package WPDesktopMode
16 */
17
18 defined( 'ABSPATH' ) || exit;
19
20 define( 'DESKTOP_MODE_VERSION', '0.9.5' );
21 define( 'DESKTOP_MODE_FILE', __FILE__ );
22 define( 'DESKTOP_MODE_DIR', plugin_dir_path( __FILE__ ) );
23 define( 'DESKTOP_MODE_URL', plugin_dir_url( __FILE__ ) );
24
25 // Foundation primitives — must load before anything that consumes them.
26 require_once DESKTOP_MODE_DIR . 'includes/core/registry-factory.php';
27
28 // Routing helpers register filters at file-load time but call
29 // chromeless / classic detection helpers (still in helpers.php)
30 // at hook-fire time — both files load before any hook fires, so
31 // the order is strict-but-flexible. Routing first because it is
32 // the smaller, more isolated piece.
33 require_once DESKTOP_MODE_DIR . 'includes/core/routing.php';
34
35 require_once DESKTOP_MODE_DIR . 'includes/helpers.php';
36
37 // Dock + payload assembly. Loaded right after helpers.php so the
38 // foundational `desktop_mode_is_enabled()` etc. exist by the time
39 // 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-links.php';
72 require_once DESKTOP_MODE_DIR . 'includes/window-chrome.php';
73 require_once DESKTOP_MODE_DIR . 'includes/window-notices.php';
74 require_once DESKTOP_MODE_DIR . 'includes/update-notice.php';
75 require_once DESKTOP_MODE_DIR . 'includes/wallpapers.php';
76 require_once DESKTOP_MODE_DIR . 'includes/widgets/heartbeat.php';
77 require_once DESKTOP_MODE_DIR . 'includes/widgets/widget-comments.php';
78 require_once DESKTOP_MODE_DIR . 'includes/widgets/widget-post-stats.php';
79 require_once DESKTOP_MODE_DIR . 'includes/widgets/widget-site-views.php';
80 require_once DESKTOP_MODE_DIR . 'includes/widgets/widget-jazz-quote.php';
81 require_once DESKTOP_MODE_DIR . 'includes/widgets/widget-starter.php';
82 require_once DESKTOP_MODE_DIR . 'includes/render.php';
83 require_once DESKTOP_MODE_DIR . 'includes/extended-options.php';
84 require_once DESKTOP_MODE_DIR . 'includes/oauth-relay.php';
85 require_once DESKTOP_MODE_DIR . 'includes/devtools.php';
86 require_once DESKTOP_MODE_DIR . 'includes/ai-copilot/bootstrap.php';
87 require_once DESKTOP_MODE_DIR . 'includes/recycle-bin/bootstrap.php';
88 require_once DESKTOP_MODE_DIR . 'includes/desktop-files/bootstrap.php';
89 require_once DESKTOP_MODE_DIR . 'includes/posts-window/bootstrap.php';
90 require_once DESKTOP_MODE_DIR . 'includes/pages-window/bootstrap.php';
91 require_once DESKTOP_MODE_DIR . 'includes/users-window/bootstrap.php';
92 require_once DESKTOP_MODE_DIR . 'includes/user-edit-window/bootstrap.php';
93 require_once DESKTOP_MODE_DIR . 'includes/plugins-window/bootstrap.php';
94 require_once DESKTOP_MODE_DIR . 'includes/comments-window/bootstrap.php';
95 require_once DESKTOP_MODE_DIR . 'includes/my-wordpress/bootstrap.php';
96 require_once DESKTOP_MODE_DIR . 'includes/content-graph/bootstrap.php';
97 require_once DESKTOP_MODE_DIR . 'includes/living-tree/bootstrap.php';
98 require_once DESKTOP_MODE_DIR . 'includes/pwa.php';
99 require_once DESKTOP_MODE_DIR . 'includes/compat/divi.php';
100
101 /**
102 * Cascade-deactivate plugins that declare `Requires Plugins: desktop-mode`
103 * when Desktop Mode itself is being deactivated.
104 *
105 * Without this, a third-party plugin like `wp-desktop-messages` keeps
106 * its `init` hook armed after Desktop Mode is turned off — the next
107 * admin page load fires `init`, the hook calls
108 * `desktop_mode_register_window()`, and the request fatals because the
109 * function lives in the plugin we just deactivated. The user lands on
110 * a white screen instead of the classic admin we redirected them to.
111 *
112 * WordPress's plugin dependency feature (6.5+) blocks ACTIVATION of a
113 * plugin whose declared `Requires Plugins` aren't all active, but it
114 * does NOT auto-deactivate dependents when their requirement is
115 * deactivated through any path — the user is expected to do that
116 * themselves. The classic plugins.php list shows a warning; the REST
117 * controller (`PUT /wp/v2/plugins/desktop-mode/desktop-mode`) we route
118 * through has no such gate. So we cascade ourselves.
119 *
120 * Timing: `deactivate_plugins()` writes `active_plugins` to the DB
121 * AFTER its hook loop finishes. If we call `deactivate_plugins()`
122 * from inside our `register_deactivation_hook` callback, our nested
123 * write-back is overwritten the moment the outer call runs its own
124 * `update_option`. So we register the cascade to fire on
125 * `shutdown` — by then the outer `deactivate_plugins` has finished
126 * and our write-back sticks.
127 *
128 * Matching uses `WP_Plugin_Dependencies::get_dependents()` keyed on
129 * our own directory slug (`dirname( plugin_basename( __FILE__ ) )`),
130 * which is the same string the dependent's `Requires Plugins` header
131 * resolves against. The filter below lets sites widen or narrow the
132 * cascade — e.g. add a plugin that wraps `desktop_mode_*` calls in
133 * `function_exists` guards and shouldn't be torn down with us.
134 *
135 * Silent deactivation (`$silent = true`) skips the dependent
136 * plugins' own deactivation hooks. Those callbacks routinely call
137 * `desktop_mode_*` helpers expecting Desktop Mode to be wired up;
138 * firing them mid-cascade can trigger the same fatal we're trying
139 * to prevent. Skipping them is the safer default.
140 *
141 * @since 0.8.2
142 */
143 function desktop_mode_cascade_deactivate_dependents() {
144 // Defer to `shutdown` so we run AFTER the outer
145 // `deactivate_plugins()` has flushed its own option update.
146 // Inline cascade gets clobbered by the outer's write-back.
147 add_action( 'shutdown', 'desktop_mode_do_cascade_deactivate', 0 );
148 }
149 register_deactivation_hook( DESKTOP_MODE_FILE, 'desktop_mode_cascade_deactivate_dependents' );
150
151 /**
152 * The deferred cascade body — runs on `shutdown` after the
153 * outer `deactivate_plugins()` has persisted its update.
154 *
155 * Split out from the `register_deactivation_hook` callback because
156 * that callback must register, not execute, the cascade. See
157 * {@see desktop_mode_cascade_deactivate_dependents} for the timing
158 * rationale.
159 *
160 * @since 0.8.2
161 */
162 function desktop_mode_do_cascade_deactivate() {
163 if ( ! class_exists( 'WP_Plugin_Dependencies' ) ) {
164 // Pre-6.5 — no native dependency tracking. Sites running an
165 // old Core won't have dependents declared via the header
166 // either; nothing to cascade.
167 return;
168 }
169
170 WP_Plugin_Dependencies::initialize();
171
172 $slug = dirname( plugin_basename( DESKTOP_MODE_FILE ) );
173 if ( '' === $slug || '.' === $slug ) {
174 return;
175 }
176
177 $dependents = (array) WP_Plugin_Dependencies::get_dependents( $slug );
178
179 /**
180 * Filter the list of plugin files to cascade-deactivate when
181 * Desktop Mode is deactivated. Defaults to every plugin whose
182 * `Requires Plugins` header lists our directory slug.
183 *
184 * @since 0.8.2
185 *
186 * @param string[] $dependents Plugin files (e.g. "foo/foo.php").
187 * @param string $slug Desktop Mode's directory slug.
188 */
189 $dependents = (array) apply_filters(
190 'desktop_mode_cascade_deactivate_dependents',
191 $dependents,
192 $slug
193 );
194
195 if ( empty( $dependents ) ) {
196 return;
197 }
198
199 $active = (array) get_option( 'active_plugins', array() );
200 $targets = array_values( array_intersect( $active, $dependents ) );
201 if ( empty( $targets ) ) {
202 return;
203 }
204
205 if ( ! function_exists( 'deactivate_plugins' ) ) {
206 require_once ABSPATH . 'wp-admin/includes/plugin.php';
207 }
208 deactivate_plugins( $targets, true );
209 }
210