PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.0
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.0
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 0.9.0, at includes/recycle-bin/capture.php

150 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Desktop Mode — 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 * `desktop_mode_recycle_bin_capture_post_types` list.
16 *
17 * - `desktop_mode_recycle_bin_capture_post_types` controls which post
18 * types we listen for in the first place.
19 * - The `desktop_mode_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 WPDesktopMode
24 * @since 0.19.0
25 */
26
27 defined( 'ABSPATH' ) || exit;
28
29 /**
30 * Default list of post types the recycle bin is willing to capture.
31 *
32 * Posts and pages already trash by default; the value of capturing them
33 * here is consistency: every "deleted" thing flows through the same
34 * filter pipeline, so a plugin that wants a single audit log can
35 * subscribe once.
36 *
37 * @since 0.19.0
38 *
39 * @return string[]
40 */
41 function desktop_mode_recycle_bin_capture_post_types() {
42 $types = array( 'post', 'page', 'attachment' );
43
44 /**
45 * Filter the post types the recycle bin tracks.
46 *
47 * Returning a list excluding `attachment` disables the soft-delete
48 * interception entirely — vanilla WordPress media deletion resumes.
49 *
50 * @since 0.19.0
51 *
52 * @param string[] $types Post types whose deletions the recycle bin tracks.
53 */
54 $types = apply_filters( 'desktop_mode_recycle_bin_capture_post_types', $types );
55
56 return array_values( array_filter( array_map( 'strval', (array) $types ) ) );
57 }
58
59 /**
60 * Mirror the capture for posts/pages so the bin has a uniform record
61 * of "who deleted this and when."
62 *
63 * Core's `wp_trash_post_meta` is set on every trash but it doesn't
64 * include the user id — we stash that ourselves under a private meta
65 * key so the table can show "deleted by Alice".
66 *
67 * @since 0.19.0
68 *
69 * @param int $post_id Post being trashed.
70 */
71 function desktop_mode_recycle_bin_on_trash_post( $post_id ) {
72 $post = get_post( $post_id );
73 if ( ! $post ) {
74 return;
75 }
76 if ( ! in_array( $post->post_type, desktop_mode_recycle_bin_capture_post_types(), true ) ) {
77 return;
78 }
79 desktop_mode_recycle_bin_record_capture( $post_id );
80 }
81
82 /**
83 * Persist who-deleted-what-when metadata for a single item.
84 *
85 * Stored under `_desktop_mode_trash_*` postmeta on the trashed post itself —
86 * survives un-trash naturally because we only consult it while in the
87 * bin, and gets cleaned up by core when the post is permanently
88 * deleted via the standard postmeta cascade.
89 *
90 * @since 0.19.0
91 *
92 * @param int $post_id Post id being captured.
93 */
94 function desktop_mode_recycle_bin_record_capture( $post_id ) {
95 $user_id = get_current_user_id();
96 $now_gmt = current_time( 'mysql', true );
97
98 update_post_meta( $post_id, '_desktop_mode_trash_user_id', (int) $user_id );
99 update_post_meta( $post_id, '_desktop_mode_trash_time_gmt', $now_gmt );
100
101 /**
102 * Fires after the recycle bin records a capture.
103 *
104 * Use this to mirror the event into an external audit log or to
105 * extend the captured payload with custom postmeta.
106 *
107 * @since 0.19.0
108 *
109 * @param int $post_id Post id that was captured.
110 * @param int $user_id User id who triggered the capture.
111 * @param string $now_gmt MySQL-format GMT timestamp.
112 */
113 do_action( 'desktop_mode_recycle_bin_item_captured', $post_id, $user_id, $now_gmt );
114 }
115
116 add_action( 'wp_trash_post', 'desktop_mode_recycle_bin_on_trash_post', 10, 1 );
117
118 /**
119 * Capture deleted-by metadata for comments — symmetric to
120 * `desktop_mode_recycle_bin_record_capture` but writing to `commentmeta`
121 * instead of `postmeta`. Comments use `wp_set_comment_status('trash')`
122 * which fires `trashed_comment`; we don't need to short-circuit
123 * anything (core already routes to a real trash status), just
124 * stamp the moment so the bin can show "by Alice, 5 minutes ago".
125 *
126 * @since 0.21.0
127 *
128 * @param int $comment_id Comment about to be trashed.
129 */
130 function desktop_mode_recycle_bin_on_trash_comment( $comment_id ) {
131 $comment_id = (int) $comment_id;
132 $user_id = get_current_user_id();
133 $now_gmt = current_time( 'mysql', true );
134
135 update_comment_meta( $comment_id, '_desktop_mode_trash_user_id', $user_id );
136 update_comment_meta( $comment_id, '_desktop_mode_trash_time_gmt', $now_gmt );
137
138 /**
139 * Fires after the recycle bin records a comment capture.
140 *
141 * @since 0.21.0
142 *
143 * @param int $comment_id Comment id that was captured.
144 * @param int $user_id User id who triggered the capture.
145 * @param string $now_gmt MySQL-format GMT timestamp.
146 */
147 do_action( 'desktop_mode_recycle_bin_comment_captured', $comment_id, $user_id, $now_gmt );
148 }
149 add_action( 'trashed_comment', 'desktop_mode_recycle_bin_on_trash_comment', 10, 1 );
150