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/desktop-files/file-shares.php +179 -147 0.9.8 → 1.1.12 View file →
@@ -1,7 +1,7 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode — single-file sharing (`target_type='file'`).
3 + * OpenStation — single-file sharing (`target_type='file'`).
4 4 *
5 5 * Shares one stored upload with specific users. Reuses the folder-
6 6 * sharing tables via the `target_type` column the schema shipped
7 7 * for exactly this (the `folder_id` column carries the STORED-FILE
@@ -19,9 +19,9 @@
19 19 * → accept (placement planted at the recipient's desktop root) /
20 20 * deny / leave / revoke, every removal scrubbing the recipient's
21 21 * placement.
22 22 *
23 - * @package WPDesktopMode
23 + * @package OpenStation
24 24 */
25 25
26 26 defined( 'ABSPATH' ) || exit;
27 27
@@ -32,10 +32,10 @@
32 32 * @param int $file_id Stored-file id.
33 33 * @param int $user_id Viewer.
34 34 * @return bool
35 35 */
36 -function desktop_mode_stored_files_share_can_manage( $file_id, $user_id ) {
37 - $file = desktop_mode_stored_files_get( (int) $file_id );
36 +function openstation_stored_files_share_can_manage( $file_id, $user_id ) {
37 + $file = openstation_stored_files_get( (int) $file_id );
38 38 $can = $file && (int) $file['owner_id'] === (int) $user_id;
39 39 /**
40 40 * Filter who can manage a stored file's shares.
41 41 *
@@ -43,9 +43,9 @@
43 43 * @param int $file_id Stored-file id.
44 44 * @param int $user_id Viewer.
45 45 * @param array|null $file Stored-file row (null when missing).
46 46 */
47 - return (bool) apply_filters( 'desktop_mode_stored_files_share_can_manage', $can, (int) $file_id, (int) $user_id, $file );
47 + return (bool) apply_filters( 'openstation_stored_files_share_can_manage', $can, (int) $file_id, (int) $user_id, $file );
48 48 }
49 49
50 50 /**
51 51 * All share rows for one stored file (owner-internal view).
@@ -52,11 +52,11 @@
52 52 *
53 53 * @param int $file_id Stored-file id.
54 54 * @return array[]
55 55 */
56 -function desktop_mode_stored_files_get_file_shares( $file_id ) {
56 +function openstation_stored_files_get_file_shares( $file_id ) {
57 57 global $wpdb;
58 - $tables = desktop_mode_files_table_names();
58 + $tables = openstation_files_table_names();
59 59 $rows = $wpdb->get_results(
60 60 $wpdb->prepare(
61 61 "SELECT * FROM {$tables['shares']} WHERE target_type = 'file' AND folder_id = %d ORDER BY invited_at_ms ASC, id ASC",
62 62 (int) $file_id
@@ -62,11 +62,11 @@
62 62 (int) $file_id
63 63 ),
64 64 ARRAY_A
65 65 );
66 - $out = array();
66 + $out = array();
67 67 foreach ( (array) $rows as $row ) {
68 - $out[] = desktop_mode_files_normalize_share_row( $row );
68 + $out[] = openstation_files_normalize_share_row( $row );
69 69 }
70 70 return $out;
71 71 }
72 72
@@ -77,11 +77,11 @@
77 77 * @param int $file_id Stored-file id.
78 78 * @param int $user_id Viewer.
79 79 * @return string 'none' | 'pending' | 'accepted' | 'denied'
80 80 */
81 -function desktop_mode_stored_file_share_state( $file_id, $user_id ) {
81 +function openstation_stored_file_share_state( $file_id, $user_id ) {
82 82 global $wpdb;
83 - $tables = desktop_mode_files_table_names();
83 + $tables = openstation_files_table_names();
84 84 $state = $wpdb->get_var(
85 85 $wpdb->prepare(
86 86 "SELECT state FROM {$tables['shares']}
87 87 WHERE target_type = 'file' AND folder_id = %d
@@ -100,37 +100,37 @@
100 100 * @param int $actor_id Actor (must manage the file's shares).
101 101 * @param int $recipient_user_id Recipient.
102 102 * @return int|WP_Error Share id.
103 103 */
104 -function desktop_mode_stored_file_share_invite( $file_id, $actor_id, $recipient_user_id ) {
104 +function openstation_stored_file_share_invite( $file_id, $actor_id, $recipient_user_id ) {
105 105 global $wpdb;
106 106 $file_id = (int) $file_id;
107 107 $actor_id = (int) $actor_id;
108 108 $uid = (int) $recipient_user_id;
109 109
110 - $file = desktop_mode_stored_files_get( $file_id );
110 + $file = openstation_stored_files_get( $file_id );
111 111 if ( ! $file ) {
112 - return new WP_Error( 'desktop_mode_stored_files_not_found', __( 'Stored file not found.', 'desktop-mode' ), array( 'status' => 404 ) );
112 + return new WP_Error( 'openstation_stored_files_not_found', __( 'Stored file not found.', 'desktop-mode' ), array( 'status' => 404 ) );
113 113 }
114 - if ( ! desktop_mode_stored_files_share_can_manage( $file_id, $actor_id ) ) {
115 - return new WP_Error( 'desktop_mode_files_forbidden', __( 'You cannot manage shares for this file.', 'desktop-mode' ), array( 'status' => 403 ) );
114 + if ( ! openstation_stored_files_share_can_manage( $file_id, $actor_id ) ) {
115 + return new WP_Error( 'openstation_files_forbidden', __( 'You cannot manage shares for this file.', 'desktop-mode' ), array( 'status' => 403 ) );
116 116 }
117 117 if ( $uid <= 0 ) {
118 - return new WP_Error( 'desktop_mode_files_invalid_user', __( 'Invalid user id.', 'desktop-mode' ), array( 'status' => 400 ) );
118 + return new WP_Error( 'openstation_files_invalid_user', __( 'Invalid user id.', 'desktop-mode' ), array( 'status' => 400 ) );
119 119 }
120 120 if ( $uid === (int) $file['owner_id'] ) {
121 - return new WP_Error( 'desktop_mode_files_share_owner', __( 'You cannot share with the file owner.', 'desktop-mode' ), array( 'status' => 400 ) );
121 + return new WP_Error( 'openstation_files_share_owner', __( 'You cannot share with the file owner.', 'desktop-mode' ), array( 'status' => 400 ) );
122 122 }
123 123 $user = get_userdata( $uid );
124 124 if ( ! $user ) {
125 - return new WP_Error( 'desktop_mode_files_unknown_user', __( 'Unknown user.', 'desktop-mode' ), array( 'status' => 404 ) );
125 + return new WP_Error( 'openstation_files_unknown_user', __( 'Unknown user.', 'desktop-mode' ), array( 'status' => 404 ) );
126 126 }
127 127 if ( ! user_can( $user, 'edit_posts' ) ) {
128 - return new WP_Error( 'desktop_mode_files_ineligible_principal', __( 'This user is not eligible.', 'desktop-mode' ), array( 'status' => 400 ) );
128 + return new WP_Error( 'openstation_files_ineligible_principal', __( 'This user is not eligible.', 'desktop-mode' ), array( 'status' => 400 ) );
129 129 }
130 130
131 - $tables = desktop_mode_files_table_names();
132 - $now = desktop_mode_files_now_ms();
131 + $tables = openstation_files_table_names();
132 + $now = openstation_files_now_ms();
133 133
134 134 // Idempotent invite, mirroring the folder rules: denied →
135 135 // pending again; pending/accepted keep their state. Capability
136 136 // stays 'read' unconditionally.
@@ -174,17 +174,17 @@
174 174 ),
175 175 array( '%s', '%d', '%s', '%s', '%s', '%s', '%d', '%d' )
176 176 );
177 177 if ( false === $ok ) {
178 - return new WP_Error( 'desktop_mode_files_share_insert_failed', __( 'Failed to record share.', 'desktop-mode' ), array( 'status' => 500 ) );
178 + return new WP_Error( 'openstation_files_share_insert_failed', __( 'Failed to record share.', 'desktop-mode' ), array( 'status' => 500 ) );
179 179 }
180 180 $id = (int) $wpdb->insert_id;
181 181 }
182 182
183 - $row = desktop_mode_files_get_share( $id );
183 + $row = openstation_files_get_share( $id );
184 184
185 185 /** This action is documented in includes/desktop-files/shares-store.php */
186 - do_action( 'desktop_mode_files_share_invited', $id, $row, $actor_id );
186 + do_action( 'openstation_files_share_invited', $id, $row, $actor_id );
187 187
188 188 return $id;
189 189 }
190 190
@@ -195,32 +195,38 @@
195 195 * @param int $share_id Share id.
196 196 * @param int $user_id Recipient.
197 197 * @return array|WP_Error Updated share row.
198 198 */
199 -function desktop_mode_stored_file_share_accept( $share_id, $user_id ) {
199 +function openstation_stored_file_share_accept( $share_id, $user_id ) {
200 200 global $wpdb;
201 201 $share_id = (int) $share_id;
202 202 $user_id = (int) $user_id;
203 - $row = desktop_mode_files_get_share( $share_id );
203 + $row = openstation_files_get_share( $share_id );
204 204 if ( ! $row || 'file' !== $row['target_type'] ) {
205 - return new WP_Error( 'desktop_mode_files_share_not_found', __( 'Share not found.', 'desktop-mode' ), array( 'status' => 404 ) );
205 + return new WP_Error( 'openstation_files_share_not_found', __( 'Share not found.', 'desktop-mode' ), array( 'status' => 404 ) );
206 206 }
207 207 if ( 'user' !== $row['principal_type'] || (int) $row['principal_ref'] !== $user_id ) {
208 - return new WP_Error( 'desktop_mode_files_share_not_recipient', __( 'This invite is not for you.', 'desktop-mode' ), array( 'status' => 403 ) );
208 + return new WP_Error( 'openstation_files_share_not_recipient', __( 'This invite is not for you.', 'desktop-mode' ), array( 'status' => 403 ) );
209 209 }
210 210 if ( 'accepted' === $row['state'] ) {
211 - return $row;
211 + // A previous attempt may have accepted the invite but failed to plant
212 + // its tile (for example, a busy upload lock). Allow that step to retry.
213 + $tables = openstation_files_table_names();
214 + $placed = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$tables['placements']} WHERE owner_id = %d AND file_type = 'upload' AND file_ref = %s LIMIT 1", $user_id, (string) $row['folder_id'] ) );
215 + if ( $placed ) {
216 + return $row;
217 + }
212 218 }
213 219 if ( 'denied' === $row['state'] ) {
214 - return new WP_Error( 'desktop_mode_files_share_already_denied', __( 'This invite was denied.', 'desktop-mode' ), array( 'status' => 410 ) );
220 + return new WP_Error( 'openstation_files_share_already_denied', __( 'This invite was denied.', 'desktop-mode' ), array( 'status' => 410 ) );
215 221 }
216 222
217 - $tables = desktop_mode_files_table_names();
223 + $tables = openstation_files_table_names();
218 224 $wpdb->update(
219 225 $tables['shares'],
220 226 array(
221 227 'state' => 'accepted',
222 - 'decided_at_ms' => desktop_mode_files_now_ms(),
228 + 'decided_at_ms' => openstation_files_now_ms(),
223 229 ),
224 230 array( 'id' => $share_id ),
225 231 array( '%s', '%d' ),
226 232 array( '%d' )
@@ -229,15 +235,18 @@
229 235 // Plant the tile — AFTER the state flip so the placement's
230 236 // `can_read` gate sees the accepted share.
231 237 $file_id = (int) $row['folder_id'];
232 238 /** This filter is documented in includes/desktop-files/shares-store.php */
233 - $parent_id = (int) apply_filters( 'desktop_mode_folder_share_accept_default_parent', 0, $file_id, $user_id, $row );
234 - desktop_mode_files_place_at_next_free_slot( $user_id, $parent_id, 'upload', (string) $file_id );
239 + $parent_id = (int) apply_filters( 'openstation_folder_share_accept_default_parent', 0, $file_id, $user_id, $row );
240 + $placed = openstation_files_place_at_next_free_slot( $user_id, $parent_id, 'upload', (string) $file_id );
241 + if ( is_wp_error( $placed ) ) {
242 + return $placed;
243 + }
235 244
236 - $next = desktop_mode_files_get_share( $share_id );
245 + $next = openstation_files_get_share( $share_id );
237 246
238 247 /** This action is documented in includes/desktop-files/shares-store.php */
239 - do_action( 'desktop_mode_files_share_accepted', $share_id, $next, $user_id );
248 + do_action( 'openstation_files_share_accepted', $share_id, $next, $user_id );
240 249
241 250 return $next;
242 251 }
243 252
@@ -247,18 +256,18 @@
247 256 * @param int $share_id Share id.
248 257 * @param int $user_id Recipient.
249 258 * @return array|WP_Error Updated share row.
250 259 */
251 -function desktop_mode_stored_file_share_deny( $share_id, $user_id ) {
260 +function openstation_stored_file_share_deny( $share_id, $user_id ) {
252 261 global $wpdb;
253 262 $share_id = (int) $share_id;
254 263 $user_id = (int) $user_id;
255 - $row = desktop_mode_files_get_share( $share_id );
264 + $row = openstation_files_get_share( $share_id );
256 265 if ( ! $row || 'file' !== $row['target_type'] ) {
257 - return new WP_Error( 'desktop_mode_files_share_not_found', __( 'Share not found.', 'desktop-mode' ), array( 'status' => 404 ) );
266 + return new WP_Error( 'openstation_files_share_not_found', __( 'Share not found.', 'desktop-mode' ), array( 'status' => 404 ) );
258 267 }
259 268 if ( 'user' !== $row['principal_type'] || (int) $row['principal_ref'] !== $user_id ) {
260 - return new WP_Error( 'desktop_mode_files_share_not_recipient', __( 'This invite is not for you.', 'desktop-mode' ), array( 'status' => 403 ) );
269 + return new WP_Error( 'openstation_files_share_not_recipient', __( 'This invite is not for you.', 'desktop-mode' ), array( 'status' => 403 ) );
261 270 }
262 271 if ( 'denied' === $row['state'] ) {
263 272 return $row;
264 273 }
@@ -263,14 +272,14 @@
263 272 return $row;
264 273 }
265 274 $was_accepted = 'accepted' === $row['state'];
266 275
267 - $tables = desktop_mode_files_table_names();
276 + $tables = openstation_files_table_names();
268 277 $wpdb->update(
269 278 $tables['shares'],
270 279 array(
271 280 'state' => 'denied',
272 - 'decided_at_ms' => desktop_mode_files_now_ms(),
281 + 'decided_at_ms' => openstation_files_now_ms(),
273 282 ),
274 283 array( 'id' => $share_id ),
275 284 array( '%s', '%d' ),
276 285 array( '%d' )
@@ -275,15 +284,15 @@
275 284 array( '%s', '%d' ),
276 285 array( '%d' )
277 286 );
278 287 if ( $was_accepted ) {
279 - desktop_mode_files_trash_upload_for_user( (int) $row['folder_id'], $user_id );
288 + openstation_files_trash_upload_for_user( (int) $row['folder_id'], $user_id );
280 289 }
281 290
282 - $next = desktop_mode_files_get_share( $share_id );
291 + $next = openstation_files_get_share( $share_id );
283 292
284 293 /** This action is documented in includes/desktop-files/shares-store.php */
285 - do_action( 'desktop_mode_files_share_denied', $share_id, $next, $user_id );
294 + do_action( 'openstation_files_share_denied', $share_id, $next, $user_id );
286 295
287 296 return $next;
288 297 }
289 298
@@ -293,21 +302,21 @@
293 302 * @param int $file_id Stored-file id.
294 303 * @param int $user_id Recipient.
295 304 * @return true|WP_Error
296 305 */
297 -function desktop_mode_stored_file_share_leave( $file_id, $user_id ) {
306 +function openstation_stored_file_share_leave( $file_id, $user_id ) {
298 307 global $wpdb;
299 308 $file_id = (int) $file_id;
300 309 $user_id = (int) $user_id;
301 - $file = desktop_mode_stored_files_get( $file_id );
310 + $file = openstation_stored_files_get( $file_id );
302 311 if ( ! $file ) {
303 - return new WP_Error( 'desktop_mode_files_not_found', __( 'File not found.', 'desktop-mode' ), array( 'status' => 404 ) );
312 + return new WP_Error( 'openstation_files_not_found', __( 'File not found.', 'desktop-mode' ), array( 'status' => 404 ) );
304 313 }
305 314 if ( (int) $file['owner_id'] === $user_id ) {
306 - return new WP_Error( 'desktop_mode_files_owner_cannot_leave', __( 'Owners cannot leave their own file.', 'desktop-mode' ), array( 'status' => 400 ) );
315 + return new WP_Error( 'openstation_files_owner_cannot_leave', __( 'Owners cannot leave their own file.', 'desktop-mode' ), array( 'status' => 400 ) );
307 316 }
308 317
309 - $tables = desktop_mode_files_table_names();
318 + $tables = openstation_files_table_names();
310 319 $row = $wpdb->get_row(
311 320 $wpdb->prepare(
312 321 "SELECT * FROM {$tables['shares']}
313 322 WHERE target_type = 'file' AND folder_id = %d
@@ -319,19 +328,19 @@
319 328 );
320 329
321 330 // Scrub the recipient's tile regardless — lingering placements
322 331 // from a previously revoked share must go too.
323 - desktop_mode_files_trash_upload_for_user( $file_id, $user_id );
332 + openstation_files_trash_upload_for_user( $file_id, $user_id );
324 333
325 334 if ( ! $row ) {
326 - return new WP_Error( 'desktop_mode_files_not_member', __( 'You do not have access to this file.', 'desktop-mode' ), array( 'status' => 404 ) );
335 + return new WP_Error( 'openstation_files_not_member', __( 'You do not have access to this file.', 'desktop-mode' ), array( 'status' => 404 ) );
327 336 }
328 - $normalized = desktop_mode_files_normalize_share_row( $row );
337 + $normalized = openstation_files_normalize_share_row( $row );
329 338 $wpdb->update(
330 339 $tables['shares'],
331 340 array(
332 341 'state' => 'denied',
333 - 'decided_at_ms' => desktop_mode_files_now_ms(),
342 + 'decided_at_ms' => openstation_files_now_ms(),
334 343 ),
335 344 array( 'id' => (int) $row['id'] ),
336 345 array( '%s', '%d' ),
337 346 array( '%d' )
@@ -337,9 +346,9 @@
337 346 array( '%d' )
338 347 );
339 348
340 349 /** This action is documented in includes/desktop-files/shares-store.php */
341 - do_action( 'desktop_mode_files_share_left', (int) $row['id'], $normalized, $user_id );
350 + do_action( 'openstation_files_share_left', (int) $row['id'], $normalized, $user_id );
342 351
343 352 return true;
344 353 }
345 354
@@ -349,30 +358,30 @@
349 358 * @param int $share_id Share id.
350 359 * @param int $actor_id Actor.
351 360 * @return true|WP_Error
352 361 */
353 -function desktop_mode_stored_file_share_revoke( $share_id, $actor_id ) {
362 +function openstation_stored_file_share_revoke( $share_id, $actor_id ) {
354 363 global $wpdb;
355 364 $share_id = (int) $share_id;
356 365 $actor_id = (int) $actor_id;
357 - $row = desktop_mode_files_get_share( $share_id );
366 + $row = openstation_files_get_share( $share_id );
358 367 if ( ! $row || 'file' !== $row['target_type'] ) {
359 - return new WP_Error( 'desktop_mode_files_share_not_found', __( 'Share not found.', 'desktop-mode' ), array( 'status' => 404 ) );
368 + return new WP_Error( 'openstation_files_share_not_found', __( 'Share not found.', 'desktop-mode' ), array( 'status' => 404 ) );
360 369 }
361 - if ( ! desktop_mode_stored_files_share_can_manage( (int) $row['folder_id'], $actor_id ) ) {
362 - return new WP_Error( 'desktop_mode_files_forbidden', __( 'You cannot manage shares for this file.', 'desktop-mode' ), array( 'status' => 403 ) );
370 + if ( ! openstation_stored_files_share_can_manage( (int) $row['folder_id'], $actor_id ) ) {
371 + return new WP_Error( 'openstation_files_forbidden', __( 'You cannot manage shares for this file.', 'desktop-mode' ), array( 'status' => 403 ) );
363 372 }
364 373
365 - $tables = desktop_mode_files_table_names();
374 + $tables = openstation_files_table_names();
366 375 $wpdb->delete( $tables['shares'], array( 'id' => $share_id ), array( '%d' ) );
367 376 $wpdb->delete( $tables['decisions'], array( 'share_id' => $share_id ), array( '%d' ) );
368 377
369 378 if ( 'accepted' === $row['state'] ) {
370 - desktop_mode_files_trash_upload_for_user( (int) $row['folder_id'], (int) $row['principal_ref'] );
379 + openstation_files_trash_upload_for_user( (int) $row['folder_id'], (int) $row['principal_ref'] );
371 380 }
372 381
373 382 /** This action is documented in includes/desktop-files/shares-store.php */
374 - do_action( 'desktop_mode_files_share_revoked', $share_id, $row, $actor_id );
383 + do_action( 'openstation_files_share_revoked', $share_id, $row, $actor_id );
375 384
376 385 return true;
377 386 }
378 387
@@ -387,9 +396,9 @@
387 396 * @param int $file_id Stored-file id.
388 397 * @param int $user_id Recipient whose placements to scrub.
389 398 * @return int Rows scrubbed.
390 399 */
391 -function desktop_mode_files_trash_upload_for_user( $file_id, $user_id ) {
400 +function openstation_files_trash_upload_for_user( $file_id, $user_id ) {
392 401 global $wpdb;
393 402 $file_id = (int) $file_id;
394 403 $user_id = (int) $user_id;
395 404 if ( $file_id <= 0 || $user_id <= 0 ) {
@@ -394,10 +403,10 @@
394 403 $user_id = (int) $user_id;
395 404 if ( $file_id <= 0 || $user_id <= 0 ) {
396 405 return 0;
397 406 }
398 - $tables = desktop_mode_files_table_names();
399 - $now = desktop_mode_files_now_ms();
407 + $tables = openstation_files_table_names();
408 + $now = openstation_files_now_ms();
400 409 $rows = $wpdb->get_results(
401 410 $wpdb->prepare(
402 411 "SELECT id FROM {$tables['placements']}
403 412 WHERE owner_id = %d
@@ -408,9 +417,9 @@
408 417 (string) $file_id
409 418 ),
410 419 ARRAY_A
411 420 );
412 - $count = 0;
421 + $count = 0;
413 422 foreach ( (array) $rows as $row ) {
414 423 $wpdb->update(
415 424 $tables['placements'],
416 425 array(
@@ -420,9 +429,9 @@
420 429 array( 'id' => (int) $row['id'] ),
421 430 array( '%d', '%d' ),
422 431 array( '%d' )
423 432 );
424 - $count++;
433 + ++$count;
425 434 }
426 435 return $count;
427 436 }
428 437
@@ -433,15 +442,15 @@
433 442 * @param int $user_id Viewer.
434 443 * @param int $since_ms Only rows with `invited_at_ms > since`.
435 444 * @return array[] Normalized share rows.
436 445 */
437 -function desktop_mode_files_get_pending_file_shares_for_user( $user_id, $since_ms = 0 ) {
446 +function openstation_files_get_pending_file_shares_for_user( $user_id, $since_ms = 0 ) {
438 447 global $wpdb;
439 448 $user_id = (int) $user_id;
440 449 if ( $user_id <= 0 ) {
441 450 return array();
442 451 }
443 - $tables = desktop_mode_files_table_names();
452 + $tables = openstation_files_table_names();
444 453 $rows = $wpdb->get_results(
445 454 $wpdb->prepare(
446 455 "SELECT s.* FROM {$tables['shares']} s
447 456 INNER JOIN {$tables['stored_files']} sf ON sf.id = s.folder_id
@@ -455,11 +464,11 @@
455 464 (string) $user_id
456 465 ),
457 466 ARRAY_A
458 467 );
459 - $out = array();
468 + $out = array();
460 469 foreach ( (array) $rows as $row ) {
461 - $out[] = desktop_mode_files_normalize_share_row( $row );
470 + $out[] = openstation_files_normalize_share_row( $row );
462 471 }
463 472 return $out;
464 473 }
465 474
@@ -468,10 +477,10 @@
468 477 *
469 478 * @param array $row Normalized share row (`target_type='file'`).
470 479 * @return array
471 480 */
472 -function desktop_mode_files_shape_file_share( $row ) {
473 - $file = desktop_mode_stored_files_get( (int) $row['folder_id'] );
481 +function openstation_files_shape_file_share( $row ) {
482 + $file = openstation_stored_files_get( (int) $row['folder_id'] );
474 483 $shape = array(
475 484 'id' => (int) $row['id'],
476 485 'targetType' => 'file',
477 486 'fileId' => (int) $row['folder_id'],
@@ -483,17 +492,17 @@
483 492 'invitedAtMs' => (int) $row['invited_at_ms'],
484 493 'decidedAtMs' => isset( $row['decided_at_ms'] ) ? $row['decided_at_ms'] : null,
485 494 );
486 495 if ( $file ) {
487 - $shape['fileName'] = (string) $file['display_name'];
488 - $shape['ownerId'] = (int) $file['owner_id'];
489 - $owner = get_userdata( (int) $file['owner_id'] );
490 - $shape['ownerName'] = $owner ? $owner->display_name : '';
496 + $shape['fileName'] = (string) $file['display_name'];
497 + $shape['ownerId'] = (int) $file['owner_id'];
498 + $owner = get_userdata( (int) $file['owner_id'] );
499 + $shape['ownerName'] = $owner ? openstation_plain_text_title( $owner->display_name ) : '';
491 500 $shape['ownerAvatar'] = $owner ? get_avatar_url( $owner->ID, array( 'size' => 48 ) ) : '';
492 501 }
493 502 // Principal enrichment for the owner-side share list.
494 - $principal = get_userdata( (int) $row['principal_ref'] );
495 - $shape['displayName'] = $principal ? $principal->display_name : '';
503 + $principal = get_userdata( (int) $row['principal_ref'] );
504 + $shape['displayName'] = $principal ? openstation_plain_text_title( $principal->display_name ) : '';
496 505 $shape['avatarUrl'] = $principal ? get_avatar_url( $principal->ID, array( 'size' => 48 ) ) : '';
497 506 return $shape;
498 507 }
499 508
@@ -502,50 +511,73 @@
502 511 // ---------------------------------------------------------------------------
503 512
504 513 /**
505 514 * Register the file-share routes. Same 404-when-disabled gate as
506 - * every other share route (`desktop_mode_files_rest_share_permission`).
515 + * every other share route (`openstation_files_rest_share_permission`).
507 516 */
508 -function desktop_mode_files_register_file_share_rest_routes() {
517 +function openstation_files_register_file_share_rest_routes() {
509 518 $ns = 'desktop-mode/v1';
510 519
511 - register_rest_route( $ns, '/files/uploads/(?P<id>\d+)/shares', array(
520 + register_rest_route(
521 + $ns,
522 + '/files/uploads/(?P<id>\d+)/shares',
512 523 array(
513 - 'methods' => WP_REST_Server::READABLE,
514 - 'permission_callback' => 'desktop_mode_files_rest_share_permission',
515 - 'callback' => 'desktop_mode_files_rest_list_file_shares',
516 - ),
524 + array(
525 + 'methods' => WP_REST_Server::READABLE,
526 + 'permission_callback' => 'openstation_files_rest_share_permission',
527 + 'callback' => 'openstation_files_rest_list_file_shares',
528 + ),
529 + array(
530 + 'methods' => WP_REST_Server::CREATABLE,
531 + 'permission_callback' => 'openstation_files_rest_share_permission',
532 + 'callback' => 'openstation_files_rest_create_file_share',
533 + 'args' => array(
534 + 'userId' => array(
535 + 'type' => 'integer',
536 + 'required' => true,
537 + ),
538 + ),
539 + ),
540 + )
541 + );
542 + register_rest_route(
543 + $ns,
544 + '/files/uploads/(?P<id>\d+)/shares/(?P<shareId>\d+)',
517 545 array(
546 + 'methods' => WP_REST_Server::DELETABLE,
547 + 'permission_callback' => 'openstation_files_rest_share_permission',
548 + 'callback' => 'openstation_files_rest_delete_file_share',
549 + )
550 + );
551 + register_rest_route(
552 + $ns,
553 + '/files/uploads/(?P<id>\d+)/shares/(?P<shareId>\d+)/accept',
554 + array(
518 555 'methods' => WP_REST_Server::CREATABLE,
519 - 'permission_callback' => 'desktop_mode_files_rest_share_permission',
520 - 'callback' => 'desktop_mode_files_rest_create_file_share',
521 - 'args' => array(
522 - 'userId' => array( 'type' => 'integer', 'required' => true ),
523 - ),
524 - ),
525 - ) );
526 - register_rest_route( $ns, '/files/uploads/(?P<id>\d+)/shares/(?P<shareId>\d+)', array(
527 - 'methods' => WP_REST_Server::DELETABLE,
528 - 'permission_callback' => 'desktop_mode_files_rest_share_permission',
529 - 'callback' => 'desktop_mode_files_rest_delete_file_share',
530 - ) );
531 - register_rest_route( $ns, '/files/uploads/(?P<id>\d+)/shares/(?P<shareId>\d+)/accept', array(
532 - 'methods' => WP_REST_Server::CREATABLE,
533 - 'permission_callback' => 'desktop_mode_files_rest_share_permission',
534 - 'callback' => 'desktop_mode_files_rest_accept_file_share',
535 - ) );
536 - register_rest_route( $ns, '/files/uploads/(?P<id>\d+)/shares/(?P<shareId>\d+)/deny', array(
537 - 'methods' => WP_REST_Server::CREATABLE,
538 - 'permission_callback' => 'desktop_mode_files_rest_share_permission',
539 - 'callback' => 'desktop_mode_files_rest_deny_file_share',
540 - ) );
541 - register_rest_route( $ns, '/files/uploads/(?P<id>\d+)/leave', array(
542 - 'methods' => WP_REST_Server::CREATABLE,
543 - 'permission_callback' => 'desktop_mode_files_rest_share_permission',
544 - 'callback' => 'desktop_mode_files_rest_leave_file_share',
545 - ) );
556 + 'permission_callback' => 'openstation_files_rest_share_permission',
557 + 'callback' => 'openstation_files_rest_accept_file_share',
558 + )
559 + );
560 + register_rest_route(
561 + $ns,
562 + '/files/uploads/(?P<id>\d+)/shares/(?P<shareId>\d+)/deny',
563 + array(
564 + 'methods' => WP_REST_Server::CREATABLE,
565 + 'permission_callback' => 'openstation_files_rest_share_permission',
566 + 'callback' => 'openstation_files_rest_deny_file_share',
567 + )
568 + );
569 + register_rest_route(
570 + $ns,
571 + '/files/uploads/(?P<id>\d+)/leave',
572 + array(
573 + 'methods' => WP_REST_Server::CREATABLE,
574 + 'permission_callback' => 'openstation_files_rest_share_permission',
575 + 'callback' => 'openstation_files_rest_leave_file_share',
576 + )
577 + );
546 578 }
547 -add_action( 'rest_api_init', 'desktop_mode_files_register_file_share_rest_routes' );
579 +add_action( 'rest_api_init', 'openstation_files_register_file_share_rest_routes' );
548 580
549 581 /**
550 582 * Resolve the `{shareId}` inside `{id}` or fail with a masked 404.
551 583 *
@@ -553,12 +585,12 @@
553 585 *
554 586 * @param WP_REST_Request $req Request.
555 587 * @return array|WP_Error Normalized share row.
556 588 */
557 -function desktop_mode_files_rest_resolve_file_share( WP_REST_Request $req ) {
558 - $row = desktop_mode_files_get_share( (int) $req['shareId'] );
589 +function openstation_files_rest_resolve_file_share( WP_REST_Request $req ) {
590 + $row = openstation_files_get_share( (int) $req['shareId'] );
559 591 if ( ! $row || 'file' !== $row['target_type'] || (int) $row['folder_id'] !== (int) $req['id'] ) {
560 - return new WP_Error( 'desktop_mode_files_share_not_found', __( 'Share not found.', 'desktop-mode' ), array( 'status' => 404 ) );
592 + return new WP_Error( 'openstation_files_share_not_found', __( 'Share not found.', 'desktop-mode' ), array( 'status' => 404 ) );
561 593 }
562 594 return $row;
563 595 }
564 596
@@ -564,17 +596,17 @@
564 596
565 597 /**
566 598 * GET /files/uploads/<id>/shares (managers only).
567 599 */
568 -function desktop_mode_files_rest_list_file_shares( WP_REST_Request $req ) {
600 +function openstation_files_rest_list_file_shares( WP_REST_Request $req ) {
569 601 $file_id = (int) $req['id'];
570 602 $user_id = get_current_user_id();
571 - if ( ! desktop_mode_stored_files_share_can_manage( $file_id, $user_id ) ) {
572 - return desktop_mode_files_download_not_found();
603 + if ( ! openstation_stored_files_share_can_manage( $file_id, $user_id ) ) {
604 + return openstation_files_download_not_found();
573 605 }
574 606 $out = array();
575 - foreach ( desktop_mode_stored_files_get_file_shares( $file_id ) as $row ) {
576 - $out[] = desktop_mode_files_shape_file_share( $row );
607 + foreach ( openstation_stored_files_get_file_shares( $file_id ) as $row ) {
608 + $out[] = openstation_files_shape_file_share( $row );
577 609 }
578 610 return rest_ensure_response( array( 'shares' => $out ) );
579 611 }
580 612
@@ -581,18 +613,18 @@
581 613 /**
582 614 * POST /files/uploads/<id>/shares — invite (read tier, always).
583 615 * A `capability` param, if sent, must be `read` — `write` is 400.
584 616 */
585 -function desktop_mode_files_rest_create_file_share( WP_REST_Request $req ) {
617 +function openstation_files_rest_create_file_share( WP_REST_Request $req ) {
586 618 $capability = $req->get_param( 'capability' );
587 619 if ( null !== $capability && 'read' !== (string) $capability ) {
588 620 return new WP_Error(
589 - 'desktop_mode_files_invalid_capability',
621 + 'openstation_files_invalid_capability',
590 622 __( 'Uploaded files can only be shared read-only.', 'desktop-mode' ),
591 623 array( 'status' => 400 )
592 624 );
593 625 }
594 - $id = desktop_mode_stored_file_share_invite(
626 + $id = openstation_stored_file_share_invite(
595 627 (int) $req['id'],
596 628 get_current_user_id(),
597 629 (int) $req->get_param( 'userId' )
598 630 );
@@ -598,20 +630,20 @@
598 630 );
599 631 if ( is_wp_error( $id ) ) {
600 632 return $id;
601 633 }
602 - return rest_ensure_response( desktop_mode_files_shape_file_share( desktop_mode_files_get_share( $id ) ) );
634 + return rest_ensure_response( openstation_files_shape_file_share( openstation_files_get_share( $id ) ) );
603 635 }
604 636
605 637 /**
606 638 * DELETE /files/uploads/<id>/shares/<shareId> — revoke.
607 639 */
608 -function desktop_mode_files_rest_delete_file_share( WP_REST_Request $req ) {
609 - $row = desktop_mode_files_rest_resolve_file_share( $req );
640 +function openstation_files_rest_delete_file_share( WP_REST_Request $req ) {
641 + $row = openstation_files_rest_resolve_file_share( $req );
610 642 if ( is_wp_error( $row ) ) {
611 643 return $row;
612 644 }
613 - $ok = desktop_mode_stored_file_share_revoke( (int) $row['id'], get_current_user_id() );
645 + $ok = openstation_stored_file_share_revoke( (int) $row['id'], get_current_user_id() );
614 646 if ( is_wp_error( $ok ) ) {
615 647 return $ok;
616 648 }
617 649 return rest_ensure_response( array( 'deleted' => true ) );
@@ -619,40 +651,40 @@
619 651
620 652 /**
621 653 * POST .../accept
622 654 */
623 -function desktop_mode_files_rest_accept_file_share( WP_REST_Request $req ) {
624 - $row = desktop_mode_files_rest_resolve_file_share( $req );
655 +function openstation_files_rest_accept_file_share( WP_REST_Request $req ) {
656 + $row = openstation_files_rest_resolve_file_share( $req );
625 657 if ( is_wp_error( $row ) ) {
626 658 return $row;
627 659 }
628 - $next = desktop_mode_stored_file_share_accept( (int) $row['id'], get_current_user_id() );
660 + $next = openstation_stored_file_share_accept( (int) $row['id'], get_current_user_id() );
629 661 if ( is_wp_error( $next ) ) {
630 662 return $next;
631 663 }
632 - return rest_ensure_response( desktop_mode_files_shape_file_share( $next ) );
664 + return rest_ensure_response( openstation_files_shape_file_share( $next ) );
633 665 }
634 666
635 667 /**
636 668 * POST .../deny
637 669 */
638 -function desktop_mode_files_rest_deny_file_share( WP_REST_Request $req ) {
639 - $row = desktop_mode_files_rest_resolve_file_share( $req );
670 +function openstation_files_rest_deny_file_share( WP_REST_Request $req ) {
671 + $row = openstation_files_rest_resolve_file_share( $req );
640 672 if ( is_wp_error( $row ) ) {
641 673 return $row;
642 674 }
643 - $next = desktop_mode_stored_file_share_deny( (int) $row['id'], get_current_user_id() );
675 + $next = openstation_stored_file_share_deny( (int) $row['id'], get_current_user_id() );
644 676 if ( is_wp_error( $next ) ) {
645 677 return $next;
646 678 }
647 - return rest_ensure_response( desktop_mode_files_shape_file_share( $next ) );
679 + return rest_ensure_response( openstation_files_shape_file_share( $next ) );
648 680 }
649 681
650 682 /**
651 683 * POST /files/uploads/<id>/leave
652 684 */
653 -function desktop_mode_files_rest_leave_file_share( WP_REST_Request $req ) {
654 - $ok = desktop_mode_stored_file_share_leave( (int) $req['id'], get_current_user_id() );
685 +function openstation_files_rest_leave_file_share( WP_REST_Request $req ) {
686 + $ok = openstation_stored_file_share_leave( (int) $req['id'], get_current_user_id() );
655 687 if ( is_wp_error( $ok ) ) {
656 688 return $ok;
657 689 }
658 690 return rest_ensure_response( array( 'left' => true ) );
@@ -670,12 +702,12 @@
670 702 *
671 703 * @param array $config Shell config.
672 704 * @return array
673 705 */
674 -function desktop_mode_files_file_share_inject_shell_config( $config ) {
706 +function openstation_files_file_share_inject_shell_config( $config ) {
675 707 $user_id = get_current_user_id();
676 - $sharing_enabled = function_exists( 'desktop_mode_files_sharing_enabled_for' )
677 - ? desktop_mode_files_sharing_enabled_for( $user_id )
708 + $sharing_enabled = function_exists( 'openstation_files_sharing_enabled_for' )
709 + ? openstation_files_sharing_enabled_for( $user_id )
678 710 : true;
679 711 if ( $user_id <= 0 || ! $sharing_enabled ) {
680 712 return $config;
681 713 }
@@ -681,11 +713,11 @@
681 713 }
682 714 $pending = isset( $config['serverPendingShares'] ) && is_array( $config['serverPendingShares'] )
683 715 ? $config['serverPendingShares']
684 716 : array();
685 - foreach ( desktop_mode_files_get_pending_file_shares_for_user( $user_id, 0 ) as $row ) {
686 - $pending[] = desktop_mode_files_shape_file_share( $row );
717 + foreach ( openstation_files_get_pending_file_shares_for_user( $user_id, 0 ) as $row ) {
718 + $pending[] = openstation_files_shape_file_share( $row );
687 719 }
688 720 $config['serverPendingShares'] = $pending;
689 721 return $config;
690 722 }
691 -add_filter( 'desktop_mode_shell_config', 'desktop_mode_files_file_share_inject_shell_config', 21 );
723 +add_filter( 'openstation_shell_config', 'openstation_files_file_share_inject_shell_config', 21 );