PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.12
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.12
1.1.12 1.1.11 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 All 36 releases
← All changes | includes/agents/identity.php +54 -49 0.9.8 → 1.1.12 View file →
@@ -1,7 +1,7 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode — Agents: identity layer (synthetic WordPress users).
3 + * OpenStation — Agents: identity layer (synthetic WordPress users).
4 4 *
5 5 * Each agent has a real row in `wp_users` so capability checks, edit
6 6 * locks, comment attribution, and the standard WP audit trail work
7 7 * without a parallel ACL. The row is "synthetic" only in that every
@@ -7,9 +7,9 @@
7 7 * without a parallel ACL. The row is "synthetic" only in that every
8 8 * login and session path is blocked — the agent never authenticates;
9 9 * it is invoked on the site's behalf.
10 10 *
11 - * Those blocks, and `desktop_mode_agent_is_agent()` itself, live in
11 + * Those blocks, and `openstation_agent_is_agent()` itself, live in
12 12 * guard.php, which loads unconditionally. This file owns the row
13 13 * lifecycle (create / delete) and the identity surface: the bot avatar
14 14 * and the wp-admin Users list "Type" column, so administrators can
15 15 * tell synthetic accounts apart.
@@ -15,14 +15,14 @@
15 15 * tell synthetic accounts apart.
16 16 *
17 17 * Definition meta constants live in store.php.
18 18 *
19 - * @package WPDesktopMode
19 + * @package OpenStation
20 20 */
21 21
22 22 defined( 'ABSPATH' ) || exit;
23 23
24 -require_once DESKTOP_MODE_DIR . 'includes/agents/guard.php';
24 +require_once OPENSTATION_DIR . 'includes/agents/guard.php';
25 25
26 26 /**
27 27 * Resolve a unique `user_login` for an agent given its desired slug.
28 28 *
@@ -31,9 +31,9 @@
31 31 *
32 32 * @param string $slug Sanitized slug.
33 33 * @return string
34 34 */
35 -function desktop_mode_agent_resolve_unique_login( $slug ) {
35 +function openstation_agent_resolve_unique_login( $slug ) {
36 36 $base = 'agent-' . $slug;
37 37 $login = $base;
38 38 $counter = 1;
39 39 while ( username_exists( $login ) ) {
@@ -52,9 +52,9 @@
52 52 *
53 53 * @param string $slug Sanitized agent slug.
54 54 * @return string
55 55 */
56 -function desktop_mode_agent_synthetic_email( $slug ) {
56 +function openstation_agent_synthetic_email( $slug ) {
57 57 $host = wp_parse_url( home_url( '/' ), PHP_URL_HOST );
58 58 if ( ! is_string( $host ) || '' === $host ) {
59 59 $host = 'invalid.local';
60 60 }
@@ -68,9 +68,9 @@
68 68 }
69 69
70 70 /**
71 71 * Create a synthetic agent user row. Definition meta is written by the
72 - * `desktop_mode_agent_create()` orchestrator in store.php — call that,
72 + * `openstation_agent_create()` orchestrator in store.php — call that,
73 73 * not this, unless you only need the bare row.
74 74 *
75 75 * @param array{name:string, role:string, slug?:string} $args Agent
76 76 * creation args. `role` MUST be one of the site's registered
@@ -76,9 +76,9 @@
76 76 * creation args. `role` MUST be one of the site's registered
77 77 * roles. `slug` defaults to `sanitize_title( $name )`.
78 78 * @return WP_User|WP_Error
79 79 */
80 -function desktop_mode_agent_create_user( $args ) {
80 +function openstation_agent_create_user( $args ) {
81 81 $name = isset( $args['name'] ) ? trim( (string) $args['name'] ) : '';
82 82 $role = isset( $args['role'] ) ? sanitize_key( $args['role'] ) : '';
83 83 $slug = isset( $args['slug'] ) ? sanitize_title( $args['slug'] ) : '';
84 84
@@ -83,9 +83,9 @@
83 83 $slug = isset( $args['slug'] ) ? sanitize_title( $args['slug'] ) : '';
84 84
85 85 if ( '' === $name ) {
86 86 return new WP_Error(
87 - 'desktop_mode_agent_invalid_name',
87 + 'openstation_agent_invalid_name',
88 88 __( 'Agent name is required.', 'desktop-mode' )
89 89 );
90 90 }
91 91
@@ -91,9 +91,9 @@
91 91
92 92 $roles = wp_roles()->get_names();
93 93 if ( '' === $role || ! isset( $roles[ $role ] ) ) {
94 94 return new WP_Error(
95 - 'desktop_mode_agent_invalid_role',
95 + 'openstation_agent_invalid_role',
96 96 __( 'Pick a valid WordPress role for the agent.', 'desktop-mode' )
97 97 );
98 98 }
99 99
@@ -101,9 +101,9 @@
101 101 $slug = sanitize_title( $name );
102 102 }
103 103 if ( '' === $slug ) {
104 104 return new WP_Error(
105 - 'desktop_mode_agent_invalid_slug',
105 + 'openstation_agent_invalid_slug',
106 106 __( 'Agent slug could not be derived from the name.', 'desktop-mode' )
107 107 );
108 108 }
109 109
@@ -108,10 +108,10 @@
108 108 }
109 109
110 110 $user_id = wp_insert_user(
111 111 array(
112 - 'user_login' => desktop_mode_agent_resolve_unique_login( $slug ),
113 - 'user_email' => desktop_mode_agent_synthetic_email( $slug ),
112 + 'user_login' => openstation_agent_resolve_unique_login( $slug ),
113 + 'user_email' => openstation_agent_synthetic_email( $slug ),
114 114 'user_pass' => wp_generate_password( 64, true, true ),
115 115 'display_name' => $name,
116 116 'nickname' => $name,
117 117 'role' => $role,
@@ -122,9 +122,9 @@
122 122 if ( is_wp_error( $user_id ) ) {
123 123 return $user_id;
124 124 }
125 125
126 - update_user_meta( $user_id, DESKTOP_MODE_AGENT_USER_MARKER_META, '1' );
126 + update_user_meta( $user_id, OPENSTATION_AGENT_USER_MARKER_META, '1' );
127 127
128 128 return new WP_User( $user_id );
129 129 }
130 130
@@ -137,13 +137,13 @@
137 137 * @param int $user_id Agent user id.
138 138 * @param int|null $reassign Optional user id to reassign authored content to.
139 139 * @return true|WP_Error
140 140 */
141 -function desktop_mode_agent_delete( $user_id, $reassign = null ) {
142 - if ( ! desktop_mode_agent_is_agent( $user_id ) ) {
141 +function openstation_agent_delete( $user_id, $reassign = null ) {
142 + if ( ! openstation_agent_is_agent( $user_id ) ) {
143 143 return new WP_Error(
144 - 'desktop_mode_agent_not_an_agent',
145 - __( 'User is not a Desktop Mode agent.', 'desktop-mode' )
144 + 'openstation_agent_not_an_agent',
145 + __( 'User is not a OpenStation agent.', 'desktop-mode' )
146 146 );
147 147 }
148 148
149 149 if ( ! function_exists( 'wp_delete_user' ) ) {
@@ -149,12 +149,28 @@
149 149 if ( ! function_exists( 'wp_delete_user' ) ) {
150 150 require_once ABSPATH . 'wp-admin/includes/user.php';
151 151 }
152 152
153 - $deleted = wp_delete_user( (int) $user_id, $reassign );
153 + // On multisite `wp_delete_user()` only removes the user from the
154 + // CURRENT site — the network account (and the agent's meta with
155 + // it) lives on. The agent's whole identity is its wp user, so
156 + // deleting the agent means the network-wide delete.
157 + if ( is_multisite() ) {
158 + if ( ! function_exists( 'wpmu_delete_user' ) ) {
159 + require_once ABSPATH . 'wp-admin/includes/ms.php';
160 + }
161 + if ( null !== $reassign ) {
162 + // `wpmu_delete_user()` has no reassign parameter; hand the
163 + // current site's content over before the user goes.
164 + wp_delete_user( (int) $user_id, $reassign );
165 + }
166 + $deleted = wpmu_delete_user( (int) $user_id );
167 + } else {
168 + $deleted = wp_delete_user( (int) $user_id, $reassign );
169 + }
154 170 if ( ! $deleted ) {
155 171 return new WP_Error(
156 - 'desktop_mode_agent_delete_failed',
172 + 'openstation_agent_delete_failed',
157 173 __( 'Could not delete the agent user.', 'desktop-mode' )
158 174 );
159 175 }
160 176
@@ -163,9 +179,9 @@
163 179 *
164 180 * @param int $user_id Agent user id (row no longer exists when this fires).
165 181 * @param int $actor_id User who deleted the agent.
166 182 */
167 - do_action( 'desktop_mode_agent_deleted', (int) $user_id, get_current_user_id() );
183 + do_action( 'openstation_agent_deleted', (int) $user_id, get_current_user_id() );
168 184
169 185 return true;
170 186 }
171 187
@@ -170,26 +186,15 @@
170 186 }
171 187
172 188 // ---------------------------------------------------------------------------
173 189 // Identity surface
190 +//
191 +// `openstation_agent_avatar_url()` lives in bootstrap.php: the WP
192 +// Explorer integration needs it for the entity icon and loads while the
193 +// feature flag is off, when this file does not.
174 194 // ---------------------------------------------------------------------------
175 195
176 196 /**
177 - * URL of the bot avatar as a real static file.
178 - *
179 - * The avatar MUST be a file URL, not the data URI: consumers routinely
180 - * run avatar URLs through `esc_url()` (wp-admin's `get_avatar()`, the
181 - * desktop user-tile renderer), and `data` is not in
182 - * `wp_allowed_protocols()` — the data URI silently becomes an empty
183 - * string and the avatar renders broken.
184 - *
185 - * @return string
186 - */
187 -function desktop_mode_agent_avatar_url() {
188 - return DESKTOP_MODE_URL . 'assets/images/agent-avatar.svg';
189 -}
190 -
191 -/**
192 197 * Substitute the bot glyph for agent avatars across the WP admin.
193 198 *
194 199 * @param array $args Args being assembled by `get_avatar_data()`.
195 200 * @param int|string|WP_User|WP_Comment $id_or_email Identifier the caller passed.
@@ -194,9 +199,9 @@
194 199 * @param array $args Args being assembled by `get_avatar_data()`.
195 200 * @param int|string|WP_User|WP_Comment $id_or_email Identifier the caller passed.
196 201 * @return array
197 202 */
198 -function desktop_mode_agent_avatar( $args, $id_or_email ) {
203 +function openstation_agent_avatar( $args, $id_or_email ) {
199 204 $user_id = 0;
200 205 if ( is_numeric( $id_or_email ) ) {
201 206 $user_id = (int) $id_or_email;
202 207 } elseif ( $id_or_email instanceof WP_User ) {
@@ -209,15 +214,15 @@
209 214 $user_id = (int) $user->ID;
210 215 }
211 216 }
212 217
213 - if ( $user_id > 0 && desktop_mode_agent_is_agent( $user_id ) ) {
214 - $args['url'] = desktop_mode_agent_avatar_url();
218 + if ( $user_id > 0 && openstation_agent_is_agent( $user_id ) ) {
219 + $args['url'] = openstation_agent_avatar_url( $user_id );
215 220 $args['found_avatar'] = true;
216 221 }
217 222 return $args;
218 223 }
219 -add_filter( 'pre_get_avatar_data', 'desktop_mode_agent_avatar', 10, 2 );
224 +add_filter( 'pre_get_avatar_data', 'openstation_agent_avatar', 10, 2 );
220 225
221 226 /**
222 227 * Add a "Type" column to the wp-admin Users list that labels agents.
223 228 *
@@ -223,13 +228,13 @@
223 228 *
224 229 * @param string[] $columns Existing column id => label map.
225 230 * @return string[]
226 231 */
227 -function desktop_mode_agent_users_columns( $columns ) {
228 - $columns['desktop_mode_agent_type'] = __( 'Type', 'desktop-mode' );
232 +function openstation_agent_users_columns( $columns ) {
233 + $columns['openstation_agent_type'] = __( 'Type', 'desktop-mode' );
229 234 return $columns;
230 235 }
231 -add_filter( 'manage_users_columns', 'desktop_mode_agent_users_columns' );
236 +add_filter( 'manage_users_columns', 'openstation_agent_users_columns' );
232 237
233 238 /**
234 239 * Render the cell for the "Type" column.
235 240 *
@@ -237,17 +242,17 @@
237 242 * @param string $column_name Column id.
238 243 * @param int $user_id User id being rendered.
239 244 * @return string
240 245 */
241 -function desktop_mode_agent_users_custom_column( $output, $column_name, $user_id ) {
242 - if ( 'desktop_mode_agent_type' !== $column_name ) {
246 +function openstation_agent_users_custom_column( $output, $column_name, $user_id ) {
247 + if ( 'openstation_agent_type' !== $column_name ) {
243 248 return $output;
244 249 }
245 - if ( desktop_mode_agent_is_agent( $user_id ) ) {
246 - return '<span class="desktop-mode-agent-type" aria-label="' . esc_attr__( 'Desktop Mode agent', 'desktop-mode' ) . '">'
250 + if ( openstation_agent_is_agent( $user_id ) ) {
251 + return '<span class="os-agent-type" aria-label="' . esc_attr__( 'OpenStation agent', 'desktop-mode' ) . '">'
247 252 . '<span class="dashicons dashicons-superhero" aria-hidden="true"></span> '
248 253 . esc_html__( 'Agent', 'desktop-mode' )
249 254 . '</span>';
250 255 }
251 - return '<span class="desktop-mode-agent-type-human">' . esc_html__( 'Person', 'desktop-mode' ) . '</span>';
256 + return '<span class="os-agent-type-human">' . esc_html__( 'Person', 'desktop-mode' ) . '</span>';
252 257 }
253 -add_filter( 'manage_users_custom_column', 'desktop_mode_agent_users_custom_column', 10, 3 );
258 +add_filter( 'manage_users_custom_column', 'openstation_agent_users_custom_column', 10, 3 );