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/recycle-bin/store.php +119 -109 0.9.81.1.10 View file →
@@ -1,7 +1,7 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode — Recycle Bin: store.
3 + * OpenStation — Recycle Bin: store.
4 4 *
5 5 * Read/restore/purge primitives that the REST layer wraps. Backed
6 6 * entirely by core post-table state — no custom tables, no options
7 7 * blob. "Trashed" items are exactly the rows with
@@ -6,13 +6,13 @@
6 6 * entirely by core post-table state — no custom tables, no options
7 7 * blob. "Trashed" items are exactly the rows with
8 8 * `post_status = 'trash'` for the post types the bin tracks.
9 9 *
10 - * Every read goes through `desktop_mode_recycle_bin_query_args` so
10 + * Every read goes through `openstation_recycle_bin_query_args` so
11 11 * plugins can scope the bin (e.g. show only the current user's
12 12 * trash, or filter by author/role for compliance use cases).
13 13 *
14 - * @package WPDesktopMode
14 + * @package OpenStation
15 15 */
16 16
17 17 defined( 'ABSPATH' ) || exit;
18 18
@@ -32,9 +32,9 @@
32 32 * @type array $items List of items shaped for the JS layer.
33 33 * @type int $total Total matching rows (across pages).
34 34 * }
35 35 */
36 -function desktop_mode_recycle_bin_get_items( $args = array() ) {
36 +function openstation_recycle_bin_get_items( $args = array() ) {
37 37 $args = wp_parse_args(
38 38 $args,
39 39 array(
40 40 'per_page' => 100,
@@ -56,9 +56,9 @@
56 56
57 57 // Source gates: each `$type` filter narrows down to the
58 58 // owning store. `''` (All) loads every source. The files-on-
59 59 // desktop sources (`shortcut` / `placement` / `folder`) live in
60 - // `desktop_mode_files_list_trashed_for_recycle_bin` — never run
60 + // `openstation_files_list_trashed_for_recycle_bin` — never run
61 61 // the WP-core post / comment queries when one of those is the
62 62 // active filter, otherwise trashed posts leak into the
63 63 // "Shortcuts" / "Folders" tabs.
64 64 $files_types = array( 'desktop', 'placement', 'shortcut', 'folder' );
@@ -65,12 +65,12 @@
65 65 $is_files_filter = in_array( $type, $files_types, true );
66 66 $wants_post_types = '' === $type
67 67 || ( 'comment' !== $type && ! $is_files_filter );
68 68 $wants_comments = ( '' === $type || 'comment' === $type )
69 - && desktop_mode_recycle_bin_comments_enabled();
69 + && openstation_recycle_bin_comments_enabled();
70 70
71 71 if ( $wants_post_types ) {
72 - $post_types = desktop_mode_recycle_bin_capture_post_types();
72 + $post_types = openstation_recycle_bin_capture_post_types();
73 73 if ( '' !== $type && in_array( $type, $post_types, true ) ) {
74 74 $post_types = array( $type );
75 75 }
76 76
@@ -90,16 +90,16 @@
90 90 *
91 91 * @param array $query_args Args passed to WP_Query.
92 92 * @param array $args Caller-provided args.
93 93 */
94 - $query_args = apply_filters( 'desktop_mode_recycle_bin_query_args', $query_args, $args );
94 + $query_args = apply_filters( 'openstation_recycle_bin_query_args', $query_args, $args );
95 95
96 96 $query = new WP_Query( $query_args );
97 97 foreach ( $query->posts as $post ) {
98 - if ( ! desktop_mode_recycle_bin_user_can_view( $post ) ) {
98 + if ( ! openstation_recycle_bin_user_can_view( $post ) ) {
99 99 continue;
100 100 }
101 - $items_posts[] = desktop_mode_recycle_bin_shape_item( $post );
101 + $items_posts[] = openstation_recycle_bin_shape_item( $post );
102 102 }
103 103 }
104 104
105 105 if ( $wants_comments ) {
@@ -115,15 +115,15 @@
115 115
116 116 /**
117 117 * Filter the `WP_Comment_Query` args used to populate the
118 118 * recycle bin's comments. Mirror of
119 - * `desktop_mode_recycle_bin_query_args` for comments.
119 + * `openstation_recycle_bin_query_args` for comments.
120 120 *
121 121 * @param array $comment_args Args passed to `get_comments()`.
122 122 * @param array $args Caller-provided args.
123 123 */
124 124 $comment_args = apply_filters(
125 - 'desktop_mode_recycle_bin_comment_query_args',
125 + 'openstation_recycle_bin_comment_query_args',
126 126 $comment_args,
127 127 $args
128 128 );
129 129
@@ -129,12 +129,12 @@
129 129
130 130 $comments = get_comments( $comment_args );
131 131 if ( is_array( $comments ) ) {
132 132 foreach ( $comments as $comment ) {
133 - if ( ! desktop_mode_recycle_bin_user_can_view_comment( $comment ) ) {
133 + if ( ! openstation_recycle_bin_user_can_view_comment( $comment ) ) {
134 134 continue;
135 135 }
136 - $items_comments[] = desktop_mode_recycle_bin_shape_comment_item( $comment );
136 + $items_comments[] = openstation_recycle_bin_shape_comment_item( $comment );
137 137 }
138 138 }
139 139 }
140 140
@@ -141,9 +141,9 @@
141 141 // Files-on-the-Desktop trash — soft-trashed placements
142 142 // (shortcuts) and folders. Returned in the same item shape so
143 143 // the JS layer treats them uniformly. The `placement` and
144 144 // `folder` types route to the desktop-files trash module on
145 - // restore / purge (see `desktop_mode_recycle_bin_handle_files_*`).
145 + // restore / purge (see `openstation_recycle_bin_handle_files_*`).
146 146 $items_files = array();
147 147 // Map UI filter → set of `type` values to keep from the
148 148 // files-on-desktop helper. The "Shortcuts" segment in the bin
149 149 // UI now covers both registered icons (`shortcut`) AND user
@@ -167,11 +167,11 @@
167 167 break;
168 168 }
169 169 if (
170 170 ! empty( $wanted_files_types )
171 - && function_exists( 'desktop_mode_files_list_trashed_for_recycle_bin' )
171 + && function_exists( 'openstation_files_list_trashed_for_recycle_bin' )
172 172 ) {
173 - $file_items = desktop_mode_files_list_trashed_for_recycle_bin(
173 + $file_items = openstation_files_list_trashed_for_recycle_bin(
174 174 get_current_user_id()
175 175 );
176 176 foreach ( (array) $file_items as $item ) {
177 177 if ( ! in_array( (string) $item['type'], $wanted_files_types, true ) ) {
@@ -186,11 +186,14 @@
186 186 // Sort the merged list chronologically by deleted_at desc. The
187 187 // shape always carries a sortable string in `deleted_at`, so a
188 188 // straight string compare is enough (`Y-m-d H:i:s` is sortable
189 189 // lexicographically).
190 - usort( $items, static function ( $a, $b ) {
191 - return strcmp( (string) $b['deleted_at'], (string) $a['deleted_at'] );
192 - } );
190 + usort(
191 + $items,
192 + static function ( $a, $b ) {
193 + return strcmp( (string) $b['deleted_at'], (string) $a['deleted_at'] );
194 + }
195 + );
193 196
194 197 // `total` reports the GLOBAL trash count (every type, every
195 198 // row, ignoring the current filter / search). The dock-tile
196 199 // + desktop-icon badge consume this directly — `setRecycleBinBadge`
@@ -196,9 +199,9 @@
196 199 // + desktop-icon badge consume this directly — `setRecycleBinBadge`
197 200 // only cares about "how many things are sitting in the bin
198 201 // right now". A future paginated UI that needs a filtered
199 202 // count can compute it from `count( $items )` itself.
200 - $total = desktop_mode_recycle_bin_count();
203 + $total = openstation_recycle_bin_count();
201 204
202 205 $offset = max( 0, ( max( 1, (int) $args['page'] ) - 1 ) * $per_page );
203 206 $sliced = array_slice( $items, $offset, $per_page );
204 207
@@ -208,9 +211,9 @@
208 211 * @param array $items Shaped list (id, title, type, deleted_at, …).
209 212 * @param array|null $query Underlying post query, or null for the
210 213 * merged post+comment shape.
211 214 */
212 - $sliced = apply_filters( 'desktop_mode_recycle_bin_items', $sliced, null );
215 + $sliced = apply_filters( 'openstation_recycle_bin_items', $sliced, null );
213 216
214 217 return array(
215 218 'items' => $sliced,
216 219 'total' => $total,
@@ -220,9 +223,9 @@
220 223 /**
221 224 * Total number of items in the recycle bin, summed across every
222 225 * tracked source (post types + comments).
223 226 *
224 - * Cheaper than `desktop_mode_recycle_bin_get_items()` because it never
227 + * Cheaper than `openstation_recycle_bin_get_items()` because it never
225 228 * loads the row data — just the COUNT(*) under the hood. Used by
226 229 * the badge on the dock tile + desktop icon, and by the REST
227 230 * `/count` endpoint subscribers refresh on broadcasts.
228 231 *
@@ -233,10 +236,10 @@
233 236 * the global trash total to low-capability users.
234 237 *
235 238 * @return int
236 239 */
237 -function desktop_mode_recycle_bin_count() {
238 - $post_types = desktop_mode_recycle_bin_capture_post_types();
240 +function openstation_recycle_bin_count() {
241 + $post_types = openstation_recycle_bin_capture_post_types();
239 242
240 243 // Bucket the tracked types by what the current user may edit:
241 244 // full count when they hold the type's `edit_others_posts`,
242 245 // author-scoped count when they only hold `edit_posts`, nothing
@@ -287,9 +290,9 @@
287 290 $post_count += (int) $own_query->found_posts;
288 291 }
289 292
290 293 $comment_count = 0;
291 - if ( desktop_mode_recycle_bin_comments_enabled() ) {
294 + if ( openstation_recycle_bin_comments_enabled() ) {
292 295 $comment_count = (int) get_comments(
293 296 array(
294 297 'status' => 'trash',
295 298 'count' => true,
@@ -297,10 +300,10 @@
297 300 );
298 301 }
299 302
300 303 $files_count = 0;
301 - if ( function_exists( 'desktop_mode_files_count_trashed_for_recycle_bin' ) ) {
302 - $files_count = (int) desktop_mode_files_count_trashed_for_recycle_bin( get_current_user_id() );
304 + if ( function_exists( 'openstation_files_count_trashed_for_recycle_bin' ) ) {
305 + $files_count = (int) openstation_files_count_trashed_for_recycle_bin( get_current_user_id() );
303 306 }
304 307
305 308 $total = $post_count + $comment_count + $files_count;
306 309
@@ -312,9 +315,9 @@
312 315 * to what the current user can edit.
313 316 * @param int $comment_count Items in trash from the comment query.
314 317 * @param int $files_count Items in trash from the desktop-files trash.
315 318 */
316 - return (int) apply_filters( 'desktop_mode_recycle_bin_count', $total, $post_count, $comment_count, $files_count );
319 + return (int) apply_filters( 'openstation_recycle_bin_count', $total, $post_count, $comment_count, $files_count );
317 320 }
318 321
319 322 /**
320 323 * Whether comments are part of the bin. Filterable so installs
@@ -322,9 +325,9 @@
322 325 * setups) can hide the segment without touching the JS.
323 326 *
324 327 * @return bool
325 328 */
326 -function desktop_mode_recycle_bin_comments_enabled() {
329 +function openstation_recycle_bin_comments_enabled() {
327 330 $on = current_user_can( 'moderate_comments' );
328 331
329 332 /**
330 333 * Filter whether the recycle bin tracks comments.
@@ -330,9 +333,9 @@
330 333 * Filter whether the recycle bin tracks comments.
331 334 *
332 335 * @param bool $on Default: current user has `moderate_comments`.
333 336 */
334 - return (bool) apply_filters( 'desktop_mode_recycle_bin_comments_enabled', $on );
337 + return (bool) apply_filters( 'openstation_recycle_bin_comments_enabled', $on );
335 338 }
336 339
337 340 /**
338 341 * Whether the current user can see a given trashed item.
@@ -343,9 +346,9 @@
343 346 *
344 347 * @param WP_Post $post Trashed post.
345 348 * @return bool
346 349 */
347 -function desktop_mode_recycle_bin_user_can_view( $post ) {
350 +function openstation_recycle_bin_user_can_view( $post ) {
348 351 $can = current_user_can( 'edit_post', $post->ID );
349 352
350 353 /**
351 354 * Filter whether the current user can see a given trashed item.
@@ -352,9 +355,9 @@
352 355 *
353 356 * @param bool $can Default: edit_post capability check.
354 357 * @param WP_Post $post Trashed post.
355 358 */
356 - return (bool) apply_filters( 'desktop_mode_recycle_bin_user_can_view', $can, $post );
359 + return (bool) apply_filters( 'openstation_recycle_bin_user_can_view', $can, $post );
357 360 }
358 361
359 362 /**
360 363 * Whether the current user can restore a given trashed item.
@@ -361,9 +364,9 @@
361 364 *
362 365 * @param WP_Post $post Trashed post.
363 366 * @return bool
364 367 */
365 -function desktop_mode_recycle_bin_user_can_restore( $post ) {
368 +function openstation_recycle_bin_user_can_restore( $post ) {
366 369 $can = current_user_can( 'delete_post', $post->ID );
367 370
368 371 /**
369 372 * Filter whether the current user can restore a given trashed item.
@@ -371,9 +374,9 @@
371 374 * @param bool $can Default: delete_post capability check (the same
372 375 * gate WP itself uses for trash/untrash).
373 376 * @param WP_Post $post Trashed post.
374 377 */
375 - return (bool) apply_filters( 'desktop_mode_recycle_bin_user_can_restore', $can, $post );
378 + return (bool) apply_filters( 'openstation_recycle_bin_user_can_restore', $can, $post );
376 379 }
377 380
378 381 /**
379 382 * Whether the current user can permanently delete a trashed item.
@@ -380,9 +383,9 @@
380 383 *
381 384 * @param WP_Post $post Trashed post.
382 385 * @return bool
383 386 */
384 -function desktop_mode_recycle_bin_user_can_purge( $post ) {
387 +function openstation_recycle_bin_user_can_purge( $post ) {
385 388 $can = current_user_can( 'delete_post', $post->ID );
386 389
387 390 /**
388 391 * Filter whether the current user can permanently delete a trashed item.
@@ -389,9 +392,9 @@
389 392 *
390 393 * @param bool $can Default: delete_post capability check.
391 394 * @param WP_Post $post Trashed post.
392 395 */
393 - return (bool) apply_filters( 'desktop_mode_recycle_bin_user_can_purge', $can, $post );
396 + return (bool) apply_filters( 'openstation_recycle_bin_user_can_purge', $can, $post );
394 397 }
395 398
396 399 /**
397 400 * Capability gates for trashed comments. Mirror of the post gates,
@@ -399,9 +402,9 @@
399 402 *
400 403 * @param WP_Comment $comment Trashed comment.
401 404 * @return bool
402 405 */
403 -function desktop_mode_recycle_bin_user_can_view_comment( $comment ) {
406 +function openstation_recycle_bin_user_can_view_comment( $comment ) {
404 407 $can = current_user_can( 'edit_comment', $comment->comment_ID );
405 408
406 409 /**
407 410 * @param bool $can Default: edit_comment capability check.
@@ -406,9 +409,9 @@
406 409 /**
407 410 * @param bool $can Default: edit_comment capability check.
408 411 * @param WP_Comment $comment Trashed comment.
409 412 */
410 - return (bool) apply_filters( 'desktop_mode_recycle_bin_user_can_view_comment', $can, $comment );
413 + return (bool) apply_filters( 'openstation_recycle_bin_user_can_view_comment', $can, $comment );
411 414 }
412 415
413 416 /**
414 417 * @param WP_Comment $comment Trashed comment.
@@ -413,9 +416,9 @@
413 416 /**
414 417 * @param WP_Comment $comment Trashed comment.
415 418 * @return bool
416 419 */
417 -function desktop_mode_recycle_bin_user_can_restore_comment( $comment ) {
420 +function openstation_recycle_bin_user_can_restore_comment( $comment ) {
418 421 $can = current_user_can( 'edit_comment', $comment->comment_ID );
419 422
420 423 /**
421 424 * @param bool $can Default: edit_comment capability check.
@@ -420,9 +423,9 @@
420 423 /**
421 424 * @param bool $can Default: edit_comment capability check.
422 425 * @param WP_Comment $comment Trashed comment.
423 426 */
424 - return (bool) apply_filters( 'desktop_mode_recycle_bin_user_can_restore_comment', $can, $comment );
427 + return (bool) apply_filters( 'openstation_recycle_bin_user_can_restore_comment', $can, $comment );
425 428 }
426 429
427 430 /**
428 431 * @param WP_Comment $comment Trashed comment.
@@ -427,9 +430,9 @@
427 430 /**
428 431 * @param WP_Comment $comment Trashed comment.
429 432 * @return bool
430 433 */
431 -function desktop_mode_recycle_bin_user_can_purge_comment( $comment ) {
434 +function openstation_recycle_bin_user_can_purge_comment( $comment ) {
432 435 $can = current_user_can( 'edit_comment', $comment->comment_ID );
433 436
434 437 /**
435 438 * @param bool $can Default: edit_comment capability check.
@@ -434,9 +437,9 @@
434 437 /**
435 438 * @param bool $can Default: edit_comment capability check.
436 439 * @param WP_Comment $comment Trashed comment.
437 440 */
438 - return (bool) apply_filters( 'desktop_mode_recycle_bin_user_can_purge_comment', $can, $comment );
441 + return (bool) apply_filters( 'openstation_recycle_bin_user_can_purge_comment', $can, $comment );
439 442 }
440 443
441 444 /**
442 445 * Shape a `WP_Comment` into the JSON the JS table consumes.
@@ -448,9 +451,9 @@
448 451 *
449 452 * @param WP_Comment $comment Trashed comment.
450 453 * @return array
451 454 */
452 -function desktop_mode_recycle_bin_shape_comment_item( $comment ) {
455 +function openstation_recycle_bin_shape_comment_item( $comment ) {
453 456 $user_id = (int) get_comment_meta( $comment->comment_ID, '_desktop_mode_trash_user_id', true );
454 457 $deleted_at = (string) get_comment_meta( $comment->comment_ID, '_desktop_mode_trash_time_gmt', true );
455 458
456 459 if ( '' === $deleted_at ) {
@@ -457,9 +460,9 @@
457 460 $deleted_at = (string) $comment->comment_date_gmt;
458 461 }
459 462
460 463 $parent = $comment->comment_post_ID ? get_post( (int) $comment->comment_post_ID ) : null;
461 - $parent_text = $parent ? desktop_mode_recycle_bin_plain_text( get_the_title( $parent ) ) : '';
464 + $parent_text = $parent ? openstation_recycle_bin_plain_text( get_the_title( $parent ) ) : '';
462 465 $author = $comment->comment_author
463 466 ? (string) $comment->comment_author
464 467 : __( 'Anonymous', 'desktop-mode' );
465 468
@@ -471,9 +474,9 @@
471 474 $parent_text
472 475 )
473 476 : $author;
474 477
475 - $subtitle = wp_trim_words( desktop_mode_recycle_bin_plain_text( (string) $comment->comment_content ), 18, '…' );
478 + $subtitle = wp_trim_words( openstation_recycle_bin_plain_text( (string) $comment->comment_content ), 18, '…' );
476 479
477 480 $user = $user_id ? get_userdata( $user_id ) : false;
478 481 $user_name = $user ? $user->display_name : '';
479 482
@@ -488,10 +491,10 @@
488 491 'icon' => 'dashicons-admin-comments',
489 492 'deleted_at' => $deleted_at,
490 493 'deleted_by' => $user_name,
491 494 'deleted_by_id' => $user_id,
492 - 'can_restore' => desktop_mode_recycle_bin_user_can_restore_comment( $comment ),
493 - 'can_purge' => desktop_mode_recycle_bin_user_can_purge_comment( $comment ),
495 + 'can_restore' => openstation_recycle_bin_user_can_restore_comment( $comment ),
496 + 'can_purge' => openstation_recycle_bin_user_can_purge_comment( $comment ),
494 497 'edit_link' => (string) get_edit_comment_link( $comment->comment_ID ),
495 498 );
496 499
497 500 /**
@@ -499,9 +502,9 @@
499 502 *
500 503 * @param array $item Item shape.
501 504 * @param WP_Comment $comment Source comment.
502 505 */
503 - return (array) apply_filters( 'desktop_mode_recycle_bin_comment_item', $item, $comment );
506 + return (array) apply_filters( 'openstation_recycle_bin_comment_item', $item, $comment );
504 507 }
505 508
506 509 /**
507 510 * Collapse a title/subtitle to plain text for the wire.
@@ -515,9 +518,9 @@
515 518 *
516 519 * @param string $text Raw filtered text.
517 520 * @return string
518 521 */
519 -function desktop_mode_recycle_bin_plain_text( $text ) {
522 +function openstation_recycle_bin_plain_text( $text ) {
520 523 return html_entity_decode(
521 524 wp_strip_all_tags( (string) $text ),
522 525 ENT_QUOTES,
523 526 get_bloginfo( 'charset' )
@@ -529,9 +532,9 @@
529 532 *
530 533 * @param WP_Post $post Trashed post.
531 534 * @return array
532 535 */
533 -function desktop_mode_recycle_bin_shape_item( $post ) {
536 +function openstation_recycle_bin_shape_item( $post ) {
534 537 $user_id = (int) get_post_meta( $post->ID, '_desktop_mode_trash_user_id', true );
535 538 $deleted_at = (string) get_post_meta( $post->ID, '_desktop_mode_trash_time_gmt', true );
536 539
537 540 // Fall back to post_modified_gmt — set when wp_trash_post runs and
@@ -540,9 +543,9 @@
540 543 $deleted_at = (string) $post->post_modified_gmt;
541 544 }
542 545
543 546 $type = (string) $post->post_type;
544 - $title = desktop_mode_recycle_bin_plain_text( (string) get_the_title( $post ) );
547 + $title = openstation_recycle_bin_plain_text( (string) get_the_title( $post ) );
545 548 $mime = (string) $post->post_mime_type;
546 549 $preview = '';
547 550 $icon = '';
548 551 $subtitle = '';
@@ -554,16 +557,17 @@
554 557 $thumb = wp_get_attachment_image_src( $post->ID, array( 64, 64 ), true );
555 558 if ( is_array( $thumb ) ) {
556 559 $preview = (string) $thumb[0];
557 560 }
558 - $icon = desktop_mode_recycle_bin_icon_for_mime( $mime );
561 + $icon = openstation_recycle_bin_icon_for_mime( $mime );
559 562 $subtitle = $mime;
560 563 } elseif ( 'post' === $type ) {
561 564 $icon = 'dashicons-admin-post';
562 - $subtitle = wp_trim_words( desktop_mode_recycle_bin_plain_text( (string) $post->post_excerpt ?: (string) $post->post_content ), 18, '…' );
565 + $excerpt = (string) $post->post_excerpt;
566 + $subtitle = wp_trim_words( openstation_recycle_bin_plain_text( $excerpt ? $excerpt : (string) $post->post_content ), 18, '…' );
563 567 } elseif ( 'page' === $type ) {
564 568 $icon = 'dashicons-admin-page';
565 - $subtitle = wp_trim_words( desktop_mode_recycle_bin_plain_text( (string) $post->post_content ), 18, '…' );
569 + $subtitle = wp_trim_words( openstation_recycle_bin_plain_text( (string) $post->post_content ), 18, '…' );
566 570 } else {
567 571 // Custom post types: reuse the type's own menu Dashicon when it
568 572 // registered one, so a trashed product row reads as a product
569 573 // instead of a generic file. Content excerpt as the subtitle,
@@ -576,9 +580,10 @@
576 580 && str_starts_with( $post_type_obj->menu_icon, 'dashicons-' )
577 581 ) {
578 582 $icon = $post_type_obj->menu_icon;
579 583 }
580 - $subtitle = wp_trim_words( desktop_mode_recycle_bin_plain_text( (string) $post->post_excerpt ?: (string) $post->post_content ), 18, '…' );
584 + $excerpt = (string) $post->post_excerpt;
585 + $subtitle = wp_trim_words( openstation_recycle_bin_plain_text( $excerpt ? $excerpt : (string) $post->post_content ), 18, '…' );
581 586 }
582 587
583 588 $user = $user_id ? get_userdata( $user_id ) : false;
584 589 $user_name = $user ? $user->display_name : '';
@@ -610,10 +615,10 @@
610 615 'icon' => $icon,
611 616 'deleted_at' => $deleted_at,
612 617 'deleted_by' => $user_name,
613 618 'deleted_by_id' => $user_id,
614 - 'can_restore' => desktop_mode_recycle_bin_user_can_restore( $post ),
615 - 'can_purge' => desktop_mode_recycle_bin_user_can_purge( $post ),
619 + 'can_restore' => openstation_recycle_bin_user_can_restore( $post ),
620 + 'can_purge' => openstation_recycle_bin_user_can_purge( $post ),
616 621 'edit_link' => (string) get_edit_post_link( $post->ID, 'raw' ),
617 622 );
618 623
619 624 /**
@@ -625,9 +630,9 @@
625 630 *
626 631 * @param array $item Item shape.
627 632 * @param WP_Post $post Source post.
628 633 */
629 - return (array) apply_filters( 'desktop_mode_recycle_bin_item', $item, $post );
634 + return (array) apply_filters( 'openstation_recycle_bin_item', $item, $post );
630 635 }
631 636
632 637 /**
633 638 * Map a mime type to a Dashicon for the type cell.
@@ -634,9 +639,9 @@
634 639 *
635 640 * @param string $mime Mime type.
636 641 * @return string Dashicon class.
637 642 */
638 -function desktop_mode_recycle_bin_icon_for_mime( $mime ) {
643 +function openstation_recycle_bin_icon_for_mime( $mime ) {
639 644 if ( '' === $mime ) {
640 645 return 'dashicons-media-default';
641 646 }
642 647 if ( str_starts_with( $mime, 'image/' ) ) {
@@ -683,29 +688,29 @@
683 688 * @param int $id Post id (or comment id when `$type === 'comment'`).
684 689 * @param string $type Entity type — '', 'post', 'page', 'attachment', or 'comment'.
685 690 * @return true|WP_Error
686 691 */
687 -function desktop_mode_recycle_bin_restore( $id, $type = '' ) {
692 +function openstation_recycle_bin_restore( $id, $type = '' ) {
688 693 $id = (int) $id;
689 694 if ( 'comment' === $type ) {
690 - return desktop_mode_recycle_bin_restore_comment( $id );
695 + return openstation_recycle_bin_restore_comment( $id );
691 696 }
692 - if ( ( 'placement' === $type || 'shortcut' === $type ) && function_exists( 'desktop_mode_files_restore_placement' ) ) {
693 - return desktop_mode_files_restore_placement( get_current_user_id(), $id );
697 + if ( ( 'placement' === $type || 'shortcut' === $type ) && function_exists( 'openstation_files_restore_placement' ) ) {
698 + return openstation_files_restore_placement( get_current_user_id(), $id );
694 699 }
695 - if ( 'folder' === $type && function_exists( 'desktop_mode_files_restore_folder' ) ) {
696 - return desktop_mode_files_restore_folder( get_current_user_id(), $id );
700 + if ( 'folder' === $type && function_exists( 'openstation_files_restore_folder' ) ) {
701 + return openstation_files_restore_folder( get_current_user_id(), $id );
697 702 }
698 703
699 704 $post = get_post( $id );
700 705 if ( ! $post ) {
701 - return new WP_Error( 'desktop_mode_recycle_bin_not_found', __( 'Item not found.', 'desktop-mode' ), array( 'status' => 404 ) );
706 + return new WP_Error( 'openstation_recycle_bin_not_found', __( 'Item not found.', 'desktop-mode' ), array( 'status' => 404 ) );
702 707 }
703 708 if ( 'trash' !== $post->post_status ) {
704 - return new WP_Error( 'desktop_mode_recycle_bin_not_trashed', __( 'Item is not in the trash.', 'desktop-mode' ), array( 'status' => 409 ) );
709 + return new WP_Error( 'openstation_recycle_bin_not_trashed', __( 'Item is not in the trash.', 'desktop-mode' ), array( 'status' => 409 ) );
705 710 }
706 - if ( ! desktop_mode_recycle_bin_user_can_restore( $post ) ) {
707 - return new WP_Error( 'desktop_mode_recycle_bin_forbidden', __( 'You are not allowed to restore this item.', 'desktop-mode' ), array( 'status' => 403 ) );
711 + if ( ! openstation_recycle_bin_user_can_restore( $post ) ) {
712 + return new WP_Error( 'openstation_recycle_bin_forbidden', __( 'You are not allowed to restore this item.', 'desktop-mode' ), array( 'status' => 403 ) );
708 713 }
709 714
710 715 /**
711 716 * Fires before a recycle-bin item is restored.
@@ -712,13 +717,13 @@
712 717 *
713 718 * @param int $id Post id about to be restored.
714 719 * @param WP_Post $post Trashed post object.
715 720 */
716 - do_action( 'desktop_mode_recycle_bin_before_restore', $id, $post );
721 + do_action( 'openstation_recycle_bin_before_restore', $id, $post );
717 722
718 723 $ok = wp_untrash_post( $id );
719 724 if ( ! $ok ) {
720 - return new WP_Error( 'desktop_mode_recycle_bin_restore_failed', __( 'Failed to restore item.', 'desktop-mode' ), array( 'status' => 500 ) );
725 + return new WP_Error( 'openstation_recycle_bin_restore_failed', __( 'Failed to restore item.', 'desktop-mode' ), array( 'status' => 500 ) );
721 726 }
722 727
723 728 delete_post_meta( $id, '_desktop_mode_trash_user_id' );
724 729 delete_post_meta( $id, '_desktop_mode_trash_time_gmt' );
@@ -727,9 +732,9 @@
727 732 * Fires after a recycle-bin item is restored.
728 733 *
729 734 * @param int $id Post id that was restored.
730 735 */
731 - do_action( 'desktop_mode_recycle_bin_after_restore', $id );
736 + do_action( 'openstation_recycle_bin_after_restore', $id );
732 737
733 738 return true;
734 739 }
735 740
@@ -738,20 +743,20 @@
738 743 *
739 744 * @param int $comment_id Comment id.
740 745 * @return true|WP_Error
741 746 */
742 -function desktop_mode_recycle_bin_restore_comment( $comment_id ) {
747 +function openstation_recycle_bin_restore_comment( $comment_id ) {
743 748 $comment_id = (int) $comment_id;
744 749 $comment = get_comment( $comment_id );
745 750
746 751 if ( ! $comment ) {
747 - return new WP_Error( 'desktop_mode_recycle_bin_not_found', __( 'Comment not found.', 'desktop-mode' ), array( 'status' => 404 ) );
752 + return new WP_Error( 'openstation_recycle_bin_not_found', __( 'Comment not found.', 'desktop-mode' ), array( 'status' => 404 ) );
748 753 }
749 754 if ( 'trash' !== $comment->comment_approved ) {
750 - return new WP_Error( 'desktop_mode_recycle_bin_not_trashed', __( 'Comment is not in the trash.', 'desktop-mode' ), array( 'status' => 409 ) );
755 + return new WP_Error( 'openstation_recycle_bin_not_trashed', __( 'Comment is not in the trash.', 'desktop-mode' ), array( 'status' => 409 ) );
751 756 }
752 - if ( ! desktop_mode_recycle_bin_user_can_restore_comment( $comment ) ) {
753 - return new WP_Error( 'desktop_mode_recycle_bin_forbidden', __( 'You are not allowed to restore this comment.', 'desktop-mode' ), array( 'status' => 403 ) );
757 + if ( ! openstation_recycle_bin_user_can_restore_comment( $comment ) ) {
758 + return new WP_Error( 'openstation_recycle_bin_forbidden', __( 'You are not allowed to restore this comment.', 'desktop-mode' ), array( 'status' => 403 ) );
754 759 }
755 760
756 761 /**
757 762 * Fires before a comment is restored from the recycle bin.
@@ -758,13 +763,13 @@
758 763 *
759 764 * @param int $comment_id Comment id.
760 765 * @param WP_Comment $comment Trashed comment.
761 766 */
762 - do_action( 'desktop_mode_recycle_bin_before_restore_comment', $comment_id, $comment );
767 + do_action( 'openstation_recycle_bin_before_restore_comment', $comment_id, $comment );
763 768
764 769 $ok = wp_untrash_comment( $comment_id );
765 770 if ( ! $ok ) {
766 - return new WP_Error( 'desktop_mode_recycle_bin_restore_failed', __( 'Failed to restore comment.', 'desktop-mode' ), array( 'status' => 500 ) );
771 + return new WP_Error( 'openstation_recycle_bin_restore_failed', __( 'Failed to restore comment.', 'desktop-mode' ), array( 'status' => 500 ) );
767 772 }
768 773
769 774 delete_comment_meta( $comment_id, '_desktop_mode_trash_user_id' );
770 775 delete_comment_meta( $comment_id, '_desktop_mode_trash_time_gmt' );
@@ -773,9 +778,9 @@
773 778 * Fires after a comment is restored from the recycle bin.
774 779 *
775 780 * @param int $comment_id Comment id.
776 781 */
777 - do_action( 'desktop_mode_recycle_bin_after_restore_comment', $comment_id );
782 + do_action( 'openstation_recycle_bin_after_restore_comment', $comment_id );
778 783
779 784 return true;
780 785 }
781 786
@@ -785,29 +790,29 @@
785 790 * @param int $id Post id (or comment id when `$type === 'comment'`).
786 791 * @param string $type Entity type — '', 'post', 'page', 'attachment', or 'comment'.
787 792 * @return true|WP_Error
788 793 */
789 -function desktop_mode_recycle_bin_purge( $id, $type = '' ) {
794 +function openstation_recycle_bin_purge( $id, $type = '' ) {
790 795 $id = (int) $id;
791 796 if ( 'comment' === $type ) {
792 - return desktop_mode_recycle_bin_purge_comment( $id );
797 + return openstation_recycle_bin_purge_comment( $id );
793 798 }
794 - if ( ( 'placement' === $type || 'shortcut' === $type ) && function_exists( 'desktop_mode_files_purge_placement' ) ) {
795 - return desktop_mode_files_purge_placement( get_current_user_id(), $id );
799 + if ( ( 'placement' === $type || 'shortcut' === $type ) && function_exists( 'openstation_files_purge_placement' ) ) {
800 + return openstation_files_purge_placement( get_current_user_id(), $id );
796 801 }
797 - if ( 'folder' === $type && function_exists( 'desktop_mode_files_purge_folder' ) ) {
798 - return desktop_mode_files_purge_folder( get_current_user_id(), $id );
802 + if ( 'folder' === $type && function_exists( 'openstation_files_purge_folder' ) ) {
803 + return openstation_files_purge_folder( get_current_user_id(), $id );
799 804 }
800 805
801 806 $post = get_post( $id );
802 807 if ( ! $post ) {
803 - return new WP_Error( 'desktop_mode_recycle_bin_not_found', __( 'Item not found.', 'desktop-mode' ), array( 'status' => 404 ) );
808 + return new WP_Error( 'openstation_recycle_bin_not_found', __( 'Item not found.', 'desktop-mode' ), array( 'status' => 404 ) );
804 809 }
805 810 if ( 'trash' !== $post->post_status ) {
806 - return new WP_Error( 'desktop_mode_recycle_bin_not_trashed', __( 'Item is not in the trash.', 'desktop-mode' ), array( 'status' => 409 ) );
811 + return new WP_Error( 'openstation_recycle_bin_not_trashed', __( 'Item is not in the trash.', 'desktop-mode' ), array( 'status' => 409 ) );
807 812 }
808 - if ( ! desktop_mode_recycle_bin_user_can_purge( $post ) ) {
809 - return new WP_Error( 'desktop_mode_recycle_bin_forbidden', __( 'You are not allowed to permanently delete this item.', 'desktop-mode' ), array( 'status' => 403 ) );
813 + if ( ! openstation_recycle_bin_user_can_purge( $post ) ) {
814 + return new WP_Error( 'openstation_recycle_bin_forbidden', __( 'You are not allowed to permanently delete this item.', 'desktop-mode' ), array( 'status' => 403 ) );
810 815 }
811 816
812 817 /**
813 818 * Fires before a recycle-bin item is permanently deleted.
@@ -814,9 +819,9 @@
814 819 *
815 820 * @param int $id Post id about to be deleted.
816 821 * @param WP_Post $post Trashed post object.
817 822 */
818 - do_action( 'desktop_mode_recycle_bin_before_purge', $id, $post );
823 + do_action( 'openstation_recycle_bin_before_purge', $id, $post );
819 824
820 825 if ( 'attachment' === $post->post_type ) {
821 826 // Force-delete (`true`) removes the attachment and its file
822 827 // permanently. (The item is already trashed, so even with
@@ -827,9 +832,9 @@
827 832 $result = wp_delete_post( $id, true );
828 833 }
829 834
830 835 if ( ! $result ) {
831 - return new WP_Error( 'desktop_mode_recycle_bin_purge_failed', __( 'Failed to permanently delete item.', 'desktop-mode' ), array( 'status' => 500 ) );
836 + return new WP_Error( 'openstation_recycle_bin_purge_failed', __( 'Failed to permanently delete item.', 'desktop-mode' ), array( 'status' => 500 ) );
832 837 }
833 838
834 839 /**
835 840 * Fires after a recycle-bin item is permanently deleted.
@@ -836,9 +841,9 @@
836 841 *
837 842 * @param int $id Post id that was purged.
838 843 * @param string $type Post type of the purged item.
839 844 */
840 - do_action( 'desktop_mode_recycle_bin_after_purge', $id, $post->post_type );
845 + do_action( 'openstation_recycle_bin_after_purge', $id, $post->post_type );
841 846
842 847 return true;
843 848 }
844 849
@@ -847,20 +852,20 @@
847 852 *
848 853 * @param int $comment_id Comment id.
849 854 * @return true|WP_Error
850 855 */
851 -function desktop_mode_recycle_bin_purge_comment( $comment_id ) {
856 +function openstation_recycle_bin_purge_comment( $comment_id ) {
852 857 $comment_id = (int) $comment_id;
853 858 $comment = get_comment( $comment_id );
854 859
855 860 if ( ! $comment ) {
856 - return new WP_Error( 'desktop_mode_recycle_bin_not_found', __( 'Comment not found.', 'desktop-mode' ), array( 'status' => 404 ) );
861 + return new WP_Error( 'openstation_recycle_bin_not_found', __( 'Comment not found.', 'desktop-mode' ), array( 'status' => 404 ) );
857 862 }
858 863 if ( 'trash' !== $comment->comment_approved ) {
859 - return new WP_Error( 'desktop_mode_recycle_bin_not_trashed', __( 'Comment is not in the trash.', 'desktop-mode' ), array( 'status' => 409 ) );
864 + return new WP_Error( 'openstation_recycle_bin_not_trashed', __( 'Comment is not in the trash.', 'desktop-mode' ), array( 'status' => 409 ) );
860 865 }
861 - if ( ! desktop_mode_recycle_bin_user_can_purge_comment( $comment ) ) {
862 - return new WP_Error( 'desktop_mode_recycle_bin_forbidden', __( 'You are not allowed to permanently delete this comment.', 'desktop-mode' ), array( 'status' => 403 ) );
866 + if ( ! openstation_recycle_bin_user_can_purge_comment( $comment ) ) {
867 + return new WP_Error( 'openstation_recycle_bin_forbidden', __( 'You are not allowed to permanently delete this comment.', 'desktop-mode' ), array( 'status' => 403 ) );
863 868 }
864 869
865 870 /**
866 871 * Fires before a comment is permanently deleted via the bin.
@@ -867,14 +872,14 @@
867 872 *
868 873 * @param int $comment_id Comment id.
869 874 * @param WP_Comment $comment Trashed comment.
870 875 */
871 - do_action( 'desktop_mode_recycle_bin_before_purge_comment', $comment_id, $comment );
876 + do_action( 'openstation_recycle_bin_before_purge_comment', $comment_id, $comment );
872 877
873 878 $result = wp_delete_comment( $comment_id, true );
874 879
875 880 if ( ! $result ) {
876 - return new WP_Error( 'desktop_mode_recycle_bin_purge_failed', __( 'Failed to permanently delete comment.', 'desktop-mode' ), array( 'status' => 500 ) );
881 + return new WP_Error( 'openstation_recycle_bin_purge_failed', __( 'Failed to permanently delete comment.', 'desktop-mode' ), array( 'status' => 500 ) );
877 882 }
878 883
879 884 /**
880 885 * Fires after a comment is permanently deleted via the bin.
@@ -880,9 +885,9 @@
880 885 * Fires after a comment is permanently deleted via the bin.
881 886 *
882 887 * @param int $comment_id Comment id.
883 888 */
884 - do_action( 'desktop_mode_recycle_bin_after_purge_comment', $comment_id );
889 + do_action( 'openstation_recycle_bin_after_purge_comment', $comment_id );
885 890
886 891 return true;
887 892 }
888 893
@@ -895,9 +900,9 @@
895 900 * Processes at most one chunk per call. The cap protects against PHP
896 901 * timeouts on large bins; the client iterates while `remaining > 0`
897 902 * (and bails when `remaining === skipped`, i.e. nothing the user can
898 903 * purge is left). Site owners with longer execution budgets can tune
899 - * the chunk size via the `desktop_mode_recycle_bin_empty_chunk_size`
904 + * the chunk size via the `openstation_recycle_bin_empty_chunk_size`
900 905 * filter.
901 906 *
902 907 * @return array {
903 908 * @type int $purged Items successfully purged in this call.
@@ -904,9 +909,9 @@
904 909 * @type int $skipped Items skipped (capability or error).
905 910 * @type int $remaining Items still in the bin after this call (across pages).
906 911 * }
907 912 */
908 -function desktop_mode_recycle_bin_empty() {
913 +function openstation_recycle_bin_empty() {
909 914 $purged = 0;
910 915 $skipped = 0;
911 916
912 917 /**
@@ -911,9 +916,9 @@
911 916
912 917 /**
913 918 * Filter the per-call chunk size for the empty-bin loop.
914 919 *
915 - * `desktop_mode_recycle_bin_empty()` only purges this many items
920 + * `openstation_recycle_bin_empty()` only purges this many items
916 921 * per invocation. The client iterates while `remaining > 0`. The
917 922 * default (200) is conservative for shared hosts; sites with
918 923 * generous PHP execution limits can raise it to make emptying a
919 924 * large bin take fewer roundtrips.
@@ -919,9 +924,9 @@
919 924 * large bin take fewer roundtrips.
920 925 *
921 926 * @param int $chunk_size Items processed per call. Default 200.
922 927 */
923 - $chunk_size = (int) apply_filters( 'desktop_mode_recycle_bin_empty_chunk_size', 200 );
928 + $chunk_size = (int) apply_filters( 'openstation_recycle_bin_empty_chunk_size', 200 );
924 929 if ( $chunk_size < 1 ) {
925 930 $chunk_size = 1;
926 931 }
927 932
@@ -928,11 +933,16 @@
928 933 // Loop in chunks — `wp_delete_post()` is cheap individually but
929 934 // hammering it on a 10k-item bin without yielding back to PHP can
930 935 // still time out. The client re-invokes us until `remaining` hits
931 936 // zero (or stalls at `skipped`).
932 - $batch = desktop_mode_recycle_bin_get_items( array( 'per_page' => $chunk_size, 'page' => 1 ) );
937 + $batch = openstation_recycle_bin_get_items(
938 + array(
939 + 'per_page' => $chunk_size,
940 + 'page' => 1,
941 + )
942 + );
933 943 foreach ( $batch['items'] as $item ) {
934 - $result = desktop_mode_recycle_bin_purge(
944 + $result = openstation_recycle_bin_purge(
935 945 (int) $item['id'],
936 946 (string) ( $item['type'] ?? '' )
937 947 );
938 948 if ( is_wp_error( $result ) ) {
@@ -947,9 +957,9 @@
947 957 *
948 958 * @param int $purged Items successfully purged in this call.
949 959 * @param int $skipped Items skipped (capability or error).
950 960 */
951 - do_action( 'desktop_mode_recycle_bin_emptied', $purged, $skipped );
961 + do_action( 'openstation_recycle_bin_emptied', $purged, $skipped );
952 962
953 963 return array(
954 964 'purged' => $purged,
955 965 'skipped' => $skipped,