PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.10
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.10
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
← All changes | includes/desktop-files/trash.php +190 -208 0.9.51.1.10 View file →
@@ -1,7 +1,7 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode — Files-on-the-Desktop trash + restore + purge.
3 + * OpenStation — Files-on-the-Desktop trash + restore + purge.
4 4 *
5 5 * Both placements and folders soft-trash before they ever hit the
6 6 * physical row delete. Trashed rows live in the same tables (with
7 7 * `trashed_at_ms` / `trashed_by` columns set; `trashed_via_folder`
@@ -19,25 +19,25 @@
19 19 *
20 20 * - Veto any trash / restore / purge (`*_user_can_*` filters).
21 21 * - Observe any state transition (`*_before_*` / `*_after_*`).
22 22 * - React to recycle-bin list / restore / purge of the new types
23 - * via the existing recycle-bin hooks (`desktop_mode_recycle_bin_*`).
23 + * via the existing recycle-bin hooks (`openstation_recycle_bin_*`).
24 24 *
25 - * @package WPDesktopMode
26 - * @since 0.8.0
25 + * @package OpenStation
27 26 */
28 27
29 28 defined( 'ABSPATH' ) || exit;
30 29
31 -/* ================================================================== *
30 +/*
31 +================================================================== *
32 32 * Capability gates.
33 - * ================================================================== */
33 + * ==================================================================
34 + */
34 35
35 36 /**
36 37 * Default ownership check shared by every trash / restore / purge
37 38 * capability gate: the acting user must be the row's `owner_id`.
38 39 *
39 - * @since 0.8.0
40 40 * @access private
41 41 *
42 42 * @param int $user_id Acting user.
43 43 * @param array $row Placement or folder row.
@@ -42,9 +42,9 @@
42 42 * @param int $user_id Acting user.
43 43 * @param array $row Placement or folder row.
44 44 * @return bool
45 45 */
46 -function desktop_mode_files_user_owns_row( $user_id, $row ) {
46 +function openstation_files_user_owns_row( $user_id, $row ) {
47 47 $user_id = (int) $user_id;
48 48 return ( $user_id > 0 )
49 49 && isset( $row['owner_id'] )
50 50 && (int) $row['owner_id'] === $user_id;
@@ -53,27 +53,23 @@
53 53 /**
54 54 * Whether the given user can trash a placement they own. Defaults
55 55 * to ownership; plugins can broaden via filter.
56 56 *
57 - * @since 0.8.0
58 - *
59 57 * @param int $user_id Acting user.
60 58 * @param array $row Placement row (raw from DB or normalized).
61 59 * @return bool
62 60 */
63 -function desktop_mode_files_user_can_trash_placement( $user_id, $row ) {
61 +function openstation_files_user_can_trash_placement( $user_id, $row ) {
64 62 /**
65 63 * Filter whether the user can trash this placement.
66 64 *
67 - * @since 0.8.0
68 - *
69 65 * @param bool $can Default: ownership match.
70 66 * @param int $user_id Acting user.
71 67 * @param array $row Placement row.
72 68 */
73 69 return (bool) apply_filters(
74 - 'desktop_mode_files_user_can_trash_placement',
75 - desktop_mode_files_user_owns_row( $user_id, $row ),
70 + 'openstation_files_user_can_trash_placement',
71 + openstation_files_user_owns_row( $user_id, $row ),
76 72 (int) $user_id,
77 73 $row
78 74 );
79 75 }
@@ -80,25 +76,21 @@
80 76
81 77 /**
82 78 * Whether the given user can restore a trashed placement.
83 79 *
84 - * @since 0.8.0
85 - *
86 80 * @param int $user_id Acting user.
87 81 * @param array $row Placement row (already trashed).
88 82 * @return bool
89 83 */
90 -function desktop_mode_files_user_can_restore_placement( $user_id, $row ) {
84 +function openstation_files_user_can_restore_placement( $user_id, $row ) {
91 85 /**
92 - * @since 0.8.0
93 - *
94 86 * @param bool $can
95 87 * @param int $user_id
96 88 * @param array $row
97 89 */
98 90 return (bool) apply_filters(
99 - 'desktop_mode_files_user_can_restore_placement',
100 - desktop_mode_files_user_owns_row( $user_id, $row ),
91 + 'openstation_files_user_can_restore_placement',
92 + openstation_files_user_owns_row( $user_id, $row ),
101 93 (int) $user_id,
102 94 $row
103 95 );
104 96 }
@@ -104,22 +96,18 @@
104 96 }
105 97
106 98 /**
107 99 * Whether the given user can permanently purge a trashed placement.
108 - *
109 - * @since 0.8.0
110 100 */
111 -function desktop_mode_files_user_can_purge_placement( $user_id, $row ) {
101 +function openstation_files_user_can_purge_placement( $user_id, $row ) {
112 102 /**
113 - * @since 0.8.0
114 - *
115 103 * @param bool $can
116 104 * @param int $user_id
117 105 * @param array $row
118 106 */
119 107 return (bool) apply_filters(
120 - 'desktop_mode_files_user_can_purge_placement',
121 - desktop_mode_files_user_owns_row( $user_id, $row ),
108 + 'openstation_files_user_can_purge_placement',
109 + openstation_files_user_owns_row( $user_id, $row ),
122 110 (int) $user_id,
123 111 $row
124 112 );
125 113 }
@@ -125,22 +113,18 @@
125 113 }
126 114
127 115 /**
128 116 * Whether the given user can trash a folder. Default: folder owner.
129 - *
130 - * @since 0.8.0
131 117 */
132 -function desktop_mode_files_user_can_trash_folder( $user_id, $row ) {
118 +function openstation_files_user_can_trash_folder( $user_id, $row ) {
133 119 /**
134 - * @since 0.8.0
135 - *
136 120 * @param bool $can
137 121 * @param int $user_id
138 122 * @param array $row
139 123 */
140 124 return (bool) apply_filters(
141 - 'desktop_mode_files_user_can_trash_folder',
142 - desktop_mode_files_user_owns_row( $user_id, $row ),
125 + 'openstation_files_user_can_trash_folder',
126 + openstation_files_user_owns_row( $user_id, $row ),
143 127 (int) $user_id,
144 128 $row
145 129 );
146 130 }
@@ -146,22 +130,18 @@
146 130 }
147 131
148 132 /**
149 133 * Whether the given user can restore a trashed folder.
150 - *
151 - * @since 0.8.0
152 134 */
153 -function desktop_mode_files_user_can_restore_folder( $user_id, $row ) {
135 +function openstation_files_user_can_restore_folder( $user_id, $row ) {
154 136 /**
155 - * @since 0.8.0
156 - *
157 137 * @param bool $can
158 138 * @param int $user_id
159 139 * @param array $row
160 140 */
161 141 return (bool) apply_filters(
162 - 'desktop_mode_files_user_can_restore_folder',
163 - desktop_mode_files_user_owns_row( $user_id, $row ),
142 + 'openstation_files_user_can_restore_folder',
143 + openstation_files_user_owns_row( $user_id, $row ),
164 144 (int) $user_id,
165 145 $row
166 146 );
167 147 }
@@ -167,28 +147,25 @@
167 147 }
168 148
169 149 /**
170 150 * Whether the given user can permanently purge a trashed folder.
171 - *
172 - * @since 0.8.0
173 151 */
174 -function desktop_mode_files_user_can_purge_folder( $user_id, $row ) {
152 +function openstation_files_user_can_purge_folder( $user_id, $row ) {
175 153 /**
176 - * @since 0.8.0
177 - *
178 154 * @param bool $can
179 155 * @param int $user_id
180 156 * @param array $row
181 157 */
182 158 return (bool) apply_filters(
183 - 'desktop_mode_files_user_can_purge_folder',
184 - desktop_mode_files_user_owns_row( $user_id, $row ),
159 + 'openstation_files_user_can_purge_folder',
160 + openstation_files_user_owns_row( $user_id, $row ),
185 161 (int) $user_id,
186 162 $row
187 163 );
188 164 }
189 165
190 -/* ================================================================== *
166 +/*
167 +================================================================== *
191 168 * Ancestry snapshot + resurrection.
192 169 *
193 170 * When a placement is soft-trashed we capture every folder in
194 171 * its parent chain into a JSON blob on `placements.trashed_meta`.
@@ -196,9 +173,10 @@
196 173 * still alive are reused, trashed folders cascade-restore, and
197 174 * hard-deleted folders are recreated (with new ids; the chain is
198 175 * rewritten as it walks). The placement comes back at the same
199 176 * visual position inside the (possibly resurrected) parent.
200 - * ================================================================== */
177 + * ==================================================================
178 + */
201 179
202 180 /**
203 181 * Walk up `$parent_id` through the folders + placements tables and
204 182 * return the parent chain root-first.
@@ -217,16 +195,14 @@
217 195 * )
218 196 *
219 197 * Returns `[]` for a root-level placement (`$parent_id === 0`).
220 198 *
221 - * @since 0.8.0
222 - *
223 199 * @param int $parent_id Immediate parent folder id.
224 200 * @return array<int, array<string, mixed>>
225 201 */
226 -function desktop_mode_files_capture_ancestry( $parent_id ) {
202 +function openstation_files_capture_ancestry( $parent_id ) {
227 203 global $wpdb;
228 - $tables = desktop_mode_files_table_names();
204 + $tables = openstation_files_table_names();
229 205 $chain = array();
230 206 $cursor = (int) $parent_id;
231 207 $guard = 0; // depth-bound — defends against accidental cycles.
232 208 while ( $cursor > 0 && $guard < 32 ) {
@@ -243,9 +219,9 @@
243 219 }
244 220 // The folder's "where I sit on the desktop tree" lives on
245 221 // its placement row. Pick any active or trashed placement
246 222 // of this folder — we just need its parent_id + (x, y).
247 - $placement = $wpdb->get_row(
223 + $placement = $wpdb->get_row(
248 224 $wpdb->prepare(
249 225 "SELECT parent_id, x, y FROM {$tables['placements']}
250 226 WHERE file_type = 'folder' AND file_ref = %s
251 227 ORDER BY id ASC LIMIT 1",
@@ -254,9 +230,9 @@
254 230 ARRAY_A
255 231 );
256 232 $share_meta_raw = isset( $folder['share_meta'] ) ? (string) $folder['share_meta'] : '';
257 233 $share_meta = '' !== $share_meta_raw ? json_decode( $share_meta_raw, true ) : null;
258 - $entry = array(
234 + $entry = array(
259 235 'folder_id' => (int) $folder['id'],
260 236 'folder_name' => (string) $folder['name'],
261 237 'folder_share_mode' => (string) $folder['share_mode'],
262 238 'folder_share_meta' => is_array( $share_meta ) ? $share_meta : null,
@@ -278,10 +254,8 @@
278 254 * downstream entries rewrite their `placement_parent_id` so a
279 255 * deeper folder lands inside the correct (possibly recreated)
280 256 * parent.
281 257 *
282 - * @since 0.8.0
283 - *
284 258 * @param int $user_id Acting user (used as owner for any
285 259 * recreated folder).
286 260 * @param array $ancestry Root-first chain captured at trash time.
287 261 * @return int Resolved leaf parent id (0 when the placement was
@@ -286,9 +260,9 @@
286 260 * @param array $ancestry Root-first chain captured at trash time.
287 261 * @return int Resolved leaf parent id (0 when the placement was
288 262 * at desktop root).
289 263 */
290 -function desktop_mode_files_resurrect_ancestry( $user_id, $ancestry ) {
264 +function openstation_files_resurrect_ancestry( $user_id, $ancestry ) {
291 265 if ( empty( $ancestry ) ) {
292 266 return 0;
293 267 }
294 268 $user_id = (int) $user_id;
@@ -302,15 +276,15 @@
302 276 $resolved_parent = isset( $id_map[ $orig_par ] )
303 277 ? (int) $id_map[ $orig_par ]
304 278 : $orig_par;
305 279
306 - $folder = desktop_mode_files_get_folder( $orig_id, true );
280 + $folder = openstation_files_get_folder( $orig_id, true );
307 281 if ( $folder ) {
308 282 // Folder still exists. If trashed, restore it (cascade
309 283 // brings back its own children that were trashed via
310 284 // folder cascade).
311 285 if ( ! empty( $folder['trashed_at_ms'] ) ) {
312 - desktop_mode_files_restore_folder( $user_id, $orig_id );
286 + openstation_files_restore_folder( $user_id, $orig_id );
313 287 }
314 288 $id_map[ $orig_id ] = $orig_id;
315 289 $resolved = $orig_id;
316 290 continue;
@@ -319,23 +293,26 @@
319 293 // Folder is gone — recreate it and place it under the
320 294 // resolved parent. Owner falls back to the acting user
321 295 // when the original owner can't be inferred (shared-
322 296 // folder edge case Phase 6 will revisit).
323 - $owner_id = (int) ( $entry['folder_owner_id'] ?: $user_id );
324 - $new_id = desktop_mode_files_create_folder( $owner_id, array(
325 - 'name' => (string) $entry['folder_name'],
326 - 'share_mode' => (string) $entry['folder_share_mode'],
327 - 'share_meta' => $entry['folder_share_meta'],
328 - ) );
297 + $owner_id = (int) ( $entry['folder_owner_id'] ? $entry['folder_owner_id'] : $user_id );
298 + $new_id = openstation_files_create_folder(
299 + $owner_id,
300 + array(
301 + 'name' => (string) $entry['folder_name'],
302 + 'share_mode' => (string) $entry['folder_share_mode'],
303 + 'share_meta' => $entry['folder_share_meta'],
304 + )
305 + );
329 306 if ( is_wp_error( $new_id ) ) {
330 307 // Fall back to root — restoring at the wrong place is
331 308 // strictly better than failing the restore outright.
332 - $resolved = $resolved_parent;
309 + $resolved = $resolved_parent;
333 310 $id_map[ $orig_id ] = $resolved;
334 311 continue;
335 312 }
336 313 // Place the recreated folder where the snapshot says.
337 - desktop_mode_files_place(
314 + openstation_files_place(
338 315 $user_id,
339 316 $resolved_parent,
340 317 'folder',
341 318 (string) $new_id,
@@ -349,11 +326,13 @@
349 326 }
350 327 return $resolved;
351 328 }
352 329
353 -/* ================================================================== *
330 +/*
331 +================================================================== *
354 332 * Placement: trash / restore / purge.
355 - * ================================================================== */
333 + * ==================================================================
334 + */
356 335
357 336 /**
358 337 * Soft-trash a placement. Sets `trashed_at_ms`, `trashed_by`. Returns
359 338 * `true` on success, `WP_Error` on permission failure / missing row.
@@ -360,19 +339,17 @@
360 339 *
361 340 * Idempotent: trashing an already-trashed placement is a no-op
362 341 * success.
363 342 *
364 - * @since 0.8.0
365 - *
366 343 * @param int $user_id Acting user.
367 344 * @param int $placement_id Placement id.
368 345 * @return true|WP_Error
369 346 */
370 -function desktop_mode_files_trash_placement( $user_id, $placement_id ) {
347 +function openstation_files_trash_placement( $user_id, $placement_id ) {
371 348 global $wpdb;
372 349 $user_id = (int) $user_id;
373 350 $placement_id = (int) $placement_id;
374 - $tables = desktop_mode_files_table_names();
351 + $tables = openstation_files_table_names();
375 352
376 353 $row = $wpdb->get_row(
377 354 $wpdb->prepare(
378 355 "SELECT * FROM {$tables['placements']} WHERE id = %d",
@@ -381,9 +358,9 @@
381 358 ARRAY_A
382 359 );
383 360 if ( ! $row ) {
384 361 return new WP_Error(
385 - 'desktop_mode_files_placement_not_found',
362 + 'openstation_files_placement_not_found',
386 363 __( 'Placement not found.', 'desktop-mode' ),
387 364 array( 'status' => 404 )
388 365 );
389 366 }
@@ -389,11 +366,11 @@
389 366 }
390 367 if ( null !== $row['trashed_at_ms'] && '' !== $row['trashed_at_ms'] ) {
391 368 return true;
392 369 }
393 - if ( ! desktop_mode_files_user_can_trash_placement( $user_id, $row ) ) {
370 + if ( ! openstation_files_user_can_trash_placement( $user_id, $row ) ) {
394 371 return new WP_Error(
395 - 'desktop_mode_files_forbidden',
372 + 'openstation_files_forbidden',
396 373 __( 'You do not have permission to trash this item.', 'desktop-mode' ),
397 374 array( 'status' => 403 )
398 375 );
399 376 }
@@ -400,18 +377,16 @@
400 377
401 378 /**
402 379 * Fires before a placement is trashed.
403 380 *
404 - * @since 0.8.0
405 - *
406 381 * @param int $placement_id Placement id.
407 382 * @param int $user_id Acting user.
408 383 * @param array $row Placement row.
409 384 */
410 - do_action( 'desktop_mode_files_before_trash_placement', $placement_id, $user_id, $row );
385 + do_action( 'openstation_files_before_trash_placement', $placement_id, $user_id, $row );
411 386
412 - $now = desktop_mode_files_now_ms();
413 - $ancestry = desktop_mode_files_capture_ancestry( (int) $row['parent_id'] );
387 + $now = openstation_files_now_ms();
388 + $ancestry = openstation_files_capture_ancestry( (int) $row['parent_id'] );
414 389 $meta = wp_json_encode( array( 'ancestry' => $ancestry ) );
415 390 $result = $wpdb->update(
416 391 $tables['placements'],
417 392 array(
@@ -430,9 +405,9 @@
430 405 // 200 OK and the UI would show "moved to trash" with nothing
431 406 // actually trashed.
432 407 if ( false === $result ) {
433 408 return new WP_Error(
434 - 'desktop_mode_files_trash_failed',
409 + 'openstation_files_trash_failed',
435 410 isset( $wpdb->last_error ) && $wpdb->last_error
436 411 ? (string) $wpdb->last_error
437 412 : __( 'Failed to write trash row.', 'desktop-mode' ),
438 413 array( 'status' => 500 )
@@ -441,14 +416,12 @@
441 416
442 417 /**
443 418 * Fires after a placement is trashed.
444 419 *
445 - * @since 0.8.0
446 - *
447 420 * @param int $placement_id Placement id.
448 421 * @param int $user_id Acting user.
449 422 */
450 - do_action( 'desktop_mode_files_after_trash_placement', $placement_id, $user_id );
423 + do_action( 'openstation_files_after_trash_placement', $placement_id, $user_id );
451 424
452 425 return true;
453 426 }
454 427
@@ -454,19 +427,17 @@
454 427
455 428 /**
456 429 * Restore a trashed placement back to its original folder + (x, y).
457 430 *
458 - * @since 0.8.0
459 - *
460 431 * @param int $user_id Acting user.
461 432 * @param int $placement_id Placement id.
462 433 * @return true|WP_Error
463 434 */
464 -function desktop_mode_files_restore_placement( $user_id, $placement_id ) {
435 +function openstation_files_restore_placement( $user_id, $placement_id ) {
465 436 global $wpdb;
466 437 $user_id = (int) $user_id;
467 438 $placement_id = (int) $placement_id;
468 - $tables = desktop_mode_files_table_names();
439 + $tables = openstation_files_table_names();
469 440
470 441 $row = $wpdb->get_row(
471 442 $wpdb->prepare(
472 443 "SELECT * FROM {$tables['placements']} WHERE id = %d",
@@ -475,9 +446,9 @@
475 446 ARRAY_A
476 447 );
477 448 if ( ! $row ) {
478 449 return new WP_Error(
479 - 'desktop_mode_files_placement_not_found',
450 + 'openstation_files_placement_not_found',
480 451 __( 'Placement not found.', 'desktop-mode' ),
481 452 array( 'status' => 404 )
482 453 );
483 454 }
@@ -483,11 +454,11 @@
483 454 }
484 455 if ( null === $row['trashed_at_ms'] || '' === $row['trashed_at_ms'] ) {
485 456 return true; // Already active — idempotent.
486 457 }
487 - if ( ! desktop_mode_files_user_can_restore_placement( $user_id, $row ) ) {
458 + if ( ! openstation_files_user_can_restore_placement( $user_id, $row ) ) {
488 459 return new WP_Error(
489 - 'desktop_mode_files_forbidden',
460 + 'openstation_files_forbidden',
490 461 __( 'You do not have permission to restore this item.', 'desktop-mode' ),
491 462 array( 'status' => 403 )
492 463 );
493 464 }
@@ -492,24 +463,24 @@
492 463 );
493 464 }
494 465
495 466 // Resolve the parent folder. Three branches:
496 - // - parent is alive → reuse the same id
497 - // - parent is trashed → cascade-restore it (and rest of the
498 - // chain) before placing the leaf
499 - // - parent is gone → walk the captured ancestry and
500 - // recreate every missing folder in
501 - // the chain
467 + // - parent is alive → reuse the same id
468 + // - parent is trashed → cascade-restore it (and rest of the
469 + // chain) before placing the leaf
470 + // - parent is gone → walk the captured ancestry and
471 + // recreate every missing folder in
472 + // the chain
502 473 $original_parent_id = (int) $row['parent_id'];
503 474 $resolved_parent_id = $original_parent_id;
504 475 if ( $original_parent_id > 0 ) {
505 - $parent_alive = desktop_mode_files_get_folder( $original_parent_id, true );
476 + $parent_alive = openstation_files_get_folder( $original_parent_id, true );
506 477 if ( $parent_alive ) {
507 478 if ( ! empty( $parent_alive['trashed_at_ms'] ) ) {
508 479 // Cascade restore — reach into the snapshot the
509 480 // folder itself stored at trash time so any chain
510 481 // above it is also resurrected.
511 - $folder_restore = desktop_mode_files_restore_folder( $user_id, $original_parent_id );
482 + $folder_restore = openstation_files_restore_folder( $user_id, $original_parent_id );
512 483 if ( is_wp_error( $folder_restore ) ) {
513 484 return $folder_restore;
514 485 }
515 486 }
@@ -516,14 +487,14 @@
516 487 $resolved_parent_id = $original_parent_id;
517 488 } else {
518 489 // Hard-deleted parent — read the ancestry snapshot we
519 490 // stored at trash time and resurrect the chain.
520 - $meta_raw = isset( $row['trashed_meta'] ) ? (string) $row['trashed_meta'] : '';
521 - $decoded = '' !== $meta_raw ? json_decode( $meta_raw, true ) : null;
522 - $ancestry = ( is_array( $decoded ) && isset( $decoded['ancestry'] ) && is_array( $decoded['ancestry'] ) )
491 + $meta_raw = isset( $row['trashed_meta'] ) ? (string) $row['trashed_meta'] : '';
492 + $decoded = '' !== $meta_raw ? json_decode( $meta_raw, true ) : null;
493 + $ancestry = ( is_array( $decoded ) && isset( $decoded['ancestry'] ) && is_array( $decoded['ancestry'] ) )
523 494 ? $decoded['ancestry']
524 495 : array();
525 - $resolved_parent_id = desktop_mode_files_resurrect_ancestry( $user_id, $ancestry );
496 + $resolved_parent_id = openstation_files_resurrect_ancestry( $user_id, $ancestry );
526 497 }
527 498 }
528 499
529 500 /**
@@ -528,15 +499,13 @@
528 499
529 500 /**
530 501 * Fires before a placement is restored.
531 502 *
532 - * @since 0.8.0
533 - *
534 503 * @param int $placement_id
535 504 * @param int $user_id
536 505 * @param array $row
537 506 */
538 - do_action( 'desktop_mode_files_before_restore_placement', $placement_id, $user_id, $row );
507 + do_action( 'openstation_files_before_restore_placement', $placement_id, $user_id, $row );
539 508
540 509 $wpdb->update(
541 510 $tables['placements'],
542 511 array(
@@ -544,9 +513,9 @@
544 513 'trashed_at_ms' => null,
545 514 'trashed_by' => null,
546 515 'trashed_via_folder' => null,
547 516 'trashed_meta' => null,
548 - 'updated_at_ms' => desktop_mode_files_now_ms(),
517 + 'updated_at_ms' => openstation_files_now_ms(),
549 518 ),
550 519 array( 'id' => $placement_id ),
551 520 array( '%d', null, null, null, null, '%d' ),
552 521 array( '%d' )
@@ -556,17 +525,15 @@
556 525 // a placement coming back to life must not carry lingering
557 526 // tombstones from an earlier (reversible) removal. Without this,
558 527 // every heartbeat tick would re-deliver those tombstones to the
559 528 // client and the row would flicker off the desktop on each tick.
560 - desktop_mode_files_clear_tombstones_for( 'placement', $placement_id );
529 + openstation_files_clear_tombstones_for( 'placement', $placement_id );
561 530
562 531 /**
563 - * @since 0.8.0
564 - *
565 532 * @param int $placement_id
566 533 * @param int $user_id
567 534 */
568 - do_action( 'desktop_mode_files_after_restore_placement', $placement_id, $user_id );
535 + do_action( 'openstation_files_after_restore_placement', $placement_id, $user_id );
569 536
570 537 return true;
571 538 }
572 539
@@ -572,19 +539,17 @@
572 539
573 540 /**
574 541 * Permanently delete a trashed placement.
575 542 *
576 - * @since 0.8.0
577 - *
578 543 * @param int $user_id
579 544 * @param int $placement_id
580 545 * @return true|WP_Error
581 546 */
582 -function desktop_mode_files_purge_placement( $user_id, $placement_id ) {
547 +function openstation_files_purge_placement( $user_id, $placement_id ) {
583 548 global $wpdb;
584 549 $user_id = (int) $user_id;
585 550 $placement_id = (int) $placement_id;
586 - $tables = desktop_mode_files_table_names();
551 + $tables = openstation_files_table_names();
587 552
588 553 $row = $wpdb->get_row(
589 554 $wpdb->prepare(
590 555 "SELECT * FROM {$tables['placements']} WHERE id = %d",
@@ -594,11 +559,11 @@
594 559 );
595 560 if ( ! $row ) {
596 561 return true; // Already gone — idempotent.
597 562 }
598 - if ( ! desktop_mode_files_user_can_purge_placement( $user_id, $row ) ) {
563 + if ( ! openstation_files_user_can_purge_placement( $user_id, $row ) ) {
599 564 return new WP_Error(
600 - 'desktop_mode_files_forbidden',
565 + 'openstation_files_forbidden',
601 566 __( 'You do not have permission to delete this item.', 'desktop-mode' ),
602 567 array( 'status' => 403 )
603 568 );
604 569 }
@@ -603,32 +568,41 @@
603 568 );
604 569 }
605 570
606 571 /**
607 - * @since 0.8.0
608 - *
609 572 * @param int $placement_id
610 573 * @param int $user_id
611 574 * @param array $row
612 575 */
613 - do_action( 'desktop_mode_files_before_purge_placement', $placement_id, $user_id, $row );
576 + do_action( 'openstation_files_before_purge_placement', $placement_id, $user_id, $row );
614 577
615 578 $wpdb->delete( $tables['placements'], array( 'id' => $placement_id ), array( '%d' ) );
616 579
580 + // Mirror `openstation_files_remove()`: a purge IS a permanent
581 + // removal, so the same lifecycle action fires. Load-bearing for
582 + // the `upload` type — the stored-files listener deletes the real
583 + // bytes when the owner's last placement goes away; without this
584 + // the recycle-bin "Delete forever" path leaked them.
585 + do_action(
586 + 'openstation_file_unplaced',
587 + $placement_id,
588 + openstation_files_normalize_placement_row( $row )
589 + );
590 +
617 591 /**
618 - * @since 0.8.0
619 - *
620 592 * @param int $placement_id
621 593 * @param int $user_id
622 594 */
623 - do_action( 'desktop_mode_files_after_purge_placement', $placement_id, $user_id );
595 + do_action( 'openstation_files_after_purge_placement', $placement_id, $user_id );
624 596
625 597 return true;
626 598 }
627 599
628 -/* ================================================================== *
600 +/*
601 +================================================================== *
629 602 * Folder: trash / restore / purge (cascades to child placements).
630 - * ================================================================== */
603 + * ==================================================================
604 + */
631 605
632 606 /**
633 607 * Soft-trash a folder. Cascades to every child placement (any
634 608 * placement whose `parent_id = folder_id`), marking them with
@@ -636,19 +610,17 @@
636 610 * the same set without time-window heuristics.
637 611 *
638 612 * Idempotent on already-trashed.
639 613 *
640 - * @since 0.8.0
641 - *
642 614 * @param int $user_id
643 615 * @param int $folder_id
644 616 * @return true|WP_Error
645 617 */
646 -function desktop_mode_files_trash_folder( $user_id, $folder_id ) {
618 +function openstation_files_trash_folder( $user_id, $folder_id ) {
647 619 global $wpdb;
648 620 $user_id = (int) $user_id;
649 621 $folder_id = (int) $folder_id;
650 - $tables = desktop_mode_files_table_names();
622 + $tables = openstation_files_table_names();
651 623
652 624 $row = $wpdb->get_row(
653 625 $wpdb->prepare(
654 626 "SELECT * FROM {$tables['folders']} WHERE id = %d",
@@ -657,9 +629,9 @@
657 629 ARRAY_A
658 630 );
659 631 if ( ! $row ) {
660 632 return new WP_Error(
661 - 'desktop_mode_files_folder_not_found',
633 + 'openstation_files_folder_not_found',
662 634 __( 'Folder not found.', 'desktop-mode' ),
663 635 array( 'status' => 404 )
664 636 );
665 637 }
@@ -665,11 +637,11 @@
665 637 }
666 638 if ( null !== $row['trashed_at_ms'] && '' !== $row['trashed_at_ms'] ) {
667 639 return true;
668 640 }
669 - if ( ! desktop_mode_files_user_can_trash_folder( $user_id, $row ) ) {
641 + if ( ! openstation_files_user_can_trash_folder( $user_id, $row ) ) {
670 642 return new WP_Error(
671 - 'desktop_mode_files_forbidden',
643 + 'openstation_files_forbidden',
672 644 __( 'You do not have permission to trash this folder.', 'desktop-mode' ),
673 645 array( 'status' => 403 )
674 646 );
675 647 }
@@ -674,17 +646,15 @@
674 646 );
675 647 }
676 648
677 649 /**
678 - * @since 0.8.0
679 - *
680 650 * @param int $folder_id
681 651 * @param int $user_id
682 652 * @param array $row
683 653 */
684 - do_action( 'desktop_mode_files_before_trash_folder', $folder_id, $user_id, $row );
654 + do_action( 'openstation_files_before_trash_folder', $folder_id, $user_id, $row );
685 655
686 - $now = desktop_mode_files_now_ms();
656 + $now = openstation_files_now_ms();
687 657 // Capture the folder's own placement-chain ancestry so a future
688 658 // restore can resurrect any parent folders that got hard-deleted
689 659 // while this one was sitting in trash.
690 660 $folder_placement = $wpdb->get_row(
@@ -695,12 +665,12 @@
695 665 (string) $folder_id
696 666 ),
697 667 ARRAY_A
698 668 );
699 - $folder_ancestry = $folder_placement
700 - ? desktop_mode_files_capture_ancestry( (int) $folder_placement['parent_id'] )
669 + $folder_ancestry = $folder_placement
670 + ? openstation_files_capture_ancestry( (int) $folder_placement['parent_id'] )
701 671 : array();
702 - $folder_meta = wp_json_encode( array( 'ancestry' => $folder_ancestry ) );
672 + $folder_meta = wp_json_encode( array( 'ancestry' => $folder_ancestry ) );
703 673
704 674 // Trash the folder row.
705 675 $folder_update = $wpdb->update(
706 676 $tables['folders'],
@@ -715,9 +685,9 @@
715 685 array( '%d' )
716 686 );
717 687 if ( false === $folder_update ) {
718 688 return new WP_Error(
719 - 'desktop_mode_files_trash_failed',
689 + 'openstation_files_trash_failed',
720 690 isset( $wpdb->last_error ) && $wpdb->last_error
721 691 ? (string) $wpdb->last_error
722 692 : __( 'Failed to trash folder.', 'desktop-mode' ),
723 693 array( 'status' => 500 )
@@ -731,9 +701,9 @@
731 701 // just one child later (after the parent folder was hard-
732 702 // deleted) can still recreate the chain — same shape as a
733 703 // direct trash. Captured per-row because every child shares
734 704 // the same parent chain, so we compute once.
735 - $ancestry = desktop_mode_files_capture_ancestry( $folder_id );
705 + $ancestry = openstation_files_capture_ancestry( $folder_id );
736 706 $meta = wp_json_encode( array( 'ancestry' => $ancestry ) );
737 707 $wpdb->query(
738 708 $wpdb->prepare(
739 709 "UPDATE {$tables['placements']}
@@ -762,18 +732,16 @@
762 732 $folder_id
763 733 )
764 734 );
765 735 foreach ( (array) $child_folder_ids as $child_id ) {
766 - desktop_mode_files_trash_folder( $user_id, (int) $child_id );
736 + openstation_files_trash_folder( $user_id, (int) $child_id );
767 737 }
768 738
769 739 /**
770 - * @since 0.8.0
771 - *
772 740 * @param int $folder_id
773 741 * @param int $user_id
774 742 */
775 - do_action( 'desktop_mode_files_after_trash_folder', $folder_id, $user_id );
743 + do_action( 'openstation_files_after_trash_folder', $folder_id, $user_id );
776 744
777 745 return true;
778 746 }
779 747
@@ -782,19 +750,17 @@
782 750 * its cascade. Items that were trashed BEFORE the folder cascade
783 751 * (i.e. `trashed_via_folder IS NULL`) stay in the recycle bin —
784 752 * the user trashed them deliberately, separate from the folder.
785 753 *
786 - * @since 0.8.0
787 - *
788 754 * @param int $user_id
789 755 * @param int $folder_id
790 756 * @return true|WP_Error
791 757 */
792 -function desktop_mode_files_restore_folder( $user_id, $folder_id ) {
758 +function openstation_files_restore_folder( $user_id, $folder_id ) {
793 759 global $wpdb;
794 760 $user_id = (int) $user_id;
795 761 $folder_id = (int) $folder_id;
796 - $tables = desktop_mode_files_table_names();
762 + $tables = openstation_files_table_names();
797 763
798 764 $row = $wpdb->get_row(
799 765 $wpdb->prepare(
800 766 "SELECT * FROM {$tables['folders']} WHERE id = %d",
@@ -803,9 +769,9 @@
803 769 ARRAY_A
804 770 );
805 771 if ( ! $row ) {
806 772 return new WP_Error(
807 - 'desktop_mode_files_folder_not_found',
773 + 'openstation_files_folder_not_found',
808 774 __( 'Folder not found.', 'desktop-mode' ),
809 775 array( 'status' => 404 )
810 776 );
811 777 }
@@ -811,11 +777,11 @@
811 777 }
812 778 if ( null === $row['trashed_at_ms'] || '' === $row['trashed_at_ms'] ) {
813 779 return true;
814 780 }
815 - if ( ! desktop_mode_files_user_can_restore_folder( $user_id, $row ) ) {
781 + if ( ! openstation_files_user_can_restore_folder( $user_id, $row ) ) {
816 782 return new WP_Error(
817 - 'desktop_mode_files_forbidden',
783 + 'openstation_files_forbidden',
818 784 __( 'You do not have permission to restore this folder.', 'desktop-mode' ),
819 785 array( 'status' => 403 )
820 786 );
821 787 }
@@ -820,17 +786,15 @@
820 786 );
821 787 }
822 788
823 789 /**
824 - * @since 0.8.0
825 - *
826 790 * @param int $folder_id
827 791 * @param int $user_id
828 792 * @param array $row
829 793 */
830 - do_action( 'desktop_mode_files_before_restore_folder', $folder_id, $user_id, $row );
794 + do_action( 'openstation_files_before_restore_folder', $folder_id, $user_id, $row );
831 795
832 - $now = desktop_mode_files_now_ms();
796 + $now = openstation_files_now_ms();
833 797 // Snapshot nested folder ids BEFORE we null `trashed_via_folder`
834 798 // on the placements — that column is the only stable link from
835 799 // a child folder's placement back to the parent cascade.
836 800 $nested_ids = $wpdb->get_col(
@@ -877,12 +841,12 @@
877 841 );
878 842 if ( $folder_placement_row ) {
879 843 $origin_parent = (int) $folder_placement_row['parent_id'];
880 844 $alive = $origin_parent > 0
881 - ? desktop_mode_files_get_folder( $origin_parent, true )
845 + ? openstation_files_get_folder( $origin_parent, true )
882 846 : null;
883 847 if ( $origin_parent > 0 && ! $alive ) {
884 - $resolved = desktop_mode_files_resurrect_ancestry( $user_id, $ancestry );
848 + $resolved = openstation_files_resurrect_ancestry( $user_id, $ancestry );
885 849 $wpdb->update(
886 850 $tables['placements'],
887 851 array(
888 852 'parent_id' => $resolved,
@@ -910,9 +874,9 @@
910 874 )
911 875 );
912 876 // Recursively restore nested folders captured in the snapshot.
913 877 foreach ( (array) $nested_ids as $nid ) {
914 - desktop_mode_files_restore_folder( $user_id, (int) $nid );
878 + openstation_files_restore_folder( $user_id, (int) $nid );
915 879 }
916 880
917 881 // Enforce the "tombstones never refer to alive rows" invariant
918 882 // across the restored cohort: the folder itself, every cascade-
@@ -920,9 +884,9 @@
920 884 // folder recursed into above already clears its own. Here we
921 885 // scrub the FOLDER's own tombstones plus those of every cascade-
922 886 // restored placement so a fresh heartbeat tick can't surface
923 887 // them as `removed.*` against the now-alive rows.
924 - desktop_mode_files_clear_tombstones_for( 'folder', $folder_id );
888 + openstation_files_clear_tombstones_for( 'folder', $folder_id );
925 889 $restored_placement_ids = $wpdb->get_col(
926 890 $wpdb->prepare(
927 891 "SELECT id FROM {$tables['placements']}
928 892 WHERE trashed_via_folder IS NULL
@@ -931,18 +895,16 @@
931 895 (string) $folder_id
932 896 )
933 897 );
934 898 foreach ( (array) $restored_placement_ids as $rpid ) {
935 - desktop_mode_files_clear_tombstones_for( 'placement', (int) $rpid );
899 + openstation_files_clear_tombstones_for( 'placement', (int) $rpid );
936 900 }
937 901
938 902 /**
939 - * @since 0.8.0
940 - *
941 903 * @param int $folder_id
942 904 * @param int $user_id
943 905 */
944 - do_action( 'desktop_mode_files_after_restore_folder', $folder_id, $user_id );
906 + do_action( 'openstation_files_after_restore_folder', $folder_id, $user_id );
945 907
946 908 return true;
947 909 }
948 910
@@ -950,19 +912,17 @@
950 912 * Permanently delete a trashed folder and all its trashed-via-
951 913 * cascade child placements. Independent placements that landed in
952 914 * the trash separately stay there.
953 915 *
954 - * @since 0.8.0
955 - *
956 916 * @param int $user_id
957 917 * @param int $folder_id
958 918 * @return true|WP_Error
959 919 */
960 -function desktop_mode_files_purge_folder( $user_id, $folder_id ) {
920 +function openstation_files_purge_folder( $user_id, $folder_id ) {
961 921 global $wpdb;
962 922 $user_id = (int) $user_id;
963 923 $folder_id = (int) $folder_id;
964 - $tables = desktop_mode_files_table_names();
924 + $tables = openstation_files_table_names();
965 925
966 926 $row = $wpdb->get_row(
967 927 $wpdb->prepare(
968 928 "SELECT * FROM {$tables['folders']} WHERE id = %d",
@@ -972,11 +932,11 @@
972 932 );
973 933 if ( ! $row ) {
974 934 return true;
975 935 }
976 - if ( ! desktop_mode_files_user_can_purge_folder( $user_id, $row ) ) {
936 + if ( ! openstation_files_user_can_purge_folder( $user_id, $row ) ) {
977 937 return new WP_Error(
978 - 'desktop_mode_files_forbidden',
938 + 'openstation_files_forbidden',
979 939 __( 'You do not have permission to delete this folder.', 'desktop-mode' ),
980 940 array( 'status' => 403 )
981 941 );
982 942 }
@@ -981,15 +941,13 @@
981 941 );
982 942 }
983 943
984 944 /**
985 - * @since 0.8.0
986 - *
987 945 * @param int $folder_id
988 946 * @param int $user_id
989 947 * @param array $row
990 948 */
991 - do_action( 'desktop_mode_files_before_purge_folder', $folder_id, $user_id, $row );
949 + do_action( 'openstation_files_before_purge_folder', $folder_id, $user_id, $row );
992 950
993 951 // Cascade-revoke every share + per-user decision for the folder
994 952 // BEFORE deleting the folder row. Without this, purge left
995 953 // orphan `folder_shares` + `share_user_decisions` rows pointing
@@ -995,13 +953,18 @@
995 953 // orphan `folder_shares` + `share_user_decisions` rows pointing
996 954 // at a folder id that no longer exists — `compute_visible_folders`
997 955 // would still join them, and the row leak grew with every
998 956 // recycle-bin empty. Mirrors the same cleanup
999 - // `desktop_mode_files_delete_folder_recursive` does for the
957 + // `openstation_files_delete_folder_recursive` does for the
1000 958 // "delete from desktop" path.
959 + // `target_type` scoping is load-bearing: `folder_id` carries a
960 + // STORED-FILE id on `target_type='file'` rows, and the two id
961 + // sequences are independent — without the predicate a folder
962 + // purge wipes an unrelated user's file share that happens to
963 + // collide numerically.
1001 964 $share_ids = (array) $wpdb->get_col(
1002 965 $wpdb->prepare(
1003 - "SELECT id FROM {$tables['shares']} WHERE folder_id = %d",
966 + "SELECT id FROM {$tables['shares']} WHERE target_type = 'folder' AND folder_id = %d",
1004 967 $folder_id
1005 968 )
1006 969 );
1007 970 if ( ! empty( $share_ids ) ) {
@@ -1032,9 +995,9 @@
1032 995 (string) $folder_id
1033 996 )
1034 997 );
1035 998 foreach ( $pointing_ids as $pid ) {
1036 - desktop_mode_files_write_tombstone( 'placement', (int) $pid );
999 + openstation_files_write_tombstone( 'placement', (int) $pid );
1037 1000 }
1038 1001 if ( ! empty( $pointing_ids ) ) {
1039 1002 $placeholders = implode( ',', array_fill( 0, count( $pointing_ids ), '%d' ) );
1040 1003 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
@@ -1045,29 +1008,50 @@
1045 1008 )
1046 1009 );
1047 1010 }
1048 1011
1012 + // Upload placements among the cascade-trashed children carry
1013 + // real bytes — run the stored-files deletion contract for them
1014 + // after the rows go. Direct guarded call (not the public
1015 + // `openstation_file_unplaced` action) so cascade hook semantics
1016 + // for every other type stay unchanged.
1017 + $cascade_upload_rows = (array) $wpdb->get_results(
1018 + $wpdb->prepare(
1019 + "SELECT * FROM {$tables['placements']}
1020 + WHERE trashed_via_folder = %d AND file_type = 'upload'",
1021 + $folder_id
1022 + ),
1023 + ARRAY_A
1024 + );
1049 1025 $wpdb->delete(
1050 1026 $tables['placements'],
1051 1027 array( 'trashed_via_folder' => $folder_id ),
1052 1028 array( '%d' )
1053 1029 );
1030 + if ( function_exists( 'openstation_stored_files_handle_unplaced' ) ) {
1031 + foreach ( $cascade_upload_rows as $upload_row ) {
1032 + openstation_stored_files_handle_unplaced(
1033 + (int) $upload_row['id'],
1034 + openstation_files_normalize_placement_row( $upload_row )
1035 + );
1036 + }
1037 + }
1054 1038 $wpdb->delete( $tables['folders'], array( 'id' => $folder_id ), array( '%d' ) );
1055 1039
1056 1040 /**
1057 - * @since 0.8.0
1058 - *
1059 1041 * @param int $folder_id
1060 1042 * @param int $user_id
1061 1043 */
1062 - do_action( 'desktop_mode_files_after_purge_folder', $folder_id, $user_id );
1044 + do_action( 'openstation_files_after_purge_folder', $folder_id, $user_id );
1063 1045
1064 1046 return true;
1065 1047 }
1066 1048
1067 -/* ================================================================== *
1049 +/*
1050 +================================================================== *
1068 1051 * Recycle-bin list builder.
1069 - * ================================================================== */
1052 + * ==================================================================
1053 + */
1070 1054
1071 1055 /**
1072 1056 * Count of trashed placements + folders surfaced to the recycle bin
1073 1057 * for `$user_id`. Mirrors `_list_trashed_for_recycle_bin`'s "skip
@@ -1072,20 +1056,18 @@
1072 1056 * Count of trashed placements + folders surfaced to the recycle bin
1073 1057 * for `$user_id`. Mirrors `_list_trashed_for_recycle_bin`'s "skip
1074 1058 * cascaded children" rule so the badge matches the visible list.
1075 1059 *
1076 - * @since 0.8.0
1077 - *
1078 1060 * @param int $user_id Owner.
1079 1061 * @return int
1080 1062 */
1081 -function desktop_mode_files_count_trashed_for_recycle_bin( $user_id ) {
1063 +function openstation_files_count_trashed_for_recycle_bin( $user_id ) {
1082 1064 global $wpdb;
1083 1065 $user_id = (int) $user_id;
1084 1066 if ( $user_id <= 0 ) {
1085 1067 return 0;
1086 1068 }
1087 - $tables = desktop_mode_files_table_names();
1069 + $tables = openstation_files_table_names();
1088 1070
1089 1071 $placements = (int) $wpdb->get_var(
1090 1072 $wpdb->prepare(
1091 1073 "SELECT COUNT(*) FROM {$tables['placements']}
@@ -1094,9 +1076,9 @@
1094 1076 AND trashed_via_folder IS NULL",
1095 1077 $user_id
1096 1078 )
1097 1079 );
1098 - $folders = (int) $wpdb->get_var(
1080 + $folders = (int) $wpdb->get_var(
1099 1081 $wpdb->prepare(
1100 1082 "SELECT COUNT(*) FROM {$tables['folders']}
1101 1083 WHERE owner_id = %d AND trashed_at_ms IS NOT NULL",
1102 1084 $user_id
@@ -1109,17 +1091,15 @@
1109 1091 * Return the trashed placements + folders for a user, shaped as
1110 1092 * recycle-bin items. Used by the recycle bin's REST list endpoint
1111 1093 * to merge files-on-the-desktop trash with the WP-core trash.
1112 1094 *
1113 - * @since 0.8.0
1114 - *
1115 1095 * @param int $user_id Owner.
1116 1096 * @return array[] List of recycle-bin item shapes.
1117 1097 */
1118 -function desktop_mode_files_list_trashed_for_recycle_bin( $user_id ) {
1098 +function openstation_files_list_trashed_for_recycle_bin( $user_id ) {
1119 1099 global $wpdb;
1120 1100 $user_id = (int) $user_id;
1121 - $tables = desktop_mode_files_table_names();
1101 + $tables = openstation_files_table_names();
1122 1102 $out = array();
1123 1103
1124 1104 // Trashed placements owned by this user.
1125 1105 $placements = $wpdb->get_results(
@@ -1136,20 +1116,22 @@
1136 1116 // the whole bundle in the recycle bin.
1137 1117 if ( ! empty( $row['trashed_via_folder'] ) ) {
1138 1118 continue;
1139 1119 }
1140 - $file = function_exists( 'desktop_mode_resolve_file' )
1141 - ? desktop_mode_resolve_file( $row['file_type'], $row['file_ref'] )
1120 + $file = function_exists( 'openstation_resolve_file' )
1121 + ? openstation_resolve_file( $row['file_type'], $row['file_ref'] )
1142 1122 : null;
1143 - $title = $file ? (string) $file->title() : (string) $row['file_type'];
1123 + $title = $file
1124 + ? openstation_plain_text_title( $file->title() )
1125 + : (string) $row['file_type'];
1144 1126 $icon = $file ? (string) $file->icon() : 'dashicons-no-alt';
1145 1127 // Two recycle-bin buckets:
1146 - // - `shortcut` → plugin-registered icons (file_type='shortcut')
1147 - // - `placement` → every other placement (post / page /
1148 - // attachment / user / term / comment / …)
1128 + // - `shortcut` → plugin-registered icons (file_type='shortcut')
1129 + // - `placement` → every other placement (post / page /
1130 + // attachment / user / term / comment / …)
1149 1131 // Lets the bin's type-filter tabs split "Shortcuts" from
1150 1132 // "Files" without overloading either label.
1151 - $bucket = ( 'shortcut' === (string) $row['file_type'] )
1133 + $bucket = ( 'shortcut' === (string) $row['file_type'] )
1152 1134 ? 'shortcut'
1153 1135 : 'placement';
1154 1136 $subtitle = ( 'shortcut' === $bucket )
1155 1137 ? __( 'Desktop shortcut', 'desktop-mode' )
@@ -1174,10 +1156,10 @@
1174 1156 'icon' => $icon,
1175 1157 'deleted_at' => gmdate( 'c', (int) round( (int) $row['trashed_at_ms'] / 1000 ) ),
1176 1158 'deleted_by' => '',
1177 1159 'deleted_by_id' => (int) $row['trashed_by'],
1178 - 'can_restore' => desktop_mode_files_user_can_restore_placement( $user_id, $row ),
1179 - 'can_purge' => desktop_mode_files_user_can_purge_placement( $user_id, $row ),
1160 + 'can_restore' => openstation_files_user_can_restore_placement( $user_id, $row ),
1161 + 'can_purge' => openstation_files_user_can_purge_placement( $user_id, $row ),
1180 1162 'edit_link' => '',
1181 1163 );
1182 1164 if ( 'link' === (string) $row['file_type'] ) {
1183 1165 $item['type_label'] = __( 'URL', 'desktop-mode' );
@@ -1202,9 +1184,9 @@
1202 1184 WHERE trashed_via_folder = %d",
1203 1185 (int) $row['id']
1204 1186 )
1205 1187 );
1206 - $out[] = array(
1188 + $out[] = array(
1207 1189 'id' => (int) $row['id'],
1208 1190 'type' => 'folder',
1209 1191 'title' => (string) $row['name'],
1210 1192 'subtitle' => $child_count > 0
@@ -1219,10 +1201,10 @@
1219 1201 'icon' => 'dashicons-portfolio',
1220 1202 'deleted_at' => gmdate( 'c', (int) round( (int) $row['trashed_at_ms'] / 1000 ) ),
1221 1203 'deleted_by' => '',
1222 1204 'deleted_by_id' => (int) $row['trashed_by'],
1223 - 'can_restore' => desktop_mode_files_user_can_restore_folder( $user_id, $row ),
1224 - 'can_purge' => desktop_mode_files_user_can_purge_folder( $user_id, $row ),
1205 + 'can_restore' => openstation_files_user_can_restore_folder( $user_id, $row ),
1206 + 'can_purge' => openstation_files_user_can_purge_folder( $user_id, $row ),
1225 1207 'edit_link' => '',
1226 1208 );
1227 1209 }
1228 1210
@@ -1233,9 +1215,9 @@
1233 1215 if ( $uid <= 0 ) {
1234 1216 continue;
1235 1217 }
1236 1218 if ( ! isset( $user_cache[ $uid ] ) ) {
1237 - $u = get_userdata( $uid );
1219 + $u = get_userdata( $uid );
1238 1220 $user_cache[ $uid ] = $u ? $u->display_name : '';
1239 1221 }
1240 1222 $item['deleted_by'] = $user_cache[ $uid ];
1241 1223 }