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
desktop-mode / includes / recycle-bin / capture.php

capture.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.10, at includes/recycle-bin/capture.php

155 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OpenStation — Recycle Bin: capture.
4 *
5 * Stamps "who-deleted-what-when" metadata onto posts, pages, and
6 * comments as they pass through `wp_trash_post()` / `trashed_comment`,
7 * so the Recycle Bin window can show "deleted by Alice, 5 minutes ago"
8 * without a second roundtrip.
9 *
10 * Media attachments are NOT auto-routed through Trash — they follow
11 * vanilla WordPress behavior (permanent-delete on first click). To
12 * enable trash for media, define `MEDIA_TRASH` as `true` in
13 * `wp-config.php`; the Recycle Bin window will surface trashed
14 * attachments automatically because `attachment` is in the default
15 * `openstation_recycle_bin_capture_post_types` list.
16 *
17 * - `openstation_recycle_bin_capture_post_types` controls which post
18 * types we listen for in the first place.
19 * - The `openstation_recycle_bin_item_captured` action fires after a
20 * successful capture so plugins can mirror the event (audit log,
21 * external storage, etc.).
22 *
23 * @package OpenStation
24 */
25
26 defined( 'ABSPATH' ) || exit;
27
28 /**
29 * Default list of post types the recycle bin is willing to capture.
30 *
31 * Posts and pages already trash by default; the value of capturing them
32 * here is consistency: every "deleted" thing flows through the same
33 * filter pipeline, so a plugin that wants a single audit log can
34 * subscribe once.
35 *
36 * Custom post types with an admin UI (`show_ui`, non-builtin) are
37 * included by default — a trashed WooCommerce product or
38 * portfolio entry belongs in the site-wide bin just as much as a
39 * post does. Visibility stays safe because every row is still gated
40 * per-item on `edit_post` before it is listed. Headless CPTs
41 * (`show_ui => false`, e.g. the pinned-notes `wpd_note`) stay out
42 * unless their owning feature opts in via the filter.
43 *
44 * @return string[]
45 */
46 function openstation_recycle_bin_capture_post_types() {
47 $types = array( 'post', 'page', 'attachment' );
48
49 $custom = get_post_types(
50 array(
51 'show_ui' => true,
52 '_builtin' => false,
53 ),
54 'names'
55 );
56 $types = array_merge( $types, array_values( (array) $custom ) );
57
58 /**
59 * Filter the post types the recycle bin tracks.
60 *
61 * Returning a list excluding `attachment` stops the bin from
62 * stamping and listing trashed attachments; it does not change how
63 * WordPress deletes media (that is governed by `MEDIA_TRASH`).
64 * Remove a custom post type here to keep its trash out of the bin,
65 * or add a headless (`show_ui => false`) type to opt it in.
66 *
67 * @param string[] $types Post types whose deletions the recycle bin tracks.
68 */
69 $types = apply_filters( 'openstation_recycle_bin_capture_post_types', $types );
70
71 return array_values( array_unique( array_filter( array_map( 'strval', (array) $types ) ) ) );
72 }
73
74 /**
75 * Mirror the capture for posts/pages so the bin has a uniform record
76 * of "who deleted this and when."
77 *
78 * Core's `wp_trash_post_meta` is set on every trash but it doesn't
79 * include the user id — we stash that ourselves under a private meta
80 * key so the table can show "deleted by Alice".
81 *
82 * @param int $post_id Post being trashed.
83 */
84 function openstation_recycle_bin_on_trash_post( $post_id ) {
85 $post = get_post( $post_id );
86 if ( ! $post ) {
87 return;
88 }
89 if ( ! in_array( $post->post_type, openstation_recycle_bin_capture_post_types(), true ) ) {
90 return;
91 }
92 openstation_recycle_bin_record_capture( $post_id );
93 }
94
95 /**
96 * Persist who-deleted-what-when metadata for a single item.
97 *
98 * Stored under `_openstation_trash_*` postmeta on the trashed post itself —
99 * survives un-trash naturally because we only consult it while in the
100 * bin, and gets cleaned up by core when the post is permanently
101 * deleted via the standard postmeta cascade.
102 *
103 * @param int $post_id Post id being captured.
104 */
105 function openstation_recycle_bin_record_capture( $post_id ) {
106 $user_id = get_current_user_id();
107 $now_gmt = current_time( 'mysql', true );
108
109 update_post_meta( $post_id, '_desktop_mode_trash_user_id', (int) $user_id );
110 update_post_meta( $post_id, '_desktop_mode_trash_time_gmt', $now_gmt );
111
112 /**
113 * Fires after the recycle bin records a capture.
114 *
115 * Use this to mirror the event into an external audit log or to
116 * extend the captured payload with custom postmeta.
117 *
118 * @param int $post_id Post id that was captured.
119 * @param int $user_id User id who triggered the capture.
120 * @param string $now_gmt MySQL-format GMT timestamp.
121 */
122 do_action( 'openstation_recycle_bin_item_captured', $post_id, $user_id, $now_gmt );
123 }
124
125 add_action( 'wp_trash_post', 'openstation_recycle_bin_on_trash_post', 10, 1 );
126
127 /**
128 * Capture deleted-by metadata for comments — symmetric to
129 * `openstation_recycle_bin_record_capture` but writing to `commentmeta`
130 * instead of `postmeta`. Comments use `wp_set_comment_status('trash')`
131 * which fires `trashed_comment`; we don't need to short-circuit
132 * anything (core already routes to a real trash status), just
133 * stamp the moment so the bin can show "by Alice, 5 minutes ago".
134 *
135 * @param int $comment_id Comment about to be trashed.
136 */
137 function openstation_recycle_bin_on_trash_comment( $comment_id ) {
138 $comment_id = (int) $comment_id;
139 $user_id = get_current_user_id();
140 $now_gmt = current_time( 'mysql', true );
141
142 update_comment_meta( $comment_id, '_desktop_mode_trash_user_id', $user_id );
143 update_comment_meta( $comment_id, '_desktop_mode_trash_time_gmt', $now_gmt );
144
145 /**
146 * Fires after the recycle bin records a comment capture.
147 *
148 * @param int $comment_id Comment id that was captured.
149 * @param int $user_id User id who triggered the capture.
150 * @param string $now_gmt MySQL-format GMT timestamp.
151 */
152 do_action( 'openstation_recycle_bin_comment_captured', $comment_id, $user_id, $now_gmt );
153 }
154 add_action( 'trashed_comment', 'openstation_recycle_bin_on_trash_comment', 10, 1 );
155