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

151 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.6.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.6.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` stops the bin from
48 * stamping and listing trashed attachments; it does not change how
49 * WordPress deletes media (that is governed by `MEDIA_TRASH`).
50 *
51 * @since 0.6.0
52 *
53 * @param string[] $types Post types whose deletions the recycle bin tracks.
54 */
55 $types = apply_filters( 'desktop_mode_recycle_bin_capture_post_types', $types );
56
57 return array_values( array_filter( array_map( 'strval', (array) $types ) ) );
58 }
59
60 /**
61 * Mirror the capture for posts/pages so the bin has a uniform record
62 * of "who deleted this and when."
63 *
64 * Core's `wp_trash_post_meta` is set on every trash but it doesn't
65 * include the user id — we stash that ourselves under a private meta
66 * key so the table can show "deleted by Alice".
67 *
68 * @since 0.6.0
69 *
70 * @param int $post_id Post being trashed.
71 */
72 function desktop_mode_recycle_bin_on_trash_post( $post_id ) {
73 $post = get_post( $post_id );
74 if ( ! $post ) {
75 return;
76 }
77 if ( ! in_array( $post->post_type, desktop_mode_recycle_bin_capture_post_types(), true ) ) {
78 return;
79 }
80 desktop_mode_recycle_bin_record_capture( $post_id );
81 }
82
83 /**
84 * Persist who-deleted-what-when metadata for a single item.
85 *
86 * Stored under `_desktop_mode_trash_*` postmeta on the trashed post itself —
87 * survives un-trash naturally because we only consult it while in the
88 * bin, and gets cleaned up by core when the post is permanently
89 * deleted via the standard postmeta cascade.
90 *
91 * @since 0.6.0
92 *
93 * @param int $post_id Post id being captured.
94 */
95 function desktop_mode_recycle_bin_record_capture( $post_id ) {
96 $user_id = get_current_user_id();
97 $now_gmt = current_time( 'mysql', true );
98
99 update_post_meta( $post_id, '_desktop_mode_trash_user_id', (int) $user_id );
100 update_post_meta( $post_id, '_desktop_mode_trash_time_gmt', $now_gmt );
101
102 /**
103 * Fires after the recycle bin records a capture.
104 *
105 * Use this to mirror the event into an external audit log or to
106 * extend the captured payload with custom postmeta.
107 *
108 * @since 0.6.0
109 *
110 * @param int $post_id Post id that was captured.
111 * @param int $user_id User id who triggered the capture.
112 * @param string $now_gmt MySQL-format GMT timestamp.
113 */
114 do_action( 'desktop_mode_recycle_bin_item_captured', $post_id, $user_id, $now_gmt );
115 }
116
117 add_action( 'wp_trash_post', 'desktop_mode_recycle_bin_on_trash_post', 10, 1 );
118
119 /**
120 * Capture deleted-by metadata for comments — symmetric to
121 * `desktop_mode_recycle_bin_record_capture` but writing to `commentmeta`
122 * instead of `postmeta`. Comments use `wp_set_comment_status('trash')`
123 * which fires `trashed_comment`; we don't need to short-circuit
124 * anything (core already routes to a real trash status), just
125 * stamp the moment so the bin can show "by Alice, 5 minutes ago".
126 *
127 * @since 0.6.0
128 *
129 * @param int $comment_id Comment about to be trashed.
130 */
131 function desktop_mode_recycle_bin_on_trash_comment( $comment_id ) {
132 $comment_id = (int) $comment_id;
133 $user_id = get_current_user_id();
134 $now_gmt = current_time( 'mysql', true );
135
136 update_comment_meta( $comment_id, '_desktop_mode_trash_user_id', $user_id );
137 update_comment_meta( $comment_id, '_desktop_mode_trash_time_gmt', $now_gmt );
138
139 /**
140 * Fires after the recycle bin records a comment capture.
141 *
142 * @since 0.6.0
143 *
144 * @param int $comment_id Comment id that was captured.
145 * @param int $user_id User id who triggered the capture.
146 * @param string $now_gmt MySQL-format GMT timestamp.
147 */
148 do_action( 'desktop_mode_recycle_bin_comment_captured', $comment_id, $user_id, $now_gmt );
149 }
150 add_action( 'trashed_comment', 'desktop_mode_recycle_bin_on_trash_comment', 10, 1 );
151