PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / trunk
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin vtrunk
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 0.8.6 0.8.5 0.8.4 All 31 releases
desktop-mode / includes / multisite.php

multisite.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin trunk, at includes/multisite.php

193 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OpenStation — Multisite integration: the shell's multisite block (which
4 * instance this shell is, the sites the user may switch to, the network
5 * admin menu mirroring the admin bar's Network Admin node — every URL a
6 * link OUT, never a window source, see docs/multisite.md), and the
7 * per-site table cleanup when a subsite is deleted.
8 *
9 * @package OpenStation
10 */
11
12 defined( 'ABSPATH' ) || exit;
13
14 /**
15 * The multisite block of the shell config.
16 *
17 * On a network every site is its own OpenStation, and so is the network
18 * admin: the block says which instance this shell is, lists every site
19 * the user may switch to (the overview's site switcher), and carries
20 * the Network Admin tile's rows. Null on a single-site install;
21 * `networkAdmin` null for users who cannot reach the network admin,
22 * which is what keeps the tile from registering.
23 *
24 * @return array|null
25 */
26 function openstation_multisite_payload() {
27 if ( ! is_multisite() || ! is_user_logged_in() ) {
28 return null;
29 }
30
31 $network_admin = null;
32 if ( current_user_can( 'manage_network' ) ) {
33 // Capability gates copied one for one from
34 // `wp_admin_bar_my_sites_menu()`, so the tile can never offer a
35 // screen the admin bar would have hidden.
36 $network = esc_url_raw( network_admin_url() );
37 $rows = array(
38 array(
39 'title' => __( 'Dashboard', 'desktop-mode' ),
40 'url' => $network,
41 ),
42 );
43 $gated = array(
44 'manage_sites' => array( 'sites.php', __( 'Sites', 'desktop-mode' ) ),
45 'manage_network_users' => array( 'users.php', __( 'Users', 'desktop-mode' ) ),
46 'manage_network_themes' => array( 'themes.php', __( 'Themes', 'desktop-mode' ) ),
47 'manage_network_plugins' => array( 'plugins.php', __( 'Plugins', 'desktop-mode' ) ),
48 'manage_network_options' => array( 'settings.php', __( 'Settings', 'desktop-mode' ) ),
49 );
50
51 foreach ( $gated as $capability => $row ) {
52 if ( current_user_can( $capability ) ) {
53 $rows[] = array(
54 'title' => $row[1],
55 'url' => esc_url_raw( network_admin_url( $row[0] ) ),
56 );
57 }
58 }
59
60 $network_admin = array(
61 'url' => $network,
62 'shellUrl' => esc_url_raw( network_admin_url( 'admin.php?page=' . OPENSTATION_SHELL_PAGE_SLUG ) ),
63 'rows' => $rows,
64 );
65 }
66
67 return array(
68 'isNetworkAdmin' => is_network_admin(),
69 'networkAdmin' => $network_admin,
70 'current' => is_network_admin() ? 'network' : (string) get_current_blog_id(),
71 'sites' => openstation_multisite_sites(),
72 );
73 }
74
75 /**
76 * How many of the network's sites a super admin's switcher lists beyond
77 * their own: the network Sites screen's first page. A row, not a
78 * directory — a larger network picks its set through the filter below.
79 */
80 const OPENSTATION_MULTISITE_SWITCHER_SITES = 20;
81
82 /**
83 * The sites the user may switch to, each with its own shell screen.
84 *
85 * The user's own sites first — `get_blogs_of_user()`, the list behind
86 * the admin bar's My Sites, minus the archived, spam and deleted, in
87 * the order Core keeps them — then, for a super admin, who can reach
88 * every site whether or not they are a member, the network's sites by
89 * path up to {@see OPENSTATION_MULTISITE_SWITCHER_SITES}.
90 *
91 * @return array[] Each `id` (the blog id, as a string), `name`, `shellUrl`.
92 */
93 function openstation_multisite_sites() {
94 $names = array();
95 foreach ( get_blogs_of_user( get_current_user_id() ) as $blog ) {
96 $names[ (int) $blog->userblog_id ] = (string) $blog->blogname;
97 }
98 if ( current_user_can( 'manage_network' ) ) {
99 $network_sites = get_sites(
100 array(
101 'number' => OPENSTATION_MULTISITE_SWITCHER_SITES,
102 'archived' => 0,
103 'spam' => 0,
104 'deleted' => 0,
105 'orderby' => 'path',
106 'order' => 'ASC',
107 )
108 );
109 foreach ( $network_sites as $site ) {
110 $blog_id = (int) $site->blog_id;
111 if ( ! isset( $names[ $blog_id ] ) ) {
112 $names[ $blog_id ] = (string) $site->blogname;
113 }
114 }
115 }
116
117 $sites = array();
118 foreach ( $names as $blog_id => $name ) {
119 $sites[] = array(
120 'id' => (string) $blog_id,
121 'name' => $name,
122 'shellUrl' => esc_url_raw( get_admin_url( $blog_id, 'admin.php?page=' . OPENSTATION_SHELL_PAGE_SLUG ) ),
123 );
124 }
125
126 /**
127 * Filters the sites the overview's site switcher offers.
128 *
129 * Trim it on a large network, reorder it, rename an entry, or build
130 * a different set. A site dropped here is not offered, though the
131 * admin bar still reaches it.
132 *
133 * @param array[] $sites Each `id` (blog id as a string), `name`, `shellUrl`.
134 */
135 return apply_filters( 'openstation_multisite_sites', $sites );
136 }
137
138 /**
139 * The plugin's per-site tables, unprefixed.
140 *
141 * A STATIC list, not a read from the schema helpers, on purpose:
142 * deleting a site must drop every table the plugin ever created there,
143 * and the games module (owner of the last two) only loads while its
144 * feature toggle is on — its helper may not exist on the request that
145 * deletes the site, but the tables it created earlier still do. The
146 * names are frozen identifiers (see AGENTS.md), and
147 * `Tests_OpenStation_Multisite` pins this list against the loaded
148 * schema helpers so a new table cannot be forgotten here.
149 *
150 * @return string[] Table names without any prefix.
151 */
152 function openstation_site_table_names() {
153 return array(
154 'desktop_mode_file_placements',
155 'desktop_mode_folders',
156 'desktop_mode_file_tombstones',
157 'desktop_mode_folder_shares',
158 'desktop_mode_share_user_decisions',
159 'desktop_mode_stored_files',
160 'desktop_mode_game_scores',
161 'desktop_mode_game_challenges',
162 );
163 }
164
165 /**
166 * Adds the plugin's tables to the set Core drops when a site is
167 * deleted. Without this, every deleted subsite left its
168 * `wp_N_desktop_mode_*` tables behind forever.
169 *
170 * Core drops with `DROP TABLE IF EXISTS`, so listing a table the site
171 * never created (games disabled, or a site deleted before its lazy
172 * `init` table creation ran) is fine.
173 *
174 * @param string[] $tables Table names Core will drop.
175 * @param int $site_id The site being deleted.
176 * @return string[] The list with the plugin's tables appended.
177 */
178 function openstation_filter_wpmu_drop_tables( $tables, $site_id ) {
179 global $wpdb;
180
181 // Core switches to the deleted site before applying the filter,
182 // but the prefix is anchored on the passed id rather than trusted
183 // from the switch — a future caller that forgets to switch would
184 // otherwise drop the CURRENT site's tables.
185 $prefix = $wpdb->get_blog_prefix( $site_id );
186 foreach ( openstation_site_table_names() as $name ) {
187 $tables[] = $prefix . $name;
188 }
189
190 return $tables;
191 }
192 add_filter( 'wpmu_drop_tables', 'openstation_filter_wpmu_drop_tables', 10, 2 );
193