PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.8
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.8
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 / includes / user-edit-window / window.php

window.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 0.9.8, at includes/user-edit-window/window.php

185 lines 7.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Desktop Mode — Native User Edit (single user) window.
4 *
5 * Singleton native window that opens when an admin clicks an
6 * OTHER user's row in the Users table (or when the URL remap for
7 * `user-edit.php?user_id=N` fires). The Users window's "Profile"
8 * tab handles the **current** user's own profile in-place — this
9 * window is the dedicated surface for editing OTHER users.
10 *
11 * Reuses the same JS render functions
12 * (`mountProfileFormAt`, `mountProfileAsideAt`,
13 * `mountProfileActivityAt`) that power the Profile tab; the only
14 * difference is the wrapper template (no Users tab strip; just
15 * the sidebar layout) and the way the target user id is resolved
16 * (read from the shared store when a row click / URL remap set a
17 * target, falling back to the viewer's own id — which is how
18 * `profile.php` opens).
19 *
20 * @package WPDesktopMode
21 */
22
23 defined( 'ABSPATH' ) || exit;
24
25 /**
26 * Echoes the User Edit window's template body.
27 */
28 function desktop_mode_user_edit_window_render_template() {
29 ob_start();
30 ?>
31 <div class="desktop-mode-user-edit-window" data-desktop-mode-user-edit-window-root>
32 <?php /*
33 * The `<wpd-user-profile>` component reads its target
34 * user id from the `user-id` attribute and mounts the
35 * full profile surface (sidebar + form + activity) on
36 * its own. The render callback in `index.ts` sets the
37 * attribute after reading the shared store; absent that,
38 * the attribute is empty and the component idles until
39 * set. */ ?>
40 <wpd-user-profile data-wpd-user-profile-host></wpd-user-profile>
41 </div>
42 <?php
43 $html = (string) ob_get_clean();
44
45 /**
46 * Filter the User Edit window's template HTML.
47 *
48 * @param string $html Default template HTML.
49 */
50 $filtered = (string) apply_filters( 'desktop_mode_user_edit_window_template_html', $html );
51
52 if ( function_exists( 'desktop_mode_kses_native_window_template' ) ) {
53 echo desktop_mode_kses_native_window_template( $filtered ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- helper kses-escapes.
54 } else {
55 echo wp_kses( $filtered, wp_kses_allowed_html( 'post' ) );
56 }
57 }
58
59 /**
60 * Build the admin colour scheme list with full colour tuples for
61 * each scheme. Mirrors what WP core feeds the
62 * `admin_color_scheme_picker` action: each entry carries the
63 * scheme `name` and a `colors` tuple (typically 3-4 hex strings)
64 * used to render mini-swatch previews — not just a slug list.
65 *
66 * @return array<string,array{name:string,colors:array<int,string>,icon_colors?:array<string,string>}>
67 */
68 function desktop_mode_user_edit_window_color_schemes() {
69 $out = array();
70 // Always pull in `wp-admin/includes/admin.php` if needed so the
71 // admin colour scheme registry is available — the user-edit
72 // window may render via REST (where `is_admin()` returns false
73 // but `current_user_can( 'edit_user', … )` is the real gate).
74 // The include is guarded by `is_readable` so a stripped-down
75 // install without admin/ on disk still degrades gracefully.
76 if ( ! function_exists( 'register_admin_color_schemes' ) ) {
77 $admin_inc = ABSPATH . 'wp-admin/includes/admin.php';
78 if ( is_readable( $admin_inc ) ) {
79 require_once $admin_inc;
80 }
81 }
82 if ( function_exists( 'register_admin_color_schemes' ) ) {
83 register_admin_color_schemes();
84 }
85 global $_wp_admin_css_colors;
86 if ( is_array( $_wp_admin_css_colors ) ) {
87 foreach ( $_wp_admin_css_colors as $slug => $info ) {
88 $out[ (string) $slug ] = array(
89 'name' => isset( $info->name )
90 ? (string) $info->name
91 : (string) $slug,
92 // The colors stylesheet URL — required for the live
93 // preview swap on self-edit. Matches what core's
94 // `wp-admin/js/user-profile.js` reads off the
95 // `.css_url` hidden field per scheme tile.
96 'url' => isset( $info->url )
97 ? esc_url_raw( (string) $info->url )
98 : '',
99 'colors' => isset( $info->colors )
100 ? array_values( (array) $info->colors )
101 : array(),
102 'icon_colors' => isset( $info->icon_colors )
103 ? (array) $info->icon_colors
104 : array(),
105 );
106 }
107 }
108 if ( empty( $out ) ) {
109 // Fallback so the picker still shows ONE option even when
110 // $_wp_admin_css_colors hasn't populated.
111 $out['fresh'] = array(
112 'name' => __( 'Default', 'desktop-mode' ),
113 'colors' => array( '#1d2327', '#2c3338', '#2271b1', '#72aee6' ),
114 );
115 }
116 return $out;
117 }
118
119 /**
120 * Register the User Edit native window on `init`.
121 */
122 function desktop_mode_user_edit_window_register_window() {
123 if ( ! desktop_mode_user_edit_window_user_can_register() ) {
124 return;
125 }
126 $viewer_id = (int) get_current_user_id();
127
128 $window_args = array(
129 'title' => __( 'Edit user', 'desktop-mode' ),
130 'icon' => 'dashicons-admin-users',
131 'template' => 'desktop_mode_user_edit_window_render_template',
132 // Reuses the Posts bundle. The render callback for
133 // `desktop-mode-user-edit` lives in `index.ts` and dispatches
134 // to `user-edit-render`'s mount points — same code the Users
135 // window's Profile tab uses.
136 'script' => 'desktop-mode-posts-window',
137 'style' => 'desktop-mode-posts-window',
138 'width' => 1100,
139 'height' => 760,
140 'min_width' => 720,
141 'min_height' => 520,
142 'placement' => 'none',
143 'config' => array(
144 'mode' => 'user-edit',
145 'restRoot' => esc_url_raw( rest_url() ),
146 'restNonce' => wp_create_nonce( 'wp_rest' ),
147 'usersUrl' => esc_url_raw( rest_url( 'wp/v2/users' ) ),
148 'currentUserId' => $viewer_id,
149 'insightsUrlBase' => esc_url_raw( rest_url( 'desktop-mode/v1/users/' ) ),
150 'editPostUrlBase' => esc_url_raw( admin_url( 'post.php' ) ),
151 // Capability flag so the JS can hide the role select for
152 // viewers without `promote_users`. Server-side `update_item`
153 // re-checks regardless; this is UX polish.
154 'canPromote' => current_user_can( 'promote_users' ),
155 // Roles the viewer is allowed to assign — the role select
156 // reads this first and falls back to {@see allRoles} for
157 // older configs. Surfacing only assignable roles in the
158 // dropdown prevents a "pick a role, hit save, get rejected"
159 // loop for viewers with `promote_users` but a narrowed
160 // `editable_roles` filter (e.g. site managers who can't
161 // promote anyone to administrator).
162 'assignableRoles' => function_exists( 'desktop_mode_users_window_role_label_map' )
163 ? desktop_mode_users_window_role_label_map( $viewer_id )
164 : array(),
165 'allRoles' => function_exists( 'desktop_mode_users_window_all_roles_map' )
166 ? desktop_mode_users_window_all_roles_map()
167 : array(),
168 'locales' => function_exists( 'desktop_mode_users_window_locales_map' )
169 ? desktop_mode_users_window_locales_map()
170 : array( '' => __( 'Site default', 'desktop-mode' ) ),
171 'contactMethods' => (array) apply_filters( 'user_contactmethods', array(), null ),
172 'colorSchemes' => desktop_mode_user_edit_window_color_schemes(),
173 ),
174 );
175
176 $window_args = (array) apply_filters( 'desktop_mode_user_edit_window_args', $window_args );
177
178 $registered = desktop_mode_register_window( 'desktop-mode-user-edit', $window_args );
179 if ( is_wp_error( $registered ) ) {
180 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
181 error_log( '[desktop-mode] User Edit window registration failed: ' . $registered->get_error_message() );
182 }
183 }
184 add_action( 'init', 'desktop_mode_user_edit_window_register_window', 25 );
185