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

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