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